Bug 1422163 - Part 1 - Make a new confirm dialog for clearing all site data that allows you to clear cache. r=Gijs
MozReview-Commit-ID: G9xQXlfT9Ay
--- a/browser/components/preferences/SiteDataManager.jsm
+++ b/browser/components/preferences/SiteDataManager.jsm
@@ -12,42 +12,94 @@ ChromeUtils.defineModuleGetter(this, "Co
XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager",
"@mozilla.org/serviceworkers/manager;1",
"nsIServiceWorkerManager");
this.EXPORTED_SYMBOLS = [
"SiteDataManager"
];
+XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
+ return Services.strings.createBundle("chrome://browser/locale/siteData.properties");
+});
+
+XPCOMUtils.defineLazyGetter(this, "gBrandBundle", function() {
+ return Services.strings.createBundle("chrome://branding/locale/brand.properties");
+});
+
this.SiteDataManager = {
_qms: Services.qms,
_appCache: Cc["@mozilla.org/network/application-cache-service;1"].getService(Ci.nsIApplicationCacheService),
// A Map of sites and their disk usage according to Quota Manager and appcache
// Key is host (group sites based on host across scheme, port, origin atttributes).
// Value is one object holding:
// - principals: instances of nsIPrincipal.
// - persisted: the persistent-storage status.
// - quotaUsage: the usage of indexedDB and localStorage.
// - appCacheList: an array of app cache; instances of nsIApplicationCache
_sites: new Map(),
+ _getCacheSizeObserver: null,
+
+ _getCacheSizePromise: null,
+
_getQuotaUsagePromise: null,
_quotaUsageRequest: null,
async updateSites() {
Services.obs.notifyObservers(null, "sitedatamanager:updating-sites");
await this._getQuotaUsage();
this._updateAppCache();
Services.obs.notifyObservers(null, "sitedatamanager:sites-updated");
},
+ /**
+ * Retrieves the amount of space currently used by disk cache.
+ *
+ * You can use DownloadUtils.convertByteUnits to convert this to
+ * a user-understandable size/unit combination.
+ *
+ * @returns a Promise that resolves with the cache size on disk in bytes.
+ */
+ getCacheSize() {
+ if (this._getCacheSizePromise) {
+ return this._getCacheSizePromise;
+ }
+
+ this._getCacheSizePromise = new Promise((resolve, reject) => {
+ // Needs to root the observer since cache service keeps only a weak reference.
+ this._getCacheSizeObserver = {
+ onNetworkCacheDiskConsumption: consumption => {
+ resolve(consumption);
+ this._getCacheSizePromise = null;
+ this._getCacheSizeObserver = null;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([
+ Components.interfaces.nsICacheStorageConsumptionObserver,
+ Components.interfaces.nsISupportsWeakReference
+ ])
+ };
+
+ try {
+ Services.cache2.asyncGetDiskConsumption(this._getCacheSizeObserver);
+ } catch (e) {
+ reject(e);
+ this._getCacheSizePromise = null;
+ this._getCacheSizeObserver = null;
+ }
+ });
+
+ return this._getCacheSizePromise;
+ },
+
_getQuotaUsage() {
// Clear old data and requests first
this._sites.clear();
this._cancelGetQuotaUsage();
this._getQuotaUsagePromise = new Promise(resolve => {
let onUsageResult = request => {
if (request.resultCode == Cr.NS_OK) {
let items = request.result;
@@ -273,18 +325,67 @@ this.SiteDataManager = {
})
.then(() => this.updateSites());
}
if (unknownHost) {
throw `SiteDataManager: removing unknown site of ${unknownHost}`;
}
},
+ /**
+ * In the specified window, shows a prompt for removing
+ * all site data, warning the user that this may log them
+ * out of websites.
+ *
+ * @param {mozIDOMWindowProxy} a parent DOM window to host the dialog.
+ * @returns a boolean whether the user confirmed the prompt.
+ */
+ promptSiteDataRemoval(win) {
+ let brandName = gBrandBundle.GetStringFromName("brandShortName");
+ let flags =
+ Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
+ Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
+ Services.prompt.BUTTON_POS_0_DEFAULT;
+ let title = gStringBundle.GetStringFromName("clearSiteDataPromptTitle");
+ let text = gStringBundle.formatStringFromName("clearSiteDataPromptText", [brandName], 1);
+ let btn0Label = gStringBundle.GetStringFromName("clearSiteDataNow");
+
+ let result = Services.prompt.confirmEx(
+ win, title, text, flags, btn0Label, null, null, null, {});
+ return result == 0;
+ },
+
+ /**
+ * Clears all site data and cache
+ *
+ * @returns a Promise that resolves when the data is cleared.
+ */
async removeAll() {
+ this.removeCache();
+ return this.removeSiteData();
+ },
+
+ /**
+ * Clears the entire network cache.
+ */
+ removeCache() {
Services.cache2.clear();
+ },
+
+ /**
+ * Clears all site data, which currently means
+ * - Cookies
+ * - AppCache
+ * - ServiceWorkers
+ * - Quota Managed Storage
+ * - persistent-storage permissions
+ *
+ * @returns a Promise that resolves with the cache size on disk in bytes
+ */
+ async removeSiteData() {
Services.cookies.removeAll();
OfflineAppCacheHelper.clear();
// Iterate through the service workers and remove them.
let promises = [];
let serviceWorkers = serviceWorkerManager.getAllRegistrations();
for (let i = 0; i < serviceWorkers.length; i++) {
let sw = serviceWorkers.queryElementAt(i, Ci.nsIServiceWorkerRegistrationInfo);
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/clearSiteData.css
@@ -0,0 +1,19 @@
+/* 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/. */
+
+.options-container {
+ background-color: var(--in-content-box-background);
+ border: 1px solid var(--in-content-box-border-color);
+ border-radius: 2px;
+ color: var(--in-content-text-color);
+ padding: 0.5em;
+}
+
+.option {
+ padding-bottom: 16px;
+}
+
+.option-description {
+ color: #737373;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/clearSiteData.js
@@ -0,0 +1,78 @@
+/* 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/. */
+
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
+ChromeUtils.import("resource:///modules/SiteDataManager.jsm");
+
+var gClearSiteDataDialog = {
+ _clearSiteDataCheckbox: null,
+ _clearCacheCheckbox: null,
+ _clearButton: null,
+
+ init() {
+ this._bundle = Services.strings
+ .createBundle("chrome://browser/locale/preferences/clearSiteData.properties");
+
+ SiteDataManager.getTotalUsage().then(bytes => {
+ // Size is an array of amount and unit, e.g. [20, "MB"].
+ let size = DownloadUtils.convertByteUnits(bytes);
+ document.getElementById("clearSiteDataLabel").value =
+ this._bundle.formatStringFromName("clearSiteDataWithEstimates.label", size, 2);
+ });
+ SiteDataManager.getCacheSize().then(bytes => {
+ // Size is an array of amount and unit, e.g. [20, "MB"].
+ let size = DownloadUtils.convertByteUnits(bytes);
+ document.getElementById("clearCacheLabel").value =
+ this._bundle.formatStringFromName("clearCacheWithEstimates.label", size, 2);
+ });
+
+ this._clearButton = document.getElementById("clearButton");
+ this._cancelButton = document.getElementById("cancelButton");
+ this._clearSiteDataCheckbox = document.getElementById("clearSiteData");
+ this._clearCacheCheckbox = document.getElementById("clearCache");
+
+ window.addEventListener("keypress", this.onWindowKeyPress);
+
+ this._cancelButton.addEventListener("command", window.close);
+ this._clearButton.addEventListener("command", () => this.onClear());
+
+ this._clearSiteDataCheckbox.addEventListener("command", e => this.onCheckboxCommand(e));
+ this._clearCacheCheckbox.addEventListener("command", e => this.onCheckboxCommand(e));
+ },
+
+ onWindowKeyPress(event) {
+ if (event.keyCode == KeyEvent.DOM_VK_ESCAPE)
+ window.close();
+ },
+
+ onCheckboxCommand(event) {
+ this._clearButton.disabled =
+ !(this._clearSiteDataCheckbox.checked || this._clearCacheCheckbox.checked);
+ },
+
+ onClear() {
+ let allowed = true;
+
+ if (this._clearSiteDataCheckbox.checked) {
+ allowed = SiteDataManager.promptSiteDataRemoval(window);
+ if (allowed) {
+ SiteDataManager.removeSiteData();
+ }
+ }
+
+ if (this._clearCacheCheckbox.checked && allowed) {
+ SiteDataManager.removeCache();
+ // Update cache UI in about:preferences
+ window.opener.gPrivacyPane.updateActualCacheSize();
+ }
+
+ if (allowed) {
+ window.close();
+ }
+ },
+};
+
+window.addEventListener("load", () => gClearSiteDataDialog.init());
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/clearSiteData.xul
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+
+<!-- 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/. -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/preferences/clearSiteData.css" type="text/css"?>
+
+<!DOCTYPE dialog [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+ <!ENTITY % clearSiteDataDTD SYSTEM "chrome://browser/locale/preferences/clearSiteData.dtd">
+ %brandDTD;
+ %clearSiteDataDTD;
+]>
+
+<window id="ClearSiteDataDialog" class="windowDialog"
+ windowtype="Browser:ClearSiteData"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ style="width: &window.width;;"
+ title="&window.title;"
+ persist="screenX screenY width height">
+
+ <script src="chrome://browser/content/preferences/clearSiteData.js"/>
+
+ <stringbundle id="bundlePreferences"
+ src="chrome://browser/locale/preferences/preferences.properties"/>
+
+ <keyset>
+ <key key="&windowClose.key;" modifiers="accel" oncommand="window.close();"/>
+ </keyset>
+
+ <vbox class="contentPane largeDialogContainer" flex="1">
+ <description control="url">&window.description;</description>
+ <separator class="thin"/>
+ <vbox class="options-container">
+ <hbox class="option">
+ <checkbox id="clearSiteData" checked="true"
+ accesskey="&clearSiteData.accesskey;" />
+ <vbox>
+ <label for="clearSiteData" id="clearSiteDataLabel" value="&clearSiteData.label;" />
+ <description class="option-description">&clearSiteData.description;</description>
+ </vbox>
+ </hbox>
+ <hbox class="option">
+ <checkbox id="clearCache" checked="true"
+ accesskey="&clearCache.accesskey;" />
+ <vbox>
+ <label for="clearCache" id="clearCacheLabel" value="&clearCache.label;" />
+ <description class="option-description">&clearCache.description;</description>
+ </vbox>
+ </hbox>
+ </vbox>
+ </vbox>
+ <vbox>
+ <hbox class="actionButtons" align="right" flex="1">
+ <button id="cancelButton" icon="close"
+ label="&button.cancel.label;" accesskey="&button.cancel.accesskey;" />
+ <button id="clearButton" icon="save"
+ label="&button.clear.label;" accesskey="&button.clear.accesskey;"/>
+ </hbox>
+ </vbox>
+</window>
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -1514,30 +1514,17 @@ var gPrivacyPane = {
let cacheSizeElem = document.getElementById("cacheSize");
let cachePref = Preferences.get("browser.cache.disk.capacity");
// Converts the cache size as specified in UI (in MB) to KB.
let intValue = parseInt(cacheSizeElem.value, 10);
cachePref.value = isNaN(intValue) ? 0 : intValue * 1024;
},
clearSiteData() {
- let flags =
- Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
- Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
- Services.prompt.BUTTON_POS_0_DEFAULT;
- let prefStrBundle = document.getElementById("bundlePreferences");
- let title = prefStrBundle.getString("clearSiteDataPromptTitle");
- let text = prefStrBundle.getString("clearSiteDataPromptText");
- let btn0Label = prefStrBundle.getString("clearSiteDataNow");
-
- let result = Services.prompt.confirmEx(
- window, title, text, flags, btn0Label, null, null, null, {});
- if (result == 0) {
- SiteDataManager.removeAll();
- }
+ gSubDialog.open("chrome://browser/content/preferences/clearSiteData.xul");
},
initDataCollection() {
this._setupLearnMoreLink("toolkit.datacollection.infoURL",
"dataCollectionPrivacyNotice");
},
initSubmitCrashes() {
--- a/browser/components/preferences/jar.mn
+++ b/browser/components/preferences/jar.mn
@@ -2,16 +2,19 @@
# 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/.
browser.jar:
content/browser/preferences/applicationManager.xul
content/browser/preferences/applicationManager.js
content/browser/preferences/blocklists.xul
content/browser/preferences/blocklists.js
+ content/browser/preferences/clearSiteData.css
+ content/browser/preferences/clearSiteData.js
+ content/browser/preferences/clearSiteData.xul
* content/browser/preferences/colors.xul
content/browser/preferences/colors.js
* content/browser/preferences/cookies.xul
content/browser/preferences/cookies.js
* content/browser/preferences/connection.xul
content/browser/preferences/connection.js
content/browser/preferences/fonts.xul
content/browser/preferences/fonts.js
--- a/browser/components/preferences/siteDataSettings.js
+++ b/browser/components/preferences/siteDataSettings.js
@@ -203,28 +203,17 @@ let gSiteDataSettings = {
removals.add(site.host);
return false;
}
return true;
});
if (removals.size > 0) {
if (this._sites.length == 0) {
- // User selects all sites so equivalent to clearing all data
- let flags =
- Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
- Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
- Services.prompt.BUTTON_POS_0_DEFAULT;
- let prefStrBundle = document.getElementById("bundlePreferences");
- let title = prefStrBundle.getString("clearSiteDataPromptTitle");
- let text = prefStrBundle.getString("clearSiteDataPromptText");
- let btn0Label = prefStrBundle.getString("clearSiteDataNow");
- let result = Services.prompt.confirmEx(window, title, text, flags, btn0Label, null, null, null, {});
- allowed = result == 0;
- if (allowed) {
+ if (SiteDataManager.promptSiteDataRemoval(window)) {
SiteDataManager.removeAll();
}
} else {
// User only removes partial sites.
// We will remove cookies based on base domain, say, user selects "news.foo.com" to remove.
// The cookies under "music.foo.com" will be removed together.
// We have to prompt user about this action.
let hostsTable = new Map();
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/preferences/clearSiteData.dtd
@@ -0,0 +1,22 @@
+<!-- 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/. -->
+
+<!ENTITY window.title "Clear Data">
+<!ENTITY window.width "35em">
+
+<!ENTITY window.description "Clearing all cookies and site data stored by &brandShortName; may sign you out of websites and remove offline web content. Clearing cache data will not affect your logins.">
+<!ENTITY windowClose.key "w">
+
+<!ENTITY clearSiteData.label "Cookies and Site Data">
+<!ENTITY clearSiteData.accesskey "S">
+<!ENTITY clearSiteData.description "You may get signed out of websites if cleared">
+
+<!ENTITY clearCache.label "Cached Web Content">
+<!ENTITY clearCache.accesskey "W">
+<!ENTITY clearCache.description "Will require websites to reload images and data">
+
+<!ENTITY button.cancel.label "Cancel">
+<!ENTITY button.cancel.accesskey "C">
+<!ENTITY button.clear.label "Clear">
+<!ENTITY button.clear.accesskey "l">
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/preferences/clearSiteData.properties
@@ -0,0 +1,12 @@
+# 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/.
+
+# LOCALIZATION NOTE (clearSiteDataWithEstimates.label, clearCacheWithEstimates.label):
+# The parameters in parentheses in these strings describe disk usage
+# in the format (size unit), e.g. "Cookies and Site Data (24 KB)"
+# %1$S = size
+# %2$S = unit (MB, KB, etc.)
+clearSiteDataWithEstimates.label = Cookies and Site Data (%1$S %2$S)
+clearCacheWithEstimates.label = Cached Web Content (%1$S %2$S)
+
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -183,19 +183,16 @@ actualAppCacheSize=Your application cach
####Preferences::Advanced::Network
#LOCALIZATION NOTE: The next string is for the total usage of site data.
# e.g., "The total usage is currently using 200 MB"
# %1$S = size
# %2$S = unit (MB, KB, etc.)
totalSiteDataSize=Your stored site data is currently using %1$S %2$S of disk space
loadingSiteDataSize=Calculating site data size…
-clearSiteDataPromptTitle=Clear all cookies and site data
-clearSiteDataPromptText=Selecting ‘Clear Now’ will clear all cookies and site data stored by Firefox. This may sign you out of websites and remove offline web content.
-clearSiteDataNow=Clear Now
persistent=Persistent
siteUsage=%1$S %2$S
acceptRemove=Remove
# LOCALIZATION NOTE (siteDataSettings2.description): %S = brandShortName
siteDataSettings2.description=The following websites store site data on your computer. %S keeps data from websites with persistent storage until you delete it, and deletes data from websites with non-persistent storage as space is needed.
# LOCALIZATION NOTE (removeAllSiteData, removeAllSiteDataShown):
# removeAllSiteData and removeAllSiteDataShown are both used on the same one button,
# never displayed together and can share the same accesskey.
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/siteData.properties
@@ -0,0 +1,8 @@
+# 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/.
+
+clearSiteDataPromptTitle=Clear all cookies and site data
+# LOCALIZATION NOTE (clearSiteDataPromptText): %S = brandShortName
+clearSiteDataPromptText=Selecting ‘Clear Now’ will clear all cookies and site data stored by %S. This may sign you out of websites and remove offline web content.
+clearSiteDataNow=Clear Now
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -33,16 +33,17 @@
locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
locale/browser/newTab.properties (%chrome/browser/newTab.properties)
locale/browser/pageInfo.dtd (%chrome/browser/pageInfo.dtd)
locale/browser/pageInfo.properties (%chrome/browser/pageInfo.properties)
locale/browser/quitDialog.properties (%chrome/browser/quitDialog.properties)
locale/browser/safeMode.dtd (%chrome/browser/safeMode.dtd)
locale/browser/sanitize.dtd (%chrome/browser/sanitize.dtd)
locale/browser/search.properties (%chrome/browser/search.properties)
+ locale/browser/siteData.properties (%chrome/browser/siteData.properties)
locale/browser/sitePermissions.properties (%chrome/browser/sitePermissions.properties)
locale/browser/engineManager.properties (%chrome/browser/engineManager.properties)
locale/browser/setDesktopBackground.dtd (%chrome/browser/setDesktopBackground.dtd)
locale/browser/shellservice.properties (%chrome/browser/shellservice.properties)
locale/browser/tabbrowser.properties (%chrome/browser/tabbrowser.properties)
locale/browser/taskbar.properties (%chrome/browser/taskbar.properties)
locale/browser/translation.dtd (%chrome/browser/translation.dtd)
locale/browser/translation.properties (%chrome/browser/translation.properties)
@@ -60,16 +61,18 @@
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
locale/browser/migration/migration.properties (%chrome/browser/migration/migration.properties)
locale/browser/preferences/advanced.dtd (%chrome/browser/preferences/advanced.dtd)
locale/browser/preferences/applicationManager.dtd (%chrome/browser/preferences/applicationManager.dtd)
locale/browser/preferences/applicationManager.properties (%chrome/browser/preferences/applicationManager.properties)
locale/browser/preferences/applications.dtd (%chrome/browser/preferences/applications.dtd)
locale/browser/preferences/blocklists.dtd (%chrome/browser/preferences/blocklists.dtd)
+ locale/browser/preferences/clearSiteData.dtd (%chrome/browser/preferences/clearSiteData.dtd)
+ locale/browser/preferences/clearSiteData.properties (%chrome/browser/preferences/clearSiteData.properties)
locale/browser/preferences/colors.dtd (%chrome/browser/preferences/colors.dtd)
locale/browser/preferences/connection.dtd (%chrome/browser/preferences/connection.dtd)
locale/browser/preferences/containers.dtd (%chrome/browser/preferences/containers.dtd)
locale/browser/preferences/containers.properties (%chrome/browser/preferences/containers.properties)
locale/browser/preferences/content.dtd (%chrome/browser/preferences/content.dtd)
locale/browser/preferences/cookies.dtd (%chrome/browser/preferences/cookies.dtd)
locale/browser/preferences/fonts.dtd (%chrome/browser/preferences/fonts.dtd)
locale/browser/preferences/languages.dtd (%chrome/browser/preferences/languages.dtd)