Bug 1348223 - Part 3 - Show and clear all site data in page info (not just cookies). r=florian
authorJohann Hofmann <jhofmann@mozilla.com>
Thu, 22 Mar 2018 17:26:52 +0100
changeset 411977 8dec8e29532e8e5759fef70bf43d4468740c7347
parent 411976 e4715e0cc3fe86fbda7a41dcabee48d77859cdf4
child 411978 0f1aa8fea3708404f66b24f958afc9dcd15dbfe2
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 3 - Show and clear all site data in page info (not just cookies). r=florian This commit changes the way that the page info security section works to not only consider cookies when answering the question "Is this website storing information about me?". The associated button used to open the cookie manager. We would like to reduce the storage management UI surface (in the interest of having one great central location for managing storage), so that button was replaced with a simple "clear data" button that clears site data for all origins of the base domain of the site. Clearing for the entire range of that base domain is a trade off between (implicit) user privacy and the risk that the user accidentally deletes too much data. I prefer to choose increased privacy. MozReview-Commit-ID: BUgxJHBeFcQ
browser/base/content/pageinfo/pageInfo.xul
browser/base/content/pageinfo/security.js
browser/locales/en-US/chrome/browser/pageInfo.dtd
browser/locales/en-US/chrome/browser/pageInfo.properties
--- a/browser/base/content/pageinfo/pageInfo.xul
+++ b/browser/base/content/pageinfo/pageInfo.xul
@@ -335,74 +335,71 @@
         <spacer flex="1"/>
         <!-- Cert button -->
         <hbox id="security-view-cert-box" pack="end">
           <button id="security-view-cert" label="&securityView.certView;"
                   accesskey="&securityView.accesskey;"
                   oncommand="security.viewCert();"/>
         </hbox>
       </groupbox>
-      
+
       <!-- Privacy & History section -->
       <groupbox id="security-privacy-groupbox" flex="1">
         <caption id="security-privacy" label="&securityView.privacy.header;" />
         <grid id="security-privacy-grid">
           <columns>
             <column flex="1"/>
             <column flex="1"/>
           </columns>
           <rows id="security-privacy-rows">
             <!-- History -->
             <row id="security-privacy-history-row">
               <label id="security-privacy-history-label"
                            control="security-privacy-history-value"
                            class="fieldLabel">&securityView.privacy.history;</label>
-              <textbox id="security-privacy-history-value"
-                       class="fieldValue"
-                       value="&securityView.unknown;"
-                       readonly="true"/>
+              <label id="security-privacy-history-value"
+                     class="fieldValue"
+                     value="&securityView.unknown;"/>
             </row>
-            <!-- Cookies -->
-            <row id="security-privacy-cookies-row">
-              <label id="security-privacy-cookies-label"
-                           control="security-privacy-cookies-value"
-                           class="fieldLabel">&securityView.privacy.cookies;</label>
-              <hbox id="security-privacy-cookies-box" align="center">
-                <textbox id="security-privacy-cookies-value"
-                         class="fieldValue"
-                         value="&securityView.unknown;"
-                         flex="1"
-                         readonly="true"/>
-                <button id="security-view-cookies"
-                        label="&securityView.privacy.viewCookies;"
-                        accesskey="&securityView.privacy.viewCookies.accessKey;"
-                        oncommand="security.viewCookies();"/>
+            <!-- Site Data & Cookies -->
+            <row id="security-privacy-sitedata-row">
+              <label id="security-privacy-sitedata-label"
+                           control="security-privacy-sitedata-value"
+                           class="fieldLabel">&securityView.privacy.siteData;</label>
+              <hbox id="security-privacy-sitedata-box" align="center">
+                <label id="security-privacy-sitedata-value"
+                       class="fieldValue"
+                       flex="1">&securityView.unknown;</label>
+                <button id="security-clear-sitedata"
+                        disabled="true"
+                        label="&securityView.privacy.clearSiteData;"
+                        accesskey="&securityView.privacy.clearSiteData.accessKey;"
+                        oncommand="security.clearSiteData();"/>
               </hbox>
             </row>
             <!-- Passwords -->
             <row id="security-privacy-passwords-row">
               <label id="security-privacy-passwords-label"
                             control="security-privacy-passwords-value"
                             class="fieldLabel">&securityView.privacy.passwords;</label>
               <hbox id="security-privacy-passwords-box" align="center">
-                <textbox id="security-privacy-passwords-value"
-                         class="fieldValue"
-                         value="&securityView.unknown;"
-                         flex="1"
-                         readonly="true"/>
+                <label id="security-privacy-passwords-value"
+                       class="fieldValue"
+                       value="&securityView.unknown;"
+                       flex="1"/>
                 <button id="security-view-password"
                         label="&securityView.privacy.viewPasswords;"
                         accesskey="&securityView.privacy.viewPasswords.accessKey;"
                         oncommand="security.viewPasswords();"/>
               </hbox>
             </row>
           </rows>
         </grid>
       </groupbox>
-      
+
       <!-- Technical Details section -->
       <groupbox id="security-technical-groupbox" flex="1">
         <caption id="security-technical" label="&securityView.technical.header;" />
         <vbox id="security-technical-box" flex="1">
           <label id="security-technical-shortform" class="fieldValue"/>
           <description id="security-technical-longform1" class="fieldLabel"/>
           <description id="security-technical-longform2" class="fieldLabel"/>
           <description id="security-technical-certificate-transparency" class="fieldLabel"/>
--- a/browser/base/content/pageinfo/security.js
+++ b/browser/base/content/pageinfo/security.js
@@ -1,14 +1,16 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* 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/BrowserUtils.jsm");
+ChromeUtils.import("resource:///modules/SiteDataManager.jsm");
+ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
 
 /* import-globals-from pageInfo.js */
 
 ChromeUtils.defineModuleGetter(this, "LoginHelper",
                                "resource://gre/modules/LoginHelper.jsm");
 ChromeUtils.defineModuleGetter(this, "PluralForm",
                                "resource://gre/modules/PluralForm.jsm");
 
@@ -128,36 +130,61 @@ var security = {
 
   // Find the secureBrowserUI object (if present)
   _getSecurityUI() {
     if (window.opener.gBrowser)
       return window.opener.gBrowser.securityUI;
     return null;
   },
 
-  /**
-   * Open the cookie manager window
-   */
-  viewCookies() {
-    var win = Services.wm.getMostRecentWindow("Browser:Cookies");
+  async _updateSiteDataInfo() {
+    // Save site data info for deleting.
+    this.siteData = await SiteDataManager.getSites(
+      SiteDataManager.getBaseDomainFromHost(this.uri.host));
 
-    var eTLD;
-    try {
-      eTLD = Services.eTLD.getBaseDomain(this.uri);
-    } catch (e) {
-      // getBaseDomain will fail if the host is an IP address or is empty
-      eTLD = this.uri.asciiHost;
+    let pageInfoBundle = document.getElementById("pageinfobundle");
+    let clearSiteDataButton = document.getElementById("security-clear-sitedata");
+    let siteDataLabel = document.getElementById("security-privacy-sitedata-value");
+
+    if (!this.siteData.length) {
+      let noStr = pageInfoBundle.getString("securitySiteDataNo");
+      siteDataLabel.textContent = noStr;
+      clearSiteDataButton.setAttribute("disabled", "true");
+      return;
     }
 
-    if (win) {
-      win.gCookiesWindow.setFilter(eTLD);
-      win.focus();
-    } else
-      window.openDialog("chrome://browser/content/preferences/cookies.xul",
-                        "Browser:Cookies", "", {filterString: eTLD});
+    let usageText;
+    let usage = this.siteData.reduce((acc, site) => acc + site.usage, 0);
+    if (usage > 0) {
+      let size = DownloadUtils.convertByteUnits(usage);
+      let hasCookies = this.siteData.some(site => site.cookies.length > 0);
+      if (hasCookies) {
+        usageText = pageInfoBundle.getFormattedString("securitySiteDataCookies", size);
+      } else {
+        usageText = pageInfoBundle.getFormattedString("securitySiteDataOnly", size);
+      }
+    } else {
+      // We're storing cookies, else the list would have been empty.
+      usageText = pageInfoBundle.getString("securitySiteDataCookiesOnly");
+    }
+
+    clearSiteDataButton.removeAttribute("disabled");
+    siteDataLabel.textContent = usageText;
+  },
+
+  /**
+   * Clear Site Data and Cookies
+   */
+  clearSiteData() {
+    if (this.siteData && this.siteData.length) {
+      let hosts = this.siteData.map(site => site.host);
+      if (SiteDataManager.promptSiteDataRemoval(window, hosts)) {
+        SiteDataManager.remove(hosts).then(() => this._updateSiteDataInfo());
+      }
+    }
   },
 
   /**
    * Open the login manager window
    */
   viewPasswords() {
     LoginHelper.openPasswordManager(window, this._getSecurityInfo().hostName);
   },
@@ -220,18 +247,23 @@ function securityOnLoad(uri, windowInfo)
     viewCert.collapsed = false;
   } else
     viewCert.collapsed = true;
 
   /* Set Privacy & History section text */
   var yesStr = pageInfoBundle.getString("yes");
   var noStr = pageInfoBundle.getString("no");
 
-  setText("security-privacy-cookies-value",
-          hostHasCookies(uri) ? yesStr : noStr);
+  // Only show quota usage data for websites, not internal sites.
+  if (uri.scheme == "http" || uri.scheme == "https") {
+    SiteDataManager.updateSites().then(() => security._updateSiteDataInfo());
+  } else {
+    document.getElementById("security-privacy-sitedata-row").hidden = true;
+  }
+
   setText("security-privacy-passwords-value",
           realmHasPasswords(uri) ? yesStr : noStr);
 
   var visitCount = previousVisitCount(info.hostName);
 
   let visitCountStr = visitCount > 0
     ? PluralForm.get(visitCount, pageInfoBundle.getString("securityVisitsNumber"))
         .replace("#1", visitCount.toLocaleString())
@@ -302,23 +334,16 @@ function viewCertHelper(parent, cert) {
   if (!cert)
     return;
 
   var cd = Cc[CERTIFICATEDIALOGS_CONTRACTID].getService(nsICertificateDialogs);
   cd.viewCert(parent, cert);
 }
 
 /**
- * Return true iff we have cookies for uri
- */
-function hostHasCookies(uri) {
-  return Services.cookies.countCookiesFromHost(uri.asciiHost) > 0;
-}
-
-/**
  * Return true iff realm (proto://host:port) (extracted from uri) has
  * saved passwords
  */
 function realmHasPasswords(uri) {
   return Services.logins.countLogins(uri.prePath, "", "") > 0;
 }
 
 /**
--- a/browser/locales/en-US/chrome/browser/pageInfo.dtd
+++ b/browser/locales/en-US/chrome/browser/pageInfo.dtd
@@ -61,18 +61,18 @@
 <!ENTITY  securityView.identity.header   "Website Identity">
 <!ENTITY  securityView.identity.owner    "Owner:">
 <!ENTITY  securityView.identity.domain   "Website:">
 <!ENTITY  securityView.identity.verifier "Verified by:">
 <!ENTITY  securityView.identity.validity "Expires on:">
 
 <!ENTITY  securityView.privacy.header                   "Privacy &amp; History">
 <!ENTITY  securityView.privacy.history                  "Have I visited this website prior to today?">
-<!ENTITY  securityView.privacy.cookies                  "Is this website storing information (cookies) on my computer?">
-<!ENTITY  securityView.privacy.viewCookies              "View Cookies">
-<!ENTITY  securityView.privacy.viewCookies.accessKey    "k">
+<!ENTITY  securityView.privacy.siteData                 "Is this website storing information on my computer?">
+<!ENTITY  securityView.privacy.clearSiteData            "Clear Cookies and Site Data">
+<!ENTITY  securityView.privacy.clearSiteData.accessKey  "C">
 <!ENTITY  securityView.privacy.passwords                "Have I saved any passwords for this website?">
 <!ENTITY  securityView.privacy.viewPasswords            "View Saved Passwords">
 <!ENTITY  securityView.privacy.viewPasswords.accessKey  "w">
 
 <!ENTITY  securityView.technical.header                 "Technical Details">
 
 <!ENTITY  helpButton.label                              "Help">
--- a/browser/locales/en-US/chrome/browser/pageInfo.properties
+++ b/browser/locales/en-US/chrome/browser/pageInfo.properties
@@ -48,16 +48,21 @@ securityNoOwner=This website does not su
 # LOCALIZATION NOTE (securityVisitsNumber):
 # Semi-colon list of plural forms.
 # See: https://developer.mozilla.org/en/docs/Localization_and_Plurals
 # #1 is the number of visits and can be used in all plural forms as needed, e.g.
 # for '1': 'Yes, #1 time'
 securityVisitsNumber=Yes, once;Yes, #1 times
 securityNoVisits=No
 
-# LOCALIZATION NOTE: The next string is for the disk usage of the
-# database
-#   e.g. indexedDBUsage : "50.23 MB"
+# LOCALIZATION NOTE(securitySiteDataCookies,securitySiteDataOnly): This is for site data disk usage.
+#   It confirms that a website is indeed using this much space.
+#   e.g. Is this website storing site data? "Yes, 50.23 MB"
 #   %1$S = size (in bytes or megabytes, ...)
 #   %2$S = unit of measure (bytes, KB, MB, ...)
-indexedDBUsage=This website is using %1$S %2$S
+securitySiteDataCookies=Yes, cookies and %1$S %2$S of site data
+securitySiteDataOnly=Yes, %1$S %2$S of site data
+# LOCALIZATION NOTE(securitySiteDataCookiesOnly,securitySiteDataNo):
+# This is for site data and cookies usage. It answers the question "Is this website storing cookies and/or site data?"
+securitySiteDataCookiesOnly=Yes, cookies
+securitySiteDataNo=No
 
 permissions.useDefault=Use Default