Bug 1348223 - Part 2 - Move SiteDataManager.jsm to components and improve functionality for getting and removing by host. r=florian
authorJohann Hofmann <jhofmann@mozilla.com>
Thu, 22 Mar 2018 17:48:13 +0100
changeset 411976 e4715e0cc3fe86fbda7a41dcabee48d77859cdf4
parent 411975 7390643a0bc13ca3a59ef2d9da51c0b0850c9662
child 411977 8dec8e29532e8e5759fef70bf43d4468740c7347
push id33778
push userapavel@mozilla.com
push dateFri, 06 Apr 2018 09:57:38 +0000
treeherdermozilla-central@46a5fc19bd7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs1348223
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
browser/components/preferences/SiteDataManager.jsm
browser/components/preferences/moz.build
browser/components/preferences/siteDataSettings.js
browser/modules/SiteDataManager.jsm
browser/modules/moz.build
--- 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',
 ]