|
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/. */ |
|
4 |
|
5 var gPrivacyPane = { |
|
6 |
|
7 /** |
|
8 * Whether the use has selected the auto-start private browsing mode in the UI. |
|
9 */ |
|
10 _autoStartPrivateBrowsing: false, |
|
11 |
|
12 /** |
|
13 * Whether the prompt to restart Firefox should appear when changing the autostart pref. |
|
14 */ |
|
15 _shouldPromptForRestart: true, |
|
16 |
|
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 }, |
|
29 |
|
30 // HISTORY MODE |
|
31 |
|
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 ], |
|
50 |
|
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 ], |
|
66 |
|
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 }, |
|
82 |
|
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; |
|
91 |
|
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"; |
|
100 |
|
101 document.getElementById("historyMode").value = mode; |
|
102 }, |
|
103 |
|
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 }, |
|
123 |
|
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"); |
|
132 |
|
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 } |
|
139 |
|
140 dntEnabledPref.value = true; |
|
141 return dntRadioGroup.selectedItem.value; |
|
142 }, |
|
143 |
|
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"); |
|
152 |
|
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; |
|
157 |
|
158 return document.getElementById("dntnopref").value; |
|
159 }, |
|
160 |
|
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; |
|
172 |
|
173 // select the remember history option if needed |
|
174 let rememberHistoryCheckbox = document.getElementById("rememberHistory"); |
|
175 if (!rememberHistoryCheckbox.checked) |
|
176 rememberHistoryCheckbox.checked = true; |
|
177 |
|
178 // select the remember forms history option |
|
179 document.getElementById("browser.formfill.enable").value = true; |
|
180 |
|
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; |
|
190 |
|
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 }, |
|
200 |
|
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); |
|
213 |
|
214 // adjust the cookie controls status |
|
215 this.readAcceptCookies(); |
|
216 document.getElementById("keepCookiesUntil").value = disabled ? 2 : |
|
217 document.getElementById("network.cookie.lifetimePolicy").value; |
|
218 |
|
219 // adjust the checked state of the sanitizeOnShutdown checkbox |
|
220 document.getElementById("alwaysClear").checked = disabled ? false : |
|
221 document.getElementById("privacy.sanitize.sanitizeOnShutdown").value; |
|
222 |
|
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; |
|
228 |
|
229 if (!disabled) { |
|
230 // adjust the Settings button for sanitizeOnShutdown |
|
231 this._updateSanitizeSettingsButton(); |
|
232 } |
|
233 } |
|
234 }, |
|
235 |
|
236 // PRIVATE BROWSING |
|
237 |
|
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 }, |
|
248 |
|
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 } |
|
263 |
|
264 if (!this._shouldPromptForRestart) { |
|
265 // We're performing a revert. Just let it happen. |
|
266 return; |
|
267 } |
|
268 |
|
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; |
|
284 |
|
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 } |
|
294 |
|
295 this._shouldPromptForRestart = false; |
|
296 |
|
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(); |
|
305 |
|
306 this._shouldPromptForRestart = true; |
|
307 }, |
|
308 |
|
309 // HISTORY |
|
310 |
|
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; |
|
319 |
|
320 // Suggest nothing if autocomplete is not enabled |
|
321 if (!getVal("autocomplete.enabled")) |
|
322 return -1; |
|
323 |
|
324 // Bottom 2 bits of default.behavior specify history/bookmark |
|
325 return getVal("default.behavior") & 3; |
|
326 }, |
|
327 |
|
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; |
|
336 |
|
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 } |
|
343 |
|
344 // Always update the enabled pref |
|
345 return enabled; |
|
346 }, |
|
347 |
|
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 */ |
|
357 |
|
358 // COOKIES |
|
359 |
|
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 */ |
|
376 |
|
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"); |
|
389 |
|
390 // enable the rest of the UI for anything other than "disable all cookies" |
|
391 var acceptCookies = (pref.value != 2); |
|
392 |
|
393 acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies; |
|
394 keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies; |
|
395 |
|
396 return acceptCookies; |
|
397 }, |
|
398 |
|
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"); |
|
407 |
|
408 #ifdef RELEASE_BUILD |
|
409 // if we're enabling cookies, automatically select 'accept third party always' |
|
410 if (accept.checked) |
|
411 acceptThirdPartyMenu.selectedIndex = 0; |
|
412 |
|
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; |
|
418 |
|
419 return accept.checked ? 3 : 2; |
|
420 #endif |
|
421 }, |
|
422 |
|
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 }, |
|
443 |
|
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 }, |
|
459 |
|
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 }, |
|
477 |
|
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 }, |
|
487 |
|
488 // CLEAR PRIVATE DATA |
|
489 |
|
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 */ |
|
497 |
|
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 }, |
|
506 |
|
507 |
|
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; |
|
518 |
|
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); |
|
523 |
|
524 // reset the timeSpan pref |
|
525 if (aClearEverything) |
|
526 ts.value = timeSpanOrig; |
|
527 }, |
|
528 |
|
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"); |
|
536 |
|
537 settingsButton.disabled = !sanitizeOnShutdownPref.value; |
|
538 } |
|
539 |
|
540 }; |