зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1323391 - Sort sites listed in Settings of Site Data, r=Gijs
MozReview-Commit-ID: ExHvd6OJNF7 --HG-- extra : rebase_source : b2db5d0fffebdd83ed118c1e09004404d4d6345a
This commit is contained in:
Родитель
737a826174
Коммит
0f6622a9e9
|
@ -33,6 +33,58 @@ const mockOfflineAppCacheHelper = {
|
|||
}
|
||||
};
|
||||
|
||||
const mockSiteDataManager = {
|
||||
sites: new Map([
|
||||
[
|
||||
"https://shopping.xyz.com/",
|
||||
{
|
||||
usage: 102400,
|
||||
host: "shopping.xyz.com",
|
||||
status: Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
}
|
||||
],
|
||||
[
|
||||
"https://music.bar.com/",
|
||||
{
|
||||
usage: 10240,
|
||||
host: "music.bar.com",
|
||||
status: Ci.nsIPermissionManager.ALLOW_ACTION
|
||||
}
|
||||
],
|
||||
[
|
||||
"https://news.foo.com/",
|
||||
{
|
||||
usage: 1024,
|
||||
host: "news.foo.com",
|
||||
status: Ci.nsIPermissionManager.DENY_ACTION
|
||||
}
|
||||
]
|
||||
]),
|
||||
|
||||
_originalGetSites: null,
|
||||
|
||||
getSites() {
|
||||
let list = [];
|
||||
this.sites.forEach((data, origin) => {
|
||||
list.push({
|
||||
usage: data.usage,
|
||||
status: data.status,
|
||||
uri: NetUtil.newURI(origin)
|
||||
});
|
||||
});
|
||||
return Promise.resolve(list);
|
||||
},
|
||||
|
||||
register() {
|
||||
this._originalGetSites = SiteDataManager.getSites;
|
||||
SiteDataManager.getSites = this.getSites.bind(this);
|
||||
},
|
||||
|
||||
unregister() {
|
||||
SiteDataManager.getSites = this._originalGetSites;
|
||||
}
|
||||
};
|
||||
|
||||
function addPersistentStoragePerm(origin) {
|
||||
let uri = NetUtil.newURI(origin);
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
|
||||
|
@ -91,7 +143,7 @@ add_task(function* () {
|
|||
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_BASE_URL + "site_data_test.html");
|
||||
yield waitForEvent(gBrowser.selectedBrowser.contentWindow, "test-indexedDB-done");
|
||||
gBrowser.removeCurrentTab();
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
|
||||
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
|
||||
|
||||
|
@ -151,5 +203,104 @@ add_task(function* () {
|
|||
is(totalUsage, 0, "The total usage should be removed");
|
||||
// Test accepting "Clear All Data" ends
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
|
||||
|
||||
mockSiteDataManager.register();
|
||||
let updatePromise = promiseSitesUpdated();
|
||||
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
|
||||
yield updatePromise;
|
||||
|
||||
// Open the siteDataSettings subdialog
|
||||
let doc = gBrowser.selectedBrowser.contentDocument;
|
||||
let settingsBtn = doc.getElementById("siteDataSettings");
|
||||
let dialogOverlay = doc.getElementById("dialogOverlay");
|
||||
let dialogPromise = promiseLoadSubDialog("chrome://browser/content/preferences/siteDataSettings.xul");
|
||||
settingsBtn.doCommand();
|
||||
yield dialogPromise;
|
||||
is(dialogOverlay.style.visibility, "visible", "The dialog should be visible");
|
||||
|
||||
let dialogFrame = doc.getElementById("dialogFrame");
|
||||
let frameDoc = dialogFrame.contentDocument;
|
||||
let hostCol = frameDoc.getElementById("hostCol");
|
||||
let usageCol = frameDoc.getElementById("usageCol");
|
||||
let statusCol = frameDoc.getElementById("statusCol");
|
||||
let sitesList = frameDoc.getElementById("sitesList");
|
||||
let mockSites = mockSiteDataManager.sites;
|
||||
|
||||
// Test default sorting
|
||||
assertSortByHost("ascending");
|
||||
|
||||
// Test sorting on the host column
|
||||
hostCol.click();
|
||||
assertSortByHost("descending");
|
||||
hostCol.click();
|
||||
assertSortByHost("ascending");
|
||||
|
||||
// Test sorting on the permission status column
|
||||
statusCol.click();
|
||||
assertSortByStatus("ascending");
|
||||
statusCol.click();
|
||||
assertSortByStatus("descending");
|
||||
|
||||
// Test sorting on the usage column
|
||||
usageCol.click();
|
||||
assertSortByUsage("ascending");
|
||||
usageCol.click();
|
||||
assertSortByUsage("descending");
|
||||
|
||||
mockSiteDataManager.unregister();
|
||||
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
|
||||
function assertSortByHost(order) {
|
||||
let siteItems = sitesList.getElementsByTagName("richlistitem");
|
||||
for (let i = 0; i < siteItems.length - 1; ++i) {
|
||||
let aOrigin = siteItems[i].getAttribute("data-origin");
|
||||
let bOrigin = siteItems[i + 1].getAttribute("data-origin");
|
||||
let a = mockSites.get(aOrigin);
|
||||
let b = mockSites.get(bOrigin);
|
||||
let result = a.host.localeCompare(b.host);
|
||||
if (order == "ascending") {
|
||||
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by host");
|
||||
} else {
|
||||
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by host");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertSortByStatus(order) {
|
||||
let siteItems = sitesList.getElementsByTagName("richlistitem");
|
||||
for (let i = 0; i < siteItems.length - 1; ++i) {
|
||||
let aOrigin = siteItems[i].getAttribute("data-origin");
|
||||
let bOrigin = siteItems[i + 1].getAttribute("data-origin");
|
||||
let a = mockSites.get(aOrigin);
|
||||
let b = mockSites.get(bOrigin);
|
||||
let result = a.status - b.status;
|
||||
if (order == "ascending") {
|
||||
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by permission status");
|
||||
} else {
|
||||
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by permission status");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertSortByUsage(order) {
|
||||
let siteItems = sitesList.getElementsByTagName("richlistitem");
|
||||
for (let i = 0; i < siteItems.length - 1; ++i) {
|
||||
let aOrigin = siteItems[i].getAttribute("data-origin");
|
||||
let bOrigin = siteItems[i + 1].getAttribute("data-origin");
|
||||
let a = mockSites.get(aOrigin);
|
||||
let b = mockSites.get(bOrigin);
|
||||
let result = a.usage - b.usage;
|
||||
if (order == "ascending") {
|
||||
Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by usage");
|
||||
} else {
|
||||
Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by usage");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -25,27 +25,68 @@ let gSiteDataSettings = {
|
|||
_list: null,
|
||||
|
||||
init() {
|
||||
function setEventListener(id, eventType, callback) {
|
||||
document.getElementById(id)
|
||||
.addEventListener(eventType, callback.bind(gSiteDataSettings));
|
||||
}
|
||||
|
||||
this._list = document.getElementById("sitesList");
|
||||
SiteDataManager.getSites().then(sites => {
|
||||
this._sites = sites;
|
||||
this._sortSites(this._sites, "decending");
|
||||
let sortCol = document.getElementById("hostCol");
|
||||
this._sortSites(this._sites, sortCol);
|
||||
this._buildSitesList(this._sites);
|
||||
});
|
||||
|
||||
setEventListener("hostCol", "click", this.onClickTreeCol);
|
||||
setEventListener("usageCol", "click", this.onClickTreeCol);
|
||||
setEventListener("statusCol", "click", this.onClickTreeCol);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort sites by usages
|
||||
*
|
||||
* @param sites {Array}
|
||||
* @param order {String} indicate to sort in the "decending" or "ascending" order
|
||||
* @param col {XULElement} the <treecol> being sorted on
|
||||
*/
|
||||
_sortSites(sites, order) {
|
||||
sites.sort((a, b) => {
|
||||
if (order === "ascending") {
|
||||
return a.usage - b.usage;
|
||||
}
|
||||
return b.usage - a.usage;
|
||||
_sortSites(sites, col) {
|
||||
let isCurrentSortCol = col.getAttribute("data-isCurrentSortCol")
|
||||
let sortDirection = col.getAttribute("data-last-sortDirection") || "ascending";
|
||||
if (isCurrentSortCol) {
|
||||
// Sort on the current column, flip the sorting direction
|
||||
sortDirection = sortDirection === "ascending" ? "descending" : "ascending";
|
||||
}
|
||||
|
||||
let sortFunc = null;
|
||||
switch (col.id) {
|
||||
case "hostCol":
|
||||
sortFunc = (a, b) => {
|
||||
let aHost = a.uri.host.toLowerCase();
|
||||
let bHost = b.uri.host.toLowerCase();
|
||||
return aHost.localeCompare(bHost);
|
||||
}
|
||||
break;
|
||||
|
||||
case "statusCol":
|
||||
sortFunc = (a, b) => a.status - b.status;
|
||||
break;
|
||||
|
||||
case "usageCol":
|
||||
sortFunc = (a, b) => a.usage - b.usage;
|
||||
break;
|
||||
}
|
||||
if (sortDirection === "descending") {
|
||||
sites.sort((a, b) => sortFunc(b, a));
|
||||
} else {
|
||||
sites.sort(sortFunc);
|
||||
}
|
||||
|
||||
let cols = this._list.querySelectorAll("treecol");
|
||||
cols.forEach(c => {
|
||||
c.removeAttribute("sortDirection");
|
||||
c.removeAttribute("data-isCurrentSortCol");
|
||||
});
|
||||
col.setAttribute("data-isCurrentSortCol", true);
|
||||
col.setAttribute("sortDirection", sortDirection);
|
||||
col.setAttribute("data-last-sortDirection", sortDirection);
|
||||
},
|
||||
|
||||
_buildSitesList(sites) {
|
||||
|
@ -65,5 +106,10 @@ let gSiteDataSettings = {
|
|||
item.setAttribute("usage", prefStrBundle.getFormattedString("siteUsage", size));
|
||||
this._list.appendChild(item);
|
||||
}
|
||||
},
|
||||
|
||||
onClickTreeCol(e) {
|
||||
this._sortSites(this._sites, e.target);
|
||||
this._buildSitesList(this._sites);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
<richlistbox id="sitesList" orient="vertical" flex="1">
|
||||
<listheader>
|
||||
<treecol flex="4" width="50" label="&hostCol.label;"/>
|
||||
<treecol flex="2" width="50" label="&statusCol.label;"/>
|
||||
<treecol flex="1" width="50" label="&usageCol.label;"/>
|
||||
<treecol flex="4" width="50" label="&hostCol.label;" id="hostCol"/>
|
||||
<treecol flex="2" width="50" label="&statusCol.label;" id="statusCol"/>
|
||||
<treecol flex="1" width="50" label="&usageCol.label;" id="usageCol"/>
|
||||
</listheader>
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
|
|
Загрузка…
Ссылка в новой задаче