Wed, 31 Dec 2014 07:53:36 +0100
Correct small whitespace inconsistency, lost while renaming variables.
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
8 var gPrivacyPane = {
10 /**
11 * Whether the use has selected the auto-start private browsing mode in the UI.
12 */
13 _autoStartPrivateBrowsing: false,
15 /**
16 * Whether the prompt to restart Firefox should appear when changing the autostart pref.
17 */
18 _shouldPromptForRestart: true,
20 /**
21 * Sets up the UI for the number of days of history to keep, and updates the
22 * label of the "Clear Now..." button.
23 */
24 init: function ()
25 {
26 this._updateSanitizeSettingsButton();
27 this.initializeHistoryMode();
28 this.updateHistoryModePane();
29 this.updatePrivacyMicroControls();
30 this.initAutoStartPrivateBrowsingReverter();
31 },
33 // HISTORY MODE
35 /**
36 * The list of preferences which affect the initial history mode settings.
37 * If the auto start private browsing mode pref is active, the initial
38 * history mode would be set to "Don't remember anything".
39 * If all of these preferences have their default values, and the auto-start
40 * private browsing mode is not active, the initial history mode would be
41 * set to "Remember everything".
42 * Otherwise, the initial history mode would be set to "Custom".
43 *
44 * Extensions adding their own preferences can append their IDs to this array if needed.
45 */
46 prefsForDefault: [
47 "places.history.enabled",
48 "browser.formfill.enable",
49 "network.cookie.cookieBehavior",
50 "network.cookie.lifetimePolicy",
51 "privacy.sanitize.sanitizeOnShutdown"
52 ],
54 /**
55 * The list of control IDs which are dependent on the auto-start private
56 * browsing setting, such that in "Custom" mode they would be disabled if
57 * the auto-start private browsing checkbox is checked, and enabled otherwise.
58 *
59 * Extensions adding their own controls can append their IDs to this array if needed.
60 */
61 dependentControls: [
62 "rememberHistory",
63 "rememberForms",
64 "keepUntil",
65 "keepCookiesUntil",
66 "alwaysClear",
67 "clearDataSettings"
68 ],
70 /**
71 * Check whether all the preferences values are set to their default values
72 *
73 * @param aPrefs an array of pref names to check for
74 * @returns boolean true if all of the prefs are set to their default values,
75 * false otherwise
76 */
77 _checkDefaultValues: function(aPrefs) {
78 for (let i = 0; i < aPrefs.length; ++i) {
79 let pref = document.getElementById(aPrefs[i]);
80 if (pref.value != pref.defaultValue)
81 return false;
82 }
83 return true;
84 },
86 /**
87 * Initialize the history mode menulist based on the privacy preferences
88 */
89 initializeHistoryMode: function PPP_initializeHistoryMode()
90 {
91 let mode;
92 let getVal = function (aPref)
93 document.getElementById(aPref).value;
95 if (this._checkDefaultValues(this.prefsForDefault)) {
96 if (getVal("browser.privatebrowsing.autostart"))
97 mode = "dontremember";
98 else
99 mode = "remember";
100 }
101 else
102 mode = "custom";
104 document.getElementById("historyMode").value = mode;
105 },
107 /**
108 * Update the selected pane based on the history mode menulist
109 */
110 updateHistoryModePane: function PPP_updateHistoryModePane()
111 {
112 let selectedIndex = -1;
113 switch (document.getElementById("historyMode").value) {
114 case "remember":
115 selectedIndex = 0;
116 break;
117 case "dontremember":
118 selectedIndex = 1;
119 break;
120 case "custom":
121 selectedIndex = 2;
122 break;
123 }
124 document.getElementById("historyPane").selectedIndex = selectedIndex;
125 },
127 /**
128 * Update the Tracking preferences based on controls.
129 */
130 setTrackingPrefs: function PPP_setTrackingPrefs()
131 {
132 let dntRadioGroup = document.getElementById("doNotTrackSelection"),
133 dntValuePref = document.getElementById("privacy.donottrackheader.value"),
134 dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled");
136 // if the selected radio button says "no preference", set on/off pref to
137 // false and don't change the value pref.
138 if (dntRadioGroup.selectedItem.value == -1) {
139 dntEnabledPref.value = false;
140 return dntValuePref.value;
141 }
143 dntEnabledPref.value = true;
144 return dntRadioGroup.selectedItem.value;
145 },
147 /**
148 * Obtain the tracking preference value and reflect it in the UI.
149 */
150 getTrackingPrefs: function PPP_getTrackingPrefs()
151 {
152 let dntValuePref = document.getElementById("privacy.donottrackheader.value"),
153 dntEnabledPref = document.getElementById("privacy.donottrackheader.enabled");
155 // if DNT is enbaled, select the value from the selected radio
156 // button, otherwise choose the "no preference" radio button
157 if (dntEnabledPref.value)
158 return dntValuePref.value;
160 return document.getElementById("dntnopref").value;
161 },
163 /**
164 * Update the private browsing auto-start pref and the history mode
165 * micro-management prefs based on the history mode menulist
166 */
167 updateHistoryModePrefs: function PPP_updateHistoryModePrefs()
168 {
169 let pref = document.getElementById("browser.privatebrowsing.autostart");
170 switch (document.getElementById("historyMode").value) {
171 case "remember":
172 if (pref.value)
173 pref.value = false;
175 // select the remember history option if needed
176 let rememberHistoryCheckbox = document.getElementById("rememberHistory");
177 if (!rememberHistoryCheckbox.checked)
178 rememberHistoryCheckbox.checked = true;
180 // select the remember forms history option
181 document.getElementById("browser.formfill.enable").value = true;
183 #ifdef RELEASE_BUILD
184 // select the accept cookies option
185 document.getElementById("network.cookie.cookieBehavior").value = 0;
186 #else
187 // select the limit cookies option
188 document.getElementById("network.cookie.cookieBehavior").value = 3;
189 #endif
190 // select the cookie lifetime policy option
191 document.getElementById("network.cookie.lifetimePolicy").value = 0;
193 // select the clear on close option
194 document.getElementById("privacy.sanitize.sanitizeOnShutdown").value = false;
195 break;
196 case "dontremember":
197 if (!pref.value)
198 pref.value = true;
199 break;
200 }
201 },
203 /**
204 * Update the privacy micro-management controls based on the
205 * value of the private browsing auto-start checkbox.
206 */
207 updatePrivacyMicroControls: function PPP_updatePrivacyMicroControls()
208 {
209 if (document.getElementById("historyMode").value == "custom") {
210 let disabled = this._autoStartPrivateBrowsing =
211 document.getElementById("privateBrowsingAutoStart").checked;
212 this.dependentControls
213 .forEach(function (aElement)
214 document.getElementById(aElement).disabled = disabled);
216 // adjust the cookie controls status
217 this.readAcceptCookies();
218 document.getElementById("keepCookiesUntil").value = disabled ? 2 :
219 document.getElementById("network.cookie.lifetimePolicy").value;
221 // adjust the checked state of the sanitizeOnShutdown checkbox
222 document.getElementById("alwaysClear").checked = disabled ? false :
223 document.getElementById("privacy.sanitize.sanitizeOnShutdown").value;
225 // adjust the checked state of the remember history checkboxes
226 document.getElementById("rememberHistory").checked = disabled ? false :
227 document.getElementById("places.history.enabled").value;
228 document.getElementById("rememberForms").checked = disabled ? false :
229 document.getElementById("browser.formfill.enable").value;
231 if (!disabled) {
232 // adjust the Settings button for sanitizeOnShutdown
233 this._updateSanitizeSettingsButton();
234 }
235 }
236 },
238 // PRIVATE BROWSING
240 /**
241 * Initialize the starting state for the auto-start private browsing mode pref reverter.
242 */
243 initAutoStartPrivateBrowsingReverter: function PPP_initAutoStartPrivateBrowsingReverter()
244 {
245 let mode = document.getElementById("historyMode");
246 let autoStart = document.getElementById("privateBrowsingAutoStart");
247 this._lastMode = mode.selectedIndex;
248 this._lastCheckState = autoStart.hasAttribute('checked');
249 },
251 _lastMode: null,
252 _lastCheckState: null,
253 updateAutostart: function PPP_updateAutostart() {
254 let mode = document.getElementById("historyMode");
255 let autoStart = document.getElementById("privateBrowsingAutoStart");
256 let pref = document.getElementById("browser.privatebrowsing.autostart");
257 if ((mode.value == "custom" && this._lastCheckState == autoStart.checked) ||
258 (mode.value == "remember" && !this._lastCheckState) ||
259 (mode.value == "dontremember" && this._lastCheckState)) {
260 // These are all no-op changes, so we don't need to prompt.
261 this._lastMode = mode.selectedIndex;
262 this._lastCheckState = autoStart.hasAttribute('checked');
263 return;
264 }
266 if (!this._shouldPromptForRestart) {
267 // We're performing a revert. Just let it happen.
268 return;
269 }
271 const Cc = Components.classes, Ci = Components.interfaces;
272 let brandName = document.getElementById("bundleBrand").getString("brandShortName");
273 let bundle = document.getElementById("bundlePreferences");
274 let msg = bundle.getFormattedString(autoStart.checked ?
275 "featureEnableRequiresRestart" : "featureDisableRequiresRestart",
276 [brandName]);
277 let title = bundle.getFormattedString("shouldRestartTitle", [brandName]);
278 let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
279 let shouldProceed = prompts.confirm(window, title, msg)
280 if (shouldProceed) {
281 let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
282 .createInstance(Ci.nsISupportsPRBool);
283 Services.obs.notifyObservers(cancelQuit, "quit-application-requested",
284 "restart");
285 shouldProceed = !cancelQuit.data;
287 if (shouldProceed) {
288 pref.value = autoStart.hasAttribute('checked');
289 document.documentElement.acceptDialog();
290 let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"]
291 .getService(Ci.nsIAppStartup);
292 appStartup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
293 return;
294 }
295 }
297 this._shouldPromptForRestart = false;
299 if (this._lastCheckState) {
300 autoStart.checked = "checked";
301 } else {
302 autoStart.removeAttribute('checked');
303 }
304 pref.value = autoStart.hasAttribute('checked');
305 mode.selectedIndex = this._lastMode;
306 mode.doCommand();
308 this._shouldPromptForRestart = true;
309 },
311 // HISTORY
313 /**
314 * Read the location bar enabled and suggestion prefs
315 * @return Int value for suggestion menulist
316 */
317 readSuggestionPref: function PPP_readSuggestionPref()
318 {
319 let getVal = function(aPref)
320 document.getElementById("browser.urlbar." + aPref).value;
322 // Suggest nothing if autocomplete is not enabled
323 if (!getVal("autocomplete.enabled"))
324 return -1;
326 // Bottom 2 bits of default.behavior specify history/bookmark
327 return getVal("default.behavior") & 3;
328 },
330 /**
331 * Write the location bar enabled and suggestion prefs when necessary
332 * @return Bool value for enabled pref
333 */
334 writeSuggestionPref: function PPP_writeSuggestionPref()
335 {
336 let menuVal = document.getElementById("locationBarSuggestion").value;
337 let enabled = menuVal != -1;
339 // Only update default.behavior if we're giving suggestions
340 if (enabled) {
341 // Put the selected menu item's value directly into the bottom 2 bits
342 let behavior = document.getElementById("browser.urlbar.default.behavior");
343 behavior.value = behavior.value >> 2 << 2 | menuVal;
344 }
346 // Always update the enabled pref
347 return enabled;
348 },
350 /*
351 * Preferences:
352 *
353 * places.history.enabled
354 * - whether history is enabled or not
355 * browser.formfill.enable
356 * - true if entries in forms and the search bar should be saved, false
357 * otherwise
358 */
360 // COOKIES
362 /*
363 * Preferences:
364 *
365 * network.cookie.cookieBehavior
366 * - determines how the browser should handle cookies:
367 * 0 means enable all cookies
368 * 1 means reject all third party cookies
369 * 2 means disable all cookies
370 * 3 means reject third party cookies unless at least one is already set for the eTLD
371 * see netwerk/cookie/src/nsCookieService.cpp for details
372 * network.cookie.lifetimePolicy
373 * - determines how long cookies are stored:
374 * 0 means keep cookies until they expire
375 * 1 means ask how long to keep each cookie
376 * 2 means keep cookies until the browser is closed
377 */
379 /**
380 * Reads the network.cookie.cookieBehavior preference value and
381 * enables/disables the rest of the cookie UI accordingly, returning true
382 * if cookies are enabled.
383 */
384 readAcceptCookies: function ()
385 {
386 var pref = document.getElementById("network.cookie.cookieBehavior");
387 var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel");
388 var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
389 var keepUntil = document.getElementById("keepUntil");
390 var menu = document.getElementById("keepCookiesUntil");
392 // enable the rest of the UI for anything other than "disable all cookies"
393 var acceptCookies = (pref.value != 2);
395 acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies;
396 keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies;
398 return acceptCookies;
399 },
401 /**
402 * Enables/disables the "keep until" label and menulist in response to the
403 * "accept cookies" checkbox being checked or unchecked.
404 */
405 writeAcceptCookies: function ()
406 {
407 var accept = document.getElementById("acceptCookies");
408 var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
410 #ifdef RELEASE_BUILD
411 // if we're enabling cookies, automatically select 'accept third party always'
412 if (accept.checked)
413 acceptThirdPartyMenu.selectedIndex = 0;
415 return accept.checked ? 0 : 2;
416 #else
417 // if we're enabling cookies, automatically select 'accept third party from visited'
418 if (accept.checked)
419 acceptThirdPartyMenu.selectedIndex = 1;
421 return accept.checked ? 3 : 2;
422 #endif
423 },
425 /**
426 * Converts between network.cookie.cookieBehavior and the third-party cookie UI
427 */
428 readAcceptThirdPartyCookies: function ()
429 {
430 var pref = document.getElementById("network.cookie.cookieBehavior");
431 switch (pref.value)
432 {
433 case 0:
434 return "always";
435 case 1:
436 return "never";
437 case 2:
438 return "never";
439 case 3:
440 return "visited";
441 default:
442 return undefined;
443 }
444 },
446 writeAcceptThirdPartyCookies: function ()
447 {
448 var accept = document.getElementById("acceptThirdPartyMenu").selectedItem;
449 switch (accept.value)
450 {
451 case "always":
452 return 0;
453 case "visited":
454 return 3;
455 case "never":
456 return 1;
457 default:
458 return undefined;
459 }
460 },
462 /**
463 * Displays fine-grained, per-site preferences for cookies.
464 */
465 showCookieExceptions: function ()
466 {
467 var bundlePreferences = document.getElementById("bundlePreferences");
468 var params = { blockVisible : true,
469 sessionVisible : true,
470 allowVisible : true,
471 prefilledHost : "",
472 permissionType : "cookie",
473 windowTitle : bundlePreferences.getString("cookiepermissionstitle"),
474 introText : bundlePreferences.getString("cookiepermissionstext") };
475 document.documentElement.openWindow("Browser:Permissions",
476 "chrome://browser/content/preferences/permissions.xul",
477 "", params);
478 },
480 /**
481 * Displays all the user's cookies in a dialog.
482 */
483 showCookies: function (aCategory)
484 {
485 document.documentElement.openWindow("Browser:Cookies",
486 "chrome://browser/content/preferences/cookies.xul",
487 "", null);
488 },
490 // CLEAR PRIVATE DATA
492 /*
493 * Preferences:
494 *
495 * privacy.sanitize.sanitizeOnShutdown
496 * - true if the user's private data is cleared on startup according to the
497 * Clear Private Data settings, false otherwise
498 */
500 /**
501 * Displays the Clear Private Data settings dialog.
502 */
503 showClearPrivateDataSettings: function ()
504 {
505 document.documentElement.openSubDialog("chrome://browser/content/preferences/sanitize.xul",
506 "", null);
507 },
510 /**
511 * Displays a dialog from which individual parts of private data may be
512 * cleared.
513 */
514 clearPrivateDataNow: function (aClearEverything)
515 {
516 var ts = document.getElementById("privacy.sanitize.timeSpan");
517 var timeSpanOrig = ts.value;
518 if (aClearEverything)
519 ts.value = 0;
521 const Cc = Components.classes, Ci = Components.interfaces;
522 var glue = Cc["@mozilla.org/browser/browserglue;1"]
523 .getService(Ci.nsIBrowserGlue);
524 glue.sanitize(window);
526 // reset the timeSpan pref
527 if (aClearEverything)
528 ts.value = timeSpanOrig;
529 },
531 /**
532 * Enables or disables the "Settings..." button depending
533 * on the privacy.sanitize.sanitizeOnShutdown preference value
534 */
535 _updateSanitizeSettingsButton: function () {
536 var settingsButton = document.getElementById("clearDataSettings");
537 var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown");
539 settingsButton.disabled = !sanitizeOnShutdownPref.value;
540 }
542 };