Bug 1348252 - Disable buttons and display loading message in Site Data section while loading data, r=Gijs
MozReview-Commit-ID: 9EfG71hRoDe
--- a/browser/components/preferences/SiteDataManager.jsm
+++ b/browser/components/preferences/SiteDataManager.jsm
@@ -38,16 +38,18 @@ this.SiteDataManager = {
_updateQuotaPromise: null,
_updateDiskCachePromise: null,
_quotaUsageRequests: null,
updateSites() {
+ Services.obs.notifyObservers(null, "sitedatamanager:updating-sites", null);
+
// Clear old data and requests first
this._sites.clear();
this._cancelQuotaUpdate();
// Collect sites granted/rejected with the persistent-storage permission
let perm = null;
let status = null;
let e = Services.perms.enumerator;
--- a/browser/components/preferences/in-content-old/advanced.js
+++ b/browser/components/preferences/in-content-old/advanced.js
@@ -50,29 +50,33 @@ var gAdvancedPane = {
this.initSubmitHealthReport();
}
this.updateOnScreenKeyboardVisibility();
this.updateCacheSizeInputField();
this.updateActualCacheSize();
if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
Services.obs.addObserver(this, "sitedatamanager:sites-updated", false);
+ Services.obs.addObserver(this, "sitedatamanager:updating-sites", false);
let unload = () => {
window.removeEventListener("unload", unload);
Services.obs.removeObserver(this, "sitedatamanager:sites-updated");
+ Services.obs.removeObserver(this, "sitedatamanager:updating-sites");
};
window.addEventListener("unload", unload);
SiteDataManager.updateSites();
setEventListener("clearSiteDataButton", "command",
gAdvancedPane.clearSiteData);
setEventListener("siteDataSettings", "command",
gAdvancedPane.showSiteDataSettings);
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "storage-permissions";
document.getElementById("siteDataLearnMoreLink").setAttribute("href", url);
+ let siteDataGroup = document.getElementById("siteDataGroup");
+ siteDataGroup.hidden = false;
}
setEventListener("layers.acceleration.disabled", "change",
gAdvancedPane.updateHardwareAcceleration);
setEventListener("advancedPrefs", "select",
gAdvancedPane.tabSelectionChanged);
if (AppConstants.MOZ_TELEMETRY_REPORTING) {
setEventListener("submitHealthReportBox", "command",
@@ -353,26 +357,32 @@ var gAdvancedPane = {
showConnections() {
gSubDialog.open("chrome://browser/content/preferences/connection.xul");
},
showSiteDataSettings() {
gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
},
- updateTotalSiteDataSize() {
- SiteDataManager.getTotalUsage()
- .then(usage => {
- let size = DownloadUtils.convertByteUnits(usage);
- let prefStrBundle = document.getElementById("bundlePreferences");
- let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
- totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
- let siteDataGroup = document.getElementById("siteDataGroup");
- siteDataGroup.hidden = false;
- });
+ toggleSiteData(shouldShow) {
+ let clearButton = document.getElementById("clearSiteDataButton");
+ let settingsButton = document.getElementById("siteDataSettings");
+ clearButton.disabled = !shouldShow;
+ settingsButton.disabled = !shouldShow;
+ },
+
+ updateTotalDataSizeLabel(usage) {
+ let prefStrBundle = document.getElementById("bundlePreferences");
+ let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
+ if (usage < 0) {
+ totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize");
+ } else {
+ let size = DownloadUtils.convertByteUnits(usage);
+ totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
+ }
},
// Retrieves the amount of space currently used by disk cache
updateActualCacheSize() {
var actualSizeLabel = document.getElementById("actualDiskCacheSize");
var prefStrBundle = document.getElementById("bundlePreferences");
// Needs to root the observer since cache service keeps only a weak reference.
@@ -786,21 +796,27 @@ var gAdvancedPane = {
/**
* Displays a dialog from which the user can manage his security devices.
*/
showSecurityDevices() {
gSubDialog.open("chrome://pippki/content/device_manager.xul");
},
observe(aSubject, aTopic, aData) {
- if (AppConstants.MOZ_UPDATER) {
- switch (aTopic) {
- case "nsPref:changed":
- this.updateReadPrefs();
- break;
+ switch (aTopic) {
+ case "nsPref:changed":
+ this.updateReadPrefs();
+ break;
- case "sitedatamanager:sites-updated":
- this.updateTotalSiteDataSize();
- break;
- }
+ case "sitedatamanager:updating-sites":
+ // While updating, we want to disable this section and display loading message until updated
+ this.toggleSiteData(false);
+ this.updateTotalDataSizeLabel(-1);
+ break;
+
+ case "sitedatamanager:sites-updated":
+ this.toggleSiteData(true);
+ SiteDataManager.getTotalUsage()
+ .then(this.updateTotalDataSizeLabel.bind(this));
+ break;
}
},
};
--- a/browser/components/preferences/in-content-old/tests/browser_advanced_siteData.js
+++ b/browser/components/preferences/in-content-old/tests/browser_advanced_siteData.js
@@ -10,16 +10,17 @@ Cu.import("resource://gre/modules/XPCOMU
Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
const TEST_HOST = "example.com";
const TEST_ORIGIN = "http://" + TEST_HOST;
const TEST_BASE_URL = TEST_ORIGIN + "/browser/browser/components/preferences/in-content-old/tests/";
const REMOVE_DIALOG_URL = "chrome://browser/content/preferences/siteDataRemoveSelected.xul";
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
+const { DownloadUtils } = Cu.import("resource://gre/modules/DownloadUtils.jsm", {});
const { SiteDataManager } = Cu.import("resource:///modules/SiteDataManager.jsm", {});
const { OfflineAppCacheHelper } = Cu.import("resource:///modules/offlineAppCache.jsm", {});
const mockOfflineAppCacheHelper = {
clear: null,
originalClear: null,
@@ -220,16 +221,59 @@ function assertSitesListed(doc, origins)
registerCleanupFunction(function() {
delete window.sinon;
delete window.setImmediate;
delete window.clearImmediate;
mockOfflineAppCacheHelper.unregister();
});
+// Test buttons are disabled and loading message shown while updating sites
+add_task(function *() {
+ yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
+ let updatedPromise = promiseSitesUpdated();
+ yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
+ yield updatedPromise;
+
+ let doc = gBrowser.selectedBrowser.contentDocument;
+ let clearBtn = doc.getElementById("clearSiteDataButton");
+ let settingsButton = doc.getElementById("siteDataSettings");
+ let prefStrBundle = doc.getElementById("bundlePreferences");
+ let totalSiteDataSizeLabel = doc.getElementById("totalSiteDataSize");
+ is(clearBtn.disabled, false, "Should enable clear button after sites updated");
+ is(settingsButton.disabled, false, "Should enable settings button after sites updated");
+ yield SiteDataManager.getTotalUsage()
+ .then(usage => {
+ let actual = totalSiteDataSizeLabel.textContent;
+ let expected = prefStrBundle.getFormattedString(
+ "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
+ is(actual, expected, "Should show the right total site data size");
+ });
+
+ Services.obs.notifyObservers(null, "sitedatamanager:updating-sites", null);
+ is(clearBtn.disabled, true, "Should disable clear button while updating sites");
+ is(settingsButton.disabled, true, "Should disable settings button while updating sites");
+ let actual = totalSiteDataSizeLabel.textContent;
+ let expected = prefStrBundle.getString("loadingSiteDataSize");
+ is(actual, expected, "Should show the loading message while updating");
+
+ Services.obs.notifyObservers(null, "sitedatamanager:sites-updated", null);
+ is(clearBtn.disabled, false, "Should enable clear button after sites updated");
+ is(settingsButton.disabled, false, "Should enable settings button after sites updated");
+ yield SiteDataManager.getTotalUsage()
+ .then(usage => {
+ let actual = totalSiteDataSizeLabel.textContent;
+ let expected = prefStrBundle.getFormattedString(
+ "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
+ is(actual, expected, "Should show the right total site data size");
+ });
+
+ yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
add_task(function* () {
yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
addPersistentStoragePerm(TEST_ORIGIN);
yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_BASE_URL + "site_data_test.html");
yield waitForEvent(gBrowser.selectedBrowser.contentWindow, "test-indexedDB-done");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -262,19 +262,21 @@ var gPrivacyPane = {
.style.height = bundlePrefs.getString("offlineAppsList.height");
let offlineGroup = document.getElementById("offlineGroup");
offlineGroup.hidden = false;
offlineGroup.removeAttribute("data-hidden-from-search");
}
if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
Services.obs.addObserver(this, "sitedatamanager:sites-updated", false);
+ Services.obs.addObserver(this, "sitedatamanager:updating-sites", false);
let unload = () => {
window.removeEventListener("unload", unload);
Services.obs.removeObserver(this, "sitedatamanager:sites-updated");
+ Services.obs.removeObserver(this, "sitedatamanager:updating-sites");
};
window.addEventListener("unload", unload);
SiteDataManager.updateSites();
setEventListener("clearSiteDataButton", "command",
gPrivacyPane.clearSiteData);
setEventListener("siteDataSettings", "command",
gPrivacyPane.showSiteDataSettings);
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "storage-permissions";
@@ -1175,24 +1177,32 @@ var gPrivacyPane = {
removeButton.setAttribute("disabled", "true");
}
},
showSiteDataSettings() {
gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
},
- updateTotalSiteDataSize() {
- SiteDataManager.getTotalUsage()
- .then(usage => {
- let size = DownloadUtils.convertByteUnits(usage);
- let prefStrBundle = document.getElementById("bundlePreferences");
- let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
- totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
- });
+ toggleSiteData(shouldShow) {
+ let clearButton = document.getElementById("clearSiteDataButton");
+ let settingsButton = document.getElementById("siteDataSettings");
+ clearButton.disabled = !shouldShow;
+ settingsButton.disabled = !shouldShow;
+ },
+
+ updateTotalDataSizeLabel(usage) {
+ let prefStrBundle = document.getElementById("bundlePreferences");
+ let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
+ if (usage < 0) {
+ totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize");
+ } else {
+ let size = DownloadUtils.convertByteUnits(usage);
+ totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
+ }
},
// Retrieves the amount of space currently used by disk cache
updateActualCacheSize() {
var actualSizeLabel = document.getElementById("actualDiskCacheSize");
var prefStrBundle = document.getElementById("bundlePreferences");
// Needs to root the observer since cache service keeps only a weak reference.
@@ -1442,14 +1452,22 @@ var gPrivacyPane = {
list.removeChild(item);
gPrivacyPane.offlineAppSelected();
this.updateActualAppCacheSize();
},
// Methods for Offline Apps (AppCache) end
observe(aSubject, aTopic, aData) {
switch (aTopic) {
+ case "sitedatamanager:updating-sites":
+ // While updating, we want to disable this section and display loading message until updated
+ this.toggleSiteData(false);
+ this.updateTotalDataSizeLabel(-1);
+ break;
+
case "sitedatamanager:sites-updated":
- this.updateTotalSiteDataSize();
+ this.toggleSiteData(true);
+ SiteDataManager.getTotalUsage()
+ .then(this.updateTotalDataSizeLabel.bind(this));
break;
}
},
};
--- a/browser/components/preferences/in-content/tests/browser_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_siteData.js
@@ -10,16 +10,17 @@ Cu.import("resource://gre/modules/XPCOMU
Services.scriptloader.loadSubScript("resource://testing-common/sinon-1.16.1.js");
const TEST_HOST = "example.com";
const TEST_ORIGIN = "http://" + TEST_HOST;
const TEST_BASE_URL = TEST_ORIGIN + "/browser/browser/components/preferences/in-content/tests/";
const REMOVE_DIALOG_URL = "chrome://browser/content/preferences/siteDataRemoveSelected.xul";
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
+const { DownloadUtils } = Cu.import("resource://gre/modules/DownloadUtils.jsm", {});
const { SiteDataManager } = Cu.import("resource:///modules/SiteDataManager.jsm", {});
const { OfflineAppCacheHelper } = Cu.import("resource:///modules/offlineAppCache.jsm", {});
const mockOfflineAppCacheHelper = {
clear: null,
originalClear: null,
@@ -161,16 +162,59 @@ function promiseCookiesCleared() {
registerCleanupFunction(function() {
delete window.sinon;
delete window.setImmediate;
delete window.clearImmediate;
mockOfflineAppCacheHelper.unregister();
});
+// Test buttons are disabled and loading message shown while updating sites
+add_task(function *() {
+ yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
+
+ let updatedPromise = promiseSiteDataManagerSitesUpdated();
+ yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
+ yield updatedPromise;
+ let doc = gBrowser.selectedBrowser.contentDocument;
+ let clearBtn = doc.getElementById("clearSiteDataButton");
+ let settingsButton = doc.getElementById("siteDataSettings");
+ let prefStrBundle = doc.getElementById("bundlePreferences");
+ let totalSiteDataSizeLabel = doc.getElementById("totalSiteDataSize");
+ is(clearBtn.disabled, false, "Should enable clear button after sites updated");
+ is(settingsButton.disabled, false, "Should enable settings button after sites updated");
+ yield SiteDataManager.getTotalUsage()
+ .then(usage => {
+ let actual = totalSiteDataSizeLabel.textContent;
+ let expected = prefStrBundle.getFormattedString(
+ "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
+ is(actual, expected, "Should show the right total site data size");
+ });
+
+ Services.obs.notifyObservers(null, "sitedatamanager:updating-sites", null);
+ is(clearBtn.disabled, true, "Should disable clear button while updating sites");
+ is(settingsButton.disabled, true, "Should disable settings button while updating sites");
+ let actual = totalSiteDataSizeLabel.textContent;
+ let expected = prefStrBundle.getString("loadingSiteDataSize");
+ is(actual, expected, "Should show the loading message while updating");
+
+ Services.obs.notifyObservers(null, "sitedatamanager:sites-updated", null);
+ is(clearBtn.disabled, false, "Should enable clear button after sites updated");
+ is(settingsButton.disabled, false, "Should enable settings button after sites updated");
+ yield SiteDataManager.getTotalUsage()
+ .then(usage => {
+ let actual = totalSiteDataSizeLabel.textContent;
+ let expected = prefStrBundle.getFormattedString(
+ "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
+ is(actual, expected, "Should show the right total site data size");
+ });
+
+ yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
+
add_task(function* () {
yield SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
addPersistentStoragePerm(TEST_ORIGIN);
yield BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_BASE_URL + "site_data_test.html");
yield waitForEvent(gBrowser.selectedBrowser.contentWindow, "test-indexedDB-done");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
--- a/browser/locales/en-US/chrome/browser/preferences-old/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences-old/preferences.properties
@@ -179,16 +179,17 @@ actualDiskCacheSizeCalculated=Calculating web content cache size…
actualAppCacheSize=Your application cache is currently using %1$S %2$S of disk space
####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
important=Important
default=Default
siteUsage=%1$S %2$S
# LOCALIZATION NOTE (removeAllSiteData, removeAllSiteDataShown):
# removeAllSiteData and removeAllSiteDataShown are both used on the same one button,
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -179,16 +179,17 @@ actualDiskCacheSizeCalculated=Calculating web content cache size…
actualAppCacheSize=Your application cache is currently using %1$S %2$S of disk space
####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
important=Important
default=Default
siteUsage=%1$S %2$S
# LOCALIZATION NOTE (removeAllSiteData, removeAllSiteDataShown):
# removeAllSiteData and removeAllSiteDataShown are both used on the same one button,