michael@0: /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: var gPrivacyPane = { michael@0: michael@0: /** michael@0: * Whether the use has selected the auto-start private browsing mode in the UI. michael@0: */ michael@0: _autoStartPrivateBrowsing: false, michael@0: michael@0: /** michael@0: * Whether the prompt to restart Firefox should appear when changing the autostart pref. michael@0: */ michael@0: _shouldPromptForRestart: true, michael@0: michael@0: /** michael@0: * Sets up the UI for the number of days of history to keep, and updates the michael@0: * label of the "Clear Now..." button. michael@0: */ michael@0: init: function () michael@0: { michael@0: this._updateSanitizeSettingsButton(); michael@0: this.initializeHistoryMode(); michael@0: this.updateHistoryModePane(); michael@0: this.updatePrivacyMicroControls(); michael@0: this.initAutoStartPrivateBrowsingReverter(); michael@0: }, michael@0: michael@0: // HISTORY MODE michael@0: michael@0: /** michael@0: * The list of preferences which affect the initial history mode settings. michael@0: * If the auto start private browsing mode pref is active, the initial michael@0: * history mode would be set to "Don't remember anything". michael@0: * If all of these preferences have their default values, and the auto-start michael@0: * private browsing mode is not active, the initial history mode would be michael@0: * set to "Remember everything". michael@0: * Otherwise, the initial history mode would be set to "Custom". michael@0: * michael@0: * Extensions adding their own preferences can append their IDs to this array if needed. michael@0: */ michael@0: prefsForDefault: [ michael@0: "places.history.enabled", michael@0: "browser.formfill.enable", michael@0: "network.cookie.cookieBehavior", michael@0: "network.cookie.lifetimePolicy", michael@0: "privacy.sanitize.sanitizeOnShutdown" michael@0: ], michael@0: michael@0: /** michael@0: * The list of control IDs which are dependent on the auto-start private michael@0: * browsing setting, such that in "Custom" mode they would be disabled if michael@0: * the auto-start private browsing checkbox is checked, and enabled otherwise. michael@0: * michael@0: * Extensions adding their own controls can append their IDs to this array if needed. michael@0: */ michael@0: dependentControls: [ michael@0: "rememberHistory", michael@0: "rememberForms", michael@0: "keepUntil", michael@0: "keepCookiesUntil", michael@0: "alwaysClear", michael@0: "clearDataSettings" michael@0: ], michael@0: michael@0: /** michael@0: * Check whether all the preferences values are set to their default values michael@0: * michael@0: * @param aPrefs an array of pref names to check for michael@0: * @returns boolean true if all of the prefs are set to their default values, michael@0: * false otherwise michael@0: */ michael@0: _checkDefaultValues: function(aPrefs) { michael@0: for (let i = 0; i < aPrefs.length; ++i) { michael@0: let pref = document.getElementById(aPrefs[i]); michael@0: if (pref.value != pref.defaultValue) michael@0: return false; michael@0: } michael@0: return true; michael@0: }, michael@0: michael@0: /** michael@0: * Initialize the history mode menulist based on the privacy preferences michael@0: */ michael@0: initializeHistoryMode: function PPP_initializeHistoryMode() michael@0: { michael@0: let mode; michael@0: let getVal = function (aPref) michael@0: document.getElementById(aPref).value; michael@0: michael@0: if (this._checkDefaultValues(this.prefsForDefault)) { michael@0: if (getVal("browser.privatebrowsing.autostart")) michael@0: mode = "dontremember"; michael@0: else michael@0: mode = "remember"; michael@0: } michael@0: else michael@0: mode = "custom"; michael@0: michael@0: document.getElementById("historyMode").value = mode; michael@0: }, michael@0: michael@0: /** michael@0: * Update the selected pane based on the history mode menulist michael@0: */ michael@0: updateHistoryModePane: function PPP_updateHistoryModePane() michael@0: { michael@0: let selectedIndex = -1; michael@0: switch (document.getElementById("historyMode").value) { michael@0: case "remember": michael@0: selectedIndex = 0; michael@0: break; michael@0: case "dontremember": michael@0: selectedIndex = 1; michael@0: break; michael@0: case "custom": michael@0: selectedIndex = 2; michael@0: break; michael@0: } michael@0: document.getElementById("historyPane").selectedIndex = selectedIndex; michael@0: }, michael@0: michael@0: /** michael@0: * Update the Tracking preferences based on controls. michael@0: */ michael@0: setTrackingPrefs: function PPP_setTrackingPrefs() michael@0: { michael@0: let dntRadioGroup = document.getElementById("doNotTrackSelection"), michael@0: dntValuePref = document.getElementById("privacy.donottrackheader.value"), michael@0: dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled"); michael@0: michael@0: // if the selected radio button says "no preference", set on/off pref to michael@0: // false and don't change the value pref. michael@0: if (dntRadioGroup.selectedItem.value == -1) { michael@0: dntEnabledPref.value = false; michael@0: return dntValuePref.value; michael@0: } michael@0: michael@0: dntEnabledPref.value = true; michael@0: return dntRadioGroup.selectedItem.value; michael@0: }, michael@0: michael@0: /** michael@0: * Obtain the tracking preference value and reflect it in the UI. michael@0: */ michael@0: getTrackingPrefs: function PPP_getTrackingPrefs() michael@0: { michael@0: let dntValuePref = document.getElementById("privacy.donottrackheader.value"), michael@0: dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled"); michael@0: michael@0: // if DNT is enbaled, select the value from the selected radio michael@0: // button, otherwise choose the "no preference" radio button michael@0: if (dntEnabledPref.value) michael@0: return dntValuePref.value; michael@0: michael@0: return document.getElementById("dntnopref").value; michael@0: }, michael@0: michael@0: /** michael@0: * Update the private browsing auto-start pref and the history mode michael@0: * micro-management prefs based on the history mode menulist michael@0: */ michael@0: updateHistoryModePrefs: function PPP_updateHistoryModePrefs() michael@0: { michael@0: let pref = document.getElementById("browser.privatebrowsing.autostart"); michael@0: switch (document.getElementById("historyMode").value) { michael@0: case "remember": michael@0: if (pref.value) michael@0: pref.value = false; michael@0: michael@0: // select the remember history option if needed michael@0: let rememberHistoryCheckbox = document.getElementById("rememberHistory"); michael@0: if (!rememberHistoryCheckbox.checked) michael@0: rememberHistoryCheckbox.checked = true; michael@0: michael@0: // select the remember forms history option michael@0: document.getElementById("browser.formfill.enable").value = true; michael@0: michael@0: #ifdef RELEASE_BUILD michael@0: // select the accept cookies option michael@0: document.getElementById("network.cookie.cookieBehavior").value = 0; michael@0: #else michael@0: // select the limit cookies option michael@0: document.getElementById("network.cookie.cookieBehavior").value = 3; michael@0: #endif michael@0: // select the cookie lifetime policy option michael@0: document.getElementById("network.cookie.lifetimePolicy").value = 0; michael@0: michael@0: // select the clear on close option michael@0: document.getElementById("privacy.sanitize.sanitizeOnShutdown").value = false; michael@0: break; michael@0: case "dontremember": michael@0: if (!pref.value) michael@0: pref.value = true; michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Update the privacy micro-management controls based on the michael@0: * value of the private browsing auto-start checkbox. michael@0: */ michael@0: updatePrivacyMicroControls: function PPP_updatePrivacyMicroControls() michael@0: { michael@0: if (document.getElementById("historyMode").value == "custom") { michael@0: let disabled = this._autoStartPrivateBrowsing = michael@0: document.getElementById("privateBrowsingAutoStart").checked; michael@0: this.dependentControls michael@0: .forEach(function (aElement) michael@0: document.getElementById(aElement).disabled = disabled); michael@0: michael@0: // adjust the cookie controls status michael@0: this.readAcceptCookies(); michael@0: document.getElementById("keepCookiesUntil").value = disabled ? 2 : michael@0: document.getElementById("network.cookie.lifetimePolicy").value; michael@0: michael@0: // adjust the checked state of the sanitizeOnShutdown checkbox michael@0: document.getElementById("alwaysClear").checked = disabled ? false : michael@0: document.getElementById("privacy.sanitize.sanitizeOnShutdown").value; michael@0: michael@0: // adjust the checked state of the remember history checkboxes michael@0: document.getElementById("rememberHistory").checked = disabled ? false : michael@0: document.getElementById("places.history.enabled").value; michael@0: document.getElementById("rememberForms").checked = disabled ? false : michael@0: document.getElementById("browser.formfill.enable").value; michael@0: michael@0: if (!disabled) { michael@0: // adjust the Settings button for sanitizeOnShutdown michael@0: this._updateSanitizeSettingsButton(); michael@0: } michael@0: } michael@0: }, michael@0: michael@0: // PRIVATE BROWSING michael@0: michael@0: /** michael@0: * Initialize the starting state for the auto-start private browsing mode pref reverter. michael@0: */ michael@0: initAutoStartPrivateBrowsingReverter: function PPP_initAutoStartPrivateBrowsingReverter() michael@0: { michael@0: let mode = document.getElementById("historyMode"); michael@0: let autoStart = document.getElementById("privateBrowsingAutoStart"); michael@0: this._lastMode = mode.selectedIndex; michael@0: this._lastCheckState = autoStart.hasAttribute('checked'); michael@0: }, michael@0: michael@0: _lastMode: null, michael@0: _lastCheckState: null, michael@0: updateAutostart: function PPP_updateAutostart() { michael@0: let mode = document.getElementById("historyMode"); michael@0: let autoStart = document.getElementById("privateBrowsingAutoStart"); michael@0: let pref = document.getElementById("browser.privatebrowsing.autostart"); michael@0: if ((mode.value == "custom" && this._lastCheckState == autoStart.checked) || michael@0: (mode.value == "remember" && !this._lastCheckState) || michael@0: (mode.value == "dontremember" && this._lastCheckState)) { michael@0: // These are all no-op changes, so we don't need to prompt. michael@0: this._lastMode = mode.selectedIndex; michael@0: this._lastCheckState = autoStart.hasAttribute('checked'); michael@0: return; michael@0: } michael@0: michael@0: if (!this._shouldPromptForRestart) { michael@0: // We're performing a revert. Just let it happen. michael@0: return; michael@0: } michael@0: michael@0: const Cc = Components.classes, Ci = Components.interfaces; michael@0: let brandName = document.getElementById("bundleBrand").getString("brandShortName"); michael@0: let bundle = document.getElementById("bundlePreferences"); michael@0: let msg = bundle.getFormattedString(autoStart.checked ? michael@0: "featureEnableRequiresRestart" : "featureDisableRequiresRestart", michael@0: [brandName]); michael@0: let title = bundle.getFormattedString("shouldRestartTitle", [brandName]); michael@0: let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService); michael@0: let shouldProceed = prompts.confirm(window, title, msg) michael@0: if (shouldProceed) { michael@0: let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] michael@0: .createInstance(Ci.nsISupportsPRBool); michael@0: Services.obs.notifyObservers(cancelQuit, "quit-application-requested", michael@0: "restart"); michael@0: shouldProceed = !cancelQuit.data; michael@0: michael@0: if (shouldProceed) { michael@0: pref.value = autoStart.hasAttribute('checked'); michael@0: document.documentElement.acceptDialog(); michael@0: let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] michael@0: .getService(Ci.nsIAppStartup); michael@0: appStartup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); michael@0: return; michael@0: } michael@0: } michael@0: michael@0: this._shouldPromptForRestart = false; michael@0: michael@0: if (this._lastCheckState) { michael@0: autoStart.checked = "checked"; michael@0: } else { michael@0: autoStart.removeAttribute('checked'); michael@0: } michael@0: pref.value = autoStart.hasAttribute('checked'); michael@0: mode.selectedIndex = this._lastMode; michael@0: mode.doCommand(); michael@0: michael@0: this._shouldPromptForRestart = true; michael@0: }, michael@0: michael@0: // HISTORY michael@0: michael@0: /** michael@0: * Read the location bar enabled and suggestion prefs michael@0: * @return Int value for suggestion menulist michael@0: */ michael@0: readSuggestionPref: function PPP_readSuggestionPref() michael@0: { michael@0: let getVal = function(aPref) michael@0: document.getElementById("browser.urlbar." + aPref).value; michael@0: michael@0: // Suggest nothing if autocomplete is not enabled michael@0: if (!getVal("autocomplete.enabled")) michael@0: return -1; michael@0: michael@0: // Bottom 2 bits of default.behavior specify history/bookmark michael@0: return getVal("default.behavior") & 3; michael@0: }, michael@0: michael@0: /** michael@0: * Write the location bar enabled and suggestion prefs when necessary michael@0: * @return Bool value for enabled pref michael@0: */ michael@0: writeSuggestionPref: function PPP_writeSuggestionPref() michael@0: { michael@0: let menuVal = document.getElementById("locationBarSuggestion").value; michael@0: let enabled = menuVal != -1; michael@0: michael@0: // Only update default.behavior if we're giving suggestions michael@0: if (enabled) { michael@0: // Put the selected menu item's value directly into the bottom 2 bits michael@0: let behavior = document.getElementById("browser.urlbar.default.behavior"); michael@0: behavior.value = behavior.value >> 2 << 2 | menuVal; michael@0: } michael@0: michael@0: // Always update the enabled pref michael@0: return enabled; michael@0: }, michael@0: michael@0: /* michael@0: * Preferences: michael@0: * michael@0: * places.history.enabled michael@0: * - whether history is enabled or not michael@0: * browser.formfill.enable michael@0: * - true if entries in forms and the search bar should be saved, false michael@0: * otherwise michael@0: */ michael@0: michael@0: // COOKIES michael@0: michael@0: /* michael@0: * Preferences: michael@0: * michael@0: * network.cookie.cookieBehavior michael@0: * - determines how the browser should handle cookies: michael@0: * 0 means enable all cookies michael@0: * 1 means reject all third party cookies michael@0: * 2 means disable all cookies michael@0: * 3 means reject third party cookies unless at least one is already set for the eTLD michael@0: * see netwerk/cookie/src/nsCookieService.cpp for details michael@0: * network.cookie.lifetimePolicy michael@0: * - determines how long cookies are stored: michael@0: * 0 means keep cookies until they expire michael@0: * 1 means ask how long to keep each cookie michael@0: * 2 means keep cookies until the browser is closed michael@0: */ michael@0: michael@0: /** michael@0: * Reads the network.cookie.cookieBehavior preference value and michael@0: * enables/disables the rest of the cookie UI accordingly, returning true michael@0: * if cookies are enabled. michael@0: */ michael@0: readAcceptCookies: function () michael@0: { michael@0: var pref = document.getElementById("network.cookie.cookieBehavior"); michael@0: var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel"); michael@0: var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu"); michael@0: var keepUntil = document.getElementById("keepUntil"); michael@0: var menu = document.getElementById("keepCookiesUntil"); michael@0: michael@0: // enable the rest of the UI for anything other than "disable all cookies" michael@0: var acceptCookies = (pref.value != 2); michael@0: michael@0: acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies; michael@0: keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies; michael@0: michael@0: return acceptCookies; michael@0: }, michael@0: michael@0: /** michael@0: * Enables/disables the "keep until" label and menulist in response to the michael@0: * "accept cookies" checkbox being checked or unchecked. michael@0: */ michael@0: writeAcceptCookies: function () michael@0: { michael@0: var accept = document.getElementById("acceptCookies"); michael@0: var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu"); michael@0: michael@0: #ifdef RELEASE_BUILD michael@0: // if we're enabling cookies, automatically select 'accept third party always' michael@0: if (accept.checked) michael@0: acceptThirdPartyMenu.selectedIndex = 0; michael@0: michael@0: return accept.checked ? 0 : 2; michael@0: #else michael@0: // if we're enabling cookies, automatically select 'accept third party from visited' michael@0: if (accept.checked) michael@0: acceptThirdPartyMenu.selectedIndex = 1; michael@0: michael@0: return accept.checked ? 3 : 2; michael@0: #endif michael@0: }, michael@0: michael@0: /** michael@0: * Converts between network.cookie.cookieBehavior and the third-party cookie UI michael@0: */ michael@0: readAcceptThirdPartyCookies: function () michael@0: { michael@0: var pref = document.getElementById("network.cookie.cookieBehavior"); michael@0: switch (pref.value) michael@0: { michael@0: case 0: michael@0: return "always"; michael@0: case 1: michael@0: return "never"; michael@0: case 2: michael@0: return "never"; michael@0: case 3: michael@0: return "visited"; michael@0: default: michael@0: return undefined; michael@0: } michael@0: }, michael@0: michael@0: writeAcceptThirdPartyCookies: function () michael@0: { michael@0: var accept = document.getElementById("acceptThirdPartyMenu").selectedItem; michael@0: switch (accept.value) michael@0: { michael@0: case "always": michael@0: return 0; michael@0: case "visited": michael@0: return 3; michael@0: case "never": michael@0: return 1; michael@0: default: michael@0: return undefined; michael@0: } michael@0: }, michael@0: michael@0: /** michael@0: * Displays fine-grained, per-site preferences for cookies. michael@0: */ michael@0: showCookieExceptions: function () michael@0: { michael@0: var bundlePreferences = document.getElementById("bundlePreferences"); michael@0: var params = { blockVisible : true, michael@0: sessionVisible : true, michael@0: allowVisible : true, michael@0: prefilledHost : "", michael@0: permissionType : "cookie", michael@0: windowTitle : bundlePreferences.getString("cookiepermissionstitle"), michael@0: introText : bundlePreferences.getString("cookiepermissionstext") }; michael@0: document.documentElement.openWindow("Browser:Permissions", michael@0: "chrome://browser/content/preferences/permissions.xul", michael@0: "", params); michael@0: }, michael@0: michael@0: /** michael@0: * Displays all the user's cookies in a dialog. michael@0: */ michael@0: showCookies: function (aCategory) michael@0: { michael@0: document.documentElement.openWindow("Browser:Cookies", michael@0: "chrome://browser/content/preferences/cookies.xul", michael@0: "", null); michael@0: }, michael@0: michael@0: // CLEAR PRIVATE DATA michael@0: michael@0: /* michael@0: * Preferences: michael@0: * michael@0: * privacy.sanitize.sanitizeOnShutdown michael@0: * - true if the user's private data is cleared on startup according to the michael@0: * Clear Private Data settings, false otherwise michael@0: */ michael@0: michael@0: /** michael@0: * Displays the Clear Private Data settings dialog. michael@0: */ michael@0: showClearPrivateDataSettings: function () michael@0: { michael@0: document.documentElement.openSubDialog("chrome://browser/content/preferences/sanitize.xul", michael@0: "", null); michael@0: }, michael@0: michael@0: michael@0: /** michael@0: * Displays a dialog from which individual parts of private data may be michael@0: * cleared. michael@0: */ michael@0: clearPrivateDataNow: function (aClearEverything) michael@0: { michael@0: var ts = document.getElementById("privacy.sanitize.timeSpan"); michael@0: var timeSpanOrig = ts.value; michael@0: if (aClearEverything) michael@0: ts.value = 0; michael@0: michael@0: const Cc = Components.classes, Ci = Components.interfaces; michael@0: var glue = Cc["@mozilla.org/browser/browserglue;1"] michael@0: .getService(Ci.nsIBrowserGlue); michael@0: glue.sanitize(window); michael@0: michael@0: // reset the timeSpan pref michael@0: if (aClearEverything) michael@0: ts.value = timeSpanOrig; michael@0: }, michael@0: michael@0: /** michael@0: * Enables or disables the "Settings..." button depending michael@0: * on the privacy.sanitize.sanitizeOnShutdown preference value michael@0: */ michael@0: _updateSanitizeSettingsButton: function () { michael@0: var settingsButton = document.getElementById("clearDataSettings"); michael@0: var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown"); michael@0: michael@0: settingsButton.disabled = !sanitizeOnShutdownPref.value; michael@0: } michael@0: michael@0: };