Bug 1442850 - Update how history mode and cookie lifetime controls interact to fit our new preferences UI. r=Gijs draft
authorJohann Hofmann <jhofmann@mozilla.com>
Mon, 05 Mar 2018 18:23:03 +0100
changeset 763943 06bdb912d2d18f8121b8ff843610e5c5534b513c
parent 763942 bccdc684210431c233622650a91454c09f6af9eb
push id101605
push userjhofmann@mozilla.com
push dateTue, 06 Mar 2018 22:14:33 +0000
reviewersGijs
bugs1442850
milestone60.0a1
Bug 1442850 - Update how history mode and cookie lifetime controls interact to fit our new preferences UI. r=Gijs We recently updated the cookie settings in about:preferences to live outside of the history mode settings, but did not change the way that changes to history mode (toggling the privatebrowsing.autostart pref) reflected in the cookies section. This patch takes care of that by moving the cookie related pieces out of the code that sets history settings and makes sure that the respective functions get called in all appropriate cases. I also moved some site data settings code to be closer to the cookies code. MozReview-Commit-ID: 6ly079uDz4C
browser/components/preferences/in-content/privacy.js
browser/components/preferences/in-content/privacy.xul
browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -120,21 +120,16 @@ if (AppConstants.NIGHTLY_BUILD) {
 if (AppConstants.MOZ_CRASHREPORTER) {
   Preferences.add({ id: "browser.crashReports.unsubmittedCheck.autoSubmit2", type: "bool" });
 }
 
 var gPrivacyPane = {
   _pane: null,
 
   /**
-   * Whether the use has selected the auto-start private browsing mode in the UI.
-   */
-  _autoStartPrivateBrowsing: false,
-
-  /**
    * Whether the prompt to restart Firefox should appear when changing the autostart pref.
    */
   _shouldPromptForRestart: true,
 
   /**
    * Show the Tracking Protection UI depending on the
    * privacy.trackingprotection.ui.enabled pref, and linkify its Learn More link
    */
@@ -526,33 +521,29 @@ var gPrivacyPane = {
    * set to "Remember everything".
    * Otherwise, the initial history mode would be set to "Custom".
    *
    * Extensions adding their own preferences can set values here if needed.
    */
   prefsForKeepingHistory: {
     "places.history.enabled": true, // History is enabled
     "browser.formfill.enable": true, // Form information is saved
-    "network.cookie.cookieBehavior": 0, // All cookies are enabled
-    "network.cookie.lifetimePolicy": 0, // Cookies use supplied lifetime
     "privacy.sanitize.sanitizeOnShutdown": false, // Private date is NOT cleared on shutdown
   },
 
   /**
    * The list of control IDs which are dependent on the auto-start private
    * browsing setting, such that in "Custom" mode they would be disabled if
    * the auto-start private browsing checkbox is checked, and enabled otherwise.
    *
    * Extensions adding their own controls can append their IDs to this array if needed.
    */
   dependentControls: [
     "rememberHistory",
     "rememberForms",
-    "keepUntil",
-    "keepCookiesUntil",
     "alwaysClear",
     "clearDataSettings"
   ],
 
   /**
    * Check whether preferences values are set to keep history
    *
    * @param aPrefs an array of pref names to check for
@@ -619,64 +610,53 @@ var gPrivacyPane = {
           pref.value = false;
 
         // select the remember history option if needed
         Preferences.get("places.history.enabled").value = true;
 
         // select the remember forms history option
         Preferences.get("browser.formfill.enable").value = true;
 
-        // select the allow cookies option
-        Preferences.get("network.cookie.cookieBehavior").value = 0;
-        // select the cookie lifetime policy option
-        Preferences.get("network.cookie.lifetimePolicy").value = 0;
-
         // select the clear on close option
         Preferences.get("privacy.sanitize.sanitizeOnShutdown").value = false;
         break;
       case "dontremember":
         if (!pref.value)
           pref.value = true;
         break;
     }
   },
 
   /**
    * Update the privacy micro-management controls based on the
-   * value of the private browsing auto-start checkbox.
+   * value of the private browsing auto-start preference.
    */
   updatePrivacyMicroControls() {
+    // Set "Keep cookies until..." to "I close Nightly" and disable the setting
+    // when we're in auto private mode (or reset it back otherwise).
+    document.getElementById("keepCookiesUntil").value = this.readKeepCookiesUntil();
+    this.readAcceptCookies();
+
     if (document.getElementById("historyMode").value == "custom") {
-      let disabled = this._autoStartPrivateBrowsing =
-        Preferences.get("browser.privatebrowsing.autostart").value;
+      let disabled = Preferences.get("browser.privatebrowsing.autostart").value;
       this.dependentControls.forEach(function(aElement) {
         let control = document.getElementById(aElement);
         let preferenceId = control.getAttribute("preference");
         if (!preferenceId) {
           let dependentControlId = control.getAttribute("control");
           if (dependentControlId) {
             let dependentControl = document.getElementById(dependentControlId);
             preferenceId = dependentControl.getAttribute("preference");
           }
         }
 
         let preference = preferenceId ? Preferences.get(preferenceId) : {};
         control.disabled = disabled || preference.locked;
       });
 
-      // adjust the cookie controls status
-      this.readAcceptCookies();
-      let lifetimePolicy = Preferences.get("network.cookie.lifetimePolicy").value;
-      if (lifetimePolicy != Ci.nsICookieService.ACCEPT_NORMALLY &&
-        lifetimePolicy != Ci.nsICookieService.ACCEPT_SESSION &&
-        lifetimePolicy != Ci.nsICookieService.ACCEPT_FOR_N_DAYS) {
-        lifetimePolicy = Ci.nsICookieService.ACCEPT_NORMALLY;
-      }
-      document.getElementById("keepCookiesUntil").value = disabled ? 2 : lifetimePolicy;
-
       // adjust the checked state of the sanitizeOnShutdown checkbox
       document.getElementById("alwaysClear").checked = disabled ? false :
         Preferences.get("privacy.sanitize.sanitizeOnShutdown").value;
 
       // adjust the checked state of the remember history checkboxes
       document.getElementById("rememberHistory").checked = disabled ? false :
         Preferences.get("places.history.enabled").value;
       document.getElementById("rememberForms").checked = disabled ? false :
@@ -684,16 +664,71 @@ var gPrivacyPane = {
 
       if (!disabled) {
         // adjust the Settings button for sanitizeOnShutdown
         this._updateSanitizeSettingsButton();
       }
     }
   },
 
+  // CLEAR PRIVATE DATA
+
+  /*
+   * Preferences:
+   *
+   * privacy.sanitize.sanitizeOnShutdown
+   * - true if the user's private data is cleared on startup according to the
+   *   Clear Private Data settings, false otherwise
+   */
+
+  /**
+   * Displays the Clear Private Data settings dialog.
+   */
+  showClearPrivateDataSettings() {
+    gSubDialog.open("chrome://browser/content/preferences/sanitize.xul", "resizable=no");
+  },
+
+
+  /**
+   * Displays a dialog from which individual parts of private data may be
+   * cleared.
+   */
+  clearPrivateDataNow(aClearEverything) {
+    var ts = Preferences.get("privacy.sanitize.timeSpan");
+    var timeSpanOrig = ts.value;
+
+    if (aClearEverything) {
+      ts.value = 0;
+    }
+
+    gSubDialog.open("chrome://browser/content/sanitize.xul", "resizable=no", null, () => {
+      // reset the timeSpan pref
+      if (aClearEverything) {
+        ts.value = timeSpanOrig;
+      }
+
+      Services.obs.notifyObservers(null, "clear-private-data");
+    });
+  },
+
+  /**
+   * Enables or disables the "Settings..." button depending
+   * on the privacy.sanitize.sanitizeOnShutdown preference value
+   */
+  _updateSanitizeSettingsButton() {
+    var settingsButton = document.getElementById("clearDataSettings");
+    var sanitizeOnShutdownPref = Preferences.get("privacy.sanitize.sanitizeOnShutdown");
+
+    settingsButton.disabled = !sanitizeOnShutdownPref.value;
+  },
+
+  toggleDoNotDisturbNotifications(event) {
+    AlertsServiceDND.manualDoNotDisturb = event.target.checked;
+  },
+
   // PRIVATE BROWSING
 
   /**
    * Initialize the starting state for the auto-start private browsing mode pref reverter.
    */
   initAutoStartPrivateBrowsingReverter() {
     let mode = document.getElementById("historyMode");
     let autoStart = document.getElementById("privateBrowsingAutoStart");
@@ -769,29 +804,17 @@ var gPrivacyPane = {
       brandShortName: brandName,
       windowTitle: bundlePreferences.getString("blockliststitle"),
       introText: bundlePreferences.getString("blockliststext")
     };
     gSubDialog.open("chrome://browser/content/preferences/blocklists.xul",
       null, params);
   },
 
-  // HISTORY
-
-  /*
-   * Preferences:
-   *
-   * places.history.enabled
-   * - whether history is enabled or not
-   * browser.formfill.enable
-   * - true if entries in forms and the search bar should be saved, false
-   *   otherwise
-   */
-
-  // COOKIES
+  // COOKIES AND SITE DATA
 
   /*
    * Preferences:
    *
    * network.cookie.cookieBehavior
    * - determines how the browser should handle cookies:
    *     0   means enable all cookies
    *     1   means reject all third party cookies
@@ -799,33 +822,51 @@ var gPrivacyPane = {
    *     3   means reject third party cookies unless at least one is already set for the eTLD
    *         see netwerk/cookie/src/nsCookieService.cpp for details
    * network.cookie.lifetimePolicy
    * - determines how long cookies are stored:
    *     0   means keep cookies until they expire
    *     2   means keep cookies until the browser is closed
    */
 
+  readKeepCookiesUntil() {
+    let privateBrowsing = Preferences.get("browser.privatebrowsing.autostart").value;
+    if (privateBrowsing) {
+      return "2";
+    }
+
+    let lifetimePolicy = Preferences.get("network.cookie.lifetimePolicy").value;
+    if (lifetimePolicy != Ci.nsICookieService.ACCEPT_NORMALLY &&
+      lifetimePolicy != Ci.nsICookieService.ACCEPT_SESSION &&
+      lifetimePolicy != Ci.nsICookieService.ACCEPT_FOR_N_DAYS) {
+      return Ci.nsICookieService.ACCEPT_NORMALLY;
+    }
+
+    return lifetimePolicy;
+  },
+
   /**
    * Reads the network.cookie.cookieBehavior preference value and
    * enables/disables the rest of the cookie UI accordingly, returning true
    * if cookies are enabled.
    */
   readAcceptCookies() {
     var pref = Preferences.get("network.cookie.cookieBehavior");
     var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel");
     var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu");
     var keepUntil = document.getElementById("keepUntil");
     var menu = document.getElementById("keepCookiesUntil");
 
     // enable the rest of the UI for anything other than "disable all cookies"
     var acceptCookies = (pref.value != 2);
 
     acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies;
-    keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies;
+
+    let privateBrowsing = Preferences.get("browser.privatebrowsing.autostart").value;
+    keepUntil.disabled = menu.disabled = privateBrowsing || !acceptCookies;
 
     // Our top-level setting is a radiogroup that only sets "enable all"
     // and "disable all", so convert the pref value accordingly.
     return acceptCookies ? "0" : "2";
   },
 
   /**
    * Updates the "accept third party cookies" menu based on whether the
@@ -888,69 +929,45 @@ var gPrivacyPane = {
       permissionType: "cookie",
       windowTitle: bundlePreferences.getString("cookiepermissionstitle1"),
       introText: bundlePreferences.getString("cookiepermissionstext1")
     };
     gSubDialog.open("chrome://browser/content/preferences/permissions.xul",
       null, params);
   },
 
-  // CLEAR PRIVATE DATA
+  showSiteDataSettings() {
+    gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
+  },
 
-  /*
-   * Preferences:
-   *
-   * privacy.sanitize.sanitizeOnShutdown
-   * - true if the user's private data is cleared on startup according to the
-   *   Clear Private Data settings, false otherwise
-   */
-
-  /**
-   * Displays the Clear Private Data settings dialog.
-   */
-  showClearPrivateDataSettings() {
-    gSubDialog.open("chrome://browser/content/preferences/sanitize.xul", "resizable=no");
+  toggleSiteData(shouldShow) {
+    let clearButton = document.getElementById("clearSiteDataButton");
+    let settingsButton = document.getElementById("siteDataSettings");
+    clearButton.disabled = !shouldShow;
+    settingsButton.disabled = !shouldShow;
   },
 
-
-  /**
-   * Displays a dialog from which individual parts of private data may be
-   * cleared.
-   */
-  clearPrivateDataNow(aClearEverything) {
-    var ts = Preferences.get("privacy.sanitize.timeSpan");
-    var timeSpanOrig = ts.value;
+  showSiteDataLoading() {
+    let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
+    let prefStrBundle = document.getElementById("bundlePreferences");
+    totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize1");
+  },
 
-    if (aClearEverything) {
-      ts.value = 0;
-    }
-
-    gSubDialog.open("chrome://browser/content/sanitize.xul", "resizable=no", null, () => {
-      // reset the timeSpan pref
-      if (aClearEverything) {
-        ts.value = timeSpanOrig;
-      }
-
-      Services.obs.notifyObservers(null, "clear-private-data");
+  updateTotalDataSizeLabel(siteDataUsage) {
+    SiteDataManager.getCacheSize().then(function(cacheUsage) {
+      let prefStrBundle = document.getElementById("bundlePreferences");
+      let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
+      let totalUsage = siteDataUsage + cacheUsage;
+      let size = DownloadUtils.convertByteUnits(totalUsage);
+      totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize2", size);
     });
   },
 
-  /**
-   * Enables or disables the "Settings..." button depending
-   * on the privacy.sanitize.sanitizeOnShutdown preference value
-   */
-  _updateSanitizeSettingsButton() {
-    var settingsButton = document.getElementById("clearDataSettings");
-    var sanitizeOnShutdownPref = Preferences.get("privacy.sanitize.sanitizeOnShutdown");
-
-    settingsButton.disabled = !sanitizeOnShutdownPref.value;
-  },
-
-  toggleDoNotDisturbNotifications(event) {
-    AlertsServiceDND.manualDoNotDisturb = event.target.checked;
+  clearSiteData() {
+    gSubDialog.open("chrome://browser/content/preferences/clearSiteData.xul");
   },
 
   // GEOLOCATION
 
   /**
    * Displays the location exceptions dialog where specific site location
    * preferences can be set.
    */
@@ -1382,47 +1399,16 @@ var gPrivacyPane = {
 
   /**
    * Displays a dialog from which the user can manage his security devices.
    */
   showSecurityDevices() {
     gSubDialog.open("chrome://pippki/content/device_manager.xul");
   },
 
-  showSiteDataSettings() {
-    gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
-  },
-
-  toggleSiteData(shouldShow) {
-    let clearButton = document.getElementById("clearSiteDataButton");
-    let settingsButton = document.getElementById("siteDataSettings");
-    clearButton.disabled = !shouldShow;
-    settingsButton.disabled = !shouldShow;
-  },
-
-  showSiteDataLoading() {
-    let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
-    let prefStrBundle = document.getElementById("bundlePreferences");
-    totalSiteDataSizeLabel.textContent = prefStrBundle.getString("loadingSiteDataSize1");
-  },
-
-  updateTotalDataSizeLabel(siteDataUsage) {
-    SiteDataManager.getCacheSize().then(function(cacheUsage) {
-      let prefStrBundle = document.getElementById("bundlePreferences");
-      let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
-      let totalUsage = siteDataUsage + cacheUsage;
-      let size = DownloadUtils.convertByteUnits(totalUsage);
-      totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize2", size);
-    });
-  },
-
-  clearSiteData() {
-    gSubDialog.open("chrome://browser/content/preferences/clearSiteData.xul");
-  },
-
   initDataCollection() {
     this._setupLearnMoreLink("toolkit.datacollection.infoURL",
       "dataCollectionPrivacyNotice");
   },
 
   initCollectBrowserErrors() {
     this._setupLearnMoreLink("browser.chrome.errorReporter.infoURL",
       "collectBrowserErrorsLearnMore");
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -181,16 +181,17 @@
               class="indent"
               align="center">
           <label id="keepUntil"
                  control="keepCookiesUntil"
                  accesskey="&keepUntil2.accesskey;">&keepUntil2.label;</label>
           <!-- Please don't remove the wrapping hbox/vbox/box for these elements. It's used to properly compute the search tooltip position. -->
           <hbox>
             <menulist id="keepCookiesUntil"
+                      onsyncfrompreference="return gPrivacyPane.readKeepCookiesUntil();"
                       preference="network.cookie.lifetimePolicy">
               <menupopup>
                 <menuitem label="&expire.label;" value="0"/>
                 <menuitem label="&close.label;" value="2"/>
               </menupopup>
             </menulist>
           </hbox>
         </hbox>
--- a/browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js
+++ b/browser/components/preferences/in-content/tests/privacypane_tests_perwindow.js
@@ -111,42 +111,55 @@ function test_dependent_elements(win) {
   // setting the mode to custom shouldn't change anything
   historymode.value = "custom";
   controlChanged(historymode);
   expect_disabled(false);
   check_independents(false);
 }
 
 function test_dependent_cookie_elements(win) {
-  let controls = [
-    win.document.getElementById("acceptThirdPartyLabel"),
-    win.document.getElementById("acceptThirdPartyMenu"),
-    win.document.getElementById("keepUntil"),
-    win.document.getElementById("keepCookiesUntil"),
-  ];
+  let keepUntil = win.document.getElementById("keepUntil");
+  let keepCookiesUntil = win.document.getElementById("keepCookiesUntil");
+  let acceptThirdPartyLabel = win.document.getElementById("acceptThirdPartyLabel");
+  let acceptThirdPartyMenu = win.document.getElementById("acceptThirdPartyMenu");
+
+  let controls = [acceptThirdPartyLabel, acceptThirdPartyMenu, keepUntil, keepCookiesUntil];
   controls.forEach(function(control) {
     ok(control, "the dependent cookie controls should exist");
   });
   let acceptcookies = win.document.getElementById("acceptCookies");
   ok(acceptcookies, "the accept cookies checkbox should exist");
 
-  function expect_disabled(disabled) {
-    controls.forEach(function(control) {
+  function expect_disabled(disabled, c = controls) {
+    c.forEach(function(control) {
       is(control.disabled, disabled,
         control.getAttribute("id") + " should " + (disabled ? "" : "not ") + "be disabled");
     });
   }
 
   acceptcookies.value = "2";
   controlChanged(acceptcookies);
   expect_disabled(true);
 
   acceptcookies.value = "1";
   controlChanged(acceptcookies);
   expect_disabled(false);
+
+  let historymode = win.document.getElementById("historyMode");
+
+  // The History mode setting for "never remember history" should still
+  // disable the "keep cookies until..." menu.
+  historymode.value = "dontremember";
+  controlChanged(historymode);
+  expect_disabled(true, [keepUntil, keepCookiesUntil]);
+  expect_disabled(false, [acceptThirdPartyLabel, acceptThirdPartyMenu]);
+
+  historymode.value = "remember";
+  controlChanged(historymode);
+  expect_disabled(false);
 }
 
 function test_dependent_clearonclose_elements(win) {
   let historymode = win.document.getElementById("historyMode");
   ok(historymode, "history mode menulist should exist");
   let pbautostart = win.document.getElementById("privateBrowsingAutoStart");
   ok(pbautostart, "the private browsing auto-start checkbox should exist");
   let alwaysclear = win.document.getElementById("alwaysClear");