Bug 723737 - Move the advanced preferences to in-content UI. r=jaws r=bmcbride
authorJon Rietveld <jon.rietveld@gmail.com>
Tue, 08 May 2012 19:18:11 -0700
changeset 93577 68e7c139e580502a3631385a5645bcdffd5dedb2
parent 93576 d849b7493ea2348c99fc7582e3d6950ca6125fdf
child 93578 bb179b7cf7222eb12b085a1be1691a6776da73ed
push id9210
push userjwein@mozilla.com
push dateWed, 09 May 2012 05:35:43 +0000
treeherdermozilla-inbound@8b195889f55c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws, bmcbride
bugs723737
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 723737 - Move the advanced preferences to in-content UI. r=jaws r=bmcbride
browser/components/preferences/in-content/advanced.js
browser/components/preferences/in-content/advanced.xul
browser/components/preferences/in-content/jar.mn
browser/components/preferences/in-content/preferences.js
browser/components/preferences/in-content/preferences.xul
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/advanced.js
@@ -0,0 +1,703 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Load DownloadUtils module for convertByteUnits
+Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
+
+var gAdvancedPane = {
+  _inited: false,
+
+  /**
+   * Brings the appropriate tab to the front and initializes various bits of UI.
+   */
+  init: function ()
+  {
+    this._inited = true;
+    var advancedPrefs = document.getElementById("advancedPrefs");
+
+    var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
+    if (preference.value !== null)
+        advancedPrefs.selectedIndex = preference.value;
+
+#ifdef MOZ_UPDATER
+    this.updateReadPrefs();
+#endif
+    this.updateOfflineApps();
+#ifdef MOZ_CRASHREPORTER
+    this.initSubmitCrashes();
+#endif
+    this.updateActualCacheSize("disk");
+    this.updateActualCacheSize("offline");
+  },
+
+  /**
+   * Stores the identity of the current tab in preferences so that the selected
+   * tab can be persisted between openings of the preferences window.
+   */
+  tabSelectionChanged: function ()
+  {
+    if (!this._inited)
+      return;
+    var advancedPrefs = document.getElementById("advancedPrefs");
+    var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
+    preference.valueFromPreferences = advancedPrefs.selectedIndex;
+  },
+
+  // GENERAL TAB
+
+  /*
+   * Preferences:
+   *
+   * accessibility.browsewithcaret
+   * - true enables keyboard navigation and selection within web pages using a
+   *   visible caret, false uses normal keyboard navigation with no caret
+   * accessibility.typeaheadfind
+   * - when set to true, typing outside text areas and input boxes will
+   *   automatically start searching for what's typed within the current
+   *   document; when set to false, no search action happens
+   * general.autoScroll
+   * - when set to true, clicking the scroll wheel on the mouse activates a
+   *   mouse mode where moving the mouse down scrolls the document downward with
+   *   speed correlated with the distance of the cursor from the original
+   *   position at which the click occurred (and likewise with movement upward);
+   *   if false, this behavior is disabled
+   * general.smoothScroll
+   * - set to true to enable finer page scrolling than line-by-line on page-up,
+   *   page-down, and other such page movements
+   * layout.spellcheckDefault
+   * - an integer:
+   *     0  disables spellchecking
+   *     1  enables spellchecking, but only for multiline text fields
+   *     2  enables spellchecking for all text fields
+   */
+
+  /**
+   * Stores the original value of the spellchecking preference to enable proper
+   * restoration if unchanged (since we're mapping a tristate onto a checkbox).
+   */
+  _storedSpellCheck: 0,
+
+  /**
+   * Returns true if any spellchecking is enabled and false otherwise, caching
+   * the current value to enable proper pref restoration if the checkbox is
+   * never changed.
+   */
+  readCheckSpelling: function ()
+  {
+    var pref = document.getElementById("layout.spellcheckDefault");
+    this._storedSpellCheck = pref.value;
+
+    return (pref.value != 0);
+  },
+
+  /**
+   * Returns the value of the spellchecking preference represented by UI,
+   * preserving the preference's "hidden" value if the preference is
+   * unchanged and represents a value not strictly allowed in UI.
+   */
+  writeCheckSpelling: function ()
+  {
+    var checkbox = document.getElementById("checkSpelling");
+    return checkbox.checked ? (this._storedSpellCheck == 2 ? 2 : 1) : 0;
+  },
+
+  /**
+   *
+   */
+  initSubmitCrashes: function ()
+  {
+    var checkbox = document.getElementById("submitCrashesBox");
+    try {
+      var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"].
+               getService(Components.interfaces.nsICrashReporter);
+      checkbox.checked = cr.submitReports;
+    } catch (e) {
+      checkbox.style.display = "none";
+    }
+  },
+
+  /**
+   *
+   */
+  updateSubmitCrashes: function ()
+  {
+    var checkbox = document.getElementById("submitCrashesBox");
+    try {
+      var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"].
+               getService(Components.interfaces.nsICrashReporter);
+      cr.submitReports = checkbox.checked;
+    } catch (e) { }
+  },
+
+  /**
+   * When the user toggles the layers.acceleration.disabled pref,
+   * sync its new value to the gfx.direct2d.disabled pref too.
+   */
+  updateHardwareAcceleration: function()
+  {
+#ifdef XP_WIN
+    var fromPref = document.getElementById("layers.acceleration.disabled");
+    var toPref = document.getElementById("gfx.direct2d.disabled");
+    toPref.value = fromPref.value;
+#endif
+  },
+
+  // NETWORK TAB
+
+  /*
+   * Preferences:
+   *
+   * browser.cache.disk.capacity
+   * - the size of the browser cache in KB
+   * - Only used if browser.cache.disk.smart_size.enabled is disabled
+   */
+
+  /**
+   * Displays a dialog in which proxy settings may be changed.
+   */
+  showConnections: function ()
+  {
+    openDialog("chrome://browser/content/preferences/connection.xul",
+               "mozilla:connectionmanager",
+               "model=yes",
+               null);
+  },
+
+  // Retrieves the amount of space currently used by disk or offline cache
+  updateActualCacheSize: function (device)
+  {
+    var visitor = {
+      visitDevice: function (deviceID, deviceInfo)
+      {
+        if (deviceID == device) {
+          var actualSizeLabel = document.getElementById(device == "disk" ?
+                                                        "actualDiskCacheSize" :
+                                                        "actualAppCacheSize");
+          var sizeStrings = DownloadUtils.convertByteUnits(deviceInfo.totalSize);
+          var prefStrBundle = document.getElementById("bundlePreferences");
+          var sizeStr = prefStrBundle.getFormattedString(device == "disk" ?
+                                                         "actualDiskCacheSize" :
+                                                         "actualAppCacheSize",
+                                                         sizeStrings);
+          actualSizeLabel.value = sizeStr;
+        }
+        // Do not enumerate entries
+        return false;
+      },
+
+      visitEntry: function (deviceID, entryInfo)
+      {
+        // Do not enumerate entries.
+        return false;
+      }
+    };
+
+    var cacheService =
+      Components.classes["@mozilla.org/network/cache-service;1"]
+                .getService(Components.interfaces.nsICacheService);
+    cacheService.visitEntries(visitor);
+  },
+
+  updateCacheSizeUI: function (smartSizeEnabled)
+  {
+    document.getElementById("useCacheBefore").disabled = smartSizeEnabled;
+    document.getElementById("cacheSize").disabled = smartSizeEnabled;
+    document.getElementById("useCacheAfter").disabled = smartSizeEnabled;
+  },
+
+  readSmartSizeEnabled: function ()
+  {
+    // The smart_size.enabled preference element is inverted="true", so its
+    // value is the opposite of the actual pref value
+    var disabled = document.getElementById("browser.cache.disk.smart_size.enabled").value;
+    this.updateCacheSizeUI(!disabled);
+  },
+
+  /**
+   * Converts the cache size from units of KB to units of MB and returns that
+   * value.
+   */
+  readCacheSize: function ()
+  {
+    var preference = document.getElementById("browser.cache.disk.capacity");
+    return preference.value / 1024;
+  },
+
+  /**
+   * Converts the cache size as specified in UI (in MB) to KB and returns that
+   * value.
+   */
+  writeCacheSize: function ()
+  {
+    var cacheSize = document.getElementById("cacheSize");
+    var intValue = parseInt(cacheSize.value, 10);
+    return isNaN(intValue) ? 0 : intValue * 1024;
+  },
+
+  /**
+   * Clears the cache.
+   */
+  clearCache: function ()
+  {
+    var cacheService = Components.classes["@mozilla.org/network/cache-service;1"]
+                                 .getService(Components.interfaces.nsICacheService);
+    try {
+      cacheService.evictEntries(Components.interfaces.nsICache.STORE_ANYWHERE);
+    } catch(ex) {}
+    this.updateActualCacheSize("disk");
+  },
+
+  /**
+   * Clears the application cache.
+   */
+  clearOfflineAppCache: function ()
+  {
+    Components.utils.import("resource:///modules/offlineAppCache.jsm");
+    OfflineAppCacheHelper.clear();
+
+    this.updateActualCacheSize("offline");
+    this.updateOfflineApps();
+  },
+
+  readOfflineNotify: function()
+  {
+    var pref = document.getElementById("browser.offline-apps.notify");
+    var button = document.getElementById("offlineNotifyExceptions");
+    button.disabled = !pref.value;
+    return pref.value;
+  },
+
+  showOfflineExceptions: function()
+  {
+    var bundlePreferences = document.getElementById("bundlePreferences");
+    var params = { blockVisible     : false,
+                   sessionVisible   : false,
+                   allowVisible     : false,
+                   prefilledHost    : "",
+                   permissionType   : "offline-app",
+                   manageCapability : Components.interfaces.nsIPermissionManager.DENY_ACTION,
+                   windowTitle      : bundlePreferences.getString("offlinepermissionstitle"),
+                   introText        : bundlePreferences.getString("offlinepermissionstext") };
+    openDialog("chrome://browser/content/preferences/permissions.xul",
+               "Browser:Permissions",
+               "model=yes",
+               params);
+  },
+
+  // XXX: duplicated in browser.js
+  _getOfflineAppUsage: function (host, groups)
+  {
+    var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
+                       getService(Components.interfaces.nsIApplicationCacheService);
+    if (!groups)
+      groups = cacheService.getGroups();
+
+    var ios = Components.classes["@mozilla.org/network/io-service;1"].
+              getService(Components.interfaces.nsIIOService);
+
+    var usage = 0;
+    for (var i = 0; i < groups.length; i++) {
+      var uri = ios.newURI(groups[i], null, null);
+      if (uri.asciiHost == host) {
+        var cache = cacheService.getActiveCache(groups[i]);
+        usage += cache.usage;
+      }
+    }
+
+    var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"].
+                         getService(Components.interfaces.nsIDOMStorageManager);
+    usage += storageManager.getUsage(host);
+
+    return usage;
+  },
+
+  /**
+   * Updates the list of offline applications
+   */
+  updateOfflineApps: function ()
+  {
+    var pm = Components.classes["@mozilla.org/permissionmanager;1"]
+                       .getService(Components.interfaces.nsIPermissionManager);
+
+    var list = document.getElementById("offlineAppsList");
+    while (list.firstChild) {
+      list.removeChild(list.firstChild);
+    }
+
+    var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
+                       getService(Components.interfaces.nsIApplicationCacheService);
+    var groups = cacheService.getGroups();
+
+    var bundle = document.getElementById("bundlePreferences");
+
+    var enumerator = pm.enumerator;
+    while (enumerator.hasMoreElements()) {
+      var perm = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
+      if (perm.type == "offline-app" &&
+          perm.capability != Components.interfaces.nsIPermissionManager.DEFAULT_ACTION &&
+          perm.capability != Components.interfaces.nsIPermissionManager.DENY_ACTION) {
+        var row = document.createElement("listitem");
+        row.id = "";
+        row.className = "offlineapp";
+        row.setAttribute("host", perm.host);
+        var converted = DownloadUtils.
+                        convertByteUnits(this._getOfflineAppUsage(perm.host, groups));
+        row.setAttribute("usage",
+                         bundle.getFormattedString("offlineAppUsage",
+                                                   converted));
+        list.appendChild(row);
+      }
+    }
+  },
+
+  offlineAppSelected: function()
+  {
+    var removeButton = document.getElementById("offlineAppsListRemove");
+    var list = document.getElementById("offlineAppsList");
+    if (list.selectedItem) {
+      removeButton.setAttribute("disabled", "false");
+    } else {
+      removeButton.setAttribute("disabled", "true");
+    }
+  },
+
+  removeOfflineApp: function()
+  {
+    var list = document.getElementById("offlineAppsList");
+    var item = list.selectedItem;
+    var host = item.getAttribute("host");
+
+    var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+                            .getService(Components.interfaces.nsIPromptService);
+    var flags = prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_0 +
+                prompts.BUTTON_TITLE_CANCEL * prompts.BUTTON_POS_1;
+
+    var bundle = document.getElementById("bundlePreferences");
+    var title = bundle.getString("offlineAppRemoveTitle");
+    var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [host]);
+    var confirm = bundle.getString("offlineAppRemoveConfirm");
+    var result = prompts.confirmEx(window, title, prompt, flags, confirm,
+                                   null, null, null, {});
+    if (result != 0)
+      return;
+
+    // clear offline cache entries
+    var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"].
+                       getService(Components.interfaces.nsIApplicationCacheService);
+    var ios = Components.classes["@mozilla.org/network/io-service;1"].
+              getService(Components.interfaces.nsIIOService);
+    var groups = cacheService.getGroups();
+    for (var i = 0; i < groups.length; i++) {
+        var uri = ios.newURI(groups[i], null, null);
+        if (uri.asciiHost == host) {
+            var cache = cacheService.getActiveCache(groups[i]);
+            cache.discard();
+        }
+    }
+
+    // send out an offline-app-removed signal.  The nsDOMStorage
+    // service will clear DOM storage for this host.
+    var obs = Components.classes["@mozilla.org/observer-service;1"]
+                        .getService(Components.interfaces.nsIObserverService);
+    obs.notifyObservers(null, "offline-app-removed", host);
+
+    // remove the permission
+    var pm = Components.classes["@mozilla.org/permissionmanager;1"]
+                       .getService(Components.interfaces.nsIPermissionManager);
+    pm.remove(host, "offline-app",
+              Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
+    pm.remove(host, "offline-app",
+              Components.interfaces.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
+
+    list.removeChild(item);
+    gAdvancedPane.offlineAppSelected();
+    this.updateActualCacheSize("offline");
+  },
+
+  // UPDATE TAB
+
+  /*
+   * Preferences:
+   *
+   * app.update.enabled
+   * - true if updates to the application are enabled, false otherwise
+   * extensions.update.enabled
+   * - true if updates to extensions and themes are enabled, false otherwise
+   * browser.search.update
+   * - true if updates to search engines are enabled, false otherwise
+   * app.update.auto
+   * - true if updates should be automatically downloaded and installed,
+   *   possibly with a warning if incompatible extensions are installed (see
+   *   app.update.mode); false if the user should be asked what he wants to do
+   *   when an update is available
+   * app.update.mode
+   * - an integer:
+   *     0    do not warn if an update will disable extensions or themes
+   *     1    warn if an update will disable extensions or themes
+   *     2    warn if an update will disable extensions or themes *or* if the
+   *          update is a major update
+   */
+
+#ifdef MOZ_UPDATER
+  /**
+   * Selects the item of the radiogroup, and sets the warnIncompatible checkbox
+   * based on the pref values and locked states.
+   *
+   * UI state matrix for update preference conditions
+   *
+   * UI Components:                              Preferences
+   * Radiogroup                                  i   = app.update.enabled
+   * Warn before disabling extensions checkbox   ii  = app.update.auto
+   *                                             iii = app.update.mode
+   *
+   * Disabled states:
+   * Element           pref  value  locked  disabled
+   * radiogroup        i     t/f    f       false
+   *                   i     t/f    *t*     *true*
+   *                   ii    t/f    f       false
+   *                   ii    t/f    *t*     *true*
+   *                   iii   0/1/2  t/f     false
+   * warnIncompatible  i     t      f       false
+   *                   i     t      *t*     *true*
+   *                   i     *f*    t/f     *true*
+   *                   ii    t      f       false
+   *                   ii    t      *t*     *true*
+   *                   ii    *f*    t/f     *true*
+   *                   iii   0/1/2  f       false
+   *                   iii   0/1/2  *t*     *true*
+   */
+  updateReadPrefs: function ()
+  {
+    var enabledPref = document.getElementById("app.update.enabled");
+    var autoPref = document.getElementById("app.update.auto");
+    var radiogroup = document.getElementById("updateRadioGroup");
+
+    if (!enabledPref.value)   // Don't care for autoPref.value in this case.
+      radiogroup.value="manual"     // 3. Never check for updates.
+    else if (autoPref.value)  // enabledPref.value && autoPref.value
+      radiogroup.value="auto";      // 1. Automatically install updates
+    else                      // enabledPref.value && !autoPref.value
+      radiogroup.value="checkOnly"; // 2. Check, but let me choose
+
+    var canCheck = Components.classes["@mozilla.org/updates/update-service;1"].
+                     getService(Components.interfaces.nsIApplicationUpdateService).
+                     canCheckForUpdates;
+    // canCheck is false if the enabledPref is false and locked,
+    // or the binary platform or OS version is not known.
+    // A locked pref is sufficient to disable the radiogroup.
+    radiogroup.disabled = !canCheck || enabledPref.locked || autoPref.locked;
+
+    var modePref = document.getElementById("app.update.mode");
+    var warnIncompatible = document.getElementById("warnIncompatible");
+    // the warnIncompatible checkbox value is set by readAddonWarn
+    warnIncompatible.disabled = radiogroup.disabled || modePref.locked ||
+                                !enabledPref.value || !autoPref.value;
+
+#ifdef MOZ_MAINTENANCE_SERVICE
+    // Check to see if the maintenance service is installed.
+    // If it is don't show the preference at all.
+    var installed;
+    try {
+      var wrk = Components.classes["@mozilla.org/windows-registry-key;1"]
+                .createInstance(Components.interfaces.nsIWindowsRegKey);
+      wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
+               "SOFTWARE\\Mozilla\\MaintenanceService",
+               wrk.ACCESS_READ | wrk.WOW64_64);
+      installed = wrk.readIntValue("Installed");
+      wrk.close();
+    } catch(e) {
+    }
+    if (installed != 1) {
+      document.getElementById("useService").hidden = true;
+    }
+#endif
+  },
+
+  /**
+   * Sets the pref values based on the selected item of the radiogroup,
+   * and sets the disabled state of the warnIncompatible checkbox accordingly.
+   */
+  updateWritePrefs: function ()
+  {
+    var enabledPref = document.getElementById("app.update.enabled");
+    var autoPref = document.getElementById("app.update.auto");
+    var radiogroup = document.getElementById("updateRadioGroup");
+    switch (radiogroup.value) {
+      case "auto":      // 1. Automatically install updates
+        enabledPref.value = true;
+        autoPref.value = true;
+        break;
+      case "checkOnly": // 2. Check, but let me choose
+        enabledPref.value = true;
+        autoPref.value = false;
+        break;
+      case "manual":    // 3. Never check for updates.
+        enabledPref.value = false;
+        autoPref.value = false;
+    }
+
+    var warnIncompatible = document.getElementById("warnIncompatible");
+    var modePref = document.getElementById("app.update.mode");
+    warnIncompatible.disabled = enabledPref.locked || !enabledPref.value ||
+                                autoPref.locked || !autoPref.value ||
+                                modePref.locked;
+  },
+
+  /**
+   * Stores the value of the app.update.mode preference, which is a tristate
+   * integer preference.  We store the value here so that we can properly
+   * restore the preference value if the UI reflecting the preference value
+   * is in a state which can represent either of two integer values (as
+   * opposed to only one possible value in the other UI state).
+   */
+  _modePreference: -1,
+
+  /**
+   * Reads the app.update.mode preference and converts its value into a
+   * true/false value for use in determining whether the "Warn me if this will
+   * disable extensions or themes" checkbox is checked.  We also save the value
+   * of the preference so that the preference value can be properly restored if
+   * the user's preferences cannot adequately be expressed by a single checkbox.
+   *
+   * app.update.mode          Checkbox State    Meaning
+   * 0                        Unchecked         Do not warn
+   * 1                        Checked           Warn if there are incompatibilities
+   * 2                        Checked           Warn if there are incompatibilities,
+   *                                            or the update is major.
+   */
+  readAddonWarn: function ()
+  {
+    var preference = document.getElementById("app.update.mode");
+    var warn = preference.value != 0;
+    gAdvancedPane._modePreference = warn ? preference.value : 1;
+    return warn;
+  },
+
+  /**
+   * Converts the state of the "Warn me if this will disable extensions or
+   * themes" checkbox into the integer preference which represents it,
+   * returning that value.
+   */
+  writeAddonWarn: function ()
+  {
+    var warnIncompatible = document.getElementById("warnIncompatible");
+    return !warnIncompatible.checked ? 0 : gAdvancedPane._modePreference;
+  },
+
+  /**
+   * Displays the history of installed updates.
+   */
+  showUpdates: function ()
+  {
+    var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
+                             .createInstance(Components.interfaces.nsIUpdatePrompt);
+    prompter.showUpdateHistory(window);
+  },
+#endif
+
+  // ENCRYPTION TAB
+
+  /*
+   * Preferences:
+   *
+   * security.enable_ssl3
+   * - true if SSL 3 encryption is enabled, false otherwise
+   * security.enable_tls
+   * - true if TLS encryption is enabled, false otherwise
+   * security.default_personal_cert
+   * - a string:
+   *     "Select Automatically"   select a certificate automatically when a site
+   *                              requests one
+   *     "Ask Every Time"         present a dialog to the user so he can select
+   *                              the certificate to use on a site which
+   *                              requests one
+   */
+
+  /**
+   * Displays the user's certificates and associated options.
+   */
+  showCertificates: function ()
+  {
+    openDialog("chrome://pippki/content/certManager.xul",
+               "mozilla:certmanager",
+               "model=yes", null);
+  },
+
+  /**
+   * Displays a dialog which describes the user's CRLs.
+   */
+  showCRLs: function ()
+  {
+    openDialog("chrome://pippki/content/crlManager.xul",
+               "mozilla:crlmanager",
+               "model=yes", null);
+  },
+
+  /**
+   * Displays a dialog in which OCSP preferences can be configured.
+   */
+  showOCSP: function ()
+  {
+    openDialog("chrome://mozapps/content/preferences/ocsp.xul",
+               "mozilla:crlmanager",
+               "model=yes", null);
+  },
+
+  /**
+   * Displays a dialog from which the user can manage his security devices.
+   */
+  showSecurityDevices: function ()
+  {
+    openDialog("chrome://pippki/content/device_manager.xul",
+               "mozilla:devicemanager",
+               "model=yes", null);
+  }
+#ifdef HAVE_SHELL_SERVICE
+  ,
+
+  // SYSTEM DEFAULTS
+
+  /*
+   * Preferences:
+   *
+   * browser.shell.checkDefault
+   * - true if a default-browser check (and prompt to make it so if necessary)
+   *   occurs at startup, false otherwise
+   */
+
+  /**
+   * Checks whether the browser is currently registered with the operating
+   * system as the default browser.  If the browser is not currently the
+   * default browser, the user is given the option of making it the default;
+   * otherwise, the user is informed that this browser already is the browser.
+   */
+  checkNow: function ()
+  {
+    var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
+                             .getService(Components.interfaces.nsIShellService);
+    var brandBundle = document.getElementById("bundleBrand");
+    var shellBundle = document.getElementById("bundleShell");
+    var brandShortName = brandBundle.getString("brandShortName");
+    var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
+    var promptMessage;
+    const IPS = Components.interfaces.nsIPromptService;
+    var psvc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+                         .getService(IPS);
+    if (!shellSvc.isDefaultBrowser(false)) {
+      promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
+                                                     [brandShortName]);
+      var rv = psvc.confirmEx(window, promptTitle, promptMessage,
+                              IPS.STD_YES_NO_BUTTONS,
+                              null, null, null, null, { });
+      if (rv == 0)
+        shellSvc.setDefaultBrowser(true, false);
+    }
+    else {
+      promptMessage = shellBundle.getFormattedString("alreadyDefaultBrowser",
+                                                     [brandShortName]);
+      psvc.alert(window, promptTitle, promptMessage);
+    }
+  }
+#endif
+};
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/advanced.xul
@@ -0,0 +1,429 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this file,
+   - You can obtain one at http://mozilla.org/MPL/2.0/.  -->
+
+<script type="application/javascript"
+        src="chrome://browser/content/preferences/in-content/advanced.js"/>
+
+<preferences id="advancedPreferences">
+  <preference id="browser.preferences.advanced.selectedTabIndex"
+              name="browser.preferences.advanced.selectedTabIndex"
+              type="int"/>
+
+  <!-- General tab -->
+  <preference id="accessibility.browsewithcaret"
+              name="accessibility.browsewithcaret"
+              type="bool"/>
+  <preference id="accessibility.typeaheadfind"
+              name="accessibility.typeaheadfind"
+              type="bool"/>
+  <preference id="accessibility.blockautorefresh"
+              name="accessibility.blockautorefresh"
+              type="bool"/>
+
+  <preference id="general.autoScroll"
+              name="general.autoScroll"
+              type="bool"/>
+  <preference id="general.smoothScroll"
+              name="general.smoothScroll"
+              type="bool"/>
+  <preference id="layers.acceleration.disabled"
+              name="layers.acceleration.disabled"
+              type="bool"
+              inverted="true"
+              onchange="gAdvancedPane.updateHardwareAcceleration()"/>
+#ifdef XP_WIN
+  <preference id="gfx.direct2d.disabled"
+              name="gfx.direct2d.disabled"
+              type="bool"
+              inverted="true"/>
+#endif
+  <preference id="layout.spellcheckDefault"
+              name="layout.spellcheckDefault"
+              type="int"/>
+
+#ifdef HAVE_SHELL_SERVICE
+  <preference id="browser.shell.checkDefaultBrowser"
+              name="browser.shell.checkDefaultBrowser"
+              type="bool"/>
+
+  <preference id="pref.general.disable_button.default_browser"
+              name="pref.general.disable_button.default_browser"
+              type="bool"/>
+#endif
+
+  <preference id="toolkit.telemetry.enabled"
+              name="toolkit.telemetry.enabled"
+              type="bool"/>
+
+  <!-- Network tab -->
+  <preference id="browser.cache.disk.capacity"
+              name="browser.cache.disk.capacity"
+              type="int"/>
+  <preference id="browser.offline-apps.notify"
+              name="browser.offline-apps.notify"
+              type="bool"/>
+
+  <preference id="browser.cache.disk.smart_size.enabled"
+              name="browser.cache.disk.smart_size.enabled"
+              inverted="true"
+              type="bool"/>
+
+ <!-- Update tab -->
+#ifdef MOZ_UPDATER
+  <preference id="app.update.enabled"
+              name="app.update.enabled"
+              type="bool"/>
+  <preference id="app.update.auto"
+              name="app.update.auto"
+              type="bool"/>
+  <preference id="app.update.mode"
+              name="app.update.mode"
+              type="int"/>
+
+  <preference id="app.update.disable_button.showUpdateHistory"
+              name="app.update.disable_button.showUpdateHistory"
+              type="bool"/>
+
+#ifdef MOZ_MAINTENANCE_SERVICE
+  <preference id="app.update.service.enabled"
+              name="app.update.service.enabled"
+              type="bool"/>
+#endif
+#endif
+
+  <preference id="browser.search.update"
+              name="browser.search.update"
+              type="bool"/>
+
+  <!-- Encryption tab -->
+  <preference id="security.enable_ssl3"
+              name="security.enable_ssl3"
+              type="bool"/>
+  <preference id="security.enable_tls"
+              name="security.enable_tls"
+              type="bool"/>
+
+  <preference id="security.default_personal_cert"
+              name="security.default_personal_cert"
+              type="string"/>
+
+  <preference id="security.disable_button.openCertManager"
+              name="security.disable_button.openCertManager"
+              type="bool"/>
+  <preference id="security.OCSP.disable_button.managecrl"
+              name="security.OCSP.disable_button.managecrl"
+              type="bool"/>
+  <preference id="security.disable_button.openDeviceManager"
+              name="security.disable_button.openDeviceManager"
+              type="bool"/>
+</preferences>
+
+#ifdef HAVE_SHELL_SERVICE
+  <stringbundle id="bundleShell" src="chrome://browser/locale/shellservice.properties"/>
+  <stringbundle id="bundleBrand" src="chrome://branding/locale/brand.properties"/>
+#endif
+
+<hbox class="heading" data-category="paneAdvanced" hidden="true">
+  <image class="preference-icon" type="advanced"/>
+  <html:h1>&paneAdvanced.title;</html:h1>
+</hbox>
+
+<tabbox id="advancedPrefs" flex="1"
+        data-category="paneAdvanced" hidden="true"
+        onselect="gAdvancedPane.tabSelectionChanged();">
+
+  <tabs id="tabsElement">
+    <tab id="generalTab" label="&generalTab.label;" helpTopic="prefs-advanced-general"/>
+    <tab id="networkTab" label="&networkTab.label;" helpTopic="prefs-advanced-network"/>
+    <tab id="updateTab" label="&updateTab.label;"  helpTopic="prefs-advanced-update"/>
+    <tab id="encryptionTab" label="&encryptionTab.label;" helpTopic="prefs-advanced-encryption"/>
+  </tabs>
+
+  <tabpanels flex="1">
+
+    <!-- General -->
+    <tabpanel id="generalPanel" orient="vertical">
+      <!-- Accessibility -->
+      <groupbox id="accessibilityGroup" align="start">
+        <caption label="&accessibility.label;"/>
+
+        <checkbox id="useCursorNavigation"
+                  label="&useCursorNavigation.label;"
+                  accesskey="&useCursorNavigation.accesskey;"
+                  preference="accessibility.browsewithcaret"/>
+        <checkbox id="searchStartTyping"
+                  label="&searchStartTyping.label;"
+                  accesskey="&searchStartTyping.accesskey;"
+                  preference="accessibility.typeaheadfind"/>
+        <checkbox id="blockAutoRefresh"
+                  label="&blockAutoRefresh.label;"
+                  accesskey="&blockAutoRefresh.accesskey;"
+                  preference="accessibility.blockautorefresh"/>
+      </groupbox>
+      <!-- Browsing -->
+      <groupbox id="browsingGroup" align="start">
+        <caption label="&browsing.label;"/>
+
+        <checkbox id="useAutoScroll"
+                  label="&useAutoScroll.label;"
+                  accesskey="&useAutoScroll.accesskey;"
+                  preference="general.autoScroll"/>
+        <checkbox id="useSmoothScrolling"
+                  label="&useSmoothScrolling.label;"
+                  accesskey="&useSmoothScrolling.accesskey;"
+                  preference="general.smoothScroll"/>
+        <checkbox id="allowHWAccel"
+                  label="&allowHWAccel.label;"
+                  accesskey="&allowHWAccel.accesskey;"
+                  preference="layers.acceleration.disabled"/>
+        <checkbox id="checkSpelling"
+                  label="&checkSpelling.label;"
+                  accesskey="&checkSpelling.accesskey;"
+                  onsyncfrompreference="return gAdvancedPane.readCheckSpelling();"
+                  onsynctopreference="return gAdvancedPane.writeCheckSpelling();"
+                  preference="layout.spellcheckDefault"/>
+      </groupbox>
+      <!-- System Defaults -->
+      <groupbox id="systemDefaultsGroup" orient="vertical">
+        <caption label="&systemDefaults.label;"/>
+
+#ifdef HAVE_SHELL_SERVICE
+        <hbox id="checkDefaultBox" align="center" flex="1">
+          <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser"
+                    label="&alwaysCheckDefault.label;" accesskey="&alwaysCheckDefault.accesskey;"
+                    flex="1"/>
+          <button id="checkDefaultButton"
+                  label="&checkNow.label;" accesskey="&checkNow.accesskey;"
+                  oncommand="gAdvancedPane.checkNow()"
+                  preference="pref.general.disable_button.default_browser"/>
+        </hbox>
+#ifdef MOZ_CRASHREPORTER
+        <checkbox id="submitCrashesBox" flex="1"
+                  oncommand="gAdvancedPane.updateSubmitCrashes();"
+                  label="&submitCrashes.label;" accesskey="&submitCrashes.accesskey;"/>
+#endif
+#endif
+        <checkbox id="submitTelemetryBox" flex="1"
+                  preference="toolkit.telemetry.enabled"
+                  label="&submitTelemetry.label;" accesskey="&submitTelemetry.accesskey;"/>
+      </groupbox>
+    </tabpanel>
+
+    <!-- Network -->
+    <tabpanel id="networkPanel" orient="vertical">
+
+      <!-- Connection -->
+      <groupbox id="connectionGroup">
+        <caption label="&connection.label;"/>
+
+        <hbox align="center">
+          <description flex="1" control="connectionSettings">&connectionDesc.label;</description>
+          <button id="connectionSettings" icon="network" label="&connectionSettings.label;"
+                  accesskey="&connectionSettings.accesskey;"
+                  oncommand="gAdvancedPane.showConnections();"/>
+        </hbox>
+      </groupbox>
+
+      <!-- Cache -->
+      <groupbox id="cacheGroup">
+        <caption label="&httpCache.label;"/>
+
+        <hbox align="center">
+          <label id="actualDiskCacheSize" flex="1"/>
+          <button id="clearCacheButton" icon="clear"
+                  label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"
+                  oncommand="gAdvancedPane.clearCache();"/>
+        </hbox>
+        <checkbox preference="browser.cache.disk.smart_size.enabled"
+                  id="allowSmartSize" flex="1"
+                  onsyncfrompreference="return gAdvancedPane.readSmartSizeEnabled();"
+                  label="&overrideSmartCacheSize.label;"
+                  accesskey="&overrideSmartCacheSize.accesskey;"/>
+        <hbox align="center" class="indent">
+          <label id="useCacheBefore" control="cacheSize"
+                accesskey="&limitCacheSizeBefore.accesskey;"
+                value="&limitCacheSizeBefore.label;"/>
+          <textbox id="cacheSize" type="number" size="4" max="1024"
+                  preference="browser.cache.disk.capacity"
+                  onsyncfrompreference="return gAdvancedPane.readCacheSize();"
+                  onsynctopreference="return gAdvancedPane.writeCacheSize();"
+                  aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
+          <label id="useCacheAfter" flex="1">&limitCacheSizeAfter.label;</label>
+        </hbox>
+      </groupbox>
+
+      <!-- Offline apps -->
+      <groupbox id="offlineGroup">
+        <caption label="&offlineStorage2.label;"/>
+
+        <hbox align="center">
+          <label id="actualAppCacheSize" flex="1"/>
+          <button id="clearOfflineAppCacheButton" icon="clear"
+                  label="&clearOfflineAppCacheNow.label;" accesskey="&clearOfflineAppCacheNow.accesskey;"
+                  oncommand="gAdvancedPane.clearOfflineAppCache();"/>
+        </hbox>
+        <hbox align="center">
+          <checkbox id="offlineNotify" flex="1"
+                    label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;"
+                    preference="browser.offline-apps.notify"
+                    onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
+          <button id="offlineNotifyExceptions"
+                  label="&offlineNotifyExceptions.label;"
+                  accesskey="&offlineNotifyExceptions.accesskey;"
+                  oncommand="gAdvancedPane.showOfflineExceptions();"/>
+        </hbox>
+        <hbox>
+          <vbox flex="1">
+            <label id="offlineAppsListLabel">&offlineAppsList2.label;</label>
+            <listbox id="offlineAppsList"
+                    style="height: &offlineAppsList.height;;"
+                    flex="1"
+                    aria-labelledby="offlineAppsListLabel"
+                    onselect="gAdvancedPane.offlineAppSelected(event);">
+            </listbox>
+          </vbox>
+          <vbox pack="end">
+            <button id="offlineAppsListRemove"
+                    disabled="true"
+                    label="&offlineAppsListRemove.label;"
+                    accesskey="&offlineAppsListRemove.accesskey;"
+                    oncommand="gAdvancedPane.removeOfflineApp();"/>
+          </vbox>
+        </hbox>
+      </groupbox>
+    </tabpanel>
+
+    <!-- Update -->
+    <tabpanel id="updatePanel" orient="vertical">
+#ifdef MOZ_UPDATER
+      <groupbox id="updateApp">
+        <caption label="&updateApp.label;"/>
+        <radiogroup id="updateRadioGroup"
+                    oncommand="gAdvancedPane.updateWritePrefs();">
+          <radio value="auto"
+                label="&updateAuto.label;"
+                accesskey="&updateAuto.accesskey;"/>
+          <hbox class="indent">
+            <checkbox id="warnIncompatible"
+                      label="&updateAutoAddonWarn.label;"
+                      accesskey="&updateAutoAddonWarn.accesskey;"
+                      preference="app.update.mode"
+                      onsyncfrompreference="return gAdvancedPane.readAddonWarn();"
+                      onsynctopreference="return gAdvancedPane.writeAddonWarn();"/>
+          </hbox>
+          <radio value="checkOnly"
+                label="&updateCheck.label;"
+                accesskey="&updateCheck.accesskey;"/>
+          <radio value="manual"
+                label="&updateManual.label;"
+                accesskey="&updateManual.accesskey;"/>
+        </radiogroup>
+
+        <hbox>
+          <button id="showUpdateHistory"
+                  label="&updateHistory.label;"
+                  accesskey="&updateHistory.accesskey;"
+                  preference="app.update.disable_button.showUpdateHistory"
+                  oncommand="gAdvancedPane.showUpdates();"/>
+        </hbox>
+
+#ifdef MOZ_MAINTENANCE_SERVICE
+        <checkbox id="useService"
+                  label="&useService.label;"
+                  accesskey="&useService.accesskey;"
+                  preference="app.update.service.enabled"/>
+#endif
+      </groupbox>
+#endif
+      <groupbox id="updateOthers">
+        <caption label="&updateOthers.label;"/>
+        <checkbox id="enableSearchUpdate"
+                  label="&enableSearchUpdate.label;"
+                  accesskey="&enableSearchUpdate.accesskey;"
+                  preference="browser.search.update"/>
+      </groupbox>
+    </tabpanel>
+
+    <!-- Encryption -->
+    <tabpanel id="encryptionPanel" orient="vertical">
+
+      <!-- Protocols -->
+      <groupbox id="protocolsGroup">
+        <caption label="&protocols.label;"/>
+
+        <grid>
+          <columns>
+            <column flex="1"/>
+            <column flex="1"/>
+          </columns>
+          <rows>
+            <row>
+              <hbox>
+                <checkbox id="useSSL3" label="&useSSL3.label;"
+                          accesskey="&useSSL3.accesskey;"
+                          preference="security.enable_ssl3"/>
+              </hbox>
+              <hbox>
+                <checkbox id="useTLS1" label="&useTLS1.label;"
+                          accesskey="&useTLS1.accesskey;"
+                          preference="security.enable_tls"/>
+              </hbox>
+            </row>
+          </rows>
+        </grid>
+      </groupbox>
+
+      <!-- Certificates -->
+      <groupbox id="certificatesGroup">
+        <caption id="CertGroupCaption" label="&certificates.label;"/>
+
+        <description id="CertSelectionDesc" control="certSelection">&certSelection.description;</description>
+
+        <!--
+          The values on these radio buttons may look like l12y issues, but
+          they're not - this preference uses *those strings* as its values.
+          I KID YOU NOT.
+        -->
+        <radiogroup id="certSelection" orient="horizontal" preftype="string"
+                    preference="security.default_personal_cert"
+                    aria-labelledby="CertGroupCaption CertSelectionDesc">
+          <radio label="&certs.auto;" accesskey="&certs.auto.accesskey;"
+                value="Select Automatically"/>
+          <radio label="&certs.ask;" accesskey="&certs.ask.accesskey;"
+                value="Ask Every Time"/>
+        </radiogroup>
+
+        <separator/>
+
+#ifdef XP_MACOSX
+        <vbox>
+#endif
+        <hbox>
+          <button id="viewCertificatesButton"
+                  label="&viewCerts.label;" accesskey="&viewCerts.accesskey;"
+                  oncommand="gAdvancedPane.showCertificates();"
+                  preference="security.disable_button.openCertManager"/>
+          <button id="viewCRLButton"
+                  label="&viewCRLs.label;" accesskey="&viewCRLs.accesskey;"
+                  oncommand="gAdvancedPane.showCRLs();"
+                  preference="security.OCSP.disable_button.managecrl"/>
+          <button id="verificationButton"
+                  label="&verify2.label;" accesskey="&verify2.accesskey;"
+                  oncommand="gAdvancedPane.showOCSP();"/>
+#ifdef XP_MACOSX
+        </hbox>
+        <hbox>
+#endif
+          <button id="viewSecurityDevicesButton"
+                  label="&viewSecurityDevices.label;" accesskey="&viewSecurityDevices.accesskey;"
+                  oncommand="gAdvancedPane.showSecurityDevices();"
+                  preference="security.disable_button.openDeviceManager"/>
+        </hbox>
+#ifdef XP_MACOSX
+        </vbox>
+#endif
+      </groupbox>
+    </tabpanel>
+  </tabpanels>
+</tabbox>
--- a/browser/components/preferences/in-content/jar.mn
+++ b/browser/components/preferences/in-content/jar.mn
@@ -3,8 +3,10 @@ browser.jar:
    content/browser/preferences/in-content/landing.xul
 *  content/browser/preferences/in-content/preferences.xul
 *  content/browser/preferences/in-content/main.xul
    content/browser/preferences/in-content/main.js
 *  content/browser/preferences/in-content/tabs.xul
 *  content/browser/preferences/in-content/tabs.js
    content/browser/preferences/in-content/privacy.xul
    content/browser/preferences/in-content/privacy.js
+*  content/browser/preferences/in-content/advanced.xul
+*  content/browser/preferences/in-content/advanced.js
\ No newline at end of file
--- a/browser/components/preferences/in-content/preferences.js
+++ b/browser/components/preferences/in-content/preferences.js
@@ -17,16 +17,17 @@ function init_all() {
   window.history.replaceState("landing", document.title);
   window.addEventListener("popstate", onStatePopped, true);
   updateCommands();
   gMainPane.init();
 #ifdef XP_WIN
   gTabsPane.init();
 #endif
   gPrivacyPane.init();
+  gAdvancedPane.init();
   var initFinished = document.createEvent("Event");
   initFinished.initEvent("Initialized", true, true);
   document.dispatchEvent(initFinished);
 }
 
 function gotoPref(page) {
   search(page, "data-category");
   window.history.pushState(page, document.title);
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -88,12 +88,13 @@
   </hbox>
   
   <hbox class="main-content" flex="1">
     <prefpane flex="1" id="mainPrefPane">
 #include landing.xul
 #include main.xul
 #include tabs.xul
 #include privacy.xul
+#include advanced.xul
     </prefpane>
   </hbox>
   
 </page>