diff --git a/browser/components/preferences/in-content/tests/browser_advanced_siteData.js b/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
index 99e8743744b6..4a80d35aa481 100644
--- a/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_advanced_siteData.js
@@ -12,6 +12,7 @@ Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js")
const TEST_HOST = "example.com";
const TEST_ORIGIN = "http://" + TEST_HOST;
const TEST_BASE_URL = TEST_ORIGIN + "/browser/browser/components/preferences/in-content/tests/";
+const REMOVE_DIALOG_URL = "chrome://browser/content/preferences/siteDataRemoveSelected.xul";
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
const { SiteDataManager } = Cu.import("resource:///modules/SiteDataManager.jsm", {});
@@ -187,6 +188,22 @@ function promiseCookiesCleared() {
});
}
+function assertSitesListed(doc, origins) {
+ let frameDoc = doc.getElementById("dialogFrame").contentDocument;
+ let removeBtn = frameDoc.getElementById("removeSelected");
+ let removeAllBtn = frameDoc.getElementById("removeAll");
+ let sitesList = frameDoc.getElementById("sitesList");
+ let totalSitesNumber = sitesList.getElementsByTagName("richlistitem").length;
+ is(totalSitesNumber, origins.length, "Should list the right sites number");
+ origins.forEach(origin => {
+ let site = sitesList.querySelector(`richlistitem[data-origin="${origin}"]`);
+ let host = site.getAttribute("host");
+ ok(origin.includes(host), `Should list the site of ${origin}`);
+ });
+ is(removeBtn.disabled, false, "Should enable the removeSelected button");
+ is(removeAllBtn.disabled, false, "Should enable the removeAllBtn button");
+}
+
registerCleanupFunction(function() {
delete window.sinon;
delete window.setImmediate;
@@ -370,28 +387,18 @@ add_task(function* () {
searchBox.value = "xyz";
searchBox.doCommand();
- assertSitesListed(mockOrigins.filter(o => o.includes("xyz")));
+ assertSitesListed(doc, mockOrigins.filter(o => o.includes("xyz")));
searchBox.value = "bar";
searchBox.doCommand();
- assertSitesListed(mockOrigins.filter(o => o.includes("bar")));
+ assertSitesListed(doc, mockOrigins.filter(o => o.includes("bar")));
searchBox.value = "";
searchBox.doCommand();
- assertSitesListed(mockOrigins);
+ assertSitesListed(doc, mockOrigins);
mockSiteDataManager.unregister();
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
- function assertSitesListed(origins) {
- let sitesList = frameDoc.getElementById("sitesList");
- let totalSitesNumber = sitesList.getElementsByTagName("richlistitem").length;
- is(totalSitesNumber, origins.length, "Should list the right sites number");
- origins.forEach(origin => {
- let site = sitesList.querySelector(`richlistitem[data-origin="${origin}"]`);
- ok(site instanceof XULElement, `Should list the site of ${origin}`);
- });
- }
});
// Test selecting and removing all sites one by one
@@ -478,19 +485,23 @@ add_task(function* () {
function assertAllSitesListed() {
frameDoc = doc.getElementById("dialogFrame").contentDocument;
let removeBtn = frameDoc.getElementById("removeSelected");
+ let removeAllBtn = frameDoc.getElementById("removeAll");
let sitesList = frameDoc.getElementById("sitesList");
let sites = sitesList.getElementsByTagName("richlistitem");
is(sites.length, fakeOrigins.length, "Should list all sites");
is(removeBtn.disabled, false, "Should enable the removeSelected button");
+ is(removeAllBtn.disabled, false, "Should enable the removeAllBtn button");
}
function assertAllSitesNotListed() {
frameDoc = doc.getElementById("dialogFrame").contentDocument;
let removeBtn = frameDoc.getElementById("removeSelected");
+ let removeAllBtn = frameDoc.getElementById("removeAll");
let sitesList = frameDoc.getElementById("sitesList");
let sites = sitesList.getElementsByTagName("richlistitem");
is(sites.length, 0, "Should not list all sites");
is(removeBtn.disabled, true, "Should disable the removeSelected button");
+ is(removeAllBtn.disabled, true, "Should disable the removeAllBtn button");
}
});
@@ -512,7 +523,6 @@ add_task(function* () {
yield updatePromise;
yield openSettingsDialog();
- const removeDialogURL = "chrome://browser/content/preferences/siteDataRemoveSelected.xul";
let doc = gBrowser.selectedBrowser.contentDocument;
let frameDoc = null;
let saveBtn = null;
@@ -521,44 +531,44 @@ add_task(function* () {
let settingsDialogClosePromise = null;
// Test the initial state
- assertSitesListed(fakeOrigins);
+ assertSitesListed(doc, fakeOrigins);
// Test the "Cancel" button
settingsDialogClosePromise = promiseSettingsDialogClose();
frameDoc = doc.getElementById("dialogFrame").contentDocument;
cancelBtn = frameDoc.getElementById("cancel");
removeSelectedSite(fakeOrigins.slice(0, 4));
- assertSitesListed(fakeOrigins.slice(4));
+ assertSitesListed(doc, fakeOrigins.slice(4));
cancelBtn.doCommand();
yield settingsDialogClosePromise;
yield openSettingsDialog();
- assertSitesListed(fakeOrigins);
+ assertSitesListed(doc, fakeOrigins);
// Test the "Save Changes" button but canceling save
- removeDialogOpenPromise = promiseWindowDialogOpen("cancel", removeDialogURL);
+ removeDialogOpenPromise = promiseWindowDialogOpen("cancel", REMOVE_DIALOG_URL);
settingsDialogClosePromise = promiseSettingsDialogClose();
frameDoc = doc.getElementById("dialogFrame").contentDocument;
saveBtn = frameDoc.getElementById("save");
removeSelectedSite(fakeOrigins.slice(0, 4));
- assertSitesListed(fakeOrigins.slice(4));
+ assertSitesListed(doc, fakeOrigins.slice(4));
saveBtn.doCommand();
yield removeDialogOpenPromise;
yield settingsDialogClosePromise;
yield openSettingsDialog();
- assertSitesListed(fakeOrigins);
+ assertSitesListed(doc, fakeOrigins);
// Test the "Save Changes" button and accepting save
- removeDialogOpenPromise = promiseWindowDialogOpen("accept", removeDialogURL);
+ removeDialogOpenPromise = promiseWindowDialogOpen("accept", REMOVE_DIALOG_URL);
settingsDialogClosePromise = promiseSettingsDialogClose();
frameDoc = doc.getElementById("dialogFrame").contentDocument;
saveBtn = frameDoc.getElementById("save");
removeSelectedSite(fakeOrigins.slice(0, 4));
- assertSitesListed(fakeOrigins.slice(4));
+ assertSitesListed(doc, fakeOrigins.slice(4));
saveBtn.doCommand();
yield removeDialogOpenPromise;
yield settingsDialogClosePromise;
yield openSettingsDialog();
- assertSitesListed(fakeOrigins.slice(4));
+ assertSitesListed(doc, fakeOrigins.slice(4));
// Always clean up the fake origins
fakeOrigins.forEach(origin => removePersistentStoragePerm(origin));
@@ -578,17 +588,48 @@ add_task(function* () {
}
});
}
-
- function assertSitesListed(origins) {
- frameDoc = doc.getElementById("dialogFrame").contentDocument;
- let removeBtn = frameDoc.getElementById("removeSelected");
- let sitesList = frameDoc.getElementById("sitesList");
- let totalSitesNumber = sitesList.getElementsByTagName("richlistitem").length;
- is(totalSitesNumber, origins.length, "Should list the right sites number");
- origins.forEach(origin => {
- let site = sitesList.querySelector(`richlistitem[data-origin="${origin}"]`);
- ok(!!site, `Should list the site of ${origin}`);
- });
- is(removeBtn.disabled, false, "Should enable the removeSelected button");
- }
+});
+
+add_task(function* () {
+ yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
+ let fakeOrigins = [
+ "https://news.foo.com/",
+ "https://books.foo.com/",
+ "https://mails.bar.com/",
+ "https://account.bar.com/",
+ "https://videos.xyz.com/",
+ "https://shopping.xyz.com/"
+ ];
+ fakeOrigins.forEach(origin => addPersistentStoragePerm(origin));
+
+ let updatePromise = promiseSitesUpdated();
+ yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
+ yield updatePromise;
+ yield openSettingsDialog();
+
+ // Search "foo" to only list foo.com sites
+ let doc = gBrowser.selectedBrowser.contentDocument;
+ let frameDoc = doc.getElementById("dialogFrame").contentDocument;
+ let searchBox = frameDoc.getElementById("searchBox");
+ searchBox.value = "foo";
+ searchBox.doCommand();
+ assertSitesListed(doc, fakeOrigins.slice(0, 2));
+
+ // Test only removing all visible sites listed
+ updatePromise = promiseSitesUpdated();
+ let acceptRemovePromise = promiseWindowDialogOpen("accept", REMOVE_DIALOG_URL);
+ let settingsDialogClosePromise = promiseSettingsDialogClose();
+ let removeAllBtn = frameDoc.getElementById("removeAll");
+ let saveBtn = frameDoc.getElementById("save");
+ removeAllBtn.doCommand();
+ saveBtn.doCommand();
+ yield acceptRemovePromise;
+ yield settingsDialogClosePromise;
+ yield updatePromise;
+ yield openSettingsDialog();
+ assertSitesListed(doc, fakeOrigins.slice(2));
+
+ // Always clean up the fake origins
+ fakeOrigins.forEach(origin => removePersistentStoragePerm(origin));
+ yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
});
diff --git a/browser/components/preferences/siteDataSettings.js b/browser/components/preferences/siteDataSettings.js
index 084d35bf49b2..a8d88d101005 100644
--- a/browser/components/preferences/siteDataSettings.js
+++ b/browser/components/preferences/siteDataSettings.js
@@ -40,23 +40,25 @@ let gSiteDataSettings = {
let sortCol = document.getElementById("hostCol");
this._sortSites(this._sites, sortCol);
this._buildSitesList(this._sites);
- this._updateButtonsState();
Services.obs.notifyObservers(null, "sitedata-settings-init", null);
});
setEventListener("hostCol", "click", this.onClickTreeCol);
setEventListener("usageCol", "click", this.onClickTreeCol);
setEventListener("statusCol", "click", this.onClickTreeCol);
- setEventListener("searchBox", "command", this.onCommandSearch);
setEventListener("cancel", "command", this.close);
setEventListener("save", "command", this.saveChanges);
- setEventListener("removeSelected", "command", this.removeSelected);
+ setEventListener("searchBox", "command", this.onCommandSearch);
+ setEventListener("removeAll", "command", this.onClickRemoveAll);
+ setEventListener("removeSelected", "command", this.onClickRemoveSelected);
},
_updateButtonsState() {
let items = this._list.getElementsByTagName("richlistitem");
- let removeBtn = document.getElementById("removeSelected");
- removeBtn.disabled = !(items.length > 0);
+ let removeSelectedBtn = document.getElementById("removeSelected");
+ let removeAllBtn = document.getElementById("removeAll");
+ removeSelectedBtn.disabled = items.length == 0;
+ removeAllBtn.disabled = removeSelectedBtn.disabled;
},
/**
@@ -136,30 +138,22 @@ let gSiteDataSettings = {
item.setAttribute("usage", prefStrBundle.getFormattedString("siteUsage", size));
this._list.appendChild(item);
}
+ this._updateButtonsState();
},
- onClickTreeCol(e) {
- this._sortSites(this._sites, e.target);
- this._buildSitesList(this._sites);
- },
-
- onCommandSearch() {
- this._buildSitesList(this._sites);
- },
-
- removeSelected() {
- let selected = this._list.selectedItem;
- if (selected) {
- let origin = selected.getAttribute("data-origin");
+ _removeSiteItems(items) {
+ for (let i = items.length - 1; i >= 0; --i) {
+ let item = items[i];
+ let origin = item.getAttribute("data-origin");
for (let site of this._sites) {
if (site.uri.spec === origin) {
site.userAction = "remove";
break;
}
}
- this._list.removeChild(selected);
- this._updateButtonsState();
+ item.remove();
}
+ this._updateButtonsState();
},
saveChanges() {
@@ -235,5 +229,28 @@ let gSiteDataSettings = {
close() {
window.close();
+ },
+
+ onClickTreeCol(e) {
+ this._sortSites(this._sites, e.target);
+ this._buildSitesList(this._sites);
+ },
+
+ onCommandSearch() {
+ this._buildSitesList(this._sites);
+ },
+
+ onClickRemoveSelected() {
+ let selected = this._list.selectedItem;
+ if (selected) {
+ this._removeSiteItems([selected]);
+ }
+ },
+
+ onClickRemoveAll() {
+ let siteItems = this._list.getElementsByTagName("richlistitem");
+ if (siteItems.length > 0) {
+ this._removeSiteItems(siteItems);
+ }
}
};
diff --git a/browser/components/preferences/siteDataSettings.xul b/browser/components/preferences/siteDataSettings.xul
index 6dd4904c7bbc..096201cefc57 100644
--- a/browser/components/preferences/siteDataSettings.xul
+++ b/browser/components/preferences/siteDataSettings.xul
@@ -44,6 +44,7 @@
+
diff --git a/browser/locales/en-US/chrome/browser/preferences/siteDataSettings.dtd b/browser/locales/en-US/chrome/browser/preferences/siteDataSettings.dtd
index 0fa896259aa2..fc2b0561bca0 100644
--- a/browser/locales/en-US/chrome/browser/preferences/siteDataSettings.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/siteDataSettings.dtd
@@ -11,6 +11,8 @@
+
+