Bug 566746 - various fixes to sanitize(). r=mak

This commit is contained in:
Mark Hammond
2013-05-09 09:08:07 +10:00
parent 04991d24e3
commit 65d594f18f
5 changed files with 49 additions and 27 deletions

View File

@@ -8,6 +8,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"); "resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
"resource://gre/modules/FormHistory.jsm"); "resource://gre/modules/FormHistory.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/commonjs/sdk/core/promise.js");
function Sanitizer() {} function Sanitizer() {}
Sanitizer.prototype = { Sanitizer.prototype = {
@@ -38,15 +40,18 @@ Sanitizer.prototype = {
}, },
/** /**
* Deletes privacy sensitive data in a batch, according to user preferences. Calls * Deletes privacy sensitive data in a batch, according to user preferences.
* errorHandler with a list of errors on failure. * Returns a promise which is resolved if no errors occurred. If an error
* occurs, a message is reported to the console and all other items are still
* cleared before the promise is finally rejected.
*/ */
sanitize: function (errorHandler) sanitize: function ()
{ {
var deferred = Promise.defer();
var psvc = Components.classes["@mozilla.org/preferences-service;1"] var psvc = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService); .getService(Components.interfaces.nsIPrefService);
var branch = psvc.getBranch(this.prefDomain); var branch = psvc.getBranch(this.prefDomain);
var errors = null; var seenError = false;
// Cache the range of times to clear // Cache the range of times to clear
if (this.ignoreTimespan) if (this.ignoreTimespan)
@@ -54,7 +59,12 @@ Sanitizer.prototype = {
else else
range = this.range || Sanitizer.getClearRange(); range = this.range || Sanitizer.getClearRange();
let itemCount = this.items.length; let itemCount = Object.keys(this.items).length;
let onItemComplete = function() {
if (!--itemCount) {
seenError ? deferred.reject() : deferred.resolve();
}
};
for (var itemName in this.items) { for (var itemName in this.items) {
let item = this.items[itemName]; let item = this.items[itemName];
item.range = range; item.range = range;
@@ -70,25 +80,18 @@ Sanitizer.prototype = {
if (aCanClear) if (aCanClear)
item.clear(); item.clear();
} catch(er) { } catch(er) {
if (!errors) seenError = true;
errors = {}; Cu.reportError("Error sanitizing " + itemName + ": " + er + "\n");
errors[itemName] = er;
dump("Error sanitizing " + itemName + ": " + er + "\n");
}
// If this is the last item that needs to receive the callback, call the error handler
if (!--itemCount && errors) {
errorHandler(error);
} }
onItemComplete();
}; };
this.canClearItem(itemName, clearCallback); this.canClearItem(itemName, clearCallback);
} else {
onItemComplete();
} }
} }
if (errors) { return deferred.promise;
errorHandler(error);
}
}, },
// Time span only makes sense in certain cases. Consumers who want // Time span only makes sense in certain cases. Consumers who want
@@ -517,7 +520,8 @@ Sanitizer._checkAndSanitize = function()
// this is a shutdown or a startup after an unclean exit // this is a shutdown or a startup after an unclean exit
var s = new Sanitizer(); var s = new Sanitizer();
s.prefDomain = "privacy.clearOnShutdown."; s.prefDomain = "privacy.clearOnShutdown.";
let errorHandler = function() prefs.setBoolPref(Sanitizer.prefDidShutdown, true); s.sanitize().then(function() {
s.sanitize(errorHandler); prefs.setBoolPref(Sanitizer.prefDidShutdown, true);
});
} }
}; };

View File

@@ -27,7 +27,7 @@
title="&sanitizeDialog2.title;" title="&sanitizeDialog2.title;"
noneverythingtitle="&sanitizeDialog2.title;" noneverythingtitle="&sanitizeDialog2.title;"
style="width: &dialog.width2;;" style="width: &dialog.width2;;"
ondialogaccept="gSanitizePromptDialog.sanitize();"> ondialogaccept="return gSanitizePromptDialog.sanitize();">
<prefpane id="SanitizeDialogPane" onpaneload="gSanitizePromptDialog.init();"> <prefpane id="SanitizeDialogPane" onpaneload="gSanitizePromptDialog.init();">
<stringbundle id="bundleBrowser" <stringbundle id="bundleBrowser"

View File

@@ -109,12 +109,23 @@ var gSanitizePromptDialog = {
s.range = Sanitizer.getClearRange(this.selectedTimespan); s.range = Sanitizer.getClearRange(this.selectedTimespan);
s.ignoreTimespan = !s.range; s.ignoreTimespan = !s.range;
// As the sanitize is async, we disable the buttons, update the label on
// the 'accept' button to indicate things are happening and return false -
// once the async operation completes (either with or without errors)
// we close the window.
let docElt = document.documentElement;
let acceptButton = docElt.getButton("accept");
acceptButton.disabled = true;
acceptButton.setAttribute("label",
this.bundleBrowser.getString("sanitizeButtonClearing"));
docElt.getButton("cancel").disabled = true;
try { try {
s.sanitize(); s.sanitize().then(window.close, window.close);
} catch (er) { } catch (er) {
Components.utils.reportError("Exception during sanitize: " + er); Components.utils.reportError("Exception during sanitize: " + er);
return true; // We *do* want to close immediately on error.
} }
return true; return false;
}, },
/** /**

View File

@@ -45,8 +45,9 @@ function test2()
prefBranch.setBoolPref("siteSettings", false); prefBranch.setBoolPref("siteSettings", false);
// Sanitize now so we can test that canClear is correct. Formdata is cleared asynchronously. // Sanitize now so we can test that canClear is correct. Formdata is cleared asynchronously.
s.sanitize(); s.sanitize().then(function() {
s.canClearItem("formdata", clearDone1, s); s.canClearItem("formdata", clearDone1, s);
});
} }
function clearDone1(aItemName, aResult, aSanitizer) function clearDone1(aItemName, aResult, aSanitizer)
@@ -59,8 +60,9 @@ function clearDone1(aItemName, aResult, aSanitizer)
function inputEntered(aItemName, aResult, aSanitizer) function inputEntered(aItemName, aResult, aSanitizer)
{ {
ok(aResult, "formdata can be cleared after input"); ok(aResult, "formdata can be cleared after input");
aSanitizer.sanitize(); aSanitizer.sanitize().then(function() {
aSanitizer.canClearItem("formdata", clearDone2); aSanitizer.canClearItem("formdata", clearDone2);
});
} }
function clearDone2(aItemName, aResult) function clearDone2(aItemName, aResult)

View File

@@ -142,6 +142,11 @@ pluginInfo.unknownPlugin=Unknown
# changed to this. See UI mockup and comment 11 at bug 480169 --> # changed to this. See UI mockup and comment 11 at bug 480169 -->
sanitizeDialog2.everything.title=Clear All History sanitizeDialog2.everything.title=Clear All History
sanitizeButtonOK=Clear Now sanitizeButtonOK=Clear Now
# LOCALIZATION NOTE (sanitizeButtonClearing): The label for the default
# button between the user clicking it and the window closing. Indicates the
# items are being cleared.
sanitizeButtonClearing=Clearing
# LOCALIZATION NOTE (sanitizeEverythingWarning2): Warning that appears when # LOCALIZATION NOTE (sanitizeEverythingWarning2): Warning that appears when
# "Time range to clear" is set to "Everything" in Clear Recent History dialog, # "Time range to clear" is set to "Everything" in Clear Recent History dialog,
# provided that the user has not modified the default set of history items to clear. # provided that the user has not modified the default set of history items to clear.