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
--- 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 & 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