Bug 1277289 - Add a function to obtain all permissions by uri in SitePermissions.jsm. r=paolo
authorJohann Hofmann <jhofmann@mozilla.com>
Thu, 02 Jun 2016 12:08:29 +0200
changeset 339338 86dca8a132b53174e19082ddad03ac806cb60f98
parent 339337 30700073705df0f07177bc72e0d380504241e1ca
child 339339 4874ff5d90f81aca0bb57d2f74586210cbee3cf6
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspaolo
bugs1277289
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1277289 - Add a function to obtain all permissions by uri in SitePermissions.jsm. r=paolo MozReview-Commit-ID: 8LKS2rK1Pqx
browser/base/content/browser.js
browser/modules/SitePermissions.jsm
browser/modules/test/xpcshell/test_SitePermissions.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -7159,54 +7159,49 @@ var gIdentityHandler = {
   },
 
   updateSitePermissions: function () {
     while (this._permissionList.hasChildNodes())
       this._permissionList.removeChild(this._permissionList.lastChild);
 
     let uri = gBrowser.currentURI;
 
-    for (let permission of SitePermissions.listPermissions()) {
-      let state = SitePermissions.get(uri, permission);
-
-      if (state == SitePermissions.UNKNOWN)
-        continue;
-
-      let item = this._createPermissionItem(permission, state);
+    for (let permission of SitePermissions.getPermissionsByURI(uri)) {
+      let item = this._createPermissionItem(permission);
       this._permissionList.appendChild(item);
     }
   },
 
   setPermission: function (aPermission, aState) {
     if (aState == SitePermissions.getDefault(aPermission))
       SitePermissions.remove(gBrowser.currentURI, aPermission);
     else
       SitePermissions.set(gBrowser.currentURI, aPermission, aState);
   },
 
-  _createPermissionItem: function (aPermission, aState) {
+  _createPermissionItem: function (aPermission) {
     let menulist = document.createElement("menulist");
     let menupopup = document.createElement("menupopup");
-    for (let state of SitePermissions.getAvailableStates(aPermission)) {
+    for (let state of aPermission.availableStates) {
       let menuitem = document.createElement("menuitem");
-      menuitem.setAttribute("value", state);
-      menuitem.setAttribute("label", SitePermissions.getStateLabel(aPermission, state));
+      menuitem.setAttribute("value", state.id);
+      menuitem.setAttribute("label", state.label);
       menupopup.appendChild(menuitem);
     }
     menulist.appendChild(menupopup);
-    menulist.setAttribute("value", aState);
+    menulist.setAttribute("value", aPermission.state);
     menulist.setAttribute("oncommand", "gIdentityHandler.setPermission('" +
-                                       aPermission + "', this.value)");
-    menulist.setAttribute("id", "identity-popup-permission:" + aPermission);
+                                       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 = SitePermissions.getPermissionLabel(aPermission);
+    label.textContent = aPermission.label;
 
     let container = document.createElement("hbox");
     container.setAttribute("align", "center");
     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.
--- a/browser/modules/SitePermissions.jsm
+++ b/browser/modules/SitePermissions.jsm
@@ -11,16 +11,55 @@ var gStringBundle =
 
 this.SitePermissions = {
 
   UNKNOWN: Services.perms.UNKNOWN_ACTION,
   ALLOW: Services.perms.ALLOW_ACTION,
   BLOCK: Services.perms.DENY_ACTION,
   SESSION: Components.interfaces.nsICookiePermission.ACCESS_SESSION,
 
+  /* Returns a list of objects representing all permissions that are currently
+   * set for the given URI. Each object contains the following keys:
+   * - id: the permissionID of the permission
+   * - label: the localized label
+   * - state: a constant representing the current permission state
+   *   (e.g. SitePermissions.ALLOW)
+   * - availableStates: an array of all available states for that permission,
+   *   represented as objects with the keys:
+   *   - id: the state constant
+   *   - label: the translated label of that state
+   */
+  getPermissionsByURI: function (aURI) {
+    if (!this.isSupportedURI(aURI)) {
+      return [];
+    }
+
+    let permissions = [];
+    for (let permission of this.listPermissions()) {
+      let state = this.get(aURI, permission);
+      if (state === this.UNKNOWN) {
+        continue;
+      }
+
+      let availableStates = this.getAvailableStates(permission).map( state => {
+        return { id: state, label: this.getStateLabel(permission, state) };
+      });
+      let label = this.getPermissionLabel(permission);
+
+      permissions.push({
+        id: permission,
+        label: label,
+        state: state,
+        availableStates: availableStates,
+      });
+    }
+
+    return permissions;
+  },
+
   /* Returns a boolean indicating whether there are any granted
    * (meaning allowed or session-allowed) permissions for the given URI.
    * Will return false for invalid URIs (such as file:// URLs).
    */
   hasGrantedPermissions: function (aURI) {
     if (!this.isSupportedURI(aURI)) {
       return false;
     }
--- a/browser/modules/test/xpcshell/test_SitePermissions.js
+++ b/browser/modules/test/xpcshell/test_SitePermissions.js
@@ -9,16 +9,21 @@ Components.utils.import("resource://gre/
 add_task(function* testPermissionsListing() {
   Assert.deepEqual(SitePermissions.listPermissions().sort(),
     ["camera","cookie","desktop-notification","geo","image",
      "indexedDB","install","microphone","pointerLock","popup"],
     "Correct list of all permissions");
 });
 
 add_task(function* testHasGrantedPermissions() {
+  // check that it returns false on an invalid URI
+  // like a file URI, which doesn't support site permissions
+  let wrongURI = Services.io.newURI("file:///example.js", null, null)
+  Assert.equal(SitePermissions.hasGrantedPermissions(wrongURI), false);
+
   let uri = Services.io.newURI("https://example.com", null, null)
   Assert.equal(SitePermissions.hasGrantedPermissions(uri), false);
 
   // check that ALLOW states return true
   SitePermissions.set(uri, "camera", SitePermissions.ALLOW);
   Assert.equal(SitePermissions.hasGrantedPermissions(uri), true);
 
   // removing the ALLOW state should revert to false
@@ -44,8 +49,70 @@ add_task(function* testHasGrantedPermiss
   Assert.equal(SitePermissions.hasGrantedPermissions(uri), true);
 
   // check that only BLOCK states will not return true
   SitePermissions.remove(uri, "geo");
   Assert.equal(SitePermissions.hasGrantedPermissions(uri), false);
 
   SitePermissions.remove(uri, "pointerLock");
 });
+
+add_task(function* testGetPermissionsByURI() {
+  // check that it returns an empty array on an invalid URI
+  // like a file URI, which doesn't support site permissions
+  let wrongURI = Services.io.newURI("file:///example.js", null, null)
+  Assert.deepEqual(SitePermissions.getPermissionsByURI(wrongURI), []);
+
+  let uri = Services.io.newURI("https://example.com", null, null)
+
+  SitePermissions.set(uri, "camera", SitePermissions.ALLOW);
+  SitePermissions.set(uri, "cookie", SitePermissions.SESSION);
+  SitePermissions.set(uri, "popup", SitePermissions.BLOCK);
+
+  let permissions = SitePermissions.getPermissionsByURI(uri);
+
+  let camera = permissions.find(({id}) => id === "camera");
+  Assert.deepEqual(camera, {
+    id: "camera",
+    label: "Use the Camera",
+    state: SitePermissions.ALLOW,
+    availableStates: [
+      { id: SitePermissions.UNKNOWN, label: "Always Ask" },
+      { id: SitePermissions.ALLOW, label: "Allow" },
+      { id: SitePermissions.BLOCK, label: "Block" },
+    ]
+  });
+
+  // check that removed permissions (State.UNKNOWN) are skipped
+  SitePermissions.remove(uri, "camera");
+  permissions = SitePermissions.getPermissionsByURI(uri);
+
+  camera = permissions.find(({id}) => id === "camera");
+  Assert.equal(camera, undefined);
+
+  // check that different available state values are represented
+
+  let cookie = permissions.find(({id}) => id === "cookie");
+  Assert.deepEqual(cookie, {
+    id: "cookie",
+    label: "Set Cookies",
+    state: SitePermissions.SESSION,
+    availableStates: [
+      { id: SitePermissions.ALLOW, label: "Allow" },
+      { id: SitePermissions.SESSION, label: "Allow for Session" },
+      { id: SitePermissions.BLOCK, label: "Block" },
+    ]
+  });
+
+  let popup = permissions.find(({id}) => id === "popup");
+  Assert.deepEqual(popup, {
+    id: "popup",
+    label: "Open Pop-up Windows",
+    state: SitePermissions.BLOCK,
+    availableStates: [
+      { id: SitePermissions.ALLOW, label: "Allow" },
+      { id: SitePermissions.BLOCK, label: "Block" },
+    ]
+  });
+
+  SitePermissions.remove(uri, "cookie");
+  SitePermissions.remove(uri, "popup");
+});