Bug 1385221 - Implement Permission sorting in the Permissions dialog. r?johannh
MozReview-Commit-ID: 1F9eZ54ppbB
--- a/browser/components/preferences/in-content/tests/browser_permissions_dialog.js
+++ b/browser/components/preferences/in-content/tests/browser_permissions_dialog.js
@@ -225,13 +225,52 @@ add_task(async function onSearch() {
SitePermissions.set(u, "desktop-notification", SitePermissions.ALLOW);
Assert.equal(doc.getElementsByAttribute("origin", "http://www.test.com")[0], null);
Assert.equal(doc.getElementsByAttribute("origin", "http://www.example.com")[0],
richlistbox.getItemAtIndex(0));
SitePermissions.remove(URI, "desktop-notification");
SitePermissions.remove(u, "desktop-notification");
+
+ doc.getElementById("cancel").click();
+});
+
+add_task(async function onPermissionsSort() {
+ SitePermissions.set(URI, "desktop-notification", SitePermissions.ALLOW);
+ let u = Services.io.newURI("http://www.test.com");
+ SitePermissions.set(u, "desktop-notification", SitePermissions.BLOCK);
+
+ await openPermissionsDialog();
+ let doc = sitePermissionsDialog.document;
+ let richlistbox = doc.getElementById("permissionsBox");
+
+ // Test default arrangement(Allow followed by Block).
+ Assert.equal(richlistbox.getItemAtIndex(0).getAttribute("origin"), "http://www.example.com");
+ Assert.equal(richlistbox.getItemAtIndex(1).getAttribute("origin"), "http://www.test.com");
+
+ doc.getElementById("statusCol").click();
+
+ // Test the rearrangement(Block followed by Allow).
+ Assert.equal(richlistbox.getItemAtIndex(0).getAttribute("origin"), "http://www.test.com");
+ Assert.equal(richlistbox.getItemAtIndex(1).getAttribute("origin"), "http://www.example.com");
+
+ doc.getElementById("siteCol").click();
+
+ // Test the rearrangement(Website names arranged in alphabhetical order).
+ Assert.equal(richlistbox.getItemAtIndex(0).getAttribute("origin"), "http://www.example.com");
+ Assert.equal(richlistbox.getItemAtIndex(1).getAttribute("origin"), "http://www.test.com");
+
+ doc.getElementById("siteCol").click();
+
+ // Test the rearrangement(Website names arranged in reverse alphabhetical order).
+ Assert.equal(richlistbox.getItemAtIndex(0).getAttribute("origin"), "http://www.test.com");
+ Assert.equal(richlistbox.getItemAtIndex(1).getAttribute("origin"), "http://www.example.com");
+
+ SitePermissions.remove(URI, "desktop-notification");
+ SitePermissions.remove(u, "desktop-notification");
+
+ doc.getElementById("cancel").click();
});
add_task(async function removeTab() {
gBrowser.removeCurrentTab();
});
--- a/browser/components/preferences/sitePermissions.js
+++ b/browser/components/preferences/sitePermissions.js
@@ -47,16 +47,17 @@ var gSitePermissionsManager = {
let permissionsText = document.getElementById("permissionsText");
while (permissionsText.hasChildNodes())
permissionsText.firstChild.remove();
permissionsText.appendChild(document.createTextNode(params.introText));
document.title = params.windowTitle;
this._loadPermissions();
+ this.buildPermissionsList();
this._searchBox.focus();
},
uninit() {
if (this._isObserving) {
Services.obs.removeObserver(this, "perm-changed");
this._isObserving = false;
@@ -70,24 +71,23 @@ var gSitePermissionsManager = {
let permission = subject.QueryInterface(Components.interfaces.nsIPermission);
// Ignore unrelated permission types.
if (permission.type !== this._type)
return;
if (data == "added") {
this._addPermissionToList(permission);
- if (this._searchBox.value != "") {
- this.filterPermissionsList();
- }
+ this.buildPermissionsList();
} else if (data == "changed") {
let p = this._permissions.get(permission.principal.origin);
p.capability = permission.capability;
p.capabilityString = this._getCapabilityString(permission.capability);
this._handleCapabilityChange(p);
+ this.buildPermissionsList();
} else if (data == "deleted") {
this._removePermissionFromList(permission.principal.origin);
}
},
_handleCapabilityChange(perm) {
let permissionlistitem = document.getElementsByAttribute("origin", perm.origin)[0];
let menulist = permissionlistitem.getElementsByTagName("menulist")[0];
@@ -113,35 +113,31 @@ var gSitePermissionsManager = {
_addPermissionToList(perm) {
if (perm.type !== this._type)
return;
let capabilityString = this._getCapabilityString(perm.capability);
let p = new Permission(perm.principal, perm.type, perm.capability,
capabilityString);
this._permissions.set(p.origin, p);
- this._createPermissionListItem(p);
},
_removePermissionFromList(origin) {
this._permissions.delete(origin);
let permissionlistitem = document.getElementsByAttribute("origin", origin)[0];
this._list.removeItemAt(this._list.getIndexOfItem(permissionlistitem));
},
_loadPermissions() {
// load permissions into a table.
let enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
let nextPermission = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
this._addPermissionToList(nextPermission);
}
-
- // disable "remove all" button if there are none
- this._setRemoveButtonState();
},
_createPermissionListItem(permission) {
let richlistitem = document.createElement("richlistitem");
richlistitem.setAttribute("origin", permission.origin);
let row = document.createElement("hbox");
row.setAttribute("flex", "1");
@@ -255,27 +251,75 @@ var gSitePermissionsManager = {
for (let p of this._permissionsToDelete.values()) {
let uri = Services.io.newURI(p.origin);
SitePermissions.remove(uri, p.type);
}
window.close();
},
- filterPermissionsList() {
+ buildPermissionsList(sortCol) {
// Clear old entries.
let oldItems = this._list.querySelectorAll("richlistitem");
for (let item of oldItems) {
item.remove();
}
+ // Sort permissions.
+ let sortedPermissions = this._sortPermissions(sortCol);
+
let keyword = this._searchBox.value.toLowerCase().trim();
- let permissions = this._permissions;
- for (let [origin, permission] of permissions) {
- if (keyword && !origin.includes(keyword)) {
+ for (let permission of sortedPermissions) {
+ if (keyword && !permission.origin.includes(keyword)) {
continue;
}
this._createPermissionListItem(permission);
}
+
this._setRemoveButtonState();
},
+
+ _sortPermissions(column) {
+ let permissions = Array.from(this._permissions.values());
+ 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 a.origin.localeCompare(b.origin);
+ };
+ break;
+
+ case "statusCol":
+ sortFunc = (a, b) => {
+ return a.capabilityString.localeCompare(b.capabilityString);
+ };
+ break;
+ }
+
+ if (sortDirection === "descending") {
+ permissions.sort((a, b) => sortFunc(b, a));
+ } else {
+ permissions.sort(sortFunc);
+ }
+
+ let cols = this._list.querySelectorAll("treecol");
+ 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);
+
+ return permissions;
+ },
};
--- a/browser/components/preferences/sitePermissions.xul
+++ b/browser/components/preferences/sitePermissions.xul
@@ -28,29 +28,31 @@
<key key="&windowClose.key;" modifiers="accel" oncommand="window.close();"/>
</keyset>
<vbox class="contentPane largeDialogContainer" flex="1">
<description id="permissionsText" control="url"/>
<separator class="thin"/>
<hbox align="start">
<textbox id="searchBox" flex="1" placeholder="&searchbox.placeholder;"
- type="search" oncommand="gSitePermissionsManager.filterPermissionsList();"/>
+ type="search" oncommand="gSitePermissionsManager.buildPermissionsList();"/>
</hbox>
<separator class="thin"/>
<richlistbox id="permissionsBox" selected="false"
hidecolumnpicker="true" flex="1"
onkeypress="gSitePermissionsManager.onPermissionKeyPress(event);"
onselect="gSitePermissionsManager.onPermissionSelect();">
<listheader>
<treecol id="siteCol" label="&treehead.sitename2.label;" flex="3"
- data-field-name="origin" persist="width" width="50"/>
+ persist="width" width="50"
+ onclick="gSitePermissionsManager.buildPermissionsList(event.target)"/>
<splitter class="tree-splitter"/>
<treecol id="statusCol" label="&treehead.status.label;" flex="1"
- data-field-name="capability" persist="width" width="50"/>
+ persist="width" width="50" data-isCurrentSortCol="true"
+ onclick="gSitePermissionsManager.buildPermissionsList(event.target);"/>
</listheader>
</richlistbox>
</vbox>
<vbox>
<hbox class="actionButtons" align="left" flex="1">
<button id="removePermission" disabled="true"
accesskey="&removepermission2.accesskey;"
icon="remove" label="&removepermission2.label;"