merge mozilla-central to mozilla-inbound. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Sat, 15 Apr 2017 20:10:39 +0200
changeset 563373 e9539186b181407d2481f7b5792cb0267ae1b7b7
parent 563372 7c9e059fe6da793ec1f20f1cf7ba1d45cb8ab4a8 (current diff)
parent 563335 ce69b6e1773e9e0d0a190ce899f34b1658e66ca4 (diff)
child 563374 616974bb80233137522000496f7e240bf2a0eb2b
push id54271
push usermaglione.k@gmail.com
push dateSun, 16 Apr 2017 16:28:54 +0000
reviewersmerge, merge
milestone55.0a1
merge mozilla-central to mozilla-inbound. r=merge a=merge
taskcluster/docker/recipes/tooltool.py
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -27,32 +27,32 @@ include $(topsrcdir)/config/config.mk
 # make sure that code itself doesn't use SSE2.
 ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
 CXXFLAGS := $(filter-out -march=% -msse -msse2 -mfpmath=sse,$(CXXFLAGS))
 CXX := $(filter-out -march=% -msse -msse2 -mfpmath=sse,$(CXX))
 CXXFLAGS += -mno-sse -mno-sse2 -mfpmath=387
 CXX += -march=pentiumpro
 endif
 
+PROGRAMS_DEST = $(DIST)/bin
+
+include $(topsrcdir)/config/rules.mk
+
 ifeq ($(OS_ARCH),WINNT)
-# Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
-# (this dependency should really be just for firefox.exe, not other targets)
+# Rebuild a .res file if the manifest changes - it's included by splash.rc.
+# (this dependency should really be just for the .res file, not other targets)
 # Note the manifest file exists in the tree, so we use the explicit filename
 # here.
 ifdef HAVE_64BIT_BUILD
-EXTRA_DEPS += firefox.exe.64.manifest
+$(RESFILE): firefox.exe.64.manifest
 else
-EXTRA_DEPS += firefox.exe.32.manifest
+$(RESFILE): firefox.exe.32.manifest
 endif
 endif
 
-PROGRAMS_DEST = $(DIST)/bin
-
-include $(topsrcdir)/config/rules.mk
-
 ifneq (,$(filter-out WINNT,$(OS_ARCH)))
 
 ifdef COMPILE_ENVIRONMENT
 libs:: 
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
 endif
 
 GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, firefox.js)
--- a/browser/app/firefox.exe.32.manifest
+++ b/browser/app/firefox.exe.32.manifest
@@ -30,16 +30,17 @@
     <ms_asmv3:requestedPrivileges>
       <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
     </ms_asmv3:requestedPrivileges>
   </ms_asmv3:security>
 </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/browser/app/firefox.exe.64.manifest
+++ b/browser/app/firefox.exe.64.manifest
@@ -24,16 +24,17 @@
     <ms_asmv3:requestedPrivileges>
       <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
     </ms_asmv3:requestedPrivileges>
   </ms_asmv3:security>
 </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/browser/base/content/browser-data-submission-info-bar.js
+++ b/browser/base/content/browser-data-submission-info-bar.js
@@ -66,17 +66,17 @@ var gDataNotificationInfoBar = {
       popup: null,
       callback: () => {
         this._actionTaken = true;
         // The advanced subpanes are only supported in the old organization, which will
         // be removed by bug 1349689.
         if (Preferences.get("browser.preferences.useOldOrganization", false)) {
           window.openAdvancedPreferences("dataChoicesTab");
         } else {
-          window.openPreferences("advanced-reports");
+          window.openPreferences("privacy-reports");
         }
       },
     }];
 
     this._log.info("Creating data reporting policy notification.");
     this._notificationBox.appendNotification(
       message,
       this._DATA_REPORTING_NOTIFICATION,
--- a/browser/base/content/browser-sidebar.js
+++ b/browser/base/content/browser-sidebar.js
@@ -218,16 +218,17 @@ var SidebarUI = {
           sidebarBroadcaster.setAttribute("checked", "true");
         }
       }
 
       this._box.hidden = false;
       this._splitter.hidden = false;
 
       this._box.setAttribute("sidebarcommand", sidebarBroadcaster.id);
+      this.lastOpenedId = sidebarBroadcaster.id;
 
       let title = sidebarBroadcaster.getAttribute("sidebartitle");
       if (!title) {
         title = sidebarBroadcaster.getAttribute("label");
       }
       this._title.value = title;
 
       let url = sidebarBroadcaster.getAttribute("sidebarurl");
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -372,16 +372,18 @@ file, You can obtain one at http://mozil
         <parameter name="openUILinkParams"/>
         <body><![CDATA[
           let isMouseEvent = event instanceof MouseEvent;
           if (isMouseEvent && event.button == 2) {
             // Do nothing for right clicks.
             return;
           }
 
+          BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(event);
+
           // Determine whether to use the selected one-off search button.  In
           // one-off search buttons parlance, "selected" means that the button
           // has been navigated to via the keyboard.  So we want to use it if
           // the triggering event is not a mouse click -- i.e., it's a Return
           // key -- or if the one-off was mouse-clicked.
           let selectedOneOff = this.popup.oneOffSearchButtons.selectedButton;
           if (selectedOneOff &&
               isMouseEvent &&
--- a/browser/components/extensions/ext-sidebarAction.js
+++ b/browser/components/extensions/ext-sidebarAction.js
@@ -96,29 +96,25 @@ this.sidebarAction = class extends Exten
     windowTracker.removeOpenListener(this.windowOpenListener);
   }
 
   build() {
     this.tabContext.on("tab-select", // eslint-disable-line mozilla/balanced-listeners
                        (evt, tab) => { this.updateWindow(tab.ownerGlobal); });
 
     let install = this.extension.startupReason === "ADDON_INSTALL";
+    let upgrade = ["ADDON_UPGRADE", "ADDON_DOWNGRADE"].includes(this.extension.startupReason);
     for (let window of windowTracker.browserWindows()) {
       this.updateWindow(window);
-      if (install) {
-        let {SidebarUI} = window;
+      let {SidebarUI} = window;
+      if (install || (upgrade && SidebarUI.lastOpenedId == this.id)) {
         SidebarUI.show(this.id);
       }
     }
 
-    // Bug 1331507: UX review/analysis of sidebar-button injection.
-    if (AppConstants.RELEASE_OR_BETA) {
-      return;
-    }
-
     if (install && !Services.prefs.prefHasUserValue("extensions.sidebar-button.shown")) {
       Services.prefs.setBoolPref("extensions.sidebar-button.shown", true);
       // If the sidebar button has never been moved to the toolbar, move it now
       // so the user can see/access the sidebars.
       let widget = CustomizableUI.getWidget("sidebar-button");
       if (!widget.areaType) {
         CustomizableUI.addWidgetToArea("sidebar-button", CustomizableUI.AREA_NAVBAR, 0);
       }
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -4,237 +4,42 @@
 
 /* import-globals-from preferences.js */
 
 // Load DownloadUtils module for convertByteUnits
 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
 Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
-
 var gAdvancedPane = {
   _inited: false,
 
-  /**
-   * Brings the appropriate tab to the front and initializes various bits of UI.
-   */
   init() {
     function setEventListener(aId, aEventType, aCallback) {
       document.getElementById(aId)
               .addEventListener(aEventType, aCallback.bind(gAdvancedPane));
     }
 
     this._inited = true;
 
     if (AppConstants.MOZ_UPDATER) {
       let onUnload = function() {
         window.removeEventListener("unload", onUnload);
         Services.prefs.removeObserver("app.update.", this);
       }.bind(this);
       window.addEventListener("unload", onUnload);
       Services.prefs.addObserver("app.update.", this);
       this.updateReadPrefs();
-    }
-    if (AppConstants.MOZ_CRASHREPORTER) {
-      this.initSubmitCrashes();
-    }
-    this.initTelemetry();
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      this.initSubmitHealthReport();
-    }
-    this.updateOnScreenKeyboardVisibility();
-
-    setEventListener("layers.acceleration.disabled", "change",
-                     gAdvancedPane.updateHardwareAcceleration);
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      setEventListener("submitHealthReportBox", "command",
-                       gAdvancedPane.updateSubmitHealthReport);
-    }
-
-    if (AppConstants.MOZ_UPDATER) {
       setEventListener("updateRadioGroup", "command",
                        gAdvancedPane.updateWritePrefs);
       setEventListener("showUpdateHistory", "command",
                        gAdvancedPane.showUpdates);
     }
   },
 
-
-  // 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
-   * ui.osk.enabled
-   * - when set to true, subject to other conditions, we may sometimes invoke
-   *   an on-screen keyboard when a text input is focused.
-   *   (Currently Windows-only, and depending on prefs, may be Windows-8-only)
-   * 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() {
-    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() {
-    var checkbox = document.getElementById("checkSpelling");
-    if (checkbox.checked) {
-      if (this._storedSpellCheck == 2) {
-        return 2;
-      }
-      return 1;
-    }
-    return 0;
-  },
-
-
-  /**
-   * When the user toggles the layers.acceleration.disabled pref,
-   * sync its new value to the gfx.direct2d.disabled pref too.
-   */
-  updateHardwareAcceleration() {
-    if (AppConstants.platform == "win") {
-      var fromPref = document.getElementById("layers.acceleration.disabled");
-      var toPref = document.getElementById("gfx.direct2d.disabled");
-      toPref.value = fromPref.value;
-    }
-  },
-
-  // DATA CHOICES TAB
-
-  /**
-   * Set up or hide the Learn More links for various data collection options
-   */
-  _setupLearnMoreLink(pref, element) {
-    // set up the Learn More link with the correct URL
-    let url = Services.prefs.getCharPref(pref);
-    let el = document.getElementById(element);
-
-    if (url) {
-      el.setAttribute("href", url);
-    } else {
-      el.setAttribute("hidden", "true");
-    }
-  },
-
-  /**
-   *
-   */
-  initSubmitCrashes() {
-    this._setupLearnMoreLink("toolkit.crashreporter.infoURL",
-                             "crashReporterLearnMore");
-  },
-
-  /**
-   * The preference/checkbox is configured in XUL.
-   *
-   * In all cases, set up the Learn More link sanely.
-   */
-  initTelemetry() {
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      this._setupLearnMoreLink("toolkit.telemetry.infoURL", "telemetryLearnMore");
-    }
-  },
-
-  /**
-   * Set the status of the telemetry controls based on the input argument.
-   * @param {Boolean} aEnabled False disables the controls, true enables them.
-   */
-  setTelemetrySectionEnabled(aEnabled) {
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      // If FHR is disabled, additional data sharing should be disabled as well.
-      let disabled = !aEnabled;
-      document.getElementById("submitTelemetryBox").disabled = disabled;
-      if (disabled) {
-        // If we disable FHR, untick the telemetry checkbox.
-        Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
-      }
-      document.getElementById("telemetryDataDesc").disabled = disabled;
-    }
-  },
-
-  /**
-   * Initialize the health report service reference and checkbox.
-   */
-  initSubmitHealthReport() {
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      this._setupLearnMoreLink("datareporting.healthreport.infoURL", "FHRLearnMore");
-
-      let checkbox = document.getElementById("submitHealthReportBox");
-
-      if (Services.prefs.prefIsLocked(PREF_UPLOAD_ENABLED)) {
-        checkbox.setAttribute("disabled", "true");
-        return;
-      }
-
-      checkbox.checked = Services.prefs.getBoolPref(PREF_UPLOAD_ENABLED);
-      this.setTelemetrySectionEnabled(checkbox.checked);
-    }
-  },
-
-  /**
-   * Update the health report preference with state from checkbox.
-   */
-  updateSubmitHealthReport() {
-    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
-      let checkbox = document.getElementById("submitHealthReportBox");
-      Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked);
-      this.setTelemetrySectionEnabled(checkbox.checked);
-    }
-  },
-
-  updateOnScreenKeyboardVisibility() {
-    if (AppConstants.platform == "win") {
-      let minVersion = Services.prefs.getBoolPref("ui.osk.require_win10") ? 10 : 6.2;
-      if (Services.vc.compare(Services.sysinfo.getProperty("version"), minVersion) >= 0) {
-        document.getElementById("useOnScreenKeyboard").hidden = false;
-      }
-    }
-  },
-
   /*
    * Preferences:
    *
    * app.update.enabled
    * - true if updates to the application are enabled, false otherwise
    * app.update.auto
    * - true if updates should be automatically downloaded and installed and
    * false if the user should be asked what he wants to do when an update is
@@ -330,31 +135,16 @@ var gAdvancedPane = {
 
   /**
    * Displays the history of installed updates.
    */
   showUpdates() {
     gSubDialog.open("chrome://mozapps/content/update/history.xul");
   },
 
-  // ENCRYPTION TAB
-
-  /*
-   * Preferences:
-   *
-   * 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
-   */
-
-
   observe(aSubject, aTopic, aData) {
     if (AppConstants.MOZ_UPDATER) {
       switch (aTopic) {
         case "nsPref:changed":
           this.updateReadPrefs();
           break;
       }
     }
--- a/browser/components/preferences/in-content/advanced.xul
+++ b/browser/components/preferences/in-content/advanced.xul
@@ -7,23 +7,16 @@
 <script type="application/javascript"
         src="chrome://browser/content/preferences/in-content/advanced.js"/>
 
 <preferences id="advancedPreferences" hidden="true" data-category="paneAdvanced">
   <preference id="browser.preferences.advanced.selectedTabIndex"
               name="browser.preferences.advanced.selectedTabIndex"
               type="int"/>
 
-<!-- Data Choices tab -->
-#ifdef MOZ_CRASHREPORTER
-  <preference id="browser.crashReports.unsubmittedCheck.autoSubmit"
-              name="browser.crashReports.unsubmittedCheck.autoSubmit"
-              type="bool"/>
-#endif
-
 <!-- 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"/>
@@ -53,97 +46,49 @@
       class="header"
       hidden="true"
       data-category="paneAdvanced">
   <label class="header-name" flex="1">&paneUpdates.title;</label>
   <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a>
 </hbox>
 
 <!-- Update -->
-#ifdef MOZ_UPDATER
-<groupbox id="updateApp" align="start" data-category="paneAdvanced" hidden="true">
+<groupbox id="updateApp" data-category="paneAdvanced" hidden="true">
   <caption><label>&updateApplication.label;</label></caption>
-  <radiogroup id="updateRadioGroup" align="start">
-    <radio id="autoDesktop"
-           value="auto"
-           label="&updateAuto1.label;"
-           accesskey="&updateAuto1.accesskey;"/>
-    <radio value="checkOnly"
-          label="&updateCheckChoose.label;"
-          accesskey="&updateCheckChoose.accesskey;"/>
-    <radio value="manual"
-          label="&updateManual.label;"
-          accesskey="&updateManual.accesskey;"/>
-  </radiogroup>
-  <separator class="thin"/>
-  <hbox>
-    <button id="showUpdateHistory"
-            label="&updateHistory.label;"
-            accesskey="&updateHistory.accesskey;"
-            preference="app.update.disable_button.showUpdateHistory"/>
-  </hbox>
-
+  <description>&updateApplication.description;</description>
+  <hbox align="start">
+    <vbox flex="1">
+#ifdef MOZ_UPDATER
+      <radiogroup id="updateRadioGroup" align="start">
+        <radio id="autoDesktop"
+               value="auto"
+               label="&updateAuto2.label;"
+               accesskey="&updateAuto2.accesskey;"/>
+        <radio value="checkOnly"
+              label="&updateCheckChoose2.label;"
+              accesskey="&updateCheckChoose2.accesskey;"/>
+        <radio value="manual"
+              label="&updateManual2.label;"
+              accesskey="&updateManual2.accesskey;"/>
+      </radiogroup>
 #ifdef MOZ_MAINTENANCE_SERVICE
-  <checkbox id="useService"
-            label="&useService.label;"
-            accesskey="&useService.accesskey;"
-            preference="app.update.service.enabled"/>
-#endif
-</groupbox>
+      <checkbox id="useService"
+                label="&useService.label;"
+                accesskey="&useService.accesskey;"
+                preference="app.update.service.enabled"/>
 #endif
-<groupbox id="updateOthers" align="start" data-category="paneAdvanced" hidden="true">
-  <caption><label>&autoUpdateOthers.label;</label></caption>
-  <checkbox id="enableSearchUpdate"
-            label="&enableSearchUpdate.label;"
-            accesskey="&enableSearchUpdate.accesskey;"
-            preference="browser.search.update"/>
-</groupbox>
-
-<!-- Data Choices -->
-#ifdef MOZ_TELEMETRY_REPORTING
-<groupbox id="historyGroup" data-category="paneAdvanced" data-subcategory="reports" hidden="true">
-<caption><label>&reports.label;</label></caption>
-  <vbox>
-    <caption>
-    <checkbox id="submitHealthReportBox" label="&enableHealthReport.label;"
-              accesskey="&enableHealthReport.accesskey;"/>
-  </caption>
-    <hbox class="indent" flex="1">
-      <label flex="1">&healthReportDesc.label;</label>
-      <label id="FHRLearnMore" flex="1"
-             class="learnMore text-link">&healthReportLearnMore.label;</label>
-    </hbox>
-    <hbox class="indent">
-      <groupbox flex="1">
-        <caption>
-          <checkbox id="submitTelemetryBox" preference="toolkit.telemetry.enabled"
-                    label="&enableTelemetryData.label;"
-                    accesskey="&enableTelemetryData.accesskey;"/>
-        </caption>
-        <hbox class="indent" flex="1">
-          <label id="telemetryDataDesc" flex="1">&telemetryDesc.label;</label>
-          <label id="telemetryLearnMore" flex="1"
-                 class="learnMore text-link">&telemetryLearnMore.label;</label>
-        </hbox>
-      </groupbox>
-    </hbox>
-  </vbox>
-</groupbox>
 #endif
-
-#ifdef MOZ_DATA_REPORTING
-#ifdef MOZ_CRASHREPORTER
-<groupbox data-category="paneAdvanced" data-subcategory="reports" hidden="true">
-  <caption>
-    <checkbox id="automaticallySubmitCrashesBox"
-              preference="browser.crashReports.unsubmittedCheck.autoSubmit"
-              label="&alwaysSubmitCrashReports.label;"
-              accesskey="&alwaysSubmitCrashReports.accesskey;"/>
-  </caption>
-  <hbox class="indent" flex="1">
-    <label flex="1">&crashReporterDesc2.label;</label>
-    <label id="crashReporterLearnMore" flex="1"
-           class="learnMore text-link">&crashReporterLearnMore.label;</label>
+      <checkbox id="enableSearchUpdate"
+                label="&enableSearchUpdate2.label;"
+                accesskey="&enableSearchUpdate2.accesskey;"
+                preference="browser.search.update"/>
+    </vbox>
+#ifdef MOZ_UPDATER
+    <spacer flex="1"/>
+    <vbox>
+      <button id="showUpdateHistory"
+              label="&updateHistory2.label;"
+              accesskey="&updateHistory2.accesskey;"
+              preference="app.update.disable_button.showUpdateHistory"/>
+    </vbox>
+#endif
   </hbox>
 </groupbox>
-
-#endif
-#endif
\ No newline at end of file
--- a/browser/components/preferences/in-content/applications.xul
+++ b/browser/components/preferences/in-content/applications.xul
@@ -58,17 +58,17 @@
   <key key="&focusSearch1.key;" modifiers="accel" id="focusSearch1" oncommand=";"/>
   <key key="&focusSearch2.key;" modifiers="accel" id="focusSearch2" oncommand=";"/>
 </keyset>
 
 <hbox id="header-applications"
       class="header"
       hidden="true"
       data-category="paneApplications">
-  <label class="header-name" flex="1">&paneDownloadLinks.title;</label>
+  <label class="header-name" flex="1">&paneFilesApplications.title;</label>
   <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a>
 </hbox>
 
 <vbox id="applicationsContent"
       data-category="paneApplications"
       hidden="true"
       flex="1">
 
@@ -104,30 +104,31 @@
       <hbox>
         <radio id="alwaysAsk"
               value="false"
               label="&alwaysAskWhere.label;"
               accesskey="&alwaysAskWhere.accesskey;"/>
       </hbox>
     </radiogroup>
   </groupbox>
-  <hbox>
+
+  <groupbox id="applicationsGroup">
+    <caption><label>&applications.label;</label></caption>
+    <description>&applications.description;</description>
     <textbox id="filter" flex="1"
              type="search"
-             placeholder="&filter.emptytext;"
+             placeholder="&filter2.emptytext;"
              aria-controls="handlersView"/>
-  </hbox>
-
-  <separator class="thin"/>
 
-  <richlistbox id="handlersView" orient="vertical" persist="lastSelectedType"
-               preference="pref.downloads.disable_button.edit_actions"
-               flex="1">
-    <listheader equalsize="always">
-        <treecol id="typeColumn" label="&typeColumn.label;" value="type"
-                 accesskey="&typeColumn.accesskey;" persist="sortDirection"
-                 flex="1" sortDirection="ascending"/>
-        <treecol id="actionColumn" label="&actionColumn2.label;" value="action"
-                 accesskey="&actionColumn2.accesskey;" persist="sortDirection"
-                 flex="1"/>
-    </listheader>
-  </richlistbox>
+    <richlistbox id="handlersView" orient="vertical" persist="lastSelectedType"
+                 preference="pref.downloads.disable_button.edit_actions"
+                 flex="1">
+      <listheader equalsize="always">
+          <treecol id="typeColumn" label="&typeColumn.label;" value="type"
+                   accesskey="&typeColumn.accesskey;" persist="sortDirection"
+                   flex="1" sortDirection="ascending"/>
+          <treecol id="actionColumn" label="&actionColumn2.label;" value="action"
+                   accesskey="&actionColumn2.accesskey;" persist="sortDirection"
+                   flex="1"/>
+      </listheader>
+    </richlistbox>
+  </groupbox>
 </vbox>
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -136,20 +136,24 @@ var gMainPane = {
     setEventListener("translateButton", "command",
       gMainPane.showTranslationExceptions);
     setEventListener("font.language.group", "change",
       gMainPane._rebuildFonts);
     setEventListener("advancedFonts", "command",
       gMainPane.configureFonts);
     setEventListener("colors", "command",
       gMainPane.configureColors);
+    setEventListener("layers.acceleration.disabled", "change",
+      gMainPane.updateHardwareAcceleration);
 
     // Initializes the fonts dropdowns displayed in this pane.
     this._rebuildFonts();
 
+    this.updateOnScreenKeyboardVisibility();
+
     // Show translation preferences if we may:
     const prefName = "browser.translation.ui.show";
     if (Services.prefs.getBoolPref(prefName)) {
       let row = document.getElementById("translationBox");
       row.removeAttribute("hidden");
       // Showing attribution only for Bing Translator.
       Components.utils.import("resource:///modules/translation/Translation.jsm");
       if (Translation.translationEngine == "bing") {
@@ -615,16 +619,43 @@ var gMainPane = {
   /**
    * Displays the colors dialog, where default web page/link/etc. colors can be
    * configured.
    */
   configureColors() {
     gSubDialog.open("chrome://browser/content/preferences/colors.xul", "resizable=no");
   },
 
+  /**
+   * ui.osk.enabled
+   * - when set to true, subject to other conditions, we may sometimes invoke
+   *   an on-screen keyboard when a text input is focused.
+   *   (Currently Windows-only, and depending on prefs, may be Windows-8-only)
+   */
+  updateOnScreenKeyboardVisibility() {
+    if (AppConstants.platform == "win") {
+      let minVersion = Services.prefs.getBoolPref("ui.osk.require_win10") ? 10 : 6.2;
+      if (Services.vc.compare(Services.sysinfo.getProperty("version"), minVersion) >= 0) {
+        document.getElementById("useOnScreenKeyboard").hidden = false;
+      }
+    }
+  },
+
+  /**
+   * When the user toggles the layers.acceleration.disabled pref,
+   * sync its new value to the gfx.direct2d.disabled pref too.
+   */
+  updateHardwareAcceleration() {
+    if (AppConstants.platform == "win") {
+      var fromPref = document.getElementById("layers.acceleration.disabled");
+      var toPref = document.getElementById("gfx.direct2d.disabled");
+      toPref.value = fromPref.value;
+    }
+  },
+
   // FONTS
 
   /**
    * Populates the default font list in UI.
    */
   _rebuildFonts() {
     var preferences = document.getElementById("mainPreferences");
     // Ensure preferences are "visible" to ensure bindings work.
@@ -697,19 +728,31 @@ var gMainPane = {
           FontBuilder.buildFontList(aLanguageGroup, prefs[i].fonttype, element);
 
         preference.setElementValue(element);
       }
     }
   },
 
   /**
+   * 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.
+   *
+   * layout.spellcheckDefault
+   * - an integer:
+   *     0  disables spellchecking
+   *     1  enables spellchecking, but only for multiline text fields
+   *     2  enables spellchecking for all text fields
    */
   readCheckSpelling() {
     var pref = document.getElementById("layout.spellcheckDefault");
     this._storedSpellCheck = pref.value;
 
     return (pref.value != 0);
   },
 
--- a/browser/components/preferences/in-content/main.xul
+++ b/browser/components/preferences/in-content/main.xul
@@ -134,32 +134,48 @@
 
   <!-- Languages -->
   <preference id="browser.translation.detectLanguage"
               name="browser.translation.detectLanguage"
               type="bool"/>
 
   <!-- General tab -->
 
-  <!-- Accessibility -->
+  <!-- Accessibility
+   * 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 -->
   <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"/>
 #ifdef XP_WIN
   <preference id="ui.osk.enabled"
               name="ui.osk.enabled"
               type="bool"/>
 #endif
-  <!-- Browsing -->
+  <!-- Browsing
+   * 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 -->
   <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"
@@ -234,18 +250,18 @@
     </deck>
     <separator class="thin"/>
   </vbox>
 #endif
 
   <html:table id="startupTable">
     <html:tr>
       <html:td class="label-cell">
-        <label accesskey="&startupPage.accesskey;"
-               control="browserStartupPage">&startupPage.label;</label>
+        <label accesskey="&startupPage2.accesskey;"
+               control="browserStartupPage">&startupPage2.label;</label>
       </html:td>
       <html:td class="content-cell">
         <menulist id="browserStartupPage"
                   class="content-cell-item"
                   preference="browser.startup.page">
           <menupopup>
           <menuitem label="&startupUserHomePage.label;"
                     value="1"
@@ -257,18 +273,18 @@
                     value="3"
                     id="browserStartupLastSession"/>
           </menupopup>
         </menulist>
       </html:td>
     </html:tr>
     <html:tr>
       <html:td class="label-cell">
-        <label accesskey="&homepage.accesskey;"
-               control="browserHomePage">&homepage.label;</label>
+        <label accesskey="&homepage2.accesskey;"
+               control="browserHomePage">&homepage2.label;</label>
       </html:td>
       <html:td class="content-cell">
         <textbox id="browserHomePage"
                  class="padded uri-element content-cell-item"
                  type="autocomplete"
                  autocompletesearch="unifiedcomplete"
                  onsyncfrompreference="return gMainPane.syncFromHomePref();"
                  onsynctopreference="return gMainPane.syncToHomePref(this.value);"
@@ -350,17 +366,17 @@
             accesskey="&removeEngine.accesskey;"
             disabled="true"
             />
   </hbox>
 
   <separator class="thin"/>
 
   <hbox id="addEnginesBox" pack="start">
-    <label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"/>
+    <label id="addEngines" class="text-link" value="&addMoreSearchEngines2.label;"/>
   </hbox>
 </groupbox>
 
 <!-- Tab preferences -->
 <groupbox data-category="paneGeneral"
           hidden="true" align="start">
     <caption><label>&tabsGroup.label;</label></caption>
 
@@ -465,19 +481,19 @@
   <grid id="fontsGrid">
     <columns>
       <column flex="1"/>
       <column/>
     </columns>
     <rows id="fontsRows">
       <row id="fontRow">
         <hbox align="center">
-          <label control="defaultFont" accesskey="&defaultFont.accesskey;">&defaultFont.label;</label>
+          <label control="defaultFont" accesskey="&defaultFont2.accesskey;">&defaultFont2.label;</label>
           <menulist id="defaultFont" delayprefsave="true" onsyncfrompreference="return FontBuilder.readFontSelection(this);"/>
-          <label id="defaultFontSizeLabel" control="defaultFontSize" accesskey="&defaultSize.accesskey;">&defaultSize.label;</label>
+          <label id="defaultFontSizeLabel" control="defaultFontSize" accesskey="&defaultSize2.accesskey;">&defaultSize2.label;</label>
           <menulist id="defaultFontSize" delayprefsave="true">
             <menupopup>
               <menuitem value="9" label="9"/>
               <menuitem value="10" label="10"/>
               <menuitem value="11" label="11"/>
               <menuitem value="12" label="12"/>
               <menuitem value="13" label="13"/>
               <menuitem value="14" label="14"/>
--- a/browser/components/preferences/in-content/preferences.xul
+++ b/browser/components/preferences/in-content/preferences.xul
@@ -113,20 +113,20 @@
         <image class="category-icon"/>
         <label class="category-name" flex="1">&paneGeneral.title;</label>
       </richlistitem>
 
       <richlistitem id="category-application"
                     class="category"
                     value="paneApplications"
                     helpTopic="prefs-applications"
-                    tooltiptext="&paneDownloadLinks.title;"
+                    tooltiptext="&paneFilesApplications.title;"
                     align="center">
         <image class="category-icon"/>
-        <label class="category-name" flex="1">&paneDownloadLinks.title;</label>
+        <label class="category-name" flex="1">&paneFilesApplications.title;</label>
       </richlistitem>
 
       <richlistitem id="category-containers"
                     class="category"
                     value="paneContainers"
                     helpTopic="prefs-containers"
                     hidden="true"/>
 
--- a/browser/components/preferences/in-content/privacy.js
+++ b/browser/components/preferences/in-content/privacy.js
@@ -13,16 +13,18 @@ XPCOMUtils.defineLazyModuleGetter(this, 
                                   "resource://gre/modules/PluralForm.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
                                   "resource://gre/modules/LoginHelper.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "SiteDataManager",
                                   "resource:///modules/SiteDataManager.jsm");
 
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
+const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
+
 XPCOMUtils.defineLazyGetter(this, "AlertsServiceDND", function() {
   try {
     let alertsService = Cc["@mozilla.org/alerts-service;1"]
                           .getService(Ci.nsIAlertsService)
                           .QueryInterface(Ci.nsIAlertsDoNotDisturb);
     // This will throw if manualDoNotDisturb isn't implemented.
     alertsService.manualDoNotDisturb;
     return alertsService;
@@ -81,16 +83,20 @@ var gPrivacyPane = {
               .getService(Components.interfaces.mozIPlacesAutoComplete);
   },
 
   /**
    * Show the Containers UI depending on the privacy.userContext.ui.enabled pref.
    */
   _initBrowserContainers() {
     if (!Services.prefs.getBoolPref("privacy.userContext.ui.enabled")) {
+      // The browserContainersGroup element has its own internal padding that
+      // is visible even if the browserContainersbox is visible, so hide the whole
+      // groupbox if the feature is disabled to prevent a gap in the preferences.
+      document.getElementById("browserContainersGroup").setAttribute("data-hidden-from-search", "true");
       return;
     }
 
     let link = document.getElementById("browserContainersLearnMore");
     link.href = Services.urlFormatter.formatURLPref("app.support.baseURL") + "containers";
 
     document.getElementById("browserContainersbox").hidden = false;
 
@@ -281,36 +287,43 @@ var gPrivacyPane = {
                        gPrivacyPane.showSiteDataSettings);
       let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "storage-permissions";
       document.getElementById("siteDataLearnMoreLink").setAttribute("href", url);
       let siteDataGroup = document.getElementById("siteDataGroup");
       siteDataGroup.hidden = false;
       siteDataGroup.removeAttribute("data-hidden-from-search");
     }
 
-
     let notificationInfoURL =
       Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
     document.getElementById("notificationsPolicyLearnMore").setAttribute("href",
                                                                          notificationInfoURL);
-
     let drmInfoURL =
       Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content";
     document.getElementById("playDRMContentLink").setAttribute("href", drmInfoURL);
     let emeUIEnabled = Services.prefs.getBoolPref("browser.eme.ui.enabled");
     // Force-disable/hide on WinXP:
     if (navigator.platform.toLowerCase().startsWith("win")) {
       emeUIEnabled = emeUIEnabled && parseFloat(Services.sysinfo.get("version")) >= 6;
     }
     if (!emeUIEnabled) {
       // Don't want to rely on .hidden for the toplevel groupbox because
       // of the pane hiding/showing code potentially interfering:
       document.getElementById("drmGroup").setAttribute("style", "display: none !important");
     }
 
+    if (AppConstants.MOZ_CRASHREPORTER) {
+      this.initSubmitCrashes();
+    }
+    this.initTelemetry();
+    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
+      this.initSubmitHealthReport();
+      setEventListener("submitHealthReportBox", "command",
+                       gPrivacyPane.updateSubmitHealthReport);
+    }
   },
 
   // TRACKING PROTECTION MODE
 
   /**
    * Selects the right item of the Tracking Protection radiogroup.
    */
   trackingProtectionReadPrefs() {
@@ -1290,16 +1303,97 @@ var gPrivacyPane = {
 
     let result = Services.prompt.confirmEx(
       window, title, text, flags, btn0Label, null, null, null, {});
     if (result == 0) {
       SiteDataManager.removeAll();
     }
   },
 
+  initSubmitCrashes() {
+    this._setupLearnMoreLink("toolkit.crashreporter.infoURL",
+                             "crashReporterLearnMore");
+  },
+
+  /**
+   * The preference/checkbox is configured in XUL.
+   *
+   * In all cases, set up the Learn More link sanely.
+   */
+  initTelemetry() {
+    if (AppConstants.MOZ_TELEMETRY_REPORTING) {
+      this._setupLearnMoreLink("toolkit.telemetry.infoURL", "telemetryLearnMore");
+    }
+  },
+
+  /**
+   * Set up or hide the Learn More links for various data collection options
+   */
+  _setupLearnMoreLink(pref, element) {
+    // set up the Learn More link with the correct URL
+    let url = Services.prefs.getCharPref(pref);
+    let el = document.getElementById(element);
+
+    if (url) {
+      el.setAttribute("href", url);
+    } else {
+      el.setAttribute("hidden", "true");
+    }
+  },
+
+  /**
+   * Set the status of the telemetry controls based on the input argument.
+   * @param {Boolean} aEnabled False disables the controls, true enables them.
+   */
+  setTelemetrySectionEnabled(aEnabled) {
+    if (!AppConstants.MOZ_TELEMETRY_REPORTING) {
+      return;
+    }
+    // If FHR is disabled, additional data sharing should be disabled as well.
+    let disabled = !aEnabled;
+    document.getElementById("submitTelemetryBox").disabled = disabled;
+    if (disabled) {
+      // If we disable FHR, untick the telemetry checkbox.
+      Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
+    }
+    document.getElementById("telemetryDataDesc").disabled = disabled;
+  },
+
+  /**
+   * Initialize the health report service reference and checkbox.
+   */
+  initSubmitHealthReport() {
+    if (!AppConstants.MOZ_TELEMETRY_REPORTING) {
+      return;
+    }
+    this._setupLearnMoreLink("datareporting.healthreport.infoURL", "FHRLearnMore");
+
+    let checkbox = document.getElementById("submitHealthReportBox");
+
+    if (Services.prefs.prefIsLocked(PREF_UPLOAD_ENABLED)) {
+      checkbox.setAttribute("disabled", "true");
+      return;
+    }
+
+    checkbox.checked = Services.prefs.getBoolPref(PREF_UPLOAD_ENABLED);
+    this.setTelemetrySectionEnabled(checkbox.checked);
+  },
+
+  /**
+   * Update the health report preference with state from checkbox.
+   */
+  updateSubmitHealthReport() {
+    if (!AppConstants.MOZ_TELEMETRY_REPORTING) {
+      return;
+    }
+    let checkbox = document.getElementById("submitHealthReportBox");
+    Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked);
+    this.setTelemetrySectionEnabled(checkbox.checked);
+  },
+
   // Methods for Offline Apps (AppCache)
 
   /**
    * Clears the application cache.
    */
   clearOfflineAppCache() {
     Components.utils.import("resource:///modules/offlineAppCache.jsm");
     OfflineAppCacheHelper.clear();
--- a/browser/components/preferences/in-content/privacy.xul
+++ b/browser/components/preferences/in-content/privacy.xul
@@ -92,17 +92,24 @@
   <!-- XXX buttons -->
   <preference id="pref.privacy.disable_button.view_passwords"
               name="pref.privacy.disable_button.view_passwords"
               type="bool"/>
   <preference id="pref.privacy.disable_button.view_passwords_exceptions"
               name="pref.privacy.disable_button.view_passwords_exceptions"
               type="bool"/>
 
-  <!-- Certificates tab -->
+  <!-- Certificates tab
+   * 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 -->
   <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"/>
 
@@ -136,29 +143,36 @@
 
   <preference id="browser.safebrowsing.downloads.remote.block_potentially_unwanted"
               name="browser.safebrowsing.downloads.remote.block_potentially_unwanted"
               type="bool"/>
   <preference id="browser.safebrowsing.downloads.remote.block_uncommon"
               name="browser.safebrowsing.downloads.remote.block_uncommon"
               type="bool"/>
 
-   <!-- Network tab -->
+  <!-- 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"/>
 
+  <!-- Data Choices tab -->
+#ifdef MOZ_CRASHREPORTER
+  <preference id="browser.crashReports.unsubmittedCheck.autoSubmit"
+              name="browser.crashReports.unsubmittedCheck.autoSubmit"
+              type="bool"/>
+#endif
+
 </preferences>
 
 <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
 
 <hbox id="header-privacy"
       class="header"
       hidden="true"
       data-category="panePrivacy">
@@ -168,17 +182,17 @@
 
 
 <!-- History -->
 <groupbox id="historyGroup" data-category="panePrivacy" hidden="true">
   <caption><label>&history.label;</label></caption>
   <hbox align="center">
     <label id="historyModeLabel"
            control="historyMode"
-           accesskey="&historyHeader.pre.accesskey;">&historyHeader.pre.label;
+           accesskey="&historyHeader2.pre.accesskey;">&historyHeader2.pre.label;
     </label>
     <menulist id="historyMode">
       <menupopup>
         <menuitem label="&historyHeader.remember.label;" value="remember"/>
         <menuitem label="&historyHeader.dontremember.label;" value="dontremember"/>
         <menuitem label="&historyHeader.custom.label;" value="custom"/>
       </menupopup>
     </menulist>
@@ -328,37 +342,43 @@
                 preference="pref.privacy.disable_button.view_passwords"/>
       </row>
     </rows>
   </grid>
 </groupbox>
 
 <!-- Tracking -->
 <groupbox id="trackingGroup" data-category="panePrivacy" hidden="true">
+  <caption><label>&trackingProtectionHeader2.label;</label></caption>
   <vbox id="trackingprotectionbox" hidden="true">
     <hbox align="start">
-      <vbox>
-        <caption><label>&trackingProtectionHeader2.label;
+      <vbox flex="1">
+        <description>
+          &trackingProtection.description;
           <label id="trackingProtectionLearnMore" class="learnMore text-link"
                  value="&trackingProtectionLearnMore.label;"/>
-        </label></caption>
-        <radiogroup id="trackingProtectionRadioGroup">
+        </description>
+        <description id="trackingProtectionDesc"
+                     control="trackingProtectionRadioGroup">
+          &trackingProtection.radioGroupLabel;
+        </description>
+        <radiogroup id="trackingProtectionRadioGroup" aria-labelledby="trackingProtectionDesc">
           <radio value="always"
                  label="&trackingProtectionAlways.label;"
                  accesskey="&trackingProtectionAlways.accesskey;"/>
           <radio value="private"
                  label="&trackingProtectionPrivate.label;"
                  accesskey="&trackingProtectionPrivate.accesskey;"/>
           <radio value="never"
                  label="&trackingProtectionNever.label;"
                  accesskey="&trackingProtectionNever.accesskey;"/>
         </radiogroup>
       </vbox>
-      <spacer flex="1" />
-      <vbox>
+      <spacer flex="1"/>
+      <vbox id="trackingProtectionAdvancedSettings">
         <button id="trackingProtectionExceptions"
                 label="&trackingProtectionExceptions.label;"
                 accesskey="&trackingProtectionExceptions.accesskey;"
                 preference="pref.privacy.disable_button.tracking_protection_exceptions"/>
         <button id="changeBlockList"
                 label="&changeBlockList.label;"
                 accesskey="&changeBlockList.accesskey;"
                 preference="pref.privacy.disable_button.change_blocklist"/>
@@ -447,28 +467,28 @@
   </grid>
 </groupbox>
 
 <!-- Location Bar -->
 <groupbox id="locationBarGroup"
           data-category="panePrivacy"
           hidden="true">
   <caption><label>&locationBar.label;</label></caption>
-  <label id="locationBarSuggestionLabel">&locbar.suggest.label;</label>
+  <label id="locationBarSuggestionLabel">&locbar.suggest2.label;</label>
   <checkbox id="historySuggestion" label="&locbar.history.label;"
             accesskey="&locbar.history.accesskey;"
             preference="browser.urlbar.suggest.history"/>
   <checkbox id="bookmarkSuggestion" label="&locbar.bookmarks.label;"
             accesskey="&locbar.bookmarks.accesskey;"
             preference="browser.urlbar.suggest.bookmark"/>
   <checkbox id="openpageSuggestion" label="&locbar.openpage.label;"
             accesskey="&locbar.openpage.accesskey;"
             preference="browser.urlbar.suggest.openpage"/>
   <label class="text-link" onclick="gotoPref('general')">
-    &suggestionSettings.label;
+    &suggestionSettings2.label;
   </label>
 </groupbox>
 
 <!-- addons, forgery (phishing) UI Security -->
 <groupbox id="addonsPhishingGroup" data-category="panePrivacy" hidden="true">
   <caption><label>&security.label;</label></caption>
 
   <hbox id="addonInstallBox">
@@ -495,55 +515,57 @@
       <checkbox id="blockUncommonUnwanted"
                 label="&blockUncommonAndUnwanted.label;"
                 accesskey="&blockUncommonAndUnwanted.accesskey;" />
     </vbox>
   </vbox>
 </groupbox>
 
 <!-- Certificates -->
-<groupbox id="certSelection" align="start" data-category="panePrivacy" hidden="true">
+<groupbox id="certSelection" data-category="panePrivacy" hidden="true">
   <caption><label>&certificateTab.label;</label></caption>
-  <description id="CertSelectionDesc" control="certSelection">&certPersonal.description;</description>
+  <description id="CertSelectionDesc" control="certSelection">&certPersonal2.description;</description>
 
   <!--
     The values on these radio buttons may look like l10n issues, but
     they're not - this preference uses *those strings* as its values.
     I KID YOU NOT.
   -->
   <radiogroup id="certSelection"
               preftype="string"
               preference="security.default_personal_cert"
               aria-labelledby="CertSelectionDesc">
     <radio label="&selectCerts.auto;"
-            accesskey="&selectCerts.auto.accesskey;"
-            value="Select Automatically"/>
+           accesskey="&selectCerts.auto.accesskey;"
+           value="Select Automatically"/>
     <radio label="&selectCerts.ask;"
-            accesskey="&selectCerts.ask.accesskey;"
-            value="Ask Every Time"/>
+           accesskey="&selectCerts.ask.accesskey;"
+           value="Ask Every Time"/>
   </radiogroup>
-  <checkbox id="enableOCSP"
-            label="&enableOCSP.label;"
-            accesskey="&enableOCSP.accesskey;"
-            onsyncfrompreference="return gPrivacyPane.readEnableOCSP();"
-            onsynctopreference="return gPrivacyPane.writeEnableOCSP();"
-            preference="security.OCSP.enabled"/>
-  <separator/>
-  <hbox>
-    <button id="viewCertificatesButton"
-            flex="1"
-            label="&viewCerts.label;"
-            accesskey="&viewCerts.accesskey;"
-            preference="security.disable_button.openCertManager"/>
-    <button id="viewSecurityDevicesButton"
-            flex="1"
-            label="&viewSecurityDevices.label;"
-            accesskey="&viewSecurityDevices.accesskey;"
-            preference="security.disable_button.openDeviceManager"/>
-    <hbox flex="10"/>
+  <hbox align="start">
+    <checkbox id="enableOCSP"
+              label="&enableOCSP.label;"
+              accesskey="&enableOCSP.accesskey;"
+              flex="1"
+              onsyncfrompreference="return gPrivacyPane.readEnableOCSP();"
+              onsynctopreference="return gPrivacyPane.writeEnableOCSP();"
+              preference="security.OCSP.enabled"/>
+    <spacer flex="1"/>
+    <vbox>
+      <button id="viewCertificatesButton"
+              flex="1"
+              label="&viewCerts.label;"
+              accesskey="&viewCerts.accesskey;"
+              preference="security.disable_button.openCertManager"/>
+      <button id="viewSecurityDevicesButton"
+              flex="1"
+              label="&viewSecurityDevices.label;"
+              accesskey="&viewSecurityDevices.accesskey;"
+              preference="security.disable_button.openDeviceManager"/>
+    </vbox>
   </hbox>
 </groupbox>
 
 <!-- DRM Content -->
 <groupbox id="drmGroup" data-category="panePrivacy" hidden="true">
   <caption><label>&drmContent.label;</label></caption>
   <grid id="contentGrid2">
     <columns>
@@ -669,8 +691,50 @@
             label="&clearSiteData.label;" accesskey="&clearSiteData.accesskey;"/>
   </hbox>
   <vbox align="end">
     <button id="siteDataSettings"
             label="&siteDataSettings.label;"
             accesskey="&siteDataSettings.accesskey;"/>
   </vbox>
 </groupbox>
+
+<!-- Data Choices -->
+#ifdef MOZ_TELEMETRY_REPORTING
+<groupbox id="historyGroup" data-category="panePrivacy" data-subcategory="reports" hidden="true">
+<caption><label>&reports.label;</label></caption>
+  <hbox align="center">
+    <checkbox id="submitHealthReportBox" label="&enableHealthReport.label;"
+              accesskey="&enableHealthReport.accesskey;"/>
+    <label id="FHRLearnMore"
+           class="learnMore text-link">&healthReportLearnMore.label;</label>
+  </hbox>
+  <description class="indent">&healthReportDesc.label;</description>
+  <vbox class="indent">
+    <hbox align="center">
+      <checkbox id="submitTelemetryBox" preference="toolkit.telemetry.enabled"
+                label="&enableTelemetryData.label;"
+                accesskey="&enableTelemetryData.accesskey;"/>
+      <label id="telemetryLearnMore"
+             class="learnMore text-link">&telemetryLearnMore.label;</label>
+    </hbox>
+    <description id="telemetryDataDesc"
+                 class="indent">&telemetryDesc.label;</description>
+  </vbox>
+</groupbox>
+#endif
+
+#ifdef MOZ_DATA_REPORTING
+#ifdef MOZ_CRASHREPORTER
+<groupbox id="crashReporterGroup" data-category="panePrivacy" data-subcategory="reports" hidden="true">
+  <hbox align="center">
+    <checkbox id="automaticallySubmitCrashesBox"
+              preference="browser.crashReports.unsubmittedCheck.autoSubmit"
+              label="&alwaysSubmitCrashReports.label;"
+              accesskey="&alwaysSubmitCrashReports.accesskey;"/>
+    <label id="crashReporterLearnMore"
+           class="learnMore text-link">&crashReporterLearnMore.label;</label>
+  </hbox>
+  <description class="indent">&crashReporterDesc2.label;</description>
+</groupbox>
+
+#endif
+#endif
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -91,17 +91,17 @@
                     onclick="gSyncPane.openChangeProfileImage(event);" hidden="true"
                     onkeypress="gSyncPane.openChangeProfileImage(event);"
                     tooltiptext="&profilePicture.tooltip;"/>
               </vbox>
               <vbox flex="1" pack="center">
                 <label id="fxaDisplayName" hidden="true"/>
                 <label id="fxaEmailAddress1"/>
                 <hbox class="fxaAccountBoxButtons">
-                  <button id="fxaUnlinkButton" label="&disconnect.label;" accesskey="&disconnect.accesskey;"/>
+                  <button id="fxaUnlinkButton" label="&disconnect2.label;" accesskey="&disconnect2.accesskey;"/>
                   <html:a id="verifiedManage" target="_blank"
                          accesskey="&verifiedManage.accesskey;"
                          onkeypress="gSyncPane.openManageFirefoxAccount(event);"><!--
                   -->&verifiedManage.label;</html:a>
                 </hbox>
               </vbox>
             </hbox>
 
@@ -144,17 +144,18 @@
                   <button id="rejectReSignIn" label="&signIn.label;" accesskey="&signIn.accesskey;"></button>
                   <button id="rejectUnlinkFxaAccount" label="&forget.label;" accesskey="&forget.accesskey;"></button>
                 </hbox>
               </vbox>
             </hbox>
           </deck>
         </groupbox>
         <groupbox id="syncOptions">
-          <caption><label>&signedIn.engines.label;</label></caption>
+          <caption><label>&signedIn.settings.label;</label></caption>
+          <description>&signedIn.settings.description;</description>
           <hbox id="fxaSyncEngines">
             <vbox align="start" flex="1">
               <checkbox label="&engine.tabs.label2;"
                         accesskey="&engine.tabs.accesskey;"
                         preference="engine.tabs"/>
               <checkbox label="&engine.bookmarks.label;"
                         accesskey="&engine.bookmarks.accesskey;"
                         preference="engine.bookmarks"/>
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -15,23 +15,25 @@ skip-if = !updater
 [browser_bug795764_cachedisabled.js]
 [browser_bug1018066_resetScrollPosition.js]
 [browser_bug1020245_openPreferences_to_paneContent.js]
 [browser_bug1184989_prevent_scrolling_when_preferences_flipped.js]
 support-files =
   browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul
 [browser_change_app_handler.js]
 skip-if = os != "win" # This test tests the windows-specific app selection dialog, so can't run on non-Windows
+[browser_checkspelling.js]
 [browser_connection.js]
 [browser_connection_bug388287.js]
 [browser_cookies_exceptions.js]
 [browser_defaultbrowser_alwayscheck.js]
 [browser_healthreport.js]
 skip-if = true || !healthreport # Bug 1185403 for the "true"
 [browser_homepages_filter_aboutpreferences.js]
+[browser_layersacceleration.js]
 [browser_notifications_do_not_disturb.js]
 [browser_permissions_urlFieldHidden.js]
 [browser_proxy_backup.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
 [browser_privacypane_4.js]
 [browser_privacypane_5.js]
 [browser_privacypane_8.js]
--- a/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js
+++ b/browser/components/preferences/in-content/tests/browser_bug1020245_openPreferences_to_paneContent.js
@@ -15,22 +15,22 @@ add_task(function*() {
   prefs = yield openPreferencesViaHash("privacy");
   is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected when hash is 'privacy'");
   prefs = yield openPreferencesViaOpenPreferencesAPI("nonexistant-category");
   is(prefs.selectedPane, "paneGeneral", "General pane is selected by default when a nonexistant-category is requested");
   prefs = yield openPreferencesViaHash("nonexistant-category");
   is(prefs.selectedPane, "paneGeneral", "General pane is selected when hash is a nonexistant-category");
   prefs = yield openPreferencesViaHash();
   is(prefs.selectedPane, "paneGeneral", "General pane is selected by default");
-  prefs = yield openPreferencesViaOpenPreferencesAPI("advanced-reports", {leaveOpen: true});
-  is(prefs.selectedPane, "paneAdvanced", "Advanced pane is selected by default");
+  prefs = yield openPreferencesViaOpenPreferencesAPI("privacy-reports", {leaveOpen: true});
+  is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected by default");
   let doc = gBrowser.contentDocument;
-  is(doc.location.hash, "#advanced", "The subcategory should be removed from the URI");
-  ok(doc.querySelector("#updateOthers").hidden, "Search Updates should be hidden when only Reports are requested");
-  ok(!doc.querySelector("#header-advanced").hidden, "The header should be visible when a subcategory is requested");
+  is(doc.location.hash, "#privacy", "The subcategory should be removed from the URI");
+  ok(doc.querySelector("#locationBarGroup").hidden, "Location Bar prefs should be hidden when only Reports are requested");
+  ok(!doc.querySelector("#header-privacy").hidden, "The header should be visible when a subcategory is requested");
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
   prefs = yield openPreferencesViaOpenPreferencesAPI("general-search", {leaveOpen: true});
   is(prefs.selectedPane, "paneGeneral", "General pane is selected by default");
   doc = gBrowser.contentDocument;
   is(doc.location.hash, "#general", "The subcategory should be removed from the URI");
   ok(doc.querySelector("#startupGroup").hidden, "Startup should be hidden when only Search is requested");
   ok(!doc.querySelector("#engineList").hidden, "The search engine list should be visible when Search is requested");
   yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_checkspelling.js
@@ -0,0 +1,24 @@
+add_task(function*() {
+  SpecialPowers.pushPrefEnv({set: [
+    ["layout.spellcheckDefault", 2]
+  ]});
+
+  let prefs = yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  is(prefs.selectedPane, "paneGeneral", "General pane was selected");
+
+  let doc = gBrowser.contentDocument;
+  let checkbox = doc.querySelector("#checkSpelling");
+  is(checkbox.checked,
+     Services.prefs.getIntPref("layout.spellcheckDefault") == 2,
+     "checkbox should represent pref value before clicking on checkbox");
+  ok(checkbox.checked, "checkbox should be checked before clicking on checkbox");
+
+  checkbox.click();
+
+  is(checkbox.checked,
+     Services.prefs.getIntPref("layout.spellcheckDefault") == 2,
+     "checkbox should represent pref value after clicking on checkbox");
+  ok(!checkbox.checked, "checkbox should not be checked after clicking on checkbox");
+
+  yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/browser_layersacceleration.js
@@ -0,0 +1,30 @@
+add_task(function*() {
+  SpecialPowers.pushPrefEnv({set: [
+    ["gfx.direct2d.disabled", false],
+    ["layers.acceleration.disabled", false]
+  ]});
+
+  let prefs = yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
+  is(prefs.selectedPane, "paneGeneral", "General pane was selected");
+
+  let doc = gBrowser.contentDocument;
+  let checkbox = doc.querySelector("#allowHWAccel");
+  is(!checkbox.checked,
+     Services.prefs.getBoolPref("layers.acceleration.disabled"),
+     "checkbox should represent inverted pref value before clicking on checkbox");
+
+  if (AppConstants.platform == "win") {
+    is(Services.prefs.getBoolPref("gfx.direct2d.disabled"), false, "direct2d pref should be set to false");
+  }
+
+  checkbox.click();
+
+  is(!checkbox.checked,
+     Services.prefs.getBoolPref("layers.acceleration.disabled"),
+     "checkbox should represent inverted pref value after clicking on checkbox");
+  if (AppConstants.platform == "win") {
+    is(Services.prefs.getBoolPref("gfx.direct2d.disabled"), true, "direct2d pref should be set to true");
+  }
+
+  yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
+});
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -67,18 +67,16 @@
         </xul:hbox>
       </xul:textbox>
     </content>
 
     <implementation implements="nsIObserver">
       <constructor><![CDATA[
         if (this.parentNode.parentNode.localName == "toolbarpaletteitem")
           return;
-        // Make sure we rebuild the popup in onpopupshowing
-        this._needToBuildPopup = true;
 
         Services.obs.addObserver(this, "browser-search-engine-modified");
 
         this._initialized = true;
 
         Services.search.init((function search_init_cb(aStatus) {
           // Bail out if the binding's been destroyed
           if (!this._initialized)
@@ -87,16 +85,24 @@
           if (Components.isSuccessCode(aStatus)) {
             // Refresh the display (updating icon, etc)
             this.updateDisplay();
             BrowserSearch.updateOpenSearchBadge();
           } else {
             Components.utils.reportError("Cannot initialize search service, bailing out: " + aStatus);
           }
         }).bind(this));
+
+        // Some accessibility tests create their own <searchbar> that doesn't
+        // use the popup binding below, so null-check oneOffButtons.
+        if (this.textbox.popup.oneOffButtons) {
+          this.textbox.popup.oneOffButtons.telemetryOrigin = "searchbar";
+          this.textbox.popup.oneOffButtons.popup = this.textbox.popup;
+          this.textbox.popup.oneOffButtons.textbox = this.textbox;
+        }
       ]]></constructor>
 
       <destructor><![CDATA[
         this.destroy();
       ]]></destructor>
 
       <method name="destroy">
         <body><![CDATA[
@@ -373,16 +379,21 @@
         <parameter name="aParams"/>
         <body><![CDATA[
           var textBox = this._textbox;
           var textValue = textBox.value;
 
           let selection = this.telemetrySearchDetails;
           let oneOffRecorded = false;
 
+          BrowserUsageTelemetry.recordSearchbarSelectedResultMethod(
+            aEvent,
+            selection ? selection.index : -1
+          );
+
           if (!selection || (selection.index == -1)) {
             oneOffRecorded = this.textbox.popup.oneOffButtons
                                  .maybeRecordTelemetry(aEvent, aWhere, aParams);
             if (!oneOffRecorded) {
               let source = "unknown";
               let type = "unknown";
               let target = aEvent.originalTarget;
               if (aEvent instanceof KeyboardEvent) {
@@ -966,16 +977,21 @@
           if (aEvent.button == 0 && !aEvent.shiftKey && !aEvent.ctrlKey &&
               !aEvent.altKey && !aEvent.metaKey) {
             controller.handleEnter(true, aEvent);
             return;
           }
 
           // Check for middle-click or modified clicks on the search bar
           if (popupForSearchBar) {
+            BrowserUsageTelemetry.recordSearchbarSelectedResultMethod(
+              aEvent,
+              this.selectedIndex
+            );
+
             // Handle search bar popup clicks
             var search = controller.getValueAt(this.selectedIndex);
 
             // open the search results according to the clicking subtlety
             var where = whereToOpenLink(aEvent, false, true);
             let params = {};
 
             // But open ctrl/cmd clicks on autocomplete items in a new background tab.
@@ -1057,36 +1073,31 @@
           let searchbar = document.getElementById("searchbar");
           searchbar.handleSearchCommandWhere(event, engine, where, params);
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="popupshowing"><![CDATA[
-        if (!this.oneOffButtons.popup) {
+        if (!this._computedMinWidth) {
           // The panel width only spans to the textbox size, but we also want it
           // to include the magnifier icon's width.
           let ltr = getComputedStyle(this).direction == "ltr";
           let magnifierWidth = parseInt(getComputedStyle(this)[
                                  ltr ? "marginLeft" : "marginRight"
                                ]) * -1;
           // Ensure the panel is wide enough to fit at least 3 engines.
           let minWidth = Math.max(
             parseInt(this.width) + magnifierWidth,
             this.oneOffButtons.buttonWidth * 3
           );
           this.style.minWidth = minWidth + "px";
 
-          // Set the origin before assigning the popup, as the assignment does
-          // a rebuild and would miss the origin.
-          this.oneOffButtons.telemetryOrigin = "searchbar";
-          // Set popup after setting the minWidth since it builds the buttons.
-          this.oneOffButtons.popup = this;
-          this.oneOffButtons.textbox = this.input;
+          this._computedMinWidth = true;
         }
 
         // First handle deciding if we are showing the reduced version of the
         // popup containing only the preferences button. We do this if the
         // glass icon has been clicked if the text field is empty.
         let searchbar = document.getElementById("searchbar");
         let tree = document.getAnonymousElementByAttribute(this, "anonid",
                                                            "tree")
--- a/browser/extensions/formautofill/FormAutofillUtils.jsm
+++ b/browser/extensions/formautofill/FormAutofillUtils.jsm
@@ -28,9 +28,47 @@ this.FormAutofillUtils = {
     if (middleName) {
       fullName += " " + middleName;
     }
     if (lastName) {
       fullName += " " + lastName;
     }
     return fullName;
   },
+
+  findLabelElements(element) {
+    let document = element.ownerDocument;
+    let labels = [];
+    // TODO: querySelectorAll is inefficient here. However, bug 1339726 is for
+    // a more efficient implementation from DOM API perspective. This function
+    // should be refined after input.labels API landed.
+    for (let label of document.querySelectorAll("label[for]")) {
+      if (element.id == label.htmlFor) {
+        labels.push(label);
+      }
+    }
+
+    if (labels.length > 0) {
+      log.debug("Label found by ID", element.id);
+      return labels;
+    }
+
+    let parent = element.parentNode;
+    if (!parent) {
+      return [];
+    }
+    do {
+      if (parent.tagName == "LABEL" &&
+          parent.control == element &&
+          !parent.hasAttribute("for")) {
+        log.debug("Label found in input's parent or ancestor.");
+        return [parent];
+      }
+      parent = parent.parentNode;
+    } while (parent);
+
+    return [];
+  },
 };
+
+this.log = null;
+this.FormAutofillUtils.defineLazyLogGetter(this, this.EXPORTED_SYMBOLS[0]);
+
new file mode 100644
--- /dev/null
+++ b/browser/extensions/formautofill/test/unit/test_findLabelElements.js
@@ -0,0 +1,90 @@
+"use strict";
+
+Cu.import("resource://formautofill/FormAutofillUtils.jsm");
+
+const TESTCASES = [
+  {
+    description: "Input contains in a label element.",
+    document: `<form>
+                 <label id="labelA"> label type A
+                   <input id="typeA" type="text">
+                 </label>
+               </form>`,
+    inputId: "typeA",
+    expectedLabelIds: ["labelA"],
+  },
+  {
+    description: "Input contains in a label element.",
+    document: `<label id="labelB"> label type B
+                 <div> inner div
+                   <input id="typeB" type="text">
+                 </div>
+               </label>`,
+    inputId: "typeB",
+    expectedLabelIds: ["labelB"],
+  },
+  {
+    description: "\"for\" attribute used to indicate input by one label.",
+    document: `<label id="labelC" for="typeC">label type C</label>
+               <input id="typeC" type="text">`,
+    inputId: "typeC",
+    expectedLabelIds: ["labelC"],
+  },
+  {
+    description: "\"for\" attribute used to indicate input by multiple labels.",
+    document: `<form>
+                 <label id="labelD1" for="typeD">label type D1</label>
+                 <label id="labelD2" for="typeD">label type D2</label>
+                 <label id="labelD3" for="typeD">label type D3</label>
+                 <input id="typeD" type="text">
+               </form>`,
+    inputId: "typeD",
+    expectedLabelIds: ["labelD1", "labelD2", "labelD3"],
+  },
+  {
+    description: "\"for\" attribute used to indicate input by multiple labels with space prefix/postfix.",
+    document: `<label id="labelE1" for="typeE">label type E1</label>
+               <label id="labelE2" for="typeE  ">label type E2</label>
+               <label id="labelE3" for="  TYPEe">label type E3</label>
+               <label id="labelE4" for="  typeE  ">label type E4</label>
+               <input id="   typeE  " type="text">`,
+    inputId: "   typeE  ",
+    expectedLabelIds: [],
+  },
+  {
+    description: "Input contains in a label element.",
+    document: `<label id="labelF"> label type F
+                 <label for="dummy"> inner label
+                   <input id="typeF" type="text">
+                   <input id="dummy" type="text">
+                 </div>
+               </label>`,
+    inputId: "typeF",
+    expectedLabelIds: ["labelF"],
+  },
+  {
+    description: "\"for\" attribute used to indicate input by labels out of the form.",
+    document: `<label id="labelG1" for="typeG">label type G1</label>
+               <form>
+                 <label id="labelG2" for="typeG">label type G2</label>
+                 <input id="typeG" type="text">
+               </form>
+               <label id="labelG3" for="typeG">label type G3</label>`,
+    inputId: "typeG",
+    expectedLabelIds: ["labelG1", "labelG2", "labelG3"],
+  },
+];
+
+TESTCASES.forEach(testcase => {
+  add_task(function* () {
+    do_print("Starting testcase: " + testcase.description);
+
+    let doc = MockDocument.createTestDocument(
+      "http://localhost:8080/test/", testcase.document);
+
+    let input = doc.getElementById(testcase.inputId);
+    let labels = FormAutofillUtils.findLabelElements(input);
+
+    Assert.deepEqual(labels.map(l => l.id), testcase.expectedLabelIds);
+  });
+});
--- a/browser/extensions/formautofill/test/unit/xpcshell.ini
+++ b/browser/extensions/formautofill/test/unit/xpcshell.ini
@@ -1,15 +1,16 @@
 [DEFAULT]
 firefox-appdir = browser
 head = head.js
 support-files =
 
 [test_autofillFormFields.js]
 [test_collectFormFields.js]
 [test_enabledStatus.js]
+[test_findLabelElements.js]
 [test_getFormInputDetails.js]
 [test_markAsAutofillField.js]
 [test_onFormSubmitted.js]
 [test_profileAutocompleteResult.js]
 [test_profileStorage.js]
 [test_savedFieldNames.js]
 
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -79,48 +79,48 @@
 <!ENTITY clearOfflineAppCacheNow.label   "Clear Now">
 <!ENTITY clearOfflineAppCacheNow.accesskey "N">
 <!ENTITY overrideSmartCacheSize.label    "Override automatic cache management">
 <!ENTITY overrideSmartCacheSize.accesskey "O">
 
 <!ENTITY updateTab.label                 "Update">
 
 <!ENTITY updateApplication.label         "&brandShortName; Updates">
-<!ENTITY updateAuto1.label               "Automatically install updates (recommended: improved security)">
-<!ENTITY updateAuto1.accesskey           "A">
-<!ENTITY updateCheckChoose.label         "Check for updates, but let you choose whether to install them">
-<!ENTITY updateCheckChoose.accesskey     "C">
-<!ENTITY updateManual.label              "Never check for updates (not recommended: security risk)">
-<!ENTITY updateManual.accesskey          "N">
+<!ENTITY updateApplication.description   "Allow &brandShortName; to">
+<!ENTITY updateAuto2.label               "Automatically install updates (recommended for improved security)">
+<!ENTITY updateAuto2.accesskey           "A">
+<!ENTITY updateCheckChoose2.label        "Check for updates but let you choose to install them">
+<!ENTITY updateCheckChoose2.accesskey    "C">
+<!ENTITY updateManual2.label             "Never check for updates (not recommended)">
+<!ENTITY updateManual2.accesskey         "N">
 
-<!ENTITY updateHistory.label             "Show Update History">
-<!ENTITY updateHistory.accesskey         "p">
+<!ENTITY updateHistory2.label            "Show Update History…">
+<!ENTITY updateHistory2.accesskey        "p">
 
 <!ENTITY useService.label                "Use a background service to install updates">
 <!ENTITY useService.accesskey            "b">
 
-<!ENTITY autoUpdateOthers.label          "Automatically Update">
-<!ENTITY enableSearchUpdate.label        "Search Engines">
-<!ENTITY enableSearchUpdate.accesskey    "E">
+<!ENTITY enableSearchUpdate2.label       "Automatically update search engines">
+<!ENTITY enableSearchUpdate2.accesskey   "e">
 
 <!ENTITY reports.label                   "Reports">
 
 <!ENTITY offlineStorageNotify.label               "Tell you when a website asks to store data for offline use">
 <!ENTITY offlineStorageNotify.accesskey           "T">
 <!ENTITY offlineStorageNotifyExceptions.label     "Exceptions…">
 <!ENTITY offlineStorageNotifyExceptions.accesskey "x">
 
 <!ENTITY offlineAppsList2.label          "The following websites are allowed to store data for offline use:">
 <!ENTITY offlineAppsList.height          "7em">
 <!ENTITY offlineAppsListRemove.label     "Remove…">
 <!ENTITY offlineAppsListRemove.accesskey "R">
 <!ENTITY offlineAppRemove.confirm        "Remove offline data">
 
 <!ENTITY certificateTab.label            "Certificates">
-<!ENTITY certPersonal.description        "When a server requests your personal certificate:">
+<!ENTITY certPersonal2.description       "When a server requests your personal certificate">
 <!ENTITY selectCerts.auto                "Select one automatically">
 <!ENTITY selectCerts.auto.accesskey      "S">
 <!ENTITY selectCerts.ask                 "Ask you every time">
 <!ENTITY selectCerts.ask.accesskey       "A">
 <!ENTITY enableOCSP.label                "Query OCSP responder servers to confirm the current validity of certificates">
 <!ENTITY enableOCSP.accesskey            "Q">
 <!ENTITY viewCerts.label                 "View Certificates">
 <!ENTITY viewCerts.accesskey             "C">
--- a/browser/locales/en-US/chrome/browser/preferences/applications.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/applications.dtd
@@ -1,14 +1,17 @@
 <!-- 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/. -->
 
+<!ENTITY  applications.label       "Applications">
+<!ENTITY  applications.description "Choose how &brandShortName; handles the files you download from the Web or the applications you use while browsing.">
+
 <!ENTITY  typeColumn.label        "Content Type">
 <!ENTITY  typeColumn.accesskey    "T">
 
 <!ENTITY  actionColumn2.label     "Action">
 <!ENTITY  actionColumn2.accesskey "A">
 
 <!ENTITY  focusSearch1.key        "f">
 <!ENTITY  focusSearch2.key        "k">
 
-<!ENTITY  filter.emptytext        "Search">
+<!ENTITY  filter2.emptytext        "Search file types or applications">
--- a/browser/locales/en-US/chrome/browser/preferences/content.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/content.dtd
@@ -16,20 +16,20 @@
 <!ENTITY  notificationsDoNotDisturb.accesskey  "n">
 <!ENTITY  notificationsDoNotDisturbDetails.value "No notification will be shown until you restart &brandShortName;">
 
 <!ENTITY  popupExceptions.label       "Exceptions…">
 <!ENTITY  popupExceptions.accesskey   "E">
 
 <!ENTITY  fontsAndColors.label        "Fonts &amp; Colors">
 
-<!ENTITY  defaultFont.label           "Default font:">
-<!ENTITY  defaultFont.accesskey       "D">
-<!ENTITY  defaultSize.label           "Size:">
-<!ENTITY  defaultSize.accesskey       "S">
+<!ENTITY  defaultFont2.label          "Default font">
+<!ENTITY  defaultFont2.accesskey      "D">
+<!ENTITY  defaultSize2.label          "Size">
+<!ENTITY  defaultSize2.accesskey      "S">
 
 <!ENTITY  advancedFonts.label         "Advanced…">
 <!ENTITY  advancedFonts.accesskey     "A">
 
 <!ENTITY  colors.label                "Colors…">
 <!ENTITY  colors.accesskey            "C">
 
 
--- a/browser/locales/en-US/chrome/browser/preferences/main.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/main.dtd
@@ -1,22 +1,22 @@
 <!-- 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/. -->
 
 <!ENTITY startup.label             "Startup">
 
-<!ENTITY startupPage.label         "When &brandShortName; starts:">
-<!ENTITY startupPage.accesskey     "s">
+<!ENTITY startupPage2.label        "When &brandShortName; starts">
+<!ENTITY startupPage2.accesskey    "s">
 <!ENTITY startupUserHomePage.label "Show your home page">
 <!ENTITY startupBlankPage.label    "Show a blank page">
 <!ENTITY startupPrevSession.label  "Show your windows and tabs from last time">
 
-<!ENTITY homepage.label            "Home Page:">
-<!ENTITY homepage.accesskey        "P">
+<!ENTITY homepage2.label           "Home Page">
+<!ENTITY homepage2.accesskey       "P">
 <!ENTITY useCurrentPage.label      "Use Current Page">
 <!ENTITY useCurrentPage.accesskey  "C">
 <!ENTITY useMultiple.label         "Use Current Pages">
 <!ENTITY chooseBookmark.label      "Use Bookmark…">
 <!ENTITY chooseBookmark.accesskey  "B">
 <!ENTITY restoreDefault.label      "Restore to Default">
 <!ENTITY restoreDefault.accesskey  "R">
 
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.dtd
@@ -10,17 +10,17 @@
 <!-- When making changes to prefWindow.styleWin test both Windows Classic and
      Luna since widget heights are different based on the OS theme -->
 <!ENTITY  prefWinMinSize.styleWin2      "width: 42em; min-height: 37.5em;">
 <!ENTITY  prefWinMinSize.styleMac       "width: 47em; min-height: 40em;">
 <!ENTITY  prefWinMinSize.styleGNOME     "width: 45.5em; min-height: 40.5em;">
 
 <!ENTITY  paneSearchResults.title       "Search Results">
 <!ENTITY  paneGeneral.title             "General">
-<!ENTITY  paneDownloadLinks.title       "Downloads &amp; Links">
+<!ENTITY  paneFilesApplications.title   "Files &amp; Applications">
 <!ENTITY  panePrivacySecurity.title     "Privacy &amp; Security">
 <!ENTITY  paneContainers.title          "Container Tabs">
 <!ENTITY  paneUpdates.title             "Updates">
 
 <!-- LOCALIZATION NOTE (paneSync1.title): This should match syncBrand.fxAccount.label in ../syncBrand.dtd -->
 <!ENTITY  paneSync1.title          "Firefox Account">
 
 <!ENTITY  helpButton.label        "Help">
--- a/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
@@ -1,13 +1,15 @@
 <!-- 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/. -->
 
 <!ENTITY  trackingProtectionHeader2.label      "Tracking Protection">
+<!ENTITY  trackingProtection.description       "Tracking is when companies collect information about you to build a profile and display content based on your browsing and personal data.">
+<!ENTITY  trackingProtection.radioGroupLabel   "Block known tracking companies from displaying content">
 <!ENTITY  trackingProtectionAlways.label       "Always">
 <!ENTITY  trackingProtectionAlways.accesskey   "y">
 <!ENTITY  trackingProtectionPrivate.label      "Only in private windows">
 <!ENTITY  trackingProtectionPrivate.accesskey  "l">
 <!ENTITY  trackingProtectionNever.label        "Never">
 <!ENTITY  trackingProtectionNever.accesskey    "n">
 <!ENTITY  trackingProtectionLearnMore.label    "Learn more">
 <!ENTITY  trackingProtectionExceptions.label   "Exceptions…">
@@ -25,28 +27,27 @@
 <!ENTITY  doNotTrack.pre.label          "You can also ">
 <!ENTITY  doNotTrack.settings.label     "manage your Do Not Track settings">
 <!ENTITY  doNotTrack.post.label         ".">
 
 <!ENTITY  history.label                 "History">
 
 <!ENTITY  locationBar.label             "Location Bar">
 
-<!ENTITY  locbar.suggest.label          "When using the location bar, suggest:">
+<!ENTITY  locbar.suggest2.label         "When using the location bar, suggest">
 <!ENTITY  locbar.history.label          "History">
 <!ENTITY  locbar.history.accesskey      "H">
 <!ENTITY  locbar.bookmarks.label        "Bookmarks">
 <!ENTITY  locbar.bookmarks.accesskey    "k">
 <!ENTITY  locbar.openpage.label         "Open tabs">
 <!ENTITY  locbar.openpage.accesskey     "O">
 <!ENTITY  locbar.searches.label         "Related searches from the default search engine">
 <!ENTITY  locbar.searches.accesskey     "d">
 
-<!ENTITY  suggestionSettings.label      "Change preferences for search engine suggestions…">
-<!ENTITY  suggestionSettings.accesskey  "g">
+<!ENTITY  suggestionSettings2.label     "Change preferences for search engine suggestions">
 
 <!ENTITY  acceptCookies.label           "Accept cookies from sites">
 <!ENTITY  acceptCookies.accesskey       "A">
 
 <!ENTITY  acceptThirdParty.pre.label      "Accept third-party cookies:">
 <!ENTITY  acceptThirdParty.pre.accesskey  "y">
 <!ENTITY  acceptThirdParty.always.label   "Always">
 <!ENTITY  acceptThirdParty.never.label    "Never">
@@ -59,18 +60,18 @@
 <!ENTITY  close.label                   "I close &brandShortName;">
 
 <!ENTITY  cookieExceptions.label        "Exceptions…">
 <!ENTITY  cookieExceptions.accesskey    "E">
 
 <!ENTITY  showCookies.label             "Show Cookies…">
 <!ENTITY  showCookies.accesskey         "S">
 
-<!ENTITY  historyHeader.pre.label          "&brandShortName; will:">
-<!ENTITY  historyHeader.pre.accesskey      "w">
+<!ENTITY  historyHeader2.pre.label         "&brandShortName; will">
+<!ENTITY  historyHeader2.pre.accesskey     "w">
 <!ENTITY  historyHeader.remember.label     "Remember history">
 <!ENTITY  historyHeader.dontremember.label "Never remember history">
 <!ENTITY  historyHeader.custom.label       "Use custom settings for history">
 <!ENTITY  historyHeader.post.label         "">
 
 <!ENTITY  rememberDescription.label      "&brandShortName; will remember your browsing, download, form and search history, and keep cookies from websites you visit.">
 
 <!-- LOCALIZATION NOTE (rememberActions.pre.label): include a trailing space as needed -->
--- a/browser/locales/en-US/chrome/browser/preferences/search.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/search.dtd
@@ -8,22 +8,22 @@
 
 <!ENTITY provideSearchSuggestions.label        "Provide search suggestions">
 <!ENTITY provideSearchSuggestions.accesskey    "s">
 
 <!ENTITY showURLBarSuggestions.label           "Show search suggestions in location bar results">
 <!ENTITY showURLBarSuggestions.accesskey       "l">
 <!ENTITY urlBarSuggestionsPermanentPB.label    "Search suggestions will not be shown in location bar results because you have configured &brandShortName; to never remember history.">
 
-<!ENTITY oneClickSearchEngines.label           "One-click Search Engines">
+<!ENTITY oneClickSearchEngines.label           "One-Click Search Engines">
 
 <!ENTITY chooseWhichOneToDisplay.label         "The search bar lets you search alternate engines directly. Choose which ones to display.">
 
 <!ENTITY engineNameColumn.label                "Search Engine">
 <!ENTITY engineKeywordColumn.label             "Keyword">
 
 <!ENTITY restoreDefaultSearchEngines.label     "Restore Default Search Engines">
 <!ENTITY restoreDefaultSearchEngines.accesskey "d">
 
 <!ENTITY removeEngine.label                    "Remove">
 <!ENTITY removeEngine.accesskey                "r">
 
-<!ENTITY addMoreSearchEngines.label            "Add more search engines…">
+<!ENTITY addMoreSearchEngines2.label           "Add more search engines">
--- a/browser/locales/en-US/chrome/browser/preferences/sync.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/sync.dtd
@@ -47,32 +47,33 @@ both, to better adapt this sentence to t
 <!ENTITY signedInLoginFailure.aftername.label "">
 
 <!ENTITY notSignedIn.label           "You are not signed in.">
 <!ENTITY signIn.label                "Sign in">
 <!ENTITY signIn.accesskey            "g">
 <!ENTITY profilePicture.tooltip      "Change profile picture">
 <!ENTITY verifiedManage.label        "Manage Account">
 <!ENTITY verifiedManage.accesskey    "o">
-<!ENTITY disconnect.label            "Disconnect…">
-<!ENTITY disconnect.accesskey        "D">
+<!ENTITY disconnect2.label           "Disconnect">
+<!ENTITY disconnect2.accesskey       "D">
 <!ENTITY verify.label                "Verify Email">
 <!ENTITY verify.accesskey            "V">
 <!ENTITY forget.label                "Forget this Email">
 <!ENTITY forget.accesskey            "F">
 
 <!ENTITY signedOut.caption            "Take Your Web With You">
 <!ENTITY signedOut.description        "Synchronize your bookmarks, history, tabs, passwords, add-ons, and preferences across all your devices.">
 <!ENTITY signedOut.accountBox.title   "Connect with a &syncBrand.fxAccount.label;">
 <!ENTITY signedOut.accountBox.create  "Create Account">
 <!ENTITY signedOut.accountBox.create.accesskey  "C">
 <!ENTITY signedOut.accountBox.signin  "Sign In">
 <!ENTITY signedOut.accountBox.signin.accesskey  "I">
 
-<!ENTITY signedIn.engines.label       "Sync Across All Devices">
+<!ENTITY signedIn.settings.label       "Sync Settings">
+<!ENTITY signedIn.settings.description "Choose what to synchronize on your devices using &brandShortName;.">
 
 <!-- LOCALIZATION NOTE (mobilePromo3.*): the following strings will be used to
      create a single sentence with active links.
      The resulting sentence in English is: "Download Firefox for
      Android or iOS to sync with your mobile device." -->
 
 <!ENTITY mobilePromo3.start            "Download Firefox for ">
 <!-- LOCALIZATION NOTE (mobilePromo3.androidLink): This is a link title that links to https://www.mozilla.org/firefox/android/ -->
--- a/browser/modules/BrowserUsageTelemetry.jsm
+++ b/browser/modules/BrowserUsageTelemetry.jsm
@@ -1,16 +1,20 @@
 /* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
 /* 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/. */
 
 "use strict";
 
-this.EXPORTED_SYMBOLS = ["BrowserUsageTelemetry", "URLBAR_SELECTED_RESULT_TYPES"];
+this.EXPORTED_SYMBOLS = [
+  "BrowserUsageTelemetry",
+  "URLBAR_SELECTED_RESULT_TYPES",
+  "URLBAR_SELECTED_RESULT_METHODS",
+ ];
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
                                   "resource://gre/modules/PrivateBrowsingUtils.jsm");
@@ -63,16 +67,29 @@ const URLBAR_SELECTED_RESULT_TYPES = {
   switchtab: 6,
   tag: 7,
   visiturl: 8,
   remotetab: 9,
   extension: 10,
   "preloaded-top-site": 11,
 };
 
+/**
+ * This maps the categories used by the FX_URLBAR_SELECTED_RESULT_METHOD and
+ * FX_SEARCHBAR_SELECTED_RESULT_METHOD histograms to their indexes in the
+ * `labels` array.  This only needs to be used by tests that need to map from
+ * category names to indexes in histogram snapshots.  Actual app code can use
+ * these category names directly when they add to a histogram.
+ */
+const URLBAR_SELECTED_RESULT_METHODS = {
+  enter: 0,
+  enterSelection: 1,
+  click: 2,
+};
+
 function getOpenTabsAndWinsCounts() {
   let tabCount = 0;
   let winCount = 0;
 
   let browserEnum = Services.wm.getEnumerator("navigator:browser");
   while (browserEnum.hasMoreElements()) {
     let win = browserEnum.getNext();
     winCount++;
@@ -203,16 +220,20 @@ let URICountListener = {
     this._domainSet.clear();
   },
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
                                          Ci.nsISupportsWeakReference]),
 };
 
 let urlbarListener = {
+
+  // This is needed for recordUrlbarSelectedResultMethod().
+  selectedIndex: -1,
+
   init() {
     Services.obs.addObserver(this, AUTOCOMPLETE_ENTER_TEXT_TOPIC, true);
   },
 
   uninit() {
     Services.obs.removeObserver(this, AUTOCOMPLETE_ENTER_TEXT_TOPIC);
   },
 
@@ -226,22 +247,32 @@ let urlbarListener = {
 
   /**
    * Used to log telemetry when the user enters text in the urlbar.
    *
    * @param {nsIAutoCompleteInput} input  The autocomplete element where the
    *                                      text was entered.
    */
   _handleURLBarTelemetry(input) {
-    if (!input ||
-        input.id != "urlbar" ||
-        input.inPrivateContext ||
-        input.popup.selectedIndex < 0) {
+    if (!input || input.id != "urlbar") {
+      return;
+    }
+    if (input.inPrivateContext || input.popup.selectedIndex < 0) {
+      this.selectedIndex = -1;
       return;
     }
+
+    // Except for the history popup, the urlbar always has a selection.  The
+    // first result at index 0 is the "heuristic" result that indicates what
+    // will happen when you press the Enter key.  Treat it as no selection.
+    this.selectedIndex =
+      input.popup.selectedIndex > 0 || !input.popup._isFirstResultHeuristic ?
+      input.popup.selectedIndex :
+      -1;
+
     let controller =
       input.popup.view.QueryInterface(Ci.nsIAutoCompleteController);
     let idx = input.popup.selectedIndex;
     let value = controller.getValueAt(idx);
     let action = input._parseActionUrl(value);
     let actionType;
     if (action) {
       actionType =
@@ -459,16 +490,67 @@ let BrowserUsageTelemetry = {
       return;
     }
 
     // The search signal was generated by typing something and pressing enter.
     this._recordSearch(engine, sourceName, "enter");
   },
 
   /**
+   * Records the method by which the user selected a urlbar result.
+   *
+   * @param {nsIDOMEvent} event
+   *        The event that triggered the selection.
+   */
+  recordUrlbarSelectedResultMethod(event) {
+    // The reason this method relies on urlbarListener instead of having the
+    // caller pass in an index is that by the time the urlbar handles a
+    // selection, the selection in its popup has been cleared, so it's not easy
+    // to tell which popup index was selected.  Fortunately this file already
+    // has urlbarListener, which gets notified of selections in the urlbar
+    // before the popup selection is cleared, so just use that.
+    this._recordUrlOrSearchbarSelectedResultMethod(
+      event, urlbarListener.selectedIndex,
+      "FX_URLBAR_SELECTED_RESULT_METHOD"
+    );
+  },
+
+  /**
+   * Records the method by which the user selected a searchbar result.
+   *
+   * @param {nsIDOMEvent} event
+   *        The event that triggered the selection.
+   * @param {number} highlightedIndex
+   *        The index that the user chose in the popup, or -1 if there wasn't a
+   *        selection.
+   */
+  recordSearchbarSelectedResultMethod(event, highlightedIndex) {
+    this._recordUrlOrSearchbarSelectedResultMethod(
+      event, highlightedIndex,
+      "FX_SEARCHBAR_SELECTED_RESULT_METHOD"
+    );
+  },
+
+  _recordUrlOrSearchbarSelectedResultMethod(event, highlightedIndex, histogramID) {
+    let histogram = Services.telemetry.getHistogramById(histogramID);
+    // command events are from the one-off context menu.  Treat them as clicks.
+    let isClick = event instanceof Ci.nsIDOMMouseEvent ||
+                  (event && event.type == "command");
+    let category;
+    if (isClick) {
+      category = "click";
+    } else if (highlightedIndex >= 0) {
+      category = "enterSelection";
+    } else {
+      category = "enter";
+    }
+    histogram.add(category);
+  },
+
+  /**
    * This gets called shortly after the SessionStore has finished restoring
    * windows and tabs. It counts the open tabs and adds listeners to all the
    * windows.
    */
   _setupAfterRestore() {
     // Make sure to catch new chrome windows and subsession splits.
     Services.obs.addObserver(this, DOMWINDOW_OPENED_TOPIC);
     Services.obs.addObserver(this, TELEMETRY_SUBSESSIONSPLIT_TOPIC);
--- a/browser/modules/test/browser/browser_UsageTelemetry_searchbar.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_searchbar.js
@@ -1,12 +1,27 @@
 "use strict";
 
 const SCALAR_SEARCHBAR = "browser.engagement.navigation.searchbar";
 
+XPCOMUtils.defineLazyModuleGetter(this, "URLBAR_SELECTED_RESULT_METHODS",
+                                  "resource:///modules/BrowserUsageTelemetry.jsm");
+
+function checkHistogramResults(resultIndexes, expected, histogram) {
+  for (let i = 0; i < resultIndexes.counts.length; i++) {
+    if (i == expected) {
+      Assert.equal(resultIndexes.counts[i], 1,
+        `expected counts should match for ${histogram} index ${i}`);
+    } else {
+      Assert.equal(resultIndexes.counts[i], 0,
+        `unexpected counts should be zero for ${histogram} index ${i}`);
+    }
+  }
+}
+
 let searchInSearchbar = Task.async(function* (inputText) {
   let win = window;
   yield new Promise(r => waitForFocus(r, win));
   let sb = BrowserSearch.searchBar;
   // Write the search query in the searchbar.
   sb.focus();
   sb.value = inputText;
   sb.textbox.controller.startSearch(inputText);
@@ -62,35 +77,42 @@ add_task(function* setup() {
   let engineDefault = Services.search.getEngineByName("MozSearch");
   let originalEngine = Services.search.currentEngine;
   Services.search.currentEngine = engineDefault;
 
   // Move the second engine at the beginning of the one-off list.
   let engineOneOff = Services.search.getEngineByName("MozSearch2");
   Services.search.moveEngine(engineOneOff, 0);
 
+  // Enable local telemetry recording for the duration of the tests.
+  let oldCanRecord = Services.telemetry.canRecordExtended;
+  Services.telemetry.canRecordExtended = true;
+
   // Enable Extended Telemetry.
   yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]});
 
   // Enable event recording for the events tested here.
   Services.telemetry.setEventRecordingEnabled("navigation", true);
 
   // Make sure to restore the engine once we're done.
   registerCleanupFunction(function* () {
+    Services.telemetry.canRecordExtended = oldCanRecord;
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engineDefault);
     Services.search.removeEngine(engineOneOff);
     Services.telemetry.setEventRecordingEnabled("navigation", false);
   });
 });
 
 add_task(function* test_plainQuery() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Simulate entering a simple search.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInSearchbar("simple query");
   EventUtils.sendKey("return");
@@ -105,23 +127,33 @@ add_task(function* test_plainQuery() {
   // Make sure SEARCH_COUNTS contains identical values.
   checkKeyedHistogram(search_hist, "other-MozSearch.searchbar", 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "searchbar", "enter", {engine: "other-MozSearch"}]]);
 
+  // Check the histograms as well.
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enter,
+    "FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
-add_task(function* test_oneOff() {
+// Performs a search using the first result, a one-off button, and the Return
+// (Enter) key.
+add_task(function* test_oneOff_enter() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Perform a one-off search using the first engine.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInSearchbar("query");
 
@@ -139,23 +171,102 @@ add_task(function* test_oneOff() {
   // Make sure SEARCH_COUNTS contains identical values.
   checkKeyedHistogram(search_hist, "other-MozSearch2.searchbar", 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "searchbar", "oneoff", {engine: "other-MozSearch2"}]]);
 
+  // Check the histograms as well.
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enter,
+    "FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
-add_task(function* test_suggestion() {
+// Performs a search using the second result, a one-off button, and the Return
+// (Enter) key.  This only tests the FX_SEARCHBAR_SELECTED_RESULT_METHOD
+// histogram since test_oneOff_enter covers everything else.
+add_task(function* test_oneOff_enterSelection() {
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
+
+  // Create an engine to generate search suggestions and add it as default
+  // for this test.
+  const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
+  let suggestionEngine = yield new Promise((resolve, reject) => {
+    Services.search.addEngine(url, null, "", false, {
+      onSuccess(engine) { resolve(engine) },
+      onError() { reject() }
+    });
+  });
+
+  let previousEngine = Services.search.currentEngine;
+  Services.search.currentEngine = suggestionEngine;
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
+
+  info("Type a query. Suggestions should be generated by the test engine.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield searchInSearchbar("query");
+
+  info("Select the second result, press Alt+Down to take us to the first one-off engine.");
+  EventUtils.synthesizeKey("VK_DOWN", {});
+  EventUtils.synthesizeKey("VK_DOWN", { altKey: true });
+  EventUtils.sendKey("return");
+  yield p;
+
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enterSelection,
+    "FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+
+  Services.search.currentEngine = previousEngine;
+  Services.search.removeEngine(suggestionEngine);
+  yield BrowserTestUtils.removeTab(tab);
+});
+
+// Performs a search using a click on a one-off button.  This only tests the
+// FX_SEARCHBAR_SELECTED_RESULT_METHOD histogram since test_oneOff_enter covers
+// everything else.
+add_task(function* test_oneOff_click() {
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
+
+  info("Type a query.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield searchInSearchbar("query");
+  info("Click the first one-off button.");
+  BrowserSearch.searchBar.textbox.popup.oneOffButtons.getSelectableButtons(false)[0].click();
+  yield p;
+
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.click,
+    "FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+
+  yield BrowserTestUtils.removeTab(tab);
+});
+
+// Clicks the first suggestion offered by the test search engine.
+add_task(function* test_suggestion_click() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
   let search_hist = getSearchCountsHistogram();
 
   // Create an engine to generate search suggestions and add it as default
   // for this test.
   const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
   let suggestionEngine = yield new Promise((resolve, reject) => {
     Services.search.addEngine(url, null, "", false, {
       onSuccess(engine) { resolve(engine) },
@@ -185,12 +296,61 @@ add_task(function* test_suggestion() {
   let searchEngineId = "other-" + suggestionEngine.name;
   checkKeyedHistogram(search_hist, searchEngineId + ".searchbar", 1);
 
   // Also check events.
   let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false);
   events = (events.default || []).filter(e => e[1] == "navigation" && e[2] == "search");
   checkEvents(events, [["navigation", "search", "searchbar", "suggestion", {engine: searchEngineId}]]);
 
+  // Check the histograms as well.
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.click,
+    "FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+
   Services.search.currentEngine = previousEngine;
   Services.search.removeEngine(suggestionEngine);
   yield BrowserTestUtils.removeTab(tab);
 });
+
+// Selects and presses the Return (Enter) key on the first suggestion offered by
+// the test search engine.  This only tests the
+// FX_SEARCHBAR_SELECTED_RESULT_METHOD histogram since test_suggestion_click
+// covers everything else.
+add_task(function* test_suggestion_enterSelection() {
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
+
+  // Create an engine to generate search suggestions and add it as default
+  // for this test.
+  const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
+  let suggestionEngine = yield new Promise((resolve, reject) => {
+    Services.search.addEngine(url, null, "", false, {
+      onSuccess(engine) { resolve(engine) },
+      onError() { reject() }
+    });
+  });
+
+  let previousEngine = Services.search.currentEngine;
+  Services.search.currentEngine = suggestionEngine;
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
+
+  info("Type a query. Suggestions should be generated by the test engine.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield searchInSearchbar("query");
+  info("Select the second result and press Return.");
+  EventUtils.synthesizeKey("VK_DOWN", {});
+  EventUtils.sendKey("return");
+  yield p;
+
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enterSelection,
+    "FX_SEARCHBAR_SELECTED_RESULT_METHOD");
+
+  Services.search.currentEngine = previousEngine;
+  Services.search.removeEngine(suggestionEngine);
+  yield BrowserTestUtils.removeTab(tab);
+});
--- a/browser/modules/test/browser/browser_UsageTelemetry_urlbar.js
+++ b/browser/modules/test/browser/browser_UsageTelemetry_urlbar.js
@@ -6,16 +6,19 @@ const SCALAR_URLBAR = "browser.engagemen
 const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches";
 // The name of the search engine used to generate suggestions.
 const SUGGESTION_ENGINE_NAME = "browser_UsageTelemetry usageTelemetrySearchSuggestions.xml";
 const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches";
 
 XPCOMUtils.defineLazyModuleGetter(this, "URLBAR_SELECTED_RESULT_TYPES",
                                   "resource:///modules/BrowserUsageTelemetry.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "URLBAR_SELECTED_RESULT_METHODS",
+                                  "resource:///modules/BrowserUsageTelemetry.jsm");
+
 function checkHistogramResults(resultIndexes, expected, histogram) {
   for (let i = 0; i < resultIndexes.counts.length; i++) {
     if (i == expected) {
       Assert.equal(resultIndexes.counts[i], 1,
         `expected counts should match for ${histogram} index ${i}`);
     } else {
       Assert.equal(resultIndexes.counts[i], 0,
         `unexpected counts should be zero for ${histogram} index ${i}`);
@@ -79,16 +82,20 @@ add_task(function* setup() {
 
   // Enable local telemetry recording for the duration of the tests.
   let oldCanRecord = Services.telemetry.canRecordExtended;
   Services.telemetry.canRecordExtended = true;
 
   // Enable event recording for the events tested here.
   Services.telemetry.setEventRecordingEnabled("navigation", true);
 
+  // Clear history so that history added by previous tests doesn't mess up this
+  // test when it selects results in the urlbar.
+  yield PlacesTestUtils.clearHistory();
+
   // Make sure to restore the engine once we're done.
   registerCleanupFunction(function* () {
     Services.telemetry.canRecordExtended = oldCanRecord;
     Services.search.currentEngine = originalEngine;
     Services.search.removeEngine(engine);
     Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF);
     Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF);
     yield PlacesTestUtils.clearHistory();
@@ -97,20 +104,22 @@ add_task(function* setup() {
 });
 
 add_task(function* test_simpleQuery() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
   let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
   let resultIndexByTypeHist = Services.telemetry.getKeyedHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
   resultIndexByTypeHist.clear();
   resultIndexHist.clear();
   resultTypeHist.clear();
+  resultMethodHist.clear();
 
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Simulate entering a simple search.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("simple query");
@@ -140,29 +149,36 @@ add_task(function* test_simpleQuery() {
     URLBAR_SELECTED_RESULT_TYPES.searchengine,
     "FX_URLBAR_SELECTED_RESULT_TYPE");
 
   let resultIndexByType = resultIndexByTypeHist.snapshot("searchengine");
   checkHistogramResults(resultIndexByType,
     0,
     "FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
 
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enter,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
 add_task(function* test_searchAlias() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
   let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
   let resultIndexByTypeHist = Services.telemetry.getKeyedHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
   resultIndexByTypeHist.clear();
   resultIndexHist.clear();
   resultTypeHist.clear();
+  resultMethodHist.clear();
 
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Search using a search alias.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("mozalias query");
@@ -192,29 +208,38 @@ add_task(function* test_searchAlias() {
     URLBAR_SELECTED_RESULT_TYPES.searchengine,
     "FX_URLBAR_SELECTED_RESULT_TYPE");
 
   let resultIndexByType = resultIndexByTypeHist.snapshot("searchengine");
   checkHistogramResults(resultIndexByType,
     0,
     "FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
 
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enter,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
-add_task(function* test_oneOff() {
+// Performs a search using the first result, a one-off button, and the Return
+// (Enter) key.
+add_task(function* test_oneOff_enter() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
   let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
   let resultIndexByTypeHist = Services.telemetry.getKeyedHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
   resultIndexByTypeHist.clear();
   resultIndexHist.clear();
   resultTypeHist.clear();
+  resultMethodHist.clear();
 
   let search_hist = getSearchCountsHistogram();
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
   info("Perform a one-off search using the first engine.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("query");
@@ -247,29 +272,109 @@ add_task(function* test_oneOff() {
     URLBAR_SELECTED_RESULT_TYPES.searchengine,
     "FX_URLBAR_SELECTED_RESULT_TYPE");
 
   let resultIndexByType = resultIndexByTypeHist.snapshot("searchengine");
   checkHistogramResults(resultIndexByType,
     0,
     "FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
 
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enter,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
   yield BrowserTestUtils.removeTab(tab);
 });
 
-add_task(function* test_suggestion() {
+// Performs a search using the second result, a one-off button, and the Return
+// (Enter) key.  This only tests the FX_URLBAR_SELECTED_RESULT_METHOD histogram
+// since test_oneOff_enter covers everything else.
+add_task(function* test_oneOff_enterSelection() {
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
+
+  // Create an engine to generate search suggestions and add it as default
+  // for this test.
+  const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
+  let suggestionEngine = yield new Promise((resolve, reject) => {
+    Services.search.addEngine(url, null, "", false, {
+      onSuccess(engine) { resolve(engine) },
+      onError() { reject() }
+    });
+  });
+
+  let previousEngine = Services.search.currentEngine;
+  Services.search.currentEngine = suggestionEngine;
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
+
+  info("Type a query. Suggestions should be generated by the test engine.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield searchInAwesomebar("query");
+
+  info("Select the second result, press Alt+Down to take us to the first one-off engine.");
+  EventUtils.synthesizeKey("VK_DOWN", {});
+  EventUtils.synthesizeKey("VK_DOWN", { altKey: true });
+  EventUtils.sendKey("return");
+  yield p;
+
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enterSelection,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
+  Services.search.currentEngine = previousEngine;
+  Services.search.removeEngine(suggestionEngine);
+  yield BrowserTestUtils.removeTab(tab);
+});
+
+// Performs a search using a click on a one-off button.  This only tests the
+// FX_URLBAR_SELECTED_RESULT_METHOD histogram since test_oneOff_enter covers
+// everything else.
+add_task(function* test_oneOff_click() {
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
+
+  info("Type a query.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield searchInAwesomebar("query");
+  info("Click the first one-off button.");
+  gURLBar.popup.oneOffSearchButtons.getSelectableButtons(false)[0].click();
+  yield p;
+
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.click,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
+  yield BrowserTestUtils.removeTab(tab);
+});
+
+// Clicks the first suggestion offered by the test search engine.
+add_task(function* test_suggestion_click() {
   // Let's reset the counts.
   Services.telemetry.clearScalars();
   Services.telemetry.clearEvents();
   let resultIndexHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX");
   let resultTypeHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_TYPE");
   let resultIndexByTypeHist = Services.telemetry.getKeyedHistogramById("FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
   resultIndexByTypeHist.clear();
   resultIndexHist.clear();
   resultTypeHist.clear();
+  resultMethodHist.clear();
 
   let search_hist = getSearchCountsHistogram();
 
   // Create an engine to generate search suggestions and add it as default
   // for this test.
   const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
   let suggestionEngine = yield new Promise((resolve, reject) => {
     Services.search.addEngine(url, null, "", false, {
@@ -278,17 +383,17 @@ add_task(function* test_suggestion() {
     });
   });
 
   let previousEngine = Services.search.currentEngine;
   Services.search.currentEngine = suggestionEngine;
 
   let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
 
-  info("Perform a one-off search using the first engine.");
+  info("Type a query. Suggestions should be generated by the test engine.");
   let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
   yield searchInAwesomebar("query");
   info("Clicking the urlbar suggestion.");
   clickURLBarSuggestion("queryfoo");
   yield p;
 
   // Check if the scalars contain the expected values.
   const scalars = getParentProcessScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, true, false);
@@ -314,12 +419,60 @@ add_task(function* test_suggestion() {
     URLBAR_SELECTED_RESULT_TYPES.searchsuggestion,
     "FX_URLBAR_SELECTED_RESULT_TYPE");
 
   let resultIndexByType = resultIndexByTypeHist.snapshot("searchsuggestion");
   checkHistogramResults(resultIndexByType,
     3,
     "FX_URLBAR_SELECTED_RESULT_INDEX_BY_TYPE");
 
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.click,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
   Services.search.currentEngine = previousEngine;
   Services.search.removeEngine(suggestionEngine);
   yield BrowserTestUtils.removeTab(tab);
 });
+
+// Selects and presses the Return (Enter) key on the first suggestion offered by
+// the test search engine.  This only tests the FX_URLBAR_SELECTED_RESULT_METHOD
+// histogram since test_suggestion_click covers everything else.
+add_task(function* test_suggestion_enterSelection() {
+  // Let's reset the counts.
+  Services.telemetry.clearScalars();
+
+  let resultMethodHist = Services.telemetry.getHistogramById("FX_URLBAR_SELECTED_RESULT_METHOD");
+  resultMethodHist.clear();
+
+  // Create an engine to generate search suggestions and add it as default
+  // for this test.
+  const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml";
+  let suggestionEngine = yield new Promise((resolve, reject) => {
+    Services.search.addEngine(url, null, "", false, {
+      onSuccess(engine) { resolve(engine) },
+      onError() { reject() }
+    });
+  });
+
+  let previousEngine = Services.search.currentEngine;
+  Services.search.currentEngine = suggestionEngine;
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank");
+
+  info("Type a query. Suggestions should be generated by the test engine.");
+  let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+  yield searchInAwesomebar("query");
+  info("Select the second result and press Return.");
+  EventUtils.synthesizeKey("VK_DOWN", {});
+  EventUtils.sendKey("return");
+  yield p;
+
+  let resultMethods = resultMethodHist.snapshot();
+  checkHistogramResults(resultMethods,
+    URLBAR_SELECTED_RESULT_METHODS.enterSelection,
+    "FX_URLBAR_SELECTED_RESULT_METHOD");
+
+  Services.search.currentEngine = previousEngine;
+  Services.search.removeEngine(suggestionEngine);
+  yield BrowserTestUtils.removeTab(tab);
+});
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -105,21 +105,16 @@ treecol {
   align-items: center;
   justify-content: space-between;
 }
 
 .header[hidden=true] {
   display: none;
 }
 
-#header-advanced {
-  border-bottom: none;
-  padding-bottom: 0;
-}
-
 /* General Pane */
 
 #startupTable {
   border-collapse: collapse;
 }
 
 #startupTable > tr > td {
   padding: 0; /* remove the padding from html.css */
@@ -178,20 +173,16 @@ treecol {
 
 #defaultFontSizeLabel {
   /* !important needed to override common !important rule */
   margin-inline-start: 4px !important;
 }
 
 /* Applications Pane Styles */
 
-#applicationsContent {
-  padding: 15px 0;
-}
-
 #filter {
   margin-inline-start: 0;
 }
 
 #handlersView {
   height: 25em;
 }
 
@@ -229,16 +220,31 @@ treecol {
   font-weight: normal;
 }
 
 .doNotTrackLearnMore > label {
   font-size: 1em !important;
   margin-left: 0;
 }
 
+/* This learn-more link is inserted at the end of a
+   xul:description element so it should behave like normal text. */
+#trackingProtectionLearnMore {
+  white-space: normal;
+  margin-inline-start: 0;
+}
+
+#trackingProtectionAdvancedSettings {
+  margin-inline-start: 15px;
+}
+
+#crashReporterGroup {
+  margin-top: 0;
+}
+
 /* Collapse the non-active vboxes in decks to use only the height the
    active vbox needs */
 #historyPane:not([selectedIndex="1"]) > #historyDontRememberPane,
 #historyPane:not([selectedIndex="2"]) > #historyCustomPane,
 #weavePrefsDeck:not([selectedIndex="1"]) > #hasFxaAccount,
 #fxaLoginStatus:not([selectedIndex="1"]) > #fxaLoginUnverified,
 #fxaLoginStatus:not([selectedIndex="2"]) > #fxaLoginRejected {
   visibility: collapse;
--- a/build/mach_bootstrap.py
+++ b/build/mach_bootstrap.py
@@ -27,84 +27,16 @@ If you would like to use a different dir
 MOZBUILD_STATE_PATH environment variable to the directory you would like to
 use and re-run mach. For this change to take effect forever, you'll likely
 want to export this environment variable from your shell's init scripts.
 
 Press ENTER/RETURN to continue or CTRL+c to abort.
 '''.lstrip()
 
 
-# TODO Bug 794506 Integrate with the in-tree virtualenv configuration.
-SEARCH_PATHS = [
-    'python/mach',
-    'python/mozboot',
-    'python/mozbuild',
-    'python/mozlint',
-    'python/mozversioncontrol',
-    'python/blessings',
-    'python/compare-locales',
-    'python/configobj',
-    'python/dlmanager',
-    'python/futures',
-    'python/jsmin',
-    'python/psutil',
-    'python/pylru',
-    'python/which',
-    'python/pystache',
-    'python/pyyaml/lib',
-    'python/requests',
-    'python/slugid',
-    'python/py',
-    'python/pytest',
-    'python/pytoml',
-    'python/redo',
-    'python/voluptuous',
-    'build',
-    'build/pymake',
-    'config',
-    'dom/bindings',
-    'dom/bindings/parser',
-    'dom/media/test/external',
-    'layout/tools/reftest',
-    'other-licenses/ply',
-    'taskcluster',
-    'testing',
-    'testing/firefox-ui/harness',
-    'testing/marionette/client',
-    'testing/marionette/harness',
-    'testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py',
-    'testing/marionette/puppeteer/firefox',
-    'testing/mozbase/mozcrash',
-    'testing/mozbase/mozdebug',
-    'testing/mozbase/mozdevice',
-    'testing/mozbase/mozfile',
-    'testing/mozbase/mozhttpd',
-    'testing/mozbase/mozinfo',
-    'testing/mozbase/mozinstall',
-    'testing/mozbase/mozleak',
-    'testing/mozbase/mozlog',
-    'testing/mozbase/moznetwork',
-    'testing/mozbase/mozprocess',
-    'testing/mozbase/mozprofile',
-    'testing/mozbase/mozrunner',
-    'testing/mozbase/mozsystemmonitor',
-    'testing/mozbase/mozscreenshot',
-    'testing/mozbase/moztest',
-    'testing/mozbase/mozversion',
-    'testing/mozbase/manifestparser',
-    'testing/taskcluster',
-    'testing/tools/autotry',
-    'testing/web-platform',
-    'testing/web-platform/harness',
-    'testing/web-platform/tests/tools/wptserve',
-    'testing/web-platform/tests/tools/six',
-    'testing/xpcshell',
-    'xpcom/idl-parser',
-]
-
 # Individual files providing mach commands.
 MACH_MODULES = [
     'addon-sdk/mach_commands.py',
     'build/valgrind/mach_commands.py',
     'devtools/shared/css/generated/mach_commands.py',
     'dom/bindings/mach_commands.py',
     'dom/media/test/external/mach_commands.py',
     'layout/tools/reftest/mach_commands.py',
@@ -179,16 +111,31 @@ CATEGORIES = {
     }
 }
 
 
 # We submit data to telemetry approximately every this many mach invocations
 TELEMETRY_SUBMISSION_FREQUENCY = 10
 
 
+def search_path(mozilla_dir, packages_txt):
+    with open(os.path.join(mozilla_dir, packages_txt)) as f:
+        packages = [line.rstrip().split(':') for line in f]
+
+    for package in packages:
+        if package[0] == 'packages.txt':
+            assert len(package) == 2
+            for p in search_path(mozilla_dir, package[1]):
+                yield os.path.join(mozilla_dir, p)
+
+        if package[0].endswith('.pth'):
+            assert len(package) == 2
+            yield os.path.join(mozilla_dir, package[1])
+
+
 def bootstrap(topsrcdir, mozilla_dir=None):
     if mozilla_dir is None:
         mozilla_dir = topsrcdir
 
     # Ensure we are running Python 2.7+. We put this check here so we generate a
     # user-friendly error message rather than a cryptic stack trace on module
     # import.
     if sys.version_info[0] != 2 or sys.version_info[1] < 7:
@@ -199,17 +146,19 @@ def bootstrap(topsrcdir, mozilla_dir=Non
     # Global build system and mach state is stored in a central directory. By
     # default, this is ~/.mozbuild. However, it can be defined via an
     # environment variable. We detect first run (by lack of this directory
     # existing) and notify the user that it will be created. The logic for
     # creation is much simpler for the "advanced" environment variable use
     # case. For default behavior, we educate users and give them an opportunity
     # to react. We always exit after creating the directory because users don't
     # like surprises.
-    sys.path[0:0] = [os.path.join(mozilla_dir, path) for path in SEARCH_PATHS]
+    sys.path[0:0] = [os.path.join(mozilla_dir, path)
+                     for path in search_path(mozilla_dir,
+                                             'build/virtualenv_packages.txt')]
     import mach.main
     from mozboot.util import get_state_dir
 
     from mozbuild.util import patch_main
     patch_main()
 
     def telemetry_handler(context, data):
         # We have not opted-in to telemetry
@@ -307,21 +256,22 @@ def bootstrap(topsrcdir, mozilla_dir=Non
             state_dir, is_environ = get_state_dir()
             if is_environ:
                 if not os.path.exists(state_dir):
                     print('Creating global state directory from environment variable: %s'
                           % state_dir)
                     os.makedirs(state_dir, mode=0o770)
             else:
                 if not os.path.exists(state_dir):
-                    print(STATE_DIR_FIRST_RUN.format(userdir=state_dir))
-                    try:
-                        sys.stdin.readline()
-                    except KeyboardInterrupt:
-                        sys.exit(1)
+                    if not os.environ.get('MOZ_AUTOMATION'):
+                        print(STATE_DIR_FIRST_RUN.format(userdir=state_dir))
+                        try:
+                            sys.stdin.readline()
+                        except KeyboardInterrupt:
+                            sys.exit(1)
 
                     print('\nCreating default state directory: %s' % state_dir)
                     os.makedirs(state_dir, mode=0o770)
 
             return state_dir
 
         if key == 'topdir':
             return topsrcdir
--- a/build/virtualenv_packages.txt
+++ b/build/virtualenv_packages.txt
@@ -1,43 +1,56 @@
-marionette_driver.pth:testing/marionette/client
-marionette_harness.pth:testing/marionette/harness
-browsermobproxy.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
-six.pth:testing/web-platform/tests/tools/six
-wptserve.pth:testing/web-platform/tests/tools/wptserve
-blessings.pth:python/blessings
-configobj.pth:python/configobj
-jsmin.pth:python/jsmin
-mach.pth:python/mach
-mozbuild.pth:python/mozbuild
-mozversioncontrol.pth:python/mozversioncontrol
-mozlint.pth:python/mozlint
-pymake.pth:build/pymake
+mozilla.pth:python/mach
+mozilla.pth:python/mozboot
+mozilla.pth:python/mozbuild
+mozilla.pth:python/mozlint
+mozilla.pth:python/mozversioncontrol
+mozilla.pth:python/blessings
+mozilla.pth:python/compare-locales
+mozilla.pth:python/configobj
+mozilla.pth:python/dlmanager
+mozilla.pth:python/futures
+mozilla.pth:python/jsmin
 optional:setup.py:python/psutil:build_ext:--inplace
-optional:psutil.pth:python/psutil
-which.pth:python/which
-ply.pth:other-licenses/ply/
-mock.pth:python/mock-1.0.0
-py.pth:python/py
-pytest.pth:python/pytest
+mozilla.pth:python/psutil
+mozilla.pth:python/pylru
+mozilla.pth:python/which
+mozilla.pth:python/pystache
+mozilla.pth:python/pyyaml/lib
+mozilla.pth:python/requests
+mozilla.pth:python/slugid
+mozilla.pth:python/py
+mozilla.pth:python/pytest
+mozilla.pth:python/pytoml
+mozilla.pth:python/redo
+mozilla.pth:python/voluptuous
 mozilla.pth:build
+objdir:build
+mozilla.pth:build/pymake
 mozilla.pth:config
-mozilla.pth:xpcom/typelib/xpt/tools
 mozilla.pth:dom/bindings
 mozilla.pth:dom/bindings/parser
+mozilla.pth:dom/media/test/external
 mozilla.pth:layout/tools/reftest
-moztreedocs.pth:tools/docs
+mozilla.pth:other-licenses/ply/
+mozilla.pth:taskcluster
+mozilla.pth:testing
+mozilla.pth:testing/firefox-ui/harness
+mozilla.pth:testing/marionette/client
+mozilla.pth:testing/marionette/harness
+mozilla.pth:testing/marionette/harness/marionette_harness/runner/mixins/browsermob-proxy-py
+mozilla.pth:testing/marionette/puppeteer/firefox
 packages.txt:testing/mozbase/packages.txt
-objdir:build
-gyp.pth:media/webrtc/trunk/tools/gyp/pylib
-pyasn1.pth:python/pyasn1
-pyasn1_modules.pth:python/pyasn1-modules
-redo.pth:python/redo
-requests.pth:python/requests
-rsa.pth:python/rsa
-futures.pth:python/futures
-ecc.pth:python/PyECC
-xpcshell.pth:testing/xpcshell
-pyyaml.pth:python/pyyaml/lib
-pytoml.pth:python/pytoml
-pylru.pth:python/pylru
-taskcluster.pth:taskcluster
-dlmanager.pth:python/dlmanager
+mozilla.pth:testing/taskcluster
+mozilla.pth:testing/tools/autotry
+mozilla.pth:testing/web-platform
+mozilla.pth:testing/web-platform/harness
+mozilla.pth:testing/web-platform/tests/tools/wptserve
+mozilla.pth:testing/web-platform/tests/tools/six
+mozilla.pth:testing/xpcshell
+mozilla.pth:python/mock-1.0.0
+mozilla.pth:xpcom/typelib/xpt/tools
+mozilla.pth:tools/docs
+mozilla.pth:media/webrtc/trunk/tools/gyp/pylib
+mozilla.pth:python/pyasn1
+mozilla.pth:python/pyasn1-modules
+mozilla.pth:python/rsa
+mozilla.pth:python/PyECC
--- a/devtools/client/netmonitor/src/components/moz.build
+++ b/devtools/client/netmonitor/src/components/moz.build
@@ -7,16 +7,27 @@ DevToolsModules(
     'cookies-panel.js',
     'custom-request-panel.js',
     'headers-panel.js',
     'mdn-link.js',
     'monitor-panel.js',
     'network-details-panel.js',
     'params-panel.js',
     'properties-view.js',
+    'request-list-column-cause.js',
+    'request-list-column-content-size.js',
+    'request-list-column-domain.js',
+    'request-list-column-file.js',
+    'request-list-column-method.js',
+    'request-list-column-protocol.js',
+    'request-list-column-remote-ip.js',
+    'request-list-column-status.js',
+    'request-list-column-transferred-size.js',
+    'request-list-column-type.js',
+    'request-list-column-waterfall.js',
     'request-list-content.js',
     'request-list-empty-notice.js',
     'request-list-header.js',
     'request-list-item.js',
     'request-list.js',
     'response-panel.js',
     'security-panel.js',
     'source-editor.js',
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-cause.js
@@ -0,0 +1,62 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+
+const { div, span } = DOM;
+
+const RequestListColumnCause = createClass({
+  displayName: "RequestListColumnCause",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+    onCauseBadgeClick: PropTypes.func.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.cause !== nextProps.item.cause;
+  },
+
+  render() {
+    const {
+      item,
+      onCauseBadgeClick,
+    } = this.props;
+
+    const { cause } = item;
+
+    let causeType = "";
+    let causeUri = undefined;
+    let causeHasStack = false;
+
+    if (cause) {
+      // Legacy server might send a numeric value. Display it as "unknown"
+      causeType = typeof cause.type === "string" ? cause.type : "unknown";
+      causeUri = cause.loadingDocumentUri;
+      causeHasStack = cause.stacktrace && cause.stacktrace.length > 0;
+    }
+
+    return (
+      div({
+        className: "requests-list-subitem requests-list-cause",
+        title: causeUri,
+      },
+        span({
+          className: "requests-list-cause-stack",
+          hidden: !causeHasStack,
+          onClick: onCauseBadgeClick,
+        }, "JS"),
+        span({ className: "subitem-label" }, causeType),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnCause;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-content-size.js
@@ -0,0 +1,46 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { getFormattedSize } = require("../utils/format-utils");
+
+const { div, span } = DOM;
+
+const RequestListColumnContentSize = createClass({
+  displayName: "RequestListColumnContentSize",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.contentSize !== nextProps.item.contentSize;
+  },
+
+  render() {
+    const { contentSize } = this.props.item;
+
+    let text;
+    if (typeof contentSize == "number") {
+      text = getFormattedSize(contentSize);
+    }
+
+    return (
+      div({
+        className: "requests-list-subitem subitem-label requests-list-size",
+        title: text,
+      },
+        span({ className: "subitem-label" }, text),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnContentSize;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-domain.js
@@ -0,0 +1,64 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { L10N } = require("../utils/l10n");
+const { propertiesEqual } = require("../utils/request-utils");
+
+const { div, span } = DOM;
+
+const UPDATED_DOMAIN_PROPS = [
+  "urlDetails",
+  "remoteAddress",
+  "securityState",
+];
+
+const RequestListColumnDomain = createClass({
+  displayName: "RequestListColumnDomain",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+    onSecurityIconClick: PropTypes.func.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return !propertiesEqual(UPDATED_DOMAIN_PROPS, this.props.item, nextProps.item);
+  },
+
+  render() {
+    const { item, onSecurityIconClick } = this.props;
+    const { urlDetails, remoteAddress, securityState } = item;
+
+    let iconClassList = ["requests-security-state-icon"];
+    let iconTitle;
+    if (urlDetails.isLocal) {
+      iconClassList.push("security-state-local");
+      iconTitle = L10N.getStr("netmonitor.security.state.secure");
+    } else if (securityState) {
+      iconClassList.push(`security-state-${securityState}`);
+      iconTitle = L10N.getStr(`netmonitor.security.state.${securityState}`);
+    }
+
+    let title = urlDetails.host + (remoteAddress ? ` (${remoteAddress})` : "");
+
+    return (
+      div({ className: "requests-list-subitem requests-list-security-and-domain" },
+        div({
+          className: iconClassList.join(" "),
+          title: iconTitle,
+          onClick: onSecurityIconClick,
+        }),
+        span({ className: "subitem-label requests-list-domain", title }, urlDetails.host),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnDomain;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-file.js
@@ -0,0 +1,54 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { propertiesEqual } = require("../utils/request-utils");
+
+const { div, img } = DOM;
+
+const UPDATED_FILE_PROPS = [
+  "urlDetails",
+  "responseContentDataUri",
+];
+
+const RequestListColumnFile = createClass({
+  displayName: "RequestListColumnFile",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return !propertiesEqual(UPDATED_FILE_PROPS, this.props.item, nextProps.item);
+  },
+
+  render() {
+    const { urlDetails, responseContentDataUri } = this.props.item;
+
+    return (
+      div({ className: "requests-list-subitem requests-list-icon-and-file" },
+        img({
+          className: "requests-list-icon",
+          src: responseContentDataUri,
+          hidden: !responseContentDataUri,
+          "data-type": responseContentDataUri ? "thumbnail" : undefined,
+        }),
+        div({
+          className: "subitem-label requests-list-file",
+          title: urlDetails.unicodeUrl,
+        },
+          urlDetails.baseNameWithQuery,
+        ),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnFile;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-method.js
@@ -0,0 +1,36 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+
+const { div, span } = DOM;
+
+const RequestListColumnMethod = createClass({
+  displayName: "RequestListColumnMethod",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.method !== nextProps.item.method;
+  },
+
+  render() {
+    const { method } = this.props.item;
+    return (
+      div({ className: "requests-list-subitem requests-list-method-box" },
+        span({ className: "subitem-label requests-list-method" }, method)
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnMethod;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-protocol.js
@@ -0,0 +1,36 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+
+const { div, span } = DOM;
+
+const RequestListColumnProtocol = createClass({
+  displayName: "RequestListColumnProtocol",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.httpVersion !== nextProps.item.httpVersion;
+  },
+
+  render() {
+    const { httpVersion } = this.props.item;
+    return (
+      div({ className: "requests-list-subitem requests-list-protocol" },
+        span({ className: "subitem-label", title: httpVersion }, httpVersion),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnProtocol;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-remote-ip.js
@@ -0,0 +1,38 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+
+const { div, span } = DOM;
+
+const RequestListColumnRemoteIP = createClass({
+  displayName: "RequestListColumnRemoteIP",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.remoteAddress !== nextProps.item.remoteAddress;
+  },
+
+  render() {
+    const { remoteAddress, remotePort } = this.props.item;
+    let remoteSummary = remoteAddress ? `${remoteAddress}:${remotePort}` : "";
+
+    return (
+      div({ className: "requests-list-subitem requests-list-remoteip" },
+        span({ className: "subitem-label", title: remoteSummary }, remoteSummary),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnRemoteIP;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-status.js
@@ -0,0 +1,68 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { propertiesEqual } = require("../utils/request-utils");
+
+const { div, span } = DOM;
+
+const UPDATED_STATUS_PROPS = [
+  "fromCache",
+  "fromServiceWorker",
+  "status",
+  "statusText",
+];
+
+const RequestListColumnStatus = createClass({
+  displayName: "RequestListColumnStatus",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return !propertiesEqual(UPDATED_STATUS_PROPS, this.props.item, nextProps.item);
+  },
+
+  render() {
+    const { status, statusText, fromCache, fromServiceWorker } = this.props.item;
+
+    let code, title;
+
+    if (status) {
+      if (fromCache) {
+        code = "cached";
+      } else if (fromServiceWorker) {
+        code = "service worker";
+      } else {
+        code = status;
+      }
+
+      if (statusText) {
+        title = `${status} ${statusText}`;
+        if (fromCache) {
+          title += " (cached)";
+        }
+        if (fromServiceWorker) {
+          title += " (service worker)";
+        }
+      }
+    }
+
+    return (
+        div({ className: "requests-list-subitem requests-list-status", title },
+        div({ className: "requests-list-status-icon", "data-code": code }),
+        span({ className: "subitem-label requests-list-status-code" }, status)
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnStatus;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-transferred-size.js
@@ -0,0 +1,63 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { getFormattedSize } = require("../utils/format-utils");
+const { L10N } = require("../utils/l10n");
+const { propertiesEqual } = require("../utils/request-utils");
+
+const { div, span } = DOM;
+
+const UPDATED_TRANSFERRED_PROPS = [
+  "transferredSize",
+  "fromCache",
+  "fromServiceWorker",
+];
+
+const RequestListColumnTransferredSize = createClass({
+  displayName: "RequestListColumnTransferredSize",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return !propertiesEqual(UPDATED_TRANSFERRED_PROPS, this.props.item, nextProps.item);
+  },
+
+  render() {
+    const { transferredSize, fromCache, fromServiceWorker, status } = this.props.item;
+
+    let text;
+    let className = "subitem-label";
+    if (fromCache || status === "304") {
+      text = L10N.getStr("networkMenu.sizeCached");
+      className += " theme-comment";
+    } else if (fromServiceWorker) {
+      text = L10N.getStr("networkMenu.sizeServiceWorker");
+      className += " theme-comment";
+    } else if (typeof transferredSize == "number") {
+      text = getFormattedSize(transferredSize);
+    } else if (transferredSize === null) {
+      text = L10N.getStr("networkMenu.sizeUnavailable");
+    }
+
+    return (
+      div({
+        className: "requests-list-subitem requests-list-transferred",
+        title: text,
+      },
+        span({ className }, text),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnTransferredSize;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-type.js
@@ -0,0 +1,52 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { getAbbreviatedMimeType } = require("../utils/request-utils");
+
+const { div, span } = DOM;
+
+const CONTENT_MIME_TYPE_ABBREVIATIONS = {
+  "ecmascript": "js",
+  "javascript": "js",
+  "x-javascript": "js"
+};
+
+const RequestListColumnType = createClass({
+  displayName: "RequestListColumnType",
+
+  propTypes: {
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.item.mimeType !== nextProps.item.mimeType;
+  },
+
+  render() {
+    const { mimeType } = this.props.item;
+    let abbrevType;
+    if (mimeType) {
+      abbrevType = getAbbreviatedMimeType(mimeType);
+      abbrevType = CONTENT_MIME_TYPE_ABBREVIATIONS[abbrevType] || abbrevType;
+    }
+
+    return (
+      div({
+        className: "requests-list-subitem requests-list-type",
+        title: mimeType,
+      },
+        span({ className: "subitem-label" }, abbrevType),
+      )
+    );
+  }
+});
+
+module.exports = RequestListColumnType;
new file mode 100644
--- /dev/null
+++ b/devtools/client/netmonitor/src/components/request-list-column-waterfall.js
@@ -0,0 +1,95 @@
+/* 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/. */
+
+"use strict";
+
+const {
+  createClass,
+  DOM,
+  PropTypes,
+} = require("devtools/client/shared/vendor/react");
+const { L10N } = require("../utils/l10n");
+const { propertiesEqual } = require("../utils/request-utils");
+
+const { div } = DOM;
+
+const UPDATED_WATERFALL_PROPS = [
+  "eventTimings",
+  "totalTime",
+  "fromCache",
+  "fromServiceWorker",
+];
+
+const RequestListColumnWaterfall = createClass({
+  displayName: "RequestListColumnWaterfall",
+
+  propTypes: {
+    firstRequestStartedMillis: PropTypes.number.isRequired,
+    item: PropTypes.object.isRequired,
+  },
+
+  shouldComponentUpdate(nextProps) {
+    return this.props.firstRequestStartedMillis !== nextProps.firstRequestStartedMillis ||
+      !propertiesEqual(UPDATED_WATERFALL_PROPS, this.props.item, nextProps.item);
+  },
+
+  render() {
+    const { item, firstRequestStartedMillis } = this.props;
+
+    return (
+      div({ className: "requests-list-subitem requests-list-waterfall" },
+        div({
+          className: "requests-list-timings",
+          style: {
+            paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`,
+          },
+        },
+          timingBoxes(item),
+        )
+      )
+    );
+  }
+});
+
+// List of properties of the timing info we want to create boxes for
+const TIMING_KEYS = ["blocked", "dns", "connect", "send", "wait", "receive"];
+
+function timingBoxes(item) {
+  const { eventTimings, totalTime, fromCache, fromServiceWorker } = item;
+  let boxes = [];
+
+  if (fromCache || fromServiceWorker) {
+    return boxes;
+  }
+
+  if (eventTimings) {
+    // Add a set of boxes representing timing information.
+    for (let key of TIMING_KEYS) {
+      let width = eventTimings.timings[key];
+
+      // Don't render anything if it surely won't be visible.
+      // One millisecond == one unscaled pixel.
+      if (width > 0) {
+        boxes.push(div({
+          key,
+          className: "requests-list-timings-box " + key,
+          style: { width }
+        }));
+      }
+    }
+  }
+
+  if (typeof totalTime === "number") {
+    let text = L10N.getFormatStr("networkMenu.totalMS", totalTime);
+    boxes.push(div({
+      key: "total",
+      className: "requests-list-timings-total",
+      title: text
+    }, text));
+  }
+
+  return boxes;
+}
+
+module.exports = RequestListColumnWaterfall;
--- a/devtools/client/netmonitor/src/components/request-list-item.js
+++ b/devtools/client/netmonitor/src/components/request-list-item.js
@@ -7,28 +7,32 @@
 const {
   createClass,
   createFactory,
   DOM,
   PropTypes,
 } = require("devtools/client/shared/vendor/react");
 const I = require("devtools/client/shared/vendor/immutable");
 
-const { getFormattedSize } = require("../utils/format-utils");
-const { L10N } = require("../utils/l10n");
-const { getAbbreviatedMimeType } = require("../utils/request-utils");
-
-const { div, img, span } = DOM;
+const { propertiesEqual } = require("../utils/request-utils");
 
-/**
- * Compare two objects on a subset of their properties
- */
-function propertiesEqual(props, item1, item2) {
-  return item1 === item2 || props.every(p => item1[p] === item2[p]);
-}
+// Components
+const RequestListColumnCause = createFactory(require("./request-list-column-cause"));
+const RequestListColumnContentSize = createFactory(require("./request-list-column-content-size"));
+const RequestListColumnDomain = createFactory(require("./request-list-column-domain"));
+const RequestListColumnFile = createFactory(require("./request-list-column-file"));
+const RequestListColumnMethod = createFactory(require("./request-list-column-method"));
+const RequestListColumnProtocol = createFactory(require("./request-list-column-protocol"));
+const RequestListColumnRemoteIP = createFactory(require("./request-list-column-remote-ip"));
+const RequestListColumnStatus = createFactory(require("./request-list-column-status"));
+const RequestListColumnTransferredSize = createFactory(require("./request-list-column-transferred-size"));
+const RequestListColumnType = createFactory(require("./request-list-column-type"));
+const RequestListColumnWaterfall = createFactory(require("./request-list-column-waterfall"));
+
+const { div } = DOM;
 
 /**
  * Used by shouldComponentUpdate: compare two items, and compare only properties
  * relevant for rendering the RequestListItem. Other properties (like request and
  * response headers, cookies, bodies) are ignored. These are very useful for the
  * network details, but not here.
  */
 const UPDATED_REQ_ITEM_PROPS = [
@@ -126,463 +130,26 @@ const RequestListItem = createClass({
       div({
         ref: "el",
         className: classList.join(" "),
         "data-id": item.id,
         tabIndex: 0,
         onContextMenu,
         onMouseDown,
       },
-        columns.get("status") && StatusColumn({ item }),
-        columns.get("method") && MethodColumn({ item }),
-        columns.get("file") && FileColumn({ item }),
-        columns.get("protocol") && ProtocolColumn({ item }),
-        columns.get("domain") && DomainColumn({ item, onSecurityIconClick }),
-        columns.get("remoteip") && RemoteIPColumn({ item }),
-        columns.get("cause") && CauseColumn({ item, onCauseBadgeClick }),
-        columns.get("type") && TypeColumn({ item }),
-        columns.get("transferred") && TransferredSizeColumn({ item }),
-        columns.get("contentSize") && ContentSizeColumn({ item }),
-        columns.get("waterfall") && WaterfallColumn({ item, firstRequestStartedMillis }),
+        columns.get("status") && RequestListColumnStatus({ item }),
+        columns.get("method") && RequestListColumnMethod({ item }),
+        columns.get("file") && RequestListColumnFile({ item }),
+        columns.get("protocol") && RequestListColumnProtocol({ item }),
+        columns.get("domain") && RequestListColumnDomain({ item, onSecurityIconClick }),
+        columns.get("remoteip") && RequestListColumnRemoteIP({ item }),
+        columns.get("cause") && RequestListColumnCause({ item, onCauseBadgeClick }),
+        columns.get("type") && RequestListColumnType({ item }),
+        columns.get("transferred") && RequestListColumnTransferredSize({ item }),
+        columns.get("contentSize") && RequestListColumnContentSize({ item }),
+        columns.get("waterfall") &&
+          RequestListColumnWaterfall({ item, firstRequestStartedMillis }),
       )
     );
   }
 });
 
-const UPDATED_STATUS_PROPS = [
-  "status",
-  "statusText",
-  "fromCache",
-  "fromServiceWorker",
-];
-
-const StatusColumn = createFactory(createClass({
-  displayName: "StatusColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return !propertiesEqual(UPDATED_STATUS_PROPS, this.props.item, nextProps.item);
-  },
-
-  render() {
-    const { status, statusText, fromCache, fromServiceWorker } = this.props.item;
-
-    let code, title;
-
-    if (status) {
-      if (fromCache) {
-        code = "cached";
-      } else if (fromServiceWorker) {
-        code = "service worker";
-      } else {
-        code = status;
-      }
-
-      if (statusText) {
-        title = `${status} ${statusText}`;
-        if (fromCache) {
-          title += " (cached)";
-        }
-        if (fromServiceWorker) {
-          title += " (service worker)";
-        }
-      }
-    }
-
-    return (
-        div({ className: "requests-list-subitem requests-list-status", title },
-        div({ className: "requests-list-status-icon", "data-code": code }),
-        span({ className: "subitem-label requests-list-status-code" }, status)
-      )
-    );
-  }
-}));
-
-const MethodColumn = createFactory(createClass({
-  displayName: "MethodColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.item.method !== nextProps.item.method;
-  },
-
-  render() {
-    const { method } = this.props.item;
-    return (
-      div({ className: "requests-list-subitem requests-list-method-box" },
-        span({ className: "subitem-label requests-list-method" }, method)
-      )
-    );
-  }
-}));
-
-const UPDATED_FILE_PROPS = [
-  "urlDetails",
-  "responseContentDataUri",
-];
-
-const FileColumn = createFactory(createClass({
-  displayName: "FileColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return !propertiesEqual(UPDATED_FILE_PROPS, this.props.item, nextProps.item);
-  },
-
-  render() {
-    const { urlDetails, responseContentDataUri } = this.props.item;
-
-    return (
-      div({ className: "requests-list-subitem requests-list-icon-and-file" },
-        img({
-          className: "requests-list-icon",
-          src: responseContentDataUri,
-          hidden: !responseContentDataUri,
-          "data-type": responseContentDataUri ? "thumbnail" : undefined,
-        }),
-        div({
-          className: "subitem-label requests-list-file",
-          title: urlDetails.unicodeUrl,
-        },
-          urlDetails.baseNameWithQuery,
-        ),
-      )
-    );
-  }
-}));
-
-const ProtocolColumn = createFactory(createClass({
-  displayName: "Protocol",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.item.httpVersion !== nextProps.item.httpVersion;
-  },
-
-  render() {
-    const { httpVersion } = this.props.item;
-    return (
-      div({ className: "requests-list-subitem requests-list-protocol" },
-        span({ className: "subitem-label", title: httpVersion }, httpVersion),
-      )
-    );
-  }
-}));
-
-const UPDATED_DOMAIN_PROPS = [
-  "urlDetails",
-  "remoteAddress",
-  "securityState",
-];
-
-const DomainColumn = createFactory(createClass({
-  displayName: "DomainColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-    onSecurityIconClick: PropTypes.func.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return !propertiesEqual(UPDATED_DOMAIN_PROPS, this.props.item, nextProps.item);
-  },
-
-  render() {
-    const { item, onSecurityIconClick } = this.props;
-    const { urlDetails, remoteAddress, securityState } = item;
-
-    let iconClassList = ["requests-security-state-icon"];
-    let iconTitle;
-    if (urlDetails.isLocal) {
-      iconClassList.push("security-state-local");
-      iconTitle = L10N.getStr("netmonitor.security.state.secure");
-    } else if (securityState) {
-      iconClassList.push(`security-state-${securityState}`);
-      iconTitle = L10N.getStr(`netmonitor.security.state.${securityState}`);
-    }
-
-    let title = urlDetails.host + (remoteAddress ? ` (${remoteAddress})` : "");
-
-    return (
-      div({ className: "requests-list-subitem requests-list-security-and-domain" },
-        div({
-          className: iconClassList.join(" "),
-          title: iconTitle,
-          onClick: onSecurityIconClick,
-        }),
-        span({ className: "subitem-label requests-list-domain", title }, urlDetails.host),
-      )
-    );
-  }
-}));
-
-const RemoteIPColumn = createFactory(createClass({
-  displayName: "RemoteIP",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.item.remoteAddress !== nextProps.item.remoteAddress;
-  },
-
-  render() {
-    const { remoteAddress, remotePort } = this.props.item;
-    let remoteSummary = remoteAddress ? `${remoteAddress}:${remotePort}` : "";
-
-    return (
-      div({ className: "requests-list-subitem requests-list-remoteip" },
-        span({ className: "subitem-label", title: remoteSummary }, remoteSummary),
-      )
-    );
-  }
-}));
-
-const CauseColumn = createFactory(createClass({
-  displayName: "CauseColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-    onCauseBadgeClick: PropTypes.func.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.item.cause !== nextProps.item.cause;
-  },
-
-  render() {
-    const {
-      item,
-      onCauseBadgeClick,
-    } = this.props;
-
-    const { cause } = item;
-
-    let causeType = "";
-    let causeUri = undefined;
-    let causeHasStack = false;
-
-    if (cause) {
-      // Legacy server might send a numeric value. Display it as "unknown"
-      causeType = typeof cause.type === "string" ? cause.type : "unknown";
-      causeUri = cause.loadingDocumentUri;
-      causeHasStack = cause.stacktrace && cause.stacktrace.length > 0;
-    }
-
-    return (
-      div({
-        className: "requests-list-subitem requests-list-cause",
-        title: causeUri,
-      },
-        span({
-          className: "requests-list-cause-stack",
-          hidden: !causeHasStack,
-          onClick: onCauseBadgeClick,
-        }, "JS"),
-        span({ className: "subitem-label" }, causeType),
-      )
-    );
-  }
-}));
-
-const CONTENT_MIME_TYPE_ABBREVIATIONS = {
-  "ecmascript": "js",
-  "javascript": "js",
-  "x-javascript": "js"
-};
-
-const TypeColumn = createFactory(createClass({
-  displayName: "TypeColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.item.mimeType !== nextProps.item.mimeType;
-  },
-
-  render() {
-    const { mimeType } = this.props.item;
-    let abbrevType;
-    if (mimeType) {
-      abbrevType = getAbbreviatedMimeType(mimeType);
-      abbrevType = CONTENT_MIME_TYPE_ABBREVIATIONS[abbrevType] || abbrevType;
-    }
-
-    return (
-      div({
-        className: "requests-list-subitem requests-list-type",
-        title: mimeType,
-      },
-        span({ className: "subitem-label" }, abbrevType),
-      )
-    );
-  }
-}));
-
-const UPDATED_TRANSFERRED_PROPS = [
-  "transferredSize",
-  "fromCache",
-  "fromServiceWorker",
-];
-
-const TransferredSizeColumn = createFactory(createClass({
-  displayName: "TransferredSizeColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return !propertiesEqual(UPDATED_TRANSFERRED_PROPS, this.props.item, nextProps.item);
-  },
-
-  render() {
-    const { transferredSize, fromCache, fromServiceWorker, status } = this.props.item;
-
-    let text;
-    let className = "subitem-label";
-    if (fromCache || status === "304") {
-      text = L10N.getStr("networkMenu.sizeCached");
-      className += " theme-comment";
-    } else if (fromServiceWorker) {
-      text = L10N.getStr("networkMenu.sizeServiceWorker");
-      className += " theme-comment";
-    } else if (typeof transferredSize == "number") {
-      text = getFormattedSize(transferredSize);
-    } else if (transferredSize === null) {
-      text = L10N.getStr("networkMenu.sizeUnavailable");
-    }
-
-    return (
-      div({
-        className: "requests-list-subitem requests-list-transferred",
-        title: text,
-      },
-        span({ className }, text),
-      )
-    );
-  }
-}));
-
-const ContentSizeColumn = createFactory(createClass({
-  displayName: "ContentSizeColumn",
-
-  propTypes: {
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.item.contentSize !== nextProps.item.contentSize;
-  },
-
-  render() {
-    const { contentSize } = this.props.item;
-
-    let text;
-    if (typeof contentSize == "number") {
-      text = getFormattedSize(contentSize);
-    }
-
-    return (
-      div({
-        className: "requests-list-subitem subitem-label requests-list-size",
-        title: text,
-      },
-        span({ className: "subitem-label" }, text),
-      )
-    );
-  }
-}));
-
-const UPDATED_WATERFALL_PROPS = [
-  "eventTimings",
-  "totalTime",
-  "fromCache",
-  "fromServiceWorker",
-];
-
-const WaterfallColumn = createFactory(createClass({
-  displayName: "WaterfallColumn",
-
-  propTypes: {
-    firstRequestStartedMillis: PropTypes.number.isRequired,
-    item: PropTypes.object.isRequired,
-  },
-
-  shouldComponentUpdate(nextProps) {
-    return this.props.firstRequestStartedMillis !== nextProps.firstRequestStartedMillis ||
-      !propertiesEqual(UPDATED_WATERFALL_PROPS, this.props.item, nextProps.item);
-  },
-
-  render() {
-    const { item, firstRequestStartedMillis } = this.props;
-
-    return (
-      div({ className: "requests-list-subitem requests-list-waterfall" },
-        div({
-          className: "requests-list-timings",
-          style: {
-            paddingInlineStart: `${item.startedMillis - firstRequestStartedMillis}px`,
-          },
-        },
-          timingBoxes(item),
-        )
-      )
-    );
-  }
-}));
-
-// List of properties of the timing info we want to create boxes for
-const TIMING_KEYS = ["blocked", "dns", "connect", "send", "wait", "receive"];
-
-function timingBoxes(item) {
-  const { eventTimings, totalTime, fromCache, fromServiceWorker } = item;
-  let boxes = [];
-
-  if (fromCache || fromServiceWorker) {
-    return boxes;
-  }
-
-  if (eventTimings) {
-    // Add a set of boxes representing timing information.
-    for (let key of TIMING_KEYS) {
-      let width = eventTimings.timings[key];
-
-      // Don't render anything if it surely won't be visible.
-      // One millisecond == one unscaled pixel.
-      if (width > 0) {
-        boxes.push(div({
-          key,
-          className: "requests-list-timings-box " + key,
-          style: { width }
-        }));
-      }
-    }
-  }
-
-  if (typeof totalTime === "number") {
-    let text = L10N.getFormatStr("networkMenu.totalMS", totalTime);
-    boxes.push(div({
-      key: "total",
-      className: "requests-list-timings-total",
-      title: text
-    }, text));
-  }
-
-  return boxes;
-}
-
 module.exports = RequestListItem;
--- a/devtools/client/netmonitor/src/utils/request-utils.js
+++ b/devtools/client/netmonitor/src/utils/request-utils.js
@@ -269,25 +269,33 @@ function ipToLong(ip) {
   }
   return octets.map((val, ix, arr) => {
     return parseInt(val, base) * Math.pow(256, (arr.length - 1) - ix);
   }).reduce((sum, val) => {
     return sum + val;
   }, 0);
 }
 
+/**
+ * Compare two objects on a subset of their properties
+ */
+function propertiesEqual(props, item1, item2) {
+  return item1 === item2 || props.every(p => item1[p] === item2[p]);
+}
+
 module.exports = {
   getFormDataSections,
   fetchHeaders,
   formDataURI,
   writeHeaderText,
   decodeUnicodeUrl,
   getAbbreviatedMimeType,
   getUrlBaseName,
   getUrlQuery,
   getUrlBaseNameWithQuery,
   getUrlHostName,
   getUrlHost,
   getUrlDetails,
   parseQueryString,
   parseFormData,
+  propertiesEqual,
   ipToLong,
 };
--- a/devtools/client/shared/widgets/tooltip/HTMLTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/HTMLTooltip.js
@@ -169,16 +169,25 @@ function (anchorRect, viewportRect, widt
 };
 
 /**
  * Get the bounding client rectangle for a given node, relative to a custom
  * reference element (instead of the default for getBoundingClientRect which
  * is always the element's ownerDocument).
  */
 const getRelativeRect = function (node, relativeTo) {
+  // getBoxQuads is a non-standard WebAPI which will not work on non-firefox
+  // browser when running launchpad on Chrome.
+  if (!node.getBoxQuads) {
+    let {top, left, width, height} = node.getBoundingClientRect();
+    let right = left + width;
+    let bottom = top + height;
+    return {top, right, bottom, left, width, height};
+  }
+
   // Width and Height can be taken from the rect.
   let {width, height} = node.getBoundingClientRect();
 
   let quads = node.getBoxQuads({relativeTo});
   let top = quads[0].bounds.top;
   let left = quads[0].bounds.left;
 
   // Compute right and bottom coordinates using the rest of the data.
--- a/devtools/client/webconsole/test/browser_webconsole_shows_reqs_in_netmonitor.js
+++ b/devtools/client/webconsole/test/browser_webconsole_shows_reqs_in_netmonitor.js
@@ -25,17 +25,17 @@ add_task(function* () {
   let target = TargetFactory.forTab(tab);
   let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
   info("Network panel is open.");
 
   yield loadDocument(browser);
   info("Document loaded.");
 
   // Test that the request appears in the network panel.
-  testNetmonitor(toolbox);
+  yield testNetmonitor(toolbox);
 
   // Test that the request appears in the console.
   let hud = yield openConsole();
   info("Web console is open");
 
   yield waitForMessages({
     webconsole: hud,
     messages: [
@@ -55,23 +55,21 @@ function loadDocument(browser) {
   browser.addEventListener("load", function () {
     deferred.resolve();
   }, {capture: true, once: true});
   BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_PATH);
 
   return deferred.promise;
 }
 
-function testNetmonitor(toolbox) {
+function* testNetmonitor(toolbox) {
   let monitor = toolbox.getCurrentPanel();
-
   let { gStore, windowRequire } = monitor.panelWin;
-  let Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
   let { getSortedRequests } = windowRequire("devtools/client/netmonitor/src/selectors/index");
 
-  gStore.dispatch(Actions.batchEnable(false));
+  yield waitUntil(() => gStore.getState().requests.requests.size > 0);
 
   is(gStore.getState().requests.requests.size, 1, "Network request appears in the network panel");
 
   let item = getSortedRequests(gStore.getState()).get(0);
   is(item.method, "GET", "The request method is correct.");
   is(item.url, TEST_PATH, "The request url is correct.");
 }
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -1009,27 +1009,25 @@ MakePropertyValuePair(nsCSSPropertyID aP
                       nsCSSParser& aParser, nsIDocument* aDocument)
 {
   MOZ_ASSERT(aDocument);
   PropertyValuePair result;
 
   result.mProperty = aProperty;
 
   if (aDocument->GetStyleBackendType() == StyleBackendType::Servo) {
-    nsCString name = nsCSSProps::GetStringValue(aProperty);
-
     NS_ConvertUTF16toUTF8 value(aStringValue);
 
     // FIXME this is using the wrong base uri (bug 1343919)
     RefPtr<URLExtraData> data = new URLExtraData(aDocument->GetDocumentURI(),
                                                  aDocument->GetDocumentURI(),
                                                  aDocument->NodePrincipal());
 
     RefPtr<RawServoDeclarationBlock> servoDeclarationBlock =
-      Servo_ParseProperty(&name, &value, data).Consume();
+      Servo_ParseProperty(aProperty, &value, data).Consume();
 
     if (servoDeclarationBlock) {
       result.mServoDeclarationBlock = servoDeclarationBlock.forget();
     }
     return result;
   }
 
   nsCSSValue value;
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -21,16 +21,17 @@
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIFrame.h"
 #include "nsError.h"
 
 #include "nsCSSParser.h"
+#include "nsCSSPseudoElements.h"
 #include "mozilla/css/StyleRule.h"
 #include "mozilla/css/Declaration.h"
 #include "nsComputedDOMStyle.h"
 #include "nsStyleSet.h"
 
 #include "nsPrintfCString.h"
 
 #include "nsReadableUtils.h"
@@ -90,16 +91,17 @@
 #include "mozilla/gfx/DataSurfaceHelpers.h"
 #include "mozilla/gfx/PatternHelpers.h"
 #include "mozilla/gfx/Swizzle.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
 #include "mozilla/ipc/PDocumentRendererParent.h"
 #include "mozilla/layers/PersistentBufferProvider.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/ServoBindings.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtr.h"
 #include "mozilla/Unused.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsWrapperCacheInlines.h"
 #include "mozilla/dom/CanvasRenderingContext2DBinding.h"
 #include "mozilla/dom/CanvasPath.h"
@@ -2695,32 +2697,27 @@ GetFontParentStyleContext(Element* aElem
       aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
     return result.forget();
   }
 
   // otherwise inherit from default (10px sans-serif)
 
-  nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
-  if (!styleSet) {
-    // XXXheycam ServoStyleSets do not support resolving style from a list of
-    // rules yet.
-    NS_ERROR("stylo: cannot resolve style for canvas from a ServoStyleSet yet");
-    aError.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
   bool changed;
   RefPtr<css::Declaration> parentRule =
     CreateFontDeclaration(NS_LITERAL_STRING("10px sans-serif"),
                           aPresShell->GetDocument(), &changed);
 
   nsTArray<nsCOMPtr<nsIStyleRule>> parentRules;
   parentRules.AppendElement(parentRule);
+
+  nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
+  MOZ_RELEASE_ASSERT(styleSet);
+
   RefPtr<nsStyleContext> result =
     styleSet->ResolveStyleForRules(nullptr, parentRules);
 
   if (!result) {
     aError.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
   return result.forget();
@@ -2739,25 +2736,16 @@ PropertyIsInheritOrInitial(Declaration* 
 }
 
 static already_AddRefed<nsStyleContext>
 GetFontStyleContext(Element* aElement, const nsAString& aFont,
                     nsIPresShell* aPresShell,
                     nsAString& aOutUsedFont,
                     ErrorResult& aError)
 {
-  nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
-  if (!styleSet) {
-    // XXXheycam ServoStyleSets do not support resolving style from a list of
-    // rules yet.
-    NS_ERROR("stylo: cannot resolve style for canvas from a ServoStyleSet yet");
-    aError.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
   bool fontParsedSuccessfully = false;
   RefPtr<css::Declaration> decl =
     CreateFontDeclaration(aFont, aPresShell->GetDocument(),
                           &fontParsedSuccessfully);
 
   if (!fontParsedSuccessfully) {
     // We got a syntax error.  The spec says this value must be ignored.
     return nullptr;
@@ -2787,54 +2775,154 @@ GetFontStyleContext(Element* aElement, c
   MOZ_ASSERT(!aPresShell->IsDestroying(),
              "GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
 
   nsTArray<nsCOMPtr<nsIStyleRule>> rules;
   rules.AppendElement(decl);
   // add a rule to prevent text zoom from affecting the style
   rules.AppendElement(new nsDisableTextZoomStyleRule);
 
+  nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
+  MOZ_RELEASE_ASSERT(styleSet);
+
   RefPtr<nsStyleContext> sc =
     styleSet->ResolveStyleForRules(parentContext, rules);
 
   // The font getter is required to be reserialized based on what we
   // parsed (including having line-height removed).  (Older drafts of
   // the spec required font sizes be converted to pixels, but that no
   // longer seems to be required.)
   decl->GetPropertyValueByID(eCSSProperty_font, aOutUsedFont);
 
   return sc.forget();
 }
 
+static already_AddRefed<RawServoDeclarationBlock>
+CreateDeclarationForServo(nsCSSPropertyID aProperty,
+                          const nsAString& aPropertyValue,
+                          nsIDocument* aDocument)
+{
+  RefPtr<URLExtraData> data =
+    new URLExtraData(aDocument->GetDocBaseURI(),
+                     aDocument->GetDocumentURI(),
+                     aDocument->NodePrincipal());
+
+  NS_ConvertUTF16toUTF8 value(aPropertyValue);
+
+  RefPtr<RawServoDeclarationBlock> servoDeclarations =
+    Servo_ParseProperty(aProperty, &value, data).Consume();
+
+  if (!servoDeclarations) {
+    // We got a syntax error.  The spec says this value must be ignored.
+    return nullptr;
+  }
+
+  // From canvas spec, force to set line-height property to 'normal' font
+  // property.
+  if (aProperty == eCSSProperty_font) {
+    const nsCString normalString = NS_LITERAL_CSTRING("normal");
+    Servo_DeclarationBlock_SetPropertyById(servoDeclarations,
+                                           eCSSProperty_line_height,
+                                           &normalString,
+                                           false,
+                                           data,
+                                           LengthParsingMode::Default);
+  }
+
+  return servoDeclarations.forget();
+}
+
+static already_AddRefed<RawServoDeclarationBlock>
+CreateFontDeclarationForServo(const nsAString& aFont,
+                              nsIDocument* aDocument)
+{
+  return CreateDeclarationForServo(eCSSProperty_font, aFont, aDocument);
+}
+
+static already_AddRefed<ServoComputedValues>
+GetFontStyleForServo(Element* aElement, const nsAString& aFont,
+                     nsIPresShell* aPresShell,
+                     nsAString& aOutUsedFont,
+                     ErrorResult& aError)
+{
+  MOZ_ASSERT(aPresShell->StyleSet()->IsServo());
+
+  RefPtr<RawServoDeclarationBlock> declarations =
+    CreateFontDeclarationForServo(aFont, aPresShell->GetDocument());
+  if (!declarations) {
+    // We got a syntax error.  The spec says this value must be ignored.
+    return nullptr;
+  }
+
+  // In addition to unparseable values, the spec says we need to reject
+  // 'inherit' and 'initial'. The easiest way to check for this is to look
+  // at font-size-adjust, which the font shorthand resets to 'none'.
+  if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations,
+                                               eCSSProperty_font_size_adjust)) {
+    return nullptr;
+  }
+
+  ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
+
+  RefPtr<ServoComputedValues> parentStyle;
+  // have to get a parent style context for inherit-like relative
+  // values (2em, bolder, etc.)
+  if (aElement && aElement->IsInUncomposedDoc()) {
+    // Inherit from the canvas element.
+    aPresShell->FlushPendingNotifications(FlushType::Style);
+    // We need to use ResolveTransientServoStyle, which involves traversal,
+    // instead of ResolveServoStyle() because we need up-to-date style even if
+    // the canvas element is display:none.
+    parentStyle = styleSet->ResolveTransientServoStyle(aElement, nullptr);
+  } else {
+    RefPtr<RawServoDeclarationBlock> declarations =
+      CreateFontDeclarationForServo(NS_LITERAL_STRING("10px sans-serif"),
+                                    aPresShell->GetDocument());
+    MOZ_ASSERT(declarations);
+
+    parentStyle = aPresShell->StyleSet()->AsServo()->
+      ResolveForDeclarations(nullptr, declarations);
+  }
+
+  MOZ_RELEASE_ASSERT(parentStyle, "Should have a valid parent style");
+
+  MOZ_ASSERT(!aPresShell->IsDestroying(),
+             "GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
+
+  RefPtr<ServoComputedValues> sc =
+    styleSet->ResolveForDeclarations(parentStyle, declarations);
+
+  // The font getter is required to be reserialized based on what we
+  // parsed (including having line-height removed).  (Older drafts of
+  // the spec required font sizes be converted to pixels, but that no
+  // longer seems to be required.)
+  Servo_DeclarationBlock_SerializeOneValue(declarations,
+                                           eCSSProperty_font,
+                                           &aOutUsedFont);
+
+  return sc.forget();
+}
+
 static already_AddRefed<Declaration>
 CreateFilterDeclaration(const nsAString& aFilter,
                         nsINode* aNode,
                         bool* aOutFilterChanged)
 {
   bool dummy;
   return CreateDeclaration(aNode,
     eCSSProperty_filter, aFilter, aOutFilterChanged,
     eCSSProperty_UNKNOWN, EmptyString(), &dummy);
 }
 
 static already_AddRefed<nsStyleContext>
-ResolveStyleForFilter(const nsAString& aFilterString,
-                      nsIPresShell* aPresShell,
-                      nsStyleContext* aParentContext,
-                      ErrorResult& aError)
-{
-  nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
-  if (!styleSet) {
-    // XXXheycam ServoStyleSets do not support resolving style from a list of
-    // rules yet.
-    NS_ERROR("stylo: cannot resolve style for canvas from a ServoStyleSet yet");
-    aError.Throw(NS_ERROR_FAILURE);
-    return nullptr;
-  }
-
+ResolveFilterStyle(const nsAString& aFilterString,
+                   nsIPresShell* aPresShell,
+                   nsStyleContext* aParentContext,
+                   ErrorResult& aError)
+{
   nsIDocument* document = aPresShell->GetDocument();
   bool filterChanged = false;
   RefPtr<css::Declaration> decl =
     CreateFilterDeclaration(aFilterString, document, &filterChanged);
 
   if (!filterChanged) {
     // Refuse to accept the filter, but do not throw an error.
     return nullptr;
@@ -2844,22 +2932,61 @@ ResolveStyleForFilter(const nsAString& a
   // 'inherit' and 'initial'.
   if (PropertyIsInheritOrInitial(decl, eCSSProperty_filter)) {
     return nullptr;
   }
 
   nsTArray<nsCOMPtr<nsIStyleRule>> rules;
   rules.AppendElement(decl);
 
+  nsStyleSet* styleSet = aPresShell->StyleSet()->GetAsGecko();
+  MOZ_RELEASE_ASSERT(styleSet);
+
   RefPtr<nsStyleContext> sc =
     styleSet->ResolveStyleForRules(aParentContext, rules);
 
   return sc.forget();
 }
 
+static already_AddRefed<RawServoDeclarationBlock>
+CreateFilterDeclarationForServo(const nsAString& aFilter,
+                                nsIDocument* aDocument)
+{
+  return CreateDeclarationForServo(eCSSProperty_filter, aFilter, aDocument);
+}
+
+static already_AddRefed<ServoComputedValues>
+ResolveFilterStyleForServo(const nsAString& aFilterString,
+                           const ServoComputedValues* aParentStyle,
+                           nsIPresShell* aPresShell,
+                           ErrorResult& aError)
+{
+  MOZ_ASSERT(aPresShell->StyleSet()->IsServo());
+
+  RefPtr<RawServoDeclarationBlock> declarations =
+    CreateFilterDeclarationForServo(aFilterString, aPresShell->GetDocument());
+  if (!declarations) {
+    // Refuse to accept the filter, but do not throw an error.
+    return nullptr;
+  }
+
+  // In addition to unparseable values, the spec says we need to reject
+  // 'inherit' and 'initial'.
+  if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations,
+                                               eCSSProperty_filter)) {
+    return nullptr;
+  }
+
+  ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
+  RefPtr<ServoComputedValues> computedValues =
+    styleSet->ResolveForDeclarations(aParentStyle, declarations);
+
+  return computedValues.forget();
+}
+
 bool
 CanvasRenderingContext2D::ParseFilter(const nsAString& aString,
                                       nsTArray<nsStyleFilter>& aFilterChain,
                                       ErrorResult& aError)
 {
   if (!mCanvasElement && !mDocShell) {
     NS_WARNING("Canvas element must be non-null or a docshell must be provided");
     aError.Throw(NS_ERROR_FAILURE);
@@ -2868,32 +2995,59 @@ CanvasRenderingContext2D::ParseFilter(co
 
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell) {
     aError.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   nsString usedFont;
-  RefPtr<nsStyleContext> parentContext =
-    GetFontStyleContext(mCanvasElement, GetFont(),
-                        presShell, usedFont, aError);
-  if (!parentContext) {
-    aError.Throw(NS_ERROR_FAILURE);
+  if (presShell->StyleSet()->IsGecko()) {
+    RefPtr<nsStyleContext> parentContext =
+      GetFontStyleContext(mCanvasElement, GetFont(),
+                          presShell, usedFont, aError);
+    if (!parentContext) {
+      aError.Throw(NS_ERROR_FAILURE);
+      return false;
+    }
+    RefPtr<nsStyleContext> sc =
+      ResolveFilterStyle(aString, presShell, parentContext, aError);
+
+    if (!sc) {
+      return false;
+    }
+    aFilterChain = sc->StyleEffects()->mFilters;
+    return true;
+  }
+
+  // For stylo
+  MOZ_ASSERT(presShell->StyleSet()->IsServo());
+
+  RefPtr<ServoComputedValues> parentStyle =
+    GetFontStyleForServo(mCanvasElement,
+                         GetFont(),
+                         presShell,
+                         usedFont,
+                         aError);
+  if (!parentStyle) {
     return false;
   }
 
-  RefPtr<nsStyleContext> sc =
-    ResolveStyleForFilter(aString, presShell, parentContext, aError);
-
-  if (!sc) {
-    return false;
-  }
-
-  aFilterChain = sc->StyleEffects()->mFilters;
+  RefPtr<ServoComputedValues> computedValues =
+    ResolveFilterStyleForServo(aString,
+                               parentStyle,
+                               presShell,
+                               aError);
+  if (!computedValues) {
+     return false;
+  }
+
+  const nsStyleEffects* effects = Servo_GetStyleEffects(computedValues);
+  // XXX: This mFilters is a one shot object, we probably could avoid copying.
+  aFilterChain = effects->mFilters;
   return true;
 }
 
 void
 CanvasRenderingContext2D::SetFilter(const nsAString& aFilter, ErrorResult& aError)
 {
   nsTArray<nsStyleFilter> filterChain;
   if (ParseFilter(aFilter, filterChain, aError)) {
@@ -3789,32 +3943,50 @@ CanvasRenderingContext2D::SetFontInterna
   }
 
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell) {
     aError.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
+  RefPtr<nsStyleContext> sc;
+  RefPtr<ServoComputedValues> computedValues;
   nsString usedFont;
-  RefPtr<nsStyleContext> sc =
-    GetFontStyleContext(mCanvasElement, aFont, presShell, usedFont, aError);
-  if (!sc) {
-    return false;
-  }
-
-  const nsStyleFont* fontStyle = sc->StyleFont();
+  const nsStyleFont* fontStyle;
+  if (presShell->StyleSet()->IsServo()) {
+    computedValues = GetFontStyleForServo(mCanvasElement,
+                                          aFont,
+                                          presShell,
+                                          usedFont,
+                                          aError);
+    if (!computedValues) {
+      return false;
+    }
+    fontStyle = Servo_GetStyleFont(computedValues);
+  } else {
+    sc = GetFontStyleContext(mCanvasElement,
+                             aFont,
+                             presShell,
+                             usedFont,
+                             aError);
+    if (!sc) {
+      return false;
+    }
+    fontStyle = sc->StyleFont();
+  }
 
   nsPresContext* c = presShell->GetPresContext();
 
   // Purposely ignore the font size that respects the user's minimum
   // font preference (fontStyle->mFont.size) in favor of the computed
   // size (fontStyle->mSize).  See
   // https://bugzilla.mozilla.org/show_bug.cgi?id=698652.
-  MOZ_ASSERT(!fontStyle->mAllowZoom,
+  // FIXME: Nobody initializes mAllowZoom for servo?
+  MOZ_ASSERT(presShell->StyleSet()->IsServo() || !fontStyle->mAllowZoom,
              "expected text zoom to be disabled on this nsStyleFont");
   nsFont resizedFont(fontStyle->mFont);
   // Create a font group working in units of CSS pixels instead of the usual
   // device pixels, to avoid being affected by page zoom. nsFontMetrics will
   // convert nsFont size in app units to device pixels for the font group, so
   // here we first apply to the size the equivalent of a conversion from device
   // pixels to CSS pixels, to adjust for the difference in expectations from
   // other nsFontMetrics clients.
--- a/dom/canvas/crashtests/crashtests.list
+++ b/dom/canvas/crashtests/crashtests.list
@@ -1,45 +1,45 @@
-asserts-if(stylo,1) load 0px-size-font-667225.html # bug 1324700
-asserts-if(stylo,1) load 0px-size-font-shadow.html # bug 1324700
+load 0px-size-font-667225.html
+load 0px-size-font-shadow.html
 load 360293-1.html
 load 421715-1.html
 load 553938-1.html
 load 647480.html
 load 727547.html
 load 729116.html
-asserts-if(stylo,1) load 745699-1.html # bug 1324700
+load 745699-1.html
 load 746813-1.html
 load 743499-negative-size.html
 skip-if(Android) load 745818-large-source.html # Bug XXX - Crashes Android mid-run w/o a stack
 load 767337-1.html
 load 779426.html
-asserts-if(stylo,1) skip-if(Android) load 780392-1.html # bug 1324700
+skip-if(Android) load 780392-1.html
 skip-if(Android) skip-if(gtkWidget&&isDebugBuild) load 789933-1.html # bug 1155252 for linux
 load 794463-1.html
 load 802926-1.html
 load 896047-1.html
 load 916128-1.html
 load 934939-1.html
-asserts-if(stylo,1) load 1099143-1.html # bug 1324700
+load 1099143-1.html
 load 1161277-1.html
 load 1183363.html
-asserts-if(stylo,1) load 1190705.html # bug 1324700
-asserts-if(stylo,1) load 1223740-1.html # bug 1324700
-asserts-if(stylo,1) load 1225381-1.html # bug 1324700
+load 1190705.html
+load 1223740-1.html
+load 1225381-1.html
 skip-if(azureCairo) load 1229983-1.html
-asserts-if(stylo,1) load 1229932-1.html # bug 1324700
+load 1229932-1.html
 load 1244850-1.html
 load 1246775-1.html
-asserts-if(stylo,1) load 1284356-1.html # bug 1324700
+load 1284356-1.html
 load 1284578-1.html
 skip-if(d2d) load 1287515-1.html
-asserts-if(stylo,1) load 1287652-1.html # bug 1324700
-asserts-if(stylo,1) load 1288872-1.html # bug 1324700
+load 1287652-1.html
+load 1288872-1.html
 load 1290628-1.html
-asserts-if(stylo,1) load 1283113-1.html # bug 1324700
+load 1283113-1.html
 load 1286458-1.html
 load 1299062-1.html
 load 1305312-1.html
 load 1298576-1.html
-asserts-if(stylo,1) load 1334366-1.html # bug 1324700
+load 1334366-1.html
 load 1334647-1.html
 
--- a/dom/canvas/test/reftest/filters/reftest-stylo.list
+++ b/dom/canvas/test/reftest/filters/reftest-stylo.list
@@ -1,31 +1,31 @@
 # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
 default-preferences pref(canvas.filters.enabled,true)
 
-fails asserts-if(stylo,2) == default-color.html default-color.html # bug 1324700
-fails asserts-if(stylo,2) == drop-shadow.html drop-shadow.html # bug 1324700
-fails asserts-if(stylo,2) == drop-shadow-transformed.html drop-shadow-transformed.html # bug 1324700
-fails asserts-if(stylo,2) == global-alpha.html global-alpha.html # bug 1324700
-fails asserts-if(stylo,2) == global-composite-operation.html global-composite-operation.html # bug 1324700
-fails asserts-if(stylo,1) == liveness.html liveness.html # bug 1324700
-fails asserts-if(stylo,2) == multiple-drop-shadows.html multiple-drop-shadows.html # bug 1324700
-fails asserts-if(stylo,2) == shadow.html shadow.html # bug 1324700
-fails asserts-if(stylo,2) == subregion-fill-paint.html subregion-fill-paint.html # bug 1324700
-fails asserts-if(stylo,2) == subregion-stroke-paint.html subregion-stroke-paint.html # bug 1324700
-fails asserts-if(stylo,2) == svg-bbox.html svg-bbox.html # bug 1324700
-fails asserts-if(stylo,2) == svg-inline.html svg-inline.html # bug 1324700
-fails asserts-if(stylo,2) == svg-liveness.html svg-liveness.html # bug 1324700
-fails asserts-if(stylo,2) == svg-off-screen.html svg-off-screen.html # bug 1324700
-fails asserts-if(stylo,2) == units.html units.html # bug 1324700
-fails asserts-if(stylo,1) == units-em.html units-em.html # bug 1324700
-fails asserts-if(stylo,1) == units-ex.html units-ex.html # bug 1324700
-fails asserts-if(stylo,2) == units-off-screen.html units-off-screen.html # bug 1324700
-fails asserts-if(stylo,2) == fillText-with-filter-opacity-1.html fillText-with-filter-opacity-1.html # bug 1324700
-fails asserts-if(stylo,2) == fillText-with-filter-opacity-2.html fillText-with-filter-opacity-2.html # bug 1324700
-fails asserts-if(stylo,2) == strokeText-with-filter-grayscale-1.html strokeText-with-filter-grayscale-1.html # bug 1324700
-fails asserts-if(stylo,2) == strokeText-with-filter-grayscale-2.html strokeText-with-filter-grayscale-2.html # bug 1324700
-fails asserts-if(stylo,1) == fillText-with-shadow-1.html fillText-with-shadow-1.html # bug 1324700
-fails asserts-if(stylo,1) == fillText-with-shadow-2.html fillText-with-shadow-2.html # bug 1324700
-fails asserts-if(stylo,2) == fillText-with-filter-grayscale-1.html fillText-with-filter-grayscale-1.html # bug 1324700
-fails asserts-if(stylo,2) == fillText-with-filter-grayscale-2.html fillText-with-filter-grayscale-2.html # bug 1324700
-fails asserts-if(stylo,1) == strokeText-with-shadow-1.html strokeText-with-shadow-1.html # bug 1324700
-fails asserts-if(stylo,1) == strokeText-with-shadow-2.html strokeText-with-shadow-2.html # bug 1324700
+== default-color.html default-color.html
+== drop-shadow.html drop-shadow.html
+== drop-shadow-transformed.html drop-shadow-transformed.html
+== global-alpha.html global-alpha.html
+== global-composite-operation.html global-composite-operation.html
+== liveness.html liveness.html
+== multiple-drop-shadows.html multiple-drop-shadows.html
+== shadow.html shadow.html
+== subregion-fill-paint.html subregion-fill-paint.html
+== subregion-stroke-paint.html subregion-stroke-paint.html
+== svg-bbox.html svg-bbox.html
+== svg-inline.html svg-inline.html
+== svg-liveness.html svg-liveness.html
+== svg-off-screen.html svg-off-screen.html
+== units.html units.html
+== units-em.html units-em.html
+== units-ex.html units-ex.html
+== units-off-screen.html units-off-screen.html
+== fillText-with-filter-opacity-1.html fillText-with-filter-opacity-1.html
+== fillText-with-filter-opacity-2.html fillText-with-filter-opacity-2.html
+== strokeText-with-filter-grayscale-1.html strokeText-with-filter-grayscale-1.html
+== strokeText-with-filter-grayscale-2.html strokeText-with-filter-grayscale-2.html
+== fillText-with-shadow-1.html fillText-with-shadow-1.html
+== fillText-with-shadow-2.html fillText-with-shadow-2.html
+== fillText-with-filter-grayscale-1.html fillText-with-filter-grayscale-1.html
+== fillText-with-filter-grayscale-2.html fillText-with-filter-grayscale-2.html
+== strokeText-with-shadow-1.html strokeText-with-shadow-1.html
+== strokeText-with-shadow-2.html strokeText-with-shadow-2.html
--- a/dom/canvas/test/reftest/reftest-stylo.list
+++ b/dom/canvas/test/reftest/reftest-stylo.list
@@ -150,25 +150,25 @@ skip-if(!winWidget) pref(webgl.disable-a
 # Do we correctly handle multiple clip paths?
 == clip-multiple-paths.html clip-multiple-paths.html
 
 # Bug 1255062
 == clip-multiple-move-1.html clip-multiple-move-1.html
 == clip-multiple-move-2.html clip-multiple-move-2.html
 
 # Bug 815648
-fails asserts-if(stylo,1) == stroketext-shadow.html stroketext-shadow.html # bug 1324700
+== stroketext-shadow.html stroketext-shadow.html
 
 # focus rings
 pref(canvas.focusring.enabled,true) skip-if(cocoaWidget) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded.html
 pref(canvas.customfocusring.enabled,true) skip-if(Android||cocoaWidget||winWidget) fuzzy-if(gtkWidget,64,410) needs-focus == drawCustomFocusRing.html drawCustomFocusRing.html
 
 # Check that captureStream() displays in a local video element
 == capturestream.html capturestream.html
 
-fails asserts-if(stylo,1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds.html # bug 1324700
+== 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds.html
 
 # Canvas Filter Reftests
 include filters/reftest-stylo.list
 
 # Bug 1305963
 == mozCurrentTransform.html mozCurrentTransform.html
 == mozCurrentTransformInverse.html mozCurrentTransformInverse.html
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -23,16 +23,17 @@
 #include "mozilla/gfx/gfxVars.h"
 #include "nsAutoPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIGfxInfo.h"
 #include "nsIWindowsRegKey.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWindowsHelpers.h"
 #include "prsystem.h"
+#include "nsIXULRuntime.h"
 
 namespace mozilla {
 
 static Atomic<bool> sDXVAEnabled(false);
 
 WMFDecoderModule::~WMFDecoderModule()
 {
   if (mWMFInitialized) {
@@ -40,17 +41,30 @@ WMFDecoderModule::~WMFDecoderModule()
     NS_ASSERTION(SUCCEEDED(hr), "MFShutdown failed");
   }
 }
 
 /* static */
 void
 WMFDecoderModule::Init()
 {
-  sDXVAEnabled = gfx::gfxVars::CanUseHardwareVideoDecoding();
+  if (XRE_IsContentProcess()) {
+    // If we're in the content process and the UseGPUDecoder pref is set, it
+    // means that we've given up on the GPU process (it's been crashing) so we
+    // should disable DXVA
+    sDXVAEnabled = !MediaPrefs::PDMUseGPUDecoder();
+  } else if (XRE_IsGPUProcess()) {
+    // Always allow DXVA in the GPU process.
+    sDXVAEnabled = true;
+  } else {
+    // Only allow DXVA in the UI process if we aren't in e10s Firefox
+    sDXVAEnabled = !mozilla::BrowserTabsRemoteAutostart();
+  }
+
+  sDXVAEnabled = sDXVAEnabled && gfx::gfxVars::CanUseHardwareVideoDecoding();
 }
 
 /* static */
 int
 WMFDecoderModule::GetNumDecoderThreads()
 {
   int32_t numCores = PR_GetNumberOfProcessors();
 
--- a/gfx/2d/Triangle.h
+++ b/gfx/2d/Triangle.h
@@ -17,17 +17,16 @@ namespace gfx {
 
 /**
  * A simple triangle data structure.
  */
 template<class Units, class F = Float>
 struct TriangleTyped
 {
   PointTyped<Units, F> p1, p2, p3;
-  F width, height;
 
   TriangleTyped()
     : p1(), p2(), p3() {}
 
   TriangleTyped(PointTyped<Units, F> aP1,
                 PointTyped<Units, F> aP2,
                 PointTyped<Units, F> aP3)
     : p1(aP1), p2(aP2), p3(aP3) {}
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -46,16 +46,23 @@
 #include "mozilla/layers/UiCompositorControllerChild.h"
 #endif // defined(MOZ_WIDGET_ANDROID)
 
 namespace mozilla {
 namespace gfx {
 
 using namespace mozilla::layers;
 
+enum class FallbackType : uint32_t
+{
+  NONE = 0,
+  DECODINGDISABLED,
+  DISABLED,
+};
+
 static StaticAutoPtr<GPUProcessManager> sSingleton;
 
 GPUProcessManager*
 GPUProcessManager::Get()
 {
   return sSingleton;
 }
 
@@ -158,16 +165,19 @@ GPUProcessManager::DisableGPUProcess(con
     return;
   }
 
   gfxConfig::SetFailed(Feature::GPU_PROCESS, FeatureStatus::Failed, aMessage);
   gfxCriticalNote << aMessage;
 
   gfxPlatform::NotifyGPUProcessDisabled();
 
+  Telemetry::Accumulate(Telemetry::GPU_PROCESS_CRASH_FALLBACKS,
+                        uint32_t(FallbackType::DISABLED));
+
   DestroyProcess();
   ShutdownVsyncIOThread();
 }
 
 bool
 GPUProcessManager::EnsureGPUReady()
 {
   if (mProcess && !mProcess->IsConnected()) {
@@ -374,16 +384,24 @@ GPUProcessManager::OnProcessUnexpectedSh
 
   DestroyProcess();
 
   if (mNumProcessAttempts > uint32_t(gfxPrefs::GPUProcessMaxRestarts())) {
     char disableMessage[64];
     SprintfLiteral(disableMessage, "GPU process disabled after %d attempts",
                    mNumProcessAttempts);
     DisableGPUProcess(disableMessage);
+  } else if (mNumProcessAttempts > uint32_t(gfxPrefs::GPUProcessMaxRestartsWithDecoder()) &&
+             mDecodeVideoOnGpuProcess) {
+    mDecodeVideoOnGpuProcess = false;
+    Telemetry::Accumulate(Telemetry::GPU_PROCESS_CRASH_FALLBACKS,
+                                     uint32_t(FallbackType::DECODINGDISABLED));
+  } else {
+    Telemetry::Accumulate(Telemetry::GPU_PROCESS_CRASH_FALLBACKS,
+                                     uint32_t(FallbackType::NONE));
   }
 
   HandleProcessLost();
 }
 
 void
 GPUProcessManager::HandleProcessLost()
 {
@@ -792,17 +810,19 @@ GPUProcessManager::CreateContentVRManage
   *aOutEndpoint = Move(childPipe);
   return true;
 }
 
 void
 GPUProcessManager::CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
                                                     ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndpoint)
 {
-  if (!EnsureGPUReady() || !MediaPrefs::PDMUseGPUDecoder()) {
+  if (!EnsureGPUReady() ||
+      !MediaPrefs::PDMUseGPUDecoder() ||
+      !mDecodeVideoOnGpuProcess) {
     return;
   }
 
   ipc::Endpoint<dom::PVideoDecoderManagerParent> parentPipe;
   ipc::Endpoint<dom::PVideoDecoderManagerChild> childPipe;
 
   nsresult rv = dom::PVideoDecoderManager::CreateEndpoints(
     mGPUChild->OtherPid(),
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -230,16 +230,18 @@ private:
   protected:
     ~Observer() {}
 
     GPUProcessManager* mManager;
   };
   friend class Observer;
 
 private:
+  bool mDecodeVideoOnGpuProcess = true;
+
   RefPtr<Observer> mObserver;
   ipc::TaskFactory<GPUProcessManager> mTaskFactory;
   RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
   uint64_t mNextLayerTreeId;
   uint64_t mNextResetSequenceNo;
   uint32_t mNumProcessAttempts;
 
   nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -297,26 +297,42 @@ GenerateTexturedTriangles(const gfx::Pol
       }
 
       MOZ_ASSERT(rect.width > 0.0f && rect.height > 0.0f);
       MOZ_ASSERT(intersection.width > 0.0f && intersection.height > 0.0f);
 
       // Since the texture was created for non-split geometry, we need to
       // update the texture coordinates to account for the split.
       gfx::TexturedTriangle t(triangle);
-      t.width = rect.width;
-      t.height = rect.height;
       UpdateTextureCoordinates(t, rect, intersection, texRect);
       texturedTriangles.AppendElement(Move(t));
     }
   }
 
   return texturedTriangles;
 }
 
+nsTArray<TexturedVertex>
+TexturedTrianglesToVertexArray(const nsTArray<gfx::TexturedTriangle>& aTriangles)
+{
+  const auto VertexFromPoints = [](const gfx::Point& p, const gfx::Point& t) {
+    return TexturedVertex { { p.x, p.y }, { t.x, t.y } };
+  };
+
+  nsTArray<TexturedVertex> vertices;
+
+  for (const gfx::TexturedTriangle& t : aTriangles) {
+    vertices.AppendElement(VertexFromPoints(t.p1, t.textureCoords.p1));
+    vertices.AppendElement(VertexFromPoints(t.p2, t.textureCoords.p2));
+    vertices.AppendElement(VertexFromPoints(t.p3, t.textureCoords.p3));
+  }
+
+  return vertices;
+}
+
 void
 Compositor::DrawPolygon(const gfx::Polygon& aPolygon,
                         const gfx::Rect& aRect,
                         const gfx::IntRect& aClipRect,
                         const EffectChain& aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect)
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -643,12 +643,21 @@ BlendOpIsMixBlendMode(gfx::CompositionOp
   case gfx::CompositionOp::OP_COLOR:
   case gfx::CompositionOp::OP_LUMINOSITY:
     return true;
   default:
     return false;
   }
 }
 
+struct TexturedVertex
+{
+  float position[2];
+  float texCoords[2];
+};
+
+nsTArray<TexturedVertex>
+TexturedTrianglesToVertexArray(const nsTArray<gfx::TexturedTriangle>& aTriangles);
+
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_COMPOSITOR_H */
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -45,22 +45,16 @@ namespace layers {
 
 static bool CanUsePartialPresents(ID3D11Device* aDevice);
 
 struct Vertex
 {
     float position[2];
 };
 
-struct TexturedVertex
-{
-    float position[2];
-    float texCoords[2];
-};
-
 // {1E4D7BEB-D8EC-4A0B-BF0A-63E6DE129425}
 static const GUID sDeviceAttachmentsD3D11 =
 { 0x1e4d7beb, 0xd8ec, 0x4a0b, { 0xbf, 0xa, 0x63, 0xe6, 0xde, 0x12, 0x94, 0x25 } };
 // {88041664-C835-4AA8-ACB8-7EC832357ED8}
 static const GUID sLayerManagerCount =
 { 0x88041664, 0xc835, 0x4aa8, { 0xac, 0xb8, 0x7e, 0xc8, 0x32, 0x35, 0x7e, 0xd8 } };
 
 const FLOAT sBlendFactor[] = { 0, 0, 0, 0 };
@@ -243,27 +237,18 @@ CompositorD3D11::UpdateDynamicVertexBuff
   D3D11_MAPPED_SUBRESOURCE resource {};
   hr = mContext->Map(mAttachments->mDynamicVertexBuffer, 0,
                      D3D11_MAP_WRITE_DISCARD, 0, &resource);
 
   if (Failed(hr, "map dynamic vertex buffer")) {
     return false;
   }
 
-  const auto vertexFromPoints = [](const gfx::Point& p, const gfx::Point& t) {
-    return TexturedVertex { { p.x, p.y }, { t.x, t.y } };
-  };
-
-  nsTArray<TexturedVertex> vertices;
-
-  for (const gfx::TexturedTriangle& t : aTriangles) {
-    vertices.AppendElement(vertexFromPoints(t.p1, t.textureCoords.p1));
-    vertices.AppendElement(vertexFromPoints(t.p2, t.textureCoords.p2));
-    vertices.AppendElement(vertexFromPoints(t.p3, t.textureCoords.p3));
-  }
+  const nsTArray<TexturedVertex> vertices =
+    TexturedTrianglesToVertexArray(aTriangles);
 
   memcpy(resource.pData, vertices.Elements(),
          vertices.Length() * sizeof(TexturedVertex));
 
   mContext->Unmap(mAttachments->mDynamicVertexBuffer, 0);
 
   return true;
 }
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -990,57 +990,59 @@ CompositorOGL::DrawQuad(const Rect& aRec
                         const EffectChain &aEffectChain,
                         Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect)
 {
   PROFILER_LABEL("CompositorOGL", "DrawQuad",
     js::ProfileEntry::Category::GRAPHICS);
 
-  DrawGeometry(aRect, aClipRect, aEffectChain,
+  DrawGeometry(aRect, aRect, aClipRect, aEffectChain,
                aOpacity, aTransform, aVisibleRect);
 }
 
 void
-CompositorOGL::DrawTriangle(const gfx::TexturedTriangle& aTriangle,
-                            const gfx::IntRect& aClipRect,
-                            const EffectChain& aEffectChain,
-                            gfx::Float aOpacity,
-                            const gfx::Matrix4x4& aTransform,
-                            const gfx::Rect& aVisibleRect)
+CompositorOGL::DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+                             const gfx::Rect& aRect,
+                             const gfx::IntRect& aClipRect,
+                             const EffectChain& aEffectChain,
+                             gfx::Float aOpacity,
+                             const gfx::Matrix4x4& aTransform,
+                             const gfx::Rect& aVisibleRect)
 {
-  PROFILER_LABEL("CompositorOGL", "DrawTriangle",
+  PROFILER_LABEL("CompositorOGL", "DrawTriangles",
     js::ProfileEntry::Category::GRAPHICS);
 
-  DrawGeometry(aTriangle, aClipRect, aEffectChain,
+  DrawGeometry(aTriangles, aRect, aClipRect, aEffectChain,
                aOpacity, aTransform, aVisibleRect);
 }
 
 template<typename Geometry>
 void
 CompositorOGL::DrawGeometry(const Geometry& aGeometry,
-                            const IntRect& aClipRect,
-                            const EffectChain &aEffectChain,
-                            Float aOpacity,
+                            const gfx::Rect& aRect,
+                            const gfx::IntRect& aClipRect,
+                            const EffectChain& aEffectChain,
+                            gfx::Float aOpacity,
                             const gfx::Matrix4x4& aTransform,
                             const gfx::Rect& aVisibleRect)
 {
   MOZ_ASSERT(mFrameInProgress, "frame not started");
   MOZ_ASSERT(mCurrentRenderTarget, "No destination");
 
   MakeCurrent();
 
   IntPoint offset = mCurrentRenderTarget->GetOrigin();
   IntSize size = mCurrentRenderTarget->GetSize();
 
   Rect renderBound(0, 0, size.width, size.height);
   renderBound.IntersectRect(renderBound, Rect(aClipRect));
   renderBound.MoveBy(offset);
 
-  Rect destRect = aTransform.TransformAndClipBounds(aGeometry, renderBound);
+  Rect destRect = aTransform.TransformAndClipBounds(aRect, renderBound);
 
   // XXX: This doesn't handle 3D transforms. It also doesn't handled rotated
   //      quads. Fix me.
   mPixelsFilled += destRect.width * destRect.height;
 
   // Do a simple culling if this rect is out of target buffer.
   // Inflate a small size to avoid some numerical imprecision issue.
   destRect.Inflate(1, 1);
@@ -1155,17 +1157,17 @@ CompositorOGL::DrawGeometry(const Geomet
     if (gl()->IsExtensionSupported(GLContext::NV_texture_barrier)) {
       // The NV_texture_barrier extension lets us read directly from the
       // backbuffer. Let's do that.
       // We need to tell OpenGL about this, so that it can make sure everything
       // on the GPU is happening in the right order.
       gl()->fTextureBarrier();
       mixBlendBackdrop = mCurrentRenderTarget->GetTextureHandle();
     } else {
-      gfx::IntRect rect = ComputeBackdropCopyRect(aGeometry, aClipRect,
+      gfx::IntRect rect = ComputeBackdropCopyRect(aRect, aClipRect,
                                                   aTransform, &backdropTransform);
       mixBlendBackdrop = CreateTexture(rect, true, mCurrentRenderTarget->GetFBO());
       createdMixBlendBackdropTexture = true;
     }
     program->SetBackdropTransform(backdropTransform);
   }
 
   program->SetRenderOffset(offset.x, offset.y);
@@ -1469,55 +1471,45 @@ CompositorOGL::DrawGeometry(const Geomet
   if (createdMixBlendBackdropTexture) {
     gl()->fDeleteTextures(1, &mixBlendBackdrop);
   }
 
   // in case rendering has used some other GL context
   MakeCurrent();
 
   LayerScope::DrawEnd(mGLContext, aEffectChain,
-                      aGeometry.width, aGeometry.height);
+                      aRect.width, aRect.height);
 }
 
 void
 CompositorOGL::BindAndDrawGeometry(ShaderProgramOGL* aProgram,
-                                   const gfx::Rect& aRect,
-                                   const gfx::Rect& aTextureRect)
+                                   const gfx::Rect& aRect)
 {
-  BindAndDrawQuad(aProgram, aRect, aTextureRect);
+  BindAndDrawQuad(aProgram, aRect);
 }
 
 void
 CompositorOGL::BindAndDrawGeometry(ShaderProgramOGL* aProgram,
-                                   const gfx::TexturedTriangle& aTriangle,
-                                   const gfx::Rect& aTextureRect)
+                                   const nsTArray<gfx::TexturedTriangle>& aTriangles)
 {
   NS_ASSERTION(aProgram->HasInitialized(), "Shader program not correctly initialized");
 
-  const gfx::TexturedTriangle& t = aTriangle;
-  const gfx::Triangle& tex = t.textureCoords;
+  const nsTArray<TexturedVertex> vertices = TexturedTrianglesToVertexArray(aTriangles);
 
-  GLfloat vertices[] = {
-    t.p1.x, t.p1.y, 0.0f, 1.0f, tex.p1.x, tex.p1.y,
-    t.p2.x, t.p2.y, 0.0f, 1.0f, tex.p2.x, tex.p2.y,
-    t.p3.x, t.p3.y, 0.0f, 1.0f, tex.p3.x, tex.p3.y
-  };
-
-  HeapCopyOfStackArray<GLfloat> verticesOnHeap(vertices);
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mTriangleVBO);
   mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER,
-                          verticesOnHeap.ByteLength(),
-                          verticesOnHeap.Data(),
+                          vertices.Length() * sizeof(TexturedVertex),
+                          vertices.Elements(),
                           LOCAL_GL_STREAM_DRAW);
 
-  const GLsizei stride = 6 * sizeof(GLfloat);
-  InitializeVAO(kCoordinateAttributeIndex, 4, stride, 0);
-  InitializeVAO(kTexCoordinateAttributeIndex, 2, stride, 4 * sizeof(GLfloat));
+  const GLsizei stride = 4 * sizeof(GLfloat);
+  InitializeVAO(kCoordinateAttributeIndex, 2, stride, 0);
+  InitializeVAO(kTexCoordinateAttributeIndex, 2, stride, 2 * sizeof(GLfloat));
 
-  mGLContext->fDrawArrays(LOCAL_GL_TRIANGLES, 0, 3);
+  mGLContext->fDrawArrays(LOCAL_GL_TRIANGLES, 0, vertices.Length());
 
   mGLContext->fDisableVertexAttribArray(kCoordinateAttributeIndex);
   mGLContext->fDisableVertexAttribArray(kTexCoordinateAttributeIndex);
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 }
 
 // |aRect| is the rectangle we want to draw to. We will draw it with
 // up to 4 draw commands if necessary to avoid wrapping.
@@ -1539,22 +1531,21 @@ CompositorOGL::BindAndDrawGeometryWithTe
                                             &layerRects,
                                             &textureRects);
 
   BindAndDrawQuads(aProg, rects, layerRects, textureRects);
 }
 
 void
 CompositorOGL::BindAndDrawGeometryWithTextureRect(ShaderProgramOGL *aProg,
-                                                  const gfx::TexturedTriangle& aTriangle,
+                                                  const nsTArray<gfx::TexturedTriangle>& aTriangles,
                                                   const gfx::Rect& aTexCoordRect,
                                                   TextureSource *aTexture)
 {
-  BindAndDrawGeometry(aProg, aTriangle,
-                      GetTextureCoordinates(aTexCoordRect, aTexture));
+  BindAndDrawGeometry(aProg, aTriangles);
 }
 
 void
 CompositorOGL::BindAndDrawQuads(ShaderProgramOGL *aProg,
                                 int aQuads,
                                 const Rect* aLayerRects,
                                 const Rect* aTextureRects)
 {
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -160,22 +160,23 @@ public:
 
   virtual void DrawQuad(const gfx::Rect& aRect,
                         const gfx::IntRect& aClipRect,
                         const EffectChain &aEffectChain,
                         gfx::Float aOpacity,
                         const gfx::Matrix4x4& aTransform,
                         const gfx::Rect& aVisibleRect) override;
 
-  virtual void DrawTriangle(const gfx::TexturedTriangle& aTriangle,
-                            const gfx::IntRect& aClipRect,
-                            const EffectChain& aEffectChain,
-                            gfx::Float aOpacity,
-                            const gfx::Matrix4x4& aTransform,
-                            const gfx::Rect& aVisibleRect) override;
+  virtual void DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+                             const gfx::Rect& aRect,
+                             const gfx::IntRect& aClipRect,
+                             const EffectChain& aEffectChain,
+                             gfx::Float aOpacity,
+                             const gfx::Matrix4x4& aTransform,
+                             const gfx::Rect& aVisibleRect) override;
 
   virtual bool SupportsLayerGeometry() const override;
 
   virtual void EndFrame() override;
 
   virtual bool SupportsPartialTextureUpdate() override;
 
   virtual bool CanUseCanvasLayerForSize(const gfx::IntSize &aSize) override
@@ -245,18 +246,19 @@ public:
 
   const ScreenPoint& GetScreenRenderOffset() const {
     return mRenderOffset;
   }
 
 private:
   template<typename Geometry>
   void DrawGeometry(const Geometry& aGeometry,
+                    const gfx::Rect& aRect,
                     const gfx::IntRect& aClipRect,
-                    const EffectChain &aEffectChain,
+                    const EffectChain& aEffectChain,
                     gfx::Float aOpacity,
                     const gfx::Matrix4x4& aTransform,
                     const gfx::Rect& aVisibleRect);
 
   void PrepareViewport(CompositingRenderTargetOGL *aRenderTarget);
 
   /** Widget associated with this compositor */
   LayoutDeviceIntSize mWidgetSize;
@@ -331,17 +333,17 @@ private:
 
   void ApplyPrimitiveConfig(ShaderConfigOGL& aConfig,
                             const gfx::Rect&)
   {
     aConfig.SetDynamicGeometry(false);
   }
 
   void ApplyPrimitiveConfig(ShaderConfigOGL& aConfig,
-                            const gfx::TexturedTriangle&)
+                            const nsTArray<gfx::TexturedTriangle>&)
   {
     aConfig.SetDynamicGeometry(true);
   }
 
   /**
    * Create a FBO backed by a texture.
    * Note that the texture target type will be
    * of the type returned by FBOTextureTarget; different
@@ -377,34 +379,30 @@ private:
     gfx::Rect layerRects[4];
     gfx::Rect textureRects[4];
     layerRects[0] = aLayerRect;
     textureRects[0] = aTextureRect;
     BindAndDrawQuads(aProg, 1, layerRects, textureRects);
   }
 
   void BindAndDrawGeometry(ShaderProgramOGL* aProgram,
-                           const gfx::Rect& aRect,
-                           const gfx::Rect& aTextureRect =
-                             gfx::Rect(0.0f, 0.0f, 1.0f, 1.0f));
+                           const gfx::Rect& aRect);
 
   void BindAndDrawGeometry(ShaderProgramOGL* aProgram,
-                           const gfx::TexturedTriangle& aTriangle,
-                           const gfx::Rect& aTextureRect =
-                             gfx::Rect(0.0f, 0.0f, 1.0f, 1.0f));
+                           const nsTArray<gfx::TexturedTriangle>& aTriangles);
 
   void BindAndDrawGeometryWithTextureRect(ShaderProgramOGL *aProg,
                                           const gfx::Rect& aRect,
                                           const gfx::Rect& aTexCoordRect,
                                           TextureSource *aTexture);
 
   void BindAndDrawGeometryWithTextureRect(ShaderProgramOGL *aProg,
-                                         const gfx::TexturedTriangle& aTriangle,
-                                         const gfx::Rect& aTexCoordRect,
-                                         TextureSource *aTexture);
+                                          const nsTArray<gfx::TexturedTriangle>& aTriangles,
+                                          const gfx::Rect& aTexCoordRect,
+                                          TextureSource *aTexture);
 
   void InitializeVAO(const GLuint aAttribIndex, const GLint aComponents,
                      const GLsizei aStride, const size_t aOffset);
 
   gfx::Rect GetTextureCoordinates(gfx::Rect textureRect,
                                   TextureSource* aTexture);
 
   /**
--- a/gfx/layers/opengl/OGLShaderProgram.cpp
+++ b/gfx/layers/opengl/OGLShaderProgram.cpp
@@ -189,17 +189,23 @@ ProgramProfileOGL::GetProfileFor(ShaderC
   vs << "uniform mat4 uLayerTransform;" << endl;
   if (aConfig.mFeatures & ENABLE_DEAA) {
     vs << "uniform mat4 uLayerTransformInverse;" << endl;
     vs << "uniform EDGE_PRECISION vec3 uSSEdges[4];" << endl;
     vs << "uniform vec2 uVisibleCenter;" << endl;
     vs << "uniform vec2 uViewportSize;" << endl;
   }
   vs << "uniform vec2 uRenderTargetOffset;" << endl;
-  vs << "attribute vec4 aCoord;" << endl;
+
+  if (!(aConfig.mFeatures & ENABLE_DYNAMIC_GEOMETRY)) {
+    vs << "attribute vec4 aCoord;" << endl;
+  } else {
+    vs << "attribute vec2 aCoord;" << endl;
+  }
+
   result.mAttributes.AppendElement(Pair<nsCString, GLuint> {"aCoord", 0});
 
   if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
     vs << "uniform mat4 uTextureTransform;" << endl;
     vs << "uniform vec4 uTextureRects[4];" << endl;
     vs << "varying vec2 vTexCoord;" << endl;
 
     if (aConfig.mFeatures & ENABLE_DYNAMIC_GEOMETRY) {
--- a/gfx/tests/crashtests/crashtests.list
+++ b/gfx/tests/crashtests/crashtests.list
@@ -26,17 +26,17 @@ skip-if(Android&&smallScreen) load 38522
 skip load 385228-2.svg  # bug 523255 / bug 385228
 load 385289-1.xhtml
 load 385417-1.html
 load 385417-2.html
 load 385423-1.html
 load 385423-2.html
 load 385719-1.html
 load 389326-1.html
-asserts-if(stylo,1) load 390476.html # bug 1324700
+load 390476.html
 load 393746-1.xhtml
 load 393749-1.html
 load 393822-1.html
 load 394384-1.html
 load 394246-1.html
 load 394246-2.html
 skip-if(Android) load 394751.xhtml # bug 922976
 load 395335-1.xhtml
@@ -98,17 +98,17 @@ load 662467-1.html
 load 665218.html
 load 675550-1.html
 load 686190-1.html
 load 691581-1.html
 load 693143-1.html
 load 696936-1.html
 load 699563-1.html
 load 710149-1.html
-asserts-if(stylo,1) load 766452-1.html # bug 1324700
+load 766452-1.html
 load 766452-2.html
 load 768079-1.html
 load 783041-1.html
 load 783041-2.html
 load 783041-3.html
 load 783041-4.html
 load 798853.html # bug 868792
 load 805760-1.html
@@ -118,17 +118,17 @@ load 839745-1.html
 load 856784-1.html
 load 893572-1.html
 load 893572-2.html
 load 893572-3.html
 load 893572-4.html
 pref(layers.force-active,true) load 914457-1.html
 load 944579.svg
 load 944579.html
-asserts-if(stylo,1) pref(security.fileuri.strict_origin_policy,false) load 950000.html # bug 1324700
+pref(security.fileuri.strict_origin_policy,false) load 950000.html
 load 1034403-1.html
 load 1056516.html
 load 1205900.html
 load 1134549-1.svg
 load balinese-letter-spacing.html
 load 1216832-1.html
 load 1225125-1.html
 load 1308394.html
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -2237,18 +2237,18 @@ gfxPlatform::InitAcceleration()
 
   if (Preferences::GetBool("media.hardware-video-decoding.enabled", false) &&
 #ifdef XP_WIN
     Preferences::GetBool("media.windows-media-foundation.use-dxva", true) &&
 #endif
       NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING,
                                                discardFailureId, &status))) {
       if (status == nsIGfxInfo::FEATURE_STATUS_OK || gfxPrefs::HardwareVideoDecodingForceEnabled()) {
-         sLayersSupportsHardwareVideoDecoding = true;
-    }
+        sLayersSupportsHardwareVideoDecoding = true;
+      }
   }
 
   sLayersAccelerationPrefsInitialized = true;
 
   if (XRE_IsParentProcess()) {
     Preferences::RegisterCallbackAndCall(VideoDecodingFailedChangedCallback,
                                          "media.hardware-video-decoding.failed");
     InitGPUProcessPrefs();
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -539,18 +539,20 @@ private:
   DECL_GFX_PREF(Live, "layers.effect.invert",                  LayersEffectInvert, bool, false);
   DECL_GFX_PREF(Once, "layers.enable-tiles",                   LayersTilesEnabled, bool, false);
   DECL_GFX_PREF(Live, "layers.flash-borders",                  FlashLayerBorders, bool, false);
   DECL_GFX_PREF(Once, "layers.force-shmem-tiles",              ForceShmemTiles, bool, false);
   DECL_GFX_PREF(Live, "layers.frame-counter",                  DrawFrameCounter, bool, false);
   DECL_GFX_PREF(Once, "layers.gpu-process.enabled",            GPUProcessEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.gpu-process.force-enabled",      GPUProcessForceEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.gpu-process.timeout_ms",         GPUProcessTimeoutMs, int32_t, 5000);
-  DECL_GFX_PREF(Live, "layers.gpu-process.max_restarts",       GPUProcessMaxRestarts, int32_t, 0);
+  DECL_GFX_PREF(Live, "layers.gpu-process.max_restarts",       GPUProcessMaxRestarts, int32_t, 1);
   DECL_GFX_PREF(Once, "layers.gpu-process.allow-software",     GPUProcessAllowSoftware, bool, false);
+  // Note: This pref will only be used if it is less than layers.gpu-process.max_restarts.
+  DECL_GFX_PREF(Live, "layers.gpu-process.max_restarts_with_decoder", GPUProcessMaxRestartsWithDecoder, int32_t, 0);
   DECL_GFX_PREF(Live, "layers.low-precision-buffer",           UseLowPrecisionBuffer, bool, false);
   DECL_GFX_PREF(Live, "layers.low-precision-opacity",          LowPrecisionOpacity, float, 1.0f);
   DECL_GFX_PREF(Live, "layers.low-precision-resolution",       LowPrecisionResolution, float, 0.25f);
   DECL_GFX_PREF(Live, "layers.max-active",                     MaxActiveLayers, int32_t, -1);
   DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false);
   DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1);
   DECL_GFX_PREF(Live, "layers.orientation.sync.timeout",       OrientationSyncMillis, uint32_t, (uint32_t)0);
   DECL_GFX_PREF(Once, "layers.prefer-opengl",                  LayersPreferOpenGL, bool, false);
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -21,19 +21,19 @@ include $(topsrcdir)/config/rules.mk
 ifneq ($(MOZ_WIDGET_TOOLKIT),android)
 #LIBS += ../contentproc/$(LIB_PREFIX)plugin-container.$(LIB_SUFFIX)
 endif
 
 ifeq ($(OS_ARCH),WINNT) #{
 # Note the manifest file exists in the tree, so we use the explicit filename
 # here.
 ifdef HAVE_64BIT_BUILD
-EXTRA_DEPS += plugin-container.exe.64.manifest
+$(RESFILE): plugin-container.exe.64.manifest
 else
-EXTRA_DEPS += plugin-container.exe.32.manifest
+$(RESFILE): plugin-container.exe.32.manifest
 endif
 endif #}
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
 
 libs::
 	$(NSINSTALL) -D $(DIST)/bin/$(PROGRAM).app
 	rsync -a -C --exclude '*.in' $(srcdir)/macbuild/Contents $(DIST)/bin/$(MOZ_CHILD_PROCESS_NAME).app 
--- a/ipc/app/plugin-container.exe.32.manifest
+++ b/ipc/app/plugin-container.exe.32.manifest
@@ -30,16 +30,17 @@
       <ms_asmv3:requestedPrivileges>
         <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
       </ms_asmv3:requestedPrivileges>
     </ms_asmv3:security>
   </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/ipc/app/plugin-container.exe.64.manifest
+++ b/ipc/app/plugin-container.exe.64.manifest
@@ -24,16 +24,17 @@
       <ms_asmv3:requestedPrivileges>
         <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
       </ms_asmv3:requestedPrivileges>
     </ms_asmv3:security>
   </ms_asmv3:trustInfo>
   <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
     <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>True/PM</dpiAware>
+      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2,PerMonitor</dpiAwareness>
     </ms_asmv3:windowsSettings>
   </ms_asmv3:application>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
     <application>
       <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
       <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -1,9 +1,8 @@
-
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=4 et sw=4 tw=99: */
 /* 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/. */
 
 #include "mozilla/Attributes.h"
 
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -75,23 +75,22 @@ public:
 #define LOAD_ERROR_NOCONTENT "ContentLength not available (not a local URL?)"
 #define LOAD_ERROR_BADCHARSET "Error converting to specified charset"
 #define LOAD_ERROR_BADREAD   "File Read Error."
 #define LOAD_ERROR_READUNDERFLOW "File Read Error (underflow.)"
 #define LOAD_ERROR_NOPRINCIPALS "Failed to get principals."
 #define LOAD_ERROR_NOSPEC "Failed to get URI spec.  This is bad."
 #define LOAD_ERROR_CONTENTTOOBIG "ContentLength is too large"
 
-mozJSSubScriptLoader::mozJSSubScriptLoader() : mSystemPrincipal(nullptr)
+mozJSSubScriptLoader::mozJSSubScriptLoader()
 {
 }
 
 mozJSSubScriptLoader::~mozJSSubScriptLoader()
 {
-    /* empty */
 }
 
 NS_IMPL_ISUPPORTS(mozJSSubScriptLoader, mozIJSSubScriptLoader)
 
 static void
 ReportError(JSContext* cx, const nsACString& msg)
 {
     NS_ConvertUTF8toUTF16 ucMsg(msg);
@@ -116,20 +115,20 @@ ReportError(JSContext* cx, const char* o
         spec.Assign("(unknown)");
 
     nsAutoCString msg(origMsg);
     msg.Append(": ");
     msg.Append(spec);
     ReportError(cx, msg);
 }
 
-bool
+static bool
 PrepareScript(nsIURI* uri,
               JSContext* cx,
-              RootedObject& targetObj,
+              HandleObject targetObj,
               const char* uriStr,
               const nsAString& charset,
               const char* buf,
               int64_t len,
               bool reuseGlobal,
               MutableHandleScript script,
               MutableHandleFunction function)
 {
@@ -179,50 +178,50 @@ PrepareScript(nsIURI* uri,
     AutoObjectVector envChain(cx);
     if (!JS_IsGlobalObject(targetObj) && !envChain.append(targetObj)) {
         return false;
     }
     return JS::CompileFunction(cx, envChain, options, nullptr, 0, nullptr,
                                buf, len, function);
 }
 
-bool
+static bool
 EvalScript(JSContext* cx,
-           RootedObject& target_obj,
+           HandleObject targetObj,
            MutableHandleValue retval,
            nsIURI* uri,
            bool cache,
-           RootedScript& script,
-           RootedFunction& function)
+           MutableHandleScript script,
+           HandleFunction function)
 {
     if (function) {
-        script = JS_GetFunctionScript(cx, function);
+        script.set(JS_GetFunctionScript(cx, function));
     }
 
     if (function) {
-        if (!JS_CallFunction(cx, target_obj, function, JS::HandleValueArray::empty(), retval)) {
+        if (!JS_CallFunction(cx, targetObj, function, JS::HandleValueArray::empty(), retval)) {
             return false;
         }
     } else {
-        if (JS_IsGlobalObject(target_obj)) {
+        if (JS_IsGlobalObject(targetObj)) {
             if (!JS_ExecuteScript(cx, script, retval)) {
                 return false;
             }
         } else {
             JS::AutoObjectVector envChain(cx);
-            if (!envChain.append(target_obj)) {
+            if (!envChain.append(targetObj)) {
                 return false;
             }
             if (!JS_ExecuteScript(cx, envChain, script, retval)) {
                 return false;
             }
         }
     }
 
-    JSAutoCompartment rac(cx, target_obj);
+    JSAutoCompartment rac(cx, targetObj);
     if (!JS_WrapValue(cx, retval)) {
         return false;
     }
 
     if (cache && !!script) {
         nsAutoCString cachePath;
         JSVersion version = JS_GetVersion(cx);
         cachePath.AppendPrintf("jssubloader/%d", version);
@@ -270,22 +269,22 @@ public:
         mozilla::HoldJSObjects(this);
     }
 
 private:
     virtual ~AsyncScriptLoader() {
         mozilla::DropJSObjects(this);
     }
 
-    RefPtr<nsIChannel>      mChannel;
-    Heap<JSObject*>           mTargetObj;
-    RefPtr<Promise>         mPromise;
-    nsString                  mCharset;
-    bool                      mReuseGlobal;
-    bool                      mCache;
+    RefPtr<nsIChannel> mChannel;
+    Heap<JSObject*> mTargetObj;
+    RefPtr<Promise> mPromise;
+    nsString mCharset;
+    bool mReuseGlobal;
+    bool mCache;
 };
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(AsyncScriptLoader)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncScriptLoader)
   NS_INTERFACE_MAP_ENTRY(nsIIncrementalStreamLoaderObserver)
 NS_INTERFACE_MAP_END
 
@@ -327,18 +326,18 @@ public:
     }
 
     void ResolvePromise(HandleValue aResolveValue) {
         mPromise->MaybeResolve(aResolveValue);
         mPromise = nullptr;
     }
 
 private:
-    AutoEntryScript&          mAutoEntryScript;
-    RefPtr<Promise>           mPromise;
+    AutoEntryScript& mAutoEntryScript;
+    RefPtr<Promise> mPromise;
     nsCOMPtr<nsIGlobalObject> mGlobalObject;
 };
 
 NS_IMETHODIMP
 AsyncScriptLoader::OnIncrementalData(nsIIncrementalStreamLoader* aLoader,
                                      nsISupports* aContext,
                                      uint32_t aDataLength,
                                      const uint8_t* aData,
@@ -379,42 +378,42 @@ AsyncScriptLoader::OnStreamComplete(nsII
     }
 
     RootedFunction function(cx);
     RootedScript script(cx);
     nsAutoCString spec;
     nsresult rv = uri->GetSpec(spec);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    RootedObject target_obj(cx, mTargetObj);
+    RootedObject targetObj(cx, mTargetObj);
 
-    if (!PrepareScript(uri, cx, target_obj, spec.get(), mCharset,
+    if (!PrepareScript(uri, cx, targetObj, spec.get(), mCharset,
                        reinterpret_cast<const char*>(aBuf), aLength,
                        mReuseGlobal, &script, &function))
     {
         return NS_OK;
     }
 
     JS::Rooted<JS::Value> retval(cx);
-    if (EvalScript(cx, target_obj, &retval, uri, mCache, script, function)) {
+    if (EvalScript(cx, targetObj, &retval, uri, mCache, &script, function)) {
         autoPromise.ResolvePromise(retval);
     }
 
     return NS_OK;
 }
 
 nsresult
 mozJSSubScriptLoader::ReadScriptAsync(nsIURI* uri, JSObject* targetObjArg,
                                       const nsAString& charset,
                                       nsIIOService* serv, bool reuseGlobal,
                                       bool cache, MutableHandleValue retval)
 {
-    RootedObject target_obj(RootingCx(), targetObjArg);
+    RootedObject targetObj(RootingCx(), targetObjArg);
 
-    nsCOMPtr<nsIGlobalObject> globalObject = xpc::NativeGlobal(target_obj);
+    nsCOMPtr<nsIGlobalObject> globalObject = xpc::NativeGlobal(targetObj);
     ErrorResult result;
 
     AutoJSAPI jsapi;
     if (NS_WARN_IF(!jsapi.Init(globalObject))) {
         return NS_ERROR_UNEXPECTED;
     }
 
     RefPtr<Promise> promise = Promise::Create(globalObject, result);
@@ -443,17 +442,17 @@ mozJSSubScriptLoader::ReadScriptAsync(ns
         return rv;
     }
 
     channel->SetContentType(NS_LITERAL_CSTRING("application/javascript"));
 
     RefPtr<AsyncScriptLoader> loadObserver =
         new AsyncScriptLoader(channel,
                               reuseGlobal,
-                              target_obj,
+                              targetObj,
                               charset,
                               cache,
                               promise);
 
     nsCOMPtr<nsIIncrementalStreamLoader> loader;
     rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), loadObserver);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -466,17 +465,17 @@ mozJSSubScriptLoader::ReadScript(nsIURI*
                                  const nsAString& charset, const char* uriStr,
                                  nsIIOService* serv, nsIPrincipal* principal,
                                  bool reuseGlobal, JS::MutableHandleScript script,
                                  JS::MutableHandleFunction function)
 {
     script.set(nullptr);
     function.set(nullptr);
 
-    RootedObject target_obj(cx, targetObjArg);
+    RootedObject targetObj(cx, targetObjArg);
 
     // We create a channel and call SetContentType, to avoid expensive MIME type
     // lookups (bug 632490).
     nsCOMPtr<nsIChannel> chan;
     nsCOMPtr<nsIInputStream> instream;
     nsresult rv;
     rv = NS_NewChannel(getter_AddRefs(chan),
                        uri,
@@ -510,17 +509,17 @@ mozJSSubScriptLoader::ReadScript(nsIURI*
         ReportError(cx, LOAD_ERROR_CONTENTTOOBIG, uri);
         return false;
     }
 
     nsCString buf;
     rv = NS_ReadInputStreamToString(instream, buf, len);
     NS_ENSURE_SUCCESS(rv, false);
 
-    return PrepareScript(uri, cx, target_obj, uriStr, charset,
+    return PrepareScript(uri, cx, targetObj, uriStr, charset,
                          buf.get(), len,
                          reuseGlobal,
                          script, function);
 }
 
 NS_IMETHODIMP
 mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
                                     HandleValue target,
@@ -528,18 +527,18 @@ mozJSSubScriptLoader::LoadSubScript(cons
                                     JSContext* cx,
                                     MutableHandleValue retval)
 {
     /*
      * Loads a local url and evals it into the current cx
      * Synchronous (an async version would be cool too.)
      *   url: The url to load.  Must be local so that it can be loaded
      *        synchronously.
-     *   target_obj: Optional object to eval the script onto (defaults to context
-     *               global)
+     *   targetObj: Optional object to eval the script onto (defaults to context
+     *              global)
      *   charset: Optional character set to use for reading
      *   returns: Whatever jsval the script pointed to by the url returns.
      * Should ONLY (O N L Y !) be called from JavaScript code.
      */
     LoadSubScriptOptions options(cx);
     options.charset = charset;
     options.target = target.isObject() ? &target.toObject() : nullptr;
     return DoLoadSubScriptWithOptions(url, options, cx, retval);
@@ -693,17 +692,17 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
                         principal, reusingGlobal, &script, &function))
         {
             return NS_OK;
         }
     } else {
         cache = nullptr;
     }
 
-    Unused << EvalScript(cx, targetObj, retval, uri, !!cache, script, function);
+    Unused << EvalScript(cx, targetObj, retval, uri, !!cache, &script, function);
     return NS_OK;
 }
 
 /**
   * Let us compile scripts from a URI off the main thread.
   */
 
 class ScriptPrecompiler : public nsIIncrementalStreamLoaderObserver
--- a/js/xpconnect/loader/mozJSSubScriptLoader.h
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.h
@@ -28,23 +28,23 @@ public:
 
     // all the interface method declarations...
     NS_DECL_ISUPPORTS
     NS_DECL_MOZIJSSUBSCRIPTLOADER
 
 private:
     virtual ~mozJSSubScriptLoader();
 
-    bool ReadScript(nsIURI* uri, JSContext* cx, JSObject* target_obj,
+    bool ReadScript(nsIURI* uri, JSContext* cx, JSObject* targetObj,
                     const nsAString& charset, const char* uriStr,
                     nsIIOService* serv, nsIPrincipal* principal,
                     bool reuseGlobal, JS::MutableHandleScript script,
                     JS::MutableHandleFunction function);
 
-    nsresult ReadScriptAsync(nsIURI* uri, JSObject* target_obj,
+    nsresult ReadScriptAsync(nsIURI* uri, JSObject* targetObj,
                              const nsAString& charset,
                              nsIIOService* serv, bool reuseGlobal,
                              bool cache, JS::MutableHandleValue retval);
 
     nsresult DoLoadSubScriptWithOptions(const nsAString& url,
                                         LoadSubScriptOptions& options,
                                         JSContext* cx,
                                         JS::MutableHandle<JS::Value> retval);
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -692,21 +692,16 @@ nsPresContext::AppUnitsPerDevPixelChange
 
 void
 nsPresContext::PreferenceChanged(const char* aPrefName)
 {
   nsDependentCString prefName(aPrefName);
   if (prefName.EqualsLiteral("layout.css.dpi") ||
       prefName.EqualsLiteral("layout.css.devPixelsPerPx")) {
 
-    // We can't use a separate observer, callback, or var cache
-    // Because they don't guarantee the order of function calls.
-    // We have to update the scale override value first.
-    nsIWidget::ScaleOverrideChanged();
-
     int32_t oldAppUnitsPerDevPixel = AppUnitsPerDevPixel();
     if (mDeviceContext->CheckDPIChange() && mShell) {
       nsCOMPtr<nsIPresShell> shell = mShell;
       // Re-fetch the view manager's window dimensions in case there's a deferred
       // resize which hasn't affected our mVisibleArea yet
       nscoord oldWidthAppUnits, oldHeightAppUnits;
       RefPtr<nsViewManager> vm = shell->GetViewManager();
       if (!vm) {
--- a/layout/reftests/canvas/reftest-stylo.list
+++ b/layout/reftests/canvas/reftest-stylo.list
@@ -4,70 +4,70 @@ fails == size-1.html size-1.html
 
 == empty-transaction-1.html empty-transaction-1.html
 
 == image-rendering-test.html image-rendering-test.html
 == image-shadow.html image-shadow.html
 
 fails == size-change-1.html size-change-1.html
 
-asserts-if(stylo,1) == subpixel-1.html subpixel-1.html # bug 1324700
+== subpixel-1.html subpixel-1.html
 
-asserts-if(stylo,1) == text-ltr-left.html text-ltr-left.html # bug 1324700
-asserts-if(stylo,1) == text-ltr-right.html text-ltr-right.html # bug 1324700
-asserts-if(stylo,1) == text-rtl-left.html text-rtl-left.html # bug 1324700
-asserts-if(stylo,1) == text-rtl-right.html text-rtl-right.html # bug 1324700
+== text-ltr-left.html text-ltr-left.html
+== text-ltr-right.html text-ltr-right.html
+== text-rtl-left.html text-rtl-left.html
+== text-rtl-right.html text-rtl-right.html
 
-asserts-if(stylo,1) == text-ltr-start.html text-ltr-start.html # bug 1324700
-asserts-if(stylo,1) == text-ltr-end.html text-ltr-end.html # bug 1324700
-asserts-if(stylo,1) == text-ltr-left.html text-ltr-left.html # bug 1324700
-asserts-if(stylo,1) == text-rtl-start.html text-rtl-start.html # bug 1324700
-asserts-if(stylo,1) == text-rtl-end.html text-rtl-end.html # bug 1324700
-asserts-if(stylo,1) == text-rtl-left.html text-rtl-left.html # bug 1324700
+== text-ltr-start.html text-ltr-start.html
+== text-ltr-end.html text-ltr-end.html
+== text-ltr-left.html text-ltr-left.html
+== text-rtl-start.html text-rtl-start.html
+== text-rtl-end.html text-rtl-end.html
+== text-rtl-left.html text-rtl-left.html
 
-asserts-if(stylo,1) == text-ltr-left.html text-ltr-left.html # bug 1324700
+== text-ltr-left.html text-ltr-left.html
 
-fails asserts-if(stylo,1) == text-ltr-alignment-test.html text-ltr-alignment-test.html # bug 1324700
-fails asserts-if(stylo,1) == text-rtl-alignment-test.html text-rtl-alignment-test.html # bug 1324700
+== text-ltr-alignment-test.html text-ltr-alignment-test.html
+== text-rtl-alignment-test.html text-rtl-alignment-test.html
 
-asserts-if(stylo,1) == text-horzline-with-bottom.html text-horzline-with-bottom.html # bug 1324700
-fails-if(azureSkia&&OSX>=1008) asserts-if(stylo,1) == text-horzline-with-top.html text-horzline-with-top.html # bug 1324700
+== text-horzline-with-bottom.html text-horzline-with-bottom.html
+fails-if(azureSkia&&OSX>=1008) == text-horzline-with-top.html text-horzline-with-top.html
 
-fails asserts-if(stylo,1) == text-big-stroke.html text-big-stroke.html # Bug 1324700
-fails asserts-if(stylo,1) == text-big-stroke.html text-big-stroke.html # Bug 1324700
+== text-big-stroke.html text-big-stroke.html
+== text-big-stroke.html text-big-stroke.html
 
-fails asserts-if(stylo,1) == text-context-state-test.html text-context-state-test.html # bug 1324700
-fails asserts-if(stylo,1) == text-font-inherit.html text-font-inherit.html # bug 1324700
-fails asserts-if(stylo,1) == text-space-replace-test.html text-space-replace-test.html # bug 1324700
+== text-context-state-test.html text-context-state-test.html
+== text-font-inherit.html text-font-inherit.html
+== text-space-replace-test.html text-space-replace-test.html
 
-fails asserts-if(stylo,1) == text-no-frame-test.html text-no-frame-test.html # bug 1324700
-fails asserts-if(stylo,1) == text-no-frame-2-test.html text-no-frame-2-test.html # bug 1324700
-fails asserts-if(stylo,1) == text-not-in-doc-test.html text-not-in-doc-test.html # bug 1324700
+== text-no-frame-test.html text-no-frame-test.html
+== text-no-frame-2-test.html text-no-frame-2-test.html
+== text-not-in-doc-test.html text-not-in-doc-test.html
 
-fails asserts-if(stylo,1) == text-bidi-ltr-test.html text-bidi-ltr-test.html # Bug 1324700
-fails asserts-if(stylo,1) == text-bidi-ltr-test.html text-bidi-ltr-test.html # Bug 1324700
-fails asserts-if(stylo,1) == text-bidi-rtl-test.html text-bidi-rtl-test.html # bug 1324700
+== text-bidi-ltr-test.html text-bidi-ltr-test.html
+== text-bidi-ltr-test.html text-bidi-ltr-test.html
+== text-bidi-rtl-test.html text-bidi-rtl-test.html
 
-fails asserts-if(stylo,4) == text-font-lang.html text-font-lang.html # bug 1324700
+== text-font-lang.html text-font-lang.html
 
-fails asserts-if(stylo,1) == text-measure.html text-measure.html # bug 1324700
-fails asserts-if(stylo,1) == text-small-caps-1.html text-small-caps-1.html # bug 1324700
+== text-measure.html text-measure.html
+== text-small-caps-1.html text-small-caps-1.html
 
-fails asserts-if(stylo,1) == text-subpixel-1.html text-subpixel-1.html # bug 1324700
+== text-subpixel-1.html text-subpixel-1.html
 
-fails asserts-if(stylo,1) == strokeText-path.html strokeText-path.html # bug 1324700
+== strokeText-path.html strokeText-path.html
 
 # check that emoji character renders as something non-blank (for Apple Color Emoji font, bug 715798)
 # apparently fails on some 10.7 systems for unknown reasons, bug 804522.
 ## Currently fails most places due to partial backout of bug 808288, see bug 837461.
 ## (Marking "random" rather than "fails" because it would pass for people
 ## if they have an Emoji font installed when running the tests.)
 ## WAS: random-if(OSX==1007) == text-emoji.html text-emoji.html
 # With Skia canvas on OS X (bug 932958) it fails even on 10.8 and 10.10.
-random-if(cocoaWidget&&azureSkia) random-if(!cocoaWidget||OSX==1006||OSX==1007) asserts-if(stylo,1) == text-emoji.html text-emoji.html # bug 1324700
+random-if(cocoaWidget&&azureSkia) random-if(!cocoaWidget||OSX==1006||OSX==1007) == text-emoji.html text-emoji.html
 
 # azure quartz uses CGDrawLinearGradient instead of DrawShading
 # so we have less control over degenerate behaviour as tested by this
 # test
 fails-if((azureSkia&&!azureSkiaGL)||(azureSkiaGL&&Android)) skip-if(stylo) == linear-gradient-1a.html linear-gradient-1a.html # Too random.
 
 # this passes with cairo on 10.7 and 10.8 but not with azure for reasons unknown
 fails-if((azureSkia&&!azureSkiaGL)||(azureSkiaGL&&Android)) skip-if(stylo) == linear-gradient-1b.html linear-gradient-1b.html # Too random.
@@ -82,36 +82,36 @@ fails-if((azureSkia&&!azureSkiaGL)||(azu
 
 == ctm-sanity.html ctm-sanity.html
 == ctm-singular-sanity.html ctm-singular-sanity.html
 == ctm-1.html ctm-1.html
 
 == 672646-alpha-radial-gradient.html 672646-alpha-radial-gradient.html
 == 674003-alpha-radial-gradient-superlum.html 674003-alpha-radial-gradient-superlum.html
 
-fails asserts-if(stylo,1) == 693610-1.html 693610-1.html # bug 1324700
+== 693610-1.html 693610-1.html
 
 == 726951-shadow-clips.html 726951-shadow-clips.html
 
 == transformed-clip.html transformed-clip.html
 fuzzy-if(azureSkia,1,15) fuzzy-if(skiaContent,1,20) == transformed-gradient.html transformed-gradient.html
 == transformed-path.html transformed-path.html
 
 == 749467-1.html 749467-1.html
 
 # You get a little bit of rounding fuzz on OSX from transforming the paths between user space and device space
 == 784573-1.html 784573-1.html
 
-fails asserts-if(stylo,1) == 802658-1.html 802658-1.html # bug 1324700
+== 802658-1.html 802658-1.html
 == 1074733-1.html 1074733-1.html
-fails asserts-if(stylo,1) == 1107096-invisibles.html 1107096-invisibles.html # bug 1324700
+== 1107096-invisibles.html 1107096-invisibles.html
 == 1151821-1.html 1151821-1.html
 == 1201272-1.html 1201272-1.html
 == 1224976-1.html 1224976-1.html
 == 1238795-1.html 1238795-1.html
 == 1303534-1.html 1303534-1.html
 
-fails asserts-if(stylo,1) == 1304353-text-global-alpha-1.html 1304353-text-global-alpha-1.html # bug 1324700
-fails asserts-if(stylo,1) == 1304353-text-global-alpha-2.html 1304353-text-global-alpha-2.html # bug 1324700
-fails asserts-if(stylo,1) == 1304353-text-global-composite-op-1.html 1304353-text-global-composite-op-1.html # bug 1324700
+== 1304353-text-global-alpha-1.html 1304353-text-global-alpha-1.html
+== 1304353-text-global-alpha-2.html 1304353-text-global-alpha-2.html
+== 1304353-text-global-composite-op-1.html 1304353-text-global-composite-op-1.html
 
 skip-if(stylo) == text-indent-1a.html text-indent-1a.html # Bug 1347410
 == text-indent-1b.html text-indent-1b.html
--- a/layout/reftests/css-grid/reftest-stylo.list
+++ b/layout/reftests/css-grid/reftest-stylo.list
@@ -13,18 +13,18 @@ fails == grid-placement-auto-row-dense-0
 fails == grid-placement-auto-col-sparse-001.html grid-placement-auto-col-sparse-001.html
 fails == grid-placement-auto-col-dense-001.html grid-placement-auto-col-dense-001.html
 fails == grid-placement-implicit-named-areas-001.html grid-placement-implicit-named-areas-001.html
 fails == grid-placement-named-lines-001.html grid-placement-named-lines-001.html
 fails == grid-placement-named-lines-002.html grid-placement-named-lines-002.html
 fails == grid-placement-named-lines-003.html grid-placement-named-lines-003.html
 fails == grid-track-sizing-001.html grid-track-sizing-001.html
 fails == grid-track-sizing-002.html grid-track-sizing-002.html
-fails == grid-abspos-items-001.html grid-abspos-items-001.html
-fails == grid-abspos-items-002.html grid-abspos-items-002.html
+== grid-abspos-items-001.html grid-abspos-items-001.html
+== grid-abspos-items-002.html grid-abspos-items-002.html
 fails == grid-abspos-items-003.html grid-abspos-items-003.html
 fails == grid-abspos-items-004.html grid-abspos-items-004.html
 fails == grid-abspos-items-005.html grid-abspos-items-005.html
 fails == grid-abspos-items-006.html grid-abspos-items-006.html
 fails == grid-abspos-items-007.html grid-abspos-items-007.html
 fails == grid-abspos-items-008.html grid-abspos-items-008.html
 fails == grid-abspos-items-009.html grid-abspos-items-009.html
 fails == grid-abspos-items-010.html grid-abspos-items-010.html
@@ -34,17 +34,17 @@ fails == grid-abspos-items-013.html grid
 fails == grid-abspos-items-014.html grid-abspos-items-014.html
 fails == grid-abspos-items-015.html grid-abspos-items-015.html
 fails == grid-order-abspos-items-001.html grid-order-abspos-items-001.html
 fails == grid-order-placement-auto-001.html grid-order-placement-auto-001.html
 fails == grid-order-placement-definite-001.html grid-order-placement-definite-001.html
 fails skip-if(Android) == grid-placement-definite-implicit-001.html grid-placement-definite-implicit-001.html
 fails == grid-placement-definite-implicit-002.html grid-placement-definite-implicit-002.html
 fails skip-if(Android) fuzzy-if(winWidget,1,32) == grid-placement-auto-implicit-001.html grid-placement-auto-implicit-001.html
-fails == grid-placement-abspos-implicit-001.html grid-placement-abspos-implicit-001.html
+== grid-placement-abspos-implicit-001.html grid-placement-abspos-implicit-001.html
 fails == rtl-grid-placement-definite-001.html rtl-grid-placement-definite-001.html
 fails == rtl-grid-placement-auto-row-sparse-001.html rtl-grid-placement-auto-row-sparse-001.html
 fails == vlr-grid-placement-auto-row-sparse-001.html vlr-grid-placement-auto-row-sparse-001.html
 fails == vrl-grid-placement-auto-row-sparse-001.html vrl-grid-placement-auto-row-sparse-001.html
 fails == grid-relpos-items-001.html grid-relpos-items-001.html
 fails == grid-item-sizing-percent-001.html grid-item-sizing-percent-001.html
 fails == grid-item-sizing-px-001.html grid-item-sizing-px-001.html
 fails == grid-item-dir-001.html grid-item-dir-001.html
@@ -74,18 +74,18 @@ fails == grid-track-intrinsic-sizing-001
 fails == grid-track-intrinsic-sizing-002.html grid-track-intrinsic-sizing-002.html
 fails == grid-track-intrinsic-sizing-003.html grid-track-intrinsic-sizing-003.html
 fails == grid-track-intrinsic-sizing-004.html grid-track-intrinsic-sizing-004.html
 fails == grid-track-percent-sizing-001.html grid-track-percent-sizing-001.html
 fails == grid-track-fit-content-sizing-001.html grid-track-fit-content-sizing-001.html
 fails == grid-track-fit-content-sizing-002.html grid-track-fit-content-sizing-002.html
 fails == grid-max-sizing-flex-001.html grid-max-sizing-flex-001.html
 fails == grid-max-sizing-flex-002.html grid-max-sizing-flex-002.html
-fails == grid-max-sizing-flex-003.html grid-max-sizing-flex-003.html
-fails == grid-max-sizing-flex-004.html grid-max-sizing-flex-004.html
+== grid-max-sizing-flex-003.html grid-max-sizing-flex-003.html
+== grid-max-sizing-flex-004.html grid-max-sizing-flex-004.html
 fails == grid-max-sizing-flex-005.html grid-max-sizing-flex-005.html
 fails == grid-max-sizing-flex-006.html grid-max-sizing-flex-006.html
 fails == grid-max-sizing-flex-007.html grid-max-sizing-flex-007.html
 fails == grid-max-sizing-flex-008.html grid-max-sizing-flex-008.html
 fails == grid-flex-min-sizing-001.html grid-flex-min-sizing-001.html
 fails == grid-flex-min-sizing-002.html grid-flex-min-sizing-002.html
 fails == grid-item-align-001.html grid-item-align-001.html
 fails == grid-item-align-002.html grid-item-align-002.html
@@ -127,17 +127,17 @@ fails == grid-item-self-baseline-001.htm
 fails == grid-item-content-baseline-001.html grid-item-content-baseline-001.html
 fails == grid-item-content-baseline-002.html grid-item-content-baseline-002.html
 fails == grid-item-mixed-baseline-001.html grid-item-mixed-baseline-001.html
 fails == grid-item-mixed-baseline-002.html grid-item-mixed-baseline-002.html
 random-if(http.oscpu!="Linux\u0020i686") == grid-item-mixed-baseline-003.html grid-item-mixed-baseline-003.html
 fails == grid-item-mixed-baseline-004.html grid-item-mixed-baseline-004.html
 fails == grid-align-content-001.html grid-align-content-001.html
 fails == grid-justify-content-001.html grid-justify-content-001.html
-fails skip-if(Android&&isDebugBuild) == grid-justify-content-002.html grid-justify-content-002.html
+skip-if(Android&&isDebugBuild) == grid-justify-content-002.html grid-justify-content-002.html
 fails skip-if(Android&&isDebugBuild) == grid-justify-content-003.html grid-justify-content-003.html
 fails == grid-container-baselines-001.html grid-container-baselines-001.html
 fails == grid-container-baselines-002.html grid-container-baselines-002.html
 fails == grid-container-baselines-003.html grid-container-baselines-003.html
 == grid-container-baselines-004.html grid-container-baselines-004.html
 fails skip-if(Android&&isDebugBuild) == grid-column-gap-001.html grid-column-gap-001.html
 fails == grid-column-gap-002.html grid-column-gap-002.html
 fails == grid-column-gap-003.html grid-column-gap-003.html
@@ -170,17 +170,17 @@ fails == grid-repeat-auto-fill-fit-003.h
 fails == grid-repeat-auto-fill-fit-004.html grid-repeat-auto-fill-fit-004.html
 fails == grid-repeat-auto-fill-fit-005.html grid-repeat-auto-fill-fit-005.html
 fails == grid-repeat-auto-fill-fit-006.html grid-repeat-auto-fill-fit-006.html
 fails == grid-repeat-auto-fill-fit-007.html grid-repeat-auto-fill-fit-007.html
 fails == grid-repeat-auto-fill-fit-008.html grid-repeat-auto-fill-fit-008.html
 fails == grid-repeat-auto-fill-fit-009.html grid-repeat-auto-fill-fit-009.html
 fails == grid-repeat-auto-fill-fit-010.html grid-repeat-auto-fill-fit-010.html
 fails == grid-repeat-auto-fill-fit-011.html grid-repeat-auto-fill-fit-011.html
-fails == grid-item-blockifying-001.html grid-item-blockifying-001.html
+== grid-item-blockifying-001.html grid-item-blockifying-001.html
 fails == grid-fragmentation-001.html grid-fragmentation-001.html
 fails == grid-fragmentation-002.html grid-fragmentation-002.html
 fails == grid-fragmentation-003.html grid-fragmentation-003.html
 fails == grid-fragmentation-004.html grid-fragmentation-004.html
 fails == grid-fragmentation-005.html grid-fragmentation-005.html
 fails == grid-fragmentation-006.html grid-fragmentation-006.html
 fails == grid-fragmentation-007.html grid-fragmentation-007.html
 fails == grid-fragmentation-008.html grid-fragmentation-008.html
--- a/layout/reftests/image-element/reftest-stylo.list
+++ b/layout/reftests/image-element/reftest-stylo.list
@@ -1,17 +1,17 @@
 # DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
 random == bug-364968.html bug-364968.html
 == bug-463204.html bug-463204.html
 == canvas-outside-document.html canvas-outside-document.html
 == mozsetimageelement-01.html mozsetimageelement-01.html
 == mozsetimageelement-02.html mozsetimageelement-02.html
 == image-outside-document-invalidate.html image-outside-document-invalidate.html
 == canvas-outside-document-invalidate-01.html canvas-outside-document-invalidate-01.html
-skip-if(stylo) == canvas-outside-document-invalidate-02.html canvas-outside-document-invalidate-02.html # Bug 1324700
+skip-if(stylo) == canvas-outside-document-invalidate-02.html canvas-outside-document-invalidate-02.html # Bug 1341761
 #fails with Skia due to Skia bug http://code.google.com/p/skia/issues/detail?id=568
 == element-paint-simple.html element-paint-simple.html # Bug 1341761
 == element-paint-repeated.html element-paint-repeated.html
 == element-paint-recursion.html element-paint-recursion.html
 HTTP(..) == element-paint-continuation.html element-paint-continuation.html
 fails == element-paint-transform-01.html element-paint-transform-01.html
 fails == element-paint-transform-02.html element-paint-transform-02.html
 == element-paint-background-size-01.html element-paint-background-size-01.html
--- a/layout/reftests/writing-mode/reftest-stylo.list
+++ b/layout/reftests/writing-mode/reftest-stylo.list
@@ -9,20 +9,20 @@ HTTP(..) == 1083848-2-inline-background.
 == 1083848-3-inline-background-repeat.html 1083848-3-inline-background-repeat.html
 == 1083892-1.html 1083892-1.html
 == 1086883-1a.html 1086883-1a.html
 == 1086883-1b.html 1086883-1b.html
 == 1088025-1.html 1088025-1.html
 == 1089388-1.html 1089388-1.html
 == 1089388-2.html 1089388-2.html
 == 1090159-1.html 1090159-1.html
-fails asserts-if(stylo,1) == 1090168-1.html 1090168-1.html
-fails asserts-if(stylo,1) == 1090168-1.html 1090168-1.html
-fails asserts-if(stylo,1) == 1090168-2.html 1090168-2.html # bug 1324700
-fails asserts-if(stylo,1) == 1090168-3.html 1090168-3.html # bug 1324700
+== 1090168-1.html 1090168-1.html
+== 1090168-1.html 1090168-1.html
+== 1090168-2.html 1090168-2.html
+== 1090168-3.html 1090168-3.html
 == 1091058-1.html 1091058-1.html
 fails == 1094434-1.html 1094434-1.html
 fails == 1094434-2.html 1094434-2.html
 == 1094914-1a.html 1094914-1a.html
 == 1094914-1b.html 1094914-1b.html
 == 1096224-1a.html 1096224-1a.html
 == 1096224-1b.html 1096224-1b.html
 == 1102175-1a.html 1102175-1a.html
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -65,16 +65,21 @@ SERVO_BINDING_FUNC(Servo_StyleSet_FillKe
                    RawServoStyleSetBorrowed set,
                    const nsACString* property,
                    nsTimingFunctionBorrowed timing_function,
                    ServoComputedValuesBorrowed computed_values,
                    RawGeckoKeyframeListBorrowedMut keyframe_list)
 SERVO_BINDING_FUNC(Servo_StyleSet_GetFontFaceRules, void,
                    RawServoStyleSetBorrowed set,
                    RawGeckoFontFaceRuleListBorrowedMut list)
+SERVO_BINDING_FUNC(Servo_StyleSet_ResolveForDeclarations,
+                   ServoComputedValuesStrong,
+                   RawServoStyleSetBorrowed set,
+                   ServoComputedValuesBorrowedOrNull parent_style,
+                   RawServoDeclarationBlockBorrowed declarations)
 
 // CSSRuleList
 SERVO_BINDING_FUNC(Servo_CssRules_ListTypes, void,
                    ServoCssRulesBorrowed rules,
                    nsTArrayBorrowed_uintptr_t result)
 SERVO_BINDING_FUNC(Servo_CssRules_InsertRule, nsresult,
                    ServoCssRulesBorrowed rules,
                    RawServoStyleSheetBorrowed sheet, const nsACString* rule,
@@ -119,17 +124,17 @@ SERVO_BINDING_FUNC(Servo_PageRule_GetSty
                    RawServoPageRuleBorrowed rule)
 SERVO_BINDING_FUNC(Servo_PageRule_SetStyle, void,
                    RawServoPageRuleBorrowed rule,
                    RawServoDeclarationBlockBorrowed declarations)
 
 // Animations API
 SERVO_BINDING_FUNC(Servo_ParseProperty,
                    RawServoDeclarationBlockStrong,
-                   const nsACString* property, const nsACString* value,
+                   nsCSSPropertyID property, const nsACString* value,
                    RawGeckoURLExtraData* data)
 SERVO_BINDING_FUNC(Servo_ParseEasing, bool,
                    const nsAString* easing,
                    RawGeckoURLExtraData* data,
                    nsTimingFunctionBorrowedMut output)
 SERVO_BINDING_FUNC(Servo_GetComputedKeyframeValues, void,
                    RawGeckoKeyframeListBorrowed keyframes,
                    ServoComputedValuesBorrowed style,
@@ -218,16 +223,19 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
                    RawGeckoURLExtraData* data,
                    mozilla::LengthParsingMode length_parsing_mode)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemoveProperty, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    const nsACString* property)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_RemovePropertyById, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_HasCSSWideKeyword, bool,
+                   RawServoDeclarationBlockBorrowed declarations,
+                   nsCSSPropertyID property)
 // Compose animation value for a given property.
 // |base_values| is nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>.
 // We use void* to avoid exposing nsRefPtrHashtable in FFI.
 SERVO_BINDING_FUNC(Servo_AnimationCompose, void,
                    RawServoAnimationValueMapBorrowed animation_values,
                    void* base_values,
                    nsCSSPropertyID property,
                    RawGeckoAnimationPropertySegmentBorrowed animation_segment,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -415,28 +415,36 @@ ServoStyleSet::ResolvePseudoElementStyle
 
   bool isBeforeOrAfter = aType == CSSPseudoElementType::before ||
                          aType == CSSPseudoElementType::after;
   return GetContext(computedValues.forget(), aParentContext, pseudoTag, aType,
                     isBeforeOrAfter ? aOriginatingElement : nullptr);
 }
 
 already_AddRefed<nsStyleContext>
-ServoStyleSet::ResolveTransientStyle(Element* aElement, CSSPseudoElementType aType)
+ServoStyleSet::ResolveTransientStyle(Element* aElement,
+                                     nsIAtom* aPseudoTag,
+                                     CSSPseudoElementType aPseudoType)
 {
-  nsIAtom* pseudoTag = nullptr;
-  if (aType != CSSPseudoElementType::NotPseudo) {
-    pseudoTag = nsCSSPseudoElements::GetPseudoAtom(aType);
-  }
+  RefPtr<ServoComputedValues> computedValues =
+    ResolveTransientServoStyle(aElement, aPseudoTag);
 
-  RefPtr<ServoComputedValues> computedValues =
-    ResolveStyleLazily(aElement, pseudoTag);
+  return GetContext(computedValues.forget(),
+                    nullptr,
+                    aPseudoTag,
+                    aPseudoType, nullptr);
+}
 
-  return GetContext(computedValues.forget(), nullptr, pseudoTag, aType,
-                    nullptr);
+already_AddRefed<ServoComputedValues>
+ServoStyleSet::ResolveTransientServoStyle(Element* aElement,
+                                          nsIAtom* aPseudoTag)
+{
+  PreTraverseSync();
+
+  return ResolveStyleLazily(aElement, aPseudoTag);
 }
 
 // aFlags is an nsStyleSet flags bitfield
 already_AddRefed<nsStyleContext>
 ServoStyleSet::ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
                                                   nsStyleContext* aParentContext,
                                                   uint32_t aFlags)
 {
@@ -911,9 +919,19 @@ ServoStyleSet::ResolveStyleLazily(Elemen
 
 bool
 ServoStyleSet::AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray)
 {
   Servo_StyleSet_GetFontFaceRules(mRawSet.get(), &aArray);
   return true;
 }
 
+already_AddRefed<ServoComputedValues>
+ServoStyleSet::ResolveForDeclarations(
+  ServoComputedValuesBorrowedOrNull aParentOrNull,
+  RawServoDeclarationBlockBorrowed aDeclarations)
+{
+  return Servo_StyleSet_ResolveForDeclarations(mRawSet.get(),
+                                               aParentOrNull,
+                                               aDeclarations).Consume();
+}
+
 bool ServoStyleSet::sInServoTraversal = false;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -156,19 +156,26 @@ public:
   ResolvePseudoElementStyle(dom::Element* aOriginatingElement,
                             mozilla::CSSPseudoElementType aType,
                             nsStyleContext* aParentContext,
                             dom::Element* aPseudoElement);
 
   // Resolves style for a (possibly-pseudo) Element without assuming that the
   // style has been resolved, and without worrying about setting the style
   // context up to live in the style context tree (a null parent is used).
+  // |aPeudoTag| and |aPseudoType| must match.
   already_AddRefed<nsStyleContext>
   ResolveTransientStyle(dom::Element* aElement,
-                        mozilla::CSSPseudoElementType aPseudoType);
+                        nsIAtom* aPseudoTag,
+                        CSSPseudoElementType aPseudoType);
+
+  // Similar to ResolveTransientStyle() but returns ServoComputedValues.
+  // Unlike ResolveServoStyle() this function calls PreTraverseSync().
+  already_AddRefed<ServoComputedValues>
+  ResolveTransientServoStyle(dom::Element* aElement, nsIAtom* aPseudoTag);
 
   // Get a style context for an anonymous box.  aPseudoTag is the pseudo-tag to
   // use and must be non-null.  It must be an anon box, and must be one that
   // inherits style from the given aParentContext.  aFlags is an nsStyleSet
   // flags bitfield.
   already_AddRefed<nsStyleContext>
   ResolveInheritingAnonymousBoxStyle(nsIAtom* aPseudoTag,
                                      nsStyleContext* aParentContext,
@@ -285,16 +292,25 @@ public:
                                const ServoComputedValuesWithParent&
                                  aServoValues);
 
   bool AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
 
   already_AddRefed<ServoComputedValues>
   GetBaseComputedValuesForElement(dom::Element* aElement, nsIAtom* aPseudoTag);
 
+  /**
+   * Resolve style for a given declaration block with/without the parent style.
+   * If the parent style is not specified, the document default computed values
+   * is used.
+   */
+  already_AddRefed<ServoComputedValues>
+  ResolveForDeclarations(ServoComputedValuesBorrowedOrNull aParentOrNull,
+                         RawServoDeclarationBlockBorrowed aDeclarations);
+
 private:
   already_AddRefed<nsStyleContext> GetContext(already_AddRefed<ServoComputedValues>,
                                               nsStyleContext* aParentContext,
                                               nsIAtom* aPseudoTag,
                                               CSSPseudoElementType aPseudoType,
                                               dom::Element* aElementForAnimation);
 
   already_AddRefed<nsStyleContext> GetContext(nsIContent* aContent,
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -97,17 +97,17 @@ load 822842.html
 load 827591-1.html
 load 829817.html
 load 840898.html
 load 842134.html
 load 861489-1.html
 load 862113.html
 load 867487.html
 load 873222.html
-asserts-if(stylo,1) load 880862.html # bug 1324701
+load 880862.html
 load 894245-1.html
 load 915440.html
 load 927734-1.html
 load 930270-1.html
 load 930270-2.html
 load 945048-1.html
 load 972199-1.html
 load 989965-1.html
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -615,17 +615,17 @@ nsComputedDOMStyle::DoGetStyleContextNoF
     if (type >= CSSPseudoElementType::Count) {
       return nullptr;
     }
   }
 
   // For Servo, compute the result directly without recursively building up
   // a throwaway style context chain.
   if (ServoStyleSet* servoSet = styleSet->GetAsServo()) {
-    return servoSet->ResolveTransientStyle(aElement, type);
+    return servoSet->ResolveTransientStyle(aElement, aPseudo, type);
   }
 
   RefPtr<nsStyleContext> parentContext;
   nsIContent* parent = aPseudo ? aElement : aElement->GetParent();
   // Don't resolve parent context for document fragments.
   if (parent && parent->IsElement()) {
     parentContext = GetStyleContextNoFlush(parent->AsElement(), nullptr,
                                            aPresShell);
--- a/layout/style/test/stylo-failures.md
+++ b/layout/style/test/stylo-failures.md
@@ -263,19 +263,19 @@ to mochitest command.
     * test_initial_storage.html `for property 'border-image-` [10]
     * test_value_storage.html `(for 'border-image-` [60]
   * -moz-alt-content parsing is wrong: servo/servo#15726
     * test_property_syntax_errors.html `-moz-alt-content` [4]
   * mask shorthand servo/servo#15772
     * test_property_syntax_errors.html `mask'` [76]
 * Incorrect serialization
   * border-radius and -moz-outline-radius shorthand servo/servo#15169
-    * test_priority_preservation.html `border-radius` [4]
-    * test_value_storage.html `border-radius:` [64]
-    * test_shorthand_property_getters.html `should condense to shortest possible` [6]
+    * test_priority_preservation.html `border-radius` [0]
+    * test_value_storage.html `border-radius:` [0]
+    * test_shorthand_property_getters.html `should condense to shortest possible` [0]
   * color value not canonicalized servo/servo#15397
     * test_shorthand_property_getters.html `should condense to canonical case` [2]
   * test_variables.html `--weird`: name of custom property is not escaped properly servo/servo#15399 [1]
   * :not(*) doesn't serialize properly servo/servo#16017
     * test_selectors.html `:not()` [8]
     * ... `:not(html|)` [1]
   * "*|a" gets serialized as "a" when it should not servo/servo#16020
     * test_selectors.html `reserialization of *|a` [6]
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -751,17 +751,21 @@ HttpChannelChild::OnTransportAndData(con
     mUnknownDecoderEventQ.AppendElement(
       MakeUnique<MaybeDivertOnDataHttpEvent>(this, data, offset, count));
   }
 
   // Hold queue lock throughout all three calls, else we might process a later
   // necko msg in between them.
   AutoEventEnqueuer ensureSerialDispatch(mEventQ);
 
-  const int64_t progressMax = mResponseHead->ContentLength();
+  int64_t progressMax;
+  if (NS_FAILED(GetContentLength(&progressMax))) {
+    progressMax = -1;
+  }
+
   const int64_t progress = offset + count;
 
   // OnTransportAndData will be run on retargeted thread if applicable, however
   // OnStatus/OnProgress event can only be fired on main thread. We need to
   // dispatch the status/progress event handling back to main thread with the
   // appropriate event target for networking.
   if (NS_IsMainThread()) {
     DoOnStatus(this, transportStatus);
rename from taskcluster/docker/recipes/tooltool.py
rename to python/mozbuild/mozbuild/action/tooltool.py
--- a/python/mozbuild/mozbuild/artifacts.py
+++ b/python/mozbuild/mozbuild/artifacts.py
@@ -37,16 +37,17 @@ A future need, perhaps.
 This module requires certain modules be importable from the ambient Python
 environment.  |mach artifact| ensures these modules are available, but other
 consumers will need to arrange this themselves.
 '''
 
 
 from __future__ import absolute_import, print_function, unicode_literals
 
+import binascii
 import collections
 import functools
 import glob
 import hashlib
 import logging
 import operator
 import os
 import pickle
@@ -65,16 +66,17 @@ from taskgraph.util.taskcluster import (
     find_task_id,
     get_artifact_url,
     list_artifacts,
 )
 
 from mozbuild.util import (
     ensureParentDir,
     FileAvoidWrite,
+    mkdir,
 )
 import mozinstall
 from mozpack.files import (
     JarFinder,
     TarFinder,
 )
 from mozpack.mozjar import (
     JarReader,
@@ -527,16 +529,17 @@ class CacheManager(object):
     Provide simple logging.
     '''
 
     def __init__(self, cache_dir, cache_name, cache_size, cache_callback=None, log=None, skip_cache=False):
         self._skip_cache = skip_cache
         self._cache = pylru.lrucache(cache_size, callback=cache_callback)
         self._cache_filename = mozpath.join(cache_dir, cache_name + '-cache.pickle')
         self._log = log
+        mkdir(cache_dir, not_indexed=True)
 
     def log(self, *args, **kwargs):
         if self._log:
             self._log(*args, **kwargs)
 
     def load_cache(self):
         if self._skip_cache:
             self.log(logging.DEBUG, 'artifact',
@@ -697,17 +700,18 @@ class ArtifactPersistLimit(PersistLimit)
         self._registering_dir = False
         self._downloaded_now = set()
 
     def log(self, *args, **kwargs):
         if self._log:
             self._log(*args, **kwargs)
 
     def register_file(self, path):
-        if path.endswith('.pickle'):
+        if path.endswith('.pickle') or \
+                os.path.basename(path) == '.metadata_never_index':
             return
         if not self._registering_dir:
             # Touch the file so that subsequent calls to a mach artifact
             # command know it was recently used. While remove_old_files
             # is based on access time, in various cases, the access time is not
             # updated when just reading the file, so we force an update.
             try:
                 os.utime(path, None)
@@ -746,36 +750,44 @@ class ArtifactPersistLimit(PersistLimit)
         self._files_size = 0
         self.files = []
 
 
 class ArtifactCache(object):
     '''Fetch Task Cluster artifact URLs and purge least recently used artifacts from disk.'''
 
     def __init__(self, cache_dir, log=None, skip_cache=False):
+        mkdir(cache_dir, not_indexed=True)
         self._cache_dir = cache_dir
         self._log = log
         self._skip_cache = skip_cache
         self._persist_limit = ArtifactPersistLimit(log)
         self._download_manager = DownloadManager(
             self._cache_dir, persist_limit=self._persist_limit)
         self._last_dl_update = -1
 
     def log(self, *args, **kwargs):
         if self._log:
             self._log(*args, **kwargs)
 
     def fetch(self, url, force=False):
-        # We download to a temporary name like HASH[:16]-basename to
-        # differentiate among URLs with the same basenames.  We used to then
-        # extract the build ID from the downloaded artifact and use it to make a
-        # human readable unique name, but extracting build IDs is time consuming
-        # (especially on Mac OS X, where we must mount a large DMG file).
-        hash = hashlib.sha256(url).hexdigest()[:16]
-        fname = hash + '-' + os.path.basename(url)
+        fname = os.path.basename(url)
+        try:
+            # Use the file name from the url if it looks like a hash digest.
+            if len(fname) not in (32, 40, 56, 64, 96, 128):
+                raise TypeError()
+            binascii.unhexlify(fname)
+        except TypeError:
+            # We download to a temporary name like HASH[:16]-basename to
+            # differentiate among URLs with the same basenames.  We used to then
+            # extract the build ID from the downloaded artifact and use it to make a
+            # human readable unique name, but extracting build IDs is time consuming
+            # (especially on Mac OS X, where we must mount a large DMG file).
+            hash = hashlib.sha256(url).hexdigest()[:16]
+            fname = hash + '-' + os.path.basename(url)
 
         path = os.path.abspath(mozpath.join(self._cache_dir, fname))
         if self._skip_cache and os.path.exists(path):
             self.log(logging.DEBUG, 'artifact',
                 {'path': path},
                 'Skipping cache: removing cached downloaded artifact {path}')
             os.remove(path)
 
--- a/python/mozbuild/mozbuild/frontend/reader.py
+++ b/python/mozbuild/mozbuild/frontend/reader.py
@@ -1438,17 +1438,17 @@ class BuildReader(object):
         for ctx in ctxs:
             for key in ctx:
                 if key not in test_manifest_contexts:
                     continue
                 for paths, obj in ctx[key]:
                     if isinstance(paths, tuple):
                         path, tests_root = paths
                         tests_root = mozpath.join(ctx.relsrcdir, tests_root)
-                        for t in (mozpath.join(tests_root, path) for path, _ in obj):
+                        for t in (mozpath.join(tests_root, it[0]) for it in obj):
                             result_context.test_files.add(mozpath.dirname(t) + '/**')
                     else:
                         for t in obj.tests:
                             if isinstance(t, tuple):
                                 path, _ = t
                                 relpath = mozpath.relpath(path,
                                                           self.config.topsrcdir)
                             else:
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -9,16 +9,18 @@ import errno
 import itertools
 import json
 import logging
 import operator
 import os
 import subprocess
 import sys
 
+from collections import OrderedDict
+
 import mozpack.path as mozpath
 
 from mach.decorators import (
     CommandArgument,
     CommandArgumentGroup,
     CommandProvider,
     Command,
     SubCommand,
@@ -1478,22 +1480,16 @@ class PackageFrontend(MachCommandBase):
 
     def _set_log_level(self, verbose):
         self.log_manager.terminal_handler.setLevel(logging.INFO if not verbose else logging.DEBUG)
 
     def _make_artifacts(self, tree=None, job=None, skip_cache=False):
         state_dir = self._mach_context.state_dir
         cache_dir = os.path.join(state_dir, 'package-frontend')
 
-        try:
-            os.makedirs(cache_dir)
-        except OSError as e:
-            if e.errno != errno.EEXIST:
-                raise
-
         import which
 
         here = os.path.abspath(os.path.dirname(__file__))
         build_obj = MozbuildObject.from_environment(cwd=here)
 
         hg = None
         if conditions.is_hg(build_obj):
             if self._is_windows():
@@ -1534,16 +1530,262 @@ class PackageFrontend(MachCommandBase):
     @ArtifactSubCommand('artifact', 'clear-cache',
         'Delete local artifacts and reset local artifact cache.')
     def artifact_clear_cache(self, tree=None, job=None, verbose=False):
         self._set_log_level(verbose)
         artifacts = self._make_artifacts(tree=tree, job=job)
         artifacts.clear_cache()
         return 0
 
+    @SubCommand('artifact', 'toolchain')
+    @CommandArgument('--verbose', '-v', action='store_true',
+        help='Print verbose output.')
+    @CommandArgument('--cache-dir', metavar='DIR',
+        help='Directory where to store the artifacts cache')
+    @CommandArgument('--skip-cache', action='store_true',
+        help='Skip all local caches to force re-fetching remote artifacts.',
+        default=False)
+    @CommandArgument('--from-build', metavar='BUILD', nargs='+',
+        help='Get toolchains resulting from the given build(s)')
+    @CommandArgument('--tooltool-manifest', metavar='MANIFEST',
+        help='Explicit tooltool manifest to process')
+    @CommandArgument('--authentication-file', metavar='FILE',
+        help='Use the RelengAPI token found in the given file to authenticate')
+    @CommandArgument('--tooltool-url', metavar='URL',
+        help='Use the given url as tooltool server')
+    @CommandArgument('--no-unpack', action='store_true',
+        help='Do not unpack any downloaded file')
+    @CommandArgument('--retry', type=int, default=0,
+        help='Number of times to retry failed downloads')
+    @CommandArgument('files', nargs='*',
+        help='Only download the given file names (you may use file name stems)')
+    def artifact_toolchain(self, verbose=False, cache_dir=None,
+                          skip_cache=False, from_build=(),
+                          tooltool_manifest=None, authentication_file=None,
+                          tooltool_url=None, no_unpack=False, retry=None,
+                          files=()):
+        '''Download, cache and install pre-built toolchains.
+        '''
+        from mozbuild.artifacts import ArtifactCache
+        from mozbuild.action.tooltool import (
+            FileRecord,
+            open_manifest,
+            unpack_file,
+        )
+        from requests.adapters import HTTPAdapter
+        import redo
+        import requests
+        import shutil
+
+        from taskgraph.generator import Kind
+        from taskgraph.optimize import optimize_task
+        from taskgraph.util.taskcluster import (
+            get_artifact_url,
+            list_artifacts,
+        )
+        import yaml
+
+        self._set_log_level(verbose)
+        # Normally, we'd use self.log_manager.enable_unstructured(),
+        # but that enables all logging, while we only really want tooltool's
+        # and it also makes structured log output twice.
+        # So we manually do what it does, and limit that to the tooltool
+        # logger.
+        if self.log_manager.terminal_handler:
+            logging.getLogger('mozbuild.action.tooltool').addHandler(
+                self.log_manager.terminal_handler)
+            logging.getLogger('redo').addHandler(
+                self.log_manager.terminal_handler)
+            self.log_manager.terminal_handler.addFilter(
+                self.log_manager.structured_filter)
+        if not cache_dir:
+            cache_dir = os.path.join(self._mach_context.state_dir, 'toolchains')
+
+        tooltool_url = (tooltool_url or
+                        'https://api.pub.build.mozilla.org/tooltool').rstrip('/')
+
+        cache = ArtifactCache(cache_dir=cache_dir, log=self.log,
+                              skip_cache=skip_cache)
+
+        if authentication_file:
+            with open(authentication_file, 'rb') as f:
+                token = f.read().strip()
+
+            class TooltoolAuthenticator(HTTPAdapter):
+                def send(self, request, *args, **kwargs):
+                    request.headers['Authorization'] = \
+                        'Bearer {}'.format(token)
+                    return super(TooltoolAuthenticator, self).send(
+                        request, *args, **kwargs)
+
+            cache._download_manager.session.mount(
+                tooltool_url, TooltoolAuthenticator())
+
+        class DownloadRecord(FileRecord):
+            def __init__(self, url, *args, **kwargs):
+                super(DownloadRecord, self).__init__(*args, **kwargs)
+                self.url = url
+                self.basename = self.filename
+
+            def fetch_with(self, cache):
+                self.filename = cache.fetch(self.url)
+                return self.filename
+
+            def validate(self):
+                if self.size is None and self.digest is None:
+                    return True
+                return super(DownloadRecord, self).validate()
+
+        records = OrderedDict()
+        downloaded = []
+
+        if tooltool_manifest:
+            manifest = open_manifest(tooltool_manifest)
+            for record in manifest.file_records:
+                url = '{}/{}/{}'.format(tooltool_url, record.algorithm,
+                                        record.digest)
+                records[record.filename] = DownloadRecord(
+                    url, record.filename, record.size, record.digest,
+                    record.algorithm, unpack=record.unpack,
+                    version=record.version, visibility=record.visibility,
+                    setup=record.setup)
+
+        if from_build:
+            params = {
+                'message': '',
+                'project': '',
+                'level': os.environ.get('MOZ_SCM_LEVEL', '3'),
+                'base_repository': '',
+                'head_repository': '',
+                'head_rev': '',
+                'moz_build_date': '',
+                'build_date': 0,
+                'pushlog_id': 0,
+                'owner': '',
+            }
+
+            # TODO: move to the taskcluster package
+            def tasks(kind):
+                kind_path = mozpath.join('taskcluster', 'ci', kind)
+                with open(mozpath.join(self.topsrcdir, kind_path, 'kind.yml')) as f:
+                    config = yaml.load(f)
+                    tasks = Kind(kind, kind_path, config).load_tasks(params, {})
+                    return {
+                        task.task['metadata']['name']: task
+                        for task in tasks
+                    }
+
+            toolchains = tasks('toolchain')
+
+            for b in from_build:
+                user_value = b
+
+                if '/' not in b:
+                    b = '{}/opt'.format(b)
+
+                if not b.startswith('toolchain-'):
+                    b = 'toolchain-{}'.format(b)
+
+                task = toolchains.get(b)
+                if not task:
+                    self.log(logging.ERROR, 'artifact', {'build': user_value},
+                             'Could not find a toolchain build named `{build}`')
+                    return 1
+
+                optimized, task_id = optimize_task(task, {})
+                if not optimized:
+                    self.log(logging.ERROR, 'artifact', {'build': user_value},
+                             'Could not find artifacts for a toolchain build '
+                             'named `{build}`')
+                    return 1
+
+                for artifact in list_artifacts(task_id):
+                    name = artifact['name']
+                    if not name.startswith('public/'):
+                        continue
+                    name = name[len('public/'):]
+                    if name.startswith('logs/'):
+                        continue
+                    records[name] = DownloadRecord(
+                        get_artifact_url(task_id, 'public/{}'.format(name)),
+                        name, None, None, None, unpack=True)
+
+        for record in records.itervalues():
+            if files and not any(record.basename == f or
+                                      record.basename.startswith('%s.' % f)
+                                      for f in files):
+                continue
+
+            self.log(logging.INFO, 'artifact', {'name': record.basename},
+                     'Downloading {name}')
+            valid = False
+            # sleeptime is 60 per retry.py, used by tooltool_wrapper.sh
+            for attempt, _ in enumerate(redo.retrier(attempts=retry+1,
+                                                     sleeptime=60)):
+                try:
+                    record.fetch_with(cache)
+                except requests.exceptions.HTTPError as e:
+                    status = e.response.status_code
+                    # The relengapi proxy likes to return error 400 bad request
+                    # which seems improbably to be due to our (simple) GET
+                    # being borked.
+                    should_retry = status >= 500 or status == 400
+                    if should_retry or attempt < retry:
+                        level = logging.WARN
+                    else:
+                        level = logging.ERROR
+                    self.log(level, 'artifact', {}, e.message)
+                    if not should_retry:
+                        break
+                    if attempt < retry:
+                        self.log(logging.INFO, 'artifact', {},
+                                 'Will retry in a moment...')
+                    continue
+                try:
+                    valid = record.validate()
+                except Exception:
+                    pass
+                if not valid:
+                    os.unlink(record.filename)
+                    if attempt < retry:
+                        self.log(logging.INFO, 'artifact', {},
+                                 'Will retry in a moment...')
+                    continue
+
+                downloaded.append(record)
+                break
+
+            if not valid:
+                self.log(logging.ERROR, 'artifact', {'name': record.basename},
+                         'Failed to download {name}')
+                return 1
+
+        for record in downloaded:
+            local = os.path.join(os.getcwd(), record.basename)
+            if os.path.exists(local):
+                os.unlink(local)
+            # unpack_file needs the file with its final name to work
+            # (https://github.com/mozilla/build-tooltool/issues/38), so we
+            # need to copy it, even though we remove it later. Use hard links
+            # when possible.
+            try:
+                os.link(record.filename, local)
+            except Exception:
+                shutil.copy(record.filename, local)
+            if record.unpack and not no_unpack:
+                unpack_file(local, record.setup)
+                os.unlink(local)
+
+        if not downloaded:
+            self.log(logging.ERROR, 'artifact', {}, 'Nothing to download')
+            return 1
+
+        return 0
+
+
 @CommandProvider
 class Vendor(MachCommandBase):
     """Vendor third-party dependencies into the source repository."""
 
     @Command('vendor', category='misc',
              description='Vendor third-party dependencies into the source repository.')
     def vendor(self):
         self.parser.print_usage()
--- a/python/mozbuild/mozbuild/test/test_artifacts.py
+++ b/python/mozbuild/mozbuild/test/test_artifacts.py
@@ -74,72 +74,76 @@ class TestArtifactCache(unittest.TestCas
 
     def utime(self, path, times):
         if times is None:
             # Ensure all downloaded files have a different timestamp
             times = (self.timestamp, self.timestamp)
             self.timestamp += 2
         self._real_utime(path, times)
 
+    def listtmpdir(self):
+        return [p for p in os.listdir(self.tmpdir)
+                if p != '.metadata_never_index']
+
     def test_artifact_cache_persistence(self):
         cache = ArtifactCache(self.tmpdir)
         cache._download_manager.session = FakeSession()
 
         path = cache.fetch('http://server/foo')
         expected = [os.path.basename(path)]
-        self.assertEqual(os.listdir(self.tmpdir), expected)
+        self.assertEqual(self.listtmpdir(), expected)
 
         path = cache.fetch('http://server/bar')
         expected.append(os.path.basename(path))
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
         # We're downloading more than the cache allows us, but since it's all
         # in the same session, no purge happens.
         path = cache.fetch('http://server/qux')
         expected.append(os.path.basename(path))
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
         path = cache.fetch('http://server/fuga')
         expected.append(os.path.basename(path))
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
         cache = ArtifactCache(self.tmpdir)
         cache._download_manager.session = FakeSession()
 
         # Downloading a new file in a new session purges the oldest files in
         # the cache.
         path = cache.fetch('http://server/hoge')
         expected.append(os.path.basename(path))
         expected = expected[2:]
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
         # Downloading a file already in the cache leaves the cache untouched
         cache = ArtifactCache(self.tmpdir)
         cache._download_manager.session = FakeSession()
 
         path = cache.fetch('http://server/qux')
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
         # bar was purged earlier, re-downloading it should purge the oldest
         # downloaded file, which at this point would be qux, but we also
         # re-downloaded it in the mean time, so the next one (fuga) should be
         # the purged one.
         cache = ArtifactCache(self.tmpdir)
         cache._download_manager.session = FakeSession()
 
         path = cache.fetch('http://server/bar')
         expected.append(os.path.basename(path))
         expected = [p for p in expected if 'fuga' not in p]
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
         # Downloading one file larger than the cache size should still leave
         # MIN_CACHED_ARTIFACTS files.
         cache = ArtifactCache(self.tmpdir)
         cache._download_manager.session = FakeSession()
 
         path = cache.fetch('http://server/larger')
         expected.append(os.path.basename(path))
         expected = expected[-2:]
-        self.assertEqual(sorted(os.listdir(self.tmpdir)), sorted(expected))
+        self.assertEqual(sorted(self.listtmpdir()), sorted(expected))
 
 
 if __name__ == '__main__':
     mozunit.main()
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -3,16 +3,18 @@
  * 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/. */
 
 #ifndef mozilla_Sandbox_h
 #define mozilla_Sandbox_h
 
 #include <string>
 
+#include "SandboxPolicies.h"
+
 enum MacSandboxType {
   MacSandboxType_Default = 0,
   MacSandboxType_Plugin,
   MacSandboxType_Content,
   MacSandboxType_Invalid
 };
 
 enum MacSandboxPluginType {
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -119,341 +119,16 @@ OSXVersion::GetVersionNumber()
     GetSystemVersion(major, minor, bugfix);
     mOSXVersion = MAC_OS_X_VERSION_10_0_HEX + (minor << 4) + bugfix;
   }
   return mOSXVersion;
 }
 
 namespace mozilla {
 
-static const char pluginSandboxRules[] =
-  "(version 1)\n"
-
-  "(define should-log (param \"SHOULD_LOG\"))\n"
-  "(define plugin-binary-path (param \"PLUGIN_BINARY_PATH\"))\n"
-  "(define app-path (param \"APP_PATH\"))\n"
-  "(define app-binary-path (param \"APP_BINARY_PATH\"))\n"
-
-  "(if (string=? should-log \"TRUE\")\n"
-  "    (deny default)\n"
-  "    (deny default (with no-log)))\n"
-
-  "(allow signal (target self))\n"
-  "(allow sysctl-read)\n"
-  "(allow iokit-open (iokit-user-client-class \"IOHIDParamUserClient\"))\n"
-  "(allow mach-lookup\n"
-  "    (global-name \"com.apple.cfprefsd.agent\")\n"
-  "    (global-name \"com.apple.cfprefsd.daemon\")\n"
-  "    (global-name \"com.apple.system.opendirectoryd.libinfo\")\n"
-  "    (global-name \"com.apple.system.logger\")\n"
-  "    (global-name \"com.apple.ls.boxd\"))\n"
-  "(allow file-read*\n"
-  "    (regex #\"^/etc$\")\n"
-  "    (regex #\"^/dev/u?random$\")\n"
-  "    (literal \"/usr/share/icu/icudt51l.dat\")\n"
-  "    (regex #\"^/System/Library/Displays/Overrides/*\")\n"
-  "    (regex #\"^/System/Library/CoreServices/CoreTypes.bundle/*\")\n"
-  "    (regex #\"^/System/Library/PrivateFrameworks/*\")\n"
-  "    (regex #\"^/usr/lib/libstdc\\+\\+\\..*dylib$\")\n"
-  "    (literal plugin-binary-path)\n"
-  "    (literal app-path)\n"
-  "    (literal app-binary-path))\n";
-
-static const char widevinePluginSandboxRulesAddend[] =
-  "(allow mach-lookup (global-name \"com.apple.windowserver.active\"))\n";
-
-static const char contentSandboxRules[] =
-  "(version 1)\n"
-  "\n"
-  "(define should-log (param \"SHOULD_LOG\"))\n"
-  "(define sandbox-level-1 (param \"SANDBOX_LEVEL_1\"))\n"
-  "(define sandbox-level-2 (param \"SANDBOX_LEVEL_2\"))\n"
-  "(define sandbox-level-3 (param \"SANDBOX_LEVEL_3\"))\n"
-  "(define macosMinorVersion-9 (param \"MAC_OS_MINOR_9\"))\n"
-  "(define appPath (param \"APP_PATH\"))\n"
-  "(define appBinaryPath (param \"APP_BINARY_PATH\"))\n"
-  "(define appDir (param \"APP_DIR\"))\n"
-  "(define appTempDir (param \"APP_TEMP_DIR\"))\n"
-  "(define hasProfileDir (param \"HAS_SANDBOXED_PROFILE\"))\n"
-  "(define profileDir (param \"PROFILE_DIR\"))\n"
-  "(define home-path (param \"HOME_PATH\"))\n"
-  "(define hasFilePrivileges (param \"HAS_FILE_PRIVILEGES\"))\n"
-  "(define isDebugBuild (param \"DEBUG_BUILD\"))\n"
-  "\n"
-  "; Allow read access to standard system paths.\n"
-  "(allow file-read*\n"
-  "  (require-all (file-mode #o0004)\n"
-  "    (require-any (subpath \"/Library/Filesystems/NetFSPlugins\")\n"
-  "      (subpath \"/System\")\n"
-  "      (subpath \"/private/var/db/dyld\")\n"
-  "      (subpath \"/usr/lib\")\n"
-  "      (subpath \"/usr/share\"))))\n"
-  "\n"
-  "(allow file-read-metadata\n"
-  "  (literal \"/etc\")\n"
-  "  (literal \"/tmp\")\n"
-  "  (literal \"/var\")\n"
-  "  (literal \"/private/etc/localtime\"))\n"
-  "\n"
-  "; Allow read access to standard special files.\n"
-  "(allow file-read*\n"
-  "  (literal \"/dev/autofs_nowait\")\n"
-  "  (literal \"/dev/random\")\n"
-  "  (literal \"/dev/urandom\"))\n"
-  "\n"
-  "(allow file-read*\n"
-  "  file-write-data\n"
-  "  (literal \"/dev/null\")\n"
-  "  (literal \"/dev/zero\"))\n"
-  "\n"
-  "(allow file-read*\n"
-  "  file-write-data\n"
-  "  file-ioctl\n"
-  "  (literal \"/dev/dtracehelper\"))\n"
-  "\n"
-  "; Used to read hw.ncpu, hw.physicalcpu_max, kern.ostype, and others\n"
-  "(allow sysctl-read)\n"
-  "\n"
-  "(begin\n"
-  "  (if (string=? should-log \"TRUE\")\n"
-  "    (deny default)\n"
-  "    (deny default (with no-log)))\n"
-  "  (debug deny)\n"
-  "\n"
-  "  (define resolving-literal literal)\n"
-  "  (define resolving-subpath subpath)\n"
-  "  (define resolving-regex regex)\n"
-  "\n"
-  "  (define container-path appPath)\n"
-  "  (define appdir-path appDir)\n"
-  "  (define var-folders-re \"^/private/var/folders/[^/][^/]\")\n"
-  "  (define var-folders2-re (string-append var-folders-re \"/[^/]+/[^/]\"))\n"
-  "\n"
-  "  (define (home-regex home-relative-regex)\n"
-  "    (resolving-regex (string-append \"^\" (regex-quote home-path) home-relative-regex)))\n"
-  "  (define (home-subpath home-relative-subpath)\n"
-  "    (resolving-subpath (string-append home-path home-relative-subpath)))\n"
-  "  (define (home-literal home-relative-literal)\n"
-  "    (resolving-literal (string-append home-path home-relative-literal)))\n"
-  "\n"
-  "  (define (profile-subpath profile-relative-subpath)\n"
-  "    (resolving-subpath (string-append profileDir profile-relative-subpath)))\n"
-  "\n"
-  "  (define (var-folders-regex var-folders-relative-regex)\n"
-  "    (resolving-regex (string-append var-folders-re var-folders-relative-regex)))\n"
-  "  (define (var-folders2-regex var-folders2-relative-regex)\n"
-  "    (resolving-regex (string-append var-folders2-re var-folders2-relative-regex)))\n"
-  "\n"
-  "  (define (allow-shared-preferences-read domain)\n"
-  "        (begin\n"
-  "          (if (defined? `user-preference-read)\n"
-  "            (allow user-preference-read (preference-domain domain)))\n"
-  "          (allow file-read*\n"
-  "                 (home-literal (string-append \"/Library/Preferences/\" domain \".plist\"))\n"
-  "                 (home-regex (string-append \"/Library/Preferences/ByHost/\" (regex-quote domain) \"\\..*\\.plist$\")))\n"
-  "          ))\n"
-  "\n"
-  "  (define (allow-shared-list domain)\n"
-  "    (allow file-read*\n"
-  "           (home-regex (string-append \"/Library/Preferences/\" (regex-quote domain)))))\n"
-  "\n"
-  "  (allow ipc-posix-shm\n"
-  "      (ipc-posix-name-regex \"^/tmp/com.apple.csseed:\")\n"
-  "      (ipc-posix-name-regex \"^CFPBS:\")\n"
-  "      (ipc-posix-name-regex \"^AudioIO\"))\n"
-  "\n"
-  "  (allow file-read-metadata\n"
-  "      (literal \"/home\")\n"
-  "      (literal \"/net\")\n"
-  "      (regex \"^/private/tmp/KSInstallAction\\.\")\n"
-  "      (var-folders-regex \"/\")\n"
-  "      (home-subpath \"/Library\"))\n"
-  "\n"
-  "  (allow signal (target self))\n"
-  "  (allow job-creation (literal \"/Library/CoreMediaIO/Plug-Ins/DAL\"))\n"
-  "  (allow iokit-set-properties (iokit-property \"IOAudioControlValue\"))\n"
-  "\n"
-  "  (allow mach-lookup\n"
-  "      (global-name \"com.apple.coreservices.launchservicesd\")\n"
-  "      (global-name \"com.apple.coreservices.appleevents\")\n"
-  "      (global-name \"com.apple.pasteboard.1\")\n"
-  "      (global-name \"com.apple.window_proxies\")\n"
-  "      (global-name \"com.apple.windowserver.active\")\n"
-  "      (global-name \"com.apple.audio.coreaudiod\")\n"
-  "      (global-name \"com.apple.audio.audiohald\")\n"
-  "      (global-name \"com.apple.PowerManagement.control\")\n"
-  "      (global-name \"com.apple.cmio.VDCAssistant\")\n"
-  "      (global-name \"com.apple.SystemConfiguration.configd\")\n"
-  "      (global-name \"com.apple.iconservices\")\n"
-  "      (global-name \"com.apple.cookied\")\n"
-  "      (global-name \"com.apple.cache_delete\")\n"
-  "      (global-name \"com.apple.pluginkit.pkd\")\n"
-  "      (global-name \"com.apple.bird\")\n"
-  "      (global-name \"com.apple.ocspd\")\n"
-  "      (global-name \"com.apple.cmio.AppleCameraAssistant\")\n"
-  "      (global-name \"com.apple.DesktopServicesHelper\"))\n"
-  "\n"
-  "; bug 1312273\n"
-  "  (if (string=? macosMinorVersion-9 \"TRUE\")\n"
-  "     (allow mach-lookup (global-name \"com.apple.xpcd\")))\n"
-  "\n"
-  "  (allow iokit-open\n"
-  "      (iokit-user-client-class \"IOHIDParamUserClient\")\n"
-  "      (iokit-user-client-class \"IOAudioControlUserClient\")\n"
-  "      (iokit-user-client-class \"IOAudioEngineUserClient\")\n"
-  "      (iokit-user-client-class \"IGAccelDevice\")\n"
-  "      (iokit-user-client-class \"nvDevice\")\n"
-  "      (iokit-user-client-class \"nvSharedUserClient\")\n"
-  "      (iokit-user-client-class \"nvFermiGLContext\")\n"
-  "      (iokit-user-client-class \"IGAccelGLContext\")\n"
-  "      (iokit-user-client-class \"IGAccelSharedUserClient\")\n"
-  "      (iokit-user-client-class \"IGAccelVideoContextMain\")\n"
-  "      (iokit-user-client-class \"IGAccelVideoContextMedia\")\n"
-  "      (iokit-user-client-class \"IGAccelVideoContextVEBox\")\n"
-  "      (iokit-user-client-class \"RootDomainUserClient\")\n"
-  "      (iokit-user-client-class \"IOUSBDeviceUserClientV2\")\n"
-  "      (iokit-user-client-class \"IOUSBInterfaceUserClientV2\"))\n"
-  "\n"
-  "; depending on systems, the 1st, 2nd or both rules are necessary\n"
-  "  (allow-shared-preferences-read \"com.apple.HIToolbox\")\n"
-  "  (allow file-read-data (literal \"/Library/Preferences/com.apple.HIToolbox.plist\"))\n"
-  "\n"
-  "  (allow-shared-preferences-read \"com.apple.ATS\")\n"
-  "  (allow file-read-data (literal \"/Library/Preferences/.GlobalPreferences.plist\"))\n"
-  "\n"
-  "  (allow file-read*\n"
-  "      (subpath \"/Library/Fonts\")\n"
-  "      (subpath \"/Library/Audio/Plug-Ins\")\n"
-  "      (subpath \"/Library/CoreMediaIO/Plug-Ins/DAL\")\n"
-  "      (subpath \"/Library/Spelling\")\n"
-  "      (literal \"/\")\n"
-  "      (literal \"/private/tmp\")\n"
-  "      (literal \"/private/var/tmp\")\n"
-  "\n"
-  "      (home-literal \"/.CFUserTextEncoding\")\n"
-  "      (home-literal \"/Library/Preferences/com.apple.DownloadAssessment.plist\")\n"
-  "      (home-subpath \"/Library/Colors\")\n"
-  "      (home-subpath \"/Library/Fonts\")\n"
-  "      (home-subpath \"/Library/FontCollections\")\n"
-  "      (home-subpath \"/Library/Keyboard Layouts\")\n"
-  "      (home-subpath \"/Library/Input Methods\")\n"
-  "      (home-subpath \"/Library/Spelling\")\n"
-  "      (home-subpath \"/Library/Application Support/Adobe/CoreSync/plugins/livetype\")\n"
-  "\n"
-  "      (subpath appdir-path)\n"
-  "\n"
-  "      (literal appPath)\n"
-  "      (literal appBinaryPath))\n"
-  "\n"
-  "  (allow-shared-list \"org.mozilla.plugincontainer\")\n"
-  "\n"
-  "; the following rule should be removed when microphone access\n"
-  "; is brokered through the content process\n"
-  "  (allow device-microphone)\n"
-  "\n"
-  "  (allow file* (var-folders2-regex \"/com\\.apple\\.IntlDataCache\\.le$\"))\n"
-  "  (allow file-read*\n"
-  "      (var-folders2-regex \"/com\\.apple\\.IconServices/\")\n"
-  "      (var-folders2-regex \"/[^/]+\\.mozrunner/extensions/[^/]+/chrome/[^/]+/content/[^/]+\\.j(s|ar)$\"))\n"
-  "\n"
-  "  (allow file-write* (var-folders2-regex \"/org\\.chromium\\.[a-zA-Z0-9]*$\"))\n"
-  "\n"
-  "; Per-user and system-wide Extensions dir\n"
-  "  (allow file-read*\n"
-  "      (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n"
-  "      (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\"))\n"
-  "\n"
-  "; The following rules impose file access restrictions which get\n"
-  "; more restrictive in higher levels. When file-origin-specific\n"
-  "; content processes are used for file:// origin browsing, the\n"
-  "; global file-read* permission should be removed from each level.\n"
-  "\n"
-  "; level 1: global read access permitted, no global write access\n"
-  "  (if (string=? sandbox-level-1 \"TRUE\") (allow file-read*))\n"
-  "\n"
-  "; level 2: global read access permitted, no global write access,\n"
-  ";          no read/write access to ~/Library,\n"
-  ";          no read/write access to $PROFILE,\n"
-  ";          read access permitted to $PROFILE/{extensions,chrome}\n"
-  "  (if (string=? sandbox-level-2 \"TRUE\")\n"
-  "    (if (string=? hasFilePrivileges \"TRUE\")\n"
-  "      ; This process has blanket file read privileges\n"
-  "      (allow file-read*)\n"
-  "      ; This process does not have blanket file read privileges\n"
-  "      (if (string=? hasProfileDir \"TRUE\")\n"
-  "        ; we have a profile dir\n"
-  "        (begin\n"
-  "          (allow file-read* (require-all\n"
-  "              (require-not (home-subpath \"/Library\"))\n"
-  "              (require-not (subpath profileDir))))\n"
-  "          (allow file-read*\n"
-  "              (profile-subpath \"/extensions\")\n"
-  "              (profile-subpath \"/chrome\")))\n"
-  "        ; we don't have a profile dir\n"
-  "        (allow file-read* (require-not (home-subpath \"/Library\"))))))\n"
-  "\n"
-  "; level 3: global read access permitted, no global write access,\n"
-  ";          no read access to the home directory,\n"
-  ";          read access permitted to $PROFILE/{extensions,chrome}\n"
-  "  (if (string=? sandbox-level-3 \"TRUE\")\n"
-  "    (if (string=? hasFilePrivileges \"TRUE\")\n"
-  "      ; This process has blanket file read privileges\n"
-  "      (allow file-read*)\n"
-  "      ; This process does not have blanket file read privileges\n"
-  "      (if (string=? hasProfileDir \"TRUE\")\n"
-  "        ; we have a profile dir\n"
-  "        (begin\n"
-  "          (allow file-read* (require-all\n"
-  "              (require-not (subpath home-path))\n"
-  "              (require-not (subpath profileDir))))\n"
-  "          (allow file-read*\n"
-  "              (profile-subpath \"/extensions\")\n"
-  "              (profile-subpath \"/chrome\")))\n"
-  "        ; we don't have a profile dir\n"
-  "        (allow file-read* (require-not (subpath home-path))))))\n"
-  "\n"
-  "; accelerated graphics\n"
-  "  (allow-shared-preferences-read \"com.apple.opengl\")\n"
-  "  (allow-shared-preferences-read \"com.nvidia.OpenGL\")\n"
-  "  (allow mach-lookup\n"
-  "      (global-name \"com.apple.cvmsServ\"))\n"
-  "  (allow iokit-open\n"
-  "      (iokit-connection \"IOAccelerator\")\n"
-  "      (iokit-user-client-class \"IOAccelerationUserClient\")\n"
-  "      (iokit-user-client-class \"IOSurfaceRootUserClient\")\n"
-  "      (iokit-user-client-class \"IOSurfaceSendRight\")\n"
-  "      (iokit-user-client-class \"IOFramebufferSharedUserClient\")\n"
-  "      (iokit-user-client-class \"AppleSNBFBUserClient\")\n"
-  "      (iokit-user-client-class \"AGPMClient\")\n"
-  "      (iokit-user-client-class \"AppleGraphicsControlClient\")\n"
-  "      (iokit-user-client-class \"AppleGraphicsPolicyClient\"))\n"
-  "\n"
-  "; bug 1153809\n"
-  "  (allow iokit-open\n"
-  "      (iokit-user-client-class \"NVDVDContextTesla\")\n"
-  "      (iokit-user-client-class \"Gen6DVDContext\"))\n"
-  "\n"
-  "; bug 1201935\n"
-  "  (allow file-read*\n"
-  "      (home-subpath \"/Library/Caches/TemporaryItems\"))\n"
-  "\n"
-  "; bug 1237847\n"
-  "  (allow file-read*\n"
-  "      (subpath appTempDir))\n"
-  "  (allow file-write*\n"
-  "      (subpath appTempDir))\n"
-  "\n"
-  "; bug 1324610\n"
-  "  (allow network-outbound (literal \"/private/var/run/cupsd\"))\n"
-  "\n"
-  "; bug 1303987\n"
-  "  (if (string=? isDebugBuild \"TRUE\")\n"
-  "      (allow file-write* (var-folders-regex \"/\")))\n"
-  ")\n";
-
 bool StartMacSandbox(MacSandboxInfo aInfo, std::string &aErrorMessage)
 {
   std::vector<const char *> params;
   char *profile = NULL;
   bool profile_needs_free = false;
   if (aInfo.type == MacSandboxType_Plugin) {
     profile = const_cast<char *>(pluginSandboxRules);
     params.push_back("SHOULD_LOG");
new file mode 100644
--- /dev/null
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -0,0 +1,341 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef mozilla_SandboxPolicies_h
+#define mozilla_SandboxPolicies_h
+
+namespace mozilla {
+
+static const char pluginSandboxRules[] = R"(
+  (version 1)
+
+  (define should-log (param "SHOULD_LOG"))
+  (define plugin-binary-path (param "PLUGIN_BINARY_PATH"))
+  (define app-path (param "APP_PATH"))
+  (define app-binary-path (param "APP_BINARY_PATH"))
+
+  (if (string=? should-log "TRUE")
+      (deny default)
+      (deny default (with no-log)))
+
+  (allow signal (target self))
+  (allow sysctl-read)
+  (allow iokit-open (iokit-user-client-class "IOHIDParamUserClient"))
+  (allow mach-lookup
+      (global-name "com.apple.cfprefsd.agent")
+      (global-name "com.apple.cfprefsd.daemon")
+      (global-name "com.apple.system.opendirectoryd.libinfo")
+      (global-name "com.apple.system.logger")
+      (global-name "com.apple.ls.boxd"))
+  (allow file-read*
+      (regex #"^/etc$")
+      (regex #"^/dev/u?random$")
+      (literal "/usr/share/icu/icudt51l.dat")
+      (regex #"^/System/Library/Displays/Overrides/*")
+      (regex #"^/System/Library/CoreServices/CoreTypes.bundle/*")
+      (regex #"^/System/Library/PrivateFrameworks/*")
+      (regex #"^/usr/lib/libstdc\+\+\..*dylib$")
+      (literal plugin-binary-path)
+      (literal app-path)
+      (literal app-binary-path))
+)";
+
+static const char widevinePluginSandboxRulesAddend[] = R"(
+  (allow mach-lookup (global-name "com.apple.windowserver.active"))
+)";
+
+static const char contentSandboxRules[] = R"(
+  (version 1)
+
+      (define should-log (param "SHOULD_LOG"))
+  (define sandbox-level-1 (param "SANDBOX_LEVEL_1"))
+  (define sandbox-level-2 (param "SANDBOX_LEVEL_2"))
+  (define sandbox-level-3 (param "SANDBOX_LEVEL_3"))
+  (define macosMinorVersion-9 (param "MAC_OS_MINOR_9"))
+  (define appPath (param "APP_PATH"))
+  (define appBinaryPath (param "APP_BINARY_PATH"))
+  (define appDir (param "APP_DIR"))
+  (define appTempDir (param "APP_TEMP_DIR"))
+  (define hasProfileDir (param "HAS_SANDBOXED_PROFILE"))
+  (define profileDir (param "PROFILE_DIR"))
+  (define home-path (param "HOME_PATH"))
+  (define hasFilePrivileges (param "HAS_FILE_PRIVILEGES"))
+  (define isDebugBuild (param "DEBUG_BUILD"))
+
+  ; Allow read access to standard system paths.
+  (allow file-read*
+    (require-all (file-mode #o0004)
+      (require-any (subpath "/Library/Filesystems/NetFSPlugins")
+        (subpath "/System")
+        (subpath "/private/var/db/dyld")
+        (subpath "/usr/lib")
+        (subpath "/usr/share"))))
+
+  (allow file-read-metadata
+    (literal "/etc")
+    (literal "/tmp")
+    (literal "/var")
+    (literal "/private/etc/localtime"))
+
+  ; Allow read access to standard special files.
+  (allow file-read*
+    (literal "/dev/autofs_nowait")
+    (literal "/dev/random")
+    (literal "/dev/urandom"))
+
+  (allow file-read*
+    file-write-data
+    (literal "/dev/null")
+    (literal "/dev/zero"))
+
+  (allow file-read*
+    file-write-data
+    file-ioctl
+    (literal "/dev/dtracehelper"))
+
+  ; Used to read hw.ncpu, hw.physicalcpu_max, kern.ostype, and others
+  (allow sysctl-read)
+
+  (begin
+    (if (string=? should-log "TRUE")
+      (deny default)
+      (deny default (with no-log)))
+    (debug deny)
+
+    (define resolving-literal literal)
+    (define resolving-subpath subpath)
+    (define resolving-regex regex)
+
+    (define container-path appPath)
+    (define appdir-path appDir)
+    (define var-folders-re "^/private/var/folders/[^/][^/]")
+    (define var-folders2-re (string-append var-folders-re "/[^/]+/[^/]"))
+
+    (define (home-regex home-relative-regex)
+      (resolving-regex (string-append "^" (regex-quote home-path) home-relative-regex)))
+    (define (home-subpath home-relative-subpath)
+      (resolving-subpath (string-append home-path home-relative-subpath)))
+    (define (home-literal home-relative-literal)
+      (resolving-literal (string-append home-path home-relative-literal)))
+
+    (define (profile-subpath profile-relative-subpath)
+      (resolving-subpath (string-append profileDir profile-relative-subpath)))
+
+    (define (var-folders-regex var-folders-relative-regex)
+      (resolving-regex (string-append var-folders-re var-folders-relative-regex)))
+    (define (var-folders2-regex var-folders2-relative-regex)
+      (resolving-regex (string-append var-folders2-re var-folders2-relative-regex)))
+
+    (define (allow-shared-preferences-read domain)
+          (begin
+            (if (defined? `user-preference-read)
+              (allow user-preference-read (preference-domain domain)))
+            (allow file-read*
+                   (home-literal (string-append "/Library/Preferences/" domain ".plist"))
+                   (home-regex (string-append "/Library/Preferences/ByHost/" (regex-quote domain) "\..*\.plist$")))
+            ))
+
+    (define (allow-shared-list domain)
+      (allow file-read*
+             (home-regex (string-append "/Library/Preferences/" (regex-quote domain)))))
+
+    (allow ipc-posix-shm
+        (ipc-posix-name-regex "^/tmp/com.apple.csseed:")
+        (ipc-posix-name-regex "^CFPBS:")
+        (ipc-posix-name-regex "^AudioIO"))
+
+    (allow file-read-metadata
+        (literal "/home")
+        (literal "/net")
+        (regex "^/private/tmp/KSInstallAction\.")
+        (var-folders-regex "/")
+        (home-subpath "/Library"))
+
+    (allow signal (target self))
+    (allow job-creation (literal "/Library/CoreMediaIO/Plug-Ins/DAL"))
+    (allow iokit-set-properties (iokit-property "IOAudioControlValue"))
+
+    (allow mach-lookup
+        (global-name "com.apple.coreservices.launchservicesd")
+        (global-name "com.apple.coreservices.appleevents")
+        (global-name "com.apple.pasteboard.1")
+        (global-name "com.apple.window_proxies")
+        (global-name "com.apple.windowserver.active")
+        (global-name "com.apple.audio.coreaudiod")
+        (global-name "com.apple.audio.audiohald")
+        (global-name "com.apple.PowerManagement.control")
+        (global-name "com.apple.cmio.VDCAssistant")
+        (global-name "com.apple.SystemConfiguration.configd")
+        (global-name "com.apple.iconservices")
+        (global-name "com.apple.cookied")
+        (global-name "com.apple.cache_delete")
+        (global-name "com.apple.pluginkit.pkd")
+        (global-name "com.apple.bird")
+        (global-name "com.apple.ocspd")
+        (global-name "com.apple.cmio.AppleCameraAssistant")
+        (global-name "com.apple.DesktopServicesHelper"))
+
+  ; bug 1312273
+    (if (string=? macosMinorVersion-9 "TRUE")
+       (allow mach-lookup (global-name "com.apple.xpcd")))
+
+    (allow iokit-open
+        (iokit-user-client-class "IOHIDParamUserClient")
+        (iokit-user-client-class "IOAudioControlUserClient")
+        (iokit-user-client-class "IOAudioEngineUserClient")
+        (iokit-user-client-class "IGAccelDevice")
+        (iokit-user-client-class "nvDevice")
+        (iokit-user-client-class "nvSharedUserClient")
+        (iokit-user-client-class "nvFermiGLContext")
+        (iokit-user-client-class "IGAccelGLContext")
+        (iokit-user-client-class "IGAccelSharedUserClient")
+        (iokit-user-client-class "IGAccelVideoContextMain")
+        (iokit-user-client-class "IGAccelVideoContextMedia")
+        (iokit-user-client-class "IGAccelVideoContextVEBox")
+        (iokit-user-client-class "RootDomainUserClient")
+        (iokit-user-client-class "IOUSBDeviceUserClientV2")
+        (iokit-user-client-class "IOUSBInterfaceUserClientV2"))
+
+  ; depending on systems, the 1st, 2nd or both rules are necessary
+    (allow-shared-preferences-read "com.apple.HIToolbox")
+    (allow file-read-data (literal "/Library/Preferences/com.apple.HIToolbox.plist"))
+
+    (allow-shared-preferences-read "com.apple.ATS")
+    (allow file-read-data (literal "/Library/Preferences/.GlobalPreferences.plist"))
+
+    (allow file-read*
+        (subpath "/Library/Fonts")
+        (subpath "/Library/Audio/Plug-Ins")
+        (subpath "/Library/CoreMediaIO/Plug-Ins/DAL")
+        (subpath "/Library/Spelling")
+        (literal "/")
+        (literal "/private/tmp")
+        (literal "/private/var/tmp")
+
+        (home-literal "/.CFUserTextEncoding")
+        (home-literal "/Library/Preferences/com.apple.DownloadAssessment.plist")
+        (home-subpath "/Library/Colors")
+        (home-subpath "/Library/Fonts")
+        (home-subpath "/Library/FontCollections")
+        (home-subpath "/Library/Keyboard Layouts")
+        (home-subpath "/Library/Input Methods")
+        (home-subpath "/Library/Spelling")
+        (home-subpath "/Library/Application Support/Adobe/CoreSync/plugins/livetype")
+
+        (subpath appdir-path)
+
+        (literal appPath)
+        (literal appBinaryPath))
+
+    (allow-shared-list "org.mozilla.plugincontainer")
+
+  ; the following rule should be removed when microphone access
+  ; is brokered through the content process
+    (allow device-microphone)
+
+    (allow file* (var-folders2-regex "/com\.apple\.IntlDataCache\.le$"))
+    (allow file-read*
+        (var-folders2-regex "/com\.apple\.IconServices/")
+        (var-folders2-regex "/[^/]+\.mozrunner/extensions/[^/]+/chrome/[^/]+/content/[^/]+\.j(s|ar)$"))
+
+    (allow file-write* (var-folders2-regex "/org\.chromium\.[a-zA-Z0-9]*$"))
+
+  ; Per-user and system-wide Extensions dir
+    (allow file-read*
+        (home-regex "/Library/Application Support/[^/]+/Extensions/[^/]/")
+        (resolving-regex "/Library/Application Support/[^/]+/Extensions/[^/]/"))
+
+  ; The following rules impose file access restrictions which get
+  ; more restrictive in higher levels. When file-origin-specific
+  ; content processes are used for file:// origin browsing, the
+  ; global file-read* permission should be removed from each level.
+
+  ; level 1: global read access permitted, no global write access
+    (if (string=? sandbox-level-1 "TRUE") (allow file-read*))
+
+  ; level 2: global read access permitted, no global write access,
+  ;          no read/write access to ~/Library,
+  ;          no read/write access to $PROFILE,
+  ;          read access permitted to $PROFILE/{extensions,chrome}
+    (if (string=? sandbox-level-2 "TRUE")
+      (if (string=? hasFilePrivileges "TRUE")
+        ; This process has blanket file read privileges
+        (allow file-read*)
+        ; This process does not have blanket file read privileges
+        (if (string=? hasProfileDir "TRUE")
+          ; we have a profile dir
+          (begin
+            (allow file-read* (require-all
+                (require-not (home-subpath "/Library"))
+                (require-not (subpath profileDir))))
+            (allow file-read*
+                (profile-subpath "/extensions")
+                (profile-subpath "/chrome")))
+          ; we don't have a profile dir
+          (allow file-read* (require-not (home-subpath "/Library"))))))
+
+  ; level 3: global read access permitted, no global write access,
+  ;          no read access to the home directory,
+  ;          read access permitted to $PROFILE/{extensions,chrome}
+    (if (string=? sandbox-level-3 "TRUE")
+      (if (string=? hasFilePrivileges "TRUE")
+        ; This process has blanket file read privileges
+        (allow file-read*)
+        ; This process does not have blanket file read privileges
+        (if (string=? hasProfileDir "TRUE")
+          ; we have a profile dir
+          (begin
+            (allow file-read* (require-all
+                (require-not (subpath home-path))
+                (require-not (subpath profileDir))))
+            (allow file-read*
+                (profile-subpath "/extensions")
+                (profile-subpath "/chrome")))
+          ; we don't have a profile dir
+          (allow file-read* (require-not (subpath home-path))))))
+
+  ; accelerated graphics
+    (allow-shared-preferences-read "com.apple.opengl")
+    (allow-shared-preferences-read "com.nvidia.OpenGL")
+    (allow mach-lookup
+        (global-name "com.apple.cvmsServ"))
+    (allow iokit-open
+        (iokit-connection "IOAccelerator")
+        (iokit-user-client-class "IOAccelerationUserClient")
+        (iokit-user-client-class "IOSurfaceRootUserClient")
+        (iokit-user-client-class "IOSurfaceSendRight")
+        (iokit-user-client-class "IOFramebufferSharedUserClient")
+        (iokit-user-client-class "AppleSNBFBUserClient")
+        (iokit-user-client-class "AGPMClient")
+        (iokit-user-client-class "AppleGraphicsControlClient")
+        (iokit-user-client-class "AppleGraphicsPolicyClient"))
+
+  ; bug 1153809
+    (allow iokit-open
+        (iokit-user-client-class "NVDVDContextTesla")
+        (iokit-user-client-class "Gen6DVDContext"))
+
+  ; bug 1201935
+    (allow file-read*
+        (home-subpath "/Library/Caches/TemporaryItems"))
+
+  ; bug 1237847
+    (allow file-read*
+        (subpath appTempDir))
+    (allow file-write*
+        (subpath appTempDir))
+
+  ; bug 1324610
+    (allow network-outbound (literal "/private/var/run/cupsd"))
+
+  ; bug 1303987
+    (if (string=? isDebugBuild "TRUE")
+        (allow file-write* (var-folders-regex "/")))
+  )
+)";
+
+}
+
+#endif // mozilla_SandboxPolicies_h
--- a/security/sandbox/mac/moz.build
+++ b/security/sandbox/mac/moz.build
@@ -1,15 +1,16 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla += [
     'Sandbox.h',
+    'SandboxPolicies.h'
 ]
 
 SOURCES += [
     'Sandbox.mm',
 ]
 
 Library('mozsandbox');
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -292,31 +292,31 @@ dependencies = [
  "cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "offscreen_gl_context 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "canvas_traits"
 version = "0.0.1"
 dependencies = [
  "cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "caseless"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -427,18 +427,18 @@ dependencies = [
  "net_traits 0.0.1",
  "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.31.0 (git+https://github.com/servo/webrender)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "constellation"
 version = "0.0.1"
 dependencies = [
  "backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bluetooth_traits 0.0.1",
@@ -463,17 +463,17 @@ dependencies = [
  "script_traits 0.0.1",
  "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_rand 0.0.1",
  "servo_remutex 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "cookie"
 version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -710,17 +710,17 @@ dependencies = [
  "msg 0.0.1",
  "net_traits 0.0.1",
  "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding"
 version = "0.2.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -996,17 +996,17 @@ dependencies = [
  "servo_url 0.0.1",
  "simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gfx_tests"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
@@ -1075,17 +1075,17 @@ dependencies = [
  "script_traits 0.0.1",
  "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo-glutin 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
  "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glx"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1393,17 +1393,17 @@ dependencies = [
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "layout_tests"
 version = "0.0.1"
 dependencies = [
  "layout 0.0.1",
 ]
@@ -1433,31 +1433,31 @@ dependencies = [
  "script_traits 0.0.1",
  "selectors 0.18.0",
  "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style 0.0.1",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "layout_traits"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
  "ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "servo_url 0.0.1",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "lazy_static"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1524,18 +1524,18 @@ dependencies = [
  "script_layout_interface 0.0.1",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style 0.0.1",
  "style_traits 0.0.1",
  "webdriver_server 0.0.1",
- "webrender 0.31.0 (git+https://github.com/servo/webrender)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "webvr 0.0.1",
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "libz-sys"
 version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1674,17 +1674,17 @@ name = "msg"
 version = "0.0.1"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "multistr"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1718,17 +1718,17 @@ dependencies = [
  "servo_config 0.0.1",
  "servo_url 0.0.1",
  "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "net2"
 version = "0.2.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1777,17 +1777,17 @@ dependencies = [
  "msg 0.0.1",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_url 0.0.1",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "net_traits_tests"
 version = "0.0.1"
 dependencies = [
  "net_traits 0.0.1",
 ]
@@ -2304,17 +2304,17 @@ dependencies = [
  "smallvec 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "webvr 0.0.1",
  "webvr_traits 0.0.1",
  "xml5ever 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "script_layout_interface"
 version = "0.0.1"
@@ -3166,18 +3166,18 @@ dependencies = [
  "servo_url 0.0.1",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender"
-version = "0.31.0"
-source = "git+https://github.com/servo/webrender#98d343f2d800bb62a19d7c081a0a6a39dd74607f"
+version = "0.32.0"
+source = "git+https://github.com/servo/webrender#9973efd033ceb40edcebea68077766a5f096cfb3"
 dependencies = [
  "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0-alpha6 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3189,23 +3189,23 @@ dependencies = [
  "gleam 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "offscreen_gl_context 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "webrender_traits"
-version = "0.32.0"
-source = "git+https://github.com/servo/webrender#98d343f2d800bb62a19d7c081a0a6a39dd74607f"
+version = "0.33.0"
+source = "git+https://github.com/servo/webrender#9973efd033ceb40edcebea68077766a5f096cfb3"
 dependencies = [
  "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3219,17 +3219,17 @@ dependencies = [
 name = "webvr"
 version = "0.0.1"
 dependencies = [
  "ipc-channel 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
- "webrender_traits 0.32.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.33.0 (git+https://github.com/servo/webrender)",
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "winapi"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -3561,18 +3561,18 @@ dependencies = [
 "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47"
 "checksum utf-8 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9aee9ba280438b56d1ebc5329f2094f0ff457f811eeeff0b278d75aa99db400"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231"
 "checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
 "checksum webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d548aabf87411b1b4ba91fd07eacd8b238135c7131a452b8a9f6386209167e18"
-"checksum webrender 0.31.0 (git+https://github.com/servo/webrender)" = "<none>"
-"checksum webrender_traits 0.32.0 (git+https://github.com/servo/webrender)" = "<none>"
+"checksum webrender 0.32.0 (git+https://github.com/servo/webrender)" = "<none>"
+"checksum webrender_traits 0.33.0 (git+https://github.com/servo/webrender)" = "<none>"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum ws 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04614a58714f3fd4a8b1da4bcae9f031c532d35988c3d39627619248113f8be8"
 "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 "checksum x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "124eb405bf0262a54e1a982d4ffe4cd1c24261bdb306e49996e2ce7d492284a8"
 "checksum x11-dl 2.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1f9986368c9bbdd8191a783a7ceb42e0c9c6d3348616c873f829b3288a139c"
 "checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61"
 "checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
--- a/servo/components/selectors/matching.rs
+++ b/servo/components/selectors/matching.rs
@@ -117,16 +117,17 @@ fn may_match<E>(mut selector: &ComplexSe
                 -> bool
     where E: Element,
 {
     // See if the bloom filter can exclude any of the descendant selectors, and
     // reject if we can.
     loop {
          match selector.next {
              None => break,
+             Some((ref cs, Combinator::Child)) |
              Some((ref cs, Combinator::Descendant)) => selector = &**cs,
              Some((ref cs, _)) => {
                  selector = &**cs;
                  continue;
              }
          };
 
         for ss in selector.compound_selector.iter() {
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -1549,16 +1549,25 @@ extern "C" {
      -> bool;
 }
 extern "C" {
     pub fn Servo_StyleSet_GetFontFaceRules(set: RawServoStyleSetBorrowed,
                                            list:
                                                RawGeckoFontFaceRuleListBorrowedMut);
 }
 extern "C" {
+    pub fn Servo_StyleSet_ResolveForDeclarations(set:
+                                                     RawServoStyleSetBorrowed,
+                                                 parent_style:
+                                                     ServoComputedValuesBorrowedOrNull,
+                                                 declarations:
+                                                     RawServoDeclarationBlockBorrowed)
+     -> ServoComputedValuesStrong;
+}
+extern "C" {
     pub fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
                                     result: nsTArrayBorrowed_uintptr_t);
 }
 extern "C" {
     pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
                                      sheet: RawServoStyleSheetBorrowed,
                                      rule: *const nsACString, index: u32,
                                      nested: bool, loader: *mut Loader,
@@ -1659,17 +1668,17 @@ extern "C" {
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_PageRule_SetStyle(rule: RawServoPageRuleBorrowed,
                                    declarations:
                                        RawServoDeclarationBlockBorrowed);
 }
 extern "C" {
-    pub fn Servo_ParseProperty(property: *const nsACString,
+    pub fn Servo_ParseProperty(property: nsCSSPropertyID,
                                value: *const nsACString,
                                data: *mut RawGeckoURLExtraData)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_ParseEasing(easing: *const nsAString,
                              data: *mut RawGeckoURLExtraData,
                              output: nsTimingFunctionBorrowedMut) -> bool;
@@ -1841,16 +1850,22 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_RemovePropertyById(declarations:
                                                          RawServoDeclarationBlockBorrowed,
                                                      property:
                                                          nsCSSPropertyID);
 }
 extern "C" {
+    pub fn Servo_DeclarationBlock_HasCSSWideKeyword(declarations:
+                                                        RawServoDeclarationBlockBorrowed,
+                                                    property: nsCSSPropertyID)
+     -> bool;
+}
+extern "C" {
     pub fn Servo_AnimationCompose(animation_values:
                                       RawServoAnimationValueMapBorrowed,
                                   base_values: *mut ::std::os::raw::c_void,
                                   property: nsCSSPropertyID,
                                   animation_segment:
                                       RawGeckoAnimationPropertySegmentBorrowed,
                                   computed_timing:
                                       RawGeckoComputedTimingBorrowed);
--- a/servo/components/style/gecko_bindings/structs_debug.rs
+++ b/servo/components/style/gecko_bindings/structs_debug.rs
@@ -5397,27 +5397,27 @@ pub mod root {
             pub struct URLValueData__bindgen_vtable {
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct URLValueData {
                 pub vtable_: *const URLValueData__bindgen_vtable,
                 pub mRefCnt: root::mozilla::ThreadSafeAutoRefCnt,
                 pub mURI: root::nsMainThreadPtrHandle<root::nsIURI>,
-                pub mString: root::RefPtr<root::nsStringBuffer>,
+                pub mString: ::nsstring::nsStringRepr,
                 pub mExtraData: root::RefPtr<root::mozilla::URLExtraData>,
                 pub mURIResolved: bool,
                 pub mIsLocalRef: [u8; 2usize],
                 pub mMightHaveRef: [u8; 2usize],
             }
             pub type URLValueData_HasThreadSafeRefCnt =
                 root::mozilla::TrueType;
             #[test]
             fn bindgen_test_layout_URLValueData() {
-                assert_eq!(::std::mem::size_of::<URLValueData>() , 48usize ,
+                assert_eq!(::std::mem::size_of::<URLValueData>() , 56usize ,
                            concat ! (
                            "Size of: " , stringify ! ( URLValueData ) ));
                 assert_eq! (::std::mem::align_of::<URLValueData>() , 8usize ,
                             concat ! (
                             "Alignment of " , stringify ! ( URLValueData ) ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const URLValueData ) ) . mRefCnt as
                             * const _ as usize } , 8usize , concat ! (
@@ -5432,79 +5432,79 @@ pub mod root {
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const URLValueData ) ) . mString as
                             * const _ as usize } , 24usize , concat ! (
                             "Alignment of field: " , stringify ! (
                             URLValueData ) , "::" , stringify ! ( mString )
                             ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const URLValueData ) ) . mExtraData
-                            as * const _ as usize } , 32usize , concat ! (
+                            as * const _ as usize } , 40usize , concat ! (
                             "Alignment of field: " , stringify ! (
                             URLValueData ) , "::" , stringify ! ( mExtraData )
                             ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const URLValueData ) ) .
-                            mURIResolved as * const _ as usize } , 40usize ,
+                            mURIResolved as * const _ as usize } , 48usize ,
                             concat ! (
                             "Alignment of field: " , stringify ! (
                             URLValueData ) , "::" , stringify ! ( mURIResolved
                             ) ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const URLValueData ) ) .
-                            mIsLocalRef as * const _ as usize } , 41usize ,
+                            mIsLocalRef as * const _ as usize } , 49usize ,
                             concat ! (
                             "Alignment of field: " , stringify ! (
                             URLValueData ) , "::" , stringify ! ( mIsLocalRef
                             ) ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const URLValueData ) ) .
-                            mMightHaveRef as * const _ as usize } , 43usize ,
+                            mMightHaveRef as * const _ as usize } , 51usize ,
                             concat ! (
                             "Alignment of field: " , stringify ! (
                             URLValueData ) , "::" , stringify ! (
                             mMightHaveRef ) ));
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct URLValue {
                 pub _base: root::mozilla::css::URLValueData,
             }
             #[test]
             fn bindgen_test_layout_URLValue() {
-                assert_eq!(::std::mem::size_of::<URLValue>() , 48usize ,
+                assert_eq!(::std::mem::size_of::<URLValue>() , 56usize ,
                            concat ! ( "Size of: " , stringify ! ( URLValue )
                            ));
                 assert_eq! (::std::mem::align_of::<URLValue>() , 8usize ,
                             concat ! (
                             "Alignment of " , stringify ! ( URLValue ) ));
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct ImageValue {
                 pub _base: root::mozilla::css::URLValueData,
                 pub mRequests: [u64; 6usize],
                 pub mInitialized: bool,
             }
             #[test]
             fn bindgen_test_layout_ImageValue() {
-                assert_eq!(::std::mem::size_of::<ImageValue>() , 104usize ,
+                assert_eq!(::std::mem::size_of::<ImageValue>() , 112usize ,
                            concat ! ( "Size of: " , stringify ! ( ImageValue )
                            ));
                 assert_eq! (::std::mem::align_of::<ImageValue>() , 8usize ,
                             concat ! (
                             "Alignment of " , stringify ! ( ImageValue ) ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const ImageValue ) ) . mRequests as
-                            * const _ as usize } , 48usize , concat ! (
+                            * const _ as usize } , 56usize , concat ! (
                             "Alignment of field: " , stringify ! ( ImageValue
                             ) , "::" , stringify ! ( mRequests ) ));
                 assert_eq! (unsafe {
                             & ( * ( 0 as * const ImageValue ) ) . mInitialized
-                            as * const _ as usize } , 96usize , concat ! (
+                            as * const _ as usize } , 104usize , concat ! (
                             "Alignment of field: " , stringify ! ( ImageValue
                             ) , "::" , stringify ! ( mInitialized ) ));
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct GridNamedArea {
                 pub mName: ::nsstring::nsStringRepr,
                 pub mColumnStart: u32,
@@ -13532,16 +13532,18 @@ pub mod root {
         pub mOverrideDPPX: f32,
         pub mLastFontInflationScreenSize: root::gfxSize,
         pub mCurAppUnitsPerDevPixel: i32,
         pub mAutoQualityMinFontSizePixelsPref: i32,
         pub mTheme: root::nsCOMPtr<root::nsITheme>,
         pub mLangService: root::nsCOMPtr<root::nsILanguageAtomService>,
         pub mPrintSettings: root::nsCOMPtr<root::nsIPrintSettings>,
         pub mPrefChangedTimer: root::nsCOMPtr<root::nsITimer>,
+        pub mBidiEngine: root::mozilla::UniquePtr<root::nsBidi,
+                                                  root::mozilla::DefaultDelete<root::nsBidi>>,
         pub mPropertyTable: root::nsPresContext_FramePropertyTable,
         pub mTransactions: [u64; 10usize],
         pub mTextPerf: root::nsAutoPtr<root::gfxTextPerfMetrics>,
         pub mMissingFonts: root::nsAutoPtr<root::gfxMissingFontRecorder>,
         pub mVisibleArea: root::nsRect,
         pub mPageSize: root::nsSize,
         pub mPageScale: f32,
         pub mPPScale: f32,
@@ -13699,17 +13701,17 @@ pub mod root {
     }
     extern "C" {
         #[link_name = "_ZN13nsPresContext21_cycleCollectorGlobalE"]
         pub static mut nsPresContext__cycleCollectorGlobal:
                    root::nsPresContext_cycleCollection;
     }
     #[test]
     fn bindgen_test_layout_nsPresContext() {
-        assert_eq!(::std::mem::size_of::<nsPresContext>() , 1320usize , concat
+        assert_eq!(::std::mem::size_of::<nsPresContext>() , 1328usize , concat
                    ! ( "Size of: " , stringify ! ( nsPresContext ) ));
         assert_eq! (::std::mem::align_of::<nsPresContext>() , 8usize , concat
                     ! ( "Alignment of " , stringify ! ( nsPresContext ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mRefCnt as *
                     const _ as usize } , 16usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mRefCnt ) ));
@@ -13872,235 +13874,240 @@ pub mod root {
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mPrintSettings ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mPrefChangedTimer
                     as * const _ as usize } , 240usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mPrefChangedTimer ) ));
         assert_eq! (unsafe {
+                    & ( * ( 0 as * const nsPresContext ) ) . mBidiEngine as *
+                    const _ as usize } , 248usize , concat ! (
+                    "Alignment of field: " , stringify ! ( nsPresContext ) ,
+                    "::" , stringify ! ( mBidiEngine ) ));
+        assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mPropertyTable as
-                    * const _ as usize } , 248usize , concat ! (
+                    * const _ as usize } , 256usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mPropertyTable ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mTransactions as
-                    * const _ as usize } , 312usize , concat ! (
+                    * const _ as usize } , 320usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mTransactions ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mTextPerf as *
-                    const _ as usize } , 392usize , concat ! (
+                    const _ as usize } , 400usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mTextPerf ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mMissingFonts as
-                    * const _ as usize } , 400usize , concat ! (
+                    * const _ as usize } , 408usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mMissingFonts ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mVisibleArea as *
-                    const _ as usize } , 408usize , concat ! (
+                    const _ as usize } , 416usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mVisibleArea ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mPageSize as *
-                    const _ as usize } , 424usize , concat ! (
+                    const _ as usize } , 432usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mPageSize ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mPageScale as *
-                    const _ as usize } , 432usize , concat ! (
+                    const _ as usize } , 440usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mPageScale ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mPPScale as *
-                    const _ as usize } , 436usize , concat ! (
+                    const _ as usize } , 444usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mPPScale ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mDefaultColor as
-                    * const _ as usize } , 440usize , concat ! (
+                    * const _ as usize } , 448usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mDefaultColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mBackgroundColor
-                    as * const _ as usize } , 444usize , concat ! (
+                    as * const _ as usize } , 452usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mBackgroundColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mLinkColor as *
-                    const _ as usize } , 448usize , concat ! (
+                    const _ as usize } , 456usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mLinkColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mActiveLinkColor
-                    as * const _ as usize } , 452usize , concat ! (
+                    as * const _ as usize } , 460usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mActiveLinkColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mVisitedLinkColor
-                    as * const _ as usize } , 456usize , concat ! (
+                    as * const _ as usize } , 464usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mVisitedLinkColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mFocusBackgroundColor as * const _ as usize } , 460usize ,
+                    mFocusBackgroundColor as * const _ as usize } , 468usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFocusBackgroundColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mFocusTextColor
-                    as * const _ as usize } , 464usize , concat ! (
+                    as * const _ as usize } , 472usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFocusTextColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mBodyTextColor as
-                    * const _ as usize } , 468usize , concat ! (
+                    * const _ as usize } , 476usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mBodyTextColor ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mViewportStyleScrollbar as * const _ as usize } , 472usize
+                    mViewportStyleScrollbar as * const _ as usize } , 480usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mViewportStyleScrollbar ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mFocusRingWidth
-                    as * const _ as usize } , 536usize , concat ! (
+                    as * const _ as usize } , 544usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFocusRingWidth ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mExistThrottledUpdates as * const _ as usize } , 537usize
+                    mExistThrottledUpdates as * const _ as usize } , 545usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mExistThrottledUpdates ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mImageAnimationMode as * const _ as usize } , 538usize ,
+                    mImageAnimationMode as * const _ as usize } , 546usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mImageAnimationMode ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mImageAnimationModePref as * const _ as usize } , 540usize
+                    mImageAnimationModePref as * const _ as usize } , 548usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mImageAnimationModePref ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mLangGroupFontPrefs as * const _ as usize } , 544usize ,
+                    mLangGroupFontPrefs as * const _ as usize } , 552usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mLangGroupFontPrefs ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mBorderWidthTable
-                    as * const _ as usize } , 1184usize , concat ! (
+                    as * const _ as usize } , 1192usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mBorderWidthTable ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mInterruptChecksToSkip as * const _ as usize } , 1196usize
+                    mInterruptChecksToSkip as * const _ as usize } , 1204usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mInterruptChecksToSkip ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mElementsRestyled
-                    as * const _ as usize } , 1200usize , concat ! (
+                    as * const _ as usize } , 1208usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mElementsRestyled ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mFramesConstructed as * const _ as usize } , 1208usize ,
+                    mFramesConstructed as * const _ as usize } , 1216usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFramesConstructed ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mFramesReflowed
-                    as * const _ as usize } , 1216usize , concat ! (
+                    as * const _ as usize } , 1224usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFramesReflowed ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mReflowStartTime
-                    as * const _ as usize } , 1224usize , concat ! (
+                    as * const _ as usize } , 1232usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mReflowStartTime ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
                     mFirstNonBlankPaintTime as * const _ as usize } ,
-                    1232usize , concat ! (
+                    1240usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFirstNonBlankPaintTime ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mFirstClickTime
-                    as * const _ as usize } , 1240usize , concat ! (
+                    as * const _ as usize } , 1248usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFirstClickTime ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mFirstKeyTime as
-                    * const _ as usize } , 1248usize , concat ! (
+                    * const _ as usize } , 1256usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFirstKeyTime ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mFirstMouseMoveTime as * const _ as usize } , 1256usize ,
+                    mFirstMouseMoveTime as * const _ as usize } , 1264usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFirstMouseMoveTime ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mFirstScrollTime
-                    as * const _ as usize } , 1264usize , concat ! (
+                    as * const _ as usize } , 1272usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mFirstScrollTime ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
                     mInteractionTimeEnabled as * const _ as usize } ,
-                    1272usize , concat ! (
+                    1280usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mInteractionTimeEnabled ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
                     mLastStyleUpdateForAllAnimations as * const _ as usize } ,
-                    1280usize , concat ! (
+                    1288usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mLastStyleUpdateForAllAnimations )
                     ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mTelemetryScrollLastY as * const _ as usize } , 1288usize
+                    mTelemetryScrollLastY as * const _ as usize } , 1296usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mTelemetryScrollLastY ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mTelemetryScrollMaxY as * const _ as usize } , 1292usize ,
+                    mTelemetryScrollMaxY as * const _ as usize } , 1300usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mTelemetryScrollMaxY ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mTelemetryScrollTotalY as * const _ as usize } , 1296usize
+                    mTelemetryScrollTotalY as * const _ as usize } , 1304usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mTelemetryScrollTotalY ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) .
-                    mRestyleLoggingEnabled as * const _ as usize } , 1306usize
+                    mRestyleLoggingEnabled as * const _ as usize } , 1314usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mRestyleLoggingEnabled ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mInitialized as *
-                    const _ as usize } , 1307usize , concat ! (
+                    const _ as usize } , 1315usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mInitialized ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsPresContext ) ) . mLayoutPhaseCount
-                    as * const _ as usize } , 1308usize , concat ! (
+                    as * const _ as usize } , 1316usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsPresContext ) ,
                     "::" , stringify ! ( mLayoutPhaseCount ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsPIDOMWindowOuter {
         pub _base: [u64; 29usize],
     }
@@ -16507,76 +16514,76 @@ pub mod root {
                     & ( * ( 0 as * const nsNodeWeakReference ) ) . mNode as *
                     const _ as usize } , 24usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsNodeWeakReference
                     ) , "::" , stringify ! ( mNode ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
     pub struct nsDOMMutationObserver([u8; 0]);
-    pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_LISTENERMANAGER;
-    pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_PROPERTIES;
-    pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_ANONYMOUS_ROOT;
-    pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
-    pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_NATIVE_ANONYMOUS_ROOT;
-    pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_FORCE_XBL_BINDINGS;
-    pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_MAY_BE_IN_BINDING_MNGR;
-    pub const NODE_IS_EDITABLE: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_EDITABLE;
-    pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_NATIVE_ANONYMOUS;
-    pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_IN_SHADOW_TREE;
-    pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_EMPTY_SELECTOR;
-    pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_SLOW_SELECTOR;
-    pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_EDGE_CHILD_SELECTOR;
-    pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
-    pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_ALL_SELECTOR_FLAGS;
-    pub const NODE_NEEDS_FRAME: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_NEEDS_FRAME;
-    pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_DESCENDANTS_NEED_FRAMES;
-    pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_ACCESSKEY;
-    pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_DIRECTION_RTL;
-    pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_HAS_DIRECTION_LTR;
-    pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_ALL_DIRECTION_FLAGS;
-    pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_CHROME_ONLY_ACCESS;
-    pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
-    pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_SHARED_RESTYLE_BIT_1;
-    pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_SHARED_RESTYLE_BIT_2;
-    pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_SHARED_RESTYLE_BIT_1;
+    pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_LISTENERMANAGER;
+    pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_PROPERTIES;
+    pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_ANONYMOUS_ROOT;
+    pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
+    pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_NATIVE_ANONYMOUS_ROOT;
+    pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_FORCE_XBL_BINDINGS;
+    pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_MAY_BE_IN_BINDING_MNGR;
+    pub const NODE_IS_EDITABLE: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_EDITABLE;
+    pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_NATIVE_ANONYMOUS;
+    pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_IN_SHADOW_TREE;
+    pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_EMPTY_SELECTOR;
+    pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_SLOW_SELECTOR;
+    pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_EDGE_CHILD_SELECTOR;
+    pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
+    pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_ALL_SELECTOR_FLAGS;
+    pub const NODE_NEEDS_FRAME: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_NEEDS_FRAME;
+    pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_DESCENDANTS_NEED_FRAMES;
+    pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_ACCESSKEY;
+    pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_DIRECTION_RTL;
+    pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_HAS_DIRECTION_LTR;
+    pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_ALL_DIRECTION_FLAGS;
+    pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_CHROME_ONLY_ACCESS;
+    pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
+    pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_1;
+    pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_2;
+    pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_1;
     pub const NODE_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO:
-              root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_SHARED_RESTYLE_BIT_2;
-    pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_114 =
-        _bindgen_ty_114::NODE_TYPE_SPECIFIC_BITS_OFFSET;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum _bindgen_ty_114 {
+              root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_SHARED_RESTYLE_BIT_2;
+    pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_104 =
+        _bindgen_ty_104::NODE_TYPE_SPECIFIC_BITS_OFFSET;
+    #[repr(u32)]
+    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+    pub enum _bindgen_ty_104 {
         NODE_HAS_LISTENERMANAGER = 4,
         NODE_HAS_PROPERTIES = 8,
         NODE_IS_ANONYMOUS_ROOT = 16,
         NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = 32,
         NODE_IS_NATIVE_ANONYMOUS_ROOT = 64,
         NODE_FORCE_XBL_BINDINGS = 128,
         NODE_MAY_BE_IN_BINDING_MNGR = 256,
         NODE_IS_EDITABLE = 512,
@@ -19625,16 +19632,19 @@ pub mod root {
                     "Alignment of " , stringify ! ( nsILanguageAtomService )
                     ));
     }
     impl Clone for nsILanguageAtomService {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
+    pub struct nsBidi([u8; 0]);
+    #[repr(C)]
+    #[derive(Debug, Copy, Clone)]
     pub struct nsIPrintSettings([u8; 0]);
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
     pub struct nsITheme([u8; 0]);
     /**
  * Interface used for handling clicks on links
  */
     #[repr(C)]
@@ -19744,55 +19754,55 @@ pub mod root {
                     * ( 0 as * const nsRootPresContext_NotifyDidPaintTimer ) )
                     . mTimer as * const _ as usize } , 8usize , concat ! (
                     "Alignment of field: " , stringify ! (
                     nsRootPresContext_NotifyDidPaintTimer ) , "::" , stringify
                     ! ( mTimer ) ));
     }
     #[test]
     fn bindgen_test_layout_nsRootPresContext() {
-        assert_eq!(::std::mem::size_of::<nsRootPresContext>() , 1480usize ,
+        assert_eq!(::std::mem::size_of::<nsRootPresContext>() , 1488usize ,
                    concat ! ( "Size of: " , stringify ! ( nsRootPresContext )
                    ));
         assert_eq! (::std::mem::align_of::<nsRootPresContext>() , 8usize ,
                     concat ! (
                     "Alignment of " , stringify ! ( nsRootPresContext ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsRootPresContext ) ) .
-                    mNotifyDidPaintTimers as * const _ as usize } , 1320usize
+                    mNotifyDidPaintTimers as * const _ as usize } , 1328usize
                     , concat ! (
                     "Alignment of field: " , stringify ! ( nsRootPresContext )
                     , "::" , stringify ! ( mNotifyDidPaintTimers ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsRootPresContext ) ) .
                     mApplyPluginGeometryTimer as * const _ as usize } ,
-                    1400usize , concat ! (
+                    1408usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsRootPresContext )
                     , "::" , stringify ! ( mApplyPluginGeometryTimer ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsRootPresContext ) ) .
-                    mRegisteredPlugins as * const _ as usize } , 1408usize ,
+                    mRegisteredPlugins as * const _ as usize } , 1416usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsRootPresContext )
                     , "::" , stringify ! ( mRegisteredPlugins ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsRootPresContext ) ) .
-                    mWillPaintObservers as * const _ as usize } , 1456usize ,
+                    mWillPaintObservers as * const _ as usize } , 1464usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsRootPresContext )
                     , "::" , stringify ! ( mWillPaintObservers ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsRootPresContext ) ) .
                     mWillPaintFallbackEvent as * const _ as usize } ,
-                    1464usize , concat ! (
+                    1472usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsRootPresContext )
                     , "::" , stringify ! ( mWillPaintFallbackEvent ) ));
         assert_eq! (unsafe {
                     & ( * ( 0 as * const nsRootPresContext ) ) .
-                    mDOMGeneration as * const _ as usize } , 1472usize ,
+                    mDOMGeneration as * const _ as usize } , 1480usize ,
                     concat ! (
                     "Alignment of field: " , stringify ! ( nsRootPresContext )
                     , "::" , stringify ! ( mDOMGeneration ) ));
     }
     #[repr(i16)]
     #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     pub enum nsCSSKeyword {
         eCSSKeyword_UNKNOWN = -1,
@@ -28261,127 +28271,127 @@ pub mod root {
                    root::nsTArray<root::nsRect> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::nsRect>>() ,
                    8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<root::nsRect> ) ));
     }
     #[test]
     fn __bindgen_test_layout_template_52() {
+        assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::nsBidi>>()
+                   , 1usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::mozilla::DefaultDelete<root::nsBidi> ) ));
+        assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::nsBidi>>()
+                   , 1usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::mozilla::DefaultDelete<root::nsBidi> ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_template_53() {
         assert_eq!(::std::mem::size_of::<[u64; 29usize]>() , 232usize , concat
                    ! (
                    "Size of template specialization: " , stringify ! (
                    [u64; 29usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 29usize]>() , 8usize , concat
                    ! (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 29usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_53() {
+    fn __bindgen_test_layout_template_54() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_54() {
+    fn __bindgen_test_layout_template_55() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::CSSValue>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::CSSValue> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::CSSValue>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::CSSValue> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_55() {
+    fn __bindgen_test_layout_template_56() {
         assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>>()
                    , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>>()
                    , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::DefaultDelete<root::mozilla::dom::TimeoutManager>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_56() {
+    fn __bindgen_test_layout_template_57() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::nsISupports>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsISupports> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::nsISupports>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsISupports> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_57() {
+    fn __bindgen_test_layout_template_58() {
         assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIRunnable>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsCOMPtr<root::nsIRunnable> ) ));
         assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIRunnable>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCOMPtr<root::nsIRunnable> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_58() {
+    fn __bindgen_test_layout_template_59() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::nsIContent>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_59() {
+    fn __bindgen_test_layout_template_60() {
         assert_eq!(::std::mem::size_of::<[u64; 6usize]>() , 48usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u64; 6usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 6usize]>() , 8usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 6usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_60() {
+    fn __bindgen_test_layout_template_61() {
         assert_eq!(::std::mem::size_of::<root::mozilla::OwningNonNull<root::nsINode>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::OwningNonNull<root::nsINode> ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::OwningNonNull<root::nsINode>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::OwningNonNull<root::nsINode> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_61() {
-        assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
-                   (
-                   "Size of template specialization: " , stringify ! (
-                   [u32; 2usize] ) ));
-        assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
-                   (
-                   "Alignment of template specialization: " , stringify ! (
-                   [u32; 2usize] ) ));
-    }
-    #[test]
     fn __bindgen_test_layout_template_62() {
         assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u32; 2usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
@@ -28395,57 +28405,57 @@ pub mod root {
                    [u32; 2usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u32; 2usize] ) ));
     }
     #[test]
     fn __bindgen_test_layout_template_64() {
+        assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
+                   (
+                   "Size of template specialization: " , stringify ! (
+                   [u32; 2usize] ) ));
+        assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
+                   (
+                   "Alignment of template specialization: " , stringify ! (
+                   [u32; 2usize] ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_template_65() {
         assert_eq!(::std::mem::size_of::<[u32; 4usize]>() , 16usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u32; 4usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u32; 4usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_65() {
-        assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
-                   (
-                   "Size of template specialization: " , stringify ! (
-                   [u32; 2usize] ) ));
-        assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
-                   (
-                   "Alignment of template specialization: " , stringify ! (
-                   [u32; 2usize] ) ));
-    }
-    #[test]
     fn __bindgen_test_layout_template_66() {
         assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u32; 2usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u32; 2usize] ) ));
     }
     #[test]
     fn __bindgen_test_layout_template_67() {
-        assert_eq!(::std::mem::size_of::<[u32; 4usize]>() , 16usize , concat !
-                   (
-                   "Size of template specialization: " , stringify ! (
-                   [u32; 4usize] ) ));
-        assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat !
-                   (
-                   "Alignment of template specialization: " , stringify ! (
-                   [u32; 4usize] ) ));
+        assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
+                   (
+                   "Size of template specialization: " , stringify ! (
+                   [u32; 2usize] ) ));
+        assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
+                   (
+                   "Alignment of template specialization: " , stringify ! (
+                   [u32; 2usize] ) ));
     }
     #[test]
     fn __bindgen_test_layout_template_68() {
         assert_eq!(::std::mem::size_of::<[u32; 4usize]>() , 16usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u32; 4usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat !
@@ -28461,35 +28471,35 @@ pub mod root {
                    [u32; 4usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u32; 4usize] ) ));
     }
     #[test]
     fn __bindgen_test_layout_template_70() {
+        assert_eq!(::std::mem::size_of::<[u32; 4usize]>() , 16usize , concat !
+                   (
+                   "Size of template specialization: " , stringify ! (
+                   [u32; 4usize] ) ));
+        assert_eq!(::std::mem::align_of::<[u32; 4usize]>() , 4usize , concat !
+                   (
+                   "Alignment of template specialization: " , stringify ! (
+                   [u32; 4usize] ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_template_71() {
         assert_eq!(::std::mem::size_of::<u32>() , 4usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u32 )
                    ));
         assert_eq!(::std::mem::align_of::<u32>() , 4usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u32 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_71() {
-        assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
-                   (
-                   "Size of template specialization: " , stringify ! (
-                   [u32; 2usize] ) ));
-        assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
-                   (
-                   "Alignment of template specialization: " , stringify ! (
-                   [u32; 2usize] ) ));
-    }
-    #[test]
     fn __bindgen_test_layout_template_72() {
         assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u32; 2usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
@@ -28503,408 +28513,419 @@ pub mod root {
                    [u32; 2usize] ) ));
         assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u32; 2usize] ) ));
     }
     #[test]
     fn __bindgen_test_layout_template_74() {
+        assert_eq!(::std::mem::size_of::<[u32; 2usize]>() , 8usize , concat !
+                   (
+                   "Size of template specialization: " , stringify ! (
+                   [u32; 2usize] ) ));
+        assert_eq!(::std::mem::align_of::<[u32; 2usize]>() , 4usize , concat !
+                   (
+                   "Alignment of template specialization: " , stringify ! (
+                   [u32; 2usize] ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_template_75() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<f64>>() , 8usize ,
                    concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<f64> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<f64>>() , 8usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<f64> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_75() {
+    fn __bindgen_test_layout_template_76() {
         assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_76() {
+    fn __bindgen_test_layout_template_77() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<root::RefPtr<root::mozilla::dom::DOMIntersectionObserverEntry>>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_77() {
+    fn __bindgen_test_layout_template_78() {
         assert_eq!(::std::mem::size_of::<root::mozilla::UniquePtr<root::ProfilerBacktrace,
                                                root::ProfilerBacktraceDestructor>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::UniquePtr<root::ProfilerBacktrace,
                          root::ProfilerBacktraceDestructor>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::UniquePtr<root::ProfilerBacktrace,
                                                 root::ProfilerBacktraceDestructor>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::UniquePtr<root::ProfilerBacktrace,
                          root::ProfilerBacktraceDestructor>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_78() {
+    fn __bindgen_test_layout_template_79() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::FontFamilyName>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::FontFamilyName> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::FontFamilyName>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::FontFamilyName> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_79() {
+    fn __bindgen_test_layout_template_80() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<::std::os::raw::c_uint>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<::std::os::raw::c_uint> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<::std::os::raw::c_uint>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<::std::os::raw::c_uint> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_80() {
+    fn __bindgen_test_layout_template_81() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::FramePropertyTable_PropertyValue>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_81() {
+    fn __bindgen_test_layout_template_82() {
         assert_eq!(::std::mem::size_of::<root::nsPtrHashKey<root::nsIFrame>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsPtrHashKey<root::nsIFrame> ) ));
         assert_eq!(::std::mem::align_of::<root::nsPtrHashKey<root::nsIFrame>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsPtrHashKey<root::nsIFrame> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_82() {
+    fn __bindgen_test_layout_template_83() {
         assert_eq!(::std::mem::size_of::<[u64; 6usize]>() , 48usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u64; 6usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 6usize]>() , 8usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 6usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_83() {
+    fn __bindgen_test_layout_template_84() {
         assert_eq!(::std::mem::size_of::<root::mozilla::OwningNonNull<root::mozilla::EffectCompositor_AnimationStyleRuleProcessor>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::OwningNonNull<root::mozilla::EffectCompositor_AnimationStyleRuleProcessor>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::OwningNonNull<root::mozilla::EffectCompositor_AnimationStyleRuleProcessor>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::OwningNonNull<root::mozilla::EffectCompositor_AnimationStyleRuleProcessor>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_84() {
+    fn __bindgen_test_layout_template_85() {
         assert_eq!(::std::mem::size_of::<root::mozilla::DefaultDelete<root::ProxyBehaviour>>()
                    , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::DefaultDelete<root::ProxyBehaviour> ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::DefaultDelete<root::ProxyBehaviour>>()
                    , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::DefaultDelete<root::ProxyBehaviour> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_template_85() {
+    fn __bindgen_test_layout_template_86() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::URLExtraData>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::URLExtraData> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::URLExtraData>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::URLExtraData> ) ));