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