Bug 1203292 - Replace permissions dropdown with 'x' icon r?paolo, gijs draft
authorRicky Chien <ricky060709@gmail.com>
Thu, 19 May 2016 18:18:03 +0800
changeset 383104 2a3375f33047b88859648900368206b2b1e4e008
parent 381597 2ab57664bf7cafdd64e136e341527c275fc8c3aa
child 524393 83f8890b616ac96b648b958e9ca46f8489e089cb
push id21934
push userbmo:rchien@mozilla.com
push dateFri, 01 Jul 2016 07:57:37 +0000
reviewerspaolo, gijs
bugs1203292
milestone50.0a1
Bug 1203292 - Replace permissions dropdown with 'x' icon r?paolo, gijs MozReview-Commit-ID: LmdRlgzeW1c
browser/base/content/browser.js
browser/base/content/test/general/browser_permissions.js
browser/components/customizableui/content/panelUI.xml
browser/themes/shared/controlcenter/panel.inc.css
browser/themes/shared/glyphs.svg
toolkit/themes/shared/jar.inc.mn
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7198,65 +7198,58 @@ var gIdentityHandler = {
   },
 
   updateSitePermissions: function () {
     while (this._permissionList.hasChildNodes())
       this._permissionList.removeChild(this._permissionList.lastChild);
 
     let uri = gBrowser.currentURI;
 
-    for (let permission of SitePermissions.getPermissionsByURI(uri)) {
-      let item = this._createPermissionItem(permission);
+    for (let permission of SitePermissions.listPermissions()) {
+      let state = SitePermissions.get(uri, permission);
+
+      if (state == SitePermissions.UNKNOWN ||
+          SitePermissions.getDefault(permission) != SitePermissions.UNKNOWN) {
+        continue;
+      }
+
+      let item = this._createPermissionItem(permission, state);
       this._permissionList.appendChild(item);
     }
   },
 
-  setPermission: function (aPermission, aState) {
-    if (aState == SitePermissions.getDefault(aPermission))
+  _createPermissionItem: function (aPermission, aState) {
+    let container = document.createElement("hbox");
+    let permLabel = document.createElement("label");
+    permLabel.setAttribute("flex", "1");
+    permLabel.setAttribute("class", "identity-popup-permission-label");
+    permLabel.textContent = SitePermissions.getPermissionLabel(aPermission);
+
+    let stateLabel = document.createElement("label");
+    stateLabel.setAttribute("align", "right");
+    stateLabel.textContent = SitePermissions.getStateLabel(aPermission, aState);
+
+    let button = document.createElement("button");
+    button.setAttribute("align", "right");
+    button.setAttribute("class", "cancel");
+    button.addEventListener("click", () => {
+      this._permissionList.removeChild(container);
       SitePermissions.remove(gBrowser.currentURI, aPermission);
-    else
-      SitePermissions.set(gBrowser.currentURI, aPermission, aState);
-  },
-
-  _createPermissionItem: function (aPermission) {
-    let menulist = document.createElement("menulist");
-    let menupopup = document.createElement("menupopup");
-    for (let state of aPermission.availableStates) {
-      let menuitem = document.createElement("menuitem");
-      menuitem.setAttribute("value", state.id);
-      menuitem.setAttribute("label", state.label);
-      menupopup.appendChild(menuitem);
-    }
-    menulist.appendChild(menupopup);
-    menulist.setAttribute("value", aPermission.state);
-    menulist.setAttribute("oncommand", "gIdentityHandler.setPermission('" +
-                                       aPermission.id + "', this.value)");
-    menulist.setAttribute("id", "identity-popup-permission:" + aPermission.id);
-
-    let label = document.createElement("label");
-    label.setAttribute("flex", "1");
-    label.setAttribute("class", "identity-popup-permission-label");
-    label.setAttribute("control", menulist.getAttribute("id"));
-    label.textContent = aPermission.label;
+    });
 
     let img = document.createElement("image");
     img.setAttribute("class",
-      "identity-popup-permission-icon " + aPermission.id + "-icon");
-
-    let container = document.createElement("hbox");
+      "identity-popup-permission-icon " + aPermission + "-icon");
+
+    container.setAttribute("class", "identity-popup-permission-item");
     container.setAttribute("align", "center");
     container.appendChild(img);
-    container.appendChild(label);
-    container.appendChild(menulist);
-
-    // The menuitem text can be long and we don't want the dropdown
-    // to expand to the width of unselected labels.
-    // Need to set this attribute after it's appended, otherwise it gets
-    // overridden with sizetopopup="pref".
-    menulist.setAttribute("sizetopopup", "none");
+    container.appendChild(permLabel);
+    container.appendChild(stateLabel);
+    container.appendChild(button);
 
     return container;
   }
 };
 
 function getNotificationBox(aWindow) {
   var foundBrowser = gBrowser.getBrowserForDocument(aWindow.document);
   if (foundBrowser)
--- a/browser/base/content/test/general/browser_permissions.js
+++ b/browser/base/content/test/general/browser_permissions.js
@@ -2,82 +2,78 @@
  * Test the Permissions section in the Control Center.
  */
 
 var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 const PERMISSIONS_PAGE = "http://example.com/browser/browser/base/content/test/general/permissions.html";
 var {SitePermissions} = Cu.import("resource:///modules/SitePermissions.jsm", {});
 
 registerCleanupFunction(function() {
-  SitePermissions.remove(gBrowser.currentURI, "install");
   SitePermissions.remove(gBrowser.currentURI, "cookie");
   SitePermissions.remove(gBrowser.currentURI, "geo");
   SitePermissions.remove(gBrowser.currentURI, "camera");
 
   while (gBrowser.tabs.length > 1) {
     gBrowser.removeCurrentTab();
   }
 });
 
 add_task(function* testMainViewVisible() {
   let {gIdentityHandler} = gBrowser.ownerGlobal;
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
 
   let permissionsList = document.getElementById("identity-popup-permission-list");
-  let emptyLabel = permissionsList.nextSibling;
+  let emptyDescription = permissionsList.nextSibling;
 
   gIdentityHandler._identityBox.click();
-  ok(!is_hidden(emptyLabel), "List of permissions is empty");
+  ok(!is_hidden(emptyDescription), "List of permissions is empty");
   gIdentityHandler._identityPopup.hidden = true;
 
-  gIdentityHandler.setPermission("install", SitePermissions.ALLOW);
+  SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.ALLOW);
 
   gIdentityHandler._identityBox.click();
-  ok(is_hidden(emptyLabel), "List of permissions is not empty");
+  ok(is_hidden(emptyDescription), "List of permissions is not empty");
 
-  let labelText = SitePermissions.getPermissionLabel("install");
+  let labelText = SitePermissions.getPermissionLabel("camera");
   let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
   is(labels.length, 1, "One permission visible in main view");
   is(labels[0].textContent, labelText, "Correct value");
 
-  let menulists = permissionsList.querySelectorAll("menulist");
-  is(menulists.length, 1, "One permission visible in main view");
-  is(menulists[0].id, "identity-popup-permission:install", "Install permission visible");
-  is(menulists[0].value, "1", "Correct value on install menulist");
-  gIdentityHandler._identityPopup.hidden = true;
+  let img = permissionsList.querySelector("image.identity-popup-permission-icon");
+  ok(img, "There is an image for the permissions");
+  ok(img.classList.contains("camera-icon"), "proper class is in image class");
 
-  let img = menulists[0].parentNode.querySelector("image");
-  ok(img, "There is an image for the permissions");
-  ok(img.classList.contains("install-icon"), "proper class is in image class");
-
-  gIdentityHandler.setPermission("install", SitePermissions.getDefault("install"));
+  SitePermissions.remove(gBrowser.currentURI, "camera");
 
   gIdentityHandler._identityBox.click();
-  ok(!is_hidden(emptyLabel), "List of permissions is empty");
+  ok(!is_hidden(emptyDescription), "List of permissions is empty");
   gIdentityHandler._identityPopup.hidden = true;
 });
 
-add_task(function* testIdentityIcon() {
+add_task(function* testPermissionRemoving() {
   let {gIdentityHandler} = gBrowser.ownerGlobal;
   let tab = gBrowser.selectedTab = gBrowser.addTab();
   yield promiseTabLoadEvent(tab, PERMISSIONS_PAGE);
 
-  gIdentityHandler.setPermission("geo", SitePermissions.ALLOW);
+  let permissionsList = document.getElementById("identity-popup-permission-list");
+  let emptyDescription = permissionsList.nextSibling;
 
-  ok(gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
-    "identity-box signals granted permssions");
+  SitePermissions.set(gBrowser.currentURI, "camera", SitePermissions.ALLOW);
+  SitePermissions.set(gBrowser.currentURI, "geo", SitePermissions.ALLOW);
 
-  gIdentityHandler.setPermission("geo", SitePermissions.getDefault("geo"));
+  gIdentityHandler._identityBox.click();
+  ok(is_hidden(emptyDescription), "List of permissions is not empty");
 
-  ok(!gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
-    "identity-box doesn't signal granted permssions");
+  let labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
+  is(labels.length, 2, "Two permissions visible in main view");
 
-  gIdentityHandler.setPermission("camera", SitePermissions.BLOCK);
-
-  ok(!gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
-    "identity-box doesn't signal granted permssions");
+  let cancelButtons = permissionsList.querySelectorAll('button.cancel');
+  cancelButtons[0].click();
+  labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
+  is(labels.length, 1, "One permission should be removed");
+  cancelButtons[1].click();
+  labels = permissionsList.querySelectorAll(".identity-popup-permission-label");
+  is(labels.length, 0, "One permission should be removed");
 
-  gIdentityHandler.setPermission("cookie", SitePermissions.SESSION);
-
-  ok(gIdentityHandler._identityBox.classList.contains("grantedPermissions"),
-    "identity-box signals granted permssions");
+  ok(!is_hidden(emptyDescription), "List of permissions is empty");
+  gIdentityHandler._identityPopup.hidden = true;
 });
--- a/browser/components/customizableui/content/panelUI.xml
+++ b/browser/components/customizableui/content/panelUI.xml
@@ -370,16 +370,20 @@
           if (!this._panel || !this._panel.parentNode) {
             return;
           }
 
           if (!this.ignoreMutations && this.showingSubView) {
             let newHeight = this._heightOfSubview(this._currentSubView, this._subViews);
             this._viewContainer.style.height = newHeight + "px";
           }
+
+          if (this._shouldSetHeight()) {
+             this._adjustContainerHeight();
+           }
         ]]></body>
       </method>
       <method name="_syncContainerWithMainView">
         <body><![CDATA[
           // Check that this panel is still alive:
           if (!this._panel || !this._panel.parentNode) {
             return;
           }
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -357,29 +357,52 @@ description#identity-popup-content-verif
 
 #identity-popup-permission-list {
   /* Offset the padding set on #identity-popup-permissions-content so that it
      shows up just below the section. The permission icons are 16px wide and
      should be right aligned with the section icon. */
   margin-inline-start: calc(-1em - 16px);
 }
 
-#identity-popup-permission-list menulist {
+#identity-popup-permission-list .identity-popup-permission-item {
   min-width: 60px;
+  min-height: 20px;
 }
 
 #identity-popup-permission-list:not(:empty) {
   margin-top: 5px;
 }
 
 #identity-popup-permission-list:not(:empty) + description {
   display: none;
 }
 
+#identity-popup-permission-list:empty + description {
+  height: 30px;
+}
+
 .identity-popup-permission-icon {
   width: 16px;
   height: 16px;
 }
 
 .identity-popup-permission-label {
   margin-inline-start: 1em;
   word-wrap: break-word;
 }
+
+button.cancel {
+  margin: 0 2px;
+  -moz-appearance: none;
+  min-width: 20px;
+  min-height: 20px;
+  border-radius: 100%;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-image: url(chrome://browser/skin/glyphs.svg#cancel);
+  filter: url(chrome://browser/skin/filters.svg#fill);
+  fill: #999;
+}
+
+button.cancel:hover {
+  background-color: #999;
+  filter: opacity(65%) invert(100%);
+}
--- a/browser/themes/shared/glyphs.svg
+++ b/browser/themes/shared/glyphs.svg
@@ -19,9 +19,10 @@
   <path id="indexedDB" d="m 2,24 a 4,4 0 0 0 4,4 l 2,0 0,-4 -2,0 0,-16 20,0 0,16 -2,0 0,4 2,0 a 4,4 0 0 0 4,-4 l 0,-16 a 4,4 0 0 0 -4,-4 l -20,0 a 4,4 0 0 0 -4,4 z m 8,-2 6,7 6,-7 -4,0 0,-8 -4,0 0,8 z" />
   <path id="login" d="m 2,26 0,4 6,0 0,-2 2,0 0,-2 1,0 0,-1 2,0 0,-3 2,0 2.5,-2.5 1.5,1.5 3,-3 a 8,8 0 1 0 -8,-8 l -3,3 2,2 z m 20,-18.1 a 2,2 0 1 1 0,0.2 z" />
   <path id="login-detailed" d="m 1,27 0,3.5 a 0.5,0.5 0 0 0 0.5,0.5 l 5,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-1.5 1.5,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-1.5 1,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-1 1,0 a 0.5,0.5 0 0 0 0.5,-0.5 l 0,-2 2,0 2.5,-2.5 q 0.5,-0.5 1,0 l 1,1 c 0.5,0.5 1,0.5 1.5,-0.5 l 1,-2 a 9,9 0 1 0 -8,-8 l -2,1 c -1,0.5 -1,1 -0.5,1.5 l 1.5,1.5 q 0.5,0.5 0,1 z m 21,-19.1 a 2,2 0 1 1 0,0.2 z" />
   <path id="microphone" d="m 8,14 0,4 a 8,8 0 0 0 6,7.7 l 0,2.3 -2,0 a 2,2 0 0 0 -2,2 l 12,0 a 2,2 0 0 0 -2,-2 l -2,0 0,-2.3 a 8,8 0 0 0 6,-7.7 l 0,-4 -2,0 0,4 a 6,6 0 0 1 -12,0 l 0,-4 z m 4,4 a 4,4 0 0 0 8,0 l 0,-12 a 4,4 0 0 0 -8,0 z" />
   <path id="microphone-detailed" d="m 8,18 a 8,8 0 0 0 6,7.7 l 0,2.3 -1,0 a 3,2 0 0 0 -3,2 l 12,0 a 3,2 0 0 0 -3,-2 l -1,0 0,-2.3 a 8,8 0 0 0 6,-7.7 l 0,-4 a 1,1 0 0 0 -2,0 l 0,4 a 6,6 0 0 1 -12,0 l 0,-4 a 1,1 0 0 0 -2,0 z m 4,0 a 4,4 0 0 0 8,0 l 0,-12 a 4,4 0 0 0 -8,0 z" />
   <path id="pointerLock" d="m 8,24 6,-5 5,10 4,-2 -5,-10 7,-1 -17,-14 z" />
   <path id="popup" d="m 2,24 a 4,4 0 0 0 4,4 l 8,0 a 10,10 0 0 1 -2,-4 l -4,0 a 2,2 0 0 1 -2,-2 l 0,-12 18,0 0,2 a 10,10 0 0 1 4,2 l 0,-8 a 4,4 0 0 0 -4,-4 l -18,0 a 4,4 0 0 0 -4,4 z m 12,-2.1 a 8,8 0 1 1 0,0.2 m 10.7,-4.3 a 5,5 0 0 0 -6.9,6.9 z m -5.4,8.4 a 5,5 0 0 0 6.9,-6.9 z" />
   <path id="screen" d="m 2,18 a 2,2 0 0 0 2,2 l 2,0 0,-6 a 4,4 0 0 1 4,-4 l 14,0 0,-6 a 2,2 0 0 0 -2,-2 l -18,0 a 2,2 0 0 0 -2,2 z m 6,10 a 2,2 0 0 0 2,2 l 18,0 a 2,2 0 0 0 2,-2 l 0,-14 a 2,2 0 0 0 -2,-2 l -18,0 a 2,2 0 0 0 -2,2 z" />
+  <path id="cancel" d="m 21,12.7-3.32,3.32,3.3,3.3-1.67,1.67-3.3-3.3-3.27,3.27-1.67-1.67,3.27-3.27-3.37-3.37,1.67-1.67,3.37,3.37,3.32-3.32 z"/>
 </svg>
--- a/toolkit/themes/shared/jar.inc.mn
+++ b/toolkit/themes/shared/jar.inc.mn
@@ -58,9 +58,8 @@ toolkit.jar:
   skin/classic/global/reader/RM-Line-Height-Minus-38x14.svg            (../../shared/reader/RM-Line-Height-Minus-38x14.svg)
   skin/classic/global/reader/RM-Line-Height-Plus-38x24.svg             (../../shared/reader/RM-Line-Height-Plus-38x24.svg)
 #ifdef MOZ_PLACES
   skin/classic/mozapps/places/defaultFavicon.png           (../../shared/places/defaultFavicon.png)
   skin/classic/mozapps/places/defaultFavicon@2x.png        (../../shared/places/defaultFavicon@2x.png)
   skin/classic/mozapps/places/defaultFavicon-inverted.png  (../../shared/places/defaultFavicon-inverted.png)
   skin/classic/mozapps/places/defaultFavicon-inverted@2x.png (../../shared/places/defaultFavicon-inverted@2x.png)
 #endif
-