--- a/mail/app/profile/all-thunderbird.js
+++ b/mail/app/profile/all-thunderbird.js
@@ -758,10 +758,22 @@ pref("mail.chat.play_notification_sound"
// Send typing notification in private conversations
pref("purple.conversations.im.send_typing", true);
// BigFiles
pref("mail.cloud_files.enabled", true);
pref("mail.cloud_files.inserted_urls.footer.link", "http://www.getthunderbird.com");
pref("mail.cloud_files.learn_more_url", "https://support.mozillamessaging.com/kb/filelink-large-attachments");
+// Sanitize dialog window
+pref("privacy.cpd.cookies", true);
+pref("privacy.cpd.cache", true);
+
+// What default should we use for the time span in the sanitizer:
+// 0 - Clear everything
+// 1 - Last Hour
+// 2 - Last 2 Hours
+// 3 - Last 4 Hours
+// 4 - Today
+pref("privacy.sanitize.timeSpan", 1);
+
// PgpMime Proxy
pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/thunderbird/addon/enigmail/");
--- a/mail/base/content/mailCore.js
+++ b/mail/base/content/mailCore.js
@@ -345,16 +345,23 @@ function showChatTab()
}
function toImport()
{
window.openDialog("chrome://messenger/content/importDialog.xul", "importDialog",
"chrome, modal, titlebar, centerscreen");
}
+function toSanitize()
+{
+ Components.classes["@mozilla.org/mail/mailglue;1"]
+ .getService(Components.interfaces.nsIMailGlue)
+ .sanitize(window);
+}
+
/**
* Opens the Preferences (Options) dialog.
*
* @param aPaneID ID of prefpane to select automatically.
* @param aTabID ID of tab to select on the prefpane.
* @param aOtherArgs other prefpane specific arguments
*/
function openOptionsDialog(aPaneID, aTabID, aOtherArgs)
--- a/mail/base/content/mailWindowOverlay.xul
+++ b/mail/base/content/mailWindowOverlay.xul
@@ -1690,16 +1690,20 @@
label="&deleteJunk.label;"
accesskey="&deleteJunk.accesskey;"
command="cmd_deleteJunk"/>
<menuseparator id="tasksMenuAfterDeleteSeparator"/>
<menuitem id="menu_import" label="&importCmd.label;"
accesskey="&importCmd.accesskey;"
oncommand="toImport();"/>
<menuitem id="javascriptConsole" label="&errorConsoleCmd.label;" accesskey="&errorConsoleCmd.accesskey;" key="key_errorConsole" oncommand="toJavaScriptConsole();"/>
+ <menuitem id="sanitizeHistory"
+ label="&clearRecentHistory.label;"
+ accesskey="&clearRecentHistory.accesskey;"
+ oncommand="toSanitize();"/>
#ifndef XP_UNIX
<menuseparator id="prefSep"/>
<menuitem id="menu_accountmgr" label="&accountManagerCmd.label;" accesskey="&accountManagerCmd.accesskey;" oncommand="MsgAccountManager(null);"/>
<menuitem id="menu_preferences" oncommand="openOptionsDialog()"/>
#else
#ifdef XP_MACOSX
<menuseparator id="prefSep"/>
<menuitem id="menu_accountmgr" label="&accountManagerCmd.label;" accesskey="&accountManagerCmd.accesskey;" oncommand="MsgAccountManager(null);"/>
new file mode 100644
--- /dev/null
+++ b/mail/base/content/sanitize.js
@@ -0,0 +1,250 @@
+/* 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/. */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+var Application = Components.classes["@mozilla.org/steel/application;1"]
+ .getService(Components.interfaces.steelIApplication);
+
+function Sanitizer() {}
+Sanitizer.prototype = {
+ // warning to the caller: this one may raise an exception (e.g. bug #265028)
+ clearItem: function (aItemName)
+ {
+ if (this.items[aItemName].canClear)
+ this.items[aItemName].clear();
+ },
+
+ canClearItem: function (aItemName)
+ {
+ return this.items[aItemName].canClear;
+ },
+
+ prefDomain: "",
+
+ getNameFromPreference: function (aPreferenceName)
+ {
+ return aPreferenceName.substr(this.prefDomain.length);
+ },
+
+ /**
+ * Deletes privacy sensitive data in a batch, according to user preferences
+ *
+ * @returns null if everything's fine; an object in the form
+ * { itemName: error, ... } on (partial) failure
+ */
+ sanitize: function ()
+ {
+ var branch = Services.prefs.getBranch(this.prefDomain);
+ var errors = null;
+
+ // Cache the range of times to clear
+ if (this.ignoreTimespan)
+ var range = null; // If we ignore timespan, clear everything
+ else
+ range = this.range || Sanitizer.getClearRange();
+
+ for (var itemName in this.items) {
+ var item = this.items[itemName];
+ item.range = range;
+ if ("clear" in item && item.canClear && branch.getBoolPref(itemName)) {
+ // Some of these clear() may raise exceptions (see bug #265028)
+ // to sanitize as much as possible, we catch and store them,
+ // rather than fail fast.
+ // Callers should check returned errors and give user feedback
+ // about items that could not be sanitized
+ try {
+ item.clear();
+ } catch(er) {
+ if (!errors)
+ errors = {};
+ errors[itemName] = er;
+ dump("Error sanitizing " + itemName + ": " + er + "\n");
+ }
+ }
+ }
+ return errors;
+ },
+
+ // Time span only makes sense in certain cases. Consumers who want
+ // to only clear some private data can opt in by setting this to false,
+ // and can optionally specify a specific range. If timespan is not ignored,
+ // and range is not set, sanitize() will use the value of the timespan
+ // pref to determine a range
+ ignoreTimespan : true,
+ range : null,
+
+ items: {
+ cache: {
+ clear: function ()
+ {
+ try {
+ // Cache doesn't consult timespan, nor does it have the
+ // facility for timespan-based eviction. Wipe it.
+ Services.cache.evictEntries(Ci.nsICache.STORE_ANYWHERE);
+ } catch(er) {}
+
+ },
+
+ get canClear()
+ {
+ return true;
+ }
+ },
+
+ cookies: {
+ clear: function ()
+ {
+ if (this.range) {
+ // Iterate through the cookies and delete any created after our cutoff.
+ var cookiesEnum = Services.cookies.enumerator;
+ while (cookiesEnum.hasMoreElements()) {
+ var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
+
+ if (cookie.creationTime > this.range[0])
+ // This cookie was created after our cutoff, clear it
+ Services.cookies.remove(cookie.host, cookie.name, cookie.path, false);
+ }
+ }
+ else {
+ // Remove everything
+ Services.cookies.removeAll();
+ }
+
+ // Clear plugin data.
+ const phInterface = Ci.nsIPluginHost;
+ const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL;
+ let ph = Cc["@mozilla.org/plugin/host;1"].getService(phInterface);
+
+ // Determine age range in seconds. (-1 means clear all.) We don't know
+ // that this.range[1] is actually now, so we compute age range based
+ // on the lower bound. If this.range results in a negative age, do
+ // nothing.
+ let age = this.range ? (Date.now() / 1000 - this.range[0] / 1000000)
+ : -1;
+ if (!this.range || age >= 0) {
+ let tags = ph.getPluginTags();
+ for (let i = 0; i < tags.length; i++) {
+ try {
+ ph.clearSiteData(tags[i], null, FLAG_CLEAR_ALL, age);
+ } catch (e) {
+ // If the plugin doesn't support clearing by age, clear everything.
+ if (e.result == Components.results.
+ NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED) {
+ try {
+ ph.clearSiteData(tags[i], null, FLAG_CLEAR_ALL, -1);
+ } catch (e) {
+ // Ignore errors from the plugin
+ }
+ }
+ }
+ }
+ }
+
+ // clear any network geolocation provider sessions
+ try {
+ var branch = Services.prefs.getBranch("geo.wifi.access_token.");
+ branch.deleteBranch("");
+ } catch (e) {}
+
+ },
+
+ get canClear()
+ {
+ return true;
+ }
+ },
+ }
+};
+
+// "Static" members
+Sanitizer.prefDomain = "privacy.sanitize.";
+Sanitizer.prefShutdown = "sanitizeOnShutdown";
+Sanitizer.prefDidShutdown = "didShutdownSanitize";
+
+// Time span constants corresponding to values of the privacy.sanitize.timeSpan
+// pref. Used to determine how much history to clear, for various items
+Sanitizer.TIMESPAN_EVERYTHING = 0;
+Sanitizer.TIMESPAN_HOUR = 1;
+Sanitizer.TIMESPAN_2HOURS = 2;
+Sanitizer.TIMESPAN_4HOURS = 3;
+Sanitizer.TIMESPAN_TODAY = 4;
+
+// Return a 2 element array representing the start and end times,
+// in the uSec-since-epoch format that PRTime likes. If we should
+// clear everything, return null. Use ts if it is defined; otherwise
+// use the timeSpan pref.
+Sanitizer.getClearRange = function (ts) {
+ if (ts === undefined)
+ ts = Sanitizer.prefs.getIntPref("timeSpan");
+ if (ts === Sanitizer.TIMESPAN_EVERYTHING)
+ return null;
+
+ // PRTime is microseconds while JS time is milliseconds
+ var endDate = Date.now() * 1000;
+ switch (ts) {
+ case Sanitizer.TIMESPAN_HOUR :
+ var startDate = endDate - 3600000000; // 1*60*60*1000000
+ break;
+ case Sanitizer.TIMESPAN_2HOURS :
+ startDate = endDate - 7200000000; // 2*60*60*1000000
+ break;
+ case Sanitizer.TIMESPAN_4HOURS :
+ startDate = endDate - 14400000000; // 4*60*60*1000000
+ break;
+ case Sanitizer.TIMESPAN_TODAY :
+ var d = new Date(); // Start with today
+ d.setHours(0); // zero us back to midnight...
+ d.setMinutes(0);
+ d.setSeconds(0);
+ startDate = d.valueOf() * 1000; // convert to epoch usec
+ break;
+ default:
+ throw "Invalid time span for clear private data: " + ts;
+ }
+ return [startDate, endDate];
+};
+
+Sanitizer._prefs = null;
+Sanitizer.__defineGetter__("prefs", function()
+{
+ return Sanitizer._prefs ? Sanitizer._prefs
+ : Sanitizer._prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService)
+ .getBranch(Sanitizer.prefDomain);
+});
+
+// Shows sanitization UI
+Sanitizer.showUI = function(aParentWindow)
+{
+Services.ww.openWindow(Application.platformIsMac ? null : aParentWindow,
+"chrome://messenger/content/sanitize.xul",
+ "Sanitize",
+ "chrome,titlebar,dialog,centerscreen,modal",
+ null);
+};
+
+/**
+ * Deletes privacy sensitive data in a batch, optionally showing the
+ * sanitize UI, according to user preferences
+ */
+Sanitizer.sanitize = function(aParentWindow)
+{
+ Sanitizer.showUI(aParentWindow);
+};
+
+// this is called on startup and shutdown, to perform pending sanitizations
+Sanitizer._checkAndSanitize = function()
+{
+ const prefs = Sanitizer.prefs;
+ if (prefs.getBoolPref(Sanitizer.prefShutdown) &&
+ !prefs.prefHasUserValue(Sanitizer.prefDidShutdown)) {
+ // this is a shutdown or a startup after an unclean exit
+ var s = new Sanitizer();
+ s.prefDomain = "privacy.clearOnShutdown.";
+ s.sanitize() || // sanitize() returns null on full success
+ prefs.setBoolPref(Sanitizer.prefDidShutdown, true);
+ }
+};
+
+
new file mode 100644
--- /dev/null
+++ b/mail/base/content/sanitize.xul
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+
+<!-- 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/. -->
+
+<?xml-stylesheet href="chrome://global/skin/"?>
+<?xml-stylesheet href="chrome://messenger/skin/sanitizeDialog.css"?>
+
+<?xml-stylesheet href="chrome://messenger/content/sanitizeDialog.css"?>
+
+<!DOCTYPE prefwindow [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+ <!ENTITY % sanitizeDTD SYSTEM "chrome://messenger/locale/sanitize.dtd">
+ %brandDTD;
+ %sanitizeDTD;
+]>
+
+<prefwindow id="SanitizeDialog" type="child"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ dlgbuttons="accept,cancel"
+ title="&sanitizeDialog2.title;"
+ noneverythingtitle="&sanitizeDialog2.title;"
+ style="width: &dialog.width;"
+ ondialogaccept="gSanitizePromptDialog.sanitize();">
+
+ <prefpane id="SanitizeDialogPane" onpaneload="gSanitizePromptDialog.init();">
+ <stringbundle id="bundleBrowser"
+ src="chrome://messenger/locale/messenger.properties"/>
+
+ <script type="application/javascript"
+ src="chrome://messenger/content/sanitize.js"/>
+
+ <script type="application/javascript"
+ src="chrome://messenger/content/sanitizeDialog.js"/>
+
+ <preferences id="sanitizePreferences">
+ <preference id="privacy.cpd.cookies" name="privacy.cpd.cookies" type="bool"/>
+ <preference id="privacy.cpd.cache" name="privacy.cpd.cache" type="bool"/>
+ </preferences>
+
+ <preferences id="nonItemPreferences">
+ <preference id="privacy.sanitize.timeSpan"
+ name="privacy.sanitize.timeSpan"
+ type="int"/>
+ </preferences>
+
+ <hbox id="SanitizeDurationBox" align="center">
+ <label value="&clearTimeDuration.label;"
+ accesskey="&clearTimeDuration.accesskey;"
+ control="sanitizeDurationChoice"
+ id="sanitizeDurationLabel"/>
+ <menulist id="sanitizeDurationChoice"
+ preference="privacy.sanitize.timeSpan"
+ onselect="gSanitizePromptDialog.selectByTimespan();"
+ flex="1">
+ <menupopup id="sanitizeDurationPopup">
+ <menuitem label="&clearTimeDuration.lastHour;" value="1"/>
+ <menuitem label="&clearTimeDuration.last2Hours;" value="2"/>
+ <menuitem label="&clearTimeDuration.last4Hours;" value="3"/>
+ <menuitem label="&clearTimeDuration.today;" value="4"/>
+ <menuseparator/>
+ <menuitem label="&clearTimeDuration.everything;" value="0"/>
+ </menupopup>
+ </menulist>
+ <label id="sanitizeDurationSuffixLabel"
+ value="&clearTimeDuration.suffix;"/>
+ </hbox>
+
+ <separator class="thin"/>
+
+ <vbox id="sanitizeEverythingWarningBox">
+ <spacer flex="1"/>
+ <hbox align="center">
+ <image id="sanitizeEverythingWarningIcon"/>
+ <vbox id="sanitizeEverythingWarningDescBox" flex="1">
+ <description id="sanitizeEverythingWarning"/>
+ <description id="sanitizeEverythingUndoWarning">&sanitizeEverythingUndoWarning;</description>
+ </vbox>
+ </hbox>
+ <spacer flex="1"/>
+ </vbox>
+
+ <separator class="thin"/>
+
+ <hbox id="detailsExpanderWrapper" align="center">
+ <button type="image"
+ id="detailsExpander"
+ class="expander-down"
+ persist="class"
+ oncommand="gSanitizePromptDialog.toggleItemList();"/>
+ <label id="detailsExpanderLabel"
+ value="&detailsProgressiveDisclosure.label;"
+ accesskey="&detailsProgressiveDisclosure.accesskey;"
+ control="detailsExpander"/>
+ </hbox>
+ <listbox id="itemList" rows="2" collapsed="true" persist="collapsed">
+ <listitem label="&itemCookies.label;"
+ type="checkbox"
+ accesskey="&itemCookies.accesskey;"
+ preference="privacy.cpd.cookies"
+ onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
+ <listitem label="&itemCache.label;"
+ type="checkbox"
+ accesskey="&itemCache.accesskey;"
+ preference="privacy.cpd.cache"
+ onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>
+ </listbox>
+
+ </prefpane>
+</prefwindow>
new file mode 100644
--- /dev/null
+++ b/mail/base/content/sanitizeDialog.css
@@ -0,0 +1,23 @@
+/* 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/. */
+
+/* Places tree */
+
+#placesTreechildren {
+ -moz-user-focus: normal;
+}
+
+#placesTreechildren::-moz-tree-cell(grippyRow),
+#placesTreechildren::-moz-tree-cell-text(grippyRow),
+#placesTreechildren::-moz-tree-image(grippyRow) {
+ cursor: -moz-grab;
+}
+
+
+/* Sanitize everything warnings */
+
+#sanitizeEverythingWarning,
+#sanitizeEverythingUndoWarning {
+ white-space: pre-wrap;
+}
new file mode 100644
--- /dev/null
+++ b/mail/base/content/sanitizeDialog.js
@@ -0,0 +1,251 @@
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+var gSanitizePromptDialog = {
+
+ get bundleBrowser()
+ {
+ if (!this._bundleBrowser)
+ this._bundleBrowser = document.getElementById("bundleBrowser");
+ return this._bundleBrowser;
+ },
+
+ get selectedTimespan()
+ {
+ var durList = document.getElementById("sanitizeDurationChoice");
+ return parseInt(durList.value);
+ },
+
+ get sanitizePreferences()
+ {
+ if (!this._sanitizePreferences) {
+ this._sanitizePreferences =
+ document.getElementById("sanitizePreferences");
+ }
+ return this._sanitizePreferences;
+ },
+
+ get warningBox()
+ {
+ return document.getElementById("sanitizeEverythingWarningBox");
+ },
+
+ init: function ()
+ {
+ // This is used by selectByTimespan() to determine if the window has loaded.
+ this._inited = true;
+
+ var s = new Sanitizer();
+ s.prefDomain = "privacy.cpd.";
+
+ let sanitizeItemList = document.querySelectorAll("#itemList > [preference]");
+ for (let i = 0; i < sanitizeItemList.length; i++) {
+ let prefItem = sanitizeItemList[i];
+ let name = s.getNameFromPreference(prefItem.getAttribute("preference"));
+ if (!s.canClearItem(name)) {
+ prefItem.preference = null;
+ prefItem.checked = false;
+ prefItem.disabled = true;
+ }
+ }
+
+ document.documentElement.getButton("accept").label =
+ this.bundleBrowser.getString("sanitizeButtonOK");
+
+ if (this.selectedTimespan === Sanitizer.TIMESPAN_EVERYTHING) {
+ this.prepareWarning();
+ this.warningBox.hidden = false;
+ document.title =
+ this.bundleBrowser.getString("sanitizeDialog2.everything.title");
+ }
+ else
+ this.warningBox.hidden = true;
+ },
+
+ selectByTimespan: function ()
+ {
+ // This method is the onselect handler for the duration dropdown. As a
+ // result it's called a couple of times before onload calls init().
+ if (!this._inited)
+ return;
+
+ var warningBox = this.warningBox;
+
+ // If clearing everything
+ if (this.selectedTimespan === Sanitizer.TIMESPAN_EVERYTHING) {
+ this.prepareWarning();
+ if (warningBox.hidden) {
+ warningBox.hidden = false;
+ window.resizeBy(0, warningBox.boxObject.height);
+ }
+ window.document.title =
+ this.bundleBrowser.getString("sanitizeDialog2.everything.title");
+ return;
+ }
+
+ // If clearing a specific time range
+ if (!warningBox.hidden) {
+ window.resizeBy(0, -warningBox.boxObject.height);
+ warningBox.hidden = true;
+ }
+ window.document.title =
+ window.document.documentElement.getAttribute("noneverythingtitle");
+ },
+
+ sanitize: function ()
+ {
+ // Update pref values before handing off to the sanitizer (bug 453440)
+ this.updatePrefs();
+ var s = new Sanitizer();
+ s.prefDomain = "privacy.cpd.";
+
+ s.range = Sanitizer.getClearRange(this.selectedTimespan);
+ s.ignoreTimespan = !s.range;
+
+ try {
+ s.sanitize();
+ } catch (er) {
+ Components.utils.reportError("Exception during sanitize: " + er);
+ }
+ return true;
+ },
+
+ /**
+ * If the panel that displays a warning when the duration is "Everything" is
+ * not set up, sets it up. Otherwise does nothing.
+ *
+ * @param aDontShowItemList Whether only the warning message should be updated.
+ * True means the item list visibility status should not
+ * be changed.
+ */
+ prepareWarning: function (aDontShowItemList) {
+ // If the date and time-aware locale warning string is ever used again,
+ // initialize it here. Currently we use the no-visits warning string,
+ // which does not include date and time. See bug 480169 comment 48.
+
+ var warningStringID;
+ if (this.hasNonSelectedItems()) {
+ warningStringID = "sanitizeSelectedWarning";
+ if (!aDontShowItemList)
+ this.showItemList();
+ }
+ else {
+ warningStringID = "sanitizeEverythingWarning2";
+ }
+
+ var warningDesc = document.getElementById("sanitizeEverythingWarning");
+ warningDesc.textContent =
+ this.bundleBrowser.getString(warningStringID);
+ },
+
+ /**
+ * Called when the value of a preference element is synced from the actual
+ * pref. Enables or disables the OK button appropriately.
+ */
+ onReadGeneric: function ()
+ {
+ var found = false;
+
+ // Find any other pref that's checked and enabled.
+ var i = 0;
+ while (!found && i < this.sanitizePreferences.childNodes.length) {
+ var preference = this.sanitizePreferences.childNodes[i];
+
+ found = !!preference.value &&
+ !preference.disabled;
+ i++;
+ }
+
+ try {
+ document.documentElement.getButton("accept").disabled = !found;
+ }
+ catch (e) { }
+
+ // Update the warning prompt if needed
+ this.prepareWarning(true);
+
+ return undefined;
+ },
+
+ /**
+ * Sanitizer.prototype.sanitize() requires the prefs to be up-to-date.
+ * Because the type of this prefwindow is "child" -- and that's needed because
+ * without it the dialog has no OK and Cancel buttons -- the prefs are not
+ * updated on dialogaccept on platforms that don't support instant-apply
+ * (i.e., Windows). We must therefore manually set the prefs from their
+ * corresponding preference elements.
+ */
+ updatePrefs : function ()
+ {
+ var tsPref = document.getElementById("privacy.sanitize.timeSpan");
+ Sanitizer.prefs.setIntPref("timeSpan", this.selectedTimespan);
+
+ // Now manually set the prefs from their corresponding preference
+ // elements.
+ var prefs = this.sanitizePreferences.rootBranch;
+ for (let i = 0; i < this.sanitizePreferences.childNodes.length; ++i) {
+ var p = this.sanitizePreferences.childNodes[i];
+ prefs.setBoolPref(p.name, p.value);
+ }
+ },
+
+ /**
+ * Check if all of the history items have been selected like the default status.
+ */
+ hasNonSelectedItems: function () {
+ let checkboxes = document.querySelectorAll("#itemList > [preference]");
+ for (let i = 0; i < checkboxes.length; ++i) {
+ let pref = document.getElementById(checkboxes[i].getAttribute("preference"));
+ if (!pref.value)
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Show the history items list.
+ */
+ showItemList: function () {
+ var itemList = document.getElementById("itemList");
+ var expanderButton = document.getElementById("detailsExpander");
+
+ if (itemList.collapsed) {
+ expanderButton.className = "expander-up";
+ itemList.setAttribute("collapsed", "false");
+ if (document.documentElement.boxObject.height)
+ window.resizeBy(0, itemList.boxObject.height);
+ }
+ },
+
+ /**
+ * Hide the history items list.
+ */
+ hideItemList: function () {
+ var itemList = document.getElementById("itemList");
+ var expanderButton = document.getElementById("detailsExpander");
+
+ if (!itemList.collapsed) {
+ expanderButton.className = "expander-down";
+ window.resizeBy(0, -itemList.boxObject.height);
+ itemList.setAttribute("collapsed", "true");
+ }
+ },
+
+ /**
+ * Called by the item list expander button to toggle the list's visibility.
+ */
+ toggleItemList: function ()
+ {
+ var itemList = document.getElementById("itemList");
+
+ if (itemList.collapsed)
+ this.showItemList();
+ else
+ this.hideItemList();
+ }
+};
\ No newline at end of file
--- a/mail/base/jar.mn
+++ b/mail/base/jar.mn
@@ -102,16 +102,20 @@ messenger.jar:
content/messenger/quickFilterBar.xul (content/quickFilterBar.xul)
content/messenger/quickFilterBar.js (content/quickFilterBar.js)
content/messenger/quickFilterBar.css (content/quickFilterBar.css)
content/messenger/downloadsOverlay.xul (content/downloadsOverlay.xul)
content/messenger/browserRequest.js (content/browserRequest.js)
content/messenger/browserRequest.xul (content/browserRequest.xul)
* content/messenger/safeMode.xul (content/safeMode.xul)
content/messenger/safeMode.js (content/safeMode.js)
+ content/messenger/sanitize.xul (content/sanitize.xul)
+ content/messenger/sanitize.js (content/sanitize.js)
+ content/messenger/sanitizeDialog.css (content/sanitizeDialog.css)
+ content/messenger/sanitizeDialog.js (content/sanitizeDialog.js)
# the following files are mail-specific overrides
*+ content/messenger/license.html (/mozilla/toolkit/content/license.html)
% override chrome://global/content/license.html chrome://messenger/content/license.html
comm.jar:
% content communicator %content/communicator/
content/communicator/contentAreaClick.js (content/contentAreaClick.js)
* content/communicator/utilityOverlay.xul (content/utilityOverlay.xul)
--- a/mail/components/Makefile.in
+++ b/mail/components/Makefile.in
@@ -4,16 +4,23 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
+
+MODULE = mailcomps
+XPIDL_MODULE = mailcompsbase
+
+XPIDLSRCS = \
+ nsIMailGlue.idl \
+ $(NULL)
# Only Mac and Windows have search integration components, but we include at
# least one module from search/ on all platforms
DIRS = compose cloudfile preferences addrbook migration activity search about-support wintaskbar newmailaccount im
ifneq (,$(filter windows gtk2 cocoa, $(MOZ_WIDGET_TOOLKIT)))
DIRS += shell
endif
--- a/mail/components/mailGlue.js
+++ b/mail/components/mailGlue.js
@@ -15,16 +15,23 @@ Cu.import("resource:///modules/mailMigra
/**
* Glue code that should be executed before any windows are opened. Any
* window-independent helper methods (a la nsBrowserGlue.js) should go in
* MailUtils.js instead.
*/
function MailGlue() {
+ XPCOMUtils.defineLazyGetter(this, "_sanitizer",
+ function() {
+ let sanitizerScope = {};
+ Services.scriptloader.loadSubScript("chrome://messenger/content/sanitize.js", sanitizerScope);
+ return sanitizerScope.Sanitizer;
+ });
+
this._init();
}
MailGlue.prototype = {
// init (called at app startup)
_init: function MailGlue__init() {
Services.obs.addObserver(this, "xpcom-shutdown", false);
Services.obs.addObserver(this, "final-ui-startup", false);
@@ -48,16 +55,21 @@ MailGlue.prototype = {
this._onProfileStartup();
break;
case "mail-startup-done":
this._onMailStartupDone();
break;
}
},
+ //nsIMailGlue implementation
+ sanitize: function MG_sanitize(aParentWindow) {
+ this._sanitizer.sanitize(aParentWindow);
+ },
+
_onProfileStartup: function MailGlue__onProfileStartup() {
TBDistCustomizer.applyPrefDefaults();
// handle any migration work that has to happen at profile startup
MailMigrator.migrateAtProfileStartup();
// check if we're in safe mode
if (Services.appinfo.inSafeMode) {
@@ -90,13 +102,14 @@ MailGlue.prototype = {
{ contentPage: "about:newaddon?id=" + aAddon.id,
clickHandler: null });
});
});
},
// for XPCOM
classID: Components.ID("{eb239c82-fac9-431e-98d7-11cacd0f71b8}"),
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsIMailGlue]),
};
var components = [MailGlue];
var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
new file mode 100644
--- /dev/null
+++ b/mail/components/nsIMailGlue.idl
@@ -0,0 +1,21 @@
+/* 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/. */
+
+#include "nsISupports.idl"
+
+interface nsIDOMWindow;
+
+[scriptable, uuid(bc873177-ea0c-4714-b26c-f89c071107ce)]
+interface nsIMailGlue : nsISupports
+{
+ /**
+ * Deletes privacy sensitive data according to user preferences
+ *
+ * @param aParentWindow an optionally null window which is the parent of the
+ * sanitization dialog
+ *
+ */
+ void sanitize(in nsIDOMWindow aParentWindow);
+
+};
--- a/mail/locales/en-US/chrome/messenger/messenger.dtd
+++ b/mail/locales/en-US/chrome/messenger/messenger.dtd
@@ -502,16 +502,18 @@ you can use these alternative items. Oth
<!ENTITY runJunkControls.accesskey "C">
<!ENTITY deleteJunk.label "Delete Mail Marked as Junk in Folder">
<!ENTITY deleteJunk.accesskey "D">
<!ENTITY importCmd.label "Import…">
<!ENTITY importCmd.accesskey "m">
<!ENTITY errorConsoleCmd.label "Error Console">
<!ENTITY errorConsoleCmd.accesskey "E">
<!ENTITY errorConsoleCmd.commandkey "j">
+<!ENTITY clearRecentHistory.label "Clear Recent History…">
+<!ENTITY clearRecentHistory.accesskey "H">
<!ENTITY accountManagerCmd.label "Account Settings…">
<!ENTITY accountManagerCmd.accesskey "S">
<!-- LOCALIZATION NOTE (accountManagerCmdUnix.accesskey): belongs to accountManagerCmd.label,
which is placed under the Edit menu on Unix systems -->
<!ENTITY accountManagerCmdUnix.accesskey "A">
<!-- Mail Toolbar -->
<!ENTITY getMsgButton.label "Get Mail">
--- a/mail/locales/en-US/chrome/messenger/messenger.properties
+++ b/mail/locales/en-US/chrome/messenger/messenger.properties
@@ -695,8 +695,23 @@ crashedpluginsMessage.title=The %S plugi
crashedpluginsMessage.reloadButton.label=Reload page
crashedpluginsMessage.reloadButton.accesskey=R
crashedpluginsMessage.submitButton.label=Submit a crash report
crashedpluginsMessage.submitButton.accesskey=S
crashedpluginsMessage.learnMore=Learn More…
carbonFailurePluginsMessage.message=This page asks to use a plugin that can only run in 32-bit mode
carbonFailurePluginsMessage.restartButton.label=Restart in 32-bit mode
carbonFailurePluginsMessage.restartButton.accesskey=R
+
+# Sanitize
+# LOCALIZATION NOTE (sanitizeDialog2.everything.title): When "Time range to
+# clear" is set to "Everything", the Clear Recent History dialog's title is
+# changed to this. See UI mockup and comment 11 at bug 480169 -->
+sanitizeDialog2.everything.title=Clear All History
+sanitizeButtonOK=Clear Now
+# LOCALIZATION NOTE (sanitizeEverythingWarning2): Warning that appears when
+# "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.
+sanitizeEverythingWarning2=All history will be cleared.
+# LOCALIZATION NOTE (sanitizeSelectedWarning): Warning that appears when
+# "Time range to clear" is set to "Everything" in Clear Recent History dialog,
+# provided that the user has modified the default set of history items to clear.
+sanitizeSelectedWarning=All selected items will be cleared.
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/mail/locales/en-US/chrome/messenger/sanitize.dtd
@@ -0,0 +1,50 @@
+<!-- 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/. -->
+
+<!ENTITY sanitizePrefs2.title "Settings for Clearing History">
+<!ENTITY sanitizeDialog2.title "Clear Recent History">
+
+<!ENTITY sanitizeItems.label "Clear the following items now:">
+<!ENTITY clearDataSettings2.label "When I quit &brandShortName;, it should automatically clear all:">
+
+<!-- XXX rearrange entities to match physical layout when l10n isn't an issue -->
+<!-- LOCALIZATION NOTE (clearTimeDuration.*): "Time range to clear" dropdown.
+ See UI mockup at bug 480169 -->
+<!ENTITY clearTimeDuration.label "Time range to clear: ">
+<!ENTITY clearTimeDuration.accesskey "T">
+<!ENTITY clearTimeDuration.lastHour "Last Hour">
+<!ENTITY clearTimeDuration.last2Hours "Last Two Hours">
+<!ENTITY clearTimeDuration.last4Hours "Last Four Hours">
+<!ENTITY clearTimeDuration.today "Today">
+<!ENTITY clearTimeDuration.everything "Everything">
+<!-- Localization note (clearTimeDuration.suffix) - trailing entity for languages
+that require it. -->
+<!ENTITY clearTimeDuration.suffix "">
+<!ENTITY clearTimeDuration.dateColumn "Visit Date">
+<!ENTITY clearTimeDuration.nameColumn "Name">
+
+<!-- LOCALIZATION NOTE (detailsProgressiveDisclosure.*): Labels and accesskeys
+ of the "Details" progressive disclosure button. See UI mockup at bug
+ 480169 -->
+<!ENTITY detailsProgressiveDisclosure.label "Details">
+<!ENTITY detailsProgressiveDisclosure.accesskey "e">
+
+<!ENTITY historySection.label "History">
+<!ENTITY dataSection.label "Data">
+
+<!-- LOCALIZATION NOTE (item*): itemHistoryAndDownloads.* and
+ itemBrowsingHistory.* will never be used at the same time, so they can
+ have the same accesskey. -->
+<!ENTITY itemCookies.label "Cookies">
+<!ENTITY itemCookies.accesskey "C">
+<!ENTITY itemCache.label "Cache">
+<!ENTITY itemCache.accesskey "A">
+
+<!-- LOCALIZATION NOTE (sanitizeEverythingUndoWarning): Second warning paragraph
+ that appears when "Time range to clear" is set to "Everything". See UI
+ mockup at bug 480169 -->
+<!ENTITY sanitizeEverythingUndoWarning "This action cannot be undone.">
+
+<!ENTITY dialog.width "28em">
+<!ENTITY column.width "14em">
--- a/mail/locales/jar.mn
+++ b/mail/locales/jar.mn
@@ -181,16 +181,17 @@
locale/@AB_CD@/messenger/downloadsOverlay.dtd (%chrome/messenger/downloadsOverlay.dtd)
locale/@AB_CD@/messenger/chat.dtd (%chrome/messenger/chat.dtd)
locale/@AB_CD@/messenger/chat.properties (%chrome/messenger/chat.properties)
locale/@AB_CD@/messenger/addbuddy.dtd (%chrome/messenger/addbuddy.dtd)
locale/@AB_CD@/messenger/joinChat.dtd (%chrome/messenger/joinChat.dtd)
locale/@AB_CD@/messenger/imAccounts.dtd (%chrome/messenger/imAccounts.dtd)
locale/@AB_CD@/messenger/imAccounts.properties (%chrome/messenger/imAccounts.properties)
locale/@AB_CD@/messenger/imAccountWizard.dtd (%chrome/messenger/imAccountWizard.dtd)
+ locale/@AB_CD@/messenger/sanitize.dtd (%chrome/messenger/sanitize.dtd)
% locale messenger-mapi @AB_CD@ %locale/@AB_CD@/messenger-mapi/
locale/@AB_CD@/messenger-mapi/mapi.properties (%chrome/messenger-mapi/mapi.properties)
% locale messenger-newsblog @AB_CD@ %locale/@AB_CD@/messenger-newsblog/
locale/@AB_CD@/messenger-newsblog/newsblog.properties (%chrome/messenger-newsblog/newsblog.properties)
locale/@AB_CD@/messenger-newsblog/feed-subscriptions.dtd (%chrome/messenger-newsblog/feed-subscriptions.dtd)
locale/@AB_CD@/messenger-newsblog/am-newsblog.dtd (%chrome/messenger-newsblog/am-newsblog.dtd)
% locale messenger-smime @AB_CD@ %locale/@AB_CD@/messenger-smime/
locale/@AB_CD@/messenger-smime/msgCompSMIMEOverlay.dtd (%chrome/messenger-smime/msgCompSMIMEOverlay.dtd)
--- a/mail/themes/gnomestripe/jar.mn
+++ b/mail/themes/gnomestripe/jar.mn
@@ -255,9 +255,10 @@ classic.jar:
skin/classic/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
skin/classic/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
skin/classic/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
skin/classic/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
skin/classic/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
skin/classic/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/messenger/sanitizeDialog.css (sanitizeDialog.css)
skin/classic/messenger/icons/box-logo.png (mail/icons/box-logo.png)
new file mode 100644
--- /dev/null
+++ b/mail/themes/gnomestripe/sanitizeDialog.css
@@ -0,0 +1,107 @@
+/* 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/. */
+
+#sanitizeDurationChoice {
+ -moz-margin-end: 0;
+}
+
+/* Align the duration label with the warning box and item list */
+#sanitizeDurationLabel {
+ -moz-margin-start: 3px;
+}
+
+
+/* Hide the duration dropdown suffix label if it's empty. Otherwise it
+ takes up a little space, causing the end of the dropdown to not be aligned
+ with the warning box. */
+#sanitizeDurationSuffixLabel[value=""] {
+ display: none;
+}
+
+
+/* Places tree */
+#placesTreechildren::-moz-tree-row(selected),
+#placesTreechildren::-moz-tree-row(grippyRow) {
+ background: #999;
+}
+
+#placesTreechildren::-moz-tree-cell-text(selected) {
+ color: #111;
+}
+
+
+/* Sanitize everything warning box */
+#sanitizeEverythingWarningBox {
+ background-color: Window;
+ border: 1px solid ThreeDDarkShadow;
+ border-radius: 5px;
+ padding: 16px;
+}
+
+#sanitizeEverythingWarningIcon {
+ list-style-image: url("moz-icon://stock/gtk-dialog-warning?size=dialog");
+ padding: 0;
+ margin: 0;
+}
+
+#sanitizeEverythingWarningDescBox {
+ padding: 0 16px;
+ margin: 0;
+}
+
+
+/* Progressive disclosure button */
+#detailsExpanderWrapper {
+ padding: 0;
+ margin-top: 6px;
+ margin-bottom: 6px;
+ -moz-margin-start: -6px;
+ -moz-margin-end: 0;
+}
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ padding: 2px 0;
+ -moz-padding-start: 2px;
+}
+
+.expander-up {
+ list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
+}
+
+.expander-down {
+ list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
+}
+
+.expander-down:hover:active {
+ list-style-image: url("chrome://global/skin/arrow/arrow-dn-hov.gif");
+}
+
+.expander-up:hover:active {
+ list-style-image: url("chrome://global/skin/arrow/arrow-up-hov.gif");
+}
+
+
+/* Make the item list the same width as the warning box */
+#itemList {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+/* Without this a useless scrollbar appears in the listbox when its rows
+ attribute is set to the total number of listitems, as it is currently. See
+ bug 489958 comment 14 and bug 491788. */
+#itemList > listitem {
+ padding: 1px 0;
+}
+
+
+/* Align the last dialog button with the end of the warning box */
+.prefWindow-dlgbuttons {
+ -moz-margin-end: 0;
+}
+.dialog-button[dlgtype="accept"] {
+ -moz-margin-end: 0;
+}
--- a/mail/themes/pinstripe/jar.mn
+++ b/mail/themes/pinstripe/jar.mn
@@ -299,11 +299,16 @@ classic.jar:
skin/classic/messenger/newmailaccount/accountProvisioner.css (mail/newmailaccount/accountProvisioner.css)
skin/classic/messenger/newmailaccount/search.gif (mail/newmailaccount/search.gif)
skin/classic/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
skin/classic/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
skin/classic/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
skin/classic/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
skin/classic/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
skin/classic/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
- skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
- skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
+ skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/messenger/places/expander-closed.png (places/expander-closed.png)
+ skin/classic/messenger/places/expander-closed-active.png (places/expander-closed-active.png)
+ skin/classic/messenger/places/expander-open.png (places/expander-open.png)
+ skin/classic/messenger/places/expander-open-active.png (places/expander-open-active.png)
+ skin/classic/messenger/sanitizeDialog.css (sanitizeDialog.css)
skin/classic/messenger/icons/box-logo.png (mail/icons/box-logo.png)
new file mode 100644
index 0000000000000000000000000000000000000000..7ef5f04f9ea9aec76eb9bee7af5aaa2c74a3fb01
GIT binary patch
literal 1329
zc$@(-1<v}3P)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004XF*Lt007q5
z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$!%0LzRCwBA
zWB>w}q%Qvd{}~Q`d;d)L|NnnX3`l^H0YCVU#AasU_{k+CyLtEQ+;AZG-+!Q?009Kj
z&+L-izfW6N*UrPqih-St1;b!QMu<U-$Oit$wCK&dPYhdj9{lt8;k{Y=7nJ4#E%*lz
zKp@jNzJGjf>FJWq@E2&~g(rU*K7IdB&<DuoGXWKe@Gvo`iSskqSQ@h|yn4nPC|m@@
zKLG*=WC8o1-#=K{SQ!~ELJenx>SBc2zz88woc|vt075|g>hnJakmp4Nxf%Zc`^^KC
zWCK|M5I~^tW&x@C3uJu!4l<YtVmL5d7@2_><UD4GFe8WtV@5C=EDywBF97k2&;J=%
z5HZLMA^-vi9^hbC0!;xM05lw|jtLP=|DihmqX*qTARDCaKO@+YXi>ue5I`(2#Y{jK
zFad)J<QPU6h6W82vVn|{Ac2|<<U=?hF^~foncx8m1^@vBw%|WV5hKLwNIqsbvUW1V
zqid&tmNR3-_P@V>8D!Lr80^Cffr$fX#y^OKjEtyC0Rjl>ga6<#X9oEK5(QvyE9zS@
zTs^W8XC6@0vt(dm0qO>Z%|B37{exJ*z=*H|Ab^-)sRCpmNHH@Iv#>#EMO{+{+t5rz
zkRf3U-*^UP11p9<fBrN428PeKAHWp&^Do2C-~SkX{QC6|W&uC|K_VIGKak5=SRko|
znF$gnpfI)Y3S)S7`#i(FOD7oqfr8=Re+FS0O$G_0Fowr3z5|ma16UlChd@E~o%;{N
z&u>5BaSaea5Far82PZdXRtN_9gq4+n;SbQT_n-bS==$U{FtZDQUCYGE!C)Ct0+eTB
zU;$z_C}v@0W?%)TQD!F8NB{^Rco2caK|TN_nQuS-F+6+oi{a(F-(WU3pAdt6bQ#!J
z=KkpnLK3nJY-|vNS=k_tVg+FqMo4NziUWWEVu2?(purzL{bl(2^)EOt038H0gb^Ix
zpp+%AW5S^C9KxVw;|Vqdl;A-@^6wu=&3|wN|Ai$`MnrA^2q3TpfByVq`10i+!`JWs
zz%F57W<<mVG>?E1flX)z+&!R@k_ni(fJG()Gf@3+P_+L24^QGS01!Z63w{EF0VKx8
z0?GOygIRz+V1X46j1WIFLbLQgpbJ5zIy0z<`O657Xof$KOa{tJ|B-?SAb_An#Xqn?
zps-{C<p-cBE64}1G6<xQ1>r1E&@lXi1`iX=aG)MgNHhKi=PMWh2q1V-0SXpTZYGA0
ze;|glLJbF5!ieT=W>C;DgK{%a{2xUBA0S%{REGX$L@BBO0tjpY3oFMTpf_1mg%}y`
ze+H)IKM;dKK4F5CfuJH6QDOu6e}QWLGC>RmdYnO!6PUC485pkJ{0#Ih>ra>k009Kj
z_lKQZ;>w2Y+YN%e-57L4SRgKk8jS3ECTKwi3xL1>AbfBJ1kx|xeqcCs?BpL-R<7e9
zX^<L#00L>{7L-)clvFd>_T%$&k-xuxFd|A*c-g{$Tv7jnRcZg>6xbp*PX2$KJW|&$
z?p@#q6nY9wX+Hr1h!I-M3jnbc5DPLOLW5KQvIi72Z-DqY5Pt#H$p8Vwh!j+upz4zW
n)v=@kV9YT5fMRf~0wBNu(gkh+k|I`<00000NkvXXu0mjf(9$K;
new file mode 100644
index 0000000000000000000000000000000000000000..7850c9e9510b196e7b34398d2c028a457c901418
GIT binary patch
literal 837
zc$@)61G@Z)P)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004XF*Lt007q5
z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!*GWV{RCwBA
zWB`Jmo*n@{KE5Mw-n`NL_wOGQ1DSx0jqR7HsOYxD#Kd4A_uv2j{}})R2qextXU?3X
z$B!TX|NHmv|CE5wpFjWKzJ2?jsZ*!U0Gi7LvH&1}Sbz+Uw{PE?nwy)0UGe?<cLtzE
zB)guSot=S)hljzyz<~Mk<;&hcAyy#%2@pUa3)p}C`o+q~$Vj%~An^0&PX>?~TwGiX
zK=ZgjAqEl#2q2IJEHFiX{`>(eA{PJ+2I~jLBRJ?m1V8|R4TlOaz#@fQfTSPJ00<x!
zWC==Kk8H``zklI;fB<5_=kn>(r!$;BeVT!pnHfV4WQd`mAwzC%E<T?y00a<<1x!q+
zS-`@=f?>;+EjV2Zl1JAAibrG%00M{!J&2I8iHQkAYHBK0!((D%7|hJfz^M*|zkT}#
z#?Ykx2c`}nfS8aY85;-=4rVYlH3d5Yqz)7`ii(O1&d$yZuU@@kc=zrd7y~mI7=zS&
z`SJyx)&T+t#R6p4gS-y%E>JN;e0)4O6M+l|76%NOnVH~t0jWX9PykOY00D#&fFOfG
zF8%T22iR2~K70VP1q1{bva_?n^0Be83{p~3SPchZ^ppq?KrFBn0RmsYeg)@dxa~+0
z2rL2^e0_bvL4zK#=qU&}k^uq;ZUIOTl-==Z1_c$7c>(SXfB<5Fl_S`aDK!8<0KxMC
zEMh4EApOuFg8Kj<fKW0Ts3ZhMD!G80n;V`NU;rS1SfDol1X{ulQUJ0HR4S4RI5;>M
zI5{~PUcP(@;=)}C5I`Uc{s1jFyL0DGD;F0R23}rXvVHLB(<cUC&G;LbXbytX4oD0j
zfIwlzEh8hNVQg%?5tu}!fDul1kqQjr-$0*SSigRK1d#g_7#cqT0*Db>F$e&$6c7tS
zeMOEXpojz|$2UOy9EiUFE%*lzK#WL1#R;lD(Q`M6;14wXf52K5009O7Gh2ejfzj5Q
P00000NkvXXu0mjfLdQsv
new file mode 100644
index 0000000000000000000000000000000000000000..673ead568d21bf9fb2d3ff1d729d8326541740e6
GIT binary patch
literal 1329
zc$@(-1<v}3P)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004XF*Lt007q5
z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$!%0LzRCwBA
zWB>w}q%Qvd{}~Q`d;d)L|NnnX3`l^H0YCVU#AasU_{k+CyLtEQ+;AZG-+!Q?009Kj
z&+L-izfW6N*UrPqih-St1;b!QMu<U-$Oit$wCK&dPYhdj9{lt8;k{Y=7nJ4#E%*lz
zKp@jNzJGjf>FJWq@E2&~g(rU*K7IdB&<DuoGXWKe@Gvo`iSskqSQ@h|yn4nPC|m@@
zKLG*=WC8o1-#=K{SQ!~ELJenx>SBc2zz88woc|vt075|g>hnJakmp4Nxf%Zc`^^KC
zWCK|M5I~^tW&x@C3uJu!4l<YtVmL5d7@2_><UD4GFe8WtV@5C=EDywBF97k2&;J=%
z5HZLMA^-vi9^hbC0!;xM05lw|jtLP=|DihmqX*qTARDCaKO@+YXi>ue5I{^Y#Y{jK
zFad*!3F<0F79bmJArk{L5VHdDsjYK>V*kN>7G{VXNIgssGt|e7NcIB+5ZHqMjQ_zx
zOi)EEFbwn`D-eU|XLrvsTspX#;nwNx3@ogmBncD;dWi+-C}tLjKCnfMs0jlgfS^A3
z4-Ru?CPsvdKt5oBuz!4i&#-q%CpZ9(Z<xvO`Q1|nW~jknHB3++FhVR~U_{sf5I{_@
zQ~?S{kYbP~7B;A>Kp1Gy{-r$(-#@<tYySP~JHy_^oj?~ueEjFne}><{Wc2L^Fa`en
z%kcB}KZYN_e*J@401!ZsNdEs1oJv4J0iv0iAaMeU)N^}RF+99_3heKH|3LUZ!^4|b
z8MZE&%b?>F4NQ^{aZn!m3k>P++<zE;e)|cJYk&ZP_y8DjU@x*lFvusYz;M2M<rKr-
zWz)f~`t|ES*tP$lZo9UBDZ|S<rx@5+nZTHZl^GacOyFQfjs$=JVu1w_NF3w?kp6Gq
z|1o_1{)gex@gode0utcV!ibiO{{d}!aqAR=ysjm~A87jg_ZONPk>UU#fLP#(8R(Y}
zpZ+p@{rVT27l008unErvhdVPPYJPy(0tyn4j~IcekQo$AumsA8$PEAi1h(MMpMMNr
zzJOf)4;VC%BnpoUXdYoiE@S_JiU**tftd?fWP+3EZ;;pj{)c61H~<JBumwMV`~zFe
z#sW=lOwcqAD;^jjerAMv;UCb2pi-R~RK)yc1V=Q(9|mwH1EsA0NI?V;K+vM%AJ`yJ
z1hath11N)md;lwhKnht9&ieZw;){R(pg#KpDK1z+A<g(7oUdR2Ab?n4VG9ZtQEn!N
zkAEPBvqB9AS;C0sZDvr=Fhe8tA4ESWqQyXE=x;`pq6#2@z!tEua{K{$lSNgCk>UPl
zU|RkIF&N|%CP*0wDsmB#4CMa>s`<+VF&OA^20=~+21R~g^1b;P=v&sGFbe<z2&C^1
zJGaD@4coUH1bMqL=!mdDTn;rD+4Ug$|9?bE`uh*U2WLPa{qpSxhC|0r{$XY1Iu4Qs
zsR0NekXCL%Nfk{=HIr>WK0g=v`}+qYxWIy?I7r#TfR>0Lw)}@vV2ju|`Tue9NL|0U
zcYz;J=qWIz{R9XgMrbiF0K`&2EXaTe4N?Kf9#GJ{0pjOC`~_4e0|XEwQc!V%s!s+~
n$C3(wF~jf!iovZ4fB*vk{nvi;!|I_m00000NkvXXu0mjfixE5#
new file mode 100644
index 0000000000000000000000000000000000000000..76553571d9744faf08b3ca6548eb1ee429fa9cc8
GIT binary patch
literal 818
zc$@(;1I_%2P)<h;3K|Lk000e1NJLTq000;O000*V1^@s65h0H)00004XF*Lt007q5
z)K6G40000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!#7RU!RCwBA
zWB`Jmo*n@{KE5Mw-n`NL_wOGQ1DSx0jqR7HsOYxD#Kd4A_uv2j{}})R2qextXU?3X
z$B!TX|NHmv|CE5wpFjWKzJ2?jsZ*!U0Gi7LvH&1}Sbz+Uw{PE?nwy)0UGe?<cLtzE
zB)guSot=S)hljzyz<~Mk<;&hcAyy#%2@pUa3)p}C`o+q~$Vj%~An^0&PX>?~TwGiX
zK=ZgjAqEl#2q2IJEHFiX{`>(eA{PJ+2I~jLBRJ?m1V8|R4TlOaz#@fQfTSPJ00<x^
zWC@V%`0%`W^T3Y5rv?Q6{{0KL6d-_@h;{k-^XD1XuV2rwYu7GPe8K<_KqwY4F)?Aq
zA3uI%=<V$VtD8G_F2nQZ&vB{+sX?{?Ab^MpqW=DVhWGE^!;>+{GMGM4ssrI~-@bt{
zRLvil1pooWgdEA(z}mHI8BU)*4K@s<4ivt?bj~ns+BAk&uU;{{d-o2Eftd`9L2ABy
z`2tVt00D$z0kW$>-aU2d6vK=eGr%qcC1H@^AhjUN)~#Cyju-SGf&zG22M8b*WY@yd
zFeuZ2g5tn|0}Q~j1z95;fYe>MaDl<p)RY0;3}gThKrG0~>g(69V1r>GB_)Ndynr0Z
z009KI03--<IX2glVF}zD00G1TD@S0-l-d9wfLLJOf<-JP04X29eE<+ZEXer)R1*I9
z@q=s&xVgFEc>x9h0*D1_^G~29>>vdo%Rr?fseprngMpKili}sdmmn_Ol>h+*vfvNU
zg0nk!?zD1oabe))<t5t(pFVwJ0M?AZfr;iIDD8m600IaUR@^c&G8)Fl#v6f2R0<g3
zWLF5lApQ;X$pv7c7y;xy1%}2?fB<5IRty3_ECs}ZP+yT_2`C~#$?**kKL_G3Knwl>
w1P~)qP;r8)PgwCmCinvl{~xec1weoS0A>@TalLnur2qf`07*qoM6N<$f)Wy5t^fc4
new file mode 100644
--- /dev/null
+++ b/mail/themes/pinstripe/sanitizeDialog.css
@@ -0,0 +1,104 @@
+/* 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/. */
+
+/* Align the duration label with the warning box and item list */
+#sanitizeDurationLabel {
+ -moz-margin-start: 1px;
+}
+
+
+/* Hide the duration dropdown suffix label if it's empty. Otherwise it
+ takes up a little space, causing the end of the dropdown to not be aligned
+ with the warning box. */
+#sanitizeDurationSuffixLabel[value=""] {
+ display: none;
+}
+
+
+/* Places tree */
+#placesTreechildren::-moz-tree-row(selected),
+#placesTreechildren::-moz-tree-row(grippyRow) {
+ background: #999;
+}
+
+#placesTreechildren::-moz-tree-cell-text(selected) {
+ color: #111;
+}
+
+
+/* Sanitize everything warning box */
+#sanitizeEverythingWarningBox {
+ background-color: Window;
+ border: 1px solid ThreeDDarkShadow;
+ border-radius: 5px;
+ padding: 16px;
+}
+
+#sanitizeEverythingWarningIcon {
+ list-style-image: url("chrome://global/skin/icons/warning-large.png");
+ padding: 0;
+ margin: 0;
+}
+
+#sanitizeEverythingWarningDescBox {
+ padding: 0 16px;
+ margin: 0;
+}
+
+
+/* Progressive disclosure button */
+#detailsExpanderWrapper {
+ padding: 0;
+ margin-top: 6px;
+ margin-bottom: 6px;
+ -moz-margin-start: -2px;
+ -moz-margin-end: 0;
+}
+
+.expander-up,
+.expander-down {
+ -moz-appearance: none;
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+}
+
+.expander-up {
+ list-style-image: url("chrome://messenger/skin/places/expander-open.png");
+}
+
+.expander-up:hover:active {
+ list-style-image: url("chrome://messenger/skin/places/expander-open-active.png");
+}
+
+.expander-down {
+ list-style-image: url("chrome://messenger/skin/places/expander-closed.png");
+}
+
+.expander-down:hover:active {
+ list-style-image: url("chrome://messenger/skin/places/expander-closed-active.png");
+}
+
+
+/* Make the item list the same width as the warning box */
+#itemList {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+/* Without this a useless scrollbar appears in the listbox when its rows
+ attribute is set to the total number of listitems, as it is currently. See
+ bug 489958 comment 14 and bug 491788. */
+#itemList > listitem {
+ padding: 1px 0;
+}
+
+
+/* Align the last dialog button with the end of the warning box */
+.prefWindow-dlgbuttons {
+ -moz-margin-end: 0;
+}
+.dialog-button[dlgtype="accept"] {
+ -moz-margin-end: 0;
+}
--- a/mail/themes/qute/jar.mn
+++ b/mail/themes/qute/jar.mn
@@ -267,16 +267,17 @@ classic.jar:
skin/classic/messenger/newmailaccount/accountProvisioner.css (mail/newmailaccount/accountProvisioner.css)
skin/classic/messenger/newmailaccount/search.gif (mail/newmailaccount/search.gif)
skin/classic/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
skin/classic/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
skin/classic/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
skin/classic/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
skin/classic/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
skin/classic/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
+ skin/classic/messenger/sanitizeDialog.css (sanitizeDialog.css)
skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
skin/classic/messenger/icons/box-logo.png (mail/icons/box-logo.png)
#ifdef XP_WIN
% skin communicator classic/1.0 %skin/classic/aero/communicator/ os=WINNT osversion>=6
skin/classic/aero/communicator/communicator.css (mail/communicator.css)
skin/classic/aero/communicator/smileys.css (mail/smileys.css)
skin/classic/aero/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile-aero.png)
@@ -528,10 +529,11 @@ classic.jar:
skin/classic/aero/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
skin/classic/aero/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
skin/classic/aero/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
skin/classic/aero/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
skin/classic/aero/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
skin/classic/aero/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
skin/classic/aero/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
skin/classic/aero/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/aero/messenger/sanitizeDialog.css (sanitizeDialog.css)
skin/classic/aero/messenger/icons/box-logo.png (mail/icons/box-logo.png)
#endif
new file mode 100644
--- /dev/null
+++ b/mail/themes/qute/sanitizeDialog.css
@@ -0,0 +1,93 @@
+/* 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/. */
+
+#sanitizeDurationChoice {
+ -moz-margin-end: 0;
+}
+
+/* Align the duration label with the warning box and item list */
+#sanitizeDurationLabel {
+ -moz-margin-start: 3px;
+}
+
+
+/* Hide the duration dropdown suffix label if it's empty. Otherwise it
+ takes up a little space, causing the end of the dropdown to not be aligned
+ with the warning box. */
+#sanitizeDurationSuffixLabel[value=""] {
+ display: none;
+}
+
+
+/* Places tree */
+#placesTreechildren::-moz-tree-row(selected),
+#placesTreechildren::-moz-tree-row(grippyRow) {
+ background: #999;
+}
+
+#placesTreechildren::-moz-tree-cell-text(selected) {
+ color: #111;
+}
+
+
+/* Sanitize everything warning box */
+#sanitizeEverythingWarningBox {
+ background-color: Window;
+ border: 1px solid ThreeDDarkShadow;
+ border-radius: 5px;
+ padding: 16px;
+}
+
+#sanitizeEverythingWarningIcon {
+ list-style-image: url("chrome://global/skin/icons/warning-large.png");
+ padding: 0;
+ margin: 0;
+}
+
+#sanitizeEverythingWarningDescBox {
+ padding: 0 16px;
+ margin: 0;
+}
+
+
+/* Progressive disclosure button */
+#detailsExpanderWrapper {
+ padding: 0;
+ margin: 6px 0;
+}
+
+.expander-up,
+.expander-down {
+ min-width: 0;
+ margin: 0;
+}
+
+.expander-up > .button-box,
+.expander-down > .button-box {
+ padding: 0;
+}
+
+.expander-up {
+ list-style-image: url("chrome://global/skin/icons/collapse.png");
+}
+
+.expander-down {
+ list-style-image: url("chrome://global/skin/icons/expand.png");
+}
+
+
+/* Make the item list the same width as the warning box */
+#itemList {
+ -moz-margin-start: 0;
+ -moz-margin-end: 0;
+}
+
+
+/* Align the last dialog button with the end of the warning box */
+.prefWindow-dlgbuttons {
+ -moz-margin-end: 0;
+}
+.dialog-button[dlgtype="cancel"] {
+ -moz-margin-end: 0;
+}