Bug 1277289 - Add a function to obtain all permissions by uri in SitePermissions.jsm. r=paolo
MozReview-Commit-ID: 8LKS2rK1Pqx
--- 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");
+});