2012-08-11 00:20:25 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2005-02-25 12:07:58 +03:00
|
|
|
|
2019-01-17 21:18:31 +03:00
|
|
|
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
|
|
var { AppConstants } = ChromeUtils.import(
|
|
|
|
"resource://gre/modules/AppConstants.jsm"
|
|
|
|
);
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-04-30 20:29:18 +03:00
|
|
|
const permissionExceptionsL10n = {
|
|
|
|
trackingprotection: {
|
2019-08-09 22:31:04 +03:00
|
|
|
window: "permissions-exceptions-etp-window",
|
|
|
|
description: "permissions-exceptions-etp-desc",
|
2018-04-30 20:29:18 +03:00
|
|
|
},
|
|
|
|
cookie: {
|
|
|
|
window: "permissions-exceptions-cookie-window",
|
|
|
|
description: "permissions-exceptions-cookie-desc",
|
|
|
|
},
|
|
|
|
popup: {
|
|
|
|
window: "permissions-exceptions-popup-window",
|
|
|
|
description: "permissions-exceptions-popup-desc",
|
|
|
|
},
|
|
|
|
"login-saving": {
|
|
|
|
window: "permissions-exceptions-saved-logins-window",
|
|
|
|
description: "permissions-exceptions-saved-logins-desc",
|
|
|
|
},
|
|
|
|
install: {
|
|
|
|
window: "permissions-exceptions-addons-window",
|
|
|
|
description: "permissions-exceptions-addons-desc",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2016-12-31 05:47:25 +03:00
|
|
|
function Permission(principal, type, capability) {
|
2015-06-02 18:42:39 +03:00
|
|
|
this.principal = principal;
|
|
|
|
this.origin = principal.origin;
|
2005-02-25 12:07:58 +03:00
|
|
|
this.type = type;
|
|
|
|
this.capability = capability;
|
|
|
|
}
|
|
|
|
|
|
|
|
var gPermissionManager = {
|
2017-03-21 21:29:43 +03:00
|
|
|
_type: "",
|
2018-06-22 16:13:53 +03:00
|
|
|
_isObserving: false,
|
|
|
|
_permissions: new Map(),
|
2017-03-21 21:29:43 +03:00
|
|
|
_permissionsToAdd: new Map(),
|
|
|
|
_permissionsToDelete: new Map(),
|
|
|
|
_bundle: null,
|
2018-06-22 16:13:53 +03:00
|
|
|
_list: null,
|
|
|
|
_removeButton: null,
|
|
|
|
_removeAllButton: null,
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 17:26:14 +03:00
|
|
|
onLoad() {
|
2018-06-05 19:30:43 +03:00
|
|
|
let params = window.arguments[0];
|
2018-06-05 17:26:14 +03:00
|
|
|
document.mozSubdialogReady = this.init(params);
|
|
|
|
},
|
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
async init(params) {
|
2018-06-22 16:13:53 +03:00
|
|
|
if (!this._isObserving) {
|
|
|
|
Services.obs.addObserver(this, "perm-changed");
|
|
|
|
this._isObserving = true;
|
2018-06-05 17:26:14 +03:00
|
|
|
}
|
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
this._type = params.permissionType;
|
2018-06-22 16:13:53 +03:00
|
|
|
this._list = document.getElementById("permissionsBox");
|
|
|
|
this._removeButton = document.getElementById("removePermission");
|
|
|
|
this._removeAllButton = document.getElementById("removeAllPermissions");
|
2018-06-05 17:26:14 +03:00
|
|
|
|
|
|
|
let permissionsText = document.getElementById("permissionsText");
|
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
let l10n = permissionExceptionsL10n[this._type];
|
|
|
|
document.l10n.setAttributes(permissionsText, l10n.description);
|
2018-06-05 17:26:14 +03:00
|
|
|
document.l10n.setAttributes(document.documentElement, l10n.window);
|
|
|
|
|
|
|
|
await document.l10n.translateElements([
|
|
|
|
permissionsText,
|
2018-06-22 16:13:53 +03:00
|
|
|
document.documentElement,
|
2018-06-05 17:26:14 +03:00
|
|
|
]);
|
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
document.getElementById("btnBlock").hidden = !params.blockVisible;
|
|
|
|
document.getElementById("btnSession").hidden = !params.sessionVisible;
|
|
|
|
document.getElementById("btnAllow").hidden = !params.allowVisible;
|
2018-06-05 17:26:14 +03:00
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
let urlFieldVisible =
|
|
|
|
params.blockVisible || params.sessionVisible || params.allowVisible;
|
2018-06-05 17:26:14 +03:00
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
let urlField = document.getElementById("url");
|
|
|
|
urlField.value = params.prefilledHost;
|
2018-06-05 17:26:14 +03:00
|
|
|
urlField.hidden = !urlFieldVisible;
|
|
|
|
|
|
|
|
this.onHostInput(urlField);
|
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
let urlLabel = document.getElementById("urlLabel");
|
2018-06-05 17:26:14 +03:00
|
|
|
urlLabel.hidden = !urlFieldVisible;
|
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
this._hideStatusColumn = params.hideStatusColumn;
|
|
|
|
let statusCol = document.getElementById("statusCol");
|
|
|
|
statusCol.hidden = this._hideStatusColumn;
|
|
|
|
if (this._hideStatusColumn) {
|
|
|
|
statusCol.removeAttribute("data-isCurrentSortCol");
|
|
|
|
document
|
|
|
|
.getElementById("siteCol")
|
|
|
|
.setAttribute("data-isCurrentSortCol", "true");
|
2018-06-05 17:26:14 +03:00
|
|
|
}
|
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
Services.obs.notifyObservers(null, "flush-pending-permissions", this._type);
|
2018-06-05 17:26:14 +03:00
|
|
|
|
|
|
|
this._loadPermissions();
|
2018-06-22 16:13:53 +03:00
|
|
|
this.buildPermissionsList();
|
2018-06-05 17:26:14 +03:00
|
|
|
|
|
|
|
urlField.focus();
|
|
|
|
},
|
|
|
|
|
|
|
|
uninit() {
|
2018-06-22 16:13:53 +03:00
|
|
|
if (this._isObserving) {
|
2018-06-05 17:26:14 +03:00
|
|
|
Services.obs.removeObserver(this, "perm-changed");
|
2018-06-22 16:13:53 +03:00
|
|
|
this._isObserving = false;
|
2018-06-05 17:26:14 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
observe(subject, topic, data) {
|
2018-06-22 16:13:53 +03:00
|
|
|
if (topic !== "perm-changed") {
|
|
|
|
return;
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2018-06-05 17:26:14 +03:00
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
let permission = subject.QueryInterface(Ci.nsIPermission);
|
2018-06-05 17:26:14 +03:00
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
// Ignore unrelated permission types.
|
|
|
|
if (permission.type !== this._type) {
|
|
|
|
return;
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
|
|
|
|
if (data == "added") {
|
|
|
|
this._addPermissionToList(permission);
|
|
|
|
this.buildPermissionsList();
|
|
|
|
} else if (data == "changed") {
|
|
|
|
let p = this._permissions.get(permission.principal.origin);
|
2019-01-23 21:19:19 +03:00
|
|
|
// Maybe this item has been excluded before because it had an invalid capability.
|
|
|
|
if (p) {
|
|
|
|
p.capability = permission.capability;
|
|
|
|
this._handleCapabilityChange(p);
|
|
|
|
} else {
|
|
|
|
this._addPermissionToList(permission);
|
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
this.buildPermissionsList();
|
|
|
|
} else if (data == "deleted") {
|
|
|
|
this._removePermissionFromList(permission.principal.origin);
|
2018-06-05 17:26:14 +03:00
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
_handleCapabilityChange(perm) {
|
|
|
|
let permissionlistitem = document.getElementsByAttribute(
|
|
|
|
"origin",
|
|
|
|
perm.origin
|
|
|
|
)[0];
|
2018-11-15 02:11:24 +03:00
|
|
|
document.l10n.setAttributes(
|
|
|
|
permissionlistitem.querySelector(".website-capability-value"),
|
|
|
|
this._getCapabilityL10nId(perm.capability)
|
|
|
|
);
|
2018-06-05 17:26:14 +03:00
|
|
|
},
|
|
|
|
|
2019-01-23 21:19:19 +03:00
|
|
|
_isCapabilitySupported(capability) {
|
|
|
|
return (
|
|
|
|
capability == Ci.nsIPermissionManager.ALLOW_ACTION ||
|
|
|
|
capability == Ci.nsIPermissionManager.DENY_ACTION ||
|
|
|
|
capability == Ci.nsICookiePermission.ACCESS_SESSION
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
2018-11-15 02:11:24 +03:00
|
|
|
_getCapabilityL10nId(capability) {
|
2018-06-05 19:30:43 +03:00
|
|
|
let stringKey = null;
|
|
|
|
switch (capability) {
|
2018-06-22 16:13:53 +03:00
|
|
|
case Ci.nsIPermissionManager.ALLOW_ACTION:
|
2018-11-15 02:11:24 +03:00
|
|
|
stringKey = "permissions-capabilities-listitem-allow";
|
2005-02-25 12:07:58 +03:00
|
|
|
break;
|
2018-06-22 16:13:53 +03:00
|
|
|
case Ci.nsIPermissionManager.DENY_ACTION:
|
2018-11-15 02:11:24 +03:00
|
|
|
stringKey = "permissions-capabilities-listitem-block";
|
2005-02-25 12:07:58 +03:00
|
|
|
break;
|
2018-06-22 16:13:53 +03:00
|
|
|
case Ci.nsICookiePermission.ACCESS_SESSION:
|
2018-11-15 02:11:24 +03:00
|
|
|
stringKey = "permissions-capabilities-listitem-allow-session";
|
2005-02-25 12:07:58 +03:00
|
|
|
break;
|
2018-06-22 16:13:53 +03:00
|
|
|
default:
|
|
|
|
throw new Error(`Unknown capability: ${capability}`);
|
2005-02-25 12:07:58 +03:00
|
|
|
}
|
2018-11-15 02:11:24 +03:00
|
|
|
return stringKey;
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
_addPermissionToList(perm) {
|
2018-11-15 02:11:24 +03:00
|
|
|
if (perm.type !== this._type) {
|
2018-11-07 14:44:26 +03:00
|
|
|
return;
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2019-01-23 21:19:19 +03:00
|
|
|
if (!this._isCapabilitySupported(perm.capability)) {
|
|
|
|
return;
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2019-01-23 21:19:19 +03:00
|
|
|
|
2018-11-15 02:11:24 +03:00
|
|
|
let p = new Permission(perm.principal, perm.type, perm.capability);
|
2018-06-22 16:13:53 +03:00
|
|
|
this._permissions.set(p.origin, p);
|
2018-06-05 17:26:14 +03:00
|
|
|
},
|
|
|
|
|
2019-03-19 17:14:03 +03:00
|
|
|
_addOrModifyPermission(principal, capability) {
|
|
|
|
// check whether the permission already exists, if not, add it
|
|
|
|
let permissionParams = { principal, type: this._type, capability };
|
|
|
|
let existingPermission = this._permissions.get(principal.origin);
|
|
|
|
if (!existingPermission) {
|
|
|
|
this._permissionsToAdd.set(principal.origin, permissionParams);
|
|
|
|
this._addPermissionToList(permissionParams);
|
|
|
|
this.buildPermissionsList();
|
|
|
|
} else if (existingPermission.capability != capability) {
|
|
|
|
existingPermission.capability = capability;
|
|
|
|
this._permissionsToAdd.set(principal.origin, permissionParams);
|
|
|
|
this._handleCapabilityChange(existingPermission);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_addNewPrincipalToList(list, uri) {
|
2019-07-08 19:37:45 +03:00
|
|
|
list.push(Services.scriptSecurityManager.createContentPrincipal(uri, {}));
|
2019-03-19 17:14:03 +03:00
|
|
|
// If we have ended up with an unknown scheme, the following will throw.
|
|
|
|
list[list.length - 1].origin;
|
|
|
|
},
|
|
|
|
|
2019-02-05 02:40:16 +03:00
|
|
|
addPermission(capability) {
|
2018-06-05 19:30:43 +03:00
|
|
|
let textbox = document.getElementById("url");
|
2019-03-23 05:32:17 +03:00
|
|
|
let input_url = textbox.value.trim(); // trim any leading and trailing space
|
2019-03-19 17:14:03 +03:00
|
|
|
let principals = [];
|
2005-02-25 12:07:58 +03:00
|
|
|
try {
|
2015-07-30 00:47:36 +03:00
|
|
|
// The origin accessor on the principal object will throw if the
|
|
|
|
// principal doesn't have a canonical origin representation. This will
|
|
|
|
// help catch cases where the URI parser parsed something like
|
|
|
|
// `localhost:8080` as having the scheme `localhost`, rather than being
|
|
|
|
// an invalid URI. A canonical origin representation is required by the
|
|
|
|
// permission manager for storage, so this won't prevent any valid
|
|
|
|
// permissions from being entered by the user.
|
2015-06-02 18:42:39 +03:00
|
|
|
try {
|
2019-03-19 17:14:03 +03:00
|
|
|
let uri = Services.io.newURI(input_url);
|
2019-07-08 19:37:45 +03:00
|
|
|
let principal = Services.scriptSecurityManager.createContentPrincipal(
|
2019-03-19 17:14:03 +03:00
|
|
|
uri,
|
|
|
|
{}
|
|
|
|
);
|
2017-03-29 16:28:46 +03:00
|
|
|
if (principal.origin.startsWith("moz-nullprincipal:")) {
|
2019-03-20 13:17:42 +03:00
|
|
|
throw new Error("Null principal");
|
2017-03-29 16:28:46 +03:00
|
|
|
}
|
2019-03-19 17:14:03 +03:00
|
|
|
principals.push(principal);
|
2016-08-14 04:58:42 +03:00
|
|
|
} catch (ex) {
|
2019-03-19 17:14:03 +03:00
|
|
|
this._addNewPrincipalToList(
|
|
|
|
principals,
|
|
|
|
Services.io.newURI("http://" + input_url)
|
|
|
|
);
|
|
|
|
this._addNewPrincipalToList(
|
|
|
|
principals,
|
|
|
|
Services.io.newURI("https://" + input_url)
|
|
|
|
);
|
2015-06-02 18:42:39 +03:00
|
|
|
}
|
2016-08-14 04:58:42 +03:00
|
|
|
} catch (ex) {
|
2018-04-30 20:29:18 +03:00
|
|
|
document.l10n
|
|
|
|
.formatValues([
|
2018-05-14 22:37:41 +03:00
|
|
|
{ id: "permissions-invalid-uri-title" },
|
2018-08-31 08:59:17 +03:00
|
|
|
{ id: "permissions-invalid-uri-label" },
|
2018-04-28 01:38:22 +03:00
|
|
|
])
|
|
|
|
.then(([title, message]) => {
|
2018-04-30 20:29:18 +03:00
|
|
|
Services.prompt.alert(window, title, message);
|
|
|
|
});
|
2005-06-08 19:10:19 +04:00
|
|
|
return;
|
2005-02-25 12:07:58 +03:00
|
|
|
}
|
|
|
|
|
2019-03-19 17:14:03 +03:00
|
|
|
for (let principal of principals) {
|
|
|
|
this._addOrModifyPermission(principal, capability);
|
2005-02-25 12:07:58 +03:00
|
|
|
}
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2005-02-25 12:07:58 +03:00
|
|
|
textbox.value = "";
|
|
|
|
textbox.focus();
|
|
|
|
|
|
|
|
// covers a case where the site exists already, so the buttons don't disable
|
|
|
|
this.onHostInput(textbox);
|
|
|
|
|
|
|
|
// enable "remove all" button as needed
|
2018-06-22 16:13:53 +03:00
|
|
|
this._setRemoveButtonState();
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
_removePermission(permission) {
|
2018-06-22 16:13:53 +03:00
|
|
|
this._removePermissionFromList(permission.origin);
|
2015-02-23 19:07:00 +03:00
|
|
|
|
|
|
|
// If this permission was added during this session, let's remove
|
|
|
|
// it from the pending adds list to prevent calls to the
|
|
|
|
// permission manager.
|
2018-06-22 16:13:53 +03:00
|
|
|
let isNewPermission = this._permissionsToAdd.delete(permission.origin);
|
2015-02-23 19:07:00 +03:00
|
|
|
if (!isNewPermission) {
|
2018-06-22 16:13:53 +03:00
|
|
|
this._permissionsToDelete.set(permission.origin, permission);
|
2015-02-23 19:07:00 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
_removePermissionFromList(origin) {
|
|
|
|
this._permissions.delete(origin);
|
|
|
|
let permissionlistitem = document.getElementsByAttribute(
|
|
|
|
"origin",
|
|
|
|
origin
|
|
|
|
)[0];
|
|
|
|
if (permissionlistitem) {
|
|
|
|
permissionlistitem.remove();
|
2015-02-23 19:07:00 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-06-05 17:26:14 +03:00
|
|
|
_loadPermissions() {
|
2018-06-22 16:13:53 +03:00
|
|
|
// load permissions into a table.
|
2018-08-19 05:27:33 +03:00
|
|
|
for (let nextPermission of Services.perms.enumerator) {
|
2018-06-05 17:26:14 +03:00
|
|
|
this._addPermissionToList(nextPermission);
|
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
_createPermissionListItem(permission) {
|
2018-08-25 03:16:27 +03:00
|
|
|
let richlistitem = document.createXULElement("richlistitem");
|
2018-06-22 16:13:53 +03:00
|
|
|
richlistitem.setAttribute("origin", permission.origin);
|
2018-08-25 03:16:27 +03:00
|
|
|
let row = document.createXULElement("hbox");
|
2018-06-22 16:13:53 +03:00
|
|
|
row.setAttribute("flex", "1");
|
|
|
|
|
2018-08-25 03:16:27 +03:00
|
|
|
let hbox = document.createXULElement("hbox");
|
|
|
|
let website = document.createXULElement("label");
|
2018-06-22 16:13:53 +03:00
|
|
|
website.setAttribute("value", permission.origin);
|
|
|
|
hbox.setAttribute("width", "0");
|
|
|
|
hbox.setAttribute("class", "website-name");
|
|
|
|
hbox.setAttribute("flex", "3");
|
|
|
|
hbox.appendChild(website);
|
|
|
|
row.appendChild(hbox);
|
|
|
|
|
|
|
|
if (!this._hideStatusColumn) {
|
2018-08-25 03:16:27 +03:00
|
|
|
hbox = document.createXULElement("hbox");
|
|
|
|
let capability = document.createXULElement("label");
|
2018-06-22 16:13:53 +03:00
|
|
|
capability.setAttribute("class", "website-capability-value");
|
2018-11-15 02:11:24 +03:00
|
|
|
document.l10n.setAttributes(
|
|
|
|
capability,
|
|
|
|
this._getCapabilityL10nId(permission.capability)
|
|
|
|
);
|
2018-06-22 16:13:53 +03:00
|
|
|
hbox.setAttribute("width", "0");
|
|
|
|
hbox.setAttribute("class", "website-name");
|
|
|
|
hbox.setAttribute("flex", "1");
|
|
|
|
hbox.appendChild(capability);
|
|
|
|
row.appendChild(hbox);
|
|
|
|
}
|
2018-06-05 17:26:14 +03:00
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
richlistitem.appendChild(row);
|
|
|
|
return richlistitem;
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
onWindowKeyPress(event) {
|
|
|
|
if (event.keyCode == KeyEvent.DOM_VK_ESCAPE) {
|
2011-05-15 03:11:48 +04:00
|
|
|
window.close();
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2011-05-15 03:11:48 +04:00
|
|
|
},
|
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
onPermissionKeyPress(event) {
|
2018-06-22 16:13:53 +03:00
|
|
|
if (!this._list.selectedItem) {
|
|
|
|
return;
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
|
|
|
|
if (
|
|
|
|
event.keyCode == KeyEvent.DOM_VK_DELETE ||
|
|
|
|
(AppConstants.platform == "macosx" &&
|
|
|
|
event.keyCode == KeyEvent.DOM_VK_BACK_SPACE)
|
|
|
|
) {
|
2018-06-05 17:26:14 +03:00
|
|
|
this.onPermissionDelete();
|
2018-06-05 19:30:43 +03:00
|
|
|
event.preventDefault();
|
2015-02-23 19:07:00 +03:00
|
|
|
}
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
onHostKeyPress(event) {
|
|
|
|
if (event.keyCode == KeyEvent.DOM_VK_RETURN) {
|
2018-06-05 17:26:14 +03:00
|
|
|
document.getElementById("btnAllow").click();
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 19:30:43 +03:00
|
|
|
onHostInput(siteField) {
|
|
|
|
document.getElementById("btnSession").disabled = !siteField.value;
|
|
|
|
document.getElementById("btnBlock").disabled = !siteField.value;
|
|
|
|
document.getElementById("btnAllow").disabled = !siteField.value;
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-22 16:13:53 +03:00
|
|
|
_setRemoveButtonState() {
|
|
|
|
if (!this._list) {
|
2005-02-25 12:07:58 +03:00
|
|
|
return;
|
2019-07-05 10:53:32 +03:00
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
|
|
|
|
let hasSelection = this._list.selectedIndex >= 0;
|
|
|
|
let hasRows = this._list.itemCount > 0;
|
|
|
|
this._removeButton.disabled = !hasSelection;
|
|
|
|
this._removeAllButton.disabled = !hasRows;
|
|
|
|
},
|
|
|
|
|
|
|
|
onPermissionDelete() {
|
|
|
|
let richlistitem = this._list.selectedItem;
|
|
|
|
let origin = richlistitem.getAttribute("origin");
|
|
|
|
let permission = this._permissions.get(origin);
|
|
|
|
|
|
|
|
this._removePermission(permission);
|
|
|
|
|
|
|
|
this._setRemoveButtonState();
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 17:12:39 +03:00
|
|
|
onAllPermissionsDelete() {
|
2018-06-22 16:13:53 +03:00
|
|
|
for (let permission of this._permissions.values()) {
|
|
|
|
this._removePermission(permission);
|
2015-02-23 19:07:00 +03:00
|
|
|
}
|
2018-06-22 16:13:53 +03:00
|
|
|
|
|
|
|
this._setRemoveButtonState();
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2018-06-05 17:26:14 +03:00
|
|
|
onPermissionSelect() {
|
2018-06-22 16:13:53 +03:00
|
|
|
this._setRemoveButtonState();
|
2018-06-05 17:26:14 +03:00
|
|
|
},
|
|
|
|
|
|
|
|
onApplyChanges() {
|
|
|
|
// Stop observing permission changes since we are about
|
|
|
|
// to write out the pending adds/deletes and don't need
|
|
|
|
// to update the UI
|
|
|
|
this.uninit();
|
|
|
|
|
|
|
|
for (let p of this._permissionsToDelete.values()) {
|
|
|
|
Services.perms.removeFromPrincipal(p.principal, p.type);
|
|
|
|
}
|
|
|
|
|
2019-04-01 15:41:51 +03:00
|
|
|
for (let p of this._permissionsToAdd.values()) {
|
|
|
|
Services.perms.addFromPrincipal(p.principal, p.type, p.capability);
|
|
|
|
}
|
|
|
|
|
2018-06-05 17:26:14 +03:00
|
|
|
window.close();
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
2015-02-23 19:07:00 +03:00
|
|
|
|
2019-02-05 02:40:16 +03:00
|
|
|
buildPermissionsList(sortCol) {
|
2018-06-22 16:13:53 +03:00
|
|
|
// Clear old entries.
|
|
|
|
let oldItems = this._list.querySelectorAll("richlistitem");
|
|
|
|
for (let item of oldItems) {
|
|
|
|
item.remove();
|
|
|
|
}
|
|
|
|
let frag = document.createDocumentFragment();
|
|
|
|
|
|
|
|
let permissions = Array.from(this._permissions.values());
|
|
|
|
|
|
|
|
for (let permission of permissions) {
|
|
|
|
let richlistitem = this._createPermissionListItem(permission);
|
|
|
|
frag.appendChild(richlistitem);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort permissions.
|
2019-02-05 02:40:16 +03:00
|
|
|
this._sortPermissions(this._list, frag, sortCol);
|
2018-06-22 16:13:53 +03:00
|
|
|
|
|
|
|
this._list.appendChild(frag);
|
|
|
|
|
|
|
|
this._setRemoveButtonState();
|
2012-01-27 01:10:00 +04:00
|
|
|
},
|
|
|
|
|
2019-02-05 02:40:16 +03:00
|
|
|
_sortPermissions(list, frag, column) {
|
2018-06-22 16:13:53 +03:00
|
|
|
let sortDirection;
|
|
|
|
|
|
|
|
if (!column) {
|
|
|
|
column = document.querySelector("treecol[data-isCurrentSortCol=true]");
|
|
|
|
sortDirection =
|
|
|
|
column.getAttribute("data-last-sortDirection") || "ascending";
|
|
|
|
} else {
|
|
|
|
sortDirection = column.getAttribute("data-last-sortDirection");
|
|
|
|
sortDirection =
|
|
|
|
sortDirection === "ascending" ? "descending" : "ascending";
|
|
|
|
}
|
|
|
|
|
|
|
|
let sortFunc = null;
|
|
|
|
switch (column.id) {
|
|
|
|
case "siteCol":
|
|
|
|
sortFunc = (a, b) => {
|
|
|
|
return comp.compare(
|
|
|
|
a.getAttribute("origin"),
|
|
|
|
b.getAttribute("origin")
|
|
|
|
);
|
|
|
|
};
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "statusCol":
|
|
|
|
sortFunc = (a, b) => {
|
2019-02-06 00:01:08 +03:00
|
|
|
// The capabilities values ("Allow" and "Block") are localized asynchronously.
|
|
|
|
// Sort based on the guaranteed-present localization ID instead, note that the
|
|
|
|
// ascending/descending arrow may be pointing the wrong way.
|
|
|
|
return (
|
|
|
|
a
|
|
|
|
.querySelector(".website-capability-value")
|
|
|
|
.getAttribute("data-l10n-id") >
|
|
|
|
b
|
|
|
|
.querySelector(".website-capability-value")
|
|
|
|
.getAttribute("data-l10n-id")
|
|
|
|
);
|
2018-06-22 16:13:53 +03:00
|
|
|
};
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
let comp = new Services.intl.Collator(undefined, {
|
2018-08-31 08:59:17 +03:00
|
|
|
usage: "sort",
|
2018-06-22 16:13:53 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
let items = Array.from(frag.querySelectorAll("richlistitem"));
|
|
|
|
|
|
|
|
if (sortDirection === "descending") {
|
|
|
|
items.sort((a, b) => sortFunc(b, a));
|
|
|
|
} else {
|
|
|
|
items.sort(sortFunc);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Re-append items in the correct order:
|
|
|
|
items.forEach(item => frag.appendChild(item));
|
|
|
|
|
2018-12-26 20:00:31 +03:00
|
|
|
let cols = list.previousElementSibling.querySelectorAll("treecol");
|
2018-06-22 16:13:53 +03:00
|
|
|
cols.forEach(c => {
|
|
|
|
c.removeAttribute("data-isCurrentSortCol");
|
|
|
|
c.removeAttribute("sortDirection");
|
|
|
|
});
|
|
|
|
column.setAttribute("data-isCurrentSortCol", "true");
|
|
|
|
column.setAttribute("sortDirection", sortDirection);
|
|
|
|
column.setAttribute("data-last-sortDirection", sortDirection);
|
2005-02-25 12:07:58 +03:00
|
|
|
},
|
|
|
|
};
|