1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/preferences/privacy.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,542 @@ 1.4 +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); 1.10 + 1.11 +var gPrivacyPane = { 1.12 + 1.13 + /** 1.14 + * Whether the use has selected the auto-start private browsing mode in the UI. 1.15 + */ 1.16 + _autoStartPrivateBrowsing: false, 1.17 + 1.18 + /** 1.19 + * Whether the prompt to restart Firefox should appear when changing the autostart pref. 1.20 + */ 1.21 + _shouldPromptForRestart: true, 1.22 + 1.23 + /** 1.24 + * Sets up the UI for the number of days of history to keep, and updates the 1.25 + * label of the "Clear Now..." button. 1.26 + */ 1.27 + init: function () 1.28 + { 1.29 + this._updateSanitizeSettingsButton(); 1.30 + this.initializeHistoryMode(); 1.31 + this.updateHistoryModePane(); 1.32 + this.updatePrivacyMicroControls(); 1.33 + this.initAutoStartPrivateBrowsingReverter(); 1.34 + }, 1.35 + 1.36 + // HISTORY MODE 1.37 + 1.38 + /** 1.39 + * The list of preferences which affect the initial history mode settings. 1.40 + * If the auto start private browsing mode pref is active, the initial 1.41 + * history mode would be set to "Don't remember anything". 1.42 + * If all of these preferences have their default values, and the auto-start 1.43 + * private browsing mode is not active, the initial history mode would be 1.44 + * set to "Remember everything". 1.45 + * Otherwise, the initial history mode would be set to "Custom". 1.46 + * 1.47 + * Extensions adding their own preferences can append their IDs to this array if needed. 1.48 + */ 1.49 + prefsForDefault: [ 1.50 + "places.history.enabled", 1.51 + "browser.formfill.enable", 1.52 + "network.cookie.cookieBehavior", 1.53 + "network.cookie.lifetimePolicy", 1.54 + "privacy.sanitize.sanitizeOnShutdown" 1.55 + ], 1.56 + 1.57 + /** 1.58 + * The list of control IDs which are dependent on the auto-start private 1.59 + * browsing setting, such that in "Custom" mode they would be disabled if 1.60 + * the auto-start private browsing checkbox is checked, and enabled otherwise. 1.61 + * 1.62 + * Extensions adding their own controls can append their IDs to this array if needed. 1.63 + */ 1.64 + dependentControls: [ 1.65 + "rememberHistory", 1.66 + "rememberForms", 1.67 + "keepUntil", 1.68 + "keepCookiesUntil", 1.69 + "alwaysClear", 1.70 + "clearDataSettings" 1.71 + ], 1.72 + 1.73 + /** 1.74 + * Check whether all the preferences values are set to their default values 1.75 + * 1.76 + * @param aPrefs an array of pref names to check for 1.77 + * @returns boolean true if all of the prefs are set to their default values, 1.78 + * false otherwise 1.79 + */ 1.80 + _checkDefaultValues: function(aPrefs) { 1.81 + for (let i = 0; i < aPrefs.length; ++i) { 1.82 + let pref = document.getElementById(aPrefs[i]); 1.83 + if (pref.value != pref.defaultValue) 1.84 + return false; 1.85 + } 1.86 + return true; 1.87 + }, 1.88 + 1.89 + /** 1.90 + * Initialize the history mode menulist based on the privacy preferences 1.91 + */ 1.92 + initializeHistoryMode: function PPP_initializeHistoryMode() 1.93 + { 1.94 + let mode; 1.95 + let getVal = function (aPref) 1.96 + document.getElementById(aPref).value; 1.97 + 1.98 + if (this._checkDefaultValues(this.prefsForDefault)) { 1.99 + if (getVal("browser.privatebrowsing.autostart")) 1.100 + mode = "dontremember"; 1.101 + else 1.102 + mode = "remember"; 1.103 + } 1.104 + else 1.105 + mode = "custom"; 1.106 + 1.107 + document.getElementById("historyMode").value = mode; 1.108 + }, 1.109 + 1.110 + /** 1.111 + * Update the selected pane based on the history mode menulist 1.112 + */ 1.113 + updateHistoryModePane: function PPP_updateHistoryModePane() 1.114 + { 1.115 + let selectedIndex = -1; 1.116 + switch (document.getElementById("historyMode").value) { 1.117 + case "remember": 1.118 + selectedIndex = 0; 1.119 + break; 1.120 + case "dontremember": 1.121 + selectedIndex = 1; 1.122 + break; 1.123 + case "custom": 1.124 + selectedIndex = 2; 1.125 + break; 1.126 + } 1.127 + document.getElementById("historyPane").selectedIndex = selectedIndex; 1.128 + }, 1.129 + 1.130 + /** 1.131 + * Update the Tracking preferences based on controls. 1.132 + */ 1.133 + setTrackingPrefs: function PPP_setTrackingPrefs() 1.134 + { 1.135 + let dntRadioGroup = document.getElementById("doNotTrackSelection"), 1.136 + dntValuePref = document.getElementById("privacy.donottrackheader.value"), 1.137 + dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled"); 1.138 + 1.139 + // if the selected radio button says "no preference", set on/off pref to 1.140 + // false and don't change the value pref. 1.141 + if (dntRadioGroup.selectedItem.value == -1) { 1.142 + dntEnabledPref.value = false; 1.143 + return dntValuePref.value; 1.144 + } 1.145 + 1.146 + dntEnabledPref.value = true; 1.147 + return dntRadioGroup.selectedItem.value; 1.148 + }, 1.149 + 1.150 + /** 1.151 + * Obtain the tracking preference value and reflect it in the UI. 1.152 + */ 1.153 + getTrackingPrefs: function PPP_getTrackingPrefs() 1.154 + { 1.155 + let dntValuePref = document.getElementById("privacy.donottrackheader.value"), 1.156 + dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled"); 1.157 + 1.158 + // if DNT is enbaled, select the value from the selected radio 1.159 + // button, otherwise choose the "no preference" radio button 1.160 + if (dntEnabledPref.value) 1.161 + return dntValuePref.value; 1.162 + 1.163 + return document.getElementById("dntnopref").value; 1.164 + }, 1.165 + 1.166 + /** 1.167 + * Update the private browsing auto-start pref and the history mode 1.168 + * micro-management prefs based on the history mode menulist 1.169 + */ 1.170 + updateHistoryModePrefs: function PPP_updateHistoryModePrefs() 1.171 + { 1.172 + let pref = document.getElementById("browser.privatebrowsing.autostart"); 1.173 + switch (document.getElementById("historyMode").value) { 1.174 + case "remember": 1.175 + if (pref.value) 1.176 + pref.value = false; 1.177 + 1.178 + // select the remember history option if needed 1.179 + let rememberHistoryCheckbox = document.getElementById("rememberHistory"); 1.180 + if (!rememberHistoryCheckbox.checked) 1.181 + rememberHistoryCheckbox.checked = true; 1.182 + 1.183 + // select the remember forms history option 1.184 + document.getElementById("browser.formfill.enable").value = true; 1.185 + 1.186 +#ifdef RELEASE_BUILD 1.187 + // select the accept cookies option 1.188 + document.getElementById("network.cookie.cookieBehavior").value = 0; 1.189 +#else 1.190 + // select the limit cookies option 1.191 + document.getElementById("network.cookie.cookieBehavior").value = 3; 1.192 +#endif 1.193 + // select the cookie lifetime policy option 1.194 + document.getElementById("network.cookie.lifetimePolicy").value = 0; 1.195 + 1.196 + // select the clear on close option 1.197 + document.getElementById("privacy.sanitize.sanitizeOnShutdown").value = false; 1.198 + break; 1.199 + case "dontremember": 1.200 + if (!pref.value) 1.201 + pref.value = true; 1.202 + break; 1.203 + } 1.204 + }, 1.205 + 1.206 + /** 1.207 + * Update the privacy micro-management controls based on the 1.208 + * value of the private browsing auto-start checkbox. 1.209 + */ 1.210 + updatePrivacyMicroControls: function PPP_updatePrivacyMicroControls() 1.211 + { 1.212 + if (document.getElementById("historyMode").value == "custom") { 1.213 + let disabled = this._autoStartPrivateBrowsing = 1.214 + document.getElementById("privateBrowsingAutoStart").checked; 1.215 + this.dependentControls 1.216 + .forEach(function (aElement) 1.217 + document.getElementById(aElement).disabled = disabled); 1.218 + 1.219 + // adjust the cookie controls status 1.220 + this.readAcceptCookies(); 1.221 + document.getElementById("keepCookiesUntil").value = disabled ? 2 : 1.222 + document.getElementById("network.cookie.lifetimePolicy").value; 1.223 + 1.224 + // adjust the checked state of the sanitizeOnShutdown checkbox 1.225 + document.getElementById("alwaysClear").checked = disabled ? false : 1.226 + document.getElementById("privacy.sanitize.sanitizeOnShutdown").value; 1.227 + 1.228 + // adjust the checked state of the remember history checkboxes 1.229 + document.getElementById("rememberHistory").checked = disabled ? false : 1.230 + document.getElementById("places.history.enabled").value; 1.231 + document.getElementById("rememberForms").checked = disabled ? false : 1.232 + document.getElementById("browser.formfill.enable").value; 1.233 + 1.234 + if (!disabled) { 1.235 + // adjust the Settings button for sanitizeOnShutdown 1.236 + this._updateSanitizeSettingsButton(); 1.237 + } 1.238 + } 1.239 + }, 1.240 + 1.241 + // PRIVATE BROWSING 1.242 + 1.243 + /** 1.244 + * Initialize the starting state for the auto-start private browsing mode pref reverter. 1.245 + */ 1.246 + initAutoStartPrivateBrowsingReverter: function PPP_initAutoStartPrivateBrowsingReverter() 1.247 + { 1.248 + let mode = document.getElementById("historyMode"); 1.249 + let autoStart = document.getElementById("privateBrowsingAutoStart"); 1.250 + this._lastMode = mode.selectedIndex; 1.251 + this._lastCheckState = autoStart.hasAttribute('checked'); 1.252 + }, 1.253 + 1.254 + _lastMode: null, 1.255 + _lastCheckState: null, 1.256 + updateAutostart: function PPP_updateAutostart() { 1.257 + let mode = document.getElementById("historyMode"); 1.258 + let autoStart = document.getElementById("privateBrowsingAutoStart"); 1.259 + let pref = document.getElementById("browser.privatebrowsing.autostart"); 1.260 + if ((mode.value == "custom" && this._lastCheckState == autoStart.checked) || 1.261 + (mode.value == "remember" && !this._lastCheckState) || 1.262 + (mode.value == "dontremember" && this._lastCheckState)) { 1.263 + // These are all no-op changes, so we don't need to prompt. 1.264 + this._lastMode = mode.selectedIndex; 1.265 + this._lastCheckState = autoStart.hasAttribute('checked'); 1.266 + return; 1.267 + } 1.268 + 1.269 + if (!this._shouldPromptForRestart) { 1.270 + // We're performing a revert. Just let it happen. 1.271 + return; 1.272 + } 1.273 + 1.274 + const Cc = Components.classes, Ci = Components.interfaces; 1.275 + let brandName = document.getElementById("bundleBrand").getString("brandShortName"); 1.276 + let bundle = document.getElementById("bundlePreferences"); 1.277 + let msg = bundle.getFormattedString(autoStart.checked ? 1.278 + "featureEnableRequiresRestart" : "featureDisableRequiresRestart", 1.279 + [brandName]); 1.280 + let title = bundle.getFormattedString("shouldRestartTitle", [brandName]); 1.281 + let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService); 1.282 + let shouldProceed = prompts.confirm(window, title, msg) 1.283 + if (shouldProceed) { 1.284 + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] 1.285 + .createInstance(Ci.nsISupportsPRBool); 1.286 + Services.obs.notifyObservers(cancelQuit, "quit-application-requested", 1.287 + "restart"); 1.288 + shouldProceed = !cancelQuit.data; 1.289 + 1.290 + if (shouldProceed) { 1.291 + pref.value = autoStart.hasAttribute('checked'); 1.292 + document.documentElement.acceptDialog(); 1.293 + let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] 1.294 + .getService(Ci.nsIAppStartup); 1.295 + appStartup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); 1.296 + return; 1.297 + } 1.298 + } 1.299 + 1.300 + this._shouldPromptForRestart = false; 1.301 + 1.302 + if (this._lastCheckState) { 1.303 + autoStart.checked = "checked"; 1.304 + } else { 1.305 + autoStart.removeAttribute('checked'); 1.306 + } 1.307 + pref.value = autoStart.hasAttribute('checked'); 1.308 + mode.selectedIndex = this._lastMode; 1.309 + mode.doCommand(); 1.310 + 1.311 + this._shouldPromptForRestart = true; 1.312 + }, 1.313 + 1.314 + // HISTORY 1.315 + 1.316 + /** 1.317 + * Read the location bar enabled and suggestion prefs 1.318 + * @return Int value for suggestion menulist 1.319 + */ 1.320 + readSuggestionPref: function PPP_readSuggestionPref() 1.321 + { 1.322 + let getVal = function(aPref) 1.323 + document.getElementById("browser.urlbar." + aPref).value; 1.324 + 1.325 + // Suggest nothing if autocomplete is not enabled 1.326 + if (!getVal("autocomplete.enabled")) 1.327 + return -1; 1.328 + 1.329 + // Bottom 2 bits of default.behavior specify history/bookmark 1.330 + return getVal("default.behavior") & 3; 1.331 + }, 1.332 + 1.333 + /** 1.334 + * Write the location bar enabled and suggestion prefs when necessary 1.335 + * @return Bool value for enabled pref 1.336 + */ 1.337 + writeSuggestionPref: function PPP_writeSuggestionPref() 1.338 + { 1.339 + let menuVal = document.getElementById("locationBarSuggestion").value; 1.340 + let enabled = menuVal != -1; 1.341 + 1.342 + // Only update default.behavior if we're giving suggestions 1.343 + if (enabled) { 1.344 + // Put the selected menu item's value directly into the bottom 2 bits 1.345 + let behavior = document.getElementById("browser.urlbar.default.behavior"); 1.346 + behavior.value = behavior.value >> 2 << 2 | menuVal; 1.347 + } 1.348 + 1.349 + // Always update the enabled pref 1.350 + return enabled; 1.351 + }, 1.352 + 1.353 + /* 1.354 + * Preferences: 1.355 + * 1.356 + * places.history.enabled 1.357 + * - whether history is enabled or not 1.358 + * browser.formfill.enable 1.359 + * - true if entries in forms and the search bar should be saved, false 1.360 + * otherwise 1.361 + */ 1.362 + 1.363 + // COOKIES 1.364 + 1.365 + /* 1.366 + * Preferences: 1.367 + * 1.368 + * network.cookie.cookieBehavior 1.369 + * - determines how the browser should handle cookies: 1.370 + * 0 means enable all cookies 1.371 + * 1 means reject all third party cookies 1.372 + * 2 means disable all cookies 1.373 + * 3 means reject third party cookies unless at least one is already set for the eTLD 1.374 + * see netwerk/cookie/src/nsCookieService.cpp for details 1.375 + * network.cookie.lifetimePolicy 1.376 + * - determines how long cookies are stored: 1.377 + * 0 means keep cookies until they expire 1.378 + * 1 means ask how long to keep each cookie 1.379 + * 2 means keep cookies until the browser is closed 1.380 + */ 1.381 + 1.382 + /** 1.383 + * Reads the network.cookie.cookieBehavior preference value and 1.384 + * enables/disables the rest of the cookie UI accordingly, returning true 1.385 + * if cookies are enabled. 1.386 + */ 1.387 + readAcceptCookies: function () 1.388 + { 1.389 + var pref = document.getElementById("network.cookie.cookieBehavior"); 1.390 + var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel"); 1.391 + var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu"); 1.392 + var keepUntil = document.getElementById("keepUntil"); 1.393 + var menu = document.getElementById("keepCookiesUntil"); 1.394 + 1.395 + // enable the rest of the UI for anything other than "disable all cookies" 1.396 + var acceptCookies = (pref.value != 2); 1.397 + 1.398 + acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies; 1.399 + keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies; 1.400 + 1.401 + return acceptCookies; 1.402 + }, 1.403 + 1.404 + /** 1.405 + * Enables/disables the "keep until" label and menulist in response to the 1.406 + * "accept cookies" checkbox being checked or unchecked. 1.407 + */ 1.408 + writeAcceptCookies: function () 1.409 + { 1.410 + var accept = document.getElementById("acceptCookies"); 1.411 + var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu"); 1.412 + 1.413 +#ifdef RELEASE_BUILD 1.414 + // if we're enabling cookies, automatically select 'accept third party always' 1.415 + if (accept.checked) 1.416 + acceptThirdPartyMenu.selectedIndex = 0; 1.417 + 1.418 + return accept.checked ? 0 : 2; 1.419 +#else 1.420 + // if we're enabling cookies, automatically select 'accept third party from visited' 1.421 + if (accept.checked) 1.422 + acceptThirdPartyMenu.selectedIndex = 1; 1.423 + 1.424 + return accept.checked ? 3 : 2; 1.425 +#endif 1.426 + }, 1.427 + 1.428 + /** 1.429 + * Converts between network.cookie.cookieBehavior and the third-party cookie UI 1.430 + */ 1.431 + readAcceptThirdPartyCookies: function () 1.432 + { 1.433 + var pref = document.getElementById("network.cookie.cookieBehavior"); 1.434 + switch (pref.value) 1.435 + { 1.436 + case 0: 1.437 + return "always"; 1.438 + case 1: 1.439 + return "never"; 1.440 + case 2: 1.441 + return "never"; 1.442 + case 3: 1.443 + return "visited"; 1.444 + default: 1.445 + return undefined; 1.446 + } 1.447 + }, 1.448 + 1.449 + writeAcceptThirdPartyCookies: function () 1.450 + { 1.451 + var accept = document.getElementById("acceptThirdPartyMenu").selectedItem; 1.452 + switch (accept.value) 1.453 + { 1.454 + case "always": 1.455 + return 0; 1.456 + case "visited": 1.457 + return 3; 1.458 + case "never": 1.459 + return 1; 1.460 + default: 1.461 + return undefined; 1.462 + } 1.463 + }, 1.464 + 1.465 + /** 1.466 + * Displays fine-grained, per-site preferences for cookies. 1.467 + */ 1.468 + showCookieExceptions: function () 1.469 + { 1.470 + var bundlePreferences = document.getElementById("bundlePreferences"); 1.471 + var params = { blockVisible : true, 1.472 + sessionVisible : true, 1.473 + allowVisible : true, 1.474 + prefilledHost : "", 1.475 + permissionType : "cookie", 1.476 + windowTitle : bundlePreferences.getString("cookiepermissionstitle"), 1.477 + introText : bundlePreferences.getString("cookiepermissionstext") }; 1.478 + document.documentElement.openWindow("Browser:Permissions", 1.479 + "chrome://browser/content/preferences/permissions.xul", 1.480 + "", params); 1.481 + }, 1.482 + 1.483 + /** 1.484 + * Displays all the user's cookies in a dialog. 1.485 + */ 1.486 + showCookies: function (aCategory) 1.487 + { 1.488 + document.documentElement.openWindow("Browser:Cookies", 1.489 + "chrome://browser/content/preferences/cookies.xul", 1.490 + "", null); 1.491 + }, 1.492 + 1.493 + // CLEAR PRIVATE DATA 1.494 + 1.495 + /* 1.496 + * Preferences: 1.497 + * 1.498 + * privacy.sanitize.sanitizeOnShutdown 1.499 + * - true if the user's private data is cleared on startup according to the 1.500 + * Clear Private Data settings, false otherwise 1.501 + */ 1.502 + 1.503 + /** 1.504 + * Displays the Clear Private Data settings dialog. 1.505 + */ 1.506 + showClearPrivateDataSettings: function () 1.507 + { 1.508 + document.documentElement.openSubDialog("chrome://browser/content/preferences/sanitize.xul", 1.509 + "", null); 1.510 + }, 1.511 + 1.512 + 1.513 + /** 1.514 + * Displays a dialog from which individual parts of private data may be 1.515 + * cleared. 1.516 + */ 1.517 + clearPrivateDataNow: function (aClearEverything) 1.518 + { 1.519 + var ts = document.getElementById("privacy.sanitize.timeSpan"); 1.520 + var timeSpanOrig = ts.value; 1.521 + if (aClearEverything) 1.522 + ts.value = 0; 1.523 + 1.524 + const Cc = Components.classes, Ci = Components.interfaces; 1.525 + var glue = Cc["@mozilla.org/browser/browserglue;1"] 1.526 + .getService(Ci.nsIBrowserGlue); 1.527 + glue.sanitize(window); 1.528 + 1.529 + // reset the timeSpan pref 1.530 + if (aClearEverything) 1.531 + ts.value = timeSpanOrig; 1.532 + }, 1.533 + 1.534 + /** 1.535 + * Enables or disables the "Settings..." button depending 1.536 + * on the privacy.sanitize.sanitizeOnShutdown preference value 1.537 + */ 1.538 + _updateSanitizeSettingsButton: function () { 1.539 + var settingsButton = document.getElementById("clearDataSettings"); 1.540 + var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown"); 1.541 + 1.542 + settingsButton.disabled = !sanitizeOnShutdownPref.value; 1.543 + } 1.544 + 1.545 +};