Bug 1348223 - Part 2 - Move SiteDataManager.jsm to components and improve functionality for getting and removing by host. r=florian
This commit is in preparation of using SiteDataManager in the page info
window to display site data information for a individual hosts.
MozReview-Commit-ID: 3YmUZInvoAT
--- a/browser/components/preferences/moz.build
+++ b/browser/components/preferences/moz.build
@@ -16,14 +16,10 @@ BROWSER_CHROME_MANIFESTS += [
for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
DEFINES[var] = CONFIG[var]
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk3', 'cocoa'):
DEFINES['HAVE_SHELL_SERVICE'] = 1
JAR_MANIFESTS += ['jar.mn']
-EXTRA_JS_MODULES += [
- 'SiteDataManager.jsm'
-]
-
with Files('**'):
BUG_COMPONENT = ('Firefox', 'Preferences')
--- a/browser/components/preferences/siteDataSettings.js
+++ b/browser/components/preferences/siteDataSettings.js
@@ -224,32 +224,19 @@ let gSiteDataSettings = {
if (removals.length > 0) {
if (this._sites.length == removals.length) {
allowed = SiteDataManager.promptSiteDataRemoval(window);
if (allowed) {
SiteDataManager.removeAll();
}
} else {
- let args = {
- hosts: removals,
- allowed: false
- };
- let features = "centerscreen,chrome,modal,resizable=no";
- window.openDialog("chrome://browser/content/preferences/siteDataRemoveSelected.xul", "", features, args);
- allowed = args.allowed;
+ allowed = SiteDataManager.promptSiteDataRemoval(window, removals);
if (allowed) {
- try {
- SiteDataManager.remove(removals);
- } catch (e) {
- // Hit error, maybe remove unknown site.
- // Let's print out the error, then proceed to close this settings dialog.
- // When we next open again we will once more get sites from the SiteDataManager and refresh the list.
- Cu.reportError(e);
- }
+ SiteDataManager.remove(removals).catch(Cu.reportError);
}
}
}
// If the user cancelled the confirm dialog keep the site data window open,
// they can still press cancel again to exit.
if (allowed) {
this.close();
rename from browser/components/preferences/SiteDataManager.jsm
rename to browser/modules/SiteDataManager.jsm
--- a/browser/components/preferences/SiteDataManager.jsm
+++ b/browser/modules/SiteDataManager.jsm
@@ -49,17 +49,17 @@ var SiteDataManager = {
// Clear old data and requests first
this._sites.clear();
this._getAllCookies();
await this._getQuotaUsage();
this._updateAppCache();
Services.obs.notifyObservers(null, "sitedatamanager:sites-updated");
},
- _getBaseDomainFromHost(host) {
+ getBaseDomainFromHost(host) {
let result = host;
try {
result = Services.eTLD.getBaseDomainFromHost(host);
} catch (e) {
if (e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS) {
// For these 2 expected errors, just take the host as the result.
// - NS_ERROR_HOST_IS_IP_ADDRESS: the host is in ipv4/ipv6.
@@ -71,17 +71,17 @@ var SiteDataManager = {
}
return result;
},
_getOrInsertSite(host) {
let site = this._sites.get(host);
if (!site) {
site = {
- baseDomain: this._getBaseDomainFromHost(host),
+ baseDomain: this.getBaseDomainFromHost(host),
cookies: [],
persisted: false,
quotaUsage: 0,
lastAccessed: 0,
principals: [],
appCacheList: [],
};
this._sites.set(host, site);
@@ -217,20 +217,38 @@ var SiteDataManager = {
usage += cache.usage;
}
usage += site.quotaUsage;
}
return usage;
});
},
- getSites() {
+ /**
+ * Gets all sites that are currently storing site data.
+ *
+ * The list is not automatically up-to-date.
+ * You need to call SiteDataManager.updateSites() before you
+ * can use this method for the first time (and whenever you want
+ * to get an updated set of list.)
+ *
+ * @param {String} [optional] baseDomain - if specified, it will
+ * only return data for sites with
+ * the specified base domain.
+ *
+ * @returns a Promise that resolves with the list of all sites.
+ */
+ getSites(baseDomain) {
return this._getQuotaUsagePromise.then(() => {
let list = [];
for (let [host, site] of this._sites) {
+ if (baseDomain && site.baseDomain != baseDomain) {
+ continue;
+ }
+
let usage = site.quotaUsage;
for (let cache of site.appCacheList) {
usage += cache.usage;
}
list.push({
baseDomain: site.baseDomain,
cookies: site.cookies,
host,
@@ -316,17 +334,28 @@ var SiteDataManager = {
// Sites are grouped and removed by host so we unregister service workers by the same host as well
if (sites.has(sw.principal.URI.host)) {
promises.push(this._unregisterServiceWorker(sw));
}
}
return Promise.all(promises);
},
- remove(hosts) {
+ /**
+ * Removes all site data for the specified list of hosts.
+ *
+ * @param {Array} a list of hosts to match for removal.
+ * @returns a Promise that resolves when data is removed and the site data
+ * manager has been updated.
+ */
+ async remove(hosts) {
+ // Make sure we have up-to-date information.
+ await this._getQuotaUsage();
+ this._updateAppCache();
+
let unknownHost = "";
let targetSites = new Map();
for (let host of hosts) {
let site = this._sites.get(host);
if (site) {
this._removePermission(site);
this._removeAppCache(site);
this._removeCookies(site);
@@ -334,40 +363,51 @@ var SiteDataManager = {
targetSites.set(host, site);
} else {
unknownHost = host;
break;
}
}
if (targetSites.size > 0) {
- this._removeServiceWorkersForSites(targetSites)
- .then(() => {
- let promises = [];
- for (let [, site] of targetSites) {
- promises.push(this._removeQuotaUsage(site));
- }
- return Promise.all(promises);
- })
- .then(() => this.updateSites());
+ await this._removeServiceWorkersForSites(targetSites);
+ let promises = [];
+ for (let [, site] of targetSites) {
+ promises.push(this._removeQuotaUsage(site));
+ }
+ await Promise.all(promises);
}
+
if (unknownHost) {
throw `SiteDataManager: removing unknown site of ${unknownHost}`;
}
+
+ return this.updateSites();
},
/**
* In the specified window, shows a prompt for removing
- * all site data, warning the user that this may log them
- * out of websites.
+ * all site data or the specified list of hosts, warning the
+ * user that this may log them out of websites.
*
* @param {mozIDOMWindowProxy} a parent DOM window to host the dialog.
+ * @param {Array} [optional] an array of host name strings that will be removed.
* @returns a boolean whether the user confirmed the prompt.
*/
- promptSiteDataRemoval(win) {
+ promptSiteDataRemoval(win, removals) {
+ if (removals) {
+ let args = {
+ hosts: removals,
+ allowed: false
+ };
+ let features = "centerscreen,chrome,modal,resizable=no";
+ win.openDialog("chrome://browser/content/preferences/siteDataRemoveSelected.xul", "", features, args);
+ return args.allowed;
+ }
+
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");
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -77,16 +77,19 @@ with Files("ProcessHangMonitor.jsm"):
BUG_COMPONENT = ("Core", "DOM: Content Processes")
with Files("ReaderParent.jsm"):
BUG_COMPONENT = ("Toolkit", "Reader Mode")
with Files("Sanitizer.jsm"):
BUG_COMPONENT = ("Firefox", "Preferences")
+with Files("SiteDataManager.jsm"):
+ BUG_COMPONENT = ("Firefox", "Preferences")
+
with Files("SitePermissions.jsm"):
BUG_COMPONENT = ("Firefox", "Site Identity and Permission Panels")
with Files("OpenInTabsUtils.jsm"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser")
with Files("ThemeVariableMap.jsm"):
BUG_COMPONENT = ("Toolkit", "WebExtensions: Themes")
@@ -150,16 +153,17 @@ EXTRA_JS_MODULES += [
'PingCentre.jsm',
'PluginContent.jsm',
'ProcessHangMonitor.jsm',
'ReaderParent.jsm',
'RecentWindow.jsm',
'RemotePrompt.jsm',
'Sanitizer.jsm',
'SchedulePressure.jsm',
+ 'SiteDataManager.jsm',
'SitePermissions.jsm',
'ThemeVariableMap.jsm',
'TransientPrefs.jsm',
'UpdateTopLevelContentWindowIDHelper.jsm',
'webrtcUI.jsm',
'ZoomUI.jsm',
]