Merge mozilla-central to mozilla-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 28 Jul 2017 15:25:58 +0200
changeset 371718 6e3ba727a94a487b0df71986d7456101a3486dbf
parent 371717 bc37ab3e9abcfaa3e25b0b9681ebd345d042b26d (current diff)
parent 371614 16ffc1d05422a81099ce8b9b59de66dde4c8b2f0 (diff)
child 371719 b5d83e1d3a96995d3bb0dba9785623716c5a3d90
push id32253
push userkwierso@gmail.com
push dateSat, 29 Jul 2017 00:40:54 +0000
treeherdermozilla-central@ec666e910442 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to mozilla-inbound
browser/base/content/browser.js
browser/components/newtab/PreviewProvider.jsm
browser/components/newtab/tests/browser/blue_page.html
browser/components/newtab/tests/browser/browser_PreviewProvider.js
dom/media/MediaDecoderReaderWrapper.cpp
dom/media/MediaDecoderReaderWrapper.h
dom/media/fmp4/MP4Stream.cpp
dom/media/fmp4/MP4Stream.h
js/xpconnect/src/XPCConvert.cpp
modules/libpref/init/all.js
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
third_party/rust/bindgen/src/ir/named.rs
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1088,21 +1088,17 @@ pref("security.sandbox.gpu.level", 0);
 //       write access to home directory is prevented, read and write access
 //       to ~/Library and profile directories are prevented (excluding
 //       $PROFILE/{extensions,chrome})"
 // 3 -> "no global read/write access, read access permitted to
 //       $PROFILE/{extensions,chrome}"
 // This setting is read when the content process is started. On Mac the content
 // process is killed when all windows are closed, so a change will take effect
 // when the 1st window is opened.
-#if defined(NIGHTLY_BUILD)
 pref("security.sandbox.content.level", 3);
-#else
-pref("security.sandbox.content.level", 1);
-#endif
 #endif
 
 #if defined(XP_LINUX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
 // This pref is introduced as part of bug 742434, the naming is inspired from
 // its Windows/Mac counterpart, but on Linux it's an integer which means:
 // 0 -> "no sandbox"
 // 1 -> "content sandbox using seccomp-bpf when available"
 // 2 -> "seccomp-bpf + write file broker"
--- a/browser/base/content/browser-media.js
+++ b/browser/base/content/browser-media.js
@@ -167,17 +167,17 @@ var gEMEHandler = {
 
     let mainAction = {
       label: gNavigatorBundle.getString(btnLabelId),
       accessKey: gNavigatorBundle.getString(btnAccessKeyId),
       callback() {
         if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
           openPreferences("paneContent", {origin: "browserMedia"});
         } else {
-          openPreferences("panePrivacy", {origin: "browserMedia"});
+          openPreferences("general-drm", {origin: "browserMedia"});
         }
       },
       dismiss: true
     };
     let options = {
       dismissed: true,
       eventCallback: aTopic => aTopic == "swapping",
       learnMoreURL: Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content",
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3836,22 +3836,22 @@ const BrowserSearch = {
       searchBar.select();
       focusUrlBarIfSearchFieldIsNotActive(searchBar);
     };
     if (placement && placement.area == CustomizableUI.AREA_PANEL) {
       // The panel is not constructed until the first time it is shown.
       PanelUI.show().then(focusSearchBar);
       return;
     }
-    if (placement && placement.area == CustomizableUI.AREA_NAVBAR && searchBar &&
-        searchBar.parentNode.getAttribute("overflowedItem") == "true") {
+    if (placement && searchBar &&
+        ((searchBar.parentNode.getAttribute("overflowedItem") == "true" &&
+          placement.area == CustomizableUI.AREA_NAVBAR) ||
+         placement.area == CustomizableUI.AREA_FIXED_OVERFLOW_PANEL)) {
       let navBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
-      navBar.overflowable.show().then(() => {
-        focusSearchBar();
-      });
+      navBar.overflowable.show().then(focusSearchBar);
       return;
     }
     if (searchBar) {
       if (window.fullScreen)
         FullScreen.showNavToolbox();
       searchBar.select();
     }
     focusUrlBarIfSearchFieldIsNotActive(searchBar);
--- a/browser/base/content/test/performance/browser_startup_images.js
+++ b/browser/base/content/test/performance/browser_startup_images.js
@@ -26,16 +26,23 @@
 const whitelist = [
   // Photon-only entries
   {
     file: "chrome://browser/skin/stop.svg",
     platforms: ["linux", "win", "macosx"],
     photon: true,
   },
 
+  // Non-Photon-only entries
+  {
+    file: "chrome://browser/skin/toolbarbutton-dropdown-arrow.png",
+    platforms: ["linux", "win", "macosx"],
+    photon: false,
+  },
+
   // Shared entries
   {
     file: "chrome://browser/skin/arrow-left.svg",
     platforms: ["linux", "win", "macosx"],
   },
   {
     file: "chrome://browser/skin/arrow-dropdown.svg",
     platforms: ["linux", "win", "macosx"],
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -79,19 +79,16 @@ var whitelist = [
 
   // Add-on API introduced in bug 1118285
   {file: "resource://app/modules/NewTabURL.jsm"},
 
   // browser/components/newtab bug 1355166
   {file: "resource://app/modules/NewTabSearchProvider.jsm"},
   {file: "resource://app/modules/NewTabWebChannel.jsm"},
 
-  // Activity Stream currently needs this file in all channels except Nightly
-  {file: "resource://app/modules/PreviewProvider.jsm", skipNightly: true},
-
   // layout/mathml/nsMathMLChar.cpp
   {file: "resource://gre/res/fonts/mathfontSTIXGeneral.properties"},
   {file: "resource://gre/res/fonts/mathfontUnicode.properties"},
 
   // toolkit/components/places/ColorAnalyzer_worker.js
   {file: "resource://gre/modules/ClusterLib.js"},
   {file: "resource://gre/modules/ColorConversion.js"},
 
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -325,16 +325,17 @@ var CustomizableUIInternal = {
 
     if (gPhotonStructure) {
       if (gAreas.has(CustomizableUI.AREA_PANEL)) {
         this.unregisterArea(CustomizableUI.AREA_PANEL, true);
       }
       this.registerArea(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, {
         type: CustomizableUI.TYPE_MENU_PANEL,
         defaultPlacements: [],
+        anchor: "nav-bar-overflow-button",
       }, true);
     } else {
       if (gAreas.has(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL)) {
         this.unregisterArea(CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, true);
       }
       // In tests we destroy some widgets. Those should be removed from the
       // default placements when re-registering the panel.
       let placementsToUse = Array.from(gDefaultPanelPlacements);
--- a/browser/components/customizableui/test/browser_901207_searchbar_in_panel.js
+++ b/browser/components/customizableui/test/browser_901207_searchbar_in_panel.js
@@ -11,50 +11,48 @@ async function waitForSearchBarFocus() {
   await waitForCondition(function() {
     logActiveElement();
     return document.activeElement === searchbar.textbox.inputField;
   });
 }
 
 // Ctrl+K should open the menu panel and focus the search bar if the search bar is in the panel.
 add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.photon.structure.enabled", false]]});
+  await SpecialPowers.pushPrefEnv({set: [["browser.photon.structure.enabled", true]]});
   let searchbar = document.getElementById("searchbar");
   gCustomizeMode.addToPanel(searchbar);
   let placement = CustomizableUI.getPlacementOfWidget("search-container");
-  is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
+  is(placement.area, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, "Should be in panel");
 
-  let shownPanelPromise = promisePanelShown(window);
+  let shownPanelPromise = promiseOverflowShown(window);
   sendWebSearchKeyCommand();
   await shownPanelPromise;
 
   await waitForSearchBarFocus();
 
-  let hiddenPanelPromise = promisePanelHidden(window);
+  let hiddenPanelPromise = promiseOverflowHidden(window);
   EventUtils.synthesizeKey("VK_ESCAPE", {});
   await hiddenPanelPromise;
   CustomizableUI.reset();
 });
 
 // Ctrl+K should give focus to the searchbar when the searchbar is in the menupanel and the panel is already opened.
 add_task(async function() {
   let searchbar = document.getElementById("searchbar");
   gCustomizeMode.addToPanel(searchbar);
   let placement = CustomizableUI.getPlacementOfWidget("search-container");
-  is(placement.area, CustomizableUI.AREA_PANEL, "Should be in panel");
+  is(placement.area, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL, "Should be in panel");
 
-  let shownPanelPromise = promisePanelShown(window);
-  PanelUI.toggle({type: "command"});
-  await shownPanelPromise;
+  await document.getElementById("nav-bar").overflowable.show();
 
   sendWebSearchKeyCommand();
 
   await waitForSearchBarFocus();
 
-  let hiddenPanelPromise = promisePanelHidden(window);
+  let hiddenPanelPromise = promiseOverflowHidden(window);
   EventUtils.synthesizeKey("VK_ESCAPE", {});
   await hiddenPanelPromise;
   CustomizableUI.reset();
 });
 
 // Ctrl+K should open the overflow panel and focus the search bar if the search bar is overflowed.
 add_task(async function() {
   this.originalWindowWidth = window.outerWidth;
--- a/browser/components/newtab/NewTabSearchProvider.jsm
+++ b/browser/components/newtab/NewTabSearchProvider.jsm
@@ -63,21 +63,17 @@ SearchProvider.prototype = {
   },
 
   removeFormHistory({browser}, suggestion) {
     ContentSearch.removeFormHistoryEntry({target: browser}, suggestion);
   },
 
   manageEngines(browser) {
     const browserWin = browser.ownerGlobal;
-    if (Services.prefs.getBoolPref("browser.preferences.useOldOrganization")) {
-      browserWin.openPreferences("paneSearch", { origin: "contentSearch" });
-    } else {
-      browserWin.openPreferences("paneGeneral", { origin: "contentSearch" });
-    }
+    browserWin.openPreferences("paneSearch", { origin: "contentSearch" });
   },
 
   async asyncGetState() {
     let state = await ContentSearch.currentStateObj(true);
     return state;
   },
 
   async asyncPerformSearch({browser}, searchData) {
deleted file mode 100644
--- a/browser/components/newtab/PreviewProvider.jsm
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["PreviewProvider"];
-
-const {utils: Cu} = Components;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/PageThumbs.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-const {OS} = Cu.import("resource://gre/modules/osfile.jsm", {});
-
-XPCOMUtils.defineLazyModuleGetter(this, "BackgroundPageThumbs",
-  "resource://gre/modules/BackgroundPageThumbs.jsm");
-XPCOMUtils.defineLazyServiceGetter(this, "MIMEService",
-  "@mozilla.org/mime;1", "nsIMIMEService");
-
-let PreviewProvider = {
-  /**
-   * Returns a thumbnail as a data URI for a url, creating it if necessary
-   *
-   * @param {String} url
-   *        a url to obtain a thumbnail for
-   * @return {Promise} A Promise that resolves with a base64 encoded thumbnail
-   */
-  getThumbnail: async function PreviewProvider_getThumbnail(url) {
-    try {
-      await BackgroundPageThumbs.captureIfMissing(url);
-      let imgPath = PageThumbsStorage.getFilePathForURL(url);
-
-      // OS.File object used to easily read off-thread
-      let file = await OS.File.open(imgPath, {read: true, existing: true});
-
-      // nsIFile object needed for MIMEService
-      let nsFile = FileUtils.File(imgPath);
-
-      let contentType = MIMEService.getTypeFromFile(nsFile);
-      let bytes = await file.read();
-      let encodedData = btoa(String.fromCharCode.apply(null, bytes));
-      file.close();
-      return `data:${contentType};base64,${encodedData}`;
-    } catch (err) {
-      Cu.reportError(`PreviewProvider_getThumbnail error: ${err}`);
-      throw err;
-    }
-  }
-};
--- a/browser/components/newtab/moz.build
+++ b/browser/components/newtab/moz.build
@@ -13,18 +13,17 @@ XPCSHELL_TESTS_MANIFESTS += [
     'tests/xpcshell/xpcshell.ini',
 ]
 
 EXTRA_JS_MODULES += [
     'NewTabPrefsProvider.jsm',
     'NewTabRemoteResources.jsm',
     'NewTabSearchProvider.jsm',
     'NewTabURL.jsm',
-    'NewTabWebChannel.jsm',
-    'PreviewProvider.jsm'
+    'NewTabWebChannel.jsm'
 ]
 
 XPIDL_SOURCES += [
     'nsIAboutNewTabService.idl',
 ]
 
 XPIDL_MODULE = 'browser-newtab'
 
deleted file mode 100644
--- a/browser/components/newtab/tests/browser/blue_page.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-  <meta charset="utf-8">
-</head>
-<body style="background-color: blue">
-</body>
-</html>
--- a/browser/components/newtab/tests/browser/browser.ini
+++ b/browser/components/newtab/tests/browser/browser.ini
@@ -1,9 +1,6 @@
 [DEFAULT]
 support-files =
-  blue_page.html
   dummy_page.html
 
-[browser_PreviewProvider.js]
-skip-if = os == 'linux' || os == 'win' # bug 1343150
 [browser_remotenewtab_pageloads.js]
 [browser_newtab_overrides.js]
deleted file mode 100644
--- a/browser/components/newtab/tests/browser/browser_PreviewProvider.js
+++ /dev/null
@@ -1,87 +0,0 @@
-"use strict";
-
-let Cu = Components.utils;
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PreviewProvider",
-                                  "resource:///modules/PreviewProvider.jsm");
-
-var oldEnabledPref = Services.prefs.getBoolPref("browser.pagethumbnails.capturing_disabled");
-Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", false);
-
-registerCleanupFunction(function() {
-  while (gBrowser.tabs.length > 1) {
-    gBrowser.removeTab(gBrowser.tabs[1]);
-  }
-  Services.prefs.setBoolPref("browser.pagethumbnails.capturing_disabled", oldEnabledPref);
-});
-
-const TEST_URL = "https://example.com/browser/browser/components/newtab/tests/browser/blue_page.html";
-
-function pixelsForDataURI(dataURI, options) {
-  return new Promise(resolve => {
-    if (!options) {
-      options = {};
-    }
-    let {width, height} = options;
-    if (!width) {
-      width = 100;
-    }
-    if (!height) {
-      height = 100;
-    }
-
-    let htmlns = "http://www.w3.org/1999/xhtml";
-    let img = document.createElementNS(htmlns, "img");
-    img.setAttribute("src", dataURI);
-
-    img.addEventListener("load", function() {
-      let canvas = document.createElementNS(htmlns, "canvas");
-      canvas.setAttribute("width", width);
-      canvas.setAttribute("height", height);
-      let ctx = canvas.getContext("2d");
-      ctx.drawImage(img, 0, 0, width, height);
-      let result = ctx.getImageData(0, 0, width, height).data;
-      resolve(result);
-    }, {once: true});
-  });
-}
-
-function* chunk_four(listData) {
-  let index = 0;
-  while (index < listData.length) {
-    yield listData.slice(index, index + 5);
-    index += 4;
-  }
-}
-
-add_task(async function open_page() {
-  let dataURI = await PreviewProvider.getThumbnail(TEST_URL);
-  let pixels = await pixelsForDataURI(dataURI, {width: 10, height: 10});
-  let rgbCount = {r: 0, g: 0, b: 0, a: 0};
-  for (let [r, g, b, a] of chunk_four(pixels)) {
-    if (r === 255) {
-      rgbCount.r += 1;
-    }
-    if (g === 255) {
-      rgbCount.g += 1;
-    }
-    if (b === 255) {
-      rgbCount.b += 1;
-    }
-    if (a === 255) {
-      rgbCount.a += 1;
-    }
-  }
-  Assert.equal(`${rgbCount.r},${rgbCount.g},${rgbCount.b},${rgbCount.a}`,
-      "0,0,100,100", "there should be 100 blue-only pixels at full opacity");
-});
-
-add_task(async function invalid_url() {
-  try {
-    await PreviewProvider.getThumbnail("invalid:URL");
-  } catch (err) {
-    Assert.ok(true, "URL Failed");
-  }
-});
--- a/browser/components/preferences/in-content-new/main.xul
+++ b/browser/components/preferences/in-content-new/main.xul
@@ -692,17 +692,17 @@
                  accesskey="&actionColumn2.accesskey;" persist="sortDirection"
                  flex="1"/>
     </listheader>
   </richlistbox>
 </groupbox>
 
 
 <!-- DRM Content -->
-<groupbox id="drmGroup" data-category="paneGeneral" hidden="true">
+<groupbox id="drmGroup" data-category="paneGeneral" data-subcategory="drm" hidden="true">
   <caption><label>&drmContent2.label;</label></caption>
   <grid id="contentGrid2">
     <columns>
       <column flex="1"/>
       <column/>
     </columns>
     <rows id="contentRows-2">
       <row id="playDRMContentRow">
--- a/browser/components/preferences/in-content-new/privacy.xul
+++ b/browser/components/preferences/in-content-new/privacy.xul
@@ -361,18 +361,18 @@
 </groupbox>
 
 <!-- Address Bar -->
 <groupbox id="locationBarGroup"
           data-category="panePrivacy"
           hidden="true">
   <caption><label>&addressBar.label;</label></caption>
   <label id="locationBarSuggestionLabel">&addressBar.suggest.label;</label>
-  <checkbox id="historySuggestion" label="&locbar.history.label;"
-            accesskey="&locbar.history.accesskey;"
+  <checkbox id="historySuggestion" label="&locbar.history2.label;"
+            accesskey="&locbar.history2.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('search')">
@@ -484,18 +484,18 @@
                 accesskey="&trackingProtectionExceptions.accesskey;"
                 preference="pref.privacy.disable_button.tracking_protection_exceptions"
                 searchkeywords="&removepermission.label;
                                 &removeallpermissions.label;
                                 &button.cancel.label;
                                 &button.ok.label;"/>
         <button id="changeBlockList"
                 class="accessory-button"
-                label="&changeBlockList.label;"
-                accesskey="&changeBlockList.accesskey;"
+                label="&changeBlockList2.label;"
+                accesskey="&changeBlockList2.accesskey;"
                 preference="pref.privacy.disable_button.change_blocklist"
                 searchkeywords="&button.cancel.label; &button.ok.label;"/>
       </vbox>
     </hbox>
     <vbox id="doNotTrackLearnMoreBox">
       <label>&doNotTrack.description;<label
       class="learnMore text-link" href="https://www.mozilla.org/dnt"
       >&doNotTrack.learnMore.label;</label></label>
@@ -669,18 +669,18 @@
               accesskey="&enableOCSP.accesskey;"
               onsyncfrompreference="return gPrivacyPane.readEnableOCSP();"
               onsynctopreference="return gPrivacyPane.writeEnableOCSP();"
               preference="security.OCSP.enabled"
               flex="1" />
     <vbox>
       <button id="viewCertificatesButton"
               class="accessory-button"
-              label="&viewCerts.label;"
-              accesskey="&viewCerts.accesskey;"
+              label="&viewCerts2.label;"
+              accesskey="&viewCerts2.accesskey;"
               preference="security.disable_button.openCertManager"
               searchkeywords="&certmgr.tab.mine;
                               &certmgr.tab.others2;
                               &certmgr.tab.websites3;
                               &certmgr.tab.ca;
                               &certmgr.tab.orphan2;
                               &certmgr.mine;
                               &certmgr.others;
@@ -689,18 +689,18 @@
                               &certmgr.orphans;
                               &certmgr.certname;
                               &certmgr.tokenname;
                               &certmgr.view2.label;
                               &certmgr.export.label;
                               &certmgr.delete2.label;"/>
       <button id="viewSecurityDevicesButton"
               class="accessory-button"
-              label="&viewSecurityDevices.label;"
-              accesskey="&viewSecurityDevices.accesskey;"
+              label="&viewSecurityDevices2.label;"
+              accesskey="&viewSecurityDevices2.accesskey;"
               preference="security.disable_button.openDeviceManager"
               searchkeywords="&devmgr.title;
                               &devmgr.devlist.label;
                               &devmgr.details.title;
                               &devmgr.details.title2;
                               &devmgr.button.login.label;
                               &devmgr.button.logout.label;
                               &devmgr.button.changepw.label;
--- a/browser/components/preferences/in-content-new/sync.xul
+++ b/browser/components/preferences/in-content-new/sync.xul
@@ -65,22 +65,22 @@
         </groupbox>
       </vbox>
       <vbox>
         <html:img class="fxaSyncIllustration" src="chrome://browser/skin/fxa/sync-illustration.svg"/>
       </vbox>
     </hbox>
     <label class="fxaMobilePromo">
         &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces
-        --><label id="fxaMobilePromo-android"
-                  class="androidLink text-link"><!--
+        --><image class="androidLink"></image><label id="fxaMobilePromo-android"
+                  class="text-link"><!--
         -->&mobilePromo3.androidLink;</label><!--
         -->&mobilePromo3.iOSBefore;<!--
-        --><label id="fxaMobilePromo-ios"
-                  class="iOSLink text-link"><!--
+        --><image class="iOSLink"></image><label id="fxaMobilePromo-ios"
+                  class="text-link"><!--
         -->&mobilePromo3.iOSLink;</label><!--
         -->&mobilePromo3.end;
     </label>
   </vbox>
 
   <vbox id="hasFxaAccount">
     <hbox>
       <vbox id="fxaContentWrapper">
@@ -213,20 +213,20 @@
                   label="&saveChangeSyncDeviceName.label;"
                   accesskey="&saveChangeSyncDeviceName.accesskey;"
                   hidden="true"/>
         </hbox>
       </hbox>
     </groupbox>
     <label class="fxaMobilePromo">
         &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces
-        --><label class="androidLink text-link" id="fxaMobilePromo-android-hasFxaAccount"><!--
+        --><image class="androidLink"></image><label class="text-link" id="fxaMobilePromo-android-hasFxaAccount"><!--
         -->&mobilePromo3.androidLink;</label><!--
         -->&mobilePromo3.iOSBefore;<!--
-        --><label class="iOSLink text-link" id="fxaMobilePromo-ios-hasFxaAccount"><!--
+        --><image class="iOSLink"></image><label class="text-link" id="fxaMobilePromo-ios-hasFxaAccount"><!--
         -->&mobilePromo3.iOSLink;</label><!--
         -->&mobilePromo3.end;
     </label>
     <vbox id="tosPP-small" align="start">
       <label id="tosPP-small-ToS" class="text-link">
         &prefs.tosLink.label;
       </label>
       <label id="tosPP-small-PP" class="text-link">
--- a/browser/config/mozconfigs/linux64/debug-asan
+++ b/browser/config/mozconfigs/linux64/debug-asan
@@ -1,13 +1,15 @@
 # Use at least -O1 for optimization to avoid stack space
 # exhaustions caused by Clang function inlining.
 ac_add_options --enable-debug
 ac_add_options --enable-optimize="-O1"
 
+. $topsrcdir/build/mozconfig.stylo
+
 # ASan specific options on Linux
 ac_add_options --enable-valgrind
 
 . $topsrcdir/build/unix/mozconfig.asan
 
 export PKG_CONFIG_LIBDIR=/usr/lib64/pkgconfig:/usr/share/pkgconfig
 . $topsrcdir/build/unix/mozconfig.gtk
 
--- a/browser/config/mozconfigs/linux64/hazards
+++ b/browser/config/mozconfigs/linux64/hazards
@@ -15,16 +15,18 @@ MOZ_AUTOMATION_PACKAGE=0
 MOZ_AUTOMATION_PACKAGE_TESTS=0
 MOZ_AUTOMATION_UPLOAD=0
 
 . "$topsrcdir/build/mozconfig.common"
 ac_add_options --enable-elf-hack
 
 . "$topsrcdir/build/unix/mozconfig.stdcxx"
 
+. "$topsrcdir/build/mozconfig.stylo"
+
 # The objdir must be at a known location so its path can be stripped from the
 # filenames stored by the analysis
 mk_add_options MOZ_OBJDIR=obj-analyzed
 
 # The configuration options are chosen to compile the most code
 # (--enable-debug, --enable-tests) in the trickiest way possible
 # (--enable-optimize) to maximize the chance of seeing tricky static orderings.
 ac_add_options --enable-debug
--- a/browser/extensions/activity-stream/lib/TopSitesFeed.jsm
+++ b/browser/extensions/activity-stream/lib/TopSitesFeed.jsm
@@ -7,19 +7,16 @@ const {utils: Cu} = Components;
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 const {actionCreators: ac, actionTypes: at} = Cu.import("resource://activity-stream/common/Actions.jsm", {});
 const {Prefs} = Cu.import("resource://activity-stream/lib/ActivityStreamPrefs.jsm", {});
 const {insertPinned} = Cu.import("resource://activity-stream/common/Reducers.jsm", {});
 
 XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils",
   "resource://gre/modules/NewTabUtils.jsm");
-// Keep a reference to PreviewProvider.jsm until it's good to remove. See #2849
-XPCOMUtils.defineLazyModuleGetter(this, "PreviewProvider",
-  "resource://app/modules/PreviewProvider.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Screenshots",
   "resource://activity-stream/lib/Screenshots.jsm");
 
 const TOP_SITES_SHOWMORE_LENGTH = 12;
 const UPDATE_TIME = 15 * 60 * 1000; // 15 minutes
 const DEFAULT_TOP_SITES = [];
 
 this.TopSitesFeed = class TopSitesFeed {
--- a/browser/extensions/formautofill/test/unit/head.js
+++ b/browser/extensions/formautofill/test/unit/head.js
@@ -198,17 +198,17 @@ function objectMatches(object, fields) {
     actual[key] = object[key];
   }
   return ObjectUtils.deepEqual(actual, fields);
 }
 
 add_task(async function head_initialize() {
   Services.prefs.setBoolPref("extensions.formautofill.experimental", true);
   Services.prefs.setBoolPref("extensions.formautofill.heuristics.enabled", true);
-  Services.prefs.setBoolPref("dom.forms.autocomplete.experimental", true);
+  Services.prefs.setBoolPref("dom.forms.autocomplete.formautofill", true);
 
   // Clean up after every test.
   do_register_cleanup(function head_cleanup() {
     Services.prefs.clearUserPref("extensions.formautofill.experimental");
     Services.prefs.clearUserPref("extensions.formautofill.heuristics.enabled");
-    Services.prefs.clearUserPref("dom.forms.autocomplete.experimental");
+    Services.prefs.clearUserPref("dom.forms.autocomplete.formautofill");
   });
 });
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -125,20 +125,20 @@ available. -->
 <!ENTITY certificateTab.label            "Certificates">
 <!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">
-<!ENTITY viewSecurityDevices.label       "Security Devices">
-<!ENTITY viewSecurityDevices.accesskey   "D">
+<!ENTITY viewCerts2.label                "View Certificates…">
+<!ENTITY viewCerts2.accesskey            "C">
+<!ENTITY viewSecurityDevices2.label      "Security Devices…">
+<!ENTITY viewSecurityDevices2.accesskey  "D">
 
 <!ENTITY performance.label               "Performance">
 <!ENTITY useRecommendedPerformanceSettings2.label
                                          "Use recommended performance settings">
 <!ENTITY useRecommendedPerformanceSettings2.description
                                          "These settings are tailored to your computer’s hardware and operating system.">
 <!ENTITY useRecommendedPerformanceSettings2.accesskey
                                          "U">
--- a/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
@@ -17,31 +17,31 @@
 
 <!-- LOCALIZATION NOTE (trackingProtectionPBM5.label): This string is displayed if privacy.trackingprotection.ui.enabled is set to true. This currently happens on the release and beta channel. -->
 <!ENTITY trackingProtectionPBM5.label         "Use Tracking Protection in Private Windows">
 <!ENTITY trackingProtectionPBM5.accesskey     "v">
 <!-- LOCALIZATION NOTE (trackingProtectionPBM6.label): This string is displayed if privacy.trackingprotection.ui.enabled is set to false. This currently happens on the nightly channel. -->
 <!ENTITY trackingProtectionPBM6.label         "Use Tracking Protection in Private Browsing to block known trackers">
 <!ENTITY trackingProtectionPBM6.accesskey     "v">
 <!ENTITY trackingProtectionPBMLearnMore.label "Learn more">
-<!ENTITY changeBlockList.label          "Change Block List">
-<!ENTITY changeBlockList.accesskey      "C">
+<!ENTITY changeBlockList2.label               "Change Block List…">
+<!ENTITY changeBlockList2.accesskey           "C">
 
 <!ENTITY  doNotTrack.description        "Send websites a “Do Not Track” signal that you don’t want to be tracked">
 <!ENTITY  doNotTrack.learnMore.label    "Learn more">
 <!ENTITY  doNotTrack.default.label      "Only when using Tracking Protection">
 <!ENTITY  doNotTrack.always.label       "Always">
 
 <!ENTITY  history.label                 "History">
 <!ENTITY  permissions.label             "Permissions">
 
 <!ENTITY  addressBar.label              "Address Bar">
 <!ENTITY  addressBar.suggest.label      "When using the address bar, suggest">
-<!ENTITY  locbar.history.label          "History">
-<!ENTITY  locbar.history.accesskey      "H">
+<!ENTITY  locbar.history2.label         "Browsing history">
+<!ENTITY  locbar.history2.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  suggestionSettings2.label     "Change preferences for search engine suggestions">
--- a/browser/modules/ContentSearch.jsm
+++ b/browser/modules/ContentSearch.jsm
@@ -408,24 +408,18 @@ this.ContentSearch = {
   _onMessageSearch(msg, data) {
     this.performSearch(msg, data);
   },
 
   _onMessageSetCurrentEngine(msg, data) {
     Services.search.currentEngine = Services.search.getEngineByName(data);
   },
 
-  _onMessageManageEngines(msg, data) {
-    let browserWin = msg.target.ownerGlobal;
-    let pref = Services.prefs.getBoolPref("browser.preferences.useOldOrganization");
-    if (pref) {
-      browserWin.openPreferences("paneSearch", {origin: "contentSearch"});
-    } else {
-      browserWin.openPreferences("general-search", {origin: "contentSearch"});
-    }
+  _onMessageManageEngines(msg) {
+    msg.target.ownerGlobal.openPreferences("paneSearch", { origin: "contentSearch" });
   },
 
   async _onMessageGetSuggestions(msg, data) {
     this._ensureDataHasProperties(data, [
       "engineName",
       "searchString",
     ]);
     let {engineName, searchString} = data;
--- a/browser/themes/shared/downloads/indicator.inc.css
+++ b/browser/themes/shared/downloads/indicator.inc.css
@@ -16,33 +16,25 @@
   min-width: 16px;
   min-height: 16px;
 }
 
 #downloads-indicator-progress-outer {
   width: 16px;
   height: 16px;
   background-size: 16px;
-  fill: var(--toolbarbutton-icon-fill);
   -moz-context-properties: fill;
 %ifdef MOZ_PHOTON_ANIMATIONS
   background: url("chrome://browser/skin/downloads/download-icons.svg#default-bar") center no-repeat;
 %else
   background: var(--downloads-indicator-image) center no-repeat;
 %endif
 }
 
 %ifdef MOZ_PHOTON_ANIMATIONS
-toolbar[brighttext] #downloads-button:not([attention="success"]) > #downloads-indicator-anchor > #downloads-indicator-icon,
-%endif
-toolbar[brighttext] #downloads-button:not([attention="success"]) > #downloads-indicator-anchor > #downloads-indicator-progress-outer {
-  fill: var(--toolbarbutton-icon-fill-inverted);
-}
-
-%ifdef MOZ_PHOTON_ANIMATIONS
 #downloads-button[attention="success"] > #downloads-indicator-anchor > #downloads-indicator-icon,
 %endif
 #downloads-button[attention="success"] > #downloads-indicator-anchor > #downloads-indicator-progress-outer {
   fill: var(--toolbarbutton-icon-fill-attention);
 }
 %ifdef MOZ_PHOTON_ANIMATIONS
 #downloads-button[progress] > #downloads-indicator-anchor > #downloads-indicator-progress-outer {
   background: url("chrome://browser/skin/downloads/download-icons.svg#progress-bar-bg") center no-repeat;
--- a/browser/themes/shared/incontentprefs/preferences.inc.css
+++ b/browser/themes/shared/incontentprefs/preferences.inc.css
@@ -545,59 +545,57 @@ groupbox {
 .fxaFirefoxLogo {
   list-style-image: url(chrome://browser/skin/fxa/logo.png);
   width: 64px;
   height: 64px;
   margin-inline-end: 14px;
 }
 
 .fxaMobilePromo {
+  line-height: 28px;
   margin-bottom: 20px;
   margin-top: 25px;
 }
 
 #fxaLoginRejectedWarning {
   list-style-image: url(chrome://browser/skin/warning.svg);
   filter: drop-shadow(0 1px 0 hsla(206, 50%, 10%, .15));
   margin: 4px 8px 0px 0px;
 }
 
 #syncOptions {
   margin-bottom: 27.5px;
 }
 
 .androidLink {
-  background-image: url("chrome://browser/skin/fxa/android.png");
+  list-style-image: url("chrome://browser/skin/fxa/android.png");
 }
 
 .iOSLink {
-  background-image: url("chrome://browser/skin/fxa/ios.png");
+  list-style-image: url("chrome://browser/skin/fxa/ios.png");
 }
 
 .androidLink,
 .iOSLink {
-  margin: 0 0 0 2px;
-  padding-left: 28px;
-  padding-top: 6px;
+  vertical-align: bottom;
+  padding: 0 5px;
   height: 28px;
-  background-repeat: no-repeat;
-  background-size: 24px 28px;
 }
 
 #tosPP-small {
   margin-top: 20px;
   margin-bottom: 20px;
 }
 
 @media (min-resolution: 1.1dppx) {
   .androidLink {
-    background-image: url("chrome://browser/skin/fxa/android@2x.png");
+    list-style-image: url("chrome://browser/skin/fxa/android@2x.png");
   }
   .iOSLink {
-    background-image: url("chrome://browser/skin/fxa/ios@2x.png");
+    list-style-image: url("chrome://browser/skin/fxa/ios@2x.png");
   }
   .fxaFirefoxLogo {
     list-style-image: url(chrome://browser/skin/fxa/logo@2x.png);
   }
 }
 
 #updateDeck > hbox > label {
   margin-inline-end: 5px ! important;
--- a/browser/themes/shared/social/social.inc.css
+++ b/browser/themes/shared/social/social.inc.css
@@ -2,22 +2,18 @@
 /* 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/. */
 %endif
 
 #manage-share-providers {
   list-style-image: url("chrome://browser/skin/settings.svg");
   -moz-context-properties: fill;
-  fill: var(--toolbarbutton-icon-fill);
-}
-
-#manage-share-providers > .toolbarbutton-icon {
-  min-height: 18px;
-  min-width: 18px;
+  fill: currentColor;
+  color: inherit;
 }
 
 .social-panel > .panel-arrowcontainer > .panel-arrowcontent {
   padding: 0;
 }
 /* fixup corners for share panel */
 .social-panel > .social-panel-frame {
   border-radius: inherit;
--- a/browser/themes/windows/preferences/in-content-new/preferences.css
+++ b/browser/themes/windows/preferences/in-content-new/preferences.css
@@ -4,34 +4,26 @@
 
 %include ../../../shared/incontentprefs/preferences.inc.css
 
 @media (-moz-windows-default-theme: 0) {
   #category-general > .category-icon {
     list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#general-native");
   }
 
-  #category-application > .category-icon {
-    list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#applications-native");
-  }
-
   #category-privacy > .category-icon {
-    list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#privacy-native");
+    list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#security-native");
   }
 
   #category-sync > .category-icon {
     list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#sync-native");
   }
 
-  #category-advanced > .category-icon {
-    list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#advanced-native");
-  }
-
-  #category-search-results > .category-icon {
-    list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#searchResults-native");
+  #category-search > .category-icon {
+    list-style-image: url("chrome://browser/skin/preferences/in-content-new/icons.svg#search-native");
   }
 }
 
 .actionsMenu > .menulist-label-box > .menulist-icon {
   margin-inline-end: 9px;
 }
 
 textbox + button,
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -348,16 +348,49 @@ def hg_version(hg):
     if not match:
         raise FatalCheckError('unable to determine Mercurial version: %s' % out)
 
     # The version string may be "unknown" for Mercurial run out of its own
     # source checkout or for bad builds. But LooseVersion handles it.
 
     return Version(match.group(1))
 
+# Resolve Mercurial config items so other checks have easy access.
+# Do NOT set this in the config because it may contain sensitive data
+# like API keys.
+@depends_all(check_build_environment, hg, hg_version)
+@imports('os')
+def hg_config(build_env, hg, version):
+    env = dict(os.environ)
+    env['HGPLAIN'] = '1'
+
+    # Warnings may get sent to stderr. But check_cmd_output() ignores
+    # stderr if exit code is 0. And the command should always succeed if
+    # `hg version` worked.
+    out = check_cmd_output(hg, 'config', env=env, cwd=build_env.topsrcdir)
+
+    # out is bytes. However, unicode literals are in effect, so implicit
+    # type coercion can occur. The underlying Mercurial config file may be
+    # in a user-defined encoding. However, HGPLAIN both overrides the decoding
+    # inside Mercurial *and* ensures output is utf-8. Because moz.configure
+    # is using unicode literals, our returned config object uses unicode
+    # keys and values to limit potential for coercion.
+
+    # Mercurial should emit utf-8. But be paranoid and ignore invalid utf-8
+    # byte sequences.
+    out = out.decode('utf-8', 'replace')
+
+    config = {}
+
+    for line in out.strip().splitlines():
+        key, value = [s.strip() for s in line.split('=', 1)]
+        config[key] = value
+
+    return config
+
 @depends_if(git)
 @checking('for Git version')
 @imports('re')
 def git_version(git):
     out = check_cmd_output(git, '--version').rstrip()
 
     match = re.search('git version (.*)$', out)
 
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -399,33 +399,49 @@ def dependable(obj):
         return depends(when=True)(obj)
     return depends(when=True)(lambda: obj)
 
 
 always = dependable(True)
 never = dependable(False)
 
 
-# Like @depends, but the decorated function is only called if one of the
-# arguments it would be called with has a positive value (bool(value) is True)
+# Create a decorator that will only execute the body of a function
+# if the passed function returns True when passed all positional
+# arguments.
 @template
-def depends_if(*args, **kwargs):
+def depends_tmpl(eval_args_fn, *args, **kwargs):
     if kwargs:
         assert len(kwargs) == 1
         when = kwargs['when']
     else:
         when = None
     def decorator(func):
         @depends(*args, when=when)
         def wrapper(*args):
-            if any(arg for arg in args):
+            if eval_args_fn(args):
                 return func(*args)
         return wrapper
     return decorator
 
+
+# Like @depends, but the decorated function is only called if one of the
+# arguments it would be called with has a positive value (bool(value) is True)
+@template
+def depends_if(*args, **kwargs):
+    return depends_tmpl(any, *args, **kwargs)
+
+
+# Like @depends, but the decorated function is only called if all of the
+# arguments it would be called with have a positive value.
+@template
+def depends_all(*args, **kwargs):
+    return depends_tmpl(all, *args, **kwargs)
+
+
 # Hacks related to old-configure
 # ==============================
 
 @dependable
 def old_configure_assignments():
     return []
 
 @dependable
--- a/build/mozconfig.stylo
+++ b/build/mozconfig.stylo
@@ -1,6 +1,2 @@
 # Tell the build system where to find llvm-config for builds on automation.
 export LLVM_CONFIG="${TOOLTOOL_DIR:-$topsrcdir}/clang/bin/llvm-config"
-
-# TODO remove once configure defaults to stylo once stylo enabled
-# on all platforms.
-ac_add_options --enable-stylo=build
--- a/build/unix/elfhack/test.c
+++ b/build/unix/elfhack/test.c
@@ -125,17 +125,17 @@ int print_status() {
  * following sections as part of the PT_TLS segment.
  * Finally, gold makes TLS segments end on an aligned virtual address,
  * even when the underlying section ends before that, and elfhack
  * sanity checks may yield an error. */
 __thread int foo;
 __thread long long int bar[512];
 
 void end_test() {
-    static int count = 0;
+    static size_t count = 0;
     /* Only exit when both constructors have been called */
     if (++count == 2)
         ret = 0;
 }
 
 void test() {
     int i = 0, j = 0;
 #define DEF_(a,i,w) \
--- a/devtools/client/themes/webconsole.css
+++ b/devtools/client/themes/webconsole.css
@@ -802,16 +802,19 @@ a.learn-more-link.webconsole-learn-more-
 .network .message-flex-body > .message-body {
   display: flex;
 }
 
 .webconsole-output-wrapper .message .indent {
   display: inline-block;
   border-inline-end: solid 1px var(--theme-splitter-color);
 }
+.webconsole-output-wrapper .message .indent[data-indent="0"] {
+  border-inline-end: none;
+}
 
 .message.startGroup .indent,
 .message.startGroupCollapsed .indent {
   border-inline-end-color: transparent;
   margin-inline-end: 5px;
 }
 
 .message.startGroup .icon,
--- a/devtools/client/webconsole/new-console-output/components/message-indent.js
+++ b/devtools/client/webconsole/new-console-output/components/message-indent.js
@@ -14,18 +14,21 @@ const {
 const INDENT_WIDTH = 12;
 
 // Store common indents so they can be used without recreating the element
 // during render.
 const CONSTANT_INDENTS = [getIndentElement(0), getIndentElement(1)];
 
 function getIndentElement(indent) {
   return dom.span({
+    "data-indent": indent,
     className: "indent",
-    style: {"width": indent * INDENT_WIDTH}
+    style: {
+      "width": indent * INDENT_WIDTH
+    }
   });
 }
 
 function MessageIndent(props) {
   const { indent } = props;
   return CONSTANT_INDENTS[indent] || getIndentElement(indent);
 }
 
--- a/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js
+++ b/devtools/client/webconsole/new-console-output/test/components/console-api-call.test.js
@@ -85,21 +85,24 @@ describe("ConsoleAPICall component:", ()
     it("has the expected indent", () => {
       const message = stubPreparedMessages.get("console.log('foobar', 'test')");
 
       const indent = 10;
       let wrapper = render(ConsoleApiCall({
         message: Object.assign({}, message, {indent}),
         serviceContainer
       }));
-      expect(wrapper.find(".indent").prop("style").width)
-        .toBe(`${indent * INDENT_WIDTH}px`);
+      let indentEl = wrapper.find(".indent");
+      expect(indentEl.prop("style").width).toBe(`${indent * INDENT_WIDTH}px`);
+      expect(indentEl.prop("data-indent")).toBe(`${indent}`);
 
       wrapper = render(ConsoleApiCall({ message, serviceContainer}));
-      expect(wrapper.find(".indent").prop("style").width).toBe(`0`);
+      indentEl = wrapper.find(".indent");
+      expect(indentEl.prop("style").width).toBe(`0`);
+      expect(indentEl.prop("data-indent")).toBe(`0`);
     });
 
     it("renders a timestamp when passed a truthy timestampsVisible prop", () => {
       const message = stubPreparedMessages.get("console.log('foobar', 'test')");
       const wrapper = render(ConsoleApiCall({
         message,
         serviceContainer,
         timestampsVisible: true,
--- a/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js
+++ b/devtools/client/webconsole/new-console-output/test/components/evaluation-result.test.js
@@ -79,21 +79,24 @@ describe("EvaluationResult component:", 
 
   it("has the expected indent", () => {
     const message = stubPreparedMessages.get("new Date(0)");
 
     const indent = 10;
     let wrapper = render(EvaluationResult({
       message: Object.assign({}, message, {indent}),
     }));
-    expect(wrapper.find(".indent").prop("style").width)
-        .toBe(`${indent * INDENT_WIDTH}px`);
+    let indentEl = wrapper.find(".indent");
+    expect(indentEl.prop("style").width).toBe(`${indent * INDENT_WIDTH}px`);
+    expect(indentEl.prop("data-indent")).toBe(`${indent}`);
 
     wrapper = render(EvaluationResult({ message}));
-    expect(wrapper.find(".indent").prop("style").width).toBe(`0`);
+    indentEl = wrapper.find(".indent");
+    expect(indentEl.prop("style").width).toBe(`0`);
+    expect(indentEl.prop("data-indent")).toBe(`0`);
   });
 
   it("has location information", () => {
     const message = stubPreparedMessages.get("1 + @");
     const wrapper = render(EvaluationResult({ message }));
 
     const locationLink = wrapper.find(`.message-location`);
     expect(locationLink.length).toBe(1);
--- a/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js
+++ b/devtools/client/webconsole/new-console-output/test/components/network-event-message.test.js
@@ -56,21 +56,24 @@ describe("NetworkEventMessage component:
     it("has the expected indent", () => {
       const message = stubPreparedMessages.get("GET request");
 
       const indent = 10;
       let wrapper = render(NetworkEventMessage({
         message: Object.assign({}, message, {indent}),
         serviceContainer
       }));
-      expect(wrapper.find(".indent").prop("style").width)
-        .toBe(`${indent * INDENT_WIDTH}px`);
+      let indentEl = wrapper.find(".indent");
+      expect(indentEl.prop("style").width).toBe(`${indent * INDENT_WIDTH}px`);
+      expect(indentEl.prop("data-indent")).toBe(`${indent}`);
 
       wrapper = render(NetworkEventMessage({ message, serviceContainer }));
-      expect(wrapper.find(".indent").prop("style").width).toBe(`0`);
+      indentEl = wrapper.find(".indent");
+      expect(indentEl.prop("style").width).toBe(`0`);
+      expect(indentEl.prop("data-indent")).toBe(`0`);
     });
   });
 
   describe("XHR GET request", () => {
     it("renders as expected", () => {
       const message = stubPreparedMessages.get("XHR GET request");
       const update = stubPreparedMessages.get("XHR GET request update");
       const wrapper = render(NetworkEventMessage({
--- a/devtools/client/webconsole/new-console-output/test/components/page-error.test.js
+++ b/devtools/client/webconsole/new-console-output/test/components/page-error.test.js
@@ -141,21 +141,24 @@ describe("PageError component:", () => {
 
   it("has the expected indent", () => {
     const message = stubPreparedMessages.get("ReferenceError: asdf is not defined");
     const indent = 10;
     let wrapper = render(PageError({
       message: Object.assign({}, message, {indent}),
       serviceContainer
     }));
-    expect(wrapper.find(".indent").prop("style").width)
-        .toBe(`${indent * INDENT_WIDTH}px`);
+    let indentEl = wrapper.find(".indent");
+    expect(indentEl.prop("style").width).toBe(`${indent * INDENT_WIDTH}px`);
+    expect(indentEl.prop("data-indent")).toBe(`${indent}`);
 
     wrapper = render(PageError({ message, serviceContainer}));
-    expect(wrapper.find(".indent").prop("style").width).toBe(`0`);
+    indentEl = wrapper.find(".indent");
+    expect(indentEl.prop("style").width).toBe(`0`);
+    expect(indentEl.prop("data-indent")).toBe(`0`);
   });
 
   it("has empty error notes", () => {
     const message = stubPreparedMessages.get("ReferenceError: asdf is not defined");
     let wrapper = render(PageError({ message, serviceContainer }));
 
     const notes = wrapper.find(".error-note");
 
--- a/devtools/client/webconsole/test/browser_console.js
+++ b/devtools/client/webconsole/test/browser_console.js
@@ -62,16 +62,22 @@ function testMessages(hud) {
   Cu.nukeSandbox(sandbox);
 
   // Add a message from a content window.
   content.console.log("bug587757b");
 
   // Test eval.
   hud.jsterm.execute("document.location.href");
 
+  // Test eval frame script
+  hud.jsterm.execute(`
+    gBrowser.selectedBrowser.messageManager.loadFrameScript('data:application/javascript,console.log("framescript-message")', false);
+    "framescript-eval";
+  `);
+
   // Check for network requests.
   let xhr = new XMLHttpRequest();
   xhr.onload = () => console.log("xhr loaded, status is: " + xhr.status);
   xhr.open("get", TEST_URI, true);
   xhr.send();
 
   // Check for xhr error.
   let xhrErr = new XMLHttpRequest();
@@ -124,16 +130,28 @@ function testMessages(hud) {
       },
       {
         name: "jsterm eval result",
         text: "browser.xul",
         category: CATEGORY_OUTPUT,
         severity: SEVERITY_LOG,
       },
       {
+        name: "jsterm eval result 2",
+        text: "framescript-eval",
+        category: CATEGORY_OUTPUT,
+        severity: SEVERITY_LOG,
+      },
+      {
+        name: "frame script message",
+        text: "framescript-message",
+        category: CATEGORY_WEBDEV,
+        severity: SEVERITY_LOG,
+      },
+      {
         name: "exception message",
         text: "foobarExceptionBug587757",
         category: CATEGORY_JS,
         severity: SEVERITY_ERROR,
       },
       {
         name: "network message",
         text: "test-console.html",
--- a/docshell/base/crashtests/crashtests.list
+++ b/docshell/base/crashtests/crashtests.list
@@ -6,12 +6,12 @@ load 430628-1.html
 load 432114-1.html
 load 432114-2.html
 load 436900-1.html
 asserts(0-1) load 436900-2.html # bug 566159
 load 500328-1.html
 load 514779-1.xhtml
 load 614499-1.html
 load 678872-1.html
-skip-if(Android) pref(dom.disable_open_during_load,false) load 914521.html
+skip-if(Android) skip-if(stylo&&isDebugBuild&&winWidget) pref(dom.disable_open_during_load,false) load 914521.html # Bug 1383845
 pref(browser.send_pings,true) load 1257730-1.html
 load 1331295.html
 load 1341657.html
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -109,18 +109,18 @@ load 593302-1.html
 load 593302-2.html
 load 595606-1.html
 load 595606-2.html
 load 601247.html
 load 603531.html
 load 604262-1.html
 load 605672-1.svg
 load 606729-1.html
-load 609560-1.xhtml
-load 610571-1.html
+skip-if(stylo&&isDebugBuild&&winWidget) load 609560-1.xhtml # Bug 1383845
+skip-if(stylo&&isDebugBuild&&winWidget) load 610571-1.html # Bug 1383845
 load 612018-1.html
 load 628599-1.html
 load 637116.html
 load 637214-1.svg
 load 637214-2.svg
 load 642022-1.html
 load 646184.html
 load 658845-1.svg
@@ -162,17 +162,17 @@ load 815477.html
 load 815500.html
 load 816253.html
 load 819014.html
 load 822691.html
 load 822723.html
 load 824719.html
 load 827190.html
 load 828054.html
-load 828903.html
+skip-if(stylo&&isDebugBuild&&winWidget) load 828903.html # Bug 1383845
 load 829428.html
 load 830098.html
 load 831287.html
 load 832644.html
 load 836890.html
 load 838489-1.html
 load 838489-2.html
 load 841205.html
@@ -210,13 +210,13 @@ pref(dom.IntersectionObserver.enabled,tr
 pref(dom.IntersectionObserver.enabled,true) load 1332939.html
 pref(dom.webcomponents.enabled,true) load 1341693.html
 pref(dom.IntersectionObserver.enabled,true) load 1353529.xul
 pref(dom.IntersectionObserver.enabled,true) load 1369363.xul
 load 1370072.html
 pref(clipboard.autocopy,true) load 1370737.html
 pref(dom.IntersectionObserver.enabled,true) load 1370968.html
 load 1377826.html
-load structured_clone_container_throws.html
+skip-if(stylo&&isDebugBuild&&winWidget) load structured_clone_container_throws.html # Bug 1383845
 HTTP(..) load xhr_abortinprogress.html
 load xhr_empty_datauri.html
 load xhr_html_nullresponse.html
 load 1383478.html
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -285,17 +285,17 @@ bool nsContentUtils::sInitialized = fals
 bool nsContentUtils::sIsFullScreenApiEnabled = false;
 bool nsContentUtils::sIsUnprefixedFullscreenApiEnabled = false;
 bool nsContentUtils::sTrustedFullScreenOnly = true;
 bool nsContentUtils::sIsCutCopyAllowed = true;
 bool nsContentUtils::sIsFrameTimingPrefEnabled = false;
 bool nsContentUtils::sIsPerformanceTimingEnabled = false;
 bool nsContentUtils::sIsResourceTimingEnabled = false;
 bool nsContentUtils::sIsUserTimingLoggingEnabled = false;
-bool nsContentUtils::sIsExperimentalAutocompleteEnabled = false;
+bool nsContentUtils::sIsFormAutofillAutocompleteEnabled = false;
 bool nsContentUtils::sIsWebComponentsEnabled = false;
 bool nsContentUtils::sIsCustomElementsEnabled = false;
 bool nsContentUtils::sSendPerformanceTimingNotifications = false;
 bool nsContentUtils::sUseActivityCursor = false;
 bool nsContentUtils::sAnimationsAPICoreEnabled = false;
 bool nsContentUtils::sAnimationsAPIElementAnimateEnabled = false;
 bool nsContentUtils::sGetBoxQuadsEnabled = false;
 bool nsContentUtils::sSkipCursorMoveForSameValueSet = false;
@@ -688,18 +688,18 @@ nsContentUtils::Init()
                                "dom.enable_resource_timing", true);
 
   Preferences::AddBoolVarCache(&sIsUserTimingLoggingEnabled,
                                "dom.performance.enable_user_timing_logging", false);
 
   Preferences::AddBoolVarCache(&sIsFrameTimingPrefEnabled,
                                "dom.enable_frame_timing", false);
 
-  Preferences::AddBoolVarCache(&sIsExperimentalAutocompleteEnabled,
-                               "dom.forms.autocomplete.experimental", false);
+  Preferences::AddBoolVarCache(&sIsFormAutofillAutocompleteEnabled,
+                               "dom.forms.autocomplete.formautofill", false);
 
   Preferences::AddBoolVarCache(&sIsWebComponentsEnabled,
                                "dom.webcomponents.enabled", false);
 
   Preferences::AddBoolVarCache(&sIsCustomElementsEnabled,
                                "dom.webcomponents.customelements.enabled", false);
 
   Preferences::AddIntVarCache(&sPrivacyMaxInnerWidth,
@@ -1179,31 +1179,31 @@ nsContentUtils::InternalSerializeAutocom
         return eAutocompleteAttrState_Invalid;
       }
       enumValue.ToString(str);
       ASCIIToLower(str);
       aInfo.mFieldName.Assign(str);
       return eAutocompleteAttrState_Valid;
     }
 
-    // Only allow on/off if experimental @autocomplete values aren't enabled
+    // Only allow on/off if form autofill @autocomplete values aren't enabled
     // and it doesn't grant all valid values.
-    if (!sIsExperimentalAutocompleteEnabled && !aGrantAllValidValue) {
+    if (!sIsFormAutofillAutocompleteEnabled && !aGrantAllValidValue) {
       return eAutocompleteAttrState_Invalid;
     }
 
     // Normal category
     if (numTokens > 3) {
       return eAutocompleteAttrState_Invalid;
     }
     category = eAutocompleteCategory_NORMAL;
   } else { // Check if the last token is of the contact category instead.
-    // Only allow on/off if experimental @autocomplete values aren't enabled
+    // Only allow on/off if form autofill @autocomplete values aren't enabled
     // and it doesn't grant all valid values.
-    if (!sIsExperimentalAutocompleteEnabled && !aGrantAllValidValue) {
+    if (!sIsFormAutofillAutocompleteEnabled && !aGrantAllValidValue) {
       return eAutocompleteAttrState_Invalid;
     }
 
     result = enumValue.ParseEnumValue(tokenString, kAutocompleteContactFieldNameTable, false);
     if (!result || numTokens > 4) {
       return eAutocompleteAttrState_Invalid;
     }
 
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -3228,17 +3228,17 @@ private:
   static bool sIsUnprefixedFullscreenApiEnabled;
   static bool sTrustedFullScreenOnly;
   static bool sIsCutCopyAllowed;
   static uint32_t sHandlingInputTimeout;
   static bool sIsPerformanceTimingEnabled;
   static bool sIsResourceTimingEnabled;
   static bool sIsUserTimingLoggingEnabled;
   static bool sIsFrameTimingPrefEnabled;
-  static bool sIsExperimentalAutocompleteEnabled;
+  static bool sIsFormAutofillAutocompleteEnabled;
   static bool sIsWebComponentsEnabled;
   static bool sIsCustomElementsEnabled;
   static bool sSendPerformanceTimingNotifications;
   static bool sUseActivityCursor;
   static bool sAnimationsAPICoreEnabled;
   static bool sAnimationsAPIElementAnimateEnabled;
   static bool sGetBoxQuadsEnabled;
   static bool sSkipCursorMoveForSameValueSet;
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -198,21 +198,16 @@ DOMInterfaces = {
     'headerFile': 'nsCSSCounterStyleRule.h',
 },
 
 'CSSFontFaceRule': {
     'nativeType': 'nsCSSFontFaceRule',
     'headerFile': 'nsCSSFontFaceRule.h',
 },
 
-'CSSFontFeatureValuesRule': {
-    'nativeType': 'nsCSSFontFeatureValuesRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
 'CSSGroupingRule': {
     'concrete': False,
     'nativeType': 'mozilla::css::GroupRule',
 },
 
 'CSSLexer': {
     'wrapperCache': False
 },
--- a/dom/canvas/moz.build
+++ b/dom/canvas/moz.build
@@ -61,16 +61,17 @@ EXPORTS.mozilla.dom += [
     'CanvasPattern.h',
     'CanvasRenderingContext2D.h',
     'CanvasRenderingContextHelper.h',
     'CanvasUtils.h',
     'ImageBitmap.h',
     'ImageBitmapRenderingContext.h',
     'ImageBitmapSource.h',
     'ImageData.h',
+    'ImageUtils.h',
     'OffscreenCanvas.h',
     'TextMetrics.h',
     'WebGLVertexArrayObject.h',
 ]
 
 # Canvas 2D and common sources
 UNIFIED_SOURCES += [
     'CanvasImageCache.cpp',
--- a/dom/canvas/test/reftest/reftest.list
+++ b/dom/canvas/test/reftest/reftest.list
@@ -15,17 +15,17 @@ pref(webgl.force-layers-readback,true) s
 skip-if(Android) == webgl-clear-test.html?depth wrapper.html?green.png
 skip-if(Android) == webgl-clear-test.html?stencil wrapper.html?green.png
 skip-if(Android) == webgl-clear-test.html?depth&stencil wrapper.html?green.png
 
 # Check that resize works:
 skip-if(Android) == webgl-resize-test.html  wrapper.html?green.png
 
 # Check that captureStream() displays in a local video element
-skip-if(Android) == webgl-capturestream-test.html?preserve wrapper.html?green.png
+skip-if(Android) skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&styloVsGecko) == webgl-capturestream-test.html?preserve wrapper.html?green.png
 
 # Some of the failure conditions are a little crazy. I'm (jgilbert) setting these based on
 # failures encountered when running on Try, and then targetting the Try config by
 # differences in the `sandbox` contents. That is, I'm labeling based on symptoms rather
 # than cause.
 # WinXP R:  winWidget && layersGPUAccelerated  && !d3d11
 # Win7+ R:  winWidget && layersGPUAccelerated  && d3d11
 # Win7+ Ru: winWidget && !layersGPUAccelerated && d3d11
@@ -136,17 +136,17 @@ fuzzy(5,30000) skip pref(webgl.prefer-16
 fuzzy(5,30000) skip pref(webgl.prefer-16bpp,true)                                         == webgl-color-test.html?16bpp&________&premult&_____  wrapper.html?colors-no-alpha.png
 fuzzy(5,30000) skip pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true)  == webgl-color-test.html?16bpp&readback&premult&_____  wrapper.html?colors-no-alpha.png
 fuzzy(9,40000) skip pref(webgl.prefer-16bpp,true)                                         == webgl-color-test.html?16bpp&________&_______&alpha  wrapper.html?colors-non-premult.png
 fuzzy(9,40000) skip pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true)  == webgl-color-test.html?16bpp&readback&_______&alpha  wrapper.html?colors-non-premult.png
 fuzzy(9,40000) skip pref(webgl.prefer-16bpp,true)                                         == webgl-color-test.html?16bpp&________&premult&alpha  wrapper.html?colors-premult.png
 fuzzy(9,40000) skip pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true)  == webgl-color-test.html?16bpp&readback&premult&alpha  wrapper.html?colors-premult.png
 
 # Force native GL (Windows):
-skip-if(!winWidget) pref(webgl.disable-angle,true)  == webgl-color-test.html?native-gl  wrapper.html?colors-no-alpha.png
+skip-if(!winWidget) skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&styloVsGecko) pref(webgl.disable-angle,true) == webgl-color-test.html?native-gl  wrapper.html?colors-no-alpha.png
 
 
 # Non-WebGL Reftests!
 
 # Do we correctly handle multiple clip paths?
 != clip-multiple-paths.html clip-multiple-paths-badref.html
 
 # Bug 1255062
--- a/dom/gamepad/GamepadManager.cpp
+++ b/dom/gamepad/GamepadManager.cpp
@@ -553,17 +553,19 @@ GamepadManager::MaybeConvertToNonstandar
                                                       nsGlobalWindow* aWindow)
 {
   MOZ_ASSERT(aWindow);
 
   if (!mNonstandardEventsEnabled) {
     return;
   }
 
-  RefPtr<Gamepad> gamepad = aWindow->GetGamepad(aEvent.index());
+  const uint32_t index = GetGamepadIndexWithServiceType(aEvent.index(),
+                                                        aEvent.service_type());
+  RefPtr<Gamepad> gamepad = aWindow->GetGamepad(index);
   const GamepadChangeEventBody& body = aEvent.body();
 
   if (gamepad) {
     switch (body.type()) {
       case GamepadChangeEventBody::TGamepadButtonInformation:
       {
         const GamepadButtonInformation& a = body.get_GamepadButtonInformation();
         FireButtonEvent(aWindow, gamepad, a.button(), a.value());
@@ -581,17 +583,16 @@ GamepadManager::MaybeConvertToNonstandar
   }
 }
 
 bool
 GamepadManager::SetGamepadByEvent(const GamepadChangeEvent& aEvent, nsGlobalWindow *aWindow)
 {
   bool ret = false;
   bool firstTime = false;
-
   const uint32_t index = GetGamepadIndexWithServiceType(aEvent.index(),
                                                         aEvent.service_type());
   if (aWindow) {
     firstTime = MaybeWindowHasSeenGamepad(aWindow, index);
   }
 
   RefPtr<Gamepad> gamepad = aWindow ? aWindow->GetGamepad(index) : GetGamepad(index);
   const GamepadChangeEventBody& body = aEvent.body();
--- a/dom/html/test/forms/test_autocompleteinfo.html
+++ b/dom/html/test/forms/test_autocompleteinfo.html
@@ -148,24 +148,24 @@ function testAutocomplete(aField, aType,
   if (aEnabled) {
     ok(aField.getAutocompleteInfo() !== null, "getAutocompleteInfo shouldn't return null");
   } else {
     is(aField.getAutocompleteInfo(), null, "getAutocompleteInfo should return null");
   }
 }
 
 // getAutocompleteInfo() should be able to parse all tokens as defined
-// in the spec regardless of whether dom.forms.autocomplete.experimental pref
+// in the spec regardless of whether dom.forms.autocomplete.formautofill pref
 // is on or off.
 add_task(async function testAutocompletePreferenceEnabled() {
-  await SpecialPowers.pushPrefEnv({"set": [["dom.forms.autocomplete.experimental", true]]}, testInputTypes);
+  await SpecialPowers.pushPrefEnv({"set": [["dom.forms.autocomplete.formautofill", true]]}, testInputTypes);
   testAutocompleteInfoValue(true);
 });
 
 add_task(async function testAutocompletePreferenceDisabled() {
-  await SpecialPowers.pushPrefEnv({"set": [["dom.forms.autocomplete.experimental", false]]}, testInputTypes);
+  await SpecialPowers.pushPrefEnv({"set": [["dom.forms.autocomplete.formautofill", false]]}, testInputTypes);
   testAutocompleteInfoValue(false);
 });
 
 </script>
 </pre>
 </body>
 </html>
--- a/dom/html/test/forms/test_input_autocomplete.html
+++ b/dom/html/test/forms/test_input_autocomplete.html
@@ -107,17 +107,17 @@ function start() {
   }
 
   var selectField = document.getElementById("select-field");
   checkAutocompleteValues(selectField, "select");
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({"set": [["dom.forms.autocomplete.experimental", true]]}, start);
+SpecialPowers.pushPrefEnv({"set": [["dom.forms.autocomplete.formautofill", true]]}, start);
 </script>
 </head>
 
 <body>
 <p id="display"></p>
 <div id="content" style="display: none">
   <form>
     <input id="input-field" />
--- a/dom/ipc/ContentPrefs.cpp
+++ b/dom/ipc/ContentPrefs.cpp
@@ -44,17 +44,17 @@ const char* mozilla::dom::ContentPrefs::
   "device.storage.writable.name",
   "dom.allow_XUL_XBL_for_file",
   "dom.allow_cut_copy",
   "dom.enable_frame_timing",
   "dom.enable_performance",
   "dom.enable_resource_timing",
   "dom.event.handling-user-input-time-limit",
   "dom.event.touch.coalescing.enabled",
-  "dom.forms.autocomplete.experimental",
+  "dom.forms.autocomplete.formautofill",
   "dom.ipc.processPriorityManager.backgroundGracePeriodMS",
   "dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS",
   "dom.max_chrome_script_run_time",
   "dom.max_script_run_time",
   "dom.mozBrowserFramesEnabled",
   "dom.performance.enable_notify_performance_timing",
   "dom.performance.enable_user_timing_logging",
   "dom.storage.testing",
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -39,21 +39,21 @@
 #include "nsTArray.h"
 #include "nsDeque.h"
 #include "prenv.h"
 
 #include "AudioSegment.h"
 #include "DOMMediaStream.h"
 #include "ImageContainer.h"
 #include "MediaDecoder.h"
-#include "MediaDecoderReaderWrapper.h"
 #include "MediaDecoderStateMachine.h"
 #include "MediaShutdownManager.h"
 #include "MediaPrefs.h"
 #include "MediaTimer.h"
+#include "ReaderProxy.h"
 #include "TimeUnits.h"
 #include "VideoSegment.h"
 #include "VideoUtils.h"
 #include "gfxPrefs.h"
 
 namespace mozilla {
 
 using namespace mozilla::dom;
@@ -253,17 +253,17 @@ protected:
     Observable,
     Suppressed
   };
 
   using Master = MediaDecoderStateMachine;
   explicit StateObject(Master* aPtr) : mMaster(aPtr) { }
   TaskQueue* OwnerThread() const { return mMaster->mTaskQueue; }
   MediaResource* Resource() const { return mMaster->mResource; }
-  MediaDecoderReaderWrapper* Reader() const { return mMaster->mReader; }
+  ReaderProxy* Reader() const { return mMaster->mReader; }
   const MediaInfo& Info() const { return mMaster->Info(); }
   bool IsExpectingMoreData() const
   {
     // We are expecting more data if either the resource states so, or if we
     // have a waiting promise pending (such as with non-MSE EME).
     return Resource()->IsExpectingMoreData()
            || mMaster->IsWaitingAudioData()
            || mMaster->IsWaitingVideoData();
@@ -995,17 +995,17 @@ public:
     return SeekingState::Enter(Move(aSeekJob), aVisibility);
   }
 
   void Exit() override
   {
     // Disconnect MediaDecoder.
     mSeekJob.RejectIfExists(__func__);
 
-    // Disconnect MediaDecoderReaderWrapper.
+    // Disconnect ReaderProxy.
     mSeekRequest.DisconnectIfExists();
 
     mWaitRequest.DisconnectIfExists();
   }
 
   void HandleAudioDecoded(AudioData* aAudio) override
   {
     MOZ_ASSERT(!mDoneAudioSeeking || !mDoneVideoSeeking,
@@ -2715,17 +2715,17 @@ MediaDecoderStateMachine::MediaDecoderSt
   mTaskQueue(new TaskQueue(
     GetMediaThreadPool(MediaThreadType::PLAYBACK),
     "MDSM::mTaskQueue", /* aSupportsTailDispatch = */ true)),
   mWatchManager(this, mTaskQueue),
   mDispatchedStateMachine(false),
   mDelayedScheduler(mTaskQueue),
   mCurrentFrameID(0),
   INIT_WATCHABLE(mObservedDuration, TimeUnit()),
-  mReader(new MediaDecoderReaderWrapper(mTaskQueue, aReader)),
+  mReader(new ReaderProxy(mTaskQueue, aReader)),
   mPlaybackRate(1.0),
   mAmpleAudioThreshold(detail::AMPLE_AUDIO_THRESHOLD),
   mAudioCaptured(false),
   mMinimizePreroll(aDecoder->GetMinimizePreroll()),
   mSentFirstFrameLoadedEvent(false),
   mVideoDecodeSuspended(false),
   mVideoDecodeSuspendTimer(mTaskQueue),
   mOutputStreamManager(new OutputStreamManager()),
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -103,18 +103,18 @@ namespace mozilla {
 
 namespace media {
 class MediaSink;
 }
 
 class AbstractThread;
 class AudioSegment;
 class DecodedStream;
-class MediaDecoderReaderWrapper;
 class OutputStreamManager;
+class ReaderProxy;
 class TaskQueue;
 
 extern LazyLogModule gMediaDecoderLog;
 
 enum class MediaEventType : int8_t
 {
   PlaybackStarted,
   PlaybackStopped,
@@ -543,17 +543,17 @@ private:
   }
 
   // Media Fragment end time.
   media::TimeUnit mFragmentEndTime = media::TimeUnit::Invalid();
 
   // The media sink resource.  Used on the state machine thread.
   RefPtr<media::MediaSink> mMediaSink;
 
-  const RefPtr<MediaDecoderReaderWrapper> mReader;
+  const RefPtr<ReaderProxy> mReader;
 
   // The end time of the last audio frame that's been pushed onto the media sink
   // in microseconds. This will approximately be the end time
   // of the audio stream, unless another frame is pushed to the hardware.
   media::TimeUnit AudioEndTime() const;
 
   // The end time of the last rendered video frame that's been sent to
   // compositor.
rename from dom/media/MediaDecoderReaderWrapper.cpp
rename to dom/media/ReaderProxy.cpp
--- a/dom/media/MediaDecoderReaderWrapper.cpp
+++ b/dom/media/ReaderProxy.cpp
@@ -1,64 +1,64 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/MozPromise.h"
-#include "MediaDecoderReaderWrapper.h"
 #include "MediaFormatReader.h"
+#include "ReaderProxy.h"
+#include "TimeUnits.h"
 
 namespace mozilla {
 
-MediaDecoderReaderWrapper::MediaDecoderReaderWrapper(
-  AbstractThread* aOwnerThread,
-  MediaFormatReader* aReader)
+ReaderProxy::ReaderProxy(AbstractThread* aOwnerThread,
+                         MediaFormatReader* aReader)
   : mOwnerThread(aOwnerThread)
   , mReader(aReader)
   , mWatchManager(this, aReader->OwnerThread())
   , mDuration(aReader->OwnerThread(),
-              NullableTimeUnit(),
-              "MediaDecoderReaderWrapper::mDuration (Mirror)")
+              media::NullableTimeUnit(),
+              "ReaderProxy::mDuration (Mirror)")
 {
   // Must support either heuristic buffering or WaitForData().
   MOZ_ASSERT(mReader->UseBufferingHeuristics() ||
              mReader->IsWaitForDataSupported());
 }
 
-MediaDecoderReaderWrapper::~MediaDecoderReaderWrapper()
+ReaderProxy::~ReaderProxy()
 {}
 
 media::TimeUnit
-MediaDecoderReaderWrapper::StartTime() const
+ReaderProxy::StartTime() const
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
   return mStartTime.ref();
 }
 
-RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
-MediaDecoderReaderWrapper::ReadMetadata()
+RefPtr<ReaderProxy::MetadataPromise>
+ReaderProxy::ReadMetadata()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
   return InvokeAsync(mReader->OwnerThread(),
                      mReader.get(),
                      __func__,
                      &MediaFormatReader::AsyncReadMetadata)
     ->Then(mOwnerThread,
            __func__,
            this,
-           &MediaDecoderReaderWrapper::OnMetadataRead,
-           &MediaDecoderReaderWrapper::OnMetadataNotRead);
+           &ReaderProxy::OnMetadataRead,
+           &ReaderProxy::OnMetadataNotRead);
 }
 
-RefPtr<MediaDecoderReaderWrapper::AudioDataPromise>
-MediaDecoderReaderWrapper::RequestAudioData()
+RefPtr<ReaderProxy::AudioDataPromise>
+ReaderProxy::RequestAudioData()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
 
   int64_t startTime = StartTime().ToMicroseconds();
   return InvokeAsync(mReader->OwnerThread(),
                      mReader.get(),
                      __func__,
@@ -69,18 +69,18 @@ MediaDecoderReaderWrapper::RequestAudioD
              aAudio->AdjustForStartTime(startTime);
              return AudioDataPromise::CreateAndResolve(aAudio.forget(), __func__);
            },
            [](const MediaResult& aError) {
              return AudioDataPromise::CreateAndReject(aError, __func__);
            });
 }
 
-RefPtr<MediaDecoderReaderWrapper::VideoDataPromise>
-MediaDecoderReaderWrapper::RequestVideoData(const media::TimeUnit& aTimeThreshold)
+RefPtr<ReaderProxy::VideoDataPromise>
+ReaderProxy::RequestVideoData(const media::TimeUnit& aTimeThreshold)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(!mShutdown);
 
   const auto threshold = aTimeThreshold > media::TimeUnit::Zero()
                          ? aTimeThreshold + StartTime()
                          : aTimeThreshold;
 
@@ -97,127 +97,125 @@ MediaDecoderReaderWrapper::RequestVideoD
              return VideoDataPromise::CreateAndResolve(aVideo.forget(),
                                                        __func__);
            },
            [](const MediaResult& aError) {
              return VideoDataPromise::CreateAndReject(aError, __func__);
            });
 }
 
-RefPtr<MediaDecoderReaderWrapper::SeekPromise>
-MediaDecoderReaderWrapper::Seek(const SeekTarget& aTarget)
+RefPtr<ReaderProxy::SeekPromise>
+ReaderProxy::Seek(const SeekTarget& aTarget)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   SeekTarget adjustedTarget = aTarget;
   adjustedTarget.SetTime(adjustedTarget.GetTime() + StartTime());
   return InvokeAsync(mReader->OwnerThread(),
                      mReader.get(),
                      __func__,
                      &MediaFormatReader::Seek,
                      Move(adjustedTarget));
 }
 
-RefPtr<MediaDecoderReaderWrapper::WaitForDataPromise>
-MediaDecoderReaderWrapper::WaitForData(MediaData::Type aType)
+RefPtr<ReaderProxy::WaitForDataPromise>
+ReaderProxy::WaitForData(MediaData::Type aType)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   MOZ_ASSERT(mReader->IsWaitForDataSupported());
   return InvokeAsync(mReader->OwnerThread(),
                      mReader.get(),
                      __func__,
                      &MediaFormatReader::WaitForData,
                      aType);
 }
 
 void
-MediaDecoderReaderWrapper::ReleaseResources()
+ReaderProxy::ReleaseResources()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   nsCOMPtr<nsIRunnable> r =
     NewRunnableMethod("MediaFormatReader::ReleaseResources",
                       mReader,
                       &MediaFormatReader::ReleaseResources);
   mReader->OwnerThread()->Dispatch(r.forget());
 }
 
 void
-MediaDecoderReaderWrapper::ResetDecode(TrackSet aTracks)
+ReaderProxy::ResetDecode(TrackSet aTracks)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   nsCOMPtr<nsIRunnable> r =
     NewRunnableMethod<TrackSet>("MediaFormatReader::ResetDecode",
                                 mReader,
                                 &MediaFormatReader::ResetDecode,
                                 aTracks);
   mReader->OwnerThread()->Dispatch(r.forget());
 }
 
 RefPtr<ShutdownPromise>
-MediaDecoderReaderWrapper::Shutdown()
+ReaderProxy::Shutdown()
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   mShutdown = true;
-  RefPtr<MediaDecoderReaderWrapper> self = this;
+  RefPtr<ReaderProxy> self = this;
   return InvokeAsync(mReader->OwnerThread(), __func__, [self]() {
     self->mDuration.DisconnectIfConnected();
     self->mWatchManager.Shutdown();
     return self->mReader->Shutdown();
   });
 }
 
-RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
-MediaDecoderReaderWrapper::OnMetadataRead(MetadataHolder&& aMetadata)
+RefPtr<ReaderProxy::MetadataPromise>
+ReaderProxy::OnMetadataRead(MetadataHolder&& aMetadata)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   if (mShutdown) {
     return MetadataPromise::CreateAndReject(
       NS_ERROR_DOM_MEDIA_ABORT_ERR, __func__);
   }
 
   if (mStartTime.isNothing()) {
     mStartTime.emplace(aMetadata.mInfo->mStartTime);
   }
   return MetadataPromise::CreateAndResolve(Move(aMetadata), __func__);
 }
 
-RefPtr<MediaDecoderReaderWrapper::MetadataPromise>
-MediaDecoderReaderWrapper::OnMetadataNotRead(const MediaResult& aError)
+RefPtr<ReaderProxy::MetadataPromise>
+ReaderProxy::OnMetadataNotRead(const MediaResult& aError)
 {
   return MetadataPromise::CreateAndReject(aError, __func__);
 }
 
 void
-MediaDecoderReaderWrapper::SetVideoBlankDecode(bool aIsBlankDecode)
+ReaderProxy::SetVideoBlankDecode(bool aIsBlankDecode)
 {
   MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
   nsCOMPtr<nsIRunnable> r =
     NewRunnableMethod<bool>("MediaFormatReader::SetVideoNullDecode",
                             mReader,
                             &MediaFormatReader::SetVideoNullDecode,
                             aIsBlankDecode);
   mReader->OwnerThread()->Dispatch(r.forget());
 }
 
 void
-MediaDecoderReaderWrapper::UpdateDuration()
+ReaderProxy::UpdateDuration()
 {
   MOZ_ASSERT(mReader->OwnerThread()->IsCurrentThreadIn());
   mReader->UpdateDuration(mDuration.Ref().ref());
 }
 
 void
-MediaDecoderReaderWrapper::SetCanonicalDuration(
+ReaderProxy::SetCanonicalDuration(
   AbstractCanonical<media::NullableTimeUnit>* aCanonical)
 {
   using DurationT = AbstractCanonical<media::NullableTimeUnit>;
-  RefPtr<MediaDecoderReaderWrapper> self = this;
+  RefPtr<ReaderProxy> self = this;
   RefPtr<DurationT> canonical = aCanonical;
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
-    "MediaDecoderReaderWrapper::SetCanonicalDuration",
-    [this, self, canonical]() {
+    "ReaderProxy::SetCanonicalDuration", [this, self, canonical]() {
       mDuration.Connect(canonical);
-      mWatchManager.Watch(mDuration,
-                          &MediaDecoderReaderWrapper::UpdateDuration);
+      mWatchManager.Watch(mDuration, &ReaderProxy::UpdateDuration);
     });
   mReader->OwnerThread()->Dispatch(r.forget());
 }
 
 } // namespace mozilla
rename from dom/media/MediaDecoderReaderWrapper.h
rename to dom/media/ReaderProxy.h
--- a/dom/media/MediaDecoderReaderWrapper.h
+++ b/dom/media/ReaderProxy.h
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 MediaDecoderReaderWrapper_h_
-#define MediaDecoderReaderWrapper_h_
+#ifndef ReaderProxy_h_
+#define ReaderProxy_h_
 
 #include "mozilla/AbstractThread.h"
 #include "mozilla/RefPtr.h"
 #include "mozilla/Variant.h"
 #include "nsISupportsImpl.h"
 
 #include "MediaEventSource.h"
 #include "MediaFormatReader.h"
@@ -18,28 +18,28 @@
 namespace mozilla {
 
 /**
  * A wrapper around MediaFormatReader to offset the timestamps of Audio/Video
  * samples by the start time to ensure MDSM can always assume zero start time.
  * It also adjusts the seek target passed to Seek() to ensure correct seek time
  * is passed to the underlying reader.
  */
-class MediaDecoderReaderWrapper {
+class ReaderProxy
+{
   using MetadataPromise = MediaFormatReader::MetadataPromise;
   using AudioDataPromise = MediaFormatReader::AudioDataPromise;
   using VideoDataPromise = MediaFormatReader::VideoDataPromise;
   using SeekPromise = MediaFormatReader::SeekPromise;
   using WaitForDataPromise = MediaFormatReader::WaitForDataPromise;
   using TrackSet = MediaFormatReader::TrackSet;
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaDecoderReaderWrapper);
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ReaderProxy);
 
 public:
-  MediaDecoderReaderWrapper(AbstractThread* aOwnerThread,
-                            MediaFormatReader* aReader);
+  ReaderProxy(AbstractThread* aOwnerThread, MediaFormatReader* aReader);
 
   media::TimeUnit StartTime() const;
   RefPtr<MetadataPromise> ReadMetadata();
 
   RefPtr<AudioDataPromise> RequestAudioData();
 
   RefPtr<VideoDataPromise>
   RequestVideoData(const media::TimeUnit& aTimeThreshold);
@@ -80,29 +80,29 @@ public:
   void SetCDMProxy(CDMProxy* aProxy) { mReader->SetCDMProxy(aProxy); }
 
   void SetVideoBlankDecode(bool aIsBlankDecode);
 
   void SetCanonicalDuration(
     AbstractCanonical<media::NullableTimeUnit>* aCanonical);
 
 private:
-  ~MediaDecoderReaderWrapper();
+  ~ReaderProxy();
   RefPtr<MetadataPromise> OnMetadataRead(MetadataHolder&& aMetadata);
   RefPtr<MetadataPromise> OnMetadataNotRead(const MediaResult& aError);
   void UpdateDuration();
 
   const RefPtr<AbstractThread> mOwnerThread;
   const RefPtr<MediaFormatReader> mReader;
 
   bool mShutdown = false;
   Maybe<media::TimeUnit> mStartTime;
 
   // State-watching manager.
-  WatchManager<MediaDecoderReaderWrapper> mWatchManager;
+  WatchManager<ReaderProxy> mWatchManager;
 
   // Duration, mirrored from the state machine task queue.
   Mirror<media::NullableTimeUnit> mDuration;
 };
 
 } // namespace mozilla
 
-#endif // MediaDecoderReaderWrapper_h_
+#endif // ReaderProxy_h_
--- a/dom/media/encoder/VP8TrackEncoder.cpp
+++ b/dom/media/encoder/VP8TrackEncoder.cpp
@@ -10,29 +10,32 @@
 #include "mozilla/gfx/2D.h"
 #include "prsystem.h"
 #include "VideoSegment.h"
 #include "VideoUtils.h"
 #include "vpx/vp8cx.h"
 #include "vpx/vpx_encoder.h"
 #include "WebMWriter.h"
 #include "mozilla/media/MediaUtils.h"
+#include "mozilla/dom/ImageUtils.h"
+#include "mozilla/dom/ImageBitmapBinding.h"
 
 namespace mozilla {
 
 LazyLogModule gVP8TrackEncoderLog("VP8TrackEncoder");
 #define VP8LOG(level, msg, ...) MOZ_LOG(gVP8TrackEncoderLog, \
                                         level, \
                                         (msg, ##__VA_ARGS__))
 
 #define DEFAULT_BITRATE_BPS 2500000
 
 using namespace mozilla::gfx;
 using namespace mozilla::layers;
 using namespace mozilla::media;
+using namespace mozilla::dom;
 
 static already_AddRefed<SourceSurface>
 GetSourceSurface(already_AddRefed<Image> aImg)
 {
   RefPtr<Image> img = aImg;
   if (!img) {
     return nullptr;
   }
@@ -310,41 +313,16 @@ VP8TrackEncoder::GetEncodedPartitions(En
            videoData->GetTimeStamp(), videoData->GetDuration(),
            videoData->GetFrameType());
     aData.AppendEncodedFrame(videoData);
   }
 
   return pkt ? NS_OK : NS_ERROR_NOT_AVAILABLE;
 }
 
-static bool isYUV420(const PlanarYCbCrImage::Data *aData)
-{
-  if (aData->mYSize == aData->mCbCrSize * 2) {
-    return true;
-  }
-  return false;
-}
-
-static bool isYUV422(const PlanarYCbCrImage::Data *aData)
-{
-  if ((aData->mYSize.width == aData->mCbCrSize.width * 2) &&
-      (aData->mYSize.height == aData->mCbCrSize.height)) {
-    return true;
-  }
-  return false;
-}
-
-static bool isYUV444(const PlanarYCbCrImage::Data *aData)
-{
-  if (aData->mYSize == aData->mCbCrSize) {
-    return true;
-  }
-  return false;
-}
-
 nsresult VP8TrackEncoder::PrepareRawFrame(VideoChunk &aChunk)
 {
   RefPtr<Image> img;
   if (aChunk.mFrame.GetForceBlack() || aChunk.IsNull()) {
     if (!mMuteFrame) {
       mMuteFrame = VideoFrame::CreateBlackImage(gfx::IntSize(mFrameWidth, mFrameHeight));
     }
     if (!mMuteFrame) {
@@ -389,20 +367,26 @@ nsresult VP8TrackEncoder::PrepareRawFram
   if (format == ImageFormat::PLANAR_YCBCR) {
     PlanarYCbCrImage* yuv = static_cast<PlanarYCbCrImage *>(img.get());
 
     MOZ_RELEASE_ASSERT(yuv);
     if (!yuv->IsValid()) {
       NS_WARNING("PlanarYCbCrImage is not valid");
       return NS_ERROR_FAILURE;
     }
-    const PlanarYCbCrImage::Data *data = yuv->GetData();
 
-    if (isYUV420(data) && !data->mCbSkip) {
+    // The ImageUtils API may change depending on our support for ImageBitmap
+    // extensions. Should this happen in a breaking way we should abstract out
+    // the format detection for use here.
+    const ImageUtils imageUtils(img);
+    const ImageBitmapFormat imageBitmapFormat = imageUtils.GetFormat();
+
+    if (imageBitmapFormat == ImageBitmapFormat::YUV420P) {
       // 420 planar, no need for conversions
+      const PlanarYCbCrImage::Data* data = yuv->GetData();
       mVPXImageWrapper->planes[VPX_PLANE_Y] = data->mYChannel;
       mVPXImageWrapper->planes[VPX_PLANE_U] = data->mCbChannel;
       mVPXImageWrapper->planes[VPX_PLANE_V] = data->mCrChannel;
       mVPXImageWrapper->stride[VPX_PLANE_Y] = data->mYStride;
       mVPXImageWrapper->stride[VPX_PLANE_U] = data->mCbCrStride;
       mVPXImageWrapper->stride[VPX_PLANE_V] = data->mCbCrStride;
 
       return NS_OK;
@@ -426,56 +410,82 @@ nsresult VP8TrackEncoder::PrepareRawFram
   if (format == ImageFormat::PLANAR_YCBCR) {
     PlanarYCbCrImage* yuv = static_cast<PlanarYCbCrImage *>(img.get());
 
     MOZ_RELEASE_ASSERT(yuv);
     if (!yuv->IsValid()) {
       NS_WARNING("PlanarYCbCrImage is not valid");
       return NS_ERROR_FAILURE;
     }
+
+    const ImageUtils imageUtils(img);
+    const ImageBitmapFormat imageBitmapFormat = imageUtils.GetFormat();
     const PlanarYCbCrImage::Data *data = yuv->GetData();
 
     int rv;
     std::string yuvFormat;
-    if (isYUV420(data) && data->mCbSkip) {
-      // If mCbSkip is set, we assume it's nv12 or nv21.
-      if (data->mCbChannel < data->mCrChannel) { // nv12
-        rv = libyuv::NV12ToI420(data->mYChannel, data->mYStride,
-                                data->mCbChannel, data->mCbCrStride,
-                                y, mFrameWidth,
-                                cb, halfWidth,
-                                cr, halfWidth,
-                                mFrameWidth, mFrameHeight);
-        yuvFormat = "NV12";
-      } else { // nv21
-        rv = libyuv::NV21ToI420(data->mYChannel, data->mYStride,
-                                data->mCrChannel, data->mCbCrStride,
-                                y, mFrameWidth,
-                                cb, halfWidth,
-                                cr, halfWidth,
-                                mFrameWidth, mFrameHeight);
-        yuvFormat = "NV21";
-      }
-    } else if (isYUV444(data) && !data->mCbSkip) {
-      rv = libyuv::I444ToI420(data->mYChannel, data->mYStride,
-                              data->mCbChannel, data->mCbCrStride,
-                              data->mCrChannel, data->mCbCrStride,
-                              y, mFrameWidth,
-                              cb, halfWidth,
-                              cr, halfWidth,
-                              mFrameWidth, mFrameHeight);
+    if (imageBitmapFormat == ImageBitmapFormat::YUV420SP_NV12) {
+      rv = libyuv::NV12ToI420(data->mYChannel,
+                              data->mYStride,
+                              data->mCbChannel,
+                              data->mCbCrStride,
+                              y,
+                              mFrameWidth,
+                              cb,
+                              halfWidth,
+                              cr,
+                              halfWidth,
+                              mFrameWidth,
+                              mFrameHeight);
+      yuvFormat = "NV12";
+    } else if (imageBitmapFormat == ImageBitmapFormat::YUV420SP_NV21) {
+      rv = libyuv::NV21ToI420(data->mYChannel,
+                              data->mYStride,
+                              data->mCrChannel,
+                              data->mCbCrStride,
+                              y,
+                              mFrameWidth,
+                              cb,
+                              halfWidth,
+                              cr,
+                              halfWidth,
+                              mFrameWidth,
+                              mFrameHeight);
+      yuvFormat = "NV21";
+    } else if (imageBitmapFormat == ImageBitmapFormat::YUV444P) {
+      rv = libyuv::I444ToI420(data->mYChannel,
+                              data->mYStride,
+                              data->mCbChannel,
+                              data->mCbCrStride,
+                              data->mCrChannel,
+                              data->mCbCrStride,
+                              y,
+                              mFrameWidth,
+                              cb,
+                              halfWidth,
+                              cr,
+                              halfWidth,
+                              mFrameWidth,
+                              mFrameHeight);
       yuvFormat = "I444";
-    } else if (isYUV422(data) && !data->mCbSkip) {
-      rv = libyuv::I422ToI420(data->mYChannel, data->mYStride,
-                              data->mCbChannel, data->mCbCrStride,
-                              data->mCrChannel, data->mCbCrStride,
-                              y, mFrameWidth,
-                              cb, halfWidth,
-                              cr, halfWidth,
-                              mFrameWidth, mFrameHeight);
+    } else if (imageBitmapFormat == ImageBitmapFormat::YUV422P) {
+      rv = libyuv::I422ToI420(data->mYChannel,
+                              data->mYStride,
+                              data->mCbChannel,
+                              data->mCbCrStride,
+                              data->mCrChannel,
+                              data->mCbCrStride,
+                              y,
+                              mFrameWidth,
+                              cb,
+                              halfWidth,
+                              cr,
+                              halfWidth,
+                              mFrameWidth,
+                              mFrameHeight);
       yuvFormat = "I422";
     } else {
       VP8LOG(LogLevel::Error, "Unsupported planar format");
       NS_ASSERTION(false, "Unsupported planar format");
       return NS_ERROR_NOT_IMPLEMENTED;
     }
 
     if (rv != 0) {
deleted file mode 100644
--- a/dom/media/fmp4/MP4Stream.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 "MP4Stream.h"
-#include "MediaResource.h"
-
-namespace mozilla {
-
-MP4Stream::MP4Stream(MediaResource* aResource)
-  : mResource(aResource)
-  , mPinCount(0)
-{
-  MOZ_COUNT_CTOR(MP4Stream);
-  MOZ_ASSERT(aResource);
-}
-
-MP4Stream::~MP4Stream()
-{
-  MOZ_COUNT_DTOR(MP4Stream);
-  MOZ_ASSERT(mPinCount == 0);
-}
-
-bool
-MP4Stream::BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnlock)
-{
-  MOZ_ASSERT(mPinCount > 0);
-  CacheBlock block(aOffset, aCount);
-  if (!block.Init()) {
-    return false;
-  }
-
-  uint32_t bytesRead = 0;
-  {
-    MonitorAutoUnlock unlock(*aToUnlock);
-    nsresult rv = mResource.ReadAt(aOffset, block.Buffer(), aCount, &bytesRead);
-    if (NS_FAILED(rv)) {
-      return false;
-    }
-  }
-
-  MOZ_ASSERT(block.mCount >= bytesRead);
-  block.mCount = bytesRead;
-
-  mCache.AppendElement(Move(block));
-  return true;
-}
-
-// We surreptitiously reimplement the supposedly-blocking ReadAt as a non-
-// blocking CachedReadAt, and record when it fails. This allows MP4Reader
-// to retry the read as an actual blocking read without holding the lock.
-bool
-MP4Stream::ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
-                  size_t* aBytesRead)
-{
-  if (mFailedRead.isSome()) {
-    mFailedRead.reset();
-  }
-
-  if (!CachedReadAt(aOffset, aBuffer, aCount, aBytesRead)) {
-    mFailedRead.emplace(aOffset, aCount);
-    return false;
-  }
-
-  return true;
-}
-
-bool
-MP4Stream::CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
-                        size_t* aBytesRead)
-{
-  // First, check our local cache.
-  for (size_t i = 0; i < mCache.Length(); ++i) {
-    if (mCache[i].mOffset == aOffset && mCache[i].mCount >= aCount) {
-      memcpy(aBuffer, mCache[i].Buffer(), aCount);
-      *aBytesRead = aCount;
-      return true;
-    }
-  }
-
-  nsresult rv =
-    mResource.GetResource()->ReadFromCache(reinterpret_cast<char*>(aBuffer),
-                                           aOffset, aCount);
-  if (NS_FAILED(rv)) {
-    *aBytesRead = 0;
-    return false;
-  }
-  *aBytesRead = aCount;
-  return true;
-}
-
-bool
-MP4Stream::Length(int64_t* aSize)
-{
-  if (mResource.GetLength() < 0)
-    return false;
-  *aSize = mResource.GetLength();
-  return true;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/fmp4/MP4Stream.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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 MP4_STREAM_H_
-#define MP4_STREAM_H_
-
-#include "mp4_demuxer/Stream.h"
-
-#include "MediaResource.h"
-
-#include "mozilla/Maybe.h"
-#include "mozilla/Monitor.h"
-#include "mozilla/UniquePtrExtensions.h"
-
-namespace mozilla {
-
-class Monitor;
-
-class MP4Stream : public mp4_demuxer::Stream {
-public:
-  explicit MP4Stream(MediaResource* aResource);
-  virtual ~MP4Stream();
-  bool BlockingReadIntoCache(int64_t aOffset, size_t aCount, Monitor* aToUnlock);
-  bool ReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
-              size_t* aBytesRead) override;
-  bool CachedReadAt(int64_t aOffset, void* aBuffer, size_t aCount,
-                    size_t* aBytesRead) override;
-  bool Length(int64_t* aSize) override;
-
-  struct ReadRecord {
-    ReadRecord(int64_t aOffset, size_t aCount) : mOffset(aOffset), mCount(aCount) {}
-    bool operator==(const ReadRecord& aOther) { return mOffset == aOther.mOffset && mCount == aOther.mCount; }
-    int64_t mOffset;
-    size_t mCount;
-  };
-  bool LastReadFailed(ReadRecord* aOut)
-  {
-    if (mFailedRead.isSome()) {
-      *aOut = mFailedRead.ref();
-      return true;
-    }
-
-    return false;
-  }
-
-  void ClearFailedRead() { mFailedRead.reset(); }
-
-  void Pin()
-  {
-    mResource.GetResource()->Pin();
-    ++mPinCount;
-  }
-
-  void Unpin()
-  {
-    mResource.GetResource()->Unpin();
-    MOZ_ASSERT(mPinCount);
-    --mPinCount;
-    if (mPinCount == 0) {
-      mCache.Clear();
-    }
-  }
-
-private:
-  MediaResourceIndex mResource;
-  Maybe<ReadRecord> mFailedRead;
-  uint32_t mPinCount;
-
-  struct CacheBlock {
-    CacheBlock(int64_t aOffset, size_t aCount)
-      : mOffset(aOffset), mCount(aCount), mBuffer(nullptr) {}
-    int64_t mOffset;
-    size_t mCount;
-
-    CacheBlock(CacheBlock&& aOther)
-      : mOffset(aOther.mOffset)
-      , mCount(aOther.mCount)
-      , mBuffer(Move(aOther.mBuffer))
-    {}
-
-    bool Init()
-    {
-      mBuffer = MakeUniqueFallible<char[]>(mCount);
-      return !!mBuffer;
-    }
-
-    char* Buffer()
-    {
-      MOZ_ASSERT(mBuffer.get());
-      return mBuffer.get();
-    }
-
-  private:
-    CacheBlock(const CacheBlock&) = delete;
-    CacheBlock& operator=(const CacheBlock&) = delete;
-
-    UniquePtr<char[]> mBuffer;
-  };
-  nsTArray<CacheBlock> mCache;
-};
-
-} // namespace mozilla
-
-#endif
--- a/dom/media/fmp4/moz.build
+++ b/dom/media/fmp4/moz.build
@@ -2,22 +2,20 @@
 # 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 += [
     'MP4Decoder.h',
     'MP4Demuxer.h',
-    'MP4Stream.h',
 ]
 
 UNIFIED_SOURCES += [
     'MP4Decoder.cpp',
-    'MP4Stream.cpp',
 ]
 
 SOURCES += [
     'MP4Demuxer.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
 
--- a/dom/media/gtest/TestMP4Demuxer.cpp
+++ b/dom/media/gtest/TestMP4Demuxer.cpp
@@ -1,16 +1,15 @@
 /* -*- 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/. */
 
 #include "gtest/gtest.h"
 #include "MP4Demuxer.h"
-#include "MP4Stream.h"
 #include "mozilla/MozPromise.h"
 #include "MediaDataDemuxer.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/TaskQueue.h"
 #include "mozilla/ArrayUtils.h"
 #include "MockMediaResource.h"
 #include "VideoUtils.h"
 
--- a/dom/media/gtest/TestVideoTrackEncoder.cpp
+++ b/dom/media/gtest/TestVideoTrackEncoder.cpp
@@ -98,17 +98,17 @@ private:
     data.mCbCrSize.height = halfHeight;
 
     image->CopyData(data);
     return image;
   }
 
   Image *CreateNV12Image()
   {
-    PlanarYCbCrImage *image = new RecyclingPlanarYCbCrImage(new BufferRecycleBin());
+    NVImage* image = new NVImage();
     PlanarYCbCrData data;
     data.mPicSize = mImageSize;
 
     const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
     const uint32_t halfWidth = (mImageSize.width + 1) / 2;
     const uint32_t halfHeight = (mImageSize.height + 1) / 2;
 
     // Y plane.
@@ -129,23 +129,23 @@ private:
     data.mCbChannel = cb;
     data.mCbSkip = 1;
 
     // 4:2:0.
     data.mCbCrStride = mImageSize.width;
     data.mCbCrSize.width = halfWidth;
     data.mCbCrSize.height = halfHeight;
 
-    image->CopyData(data);
+    image->SetData(data);
     return image;
   }
 
   Image *CreateNV21Image()
   {
-    PlanarYCbCrImage *image = new RecyclingPlanarYCbCrImage(new BufferRecycleBin());
+    NVImage* image = new NVImage();
     PlanarYCbCrData data;
     data.mPicSize = mImageSize;
 
     const uint32_t yPlaneSize = mImageSize.width * mImageSize.height;
     const uint32_t halfWidth = (mImageSize.width + 1) / 2;
     const uint32_t halfHeight = (mImageSize.height + 1) / 2;
 
     // Y plane.
@@ -166,17 +166,17 @@ private:
     data.mCbChannel = cb;
     data.mCbSkip = 1;
 
     // 4:2:0.
     data.mCbCrStride = mImageSize.width;
     data.mCbCrSize.width = halfWidth;
     data.mCbCrSize.height = halfHeight;
 
-    image->CopyData(data);
+    image->SetData(data);
     return image;
   }
 
 private:
   mozilla::gfx::IntSize mImageSize;
   nsTArray<uint8_t> mSourceBuffer;
 };
 
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -10,19 +10,19 @@
 #include "mozilla/EndianUtils.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/ErrorResult.h"
 #include "mp4_demuxer/MoofParser.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Maybe.h"
 #include "MediaData.h"
 #ifdef MOZ_FMP4
-#include "MP4Stream.h"
 #include "mp4_demuxer/AtomType.h"
 #include "mp4_demuxer/ByteReader.h"
+#include "mp4_demuxer/Stream.h"
 #endif
 #include "nsAutoPtr.h"
 #include "SourceBufferResource.h"
 #include <algorithm>
 
 extern mozilla::LogModule* GetMediaSourceSamplesLog();
 
 #define STRINGIFY(x) #x
@@ -353,16 +353,82 @@ public:
 private:
   WebMBufferedParser mParser;
   nsTArray<WebMTimeDataOffset> mOverlappedMapping;
   int64_t mOffset;
   Maybe<WebMTimeDataOffset> mLastMapping;
 };
 
 #ifdef MOZ_FMP4
+
+class MP4Stream : public mp4_demuxer::Stream
+{
+public:
+  explicit MP4Stream(SourceBufferResource* aResource);
+  virtual ~MP4Stream();
+  bool ReadAt(int64_t aOffset,
+              void* aBuffer,
+              size_t aCount,
+              size_t* aBytesRead) override;
+  bool CachedReadAt(int64_t aOffset,
+                    void* aBuffer,
+                    size_t aCount,
+                    size_t* aBytesRead) override;
+  bool Length(int64_t* aSize) override;
+
+private:
+  RefPtr<SourceBufferResource> mResource;
+};
+
+MP4Stream::MP4Stream(SourceBufferResource* aResource)
+  : mResource(aResource)
+{
+  MOZ_COUNT_CTOR(MP4Stream);
+  MOZ_ASSERT(aResource);
+}
+
+MP4Stream::~MP4Stream()
+{
+  MOZ_COUNT_DTOR(MP4Stream);
+}
+
+bool
+MP4Stream::ReadAt(int64_t aOffset,
+                  void* aBuffer,
+                  size_t aCount,
+                  size_t* aBytesRead)
+{
+  return CachedReadAt(aOffset, aBuffer, aCount, aBytesRead);
+}
+
+bool
+MP4Stream::CachedReadAt(int64_t aOffset,
+                        void* aBuffer,
+                        size_t aCount,
+                        size_t* aBytesRead)
+{
+  nsresult rv = mResource->ReadFromCache(
+    reinterpret_cast<char*>(aBuffer), aOffset, aCount);
+  if (NS_FAILED(rv)) {
+    *aBytesRead = 0;
+    return false;
+  }
+  *aBytesRead = aCount;
+  return true;
+}
+
+bool
+MP4Stream::Length(int64_t* aSize)
+{
+  if (mResource->GetLength() < 0)
+    return false;
+  *aSize = mResource->GetLength();
+  return true;
+}
+
 class MP4ContainerParser : public ContainerParser
 {
 public:
   explicit MP4ContainerParser(const MediaContainerType& aType)
     : ContainerParser(aType)
   {
   }
 
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -218,17 +218,16 @@ UNIFIED_SOURCES += [
     'FileBlockCache.cpp',
     'GetUserMediaRequest.cpp',
     'GraphDriver.cpp',
     'Latency.cpp',
     'MediaCache.cpp',
     'MediaContainerType.cpp',
     'MediaData.cpp',
     'MediaDecoder.cpp',
-    'MediaDecoderReaderWrapper.cpp',
     'MediaDecoderStateMachine.cpp',
     'MediaDeviceInfo.cpp',
     'MediaDevices.cpp',
     'MediaFormatReader.cpp',
     'MediaInfo.cpp',
     'MediaManager.cpp',
     'MediaMIMETypes.cpp',
     'MediaPrefs.cpp',
@@ -240,16 +239,17 @@ UNIFIED_SOURCES += [
     'MediaStreamListener.cpp',
     'MediaStreamTrack.cpp',
     'MediaStreamVideoSink.cpp',
     'MediaTimer.cpp',
     'MediaTrack.cpp',
     'MediaTrackList.cpp',
     'MemoryBlockCache.cpp',
     'QueueObject.cpp',
+    'ReaderProxy.cpp',
     'SeekJob.cpp',
     'StreamTracks.cpp',
     'TextTrack.cpp',
     'TextTrackCue.cpp',
     'TextTrackCueList.cpp',
     'TextTrackList.cpp',
     'TextTrackRegion.cpp',
     'TrackUnionStream.cpp',
--- a/dom/smil/crashtests/crashtests.list
+++ b/dom/smil/crashtests/crashtests.list
@@ -15,17 +15,17 @@ load 551620-1.svg
 load 554141-1.svg
 load 554202-1.svg
 load 554202-2.svg
 load 555026-1.svg
 load 556841-1.svg
 load 572938-1.svg
 load 572938-2.svg
 load 572938-3.svg
-load 572938-4.svg
+skip-if(stylo) load 572938-4.svg # Bug 1385089
 load 588287-1.svg
 load 588287-2.svg
 load 590425-1.html
 load 592477-1.xhtml
 load 594653-1.svg
 load 596796-1.svg
 load 605345-1.svg
 load 606101-1.svg
--- a/dom/vr/test/mochitest/mochitest.ini
+++ b/dom/vr/test/mochitest/mochitest.ini
@@ -1,18 +1,18 @@
 [DEFAULT]
 support-files =
   VRSimulationDriver.js
   requestPresent.js
   runVRTest.js
   WebVRHelpers.js
 
 [test_vrController_displayId.html]
-# Enable Linux after Bug 1310655 # TIMED_OUT for nonE10s and Android.
-skip-if = (os != "win" && release_or_beta) || (!e10s) || (os == "android")
+# Enable Linux after Bug 1310655 # TIMED_OUT for Android.
+skip-if = (os != "win" && release_or_beta) || (os == "android")
 [test_vrDisplay_canvas2d.html]
 skip-if = (os != "win" && release_or_beta) # Enable Linux after Bug 1310655
 [test_vrDisplay_exitPresent.html]
 skip-if = (os != "win" && release_or_beta) # Enable Linux after Bug 1310655
 [test_vrDisplay_getFrameData.html]
 skip-if = (os != "win" && release_or_beta) # Enable Linux after Bug 1310655
 [test_vrDisplay_onvrdisplaydeactivate_crosscontent.html]
 skip-if = true
--- a/dom/vr/test/mochitest/test_vrController_displayId.html
+++ b/dom/vr/test/mochitest/test_vrController_displayId.html
@@ -20,35 +20,35 @@
           return VRSimulationDriver.AttachVRController().then((controller) => {
             controller.newButtonEvent(0, true);
           });
         }, "Finish to add VRController.");
       }
 
       function listenControllerEvents() {
         async_test(function(t) {
-          window.addEventListener("gamepadconnected", function() {
-              var gamepads = navigator.getGamepads();
-              assert_equals(gamepads[controllerCount].displayId, vrDisplay.displayId, "gamepad.displayId should be equal to vrDisplay.");
+          window.addEventListener("gamepadbuttondown", function(e) {
+              assert_equals(e.gamepad.displayId, vrDisplay.displayId, "gamepad.displayId should be equal to vrDisplay.");
               ++controllerCount;
-              if (controllerCount == 1) {
+              if (controllerCount == 2) {
                 t.done();
               }
           });
         }, "Finish to verify VRController.displayId.");
       }
 
       function startTest() {
         promise_test((test) => {
           listenControllerEvents();
           return navigator.getVRDisplays().then((displays) => {
             vrDisplay = displays[0];
             assert_equals(displays.length, 1, "displays.length must be one after attach.");
             assert_equals(displays[0].displayId, 1, "displayId must be one.");
             addController();
+            addController();
           });
         }, "Finish to add VRDisplay.");
       }
 
       runVRTest(startTest);
     </script>
   </body>
 </html>
\ No newline at end of file
--- a/dom/webauthn/WebAuthnManager.cpp
+++ b/dom/webauthn/WebAuthnManager.cpp
@@ -430,18 +430,20 @@ WebAuthnManager::MakeCredential(nsPIDOMW
   // and compute the clientDataJSON and clientDataHash.
 
   CryptoBuffer challenge;
   if (!challenge.Assign(aOptions.mChallenge)) {
     promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
     return promise.forget();
   }
 
+  // WD-05 vs. WD-06: In WD-06, the first parameter should be "origin". Fix
+  // this in Bug 1384776
   nsAutoCString clientDataJSON;
-  srv = AssembleClientData(origin, challenge, clientDataJSON);
+  srv = AssembleClientData(NS_ConvertUTF8toUTF16(rpId), challenge, clientDataJSON);
   if (NS_WARN_IF(NS_FAILED(srv))) {
     promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
     return promise.forget();
   }
 
   CryptoBuffer clientDataHash;
   if (!clientDataHash.SetLength(SHA256_LENGTH, fallible)) {
     promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
@@ -583,17 +585,19 @@ WebAuthnManager::GetAssertion(nsPIDOMWin
   // the clientDataJSON and clientDataHash.
   CryptoBuffer challenge;
   if (!challenge.Assign(aOptions.mChallenge)) {
     promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
     return promise.forget();
   }
 
   nsAutoCString clientDataJSON;
-  srv = AssembleClientData(origin, challenge, clientDataJSON);
+  // WD-05 vs. WD-06: In WD-06, the first parameter should be "origin". Fix
+  // this in Bug 1384776
+  srv = AssembleClientData(NS_ConvertUTF8toUTF16(rpId), challenge, clientDataJSON);
   if (NS_WARN_IF(NS_FAILED(srv))) {
     promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
     return promise.forget();
   }
 
   CryptoBuffer clientDataHash;
   if (!clientDataHash.SetLength(SHA256_LENGTH, fallible)) {
     promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
--- a/dom/webauthn/tests/test_webauthn_loopback.html
+++ b/dom/webauthn/tests/test_webauthn_loopback.html
@@ -53,17 +53,19 @@ function() {
 
     is(aCredInfo.type, "public-key", "Credential type must be public-key")
 
     ok(aCredInfo.rawId.length > 0, "Key ID exists");
     is(aCredInfo.id, bytesToBase64UrlSafe(aCredInfo.rawId), "Encoded Key ID and Raw Key ID match");
 
     let clientData = JSON.parse(buffer2string(aCredInfo.response.clientDataJSON));
     is(clientData.challenge, bytesToBase64UrlSafe(gCredentialChallenge), "Challenge is correct");
-    is(clientData.origin, window.location.origin, "Origin is correct");
+    // WD-05 vs. WD-06: In WD-06, the second parameter should be "window.location.origin". Fix
+    // this in Bug 1384776
+    is(clientData.origin, document.domain, "Origin is correct");
     is(clientData.hashAlg, "S256", "Hash algorithm is correct");
 
     return webAuthnDecodeAttestation(aCredInfo.response.attestationObject.buffer)
     .then(function(decodedResult) {
       aCredInfo.clientDataObj = clientData;
       aCredInfo.publicKeyHandle = decodedResult.publicKeyHandle;
       aCredInfo.attestationObject = decodedResult.attestationObject;
       return aCredInfo;
@@ -84,17 +86,19 @@ function() {
     is(aAssertion.type, "public-key", "Credential type must be public-key")
 
     ok(aAssertion.rawId.length > 0, "Key ID exists");
     is(aAssertion.id, bytesToBase64UrlSafe(aAssertion.rawId), "Encoded Key ID and Raw Key ID match");
 
     ok(aAssertion.response.authenticatorData.length > 0, "Authenticator data exists");
     let clientData = JSON.parse(buffer2string(aAssertion.response.clientDataJSON));
     is(clientData.challenge, bytesToBase64UrlSafe(gAssertionChallenge), "Challenge is correct");
-    is(clientData.origin, window.location.origin, "Origin is correct");
+    // WD-05 vs. WD-06: In WD-06, the second parameter should be "window.location.origin". Fix
+    // this in Bug 1384776
+    is(clientData.origin, document.domain, "Origin is correct");
     is(clientData.hashAlg, "S256", "Hash algorithm is correct");
 
     // Parse the signature data
     if (aAssertion.response.signature[0] != 0x01) {
       throw "User presence byte not set";
     }
     let presenceAndCounter = aAssertion.response.signature.slice(0,5);
     let signatureValue = aAssertion.response.signature.slice(5);
--- a/dom/webidl/HTMLSelectElement.webidl
+++ b/dom/webidl/HTMLSelectElement.webidl
@@ -6,17 +6,17 @@
  * The origin of this IDL file is
  * http://www.whatwg.org/html/#the-select-element
  */
 
 [HTMLConstructor]
 interface HTMLSelectElement : HTMLElement {
   [CEReactions, SetterThrows, Pure]
            attribute boolean autofocus;
-  [CEReactions, Pref="dom.forms.autocomplete.experimental", SetterThrows, Pure]
+  [CEReactions, Pref="dom.forms.autocomplete.formautofill", SetterThrows, Pure]
            attribute DOMString autocomplete;
   [CEReactions, SetterThrows, Pure]
            attribute boolean disabled;
   [Pure]
   readonly attribute HTMLFormElement? form;
   [CEReactions, SetterThrows, Pure]
            attribute boolean multiple;
   [CEReactions, SetterThrows, Pure]
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -263,22 +263,27 @@ nsXBLResourceLoader::NotifyBoundElements
             nsStyleContext* sc =
               shell->FrameManager()->GetUndisplayedContent(content);
 
             if (!sc) {
               sc = shell->FrameManager()->GetDisplayContentsStyleFor(content);
             }
 
             if (!sc) {
-              if (shell->StyleSet()->IsServo()) {
+              if (ServoStyleSet* servoSet = shell->StyleSet()->GetAsServo()) {
                 // Ensure the element has servo data so that
                 // nsChangeHint_ReconstructFrame posted by
                 // PostRecreateFramesFor() is recognized.
-                shell->StyleSet()->GetAsServo()->StyleNewlyBoundElement(
-                  content->AsElement());
+                //
+                // Also check MayTraverseFrom to handle programatic XBL consumers.
+                // See bug 1370793.
+                Element* element = content->AsElement();
+                if (servoSet->MayTraverseFrom(element)) {
+                  servoSet->StyleNewlyBoundElement(element);
+                }
               }
               shell->PostRecreateFramesFor(content->AsElement());
             }
           }
         }
 
         // Flush again
         // XXXbz why is this needed?
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -416,18 +416,23 @@ class MOZ_STACK_CLASS AutoStyleNewChildr
 public:
   explicit AutoStyleNewChildren(Element* aElement) : mElement(aElement) { MOZ_ASSERT(mElement); }
   ~AutoStyleNewChildren()
   {
     nsIPresShell* presShell = mElement->OwnerDoc()->GetShell();
     if (!presShell || !presShell->DidInitialize()) {
       return;
     }
+
     if (ServoStyleSet* servoSet = presShell->StyleSet()->GetAsServo()) {
-      servoSet->StyleNewlyBoundElement(mElement);
+      // Check MayTraverseFrom to handle programatic XBL consumers.
+      // See bug 1370793.
+      if (servoSet->MayTraverseFrom(mElement)) {
+        servoSet->StyleNewlyBoundElement(mElement);
+      }
     }
   }
 
 private:
   Element* mElement;
 };
 
 // This function loads a particular XBL file and installs all of the bindings
--- a/dom/xslt/crashtests/crashtests.list
+++ b/dom/xslt/crashtests/crashtests.list
@@ -8,15 +8,15 @@ load 485217.xml
 load 485286.xml
 load 527558_1.xml
 load 528300.xml
 load 528488.xml
 load 528963.xml
 load 545927.html
 load 601543.html
 load 602115.html
-load 603844.html
+skip-if(stylo&&isDebugBuild&&winWidget) load 603844.html # Bug 1383845
 load 667315.xml
 load 1089049.html
 load 1205163.xml
 load 1243337.xml
 load 1338277.html
 load 1361892.html
--- a/editor/libeditor/crashtests/crashtests.list
+++ b/editor/libeditor/crashtests/crashtests.list
@@ -10,19 +10,19 @@ load 407256-1.html
 load 407277-1.html
 load 414178-1.html
 load 418923-1.html
 load 420439.html
 load 428489-1.html
 load 429586-1.html
 load 430624-1.html
 load 431086-1.xhtml
-load 448329-1.html
+skip-if(stylo&&isDebugBuild&&winWidget) load 448329-1.html # Bug 1383845
 load 448329-2.html
-load 448329-3.html
+skip-if(stylo&&isDebugBuild&&winWidget) load 448329-3.html # Bug 1383845
 load 456727-1.html
 load 456727-2.html
 load 459613.html
 needs-focus load 467647-1.html
 load 475132-1.xhtml
 load 499844-1.html
 load 503709-1.xhtml
 load 513375-1.xhtml
--- a/editor/reftests/xul/reftest.list
+++ b/editor/reftests/xul/reftest.list
@@ -1,29 +1,29 @@
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == empty-1.xul empty-ref.xul # Windows: bug 1239170
 != empty-2.xul empty-ref.xul
 # There is no way to simulate an autocomplete textbox in windows XP/Vista/7/8/10 default theme using CSS.
 # Therefore, the equlity tests below should be marked as failing.
-fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) == autocomplete-1.xul autocomplete-ref.xul # bug 783658
-fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) == emptyautocomplete-1.xul emptyautocomplete-ref.xul # bug 783658
+fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)&&!styloVsGecko) == autocomplete-1.xul autocomplete-ref.xul # bug 783658
+fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)&&!styloVsGecko) == emptyautocomplete-1.xul emptyautocomplete-ref.xul # bug 783658
 != emptymultiline-1.xul emptymultiline-ref.xul
 fails-if(Android) == emptymultiline-2.xul emptymultiline-ref.xul # bug 783658
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == emptytextbox-1.xul emptytextbox-ref.xul # Windows: bug 1239170
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == emptytextbox-2.xul emptytextbox-ref.xul # Windows: bug 1239170
 != emptytextbox-3.xul emptytextbox-ref.xul
 != emptytextbox-4.xul emptytextbox-ref.xul
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == emptytextbox-5.xul emptytextbox-ref.xul # Windows: bug 1239170
 # There is no way to simulate a number textbox in windows XP/Vista/7 default theme using CSS.
 # Therefore, the equlity tests below should be marked as failing.
 != number-1.xul number-ref.xul
 != number-2.xul number-ref.xul
-fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) == number-3.xul number-ref.xul # bug 783658
+fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)&&!styloVsGecko) == number-3.xul number-ref.xul # bug 783658
 != number-4.xul number-ref.xul
-fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) == number-5.xul number-ref.xul # bug 783658
-fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) == numberwithvalue-1.xul numberwithvalue-ref.xul # bug 783658
+fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)&&!styloVsGecko) == number-5.xul number-ref.xul # bug 783658
+fails-if(Android) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)&&!styloVsGecko) == numberwithvalue-1.xul numberwithvalue-ref.xul # bug 783658
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == passwd-1.xul passwd-ref.xul # Windows: bug 1239170
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == passwd-2.xul passwd-ref.xul # Windows: bug 1239170
 != passwd-3.xul passwd-ref.xul
 fails-if(Android) == plain-1.xul plain-ref.xul # bug 783658
 fails-if(Android) skip-if(browserIsRemote&&winWidget) == textbox-1.xul textbox-ref.xul # Windows: bug 1239170
 != textbox-disabled.xul textbox-ref.xul
 # Read-only textboxes look like normal textboxes in windows Vista/7 default theme
 fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(6\.[012]|10\.0)/.test(http.oscpu)) skip-if(browserIsRemote&&winWidget) != textbox-readonly.xul textbox-ref.xul # Windows: bug 1239170
--- a/gfx/src/nsCoord.h
+++ b/gfx/src/nsCoord.h
@@ -41,17 +41,17 @@ inline bool NS_IEEEIsNan(float aF) {
     (pun.mBits & 0x007FFFFF) != 0;
 }
 
 #ifdef NS_COORD_IS_FLOAT
 typedef float nscoord;
 #define nscoord_MAX NS_IEEEPositiveInfinity()
 #else
 typedef int32_t nscoord;
-#define nscoord_MAX nscoord(1 << 30)
+#define nscoord_MAX nscoord((1 << 30) - 1)
 #endif
 
 #define nscoord_MIN (-nscoord_MAX)
 
 inline void VERIFY_COORD(nscoord aCoord) {
 #ifdef NS_COORD_IS_FLOAT
   NS_ASSERTION(floorf(aCoord) == aCoord,
                "Coords cannot have fractions");
@@ -127,18 +127,18 @@ inline nscoord _nscoordSaturatingMultipl
     MOZ_ASSERT(aScale >= 0.0f,
                "negative scaling factors must be handled manually");
   }
 #ifdef NS_COORD_IS_FLOAT
   return floorf(aCoord * aScale);
 #else
   float product = aCoord * aScale;
   if (requireNotNegative ? aCoord > 0 : (aCoord > 0) == (aScale > 0))
-    return NSToCoordRoundWithClamp(std::min<float>(nscoord_MAX, product));
-  return NSToCoordRoundWithClamp(std::max<float>(nscoord_MIN, product));
+    return NSToCoordRoundWithClamp(std::min<float>((float)nscoord_MAX, product));
+  return NSToCoordRoundWithClamp(std::max<float>((float)nscoord_MIN, product));
 #endif
 }
 
 /**
  * Returns aCoord * aScale, capping the product to nscoord_MAX or nscoord_MIN as
  * appropriate for the sign of aCoord.  This method requires aScale to not be
  * negative; use this method when you know that aScale should never be
  * negative to get a sanity check of that invariant in debug builds.
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -1547,60 +1547,67 @@ VRSystemManagerOculus::HandleInput()
     controller->SetButtonTouched(inputState.Touches);
 
     axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickXAxis);
     HandleAxisMove(i, axis, inputState.Thumbstick[i].x);
 
     axis = static_cast<uint32_t>(OculusControllerAxisType::ThumbstickYAxis);
     HandleAxisMove(i, axis, -inputState.Thumbstick[i].y);
 
-    // Start to process pose
+    // Process pose state.
+    GamepadPoseState poseState;
+    GetControllerPoseState(handIdx, poseState);
+    HandlePoseTracking(i, poseState, controller);
+  }
+}
+
+void
+VRSystemManagerOculus::GetControllerPoseState(uint32_t aHandIdx, GamepadPoseState& aPoseState,
+                                              bool aForceUpdate)
+{
     ovrTrackingState state = ovr_GetTrackingState(mSession->Get(), 0.0, false);
 
     // HandPoses is ordered by ovrControllerType_LTouch and ovrControllerType_RTouch,
     // therefore, we can't get its state by the index of mOculusController.
-    ovrPoseStatef& pose(state.HandPoses[handIdx]);
-    GamepadPoseState poseState;
+    ovrPoseStatef& pose(state.HandPoses[aHandIdx]);
 
-    if (state.HandStatusFlags[handIdx] & ovrStatus_OrientationTracked) {
-      poseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
-      poseState.orientation[0] = pose.ThePose.Orientation.x;
-      poseState.orientation[1] = pose.ThePose.Orientation.y;
-      poseState.orientation[2] = pose.ThePose.Orientation.z;
-      poseState.orientation[3] = pose.ThePose.Orientation.w;
-      poseState.angularVelocity[0] = pose.AngularVelocity.x;
-      poseState.angularVelocity[1] = pose.AngularVelocity.y;
-      poseState.angularVelocity[2] = pose.AngularVelocity.z;
+    if (aForceUpdate || state.HandStatusFlags[aHandIdx] & ovrStatus_OrientationTracked) {
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_Orientation;
+      aPoseState.orientation[0] = pose.ThePose.Orientation.x;
+      aPoseState.orientation[1] = pose.ThePose.Orientation.y;
+      aPoseState.orientation[2] = pose.ThePose.Orientation.z;
+      aPoseState.orientation[3] = pose.ThePose.Orientation.w;
+      aPoseState.angularVelocity[0] = pose.AngularVelocity.x;
+      aPoseState.angularVelocity[1] = pose.AngularVelocity.y;
+      aPoseState.angularVelocity[2] = pose.AngularVelocity.z;
 
-      poseState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
-      poseState.angularAcceleration[0] = pose.AngularAcceleration.x;
-      poseState.angularAcceleration[1] = pose.AngularAcceleration.y;
-      poseState.angularAcceleration[2] = pose.AngularAcceleration.z;
-      poseState.isOrientationValid = true;
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_AngularAcceleration;
+      aPoseState.angularAcceleration[0] = pose.AngularAcceleration.x;
+      aPoseState.angularAcceleration[1] = pose.AngularAcceleration.y;
+      aPoseState.angularAcceleration[2] = pose.AngularAcceleration.z;
+      aPoseState.isOrientationValid = true;
     }
-    if (state.HandStatusFlags[handIdx] & ovrStatus_PositionTracked) {
-      poseState.flags |= GamepadCapabilityFlags::Cap_Position;
-      poseState.position[0] = pose.ThePose.Position.x;
-      poseState.position[1] = pose.ThePose.Position.y;
-      poseState.position[2] = pose.ThePose.Position.z;
-      poseState.linearVelocity[0] = pose.LinearVelocity.x;
-      poseState.linearVelocity[1] = pose.LinearVelocity.y;
-      poseState.linearVelocity[2] = pose.LinearVelocity.z;
+    if (aForceUpdate || state.HandStatusFlags[aHandIdx] & ovrStatus_PositionTracked) {
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_Position;
+      aPoseState.position[0] = pose.ThePose.Position.x;
+      aPoseState.position[1] = pose.ThePose.Position.y;
+      aPoseState.position[2] = pose.ThePose.Position.z;
+      aPoseState.linearVelocity[0] = pose.LinearVelocity.x;
+      aPoseState.linearVelocity[1] = pose.LinearVelocity.y;
+      aPoseState.linearVelocity[2] = pose.LinearVelocity.z;
 
-      poseState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
-      poseState.linearAcceleration[0] = pose.LinearAcceleration.x;
-      poseState.linearAcceleration[1] = pose.LinearAcceleration.y;
-      poseState.linearAcceleration[2] = pose.LinearAcceleration.z;
+      aPoseState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
+      aPoseState.linearAcceleration[0] = pose.LinearAcceleration.x;
+      aPoseState.linearAcceleration[1] = pose.LinearAcceleration.y;
+      aPoseState.linearAcceleration[2] = pose.LinearAcceleration.z;
 
       float eyeHeight = ovr_GetFloat(mSession->Get(), OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
-      poseState.position[1] -= eyeHeight;
-      poseState.isPositionValid = true;
+      aPoseState.position[1] -= eyeHeight;
+      aPoseState.isPositionValid = true;
     }
-    HandlePoseTracking(i, poseState, controller);
-  }
 }
 
 void
 VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
                                          uint32_t aButton,
                                          uint64_t aButtonMask,
                                          uint64_t aButtonPressed,
                                          uint64_t aButtonTouched)
@@ -1761,16 +1768,21 @@ VRSystemManagerOculus::ScanForController
   // at GetHMDs().
   if (!mSession || !mSession->IsTrackingReady()) {
     return;
   }
 
   ovrInputState inputState;
   bool hasInputState = ovr_GetInputState(mSession->Get(), ovrControllerType_Touch,
                                          &inputState) == ovrSuccess;
+
+  if (!hasInputState) {
+    return;
+  }
+
   ovrControllerType activeControllerArray[2];
   uint32_t newControllerCount = 0;
 
   if (inputState.ControllerType & ovrControllerType_LTouch) {
     activeControllerArray[newControllerCount] = ovrControllerType_LTouch;
     ++newControllerCount;
   }
 
@@ -1795,16 +1807,26 @@ VRSystemManagerOculus::ScanForController
           break;
       }
       RefPtr<VRControllerOculus> oculusController = new VRControllerOculus(hand,
                                                       mDisplay->GetDisplayInfo().GetDisplayID());
       mOculusController.AppendElement(oculusController);
 
       // Not already present, add it.
       AddGamepad(oculusController->GetControllerInfo());
+
+      // Process pose state.
+      // We wanna Oculus Touch has the right position when it shows up,
+      // so we force to update the pose no matter if it has OrientationTracked
+      // or PositionTracked.
+      const uint32_t handIdx = static_cast<uint32_t>(hand) - 1;
+      GamepadPoseState poseState;
+      GetControllerPoseState(handIdx, poseState, true);
+      HandlePoseTracking(i, poseState, oculusController);
+
       ++mControllerCount;
     }
   }
 }
 
 void
 VRSystemManagerOculus::RemoveControllers()
 {
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -197,16 +197,19 @@ private:
                       float aValue);
   void HandlePoseTracking(uint32_t aControllerIdx,
                           const dom::GamepadPoseState& aPose,
                           VRControllerHost* aController);
   void HandleIndexTriggerPress(uint32_t aControllerIdx, uint32_t aButton, float aValue);
   void HandleHandTriggerPress(uint32_t aControllerIdx, uint32_t aButton, float aValue);
   void HandleTouchEvent(uint32_t aControllerIdx, uint32_t aButton,
                         uint64_t aTouchMask, uint64_t aTouched);
+  void GetControllerPoseState(uint32_t aHandIdx, dom::GamepadPoseState& aPoseState,
+                              bool aForceUpdate = false);
+
   RefPtr<impl::VRDisplayOculus> mDisplay;
   nsTArray<RefPtr<impl::VRControllerOculus>> mOculusController;
   RefPtr<impl::VROculusSession> mSession;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
--- a/gfx/vr/gfxVROpenVR.cpp
+++ b/gfx/vr/gfxVROpenVR.cpp
@@ -200,19 +200,20 @@ VRDisplayOpenVR::PollEvents()
   }
 }
 
 VRHMDSensorState
 VRDisplayOpenVR::GetSensorState()
 {
   PollEvents();
 
-  ::vr::TrackedDevicePose_t poses[::vr::k_unMaxTrackedDeviceCount];
-  // Note: We *must* call WaitGetPoses in order for any rendering to happen at all
-  mVRCompositor->WaitGetPoses(poses, ::vr::k_unMaxTrackedDeviceCount, nullptr, 0);
+  const uint32_t posesSize = ::vr::k_unTrackedDeviceIndex_Hmd + 1;
+  ::vr::TrackedDevicePose_t poses[posesSize];
+  // Note: We *must* call WaitGetPoses in order for any rendering to happen at all.
+  mVRCompositor->WaitGetPoses(nullptr, 0, poses, posesSize);
 
   VRHMDSensorState result;
 
   ::vr::Compositor_FrameTiming timing;
   timing.m_nSize = sizeof(::vr::Compositor_FrameTiming);
   if (mVRCompositor->GetFrameTiming(&timing)) {
     result.timestamp = timing.m_flSystemTimeInSeconds;
   } else {
--- a/gfx/vr/gfxVRPuppet.cpp
+++ b/gfx/vr/gfxVRPuppet.cpp
@@ -493,16 +493,17 @@ VRDisplayPuppet::NotifyVSync()
   mDisplayInfo.mIsConnected = true;
 
   VRDisplayHost::NotifyVSync();
 }
 
 VRControllerPuppet::VRControllerPuppet(dom::GamepadHand aHand, uint32_t aDisplayID)
   : VRControllerHost(VRDeviceType::Puppet, aHand, aDisplayID)
   , mButtonPressState(0)
+  , mButtonTouchState(0)
 {
   MOZ_COUNT_CTOR_INHERITED(VRControllerPuppet, VRControllerHost);
   mControllerInfo.mControllerName.AssignLiteral("Puppet Gamepad");
   mControllerInfo.mNumButtons = kNumPuppetButtonMask;
   mControllerInfo.mNumAxes = kNumPuppetAxis;
   mControllerInfo.mNumHaptics = kNumPuppetHaptcs;
 }
 
@@ -646,20 +647,21 @@ VRSystemManagerPuppet::GetIsPresenting()
 
 void
 VRSystemManagerPuppet::HandleInput()
 {
   RefPtr<impl::VRControllerPuppet> controller;
   for (uint32_t i = 0; i < mPuppetController.Length(); ++i) {
     controller = mPuppetController[i];
     for (uint32_t j = 0; j < kNumPuppetButtonMask; ++j) {
-      HandleButtonPress(i, j, kPuppetButtonMask[i], controller->GetButtonPressState(),
+      HandleButtonPress(i, j, kPuppetButtonMask[j], controller->GetButtonPressState(),
                         controller->GetButtonTouchState());
     }
     controller->SetButtonPressed(controller->GetButtonPressState());
+    controller->SetButtonTouched(controller->GetButtonTouchState());
 
     for (uint32_t j = 0; j < kNumPuppetAxis; ++j) {
       HandleAxisMove(i, j, controller->GetAxisMoveState(j));
     }
     HandlePoseTracking(i, controller->GetPoseMoveState(), controller);
   }
 }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1383972.js
@@ -0,0 +1,92 @@
+// |jit-test| --ion-limit-script-size=off; error:ReferenceError
+
+function f() {
+    for (var i = 0; i < 1; i++) {
+        let x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+            x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+            x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+            x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+            x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+            x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+            x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+            x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+            x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+            x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+            xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+            xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+            xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+            xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+            xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+            xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7, xF8, xF9, xFA, xFB, xFC, xFD, xFE, xFF;
+        let y00, y01, y02, y03, y04, y05, y06, y07, y08, y09, y0A, y0B, y0C, y0D, y0E, y0F,
+            y10, y11, y12, y13, y14, y15, y16, y17, y18, y19, y1A, y1B, y1C, y1D, y1E, y1F,
+            y20, y21, y22, y23, y24, y25, y26, y27, y28, y29, y2A, y2B, y2C, y2D, y2E, y2F,
+            y30, y31, y32, y33, y34, y35, y36, y37, y38, y39, y3A, y3B, y3C, y3D, y3E, y3F,
+            y40, y41, y42, y43, y44, y45, y46, y47, y48, y49, y4A, y4B, y4C, y4D, y4E, y4F,
+            y50, y51, y52, y53, y54, y55, y56, y57, y58, y59, y5A, y5B, y5C, y5D, y5E, y5F,
+            y60, y61, y62, y63, y64, y65, y66, y67, y68, y69, y6A, y6B, y6C, y6D, y6E, y6F,
+            y70, y71, y72, y73, y74, y75, y76, y77, y78, y79, y7A, y7B, y7C, y7D, y7E, y7F,
+            y80, y81, y82, y83, y84, y85, y86, y87, y88, y89, y8A, y8B, y8C, y8D, y8E, y8F,
+            y90, y91, y92, y93, y94, y95, y96, y97, y98, y99, y9A, y9B, y9C, y9D, y9E, y9F,
+            yA0, yA1, yA2, yA3, yA4, yA5, yA6, yA7, yA8, yA9, yAA, yAB, yAC, yAD, yAE, yAF,
+            yB0, yB1, yB2, yB3, yB4, yB5, yB6, yB7, yB8, yB9, yBA, yBB, yBC, yBD, yBE, yBF,
+            yC0, yC1, yC2, yC3, yC4, yC5, yC6, yC7, yC8, yC9, yCA, yCB, yCC, yCD, yCE, yCF,
+            yD0, yD1, yD2, yD3, yD4, yD5, yD6, yD7, yD8, yD9, yDA, yDB, yDC, yDD, yDE, yDF,
+            yE0, yE1, yE2, yE3, yE4, yE5, yE6, yE7, yE8, yE9, yEA, yEB, yEC, yED, yEE, yEF,
+            yF0, yF1, yF2, yF3, yF4, yF5, yF6, yF7, yF8, yF9, yFA, yFB, yFC, yFD, yFE, yFF;
+
+        if (b()) {
+            x00 = x01 = x02 = x03 = x04 = x05 = x06 = x07 = a();
+            x08 = x09 = x0A = x0B = x0C = x0D = x0E = x0F = a();
+            x10 = x11 = x12 = x13 = x14 = x15 = x16 = x17 = a();
+            x18 = x19 = x1A = x1B = x1C = x1D = x1E = x1F = a();
+            x20 = x21 = x22 = x23 = x24 = x25 = x26 = x27 = a();
+            x28 = x29 = x2A = x2B = x2C = x2D = x2E = x2F = a();
+            x30 = x31 = x32 = x33 = x34 = x35 = x36 = x37 = a();
+            x38 = x39 = x3A = x3B = x3C = x3D = x3E = x3F = a();
+            x40 = x41 = x42 = x43 = x44 = x45 = x46 = x47 = a();
+            x48 = x49 = x4A = x4B = x4C = x4D = x4E = x4F = a();
+            x50 = x51 = x52 = x53 = x54 = x55 = x56 = x57 = a();
+            x58 = x59 = x5A = x5B = x5C = x5D = x5E = x5F = a();
+            x60 = x61 = x62 = x63 = x64 = x65 = x66 = x67 = a();
+            x68 = x69 = x6A = x6B = x6C = x6D = x6E = x6F = a();
+            x70 = x71 = x72 = x73 = x74 = x75 = x76 = x77 = a();
+            x78 = x79 = x7A = x7B = x7C = x7D = x7E = x7F = a();
+            x80 = x81 = x82 = x83 = x84 = x85 = x86 = x87 = a();
+            x88 = x89 = x8A = x8B = x8C = x8D = x8E = x8F = a();
+            x90 = x91 = x92 = x93 = x94 = x95 = x96 = x97 = a();
+            x98 = x99 = x9A = x9B = x9C = x9D = x9E = x9F = a();
+            xA0 = xA1 = xA2 = xA3 = xA4 = xA5 = xA6 = xA7 = a();
+            xA8 = xA9 = xAA = xAB = xAC = xAD = xAE = xAF = a();
+            xB0 = xB1 = xB2 = xB3 = xB4 = xB5 = xB6 = xB7 = a();
+            xB8 = xB9 = xBA = xBB = xBC = xBD = xBE = xBF = a();
+            xC0 = xC1 = xC2 = xC3 = xC4 = xC5 = xC6 = xC7 = a();
+            xC8 = xC9 = xCA = xCB = xCC = xCD = xCE = xCF = a();
+            xD0 = xD1 = xD2 = xD3 = xD4 = xD5 = xD6 = xD7 = a();
+            xD8 = xD9 = xDA = xDB = xDC = xDD = xDE = xDF = a();
+            xE0 = xE1 = xE2 = xE3 = xE4 = xE5 = xE6 = xE7 = a();
+            xE8 = xE9 = xEA = xEB = xEC = xED = xEE = xEF = a();
+            xF0 = xF1 = xF2 = xF3 = xF4 = xF5 = xF6 = xF7 = a();
+            xF8 = xF9 = xFA = xFB = xFC = xFD = xFE = xFF = a();
+        }
+
+        foo(x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+            x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+            x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+            x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+            x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+            x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+            x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+            x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+            x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+            x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+            xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+            xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+            xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+            xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+            xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+            xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7, xF8, xF9, xFA, xFB, xFC, xFD, xFE, xFF);
+    }
+}
+
+f();
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -1730,16 +1730,19 @@ TypeAnalyzer::insertConversions()
         for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ) {
             MPhi* phi = *iter++;
             if (phi->type() == MIRType::Undefined ||
                 phi->type() == MIRType::Null ||
                 phi->type() == MIRType::MagicOptimizedArguments ||
                 phi->type() == MIRType::MagicOptimizedOut ||
                 phi->type() == MIRType::MagicUninitializedLexical)
             {
+                if (!alloc().ensureBallast())
+                    return false;
+
                 replaceRedundantPhi(phi);
                 block->discardPhi(phi);
             } else {
                 if (!adjustPhiInputs(phi))
                     return false;
             }
         }
 
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -465,16 +465,23 @@ if test "$GNU_CC"; then
 
     AC_MSG_CHECKING([for -z text option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,-z,text"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
+    AC_MSG_CHECKING([for -z relro option to ld])
+    _SAVE_LDFLAGS=$LDFLAGS
+    LDFLAGS="$LDFLAGS -Wl,-z,relro"
+    AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
+                  AC_MSG_RESULT([no])
+                  LDFLAGS=$_SAVE_LDFLAGS)
+
     AC_MSG_CHECKING([for --build-id option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,--build-id"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     _DEFINES_CFLAGS='-include $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT'
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1703,24 +1703,16 @@ XPCConvert::JSStringWithSize2Native(void
         case nsXPTType::T_PSTRING_SIZE_IS:
         {
             if (s.isUndefined() || s.isNull()) {
                 if (0 != count) {
                     if (pErr)
                         *pErr = NS_ERROR_XPC_NOT_ENOUGH_CHARS_IN_STRING;
                     return false;
                 }
-                if (0 != count) {
-                    len = (count + 1) * sizeof(char);
-                    if (!(*((void**)d) = moz_xmalloc(len)))
-                        return false;
-                    return true;
-                }
-                // else ...
-
                 *((char**)d) = nullptr;
                 return true;
             }
 
             JSString* str = ToString(cx, s);
             if (!str) {
                 return false;
             }
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1526,16 +1526,35 @@ RestyleManager::ProcessRestyledFrames(ns
 
       if (!(frame->GetStateBits() & NS_FRAME_MAY_BE_TRANSFORMED)) {
         // Frame can not be transformed, and thus a change in transform will
         // have no effect and we should not use the
         // nsChangeHint_UpdatePostTransformOverflow hint.
         hint &= ~nsChangeHint_UpdatePostTransformOverflow;
       }
 
+      if (hint & nsChangeHint_AddOrRemoveTransform) {
+        // When dropping a running transform animation we will first add an
+        // nsChangeHint_UpdateTransformLayer hint as part of the animation-only
+        // restyle. During the subsequent regular restyle, if the animation was
+        // the only reason the element had any transform applied, we will add
+        // nsChangeHint_AddOrRemoveTransform as part of the regular restyle.
+        //
+        // With the Gecko backend, these two change hints are processed
+        // after each restyle but when using the Servo backend they accumulate
+        // and are processed together after we have already removed the
+        // transform as part of the regular restyle. Since we don't actually
+        // need the nsChangeHint_UpdateTransformLayer hint if we already have
+        // a nsChangeHint_AddOrRemoveTransform hint, and since we
+        // will fail an assertion in ApplyRenderingChangeToTree if we try
+        // specify nsChangeHint_UpdateTransformLayer but don't have any
+        // transform style, we just drop the unneeded hint here.
+        hint &= ~nsChangeHint_UpdateTransformLayer;
+      }
+
       if (hint & nsChangeHint_UpdateEffects) {
         for (nsIFrame* cont = frame; cont;
              cont = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(cont)) {
           nsSVGEffects::UpdateEffects(cont);
         }
       }
       if ((hint & nsChangeHint_InvalidateRenderingObservers) ||
           ((hint & nsChangeHint_UpdateOpacityLayer) &&
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -249,17 +249,17 @@ ServoRestyleManager::ClearRestyleStateFr
       if (n->IsElement()) {
         ClearRestyleStateFromSubtree(n->AsElement());
       }
     }
   }
 
   bool wasRestyled;
   Unused << Servo_TakeChangeHint(aElement,
-                                 TraversalRestyleBehavior::Normal,
+                                 ServoTraversalFlags::Empty,
                                  &wasRestyled);
   aElement->UnsetHasDirtyDescendantsForServo();
   aElement->UnsetHasAnimationOnlyDirtyDescendantsForServo();
   aElement->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES);
 }
 
 /**
  * This struct takes care of encapsulating some common state that text nodes may
@@ -487,51 +487,51 @@ UpdateFramePseudoElementStyles(nsIFrame*
   }
 
   UpdateBackdropIfNeeded(
     aFrame, aRestyleState.StyleSet(), aRestyleState.ChangeList());
 }
 
 static inline bool
 NeedsToTraverseElementChildren(const Element& aParent,
-                               TraversalRestyleBehavior aRestyleBehavior)
+                               ServoTraversalFlags aFlags)
 {
   if (aParent.HasAnimationOnlyDirtyDescendantsForServo()) {
     return true;
   }
 
-  if (aRestyleBehavior != TraversalRestyleBehavior::ForThrottledAnimationFlush) {
+  if (!(aFlags & ServoTraversalFlags::AnimationOnly)) {
     return aParent.HasDirtyDescendantsForServo() ||
            aParent.HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
   }
   return false;
 }
 
 bool
 ServoRestyleManager::ProcessPostTraversal(
   Element* aElement,
   ServoStyleContext* aParentContext,
   ServoRestyleState& aRestyleState,
-  TraversalRestyleBehavior aRestyleBehavior)
+  ServoTraversalFlags aFlags)
 {
   nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
 
   // NOTE(emilio): This is needed because for table frames the bit is set on the
   // table wrapper (which is the primary frame), not on the table itself.
   const bool isOutOfFlow =
     aElement->GetPrimaryFrame() &&
     aElement->GetPrimaryFrame()->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW);
 
   // Grab the change hint from Servo.
   // In case of flushing throttled animations, any restyle hints other than
   // animations are preserved since they are the hints which will be processed
   // in normal restyle later.
   bool wasRestyled;
   nsChangeHint changeHint = Servo_TakeChangeHint(aElement,
-                                                 aRestyleBehavior,
+                                                 aFlags,
                                                  &wasRestyled);
 
   // We should really fix the weird primary frame mapping for image maps
   // (bug 135040)...
   if (styleFrame && styleFrame->GetContent() != aElement) {
     MOZ_ASSERT(styleFrame->IsImageFrame());
     styleFrame = nullptr;
   }
@@ -599,17 +599,17 @@ ServoRestyleManager::ProcessPostTraversa
   // other elements without frames).
   ServoRestyleState& childrenRestyleState =
     thisFrameRestyleState ? *thisFrameRestyleState : aRestyleState;
 
   RefPtr<ServoStyleContext> newContext = nullptr;
   if (wasRestyled && oldStyleContext) {
     MOZ_ASSERT(styleFrame || displayContentsNode);
     newContext =
-      aRestyleState.StyleSet().ResolveServoStyle(aElement, aRestyleBehavior);
+      aRestyleState.StyleSet().ResolveServoStyle(aElement, aFlags);
     MOZ_ASSERT(oldStyleContext->ComputedData() != newContext->ComputedData());
 
     newContext->ResolveSameStructsAs(oldStyleContext);
 
     // We want to walk all the continuations here, even the ones with different
     // styles.  In practice, the only reason we get continuations with different
     // styles here is ::first-line (::first-letter never affects element
     // styles).  But in that case, newContext is the right context for the
@@ -653,38 +653,38 @@ ServoRestyleManager::ProcessPostTraversa
     // Since AddLayerChangesForAnimation checks if |styleFrame| has a transform
     // style or not, we need to call it *after* setting |newContext| to
     // |styleFrame| to ensure the animated transform has been removed first.
     AddLayerChangesForAnimation(
       styleFrame, aElement, aRestyleState.ChangeList());
   }
 
   const bool traverseElementChildren =
-    NeedsToTraverseElementChildren(*aElement, aRestyleBehavior);
+    NeedsToTraverseElementChildren(*aElement, aFlags);
   const bool descendantsNeedFrames =
     aElement->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
   const bool forThrottledAnimationFlush =
-    aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush;
+    !!(aFlags & ServoTraversalFlags::AnimationOnly);
   const bool traverseTextChildren =
     wasRestyled || (!forThrottledAnimationFlush && descendantsNeedFrames);
   bool recreatedAnyContext = wasRestyled;
   if (traverseElementChildren || traverseTextChildren) {
     ServoStyleContext* upToDateContext =
       wasRestyled ? newContext : oldStyleContext;
 
     StyleChildrenIterator it(aElement);
     TextPostTraversalState textState(*upToDateContext,
                                      displayContentsNode && wasRestyled,
                                      childrenRestyleState);
     for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
       if (traverseElementChildren && n->IsElement()) {
         recreatedAnyContext |= ProcessPostTraversal(n->AsElement(),
                                                     upToDateContext,
                                                     childrenRestyleState,
-                                                    aRestyleBehavior);
+                                                    aFlags);
       } else if (traverseTextChildren && n->IsNodeOfType(nsINode::eTEXT)) {
         recreatedAnyContext |= ProcessPostTraversalForText(n, textState);
       }
     }
   }
 
   // We want to update frame pseudo-element styles after we've traversed our
   // kids, because some of those updates (::first-line/::first-letter) need to
@@ -805,18 +805,17 @@ ServoRestyleManager::FrameForPseudoEleme
   }
 
   MOZ_CRASH("Unkown pseudo-element given to "
             "ServoRestyleManager::FrameForPseudoElement");
   return nullptr;
 }
 
 void
-ServoRestyleManager::DoProcessPendingRestyles(TraversalRestyleBehavior
-                                                aRestyleBehavior)
+ServoRestyleManager::DoProcessPendingRestyles(ServoTraversalFlags aFlags)
 {
   MOZ_ASSERT(PresContext()->Document(), "No document?  Pshaw!");
   MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(), "Missing a script blocker!");
   MOZ_ASSERT(!mInStyleRefresh, "Reentrant call?");
 
   if (MOZ_UNLIKELY(!PresContext()->PresShell()->DidInitialize())) {
     // PresShell::FlushPendingNotifications doesn't early-return in the case
     // where the PreShell hasn't yet been initialized (and therefore we haven't
@@ -828,55 +827,52 @@ ServoRestyleManager::DoProcessPendingRes
 
   // Create a AnimationsWithDestroyedFrame during restyling process to
   // stop animations and transitions on elements that have no frame at the end
   // of the restyling process.
   AnimationsWithDestroyedFrame animationsWithDestroyedFrame(this);
 
   ServoStyleSet* styleSet = StyleSet();
   nsIDocument* doc = PresContext()->Document();
-  bool forThrottledAnimationFlush =
-    aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush;
+  bool forThrottledAnimationFlush = !!(aFlags & ServoTraversalFlags::AnimationOnly);
 
   // Ensure the refresh driver is active during traversal to avoid mutating
   // mActiveTimer and mMostRecentRefresh time.
   PresContext()->RefreshDriver()->MostRecentRefresh();
 
 
   // Perform the Servo traversal, and the post-traversal if required. We do this
   // in a loop because certain rare paths in the frame constructor (like
   // uninstalling XBL bindings) can trigger additional style validations.
   mInStyleRefresh = true;
   if (mHaveNonAnimationRestyles && !forThrottledAnimationFlush) {
     ++mAnimationGeneration;
   }
 
-  TraversalRestyleBehavior restyleBehavior = mRestyleForCSSRuleChanges
-    ? TraversalRestyleBehavior::ForCSSRuleChanges
-    : TraversalRestyleBehavior::Normal;
-  while (forThrottledAnimationFlush
-          ? styleSet->StyleDocumentForThrottledAnimationFlush()
-          : styleSet->StyleDocument(restyleBehavior)) {
+  if (mRestyleForCSSRuleChanges) {
+    aFlags |= ServoTraversalFlags::ForCSSRuleChanges;
+  }
+
+  while (styleSet->StyleDocument(aFlags)) {
     if (!forThrottledAnimationFlush) {
       ClearSnapshots();
     }
 
     nsStyleChangeList currentChanges(StyleBackendType::Servo);
     bool anyStyleChanged = false;
 
     // Recreate style contexts, and queue up change hints (which also handle
     // lazy frame construction).
     {
-      AutoRestyleTimelineMarker marker(
-        mPresContext->GetDocShell(), forThrottledAnimationFlush);
+      AutoRestyleTimelineMarker marker(mPresContext->GetDocShell(), forThrottledAnimationFlush);
       DocumentStyleRootIterator iter(doc);
       while (Element* root = iter.GetNextStyleRoot()) {
         ServoRestyleState state(*styleSet, currentChanges);
         anyStyleChanged |=
-          ProcessPostTraversal(root, nullptr, state, aRestyleBehavior);
+          ProcessPostTraversal(root, nullptr, state, aFlags);
       }
     }
 
     // Process the change hints.
     //
     // Unfortunately, the frame constructor can generate new change hints while
     // processing existing ones. We redirect those into a secondary queue and
     // iterate until there's nothing left.
@@ -936,29 +932,29 @@ ServoRestyleManager::DoProcessPendingRes
   //       |mAnimationsWithDestroyedFrame| is still valid.
   MOZ_ASSERT(mAnimationsWithDestroyedFrame);
   mAnimationsWithDestroyedFrame->StopAnimationsForElementsWithoutFrames();
 }
 
 void
 ServoRestyleManager::ProcessPendingRestyles()
 {
-  DoProcessPendingRestyles(TraversalRestyleBehavior::Normal);
+  DoProcessPendingRestyles(ServoTraversalFlags::Empty);
 }
 
 void
 ServoRestyleManager::UpdateOnlyAnimationStyles()
 {
   // Bug 1365855: We also need to implement this for SMIL.
   bool doCSS = PresContext()->EffectCompositor()->HasPendingStyleUpdates();
   if (!doCSS) {
     return;
   }
 
-  DoProcessPendingRestyles(TraversalRestyleBehavior::ForThrottledAnimationFlush);
+  DoProcessPendingRestyles(ServoTraversalFlags::AnimationOnly);
 }
 
 void
 ServoRestyleManager::ContentStateChanged(nsIContent* aContent,
                                          EventStates aChangedBits)
 {
   MOZ_ASSERT(!mInStyleRefresh);
 
--- a/layout/base/ServoRestyleManager.h
+++ b/layout/base/ServoRestyleManager.h
@@ -118,16 +118,29 @@ public:
                         nsChangeHint aMinChangeHint);
   void PostRestyleEventForCSSRuleChanges();
   void RebuildAllStyleData(nsChangeHint aExtraHint,
                            nsRestyleHint aRestyleHint);
   void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
                                     nsRestyleHint aRestyleHint);
   void ProcessPendingRestyles();
 
+  /**
+   * Performs a Servo animation-only traversal to compute style for all nodes
+   * with the animation-only dirty bit in the document.
+   *
+   * This processes just the traversal for animation-only restyles and skips the
+   * normal traversal for other restyles unrelated to animations.
+   * This is used to bring throttled animations up-to-date such as when we need
+   * to get correct position for transform animations that are throttled because
+   * they are running on the compositor.
+   *
+   * This will traverse all of the document's style roots (that is, its document
+   * element, and the roots of the document-level native anonymous content).
+   */
   void UpdateOnlyAnimationStyles();
 
   void ContentStateChanged(nsIContent* aContent, EventStates aStateMask);
   void AttributeWillChange(dom::Element* aElement,
                            int32_t aNameSpaceID,
                            nsIAtom* aAttribute,
                            int32_t aModType,
                            const nsAttrValue* aNewValue);
@@ -186,17 +199,17 @@ private:
    * Returns whether any style did actually change. There may be cases where we
    * didn't need to change any style after all, for example, when a content
    * attribute changes that happens not to have any effect on the style of that
    * element or any descendant or sibling.
    */
   bool ProcessPostTraversal(Element* aElement,
                             ServoStyleContext* aParentContext,
                             ServoRestyleState& aRestyleState,
-                            TraversalRestyleBehavior aRestyleBehavior);
+                            ServoTraversalFlags aFlags);
 
   struct TextPostTraversalState;
   bool ProcessPostTraversalForText(nsIContent* aTextNode,
                                    TextPostTraversalState& aState);
 
   inline ServoStyleSet* StyleSet() const
   {
     MOZ_ASSERT(PresContext()->StyleSet()->IsServo(),
@@ -207,17 +220,17 @@ private:
 
   const SnapshotTable& Snapshots() const { return mSnapshots; }
   void ClearSnapshots();
   ServoElementSnapshot& SnapshotFor(mozilla::dom::Element* aElement);
   void TakeSnapshotForAttributeChange(mozilla::dom::Element* aElement,
                                       int32_t aNameSpaceID,
                                       nsIAtom* aAttribute);
 
-  void DoProcessPendingRestyles(TraversalRestyleBehavior aRestyleBehavior);
+  void DoProcessPendingRestyles(ServoTraversalFlags aFlags);
 
   // We use a separate data structure from nsStyleChangeList because we need a
   // frame to create nsStyleChangeList entries, and the primary frame may not be
   // attached yet.
   struct ReentrantChange {
     nsCOMPtr<nsIContent> mContent;
     nsChangeHint mHint;
   };
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -36,17 +36,17 @@ load 243519-1.html
 load 244490-1.html
 load 254367-1.html
 load 263359-1.html
 load 265027-1.html
 load 265736-1.html
 load 265736-2.html
 load 265899-1.html
 load 265973-1.html
-asserts(6-12) load 265986-1.html # Bug 512405
+asserts-if(!stylo,6-12) load 265986-1.html # Bug 512405 , bug 718883
 load 265999-1.html
 load 266222-1.html
 asserts(1-7) load 266360-1.html # bug 576358
 load 266445-1.html
 asserts(2) load 266445-2.html
 load 268157-1.html
 load 269566-1.html
 load 272647-1.html
@@ -147,17 +147,17 @@ load 372550-1.html
 load 372576.xul
 load 373628-1.html
 load 373919.xhtml
 load 374193-1.xhtml
 load 374297-1.html
 load 374297-2.html
 load 376223-1.xhtml
 load 378325-1.html
-load 378682.html
+skip-if(stylo&&isDebugBuild&&winWidget) load 378682.html # Bug 1383845
 load 379105-1.xhtml
 load 379419-1.xhtml
 load 379768-1.html
 load 379799-1.html
 load 379920-1.svg
 load 379920-2.svg
 load 379975.html
 load 380096-1.html
@@ -406,17 +406,17 @@ load 695964-1.svg
 load 698335.html
 needs-focus pref(accessibility.browsewithcaret,true) load 699353-1.html
 load 701504.html
 load 707098.html
 load 709536-1.xhtml
 load 722137.html
 load 725535.html # bug 1323652
 load 727601.html # bug 1323652
-skip-if(Android) asserts(0-2) pref(dom.disable_open_during_load,false) load 735943.html # the assertion is bug 735966, for android bug 760271
+skip-if(Android) skip-if(stylo&&isDebugBuild&&winWidget) asserts(0-2) pref(dom.disable_open_during_load,false) load 735943.html # the assertion is bug 735966, for android bug 760271, for Stylo bug 1383845
 asserts(0-2) load 736389-1.xhtml # sometimes the above assertions are delayed and is reported on this test instead
 load 736924-1.html
 load 749816-1.html
 load 763223-1.html
 test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.lineThreshold,100) load 763702.xhtml
 load 767593-1.html
 load 767593-2.html
 load 770381-1.html
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2517,17 +2517,17 @@ nsCSSFrameConstructor::ConstructDocEleme
   // siblings.
   aDocElement->UnsetRestyleFlagsIfGecko();
 
   // --------- CREATE AREA OR BOX FRAME -------
   if (ServoStyleSet* set = mPresShell->StyleSet()->GetAsServo()) {
     // NOTE(emilio): If the root has a non-null binding, we'll stop at the
     // document element and won't process any children, loading the bindings (or
     // failing to do so) will take care of the rest.
-    set->StyleDocument(TraversalRestyleBehavior::Normal);
+    set->StyleDocument(ServoTraversalFlags::Empty);
   }
 
   // FIXME: Should this use ResolveStyleContext?  (The calls in this
   // function are the only case in nsCSSFrameConstructor where we don't
   // do so for the construction of a style context for an element.)
   RefPtr<nsStyleContext> styleContext =
     mPresShell->StyleSet()->ResolveStyleFor(aDocElement,
                                             nullptr,
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2439,17 +2439,17 @@ static void ConstrainToCoordValues(float
   // We must also clamp aSize to {0,nscoord_MAX} since nsRect::Width/Height()
   // can't return a value greater than nscoord_MAX. If aSize is greater than
   // nscoord_MAX then we reduce it to nscoord_MAX while keeping the rect
   // centered:
   if (aSize > nscoord_MAX) {
     float excess = aSize - nscoord_MAX;
     excess /= 2;
     aStart += excess;
-    aSize = nscoord_MAX;
+    aSize = (float)nscoord_MAX;
   }
 }
 
 /**
  * Given a gfxFloat, constrains its value to be between nscoord_MIN and nscoord_MAX.
  *
  * @param aVal The value to constrain (in/out)
  */
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -20,17 +20,17 @@ load 309322-1.html
 load 309322-2.html
 load 309322-3.html
 load 309322-4.html
 load 310556-1.xhtml
 load 321224.xul
 load 322780-1.xul
 load 323381-1.html
 load 323381-2.html
-asserts-if(gtkWidget,1) asserts-if(Android&&asyncPan,1) asserts-if(stylo,1) load 323386-1.html # Bug 718883
+asserts-if(gtkWidget,1) asserts-if(Android&&asyncPan,1) asserts-if(stylo&&!(cocoaWidget&&isDebugBuild),1) load 323386-1.html # Bug 718883
 load 323389-1.html
 load 323389-2.html
 load 323493-1.html
 load 323495-1.html
 load 324318-1.html
 load 328946-1.html
 load 331284-1.xhtml
 load 331292.html
@@ -136,17 +136,17 @@ load 387058-1.html
 load 387058-2.html
 load 387088-1.html
 load 387209-1.html
 load 387213-1.html
 load 387215-1.xhtml
 load 387219-1.xhtml
 load 387233-1.html
 load 387233-2.html
-load 387282-1.html
+asserts-if(stylo,2) load 387282-1.html
 load 388175-1.html
 load 388367-1.html
 load 388709-1.html
 load 389635-1.html
 load 390050-1.html
 load 390050-2.html
 load 390050-3.html
 load 390762-1.html
@@ -394,18 +394,18 @@ load 533379-1.html
 load 533379-2.html
 load 534082-1.html
 load 534366-1.html
 load 534366-2.html
 load 536692-1.xhtml
 load 537645.xhtml
 load 541277-1.html
 load 541277-2.html
-load 541714-1.html
-load 541714-2.html
+asserts-if(stylo,2) load 541714-1.html # bug 634161
+asserts-if(stylo,3) load 541714-2.html # bug 634161
 load 542136-1.html
 load 545571-1.html
 load 547338.xul
 load 547843-1.xhtml
 load 551635-1.html
 load 553504-1.xhtml
 load 564368-1.xhtml
 load 564968.xhtml
@@ -553,17 +553,17 @@ load 885009-1.html
 load 893496-1.html
 load 893523.html
 asserts(0-3) load 898871.html # bug 479160 - mostly OSX, sometimes Windows
 asserts(0-3) load 914501.html # bug 1144852 - all platforms
 load 914891.html
 load 915475.xhtml
 load 927558.html
 load 943509-1.html
-asserts(2-8) load 944909-1.html
+asserts-if(stylo,2-8) load 944909-1.html
 load 946167-1.html
 load 947158.html
 load 949932.html
 asserts-if(Android,0-1) load 964078.html # bug 989718
 load 970710.html
 load 973701-1.xhtml
 load 973701-2.xhtml
 load 986899.html
@@ -627,17 +627,17 @@ load outline-on-frameset.xhtml
 load summary-position-out-of-flow.html
 load text-overflow-bug666751-1.html
 load text-overflow-bug666751-2.html
 load text-overflow-bug670564.xhtml
 load text-overflow-bug671796.xhtml
 load text-overflow-bug713610.html
 load text-overflow-form-elements.html
 load text-overflow-iframe.html
-asserts-if(Android,2-4) asserts-if(!Android,4) load 1225005.html # bug 682647 and bug 448083
+asserts(1-4) load 1225005.html # bug 682647 and bug 448083
 load 1233191.html
 asserts-if(stylo,0-15) load 1271765.html # bug 1324684
 asserts(2) load 1272983-1.html # bug 586628
 asserts(2) load 1272983-2.html # bug 586628
 load 1275059.html
 load 1278007.html
 load 1278080.html
 load 1279814.html
--- a/layout/reftests/bidi/dirAuto/reftest.list
+++ b/layout/reftests/bidi/dirAuto/reftest.list
@@ -1,119 +1,119 @@
 == bdi-auto-dir-default.html bdi-auto-dir-default-ref.html
 == dir_auto-set-contained-dir-L.html dir_auto-contained-dir-L-ref.html
 == dir_auto-set-contained-dir-R.html dir_auto-contained-dir-R-ref.html
 == dir_auto-set-contained-invalid-dir-L.html dir_auto-contained-dir-L-ref.html
 == dir_auto-set-contained-invalid-dir-R.html dir_auto-contained-dir-R-ref.html
 == dir_auto-unset-contained-dir-L.html dir_auto-unset-contained-dir-L-ref.html
 == dir_auto-unset-contained-dir-R.html dir_auto-unset-contained-dir-R-ref.html
-== dynamicDirAuto-setLTR-Auto1.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-Auto2.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-Auto3.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-Auto4.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-Auto5.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-Auto6.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR1.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR2.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR3.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR4.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR5.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR6.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR7.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-LTR8.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-RTL1.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL2.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL3.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL4.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL5.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL6.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL7.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-RTL8.html dynamicDirAuto-refLTR-RTL.html
-== dynamicDirAuto-setLTR-NoDir1.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir2.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir3.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir4.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir5.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir6.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir7.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-NoDir8.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir1.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir2.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir3.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir4.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir5.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir6.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-setRTL-Auto1.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-Auto2.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-Auto3.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-Auto4.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-Auto5.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-Auto6.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-LTR1.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR2.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR3.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR4.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR5.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR6.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR7.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-LTR8.html dynamicDirAuto-refRTL-LTR.html
-== dynamicDirAuto-setRTL-RTL1.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL2.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL3.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL4.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL5.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL6.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL7.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-RTL8.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-setRTL-NoDir1.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir2.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir3.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir4.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir5.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir6.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir7.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-NoDir8.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir1.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir2.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir3.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir4.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir5.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir6.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir7.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-setRTL-InvalidDir8.html dynamicDirAuto-refRTL-NoDir.html
-== dynamicDirAuto-addLTR-Auto.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-addRTL-Auto.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-ChangeText-LTR1.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR2.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR3.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR4.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR5.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR6.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR7.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR8.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR9.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-LTR10.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-ChangeText-RTL1.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-ChangeText-RTL2.html dynamicDirAuto-refRTL-RTL.html
-fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL3.html dynamicDirAuto-refRTL-RTL.html
-fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL4.html dynamicDirAuto-refRTL-RTL.html
-fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL5.html dynamicDirAuto-refRTL-RTL.html
-fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL6.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-ChangeText-RTL7.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-ChangeText-RTL8.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-ChangeText-RTL9.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-ChangeText-RTL10.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-DeleteText-LTR1.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-DeleteText-LTR2.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-DeleteText-LTR3.html dynamicDirAuto-refLTR-LTR.html
-== dynamicDirAuto-DeleteText-RTL1.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-DeleteText-RTL2.html dynamicDirAuto-refRTL-RTL.html
-== dynamicDirAuto-DeleteText-RTL3.html dynamicDirAuto-refRTL-RTL.html
-== 839886-1.html 839886-1-ref.html
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-Auto1.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-Auto2.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-Auto3.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-Auto4.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-Auto5.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-Auto6.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR1.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR2.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR3.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR4.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR5.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR6.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR7.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-LTR8.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL1.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL2.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL3.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL4.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL5.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL6.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL7.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-RTL8.html dynamicDirAuto-refLTR-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir1.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir2.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir3.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir4.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir5.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir6.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir7.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-NoDir8.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir1.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir2.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir3.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir4.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir5.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir6.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setLTR-InvalidDir7.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-Auto1.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-Auto2.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-Auto3.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-Auto4.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-Auto5.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-Auto6.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR1.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR2.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR3.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR4.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR5.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR6.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR7.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-LTR8.html dynamicDirAuto-refRTL-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL1.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL2.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL3.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL4.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL5.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL6.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL7.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-RTL8.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir1.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir2.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir3.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir4.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir5.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir6.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir7.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-NoDir8.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir1.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir2.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir3.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir4.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir5.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir6.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir7.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-setRTL-InvalidDir8.html dynamicDirAuto-refRTL-NoDir.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-addLTR-Auto.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-addRTL-Auto.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR1.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR2.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR3.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR4.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR5.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR6.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR7.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR8.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR9.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-LTR10.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-RTL1.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-RTL2.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL3.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL4.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL5.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated&&!azureSkia,30,1) == dynamicDirAuto-ChangeText-RTL6.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-RTL7.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-RTL8.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-RTL9.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-ChangeText-RTL10.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-DeleteText-LTR1.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-DeleteText-LTR2.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-DeleteText-LTR3.html dynamicDirAuto-refLTR-LTR.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-DeleteText-RTL1.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-DeleteText-RTL2.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == dynamicDirAuto-DeleteText-RTL3.html dynamicDirAuto-refRTL-RTL.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == 839886-1.html 839886-1-ref.html # Bug 1383869
 == 859093-1.html 859093-1-ref.html
 == 889742-1.html 889742-1-ref.html
 == 1103348-1.html 1103348-1-ref.html
-== 1169267-delete-add-1a.html 1169267-delete-add-1-ref.html
-== 1169267-delete-add-1b.html 1169267-delete-add-1-ref.html
-== 1169267-delete-add-2a.html 1169267-delete-add-2-ref.html
-== 1169267-delete-add-2b.html 1169267-delete-add-2-ref.html
+fails-if(cocoaWidget&&styloVsGecko) == 1169267-delete-add-1a.html 1169267-delete-add-1-ref.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == 1169267-delete-add-1b.html 1169267-delete-add-1-ref.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == 1169267-delete-add-2a.html 1169267-delete-add-2-ref.html # Bug 1383869
+fails-if(cocoaWidget&&styloVsGecko) == 1169267-delete-add-2b.html 1169267-delete-add-2-ref.html # Bug 1383869
--- a/layout/reftests/border-image/reftest.list
+++ b/layout/reftests/border-image/reftest.list
@@ -31,17 +31,17 @@ fails-if(Android) fails-if(usesRepeatRes
 == border-image-width-1b.html border-image-width-1-ref.html
 == border-image-width-1c.html border-image-width-1-ref.html
 == border-image-width-large.html border-image-width-large-ref.html
 == border-image-outset-1a.html border-image-outset-1-ref.html
 == border-image-outset-1b.html border-image-outset-1-ref.html
 == border-image-outset-1c.html border-image-outset-1-ref.html
 == border-image-nofill-1.html border-image-nofill-1-ref.html
 == border-image-outset-resize-1.html border-image-outset-resize-1-ref.html
-fuzzy-if(asyncPan&&!layersGPUAccelerated,140,514) == border-image-outset-move-1.html border-image-outset-move-1-ref.html
+fuzzy-if(asyncPan&&!layersGPUAccelerated,140,514) fuzzy-if(winWidget&&stylo,144,448) == border-image-outset-move-1.html border-image-outset-move-1-ref.html
 == border-image-style-none.html border-image-style-none-ref.html
 == border-image-style-none-length.html border-image-style-none-length-ref.html
 == border-image-style-none-auto.html border-image-style-none-auto-ref.html
 
 # border images with gradients
 == border-image-linear-gradient.html border-image-linear-gradient-ref.html
 fuzzy(1,98) fuzzy-if(skiaContent,1,350) == border-image-linear-gradient-slice-1.html border-image-linear-gradient-slice-1-ref.html
 fuzzy(1,149) fuzzy-if(OSX,1,10595) == border-image-linear-gradient-slice-2.html border-image-linear-gradient-slice-2-ref.html
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -47,17 +47,17 @@ fuzzy-if(skiaContent,17,62) == clipping-
 fuzzy-if(true,1,20) fuzzy-if(d2d,64,196) fuzzy-if(cocoaWidget,1,180) fuzzy-if(Android,140,237) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
 fuzzy-if(Android,5,54) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,10) fuzzy-if(skiaContent,1,172) == clipping-4-image.html clipping-4-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,10) fuzzy-if(skiaContent,1,77) == clipping-4-overflow-hidden.html clipping-4-ref.html
 == clipping-5-canvas.html clipping-5-refc.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) == clipping-5-image.html clipping-5-refi.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(skiaContent,1,77) == clipping-5-overflow-hidden.html clipping-5-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,5,21) fuzzy-if(skiaContent,1,97) == clipping-5-refi.html clipping-5-ref.html
 fuzzy-if(true,1,7) fuzzy-if(d2d,48,94) fuzzy-if(cocoaWidget,1,99) fuzzy-if(Android,99,115) fuzzy-if(skiaContent,1,77) == clipping-5-refc.html clipping-5-ref.html # bug 732535
-fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,7,58) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(webrender,7-7,62-62) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical
+fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,7,58) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(webrender,7-7,62-62) fuzzy-if(winWidget&&stylo,137,226-319) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical
 fuzzy-if(true,2,29) fuzzy-if(d2d,46,50) fuzzy-if(Android,255,586) fuzzy-if(skiaContent,28,96) == clipping-7.html clipping-7-ref.html # ColorLayer and MaskLayer with transforms that aren't identical. Reference image rendered without using layers (which causes fuzzy failures).
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) == clipping-and-zindex-1.html clipping-and-zindex-1-ref.html
 fuzzy-if(cocoaWidget,1,4) fuzzy-if(d3d11&&advancedLayers,30,3) == intersecting-clipping-1-canvas.html intersecting-clipping-1-refc.html
 == intersecting-clipping-1-image.html intersecting-clipping-1-refi.html
 == intersecting-clipping-1-overflow-hidden.html intersecting-clipping-1-ref.html
 fuzzy-if(Android,5,105) fuzzy-if(d2d,1,20) fuzzy-if(skiaContent,1,300) == intersecting-clipping-1-refi.html intersecting-clipping-1-ref.html
 fuzzy-if(true,1,33) fuzzy-if(d2d,48,350) fuzzy-if(cocoaWidget,1,332) fuzzy-if(Android,124,440) fuzzy-if(skiaContent,1,135) fuzzy-if(d3d11&&advancedLayers,48,353) == intersecting-clipping-1-refc.html intersecting-clipping-1-ref.html # bug 732535
 
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -322,17 +322,17 @@ random-if(d2d) == 299837-3.xul 299837-3-
 == 300691-1b.html 300691-1-ref.html
 == 300691-1c.html 300691-1-ref.html
 == 300691-1d.html 300691-1-ref.html
 == 300691-1e.html 300691-1-ref.html
 == 300691-1f.html 300691-1-ref.html
 == 301726-1.html 301726-1-ref.html
 fails-if(Android) != 301726-2.html 301726-2-ref.html
 == 302379.html 302379-ref.html
-== 306630-1.html 306630-1-ref.html
+skip-if((stylo||styloVsGecko)&&isDebugBuild&&winWidget) == 306630-1.html 306630-1-ref.html # Bug 1383845
 == 306660-1.html 306660-1-ref.html
 == 306660-2.html 306660-2-ref.html
 == 306660-3.html 306660-3-ref.html
 == 307076-1.html 307076-1-ref.html
 == 307102-1.html 307102-1-ref.html
 == 307102-2.html 307102-2-ref.html
 == 307102-3.html 307102-3-ref.html
 == 307102-4.html 307102-4-ref.html
@@ -831,17 +831,17 @@ fuzzy-if(skiaContent,2,21) == 398682-1.h
 == 399209-2.html 399209-2-ref.html
 == 399258-1.html 399258-1-ref.html
 == 399384-1.html 399384-1-ref.html
 random-if(gtkWidget) == 399636-standards-css.html 399636-standards-ref.html # bug 429022
 random-if(gtkWidget) == 399636-standards-html.html 399636-standards-ref.html # bug 429022
 random-if(gtkWidget) == 399636-quirks-css.html 399636-quirks-ref.html # bug 429022
 # We can't rely on this test working on platforms other than Windows and
 # Mac because they need not have a font called "Symbol".
-fails-if(winWidget) fails-if(cocoaWidget) random-if(!cocoaWidget&&!winWidget) != 399636-quirks-html.html 399636-quirks-ref.html # windows failure bug 429017, mac failure bug 429019
+fails-if(winWidget&&!styloVsGecko) fails-if(cocoaWidget&&!styloVsGecko) random-if(!cocoaWidget&&!winWidget) != 399636-quirks-html.html 399636-quirks-ref.html # windows failure bug 429017, mac failure bug 429019
 == 400081-1.html about:blank
 == 400171-1a.html 400171-1-ref.html
 == 400171-1b.html 400171-1-ref.html
 == 400171-1c.html 400171-1-ref.html
 == 400171-2a.html 400171-2-ref.html
 == 400171-2b.html 400171-2-ref.html
 == 400171-2c.html 400171-2-ref.html
 == 400421-1.html 400421-1-ref.html
@@ -1169,38 +1169,38 @@ fails-if(Android) fails-if(usesRepeatRes
 fails-if(Android) fails-if(usesRepeatResampling) == 446100-1c.html about:blank
 fails-if(usesRepeatResampling) == 446100-1d.html about:blank
 fails-if(usesRepeatResampling) == 446100-1e.html about:blank
 == 446100-1f.html about:blank
 fails-if(usesRepeatResampling) fails-if(Android) == 446100-1g.html about:blank
 == 446100-1h.html about:blank
 == 447749-1.html 447749-1-ref.html
 fuzzy(127,2) == 448193.html 448193-ref.html
-fails-if(styloVsGecko) != 449149-1a.html about:blank
-fails-if(styloVsGecko) != 449149-1b.html about:blank
+fails-if((cocoaWidget||gtkWidget)&&styloVsGecko) != 449149-1a.html about:blank
+fails-if((cocoaWidget||gtkWidget)&&styloVsGecko) != 449149-1b.html about:blank
 # Retry the above with XBL scopes
-test-pref(dom.use_xbl_scopes_for_remote_xul,true) fails-if(styloVsGecko) != 449149-1a.html about:blank
-test-pref(dom.use_xbl_scopes_for_remote_xul,true) fails-if(styloVsGecko) != 449149-1b.html about:blank
+test-pref(dom.use_xbl_scopes_for_remote_xul,true) fails-if((cocoaWidget||gtkWidget)&&styloVsGecko) != 449149-1a.html about:blank
+test-pref(dom.use_xbl_scopes_for_remote_xul,true) fails-if((cocoaWidget||gtkWidget)&&styloVsGecko) != 449149-1b.html about:blank
 == 449149-2.html 449149-2-ref.html
 == 449171-1.html 449171-ref.html
 == 449362-1.html 449362-1-ref.html
 == 449519-1.html 449519-1-ref.html
 == 450670-1.html 450670-1-ref.html
 == 451168-1.html 451168-1-ref.html
 == 451876-1.html 451876-1-ref.html
 == 451876-2.html 451876-2-ref.html
 == 452915-1.html 452915-1-ref.html
 == 452964-1.html 452964-1-ref.html
 == 454361.html about:blank
 == 455105-1.html 455105-ref.html
 == 455105-2.html 455105-ref.html
 == 455171-5.html 455171-5-ref.html
 == 455280-1.xhtml 455280-1-ref.xhtml
 == 455826-1.html 455826-1-ref.html
-fails-if(cocoaWidget) fails-if(Android) == 456147.xul 456147-ref.html # bug 458047
+fails-if(cocoaWidget&&!styloVsGecko) fails-if(Android) == 456147.xul 456147-ref.html # bug 458047
 fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) == 456219-1a.html 456219-1-ref.html # bug 1128229
 fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) fuzzy-if(webrender,24-24,155-155) == 456219-1b.html 456219-1-ref.html # bug 1128229
 fuzzy-if(Android,11,41) fuzzy-if(winWidget||gtkWidget,4,6) fuzzy-if(d2d,4,69) fuzzy-if(skiaContent,42,150) fuzzy-if(webrender,24-24,155-155) == 456219-1c.html 456219-1-ref.html # bug 1128229
 fuzzy-if(skiaContent,1,45) == 456219-2.html 456219-2-ref.html
 == 456330-1.gif 456330-1-ref.png
 == 456484-1.html 456484-1-ref.html
 == 457398-1.html 457398-1-ref.html
 == 457398-2.html 457398-2-ref.html
@@ -1575,17 +1575,17 @@ fails-if(Android) random-if(layersGPUAcc
 skip-if(Android) == 580160-1.html 580160-1-ref.html # bug 920927 for Android; issues without the test-plugin
 fuzzy-if(asyncPan&&!layersGPUAccelerated,255,141) HTTP(..) == 580863-1.html 580863-1-ref.html
 fails-if(Android) random-if(layersGPUAccelerated) fuzzy-if(skiaContent,1,6436) == 581317-1.html 581317-1-ref.html
 == 581579-1.html 581579-1-ref.html
 == 582037-1a.html 582037-1-ref.html
 == 582037-1b.html 582037-1-ref.html
 fuzzy-if(Android,3,256) == 582037-2a.html 582037-2-ref.html
 fuzzy-if(Android,3,256) == 582037-2b.html 582037-2-ref.html
-asserts(1-2) asserts-if(styloVsGecko,4) == 582146-1.html about:blank
+asserts(1-2) asserts-if(styloVsGecko,3) == 582146-1.html about:blank
 == 582476-1.svg 582476-1-ref.svg
 == 584400-dash-length.svg 584400-dash-length-ref.svg
 == 584699-1.html 584699-1-ref.html
 fuzzy-if(Android,2,48) == 585598-2.xhtml 585598-2-ref.xhtml
 == 586400-1.html 586400-1-ref.html
 fuzzy-if(d2d,52,1051) == 586683-1.html 586683-1-ref.html
 == 589615-1a.xhtml 589615-1-ref.html
 == 589615-1b.html 589615-1-ref.html
@@ -1983,17 +1983,17 @@ random-if(Android) fuzzy-if(skiaContent,
 fuzzy-if(Android,27,874) fuzzy-if(gtkWidget,14,29) == 1313772.xhtml 1313772-ref.xhtml # Bug 1128229
 fuzzy(2,320000) == 1315113-1.html 1315113-1-ref.html
 fuzzy(2,20000) == 1315113-2.html 1315113-2-ref.html
 == 1315632-1.html 1315632-1-ref.html
 fuzzy(2,40000) fuzzy-if(webrender,1-2,349-349) == 1316719-1a.html 1316719-1-ref.html
 fuzzy(2,40000) fuzzy-if(webrender,1-2,349-349) == 1316719-1b.html 1316719-1-ref.html
 fuzzy(2,40000) fuzzy-if(webrender,1-1,323-323) == 1316719-1c.html 1316719-1-ref.html
 skip-if(Android) != 1318769-1.html 1318769-1-ref.html
-fails-if(styloVsGecko) == 1322512-1.html 1322512-1-ref.html
+fails-if((cocoaWidget||gtkWidget)&&styloVsGecko) == 1322512-1.html 1322512-1-ref.html
 == 1330051.svg 1330051-ref.svg
 == 1348481-1.html 1348481-ref.html
 == 1348481-2.html 1348481-ref.html
 == 1352464-1.html 1352464-1-ref.html
 == 1358375-1.html 1358375-ref.html
 == 1358375-2.html 1358375-ref.html
 == 1358375-3.html 1358375-ref.html
 == 1364280-1.html 1364280-1-ref.html
--- a/layout/reftests/canvas/reftest.list
+++ b/layout/reftests/canvas/reftest.list
@@ -23,17 +23,17 @@ random-if(cocoaWidget) == subpixel-1.htm
 != text-rtl-left.html text-rtl-right.html
 
 == text-ltr-left.html text-rtl-left.html
 
 == text-ltr-alignment-test.html text-ltr-alignment-ref.html
 == text-rtl-alignment-test.html text-rtl-alignment-ref.html
 
 == text-horzline-with-bottom.html text-horzline.html
-fails-if(azureSkia&&OSX) == text-horzline-with-top.html text-horzline.html
+fails-if(azureSkia&&OSX&&!styloVsGecko) == text-horzline-with-top.html text-horzline.html
 
 != text-big-stroke.html text-blank.html
 != text-big-stroke.html text-big-fill.html
 
 == text-context-state-test.html text-context-state-ref.html
 == text-font-inherit.html text-big-fill.html
 == text-space-replace-test.html text-space-replace-ref.html
 
--- a/layout/reftests/css-ruby/reftest.list
+++ b/layout/reftests/css-ruby/reftest.list
@@ -19,17 +19,17 @@
 test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == inflated-ruby-1.html inflated-ruby-1-ref.html
 == intra-level-whitespace-1.html intra-level-whitespace-1-ref.html
 == intra-level-whitespace-2.html intra-level-whitespace-2-ref.html
 == intra-level-whitespace-3.html intra-level-whitespace-3-ref.html
 == intrinsic-isize-1.html intrinsic-isize-1-ref.html
 == intrinsic-isize-2.html intrinsic-isize-2-ref.html
 == justification-1.html justification-1-ref.html
 == justification-2.html justification-2-ref.html
-fuzzy-if(winWidget,255,792) == lang-specific-style-1.html lang-specific-style-1-ref.html # bug 1134947
+fails-if((stylo||styloVsGecko)&&cocoaWidget) fuzzy-if(winWidget,255,792) == lang-specific-style-1.html lang-specific-style-1-ref.html # bug 1134947
 == line-breaking-1.html line-breaking-1-ref.html
 == line-breaking-2.html line-breaking-2-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),3,2) == line-break-suppression-1.html line-break-suppression-1-ref.html
 fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),3,2) == line-break-suppression-2.html line-break-suppression-2-ref.html
 == line-break-suppression-3.html line-break-suppression-3-ref.html
 == line-break-suppression-4.html line-break-suppression-4-ref.html
 == line-break-suppression-5.html line-break-suppression-5-ref.html
 == line-height-1.html line-height-1-ref.html
--- a/layout/reftests/first-letter/reftest.list
+++ b/layout/reftests/first-letter/reftest.list
@@ -55,17 +55,17 @@ HTTP(..) == 329069-5.html 329069-5-ref.h
 == 429968-1b.html 429968-1-ref.html
 == 429968-2a.html 429968-2-ref.html
 == 429968-2b.html 429968-2-ref.html
 == 429968-2c.html 429968-2-ref.html
 == 441418-1.html 441418-1-ref.html
 == 469227-1.html 469227-1-ref.html
 == 484400-1.html 484400-1-ref.html
 == 594303-1.html 594303-1-ref.html
-fails-if(winWidget||cocoaWidget) == 617869-1.html 617869-1-ref.html
+fails-if((winWidget||cocoaWidget)&&!styloVsGecko) == 617869-1.html 617869-1-ref.html
 == 723509-1.html 723509-1-ref.html
 == 922550-1.html 922550-1-ref.html
 == 958249.html 958249-ref.html
 == font-text-styles.html font-text-styles-ref.html
 random-if(gtkWidget) random-if(winWidget&&!d2d) == font-text-styles-floater.html font-text-styles-floater-ref.html # bug 992846
 == inline-height-empty.html inline-height-empty-ref.html
 HTTP(..) == indic-clusters-1.html indic-clusters-1-ref.html
 == overflow-float-nooverflow.html overflow-float-nooverflow-ref.html
--- a/layout/reftests/flexbox/reftest.list
+++ b/layout/reftests/flexbox/reftest.list
@@ -38,21 +38,21 @@ fuzzy-if(cocoaWidget,1,2) random-if(winW
 == flexbox-dyn-changePadding-1a.xhtml flexbox-dyn-changePadding-1-ref.xhtml
 == flexbox-dyn-changePadding-1b.xhtml flexbox-dyn-changePadding-1-ref.xhtml
 
 # Tests for dynamic insertions of content into a flex container
 # (with existing [div | span | text] inside the flexbox, and new content
 # inserted adjacent to that existing content.)
 fuzzy-if(skiaContent,3,10) == flexbox-dyn-insertAroundDiv-1.xhtml flexbox-dyn-insertAroundDiv-1-ref.xhtml
 == flexbox-dyn-insertAroundDiv-2.xhtml flexbox-dyn-insertAroundDiv-2-ref.xhtml
-fuzzy-if(skiaContent,3,10) fails-if(styloVsGecko) == flexbox-dyn-insertAroundDiv-3.xhtml flexbox-dyn-insertAroundDiv-3-ref.xhtml
+fuzzy-if(skiaContent,3,10) fails-if(gtkWidget&&styloVsGecko) == flexbox-dyn-insertAroundDiv-3.xhtml flexbox-dyn-insertAroundDiv-3-ref.xhtml
 
 fuzzy-if(skiaContent,3,10) == flexbox-dyn-insertAroundSpan-1.xhtml flexbox-dyn-insertAroundDiv-1-ref.xhtml
 == flexbox-dyn-insertAroundSpan-2.xhtml flexbox-dyn-insertAroundDiv-2-ref.xhtml
-fuzzy-if(skiaContent,3,10) fails-if(styloVsGecko) == flexbox-dyn-insertAroundSpan-3.xhtml flexbox-dyn-insertAroundDiv-3-ref.xhtml
+fuzzy-if(skiaContent,3,10) fails-if(gtkWidget&&styloVsGecko) == flexbox-dyn-insertAroundSpan-3.xhtml flexbox-dyn-insertAroundDiv-3-ref.xhtml
 
 == flexbox-dyn-insertAroundText-1.xhtml flexbox-dyn-insertAroundText-1-ref.xhtml
 == flexbox-dyn-insertAroundText-2.xhtml flexbox-dyn-insertAroundText-2-ref.xhtml
 == flexbox-dyn-insertAroundText-3.xhtml flexbox-dyn-insertAroundText-3-ref.xhtml
 
 # Variant of one of the above tests, to regression-test an invalidation issue
 == flexbox-dyn-insertEmptySpan-1.xhtml flexbox-dyn-insertEmptySpan-1-ref.xhtml
 
--- a/layout/reftests/font-face/reftest.list
+++ b/layout/reftests/font-face/reftest.list
@@ -128,17 +128,17 @@ HTTP(..) != 507960-1-bad-sfnt-version-tt
 HTTP(..) != 507960-1-bad-sfnt-version-woff.html 507960-1-ref.html
 HTTP(..) != 507960-1-bad-woff-sig.html 507960-1-ref.html
 HTTP(..) != 507960-1-bad-offset-woff.html 507960-1-ref.html
 HTTP(..) != 507960-1-woff-bad-hint.html 507960-1-ref.html
 
 # Tests for bug 523717
 HTTP(..) == underline-offset-change-1.html underline-offset-change-1-ref.html
 HTTP(..) == underline-offset-change-2.html underline-offset-change-2-ref.html
-fails-if(cocoaWidget) fails-if(winWidget) HTTP(..) != underline-offset-change-1-ref.html underline-offset-change-2-ref.html # Bug 534132
+fails-if(cocoaWidget&&!styloVsGecko) fails-if(winWidget&&!styloVsGecko) HTTP(..) != underline-offset-change-1-ref.html underline-offset-change-2-ref.html # Bug 534132
 
 HTTP(..) != 534352-1-extra-cmap-sentinel.html 534352-1-extra-cmap-sentinel-ref.html
 HTTP(..) == bug533251.html bug533251-ref.html
 
 # Bug 875287
 HTTP(..) == font-familiy-whitespace-1.html font-familiy-whitespace-1-ref.html
 HTTP(..) != font-familiy-whitespace-1.html font-familiy-whitespace-1-notref.html
 
--- a/layout/reftests/font-features/reftest.list
+++ b/layout/reftests/font-features/reftest.list
@@ -49,17 +49,17 @@ HTTP(..) == font-features-order-2.html f
 HTTP(..) == font-features-order-3.html font-features-noliga.html
 HTTP(..) == font-features-order-4.html font-features-noliga.html
 HTTP(..) == font-features-order-5.html font-features-hlig.html
 
 # check priority involving feature settings and font-variant-alternates
 fails-if(styloVsGecko||stylo) HTTP(..) == alternates-order.html alternates-order-ref.html
 
 # check that font-specific values line up with @font-face feature settings
-HTTP(..) == annotations.html annotations-ref.html
+fails-if((stylo||styloVsGecko)&&cocoaWidget) skip-if((stylo||styloVsGecko)&&winWidget) HTTP(..) == annotations.html annotations-ref.html
 
 # font-variant subproperties
 # test for specific features being on and others off, based on prop values
 # (debug problems with font-variant-debug.html which displays all props)
 fails-if(styloVsGecko||stylo) HTTP(..) == font-variant-alternates.html font-variant-alternates-ref.html
 HTTP(..) == font-variant-caps.html font-variant-caps-ref.html
 HTTP(..) == font-variant-east-asian.html font-variant-east-asian-ref.html
 HTTP(..) == font-variant-ligatures.html font-variant-ligatures-ref.html
@@ -84,20 +84,20 @@ HTTP(..) != kerning-sanity-check-nokern.
 # OpenType features should work across inter-word spaces
 HTTP(..) == font-features-across-space-1.html font-features-across-space-1-ref.html
 HTTP(..) == spacelookups.html spacelookups-ref.html
 # tests whether word cache is in use by testing for ignored space kerns
 HTTP(..) == spacelookups-wordcache.html spacelookups-wordcache-ref.html
 # requires Japanese font with feature support, WinXP lacks one
 random-if(!winWidget&&!cocoaWidget) HTTP(..) == fwid-spaces.html fwid-spaces-ref.html
 # Arial/Times New Roman on Win7+/OSX 10.6+ have kerning pairs that include spaces
-random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) HTTP(..) != kerning-spaces-arial-nokern.html kerning-spaces-arial-default.html
-random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) HTTP(..) == kerning-spaces-arial-kern.html kerning-spaces-arial-default.html
-random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) HTTP(..) != kerning-spaces-tnr-nokern.html kerning-spaces-tnr-default.html
-random-if(!winWidget&&!cocoaWidget) fails-if(winWidget||cocoaWidget) HTTP(..) == kerning-spaces-tnr-kern.html kerning-spaces-tnr-default.html
+random-if(!winWidget&&!cocoaWidget) fails-if((winWidget||cocoaWidget)&&!styloVsGecko) HTTP(..) != kerning-spaces-arial-nokern.html kerning-spaces-arial-default.html
+random-if(!winWidget&&!cocoaWidget) fails-if((winWidget||cocoaWidget)&&!styloVsGecko) HTTP(..) == kerning-spaces-arial-kern.html kerning-spaces-arial-default.html
+random-if(!winWidget&&!cocoaWidget) fails-if((winWidget||cocoaWidget)&&!styloVsGecko) HTTP(..) != kerning-spaces-tnr-nokern.html kerning-spaces-tnr-default.html
+random-if(!winWidget&&!cocoaWidget) fails-if((winWidget||cocoaWidget)&&!styloVsGecko) HTTP(..) == kerning-spaces-tnr-kern.html kerning-spaces-tnr-default.html
 
 # font-variant-caps fallback
 # -- sanity check - none of these should look like the default rendering
 HTTP(..) != caps-fallback-smallcaps1.html caps-fallback-default.html
 HTTP(..) != caps-fallback-smallcaps2.html caps-fallback-default.html
 HTTP(..) != caps-fallback-petitecaps.html caps-fallback-default.html
 HTTP(..) != caps-fallback-allsmallcaps.html caps-fallback-default.html
 HTTP(..) != caps-fallback-allpetitecaps.html caps-fallback-default.html
--- a/layout/reftests/mathml/reftest.list
+++ b/layout/reftests/mathml/reftest.list
@@ -128,17 +128,17 @@ fails-if(gtkWidget&&!styloVsGecko) rando
 == mathbackground-4.xml mathbackground-4-ref.xml
 == mstyle-1.xhtml mstyle-1-ref.xhtml
 == mstyle-2.xhtml mstyle-2-ref.xhtml
 fuzzy-if(OSX,16,8) == mstyle-3.xhtml mstyle-3-ref.xhtml
 == mstyle-4.xhtml mstyle-4-ref.xhtml
 == mstyle-5.xhtml mstyle-5-ref.xhtml # Bug 787215
 == scale-stretchy-1.xhtml scale-stretchy-1-ref.xhtml
 != scale-stretchy-2.xhtml scale-stretchy-2-ref.xhtml
-fails-if(skiaContent&&OSX>=1010) == scale-stretchy-3.xhtml scale-stretchy-3-ref.xhtml
+fails-if(skiaContent&&OSX>=1010&&!styloVsGecko) == scale-stretchy-3.xhtml scale-stretchy-3-ref.xhtml
 != scale-stretchy-4.xhtml scale-stretchy-4-ref.xhtml
 != scale-stretchy-5.xhtml scale-stretchy-5-ref.xhtml
 != stretchy-1.html stretchy-1-ref.html
 == mspace-1.html mspace-1-ref.html
 == mpadded-1.html mpadded-1-ref.html
 == mpadded-2.html mpadded-2-ref.html
 == mpadded-3.html mpadded-3-ref.html
 == mpadded-4.html mpadded-4-ref.html
@@ -279,22 +279,22 @@ fuzzy-if(d2d,7,1) == menclose-6-downdiag
 == menclose-6-right.html menclose-6-ref.html
 fuzzy-if(skiaContent,2,3) == menclose-6-roundedbox.html menclose-6-ref.html
 == menclose-6-top.html menclose-6-ref.html
 == menclose-6-updiagonalarrow.html menclose-6-ref.html
 fuzzy-if(d2d,7,1) == menclose-6-updiagonalstrike.html menclose-6-ref.html
 == menclose-6-verticalstrike.html menclose-6-ref.html
 == menclose-6-phasorangle.html menclose-6-ref.html
 == mmultiscript-align.html mmultiscript-align-ref.html
-fails-if(winWidget) == subscript-italic-correction.html subscript-italic-correction-ref.html # bug 961482
+fails-if(winWidget&&!styloVsGecko) == subscript-italic-correction.html subscript-italic-correction-ref.html # bug 961482
 fails-if(Android) == mathvariant-1a.html mathvariant-1a-ref.html # Bug 1010679
 fails-if(Android) == mathvariant-1b.html mathvariant-1b-ref.html # Bug 1010679
 fails-if(Android) == mathvariant-1c.html mathvariant-1c-ref.html # Bug 1010679
 == mathvariant-1d.html mathvariant-1d-ref.html
-fails-if(Android||OSX) == mathvariant-2.html mathvariant-2-ref.html # Bugs 1010678, 1010679
+fails-if((Android||OSX)&&!styloVsGecko) == mathvariant-2.html mathvariant-2-ref.html # Bugs 1010678, 1010679
 == mathvariant-3.html mathvariant-3-ref.html
 == mathvariant-4.html mathvariant-4-ref.html
 == mathvariant-5.html mathvariant-5-ref.html
 == dtls-1.html dtls-1-ref.html
 == dtls-2.html dtls-2-ref.html
 == dtls-3.html dtls-3-ref.html
 == ssty-1.html ssty-1-ref.html
 == ssty-2.html ssty-2-ref.html
--- a/layout/reftests/reftest-sanity/reftest.list
+++ b/layout/reftests/reftest-sanity/reftest.list
@@ -39,17 +39,17 @@ HTTP != blank.html default.html
 HTTP(..) == filter-1.xhtml filter-1-ref.xhtml
 HTTP(..) == filter-2.xhtml filter-2-ref.xhtml
 
 # test that the MozReftestInvalidate event fires
 == invalidation.html about:blank
 == zoom-invalidation.html zoom-invalidation-ref.html # bug 773482
 
 # test that xulRuntime.OS works
-fails-if(xulRuntime.OS!="Linux"&&!Android) == data:text/html,<body>Linux data:text/html,<script>document.write(navigator.platform.substr(0,5))</script>
+fails-if(xulRuntime.OS!="Linux"&&!Android&&!styloVsGecko) == data:text/html,<body>Linux data:text/html,<script>document.write(navigator.platform.substr(0,5))</script>
 fails-if(xulRuntime.OS!="WINNT"&&!styloVsGecko) == data:text/html,<body>Win data:text/html,<script>document.write(navigator.platform.substr(0,3))</script>
 fails-if(xulRuntime.OS!="Darwin"&&!styloVsGecko) == data:text/html,<body>Mac data:text/html,<script>document.write(navigator.platform.substr(0,3))</script>
 
 # test parsing of asserts() expressions
 asserts(0) load about:blank
 asserts(0-5) load about:blank
 asserts-if(true,0) load about:blank
 asserts-if(false,7) load about:blank
--- a/layout/reftests/selection/reftest.list
+++ b/layout/reftests/selection/reftest.list
@@ -22,18 +22,18 @@ fuzzy-if(skiaContent,1,700) == extend-3f
 fuzzy-if(skiaContent,1,700) == extend-3g.html extend-3-ref.html
 fuzzy-if(skiaContent,1,700) == extend-3h.html extend-3-ref.html
 fuzzy-if(skiaContent,1,700) == extend-3i.html extend-3-ref.html
 == extend-4a.html extend-4-ref.html
 == extend-4b.html extend-4-ref.html
 # these 3 random-if(Android) are a difference of Native & Xul, see bug 739714
 random-if(Android) needs-focus != pseudo-element-of-native-anonymous.html pseudo-element-of-native-anonymous-ref.html # bug 676641
 # These tests uses Highlight and HighlightText color keywords, they are not same as text selection color on Mac.
-random-if(Android) fails-if(cocoaWidget) needs-focus == non-themed-widget.html non-themed-widget-ref.html
-random-if(Android) fails-if(cocoaWidget) needs-focus == themed-widget.html themed-widget-ref.html
+random-if(Android) fails-if(cocoaWidget&&!styloVsGecko) needs-focus == non-themed-widget.html non-themed-widget-ref.html
+random-if(Android) fails-if(cocoaWidget&&!styloVsGecko) needs-focus == themed-widget.html themed-widget-ref.html
 == addrange-1.html addrange-ref.html
 fuzzy-if(skiaContent,1,1200) == addrange-2.html addrange-ref.html
 == splitText-normalize.html splitText-normalize-ref.html
 == modify-range.html modify-range-ref.html
 == dom-mutations.html dom-mutations-ref.html
 fuzzy-if(OSX==1010,9,1) fuzzy-if(OSX&&skiaContent,6,1) fuzzy-if(skiaContent&&!OSX,1,2138) == trailing-space-1.html trailing-space-1-ref.html
 != invalidation-1-ref.html invalidation-2-ref.html
 == invalidation-1a.html invalidation-1-ref.html
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -203,17 +203,17 @@ fuzzy-if(skiaContent,1,2) == fallback-co
 == filter-bounds-02.svg pass.svg
 # This pref is normally on by default, but we turn it off in reftest runs to
 # disable an unnecessary security-check. This reftest is actually testing that
 # the security check works, though, so it needs the pref to be turned on:
 fails-if(Android) pref(security.fileuri.strict_origin_policy,true) == filter-extref-differentOrigin-01.svg pass.svg # Bug 695385
 == filter-foreignObject-01.svg pass.svg
 == filter-in-mask-01.svg pass.svg
 == filter-invalidation-01.svg pass.svg
-fuzzy(71,817) == filter-on-continuation-box-01.html filter-on-continuation-box-ref.html
+fuzzy(71,817) fails-if(winWidget&&stylo) == filter-on-continuation-box-01.html filter-on-continuation-box-ref.html
 == filter-result-01.svg filter-result-01-ref.svg
 == filter-scaled-01.svg pass.svg
 fuzzy-if(skiaContent,1,500) == filter-scaled-02.html filter-scaled-02-ref.html
 == filter-translated-01.svg filter-translated-01-ref.svg
 == filter-use-element-01.svg pass.svg
 fuzzy-if(skiaContent,1,800000) == filters-and-group-opacity-01.svg filters-and-group-opacity-01-ref.svg
 
 == foreignObject-01.svg pass.svg
@@ -376,17 +376,17 @@ fuzzy-if(skiaContent,3,5) == pattern-sca
 # reftest harness.
 # == pseudo-classes-02.svg pseudo-classes-02-ref.svg
 
 == radialGradient-basic-01.svg pass.svg
 == radialGradient-basic-02.svg pass.svg
 fuzzy-if(cocoaWidget,4,15982) fuzzy-if(winWidget,4,92) fuzzy-if(skiaContent,4,60) == radialGradient-basic-03.svg radialGradient-basic-03-ref.svg
 == radialGradient-basic-04.svg pass.svg
 == radialGradient-fr-01.svg pass.svg
-fuzzy(1,3235) fuzzy-if(winWidget,1,6704) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg
+fuzzy(1,3235) fuzzy-if(winWidget,1,6704) fuzzy-if(winWidget&&stylo,1,6711) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg
 
 fuzzy-if(skiaContent,1,3600) == rect-01.svg pass.svg
 == rect-02.svg pass.svg
 == rect-03.svg pass.svg
 == rect-04.svg pass.svg
 == rect-with-rx-and-ry-01.svg pass.svg
 == rect-with-rx-or-ry-01.svg rect-with-rx-or-ry-01-ref.svg
 
--- a/layout/reftests/svg/smil/reftest.list
+++ b/layout/reftests/svg/smil/reftest.list
@@ -271,17 +271,17 @@ fuzzy-if(cocoaWidget&&layersGPUAccelerat
 # Test animation using defs element
 == anim-defs-gradient-property.svg lime.svg
 == anim-defs-gradient-attribute.svg lime.svg
 == anim-defs-fill.svg lime.svg
 == anim-defs-width.svg lime.svg
 
 # Test animation that changes 'display' attribute
 == anim-display.svg lime.svg
-== anim-display-in-g-element.svg lime.svg
+skip-if(styloVsGecko||stylo) == anim-display-in-g-element.svg lime.svg # Bug 1385089
 
 # Test animation that change 'display' style value to 'none'
 == anim-change-display-none-for-ancestor-elem.html lime.html
 == anim-change-display-none-for-target-elem.html lime.html
 == anim-change-display-none-for-dynamically-appended-elem.html lime.html
 == anim-change-display-block-for-dynamically-appended-elem.html anim-standard-ref.html
 
 pref(layout.css.clip-path-shapes.enabled,true) fuzzy(63,146) == anim-clipPath-viewBox.svg anim-clipPath-viewBox-ref.svg
--- a/layout/reftests/text/reftest.list
+++ b/layout/reftests/text/reftest.list
@@ -19,17 +19,17 @@ random-if(!cocoaWidget) == font-size-adj
 == justification-cjk-extension.html justification-cjk-extension-ref.html
 == justification-space-diacritic.html justification-space-diacritic-ref.html
 HTTP(..) load ligature-with-space-1.html
 == line-editing-1a.html line-editing-1-ref.html
 == line-editing-1b.html line-editing-1-ref.html
 == line-editing-1c.html line-editing-1-ref.html
 == line-editing-1d.html line-editing-1-ref.html
 == line-editing-1e.html line-editing-1-ref.html
-fails-if(cocoaWidget||(winWidget&&dwrite)) HTTP(..) == lineheight-metrics-1.html lineheight-metrics-1-ref.html # bug 657864
+fails-if((cocoaWidget||(winWidget&&dwrite))&&!styloVsGecko) HTTP(..) == lineheight-metrics-1.html lineheight-metrics-1-ref.html # bug 657864
 HTTP(..) == lineheight-metrics-2a.html lineheight-metrics-2-ref.html
 HTTP(..) == lineheight-metrics-2b.html lineheight-metrics-2-ref.html
 == lineheight-percentage-1.html lineheight-percentage-1-ref.html
 == long-1.html long-ref.html
 fuzzy-if(Android,255,147) == pre-line-1.html pre-line-1-ref.html
 == pre-line-2.html pre-line-2-ref.html
 == pre-line-3.html pre-line-3-ref.html
 == pre-line-4.html pre-line-4-ref.html
@@ -112,17 +112,17 @@ HTTP(..) == variation-selector-unsupport
 == white-space-1b.html white-space-1-ref.html
 == white-space-2.html white-space-2-ref.html
 == wordbreak-1.html wordbreak-1-ref.html
 == wordbreak-2.html wordbreak-2-ref.html
 == wordbreak-3.html wordbreak-3-ref.html
 skip-if(Android) == wordbreak-4a.html wordbreak-4a-ref.html
 == wordbreak-4b.html wordbreak-4b-ref.html
 == wordbreak-5.html wordbreak-5-ref.html
-fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == wordbreak-6.html wordbreak-6-ref.html # Bug 1258239
+fails-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&!styloVsGecko) == wordbreak-6.html wordbreak-6-ref.html # Bug 1258239
 HTTP(..) == wordbreak-7a.html wordbreak-7a-ref.html
 fails-if(!styloVsGecko) HTTP(..) == wordbreak-7b.html wordbreak-7b-ref.html # bug 479829
 == wordbreak-8.html wordbreak-8-ref.html
 pref(gfx.font_rendering.graphite.enabled,true) HTTP(..) == wordbreak-9.html wordbreak-9-ref.html
 == wordbreak-dynamic-1.html wordbreak-dynamic-1-ref.html
 == wordwrap-01.html wordwrap-01-ref.html
 HTTP(..) == wordwrap-02.html wordwrap-02-ref.html
 fuzzy-if(gtkWidget,1,177) fuzzy-if(skiaContent,1,50) HTTP(..) == wordwrap-03.html wordwrap-03-ref.html # Fuzzy on Linux because the native textbox gradient is painted in a slightly different position depending on the invalid area.
@@ -146,17 +146,17 @@ fuzzy-if(gtkWidget,1,177) fuzzy-if(skiaC
 # the following will fail when rendering with Core Text (see bug 389074) due to what appears to be
 # an Apple bug: the presence of ZWNJ disturbs the positioning of an adjacent glyph. rdar://6427865
 random-if(cocoaWidget) random-if(gtkWidget) HTTP(..) == zwnj-01.xhtml zwnj-01-ref.xhtml # gtkWidget:bug 1309113
 HTTP(..) == zwnj-02.xhtml zwnj-02-ref.xhtml # HTTP(..) for ../filters.svg
 != zwnj-01.html zwnj-01-notref.html
 == initial-zwj-1.html initial-zwj-1-ref.html
 == cgj-01.html cgj-01-ref.html
 == 444656.html 444656-ref.html
-== 449555-1.html 449555-1-ref.html
+fails-if(cocoaWidget&&styloVsGecko) == 449555-1.html 449555-1-ref.html
 == 467722.html 467722-ref.html
 fuzzy-if(skiaContent,1,600) HTTP(..) == 475092-sub.html 475092-ref.html
 fails-if(Android) fuzzy-if(skiaContent&&!Android,90,3100) HTTP(..) == 475092-pos.html 475092-sub.html # bug 482596
 == 476378-soft-hyphen-fallback.html 476378-soft-hyphen-fallback-ref.html
 # Test for bug 484954
 == rgba-text.html rgba-text-ref.html
 # Test for bug 575695, 'kern' table support
 HTTP(..) != kerning-01.html kerning-01-notref.html
@@ -164,33 +164,33 @@ HTTP(..) != kerning-01.html kerning-01-n
 random-if(!cocoaWidget) == 577380.html 577380-ref.html
 # Test for OpenType Arabic shaping support
 HTTP(..) == arabic-shaping-1.html arabic-shaping-1-ref.html
 # check ligature in Arial Bold on Windows, for bug 644184; may fail on other platforms depending on fonts
 random-if(!winWidget) == arial-bold-lam-alef-1.html arial-bold-lam-alef-1-ref.html
 # Fallback (presentation-forms) shaping with a font that lacks GSUB/GPOS
 # These tests are not valid with Mac or FT2 font backends because our masking of complex-script ranges
 # in the 'cmap' will prevent the test font (without GSUB) being used.
-fails-if(cocoaWidget||Android) HTTP(..) == arabic-fallback-1.html arabic-fallback-1-ref.html
-fails-if(cocoaWidget||Android) HTTP(..) == arabic-fallback-2.html arabic-fallback-2-ref.html
-fails-if(cocoaWidget||Android) HTTP(..) == arabic-fallback-3.html arabic-fallback-3-ref.html
+fails-if((cocoaWidget||Android)&&!styloVsGecko) HTTP(..) == arabic-fallback-1.html arabic-fallback-1-ref.html
+fails-if((cocoaWidget||Android)&&!styloVsGecko) HTTP(..) == arabic-fallback-2.html arabic-fallback-2-ref.html
+fails-if((cocoaWidget||Android)&&!styloVsGecko) HTTP(..) == arabic-fallback-3.html arabic-fallback-3-ref.html
 fails-if(!cocoaWidget&&!Android&&!styloVsGecko) HTTP(..) != arabic-fallback-4.html arabic-fallback-4-notref.html
 == arabic-marks-1.html arabic-marks-1-ref.html
 == arabic-final-ligature-spacing.html arabic-final-ligature-spacing-ref.html
 # harfbuzz fallback mark stacking in the absence of GPOS:
 HTTP(..) != fallback-mark-stacking-1.html fallback-mark-stacking-1-notref.html
 
 == 726392-1.html 726392-1-ref.html
 == 726392-2.html 726392-2-ref.html
 == 726392-3.html 726392-3-ref.html
 == 745555-1.html 745555-1-ref.html
 == 745555-2.html 745555-2-ref.html
 == 820255.html 820255-ref.html
 HTTP(..) != 1170688.html 1170688-ref.html
-fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9
+fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!styloVsGecko) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9
 HTTP(..) == 1331339-script-extensions-shaping-1.html 1331339-script-extensions-shaping-1-ref.html
 skip-if(!cocoaWidget) != 1349308-1.html 1349308-notref.html # macOS-specific test for -apple-system glyph metrics
 
 # ensure emoji chars don't render blank (bug 715798, bug 779042);
 # should at least render hexboxes if there's no font support
 != emoji-01.html emoji-01-notref.html
 != emoji-02.html emoji-02-notref.html
 
--- a/layout/reftests/transform-3d/reftest.list
+++ b/layout/reftests/transform-3d/reftest.list
@@ -18,18 +18,18 @@ fails-if(webrender) == preserve3d-2a.htm
 fails-if(webrender) == preserve3d-2b.html preserve3d-2-ref.html
 == preserve3d-2c.html preserve3d-2-ref.html
 fails-if(webrender) == preserve3d-2d.html preserve3d-2-ref.html
 fails-if(webrender) == preserve3d-3a.html preserve3d-3-ref.html
 == preserve3d-4a.html about:blank
 fuzzy-if(gtkWidget,4,200) fuzzy-if(Android,4,300) fuzzy-if(winWidget&&!layersGPUAccelerated,2,100) fuzzy-if(skiaContent,16,100) fails-if(webrender) == preserve3d-5a.html preserve3d-5-ref.html
 == preserve3d-6a.html preserve3d-6-ref.html
 == scale3d-z.html scalez-1-ref.html
-fuzzy-if(winWidget,143,689) fuzzy-if(OSX,224,924) == scale3d-all.html scale3d-1-ref.html # subpixel AA
-fuzzy-if(winWidget,143,689) fuzzy-if(OSX,224,924) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
+fuzzy-if(winWidget,143,689) fuzzy-if(OSX,224,924) fuzzy-if(winWidget&&stylo,154,644) == scale3d-all.html scale3d-1-ref.html # subpixel AA
+fuzzy-if(winWidget,143,689) fuzzy-if(OSX,224,924) fuzzy-if(winWidget&&stylo,154,644) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA
 == scale3d-xz.html scale3d-1-ref.html
 == translatez-1a.html translatez-1-ref.html
 != translatez-1b.html translatez-1-ref.html
 == translate3d-1a.html translate3d-1-ref.html
 fuzzy-if(skiaContent,1,4) == matrix3d-1a.html matrix3d-1-ref.html
 == matrix3d-2a.html matrix3d-2-ref.html
 == rotate3d-1a.html rotatex-1-ref.html
 == rotate3d-2a.html rotatey-1-ref.html
--- a/layout/reftests/w3c-css/failures.list
+++ b/layout/reftests/w3c-css/failures.list
@@ -57,24 +57,24 @@ fails-if(!styloVsGecko) css-writing-mode
 fails-if(!styloVsGecko) css-writing-modes-3/float-lft-orthog-vrl-in-htb-002.xht
 fails-if(!styloVsGecko) css-writing-modes-3/float-rgt-orthog-htb-in-vlr-003.xht
 fails-if(!styloVsGecko) css-writing-modes-3/float-rgt-orthog-htb-in-vrl-003.xht
 fails-if(!styloVsGecko) css-writing-modes-3/float-rgt-orthog-vlr-in-htb-003.xht
 fails-if(!styloVsGecko) css-writing-modes-3/float-rgt-orthog-vrl-in-htb-003.xht
 fails-if(!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vrl-001.xht
 fails-if(!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vrl-004.xht
 fails-if(!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vrl-013.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-htb-in-vlr-008.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-htb-in-vlr-020.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-htb-in-vrl-008.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-htb-in-vrl-020.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-vlr-in-htb-008.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-vlr-in-htb-020.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-vrl-in-htb-008.xht
-fails-if(OSX||winWidget||Android) css-writing-modes-3/sizing-orthog-vrl-in-htb-020.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vlr-008.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vlr-020.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vrl-008.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-htb-in-vrl-020.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-vlr-in-htb-008.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-vlr-in-htb-020.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-vrl-in-htb-008.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) css-writing-modes-3/sizing-orthog-vrl-in-htb-020.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vlr-003.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vlr-009.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vlr-015.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vlr-021.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vrl-003.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vrl-009.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vrl-015.xht
 fails-if(Android) css-writing-modes-3/sizing-orthog-htb-in-vrl-021.xht
@@ -197,17 +197,17 @@ fuzzy(135,467) css-multicol-1/multicol-c
 fuzzy(87,180) css-multicol-1/multicol-columns-001.xht
 fuzzy(87,180) css-multicol-1/multicol-columns-002.xht
 fuzzy(87,180) css-multicol-1/multicol-columns-003.xht
 fuzzy(87,180) css-multicol-1/multicol-columns-004.xht
 fuzzy(87,180) css-multicol-1/multicol-columns-005.xht
 fuzzy(87,180) css-multicol-1/multicol-columns-006.xht
 fuzzy(87,180) css-multicol-1/multicol-columns-007.xht
 fuzzy(204,930) fuzzy-if(skiaContent,208,930) css-multicol-1/multicol-columns-invalid-001.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-columns-invalid-002.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-columns-invalid-002.xht
 fuzzy(204,930) fuzzy-if(skiaContent,208,930) css-multicol-1/multicol-columns-toolong-001.xht
 fuzzy(135,530) css-multicol-1/multicol-containing-001.xht
 fuzzy(215,241) css-multicol-1/multicol-containing-002.xht
 fuzzy(87,180) css-multicol-1/multicol-count-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-count-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-count-computed-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-count-computed-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-count-computed-003.xht
@@ -239,33 +239,33 @@ fails-if(!styloVsGecko) css-multicol-1/m
 fails-if(!styloVsGecko) css-multicol-1/multicol-inherit-004.xht
 fuzzy(96,264) css-multicol-1/multicol-list-item-001.xht
 fuzzy(73,1200) css-multicol-1/multicol-margin-001.xht
 fuzzy(73,1200) css-multicol-1/multicol-margin-002.xht
 fuzzy(243,3322) fuzzy-if(skiaContent,244,3322) css-multicol-1/multicol-margin-child-001.xht
 fuzzy(255,4008) css-multicol-1/multicol-nested-002.xht
 fuzzy(255,4109) css-multicol-1/multicol-nested-005.xht
 fuzzy(204,2463) fuzzy-if(skiaContent,208,2463) css-multicol-1/multicol-nested-margin-001.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-nested-margin-002.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-nested-margin-002.xht
 fuzzy(204,2371) fuzzy-if(skiaContent,208,2371) css-multicol-1/multicol-nested-margin-003.xht
 fuzzy(225,2529) css-multicol-1/multicol-nested-margin-004.xht
 fuzzy(225,2529) css-multicol-1/multicol-nested-margin-005.xht
 fuzzy(135,142) css-multicol-1/multicol-overflow-000.xht
 fuzzy(204,1844) fuzzy-if(skiaContent,208,1844) css-multicol-1/multicol-overflowing-001.xht
 fuzzy-if(OSX,61,2) fuzzy-if(skiaContent,64,2) css-multicol-1/multicol-reduce-000.xht
 fuzzy-if(OSX,8,20) css-multicol-1/multicol-rule-000.xht
 fuzzy(135,1584) css-multicol-1/multicol-rule-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-rule-002.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-rule-003.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-rule-color-001.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-rule-003.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-rule-color-001.xht
 fuzzy(106,354) css-multicol-1/multicol-rule-dashed-000.xht
 fuzzy(106,354) css-multicol-1/multicol-rule-dotted-000.xht
 fuzzy(106,354) css-multicol-1/multicol-rule-double-000.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-rule-fraction-001.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-rule-fraction-002.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-rule-fraction-001.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-rule-fraction-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-rule-fraction-003.xht
 fuzzy(127,500) fails-if(webrender) css-multicol-1/multicol-rule-groove-000.xht
 fuzzy(94,256) css-multicol-1/multicol-rule-hidden-000.xht
 fuzzy(127,500) fails-if(webrender) css-multicol-1/multicol-rule-inset-000.xht
 fuzzy(127,500) fails-if(webrender) css-multicol-1/multicol-rule-outset-000.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-rule-px-001.xht
 fuzzy(127,500) fails-if(webrender) css-multicol-1/multicol-rule-ridge-000.xht
 fuzzy(106,354) css-multicol-1/multicol-rule-solid-000.xht
@@ -275,17 +275,17 @@ fails-if(webrender) css-multicol-1/multi
 fails-if(webrender) css-multicol-1/multicol-rule-style-outset-001.xht
 fails-if(webrender) css-multicol-1/multicol-rule-style-ridge-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-shorthand-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-000.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-003.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-child-001.xht
-fails-if(OSX||winWidget) css-multicol-1/multicol-span-all-child-002.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) css-multicol-1/multicol-span-all-child-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-bottom-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-nested-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-nested-002.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-nested-003.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-all-margin-nested-firstchild-001.xht
 fails-if(!styloVsGecko) css-multicol-1/multicol-span-float-001.xht
--- a/layout/reftests/w3c-css/received/reftest.list
+++ b/layout/reftests/w3c-css/received/reftest.list
@@ -60,17 +60,17 @@ fuzzy(135,467) == css-multicol-1/multico
 fuzzy(87,180) == css-multicol-1/multicol-columns-001.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-columns-002.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-columns-003.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-columns-004.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-columns-005.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-columns-006.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-columns-007.xht css-multicol-1/multicol-columns-001-ref.xht
 fuzzy(204,930) fuzzy-if(skiaContent,208,930) == css-multicol-1/multicol-columns-invalid-001.xht css-multicol-1/multicol-columns-invalid-001-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-columns-invalid-002.xht css-multicol-1/multicol-columns-invalid-001-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-columns-invalid-002.xht css-multicol-1/multicol-columns-invalid-001-ref.xht
 fuzzy(204,930) fuzzy-if(skiaContent,208,930) == css-multicol-1/multicol-columns-toolong-001.xht css-multicol-1/multicol-columns-invalid-001-ref.xht
 fuzzy(135,530) == css-multicol-1/multicol-containing-001.xht css-multicol-1/multicol-containing-001-ref.xht
 fuzzy(215,241) == css-multicol-1/multicol-containing-002.xht css-multicol-1/multicol-containing-002-ref.xht
 fuzzy(87,180) == css-multicol-1/multicol-count-001.xht css-multicol-1/multicol-columns-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-count-002.xht css-multicol-1/multicol-count-002-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-count-computed-001.xht css-multicol-1/multicol-count-computed-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-count-computed-002.xht css-multicol-1/multicol-count-computed-2-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-count-computed-003.xht css-multicol-1/multicol-count-computed-003-ref.xht
@@ -109,36 +109,36 @@ fails-if(!styloVsGecko) == css-multicol-
 fuzzy(96,264) == css-multicol-1/multicol-list-item-001.xht css-multicol-1/multicol-list-item-001-ref.xht
 fuzzy(73,1200) == css-multicol-1/multicol-margin-001.xht reference/ref-filled-green-100px-square.xht
 fuzzy(73,1200) == css-multicol-1/multicol-margin-002.xht reference/ref-filled-green-100px-square.xht
 fuzzy(243,3322) fuzzy-if(skiaContent,244,3322) == css-multicol-1/multicol-margin-child-001.xht css-multicol-1/multicol-margin-child-001-ref.xht
 fuzzy(255,4008) == css-multicol-1/multicol-nested-002.xht css-multicol-1/multicol-nested-002-ref.xht
 fuzzy(255,4109) == css-multicol-1/multicol-nested-005.xht css-multicol-1/multicol-nested-005-ref.xht
 fuzzy(225,13600) == css-multicol-1/multicol-nested-column-rule-001.xht css-multicol-1/multicol-nested-column-rule-001-ref.xht
 fuzzy(204,2463) fuzzy-if(skiaContent,208,2463) == css-multicol-1/multicol-nested-margin-001.xht css-multicol-1/multicol-nested-margin-001-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-nested-margin-002.xht css-multicol-1/multicol-nested-margin-002-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-nested-margin-002.xht css-multicol-1/multicol-nested-margin-002-ref.xht
 fuzzy(204,2371) fuzzy-if(skiaContent,208,2371) == css-multicol-1/multicol-nested-margin-003.xht css-multicol-1/multicol-nested-margin-003-ref.xht
 fuzzy(225,2529) == css-multicol-1/multicol-nested-margin-004.xht css-multicol-1/multicol-nested-margin-004-ref.xht
 fuzzy(225,2529) == css-multicol-1/multicol-nested-margin-005.xht css-multicol-1/multicol-nested-margin-004-ref.xht
 fuzzy(135,142) == css-multicol-1/multicol-overflow-000.xht css-multicol-1/multicol-overflow-000-ref.xht
 fuzzy(204,1844) fuzzy-if(skiaContent,208,1844) == css-multicol-1/multicol-overflowing-001.xht css-multicol-1/multicol-overflowing-001-ref.xht
 fuzzy-if(OSX,61,2) fuzzy-if(skiaContent,64,2) == css-multicol-1/multicol-reduce-000.xht css-multicol-1/multicol-reduce-000-ref.xht
 fuzzy-if(OSX,8,20) == css-multicol-1/multicol-rule-000.xht css-multicol-1/multicol-rule-000-ref.xht
 fuzzy(135,1584) == css-multicol-1/multicol-rule-001.xht css-multicol-1/multicol-rule-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-rule-002.xht css-multicol-1/multicol-rule-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-rule-003.xht css-multicol-1/multicol-rule-003-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-rule-003.xht css-multicol-1/multicol-rule-003-ref.xht
 == css-multicol-1/multicol-rule-004.xht css-multicol-1/multicol-rule-004-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-rule-color-001.xht css-multicol-1/multicol-rule-color-001-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-rule-color-001.xht css-multicol-1/multicol-rule-color-001-ref.xht
 == css-multicol-1/multicol-rule-color-inherit-001.xht css-multicol-1/multicol-rule-color-inherit-001-ref.xht
 == css-multicol-1/multicol-rule-color-inherit-002.xht css-multicol-1/multicol-rule-color-inherit-001-ref.xht
 fuzzy(106,354) == css-multicol-1/multicol-rule-dashed-000.xht css-multicol-1/multicol-rule-dashed-000-ref.xht
 fuzzy(106,354) == css-multicol-1/multicol-rule-dotted-000.xht css-multicol-1/multicol-rule-dotted-000-ref.xht
 fuzzy(106,354) == css-multicol-1/multicol-rule-double-000.xht css-multicol-1/multicol-rule-double-000-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-rule-fraction-001.xht css-multicol-1/multicol-rule-fraction-001-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-rule-fraction-002.xht css-multicol-1/multicol-rule-fraction-002-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-rule-fraction-001.xht css-multicol-1/multicol-rule-fraction-001-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-rule-fraction-002.xht css-multicol-1/multicol-rule-fraction-002-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-rule-fraction-003.xht css-multicol-1/multicol-rule-fraction-3-ref.xht
 fuzzy(127,500) fails-if(webrender) == css-multicol-1/multicol-rule-groove-000.xht css-multicol-1/multicol-rule-groove-000-ref.xht
 fuzzy(94,256) == css-multicol-1/multicol-rule-hidden-000.xht css-multicol-1/multicol-rule-hidden-000-ref.xht
 fuzzy(127,500) fails-if(webrender) == css-multicol-1/multicol-rule-inset-000.xht css-multicol-1/multicol-rule-ridge-000-ref.xht
 fuzzy(255,2808) == css-multicol-1/multicol-rule-large-001.xht css-multicol-1/multicol-rule-large-001-ref.xht
 fuzzy(94,256) == css-multicol-1/multicol-rule-none-000.xht css-multicol-1/multicol-rule-hidden-000-ref.xht
 fuzzy(127,500) fails-if(webrender) == css-multicol-1/multicol-rule-outset-000.xht css-multicol-1/multicol-rule-groove-000-ref.xht
 == css-multicol-1/multicol-rule-percent-001.xht css-multicol-1/multicol-containing-002-ref.xht
@@ -154,17 +154,17 @@ fails-if(webrender) == css-multicol-1/mu
 fails-if(webrender) == css-multicol-1/multicol-rule-style-ridge-001.xht css-multicol-1/multicol-rule-style-ridge-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-shorthand-001.xht css-multicol-1/multicol-rule-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-000.xht css-multicol-1/multicol-span-000-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-001.xht css-multicol-1/multicol-span-all-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-002.xht css-multicol-1/multicol-span-all-002-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-003.xht css-multicol-1/multicol-count-002-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-block-sibling-003.xht css-multicol-1/multicol-span-all-block-sibling-3-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-child-001.xht css-multicol-1/multicol-span-all-child-001-ref.xht
-fails-if(OSX||winWidget) == css-multicol-1/multicol-span-all-child-002.xht css-multicol-1/multicol-span-all-child-002-ref.xht
+fails-if((OSX||winWidget)&&!styloVsGecko) == css-multicol-1/multicol-span-all-child-002.xht css-multicol-1/multicol-span-all-child-002-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-001.xht css-multicol-1/multicol-span-all-margin-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-002.xht css-multicol-1/multicol-span-all-margin-002-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-bottom-001.xht css-multicol-1/multicol-span-all-margin-bottom-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-nested-001.xht css-multicol-1/multicol-span-all-margin-nested-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-nested-002.xht css-multicol-1/multicol-span-all-margin-nested-001-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-nested-003.xht css-multicol-1/multicol-span-all-margin-nested-3-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-all-margin-nested-firstchild-001.xht css-multicol-1/multicol-span-all-margin-nested-firstchild-ref.xht
 fails-if(!styloVsGecko) == css-multicol-1/multicol-span-float-001.xht css-multicol-1/multicol-span-float-001-ref.xht
@@ -919,47 +919,47 @@ fuzzy-if(OSX||winWidget,110,1200) == css
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/row-progression-vrl-004.xht css-writing-modes-3/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/row-progression-vrl-006.xht css-writing-modes-3/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/row-progression-vrl-008.xht css-writing-modes-3/block-flow-direction-001-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-001.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-001-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vlr-003.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-003-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-004.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-004-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-006.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-006-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-007.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-007-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-htb-in-vlr-008.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-008-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vlr-008.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-008-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vlr-009.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-003-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-010.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-010-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-011.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-011-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-012.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-006-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-013.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-013-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vlr-015.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-015-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-016.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-016-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-018.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-018-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-019.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-019-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-htb-in-vlr-020.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-020-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vlr-020.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-020-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vlr-021.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-015-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-022.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-022-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-023.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-023-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vlr-024.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-018-ref.xht
 fails-if(!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vrl-001.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-001-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vrl-003.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-003-ref.xht
 fails-if(!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vrl-004.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-004-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-006.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-006-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-007.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-007-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-htb-in-vrl-008.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-008-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vrl-008.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-008-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vrl-009.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-003-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-010.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-010-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-011.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-011-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-012.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-006-ref.xht
 fails-if(!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vrl-013.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-013-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vrl-015.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-015-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-016.xht css-writing-modes-3/sizing-orthog-htb-in-vlr-016-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-018.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-018-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-019.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-019-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-htb-in-vrl-020.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-020-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-htb-in-vrl-020.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-020-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-htb-in-vrl-021.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-015-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-022.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-022-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-023.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-023-ref.xht
 == css-writing-modes-3/sizing-orthog-htb-in-vrl-024.xht css-writing-modes-3/sizing-orthog-htb-in-vrl-018-ref.xht
 == css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-001.xht css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-001-ref.xht
 == css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-002.xht css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-002-ref.xht
 == css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-003.xht css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-003-ref.xht
 == css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-004.xht css-writing-modes-3/sizing-orthog-prct-htb-in-vlr-004-ref.xht
@@ -991,47 +991,47 @@ fails-if(Android) == css-writing-modes-3
 == css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-006.xht css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-006-ref.xht
 == css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-007.xht css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-007-ref.xht
 == css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-008.xht css-writing-modes-3/sizing-orthog-prct-vrl-in-htb-008-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-001.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-001-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vlr-in-htb-003.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-003-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-004.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-004-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-006.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-006-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-007.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-007-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-vlr-in-htb-008.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-008-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-vlr-in-htb-008.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-008-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vlr-in-htb-009.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-009-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-010.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-010-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-011.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-011-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-012.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-012-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-013.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-013-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vlr-in-htb-015.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-015-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-016.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-016-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-018.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-018-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-019.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-019-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-vlr-in-htb-020.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-020-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-vlr-in-htb-020.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-020-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vlr-in-htb-021.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-015-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-022.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-022-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-023.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-023-ref.xht
 == css-writing-modes-3/sizing-orthog-vlr-in-htb-024.xht css-writing-modes-3/sizing-orthog-vlr-in-htb-018-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-001.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-001-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vrl-in-htb-003.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-003-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-004.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-004-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-006.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-006-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-007.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-007-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-vrl-in-htb-008.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-008-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-vrl-in-htb-008.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-008-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vrl-in-htb-009.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-009-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-010.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-010-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-011.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-011-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-012.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-012-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-013.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-013-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vrl-in-htb-015.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-015-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-016.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-016-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-018.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-018-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-019.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-019-ref.xht
-fails-if(OSX||winWidget||Android) == css-writing-modes-3/sizing-orthog-vrl-in-htb-020.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-020-ref.xht
+fails-if((OSX||winWidget||Android)&&!styloVsGecko) == css-writing-modes-3/sizing-orthog-vrl-in-htb-020.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-020-ref.xht
 fails-if(Android) == css-writing-modes-3/sizing-orthog-vrl-in-htb-021.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-015-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-022.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-022-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-023.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-023-ref.xht
 == css-writing-modes-3/sizing-orthog-vrl-in-htb-024.xht css-writing-modes-3/sizing-orthog-vrl-in-htb-018-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/table-column-order-002.xht css-writing-modes-3/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/table-column-order-003.xht css-writing-modes-3/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/table-column-order-004.xht css-writing-modes-3/block-flow-direction-001-ref.xht
 fuzzy-if(OSX||winWidget,110,1200) == css-writing-modes-3/table-column-order-005.xht css-writing-modes-3/block-flow-direction-001-ref.xht
--- a/layout/reftests/w3c-css/submitted/shapes1/reftest.list
+++ b/layout/reftests/w3c-css/submitted/shapes1/reftest.list
@@ -91,17 +91,17 @@ fails-if(!styloVsGecko) == shape-outside
 == shape-outside-inset-019.html shape-outside-inset-019-ref.html
 == shape-outside-inset-020.html shape-outside-inset-020-ref.html
 == shape-outside-inset-021.html shape-outside-inset-021-ref.html
 == shape-outside-inset-022.html shape-outside-inset-022-ref.html
 == shape-outside-inset-023.html shape-outside-inset-023-ref.html
 == shape-outside-inset-024.html shape-outside-inset-024-ref.html
 == shape-outside-inset-025.html shape-outside-inset-025-ref.html
 == shape-outside-inset-026.html shape-outside-inset-026-ref.html
-== shape-outside-inset-027.html shape-outside-inset-027-ref.html
+skip-if(stylo&&winWidget) == shape-outside-inset-027.html shape-outside-inset-027-ref.html
 
 # Basic shape: polygon()
 == shape-outside-polygon-018.html shape-outside-polygon-018-ref.html
 == shape-outside-polygon-019.html shape-outside-polygon-019-ref.html
 == shape-outside-polygon-020.html shape-outside-polygon-020-ref.html
 == shape-outside-polygon-021.html shape-outside-polygon-021-ref.html
 == shape-outside-polygon-022.html shape-outside-polygon-022-ref.html
 == shape-outside-polygon-023.html shape-outside-polygon-023-ref.html
--- a/layout/reftests/writing-mode/reftest.list
+++ b/layout/reftests/writing-mode/reftest.list
@@ -64,17 +64,17 @@ fuzzy(116,94) fuzzy-if(winWidget,135,124
 == ua-style-sheet-fieldset-1.html ua-style-sheet-fieldset-1-ref.html
 skip-if(Android||winWidget) == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1a-ref.html
 skip-if(!(Android)) == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1b-ref.html
 skip-if(!winWidget) == ua-style-sheet-textarea-1.html ua-style-sheet-textarea-1c-ref.html
 fuzzy-if(Android,1,18) == ua-style-sheet-checkbox-radio-1.html ua-style-sheet-checkbox-radio-1-ref.html
 skip-if(Android) fuzzy-if(skiaContent&&!Android,2,6) == ua-style-sheet-button-1.html ua-style-sheet-button-1a-ref.html
 skip-if(!(Android)) == ua-style-sheet-button-1.html ua-style-sheet-button-1b-ref.html
 == ua-style-sheet-input-color-1.html ua-style-sheet-input-color-1-ref.html
-fuzzy-if(gtkWidget,1,15) == ua-style-sheet-input-number-1.html ua-style-sheet-input-number-1-ref.html
+fuzzy-if(gtkWidget,1,15) skip-if(stylo&&isDebugBuild) == ua-style-sheet-input-number-1.html ua-style-sheet-input-number-1-ref.html
 
 HTTP(..) == 1127488-align-default-horizontal-tb-ltr.html 1127488-align-top-left-ref.html
 HTTP(..) == 1127488-align-start-horizontal-tb-ltr.html 1127488-align-top-left-ref.html
 HTTP(..) == 1127488-align-end-horizontal-tb-ltr.html 1127488-align-top-right-ref.html
 HTTP(..) == 1127488-align-left-horizontal-tb-ltr.html 1127488-align-top-left-ref.html
 HTTP(..) == 1127488-align-right-horizontal-tb-ltr.html 1127488-align-top-right-ref.html
 HTTP(..) == 1127488-align-default-horizontal-tb-rtl.html 1127488-align-top-right-ref.html
 HTTP(..) == 1127488-align-start-horizontal-tb-rtl.html 1127488-align-top-right-ref.html
@@ -134,17 +134,17 @@ test-pref(dom.meta-viewport.enabled,true
 == 1151993-1-orthogonal-block-size.html 1151993-1-orthogonal-block-size-ref.html
 == 1152941-1-orthogonal-blocksize-overflow.html 1152941-1-orthogonal-blocksize-overflow-ref.html
 == 1156021-text-indent-percent.html 1156021-text-indent-percent-ref.html
 == 1157752-upright-bidi.html 1157752-upright-bidi-ref.html
 == 1157758-1-vertical-arabic.html 1157758-1-vertical-arabic-ref.html
 == 1158549-1-vertical-block-size-constraints.html 1158549-1-vertical-block-size-constraints-ref.html
 == 1163238-orthogonal-auto-margins.html 1163238-orthogonal-auto-margins-ref.html
 == 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html
-== 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html
+fails-if((stylo||styloVsGecko)&&cocoaWidget) == 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html
 == 1188061-1-nsChangeHint_ClearAncestorIntrinsics.html 1188061-1-nsChangeHint_ClearAncestorIntrinsics-ref.html
 == 1188061-2-nsChangeHint_UpdateComputedBSize.html 1188061-2-nsChangeHint_UpdateComputedBSize-ref.html
 
 # tests involving sideways-lr mode
 == 1193519-sideways-lr-1.html 1193519-sideways-lr-1-ref.html
 == 1193519-sideways-lr-2.html 1193519-sideways-lr-2-ref.html
 fuzzy-if(winWidget,3,84) == 1193519-sideways-lr-3.html 1193519-sideways-lr-3-ref.html
 fuzzy-if(winWidget,3,112) fails-if(webrender) == 1193519-sideways-lr-4.html 1193519-sideways-lr-4-ref.html # see bug 1366692. Rounding error with WR enabled.
--- a/layout/reftests/xul/reftest.list
+++ b/layout/reftests/xul/reftest.list
@@ -1,18 +1,18 @@
 == css-flex-1.xul css-flex-1-ref.html
 
 == menuitem-key.xul menuitem-key-ref.xul
 # these random-if(Android) are due to differences between Android Native & Xul, see bug 732569
 random-if(Android) == menulist-shrinkwrap-1.xul menulist-shrinkwrap-1-ref.xul
-random-if(Android) fails-if(winWidget) == menulist-shrinkwrap-2.xul menulist-shrinkwrap-2-ref.xul
+random-if(Android) fails-if(winWidget&&!styloVsGecko) == menulist-shrinkwrap-2.xul menulist-shrinkwrap-2-ref.xul
 == textbox-overflow-1.xul textbox-overflow-1-ref.xul # for bug 749658
 # accesskeys are not normally displayed on Mac, so skip this test
 skip-if(cocoaWidget) == accesskey.xul accesskey-ref.xul
-fails-if(cocoaWidget) fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,11) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # win8: bug 1254832
+fails-if(cocoaWidget&&!styloVsGecko) fuzzy-if(xulRuntime.widgetToolkit=="gtk3",1,11) == tree-row-outline-1.xul tree-row-outline-1-ref.xul # win8: bug 1254832
 skip-if(!cocoaWidget) == mac-tab-toolbar.xul mac-tab-toolbar-ref.xul
 != tree-row-outline-1.xul tree-row-outline-1-notref.xul
 == text-crop.xul text-crop-ref.xul
 == text-small-caps-1.xul text-small-caps-1-ref.xul
 fuzzy-if(skiaContent,1,60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,1,31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,1,50) == inactive-fixed-bg-bug1205630.xul inactive-fixed-bg-bug1205630-ref.html
 fuzzy-if(skiaContent,1,60) fuzzy-if(cocoaWidget&&browserIsRemote&&!skiaContent,1,31) fuzzy-if(winWidget&&browserIsRemote&&layersGPUAccelerated,1,50) == inactive-fixed-bg-bug1272525.xul inactive-fixed-bg-bug1272525-ref.html
 
 # Tests for XUL <image> with 'object-fit' & 'object-position':
new file mode 100644
--- /dev/null
+++ b/layout/style/CSSFontFeatureValuesRule.cpp
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/dom/CSSFontFeatureValuesRule.h"
+#include "mozilla/dom/CSSFontFeatureValuesRuleBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_ADDREF_INHERITED(CSSFontFeatureValuesRule, css::Rule)
+NS_IMPL_RELEASE_INHERITED(CSSFontFeatureValuesRule, css::Rule)
+
+// QueryInterface implementation for CSSFontFeatureValuesRule
+// If this ever gets its own cycle-collection bits, reevaluate our IsCCLeaf
+// implementation.
+NS_INTERFACE_MAP_BEGIN(CSSFontFeatureValuesRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
+NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
+
+void
+CSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFamily,
+                                              ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void
+CSSFontFeatureValuesRule::SetValueText(const nsAString& aFamily,
+                                             ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+bool
+CSSFontFeatureValuesRule::IsCCLeaf() const
+{
+  return Rule::IsCCLeaf();
+}
+
+/* virtual */ JSObject*
+CSSFontFeatureValuesRule::WrapObject(JSContext* aCx,
+                                       JS::Handle<JSObject*> aGivenProto)
+{
+  return CSSFontFeatureValuesRuleBinding::Wrap(aCx, this, aGivenProto);
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/style/CSSFontFeatureValuesRule.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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_dom_CSSFontFeatureValuesRule_h
+#define mozilla_dom_CSSFontFeatureValuesRule_h
+
+#include "mozilla/css/Rule.h"
+
+#include "nsICSSDeclaration.h"
+#include "nsIDOMCSSFontFeatureValuesRule.h"
+#include "nsIDOMCSSStyleDeclaration.h"
+
+namespace mozilla {
+namespace dom {
+
+class CSSFontFeatureValuesRule : public css::Rule
+                               , public nsIDOMCSSFontFeatureValuesRule
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+
+  virtual bool IsCCLeaf() const override;
+
+  int32_t GetType() const final { return Rule::FONT_FEATURE_VALUES_RULE; }
+  using Rule::GetType;
+  virtual already_AddRefed<mozilla::css::Rule> Clone() const override = 0;
+
+  using nsIDOMCSSFontFeatureValuesRule::SetFontFamily;
+  using nsIDOMCSSFontFeatureValuesRule::SetValueText;
+  // WebIDL interfaces
+  uint16_t Type() const final { return nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE; }
+  virtual void GetCssTextImpl(nsAString& aCssText) const override = 0;
+  // The XPCOM GetFontFamily is fine
+  void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv);
+  // The XPCOM GetValueText is fine
+  void SetValueText(const nsAString& aFamily, mozilla::ErrorResult& aRv);
+
+  virtual size_t
+  SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
+
+  JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
+protected:
+  using Rule::Rule;
+
+  virtual ~CSSFontFeatureValuesRule() {};
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_CSSFontFeatureValuesRule_h
--- a/layout/style/ServoArcTypeList.h
+++ b/layout/style/ServoArcTypeList.h
@@ -15,9 +15,10 @@ SERVO_ARC_TYPE(AnimationValue, RawServoA
 SERVO_ARC_TYPE(Keyframe, RawServoKeyframe)
 SERVO_ARC_TYPE(KeyframesRule, RawServoKeyframesRule)
 SERVO_ARC_TYPE(MediaList, RawServoMediaList)
 SERVO_ARC_TYPE(MediaRule, RawServoMediaRule)
 SERVO_ARC_TYPE(NamespaceRule, RawServoNamespaceRule)
 SERVO_ARC_TYPE(PageRule, RawServoPageRule)
 SERVO_ARC_TYPE(SupportsRule, RawServoSupportsRule)
 SERVO_ARC_TYPE(DocumentRule, RawServoDocumentRule)
+SERVO_ARC_TYPE(FontFeatureValuesRule, RawServoFontFeatureValuesRule)
 SERVO_ARC_TYPE(RuleNode, RawServoRuleNode)
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -132,16 +132,17 @@ BASIC_RULE_FUNCS(Style)
 BASIC_RULE_FUNCS(Import)
 BASIC_RULE_FUNCS_WITHOUT_GETTER(Keyframe)
 BASIC_RULE_FUNCS(Keyframes)
 GROUP_RULE_FUNCS(Media)
 BASIC_RULE_FUNCS(Namespace)
 BASIC_RULE_FUNCS(Page)
 GROUP_RULE_FUNCS(Supports)
 GROUP_RULE_FUNCS(Document)
+BASIC_RULE_FUNCS(FontFeatureValues)
 #undef GROUP_RULE_FUNCS
 #undef BASIC_RULE_FUNCS
 #undef BASIC_RULE_FUNCS_WITHOUT_GETTER
 SERVO_BINDING_FUNC(Servo_CssRules_GetFontFaceRuleAt, nsCSSFontFaceRule*,
                    ServoCssRulesBorrowed rules, uint32_t index)
 SERVO_BINDING_FUNC(Servo_CssRules_GetCounterStyleRuleAt, nsCSSCounterStyleRule*,
                    ServoCssRulesBorrowed rules, uint32_t index)
 SERVO_BINDING_FUNC(Servo_StyleRule_GetStyle, RawServoDeclarationBlockStrong,
@@ -206,16 +207,22 @@ SERVO_BINDING_FUNC(Servo_PageRule_GetSty
                    RawServoPageRuleBorrowed rule)
 SERVO_BINDING_FUNC(Servo_PageRule_SetStyle, void,
                    RawServoPageRuleBorrowed rule,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_SupportsRule_GetConditionText, void,
                    RawServoSupportsRuleBorrowed rule, nsAString* result)
 SERVO_BINDING_FUNC(Servo_DocumentRule_GetConditionText, void,
                    RawServoDocumentRuleBorrowed rule, nsAString* result)
+SERVO_BINDING_FUNC(Servo_FontFeatureValuesRule_GetFontFamily, void,
+                   RawServoFontFeatureValuesRuleBorrowed rule,
+                   nsAString* result)
+SERVO_BINDING_FUNC(Servo_FontFeatureValuesRule_GetValueText, void,
+                   RawServoFontFeatureValuesRuleBorrowed rule,
+                   nsAString* result)
 
 // Animations API
 SERVO_BINDING_FUNC(Servo_ParseProperty,
                    RawServoDeclarationBlockStrong,
                    nsCSSPropertyID property, const nsACString* value,
                    RawGeckoURLExtraData* data,
                    mozilla::ParsingMode parsing_mode,
                    nsCompatibility quirks_mode,
@@ -490,22 +497,24 @@ SERVO_BINDING_FUNC(Servo_Initialize, voi
 SERVO_BINDING_FUNC(Servo_Shutdown, void)
 
 // Restyle and change hints.
 SERVO_BINDING_FUNC(Servo_NoteExplicitHints, void, RawGeckoElementBorrowed element,
                    nsRestyleHint restyle_hint, nsChangeHint change_hint)
 SERVO_BINDING_FUNC(Servo_TakeChangeHint,
                    nsChangeHint,
                    RawGeckoElementBorrowed element,
-                   mozilla::TraversalRestyleBehavior restyle_behavior,
+                   mozilla::ServoTraversalFlags flags,
                    bool* was_restyled)
 SERVO_BINDING_FUNC(Servo_ResolveStyle, ServoStyleContextStrong,
                    RawGeckoElementBorrowed element,
                    RawServoStyleSetBorrowed set,
-                   mozilla::TraversalRestyleBehavior restyle_behavior)
+                   mozilla::ServoTraversalFlags flags)
+SERVO_BINDING_FUNC(Servo_ResolveStyleAllowStale, ServoStyleContextStrong,
+                   RawGeckoElementBorrowed element)
 SERVO_BINDING_FUNC(Servo_ResolvePseudoStyle, ServoStyleContextStrong,
                    RawGeckoElementBorrowed element,
                    mozilla::CSSPseudoElementType pseudo_type,
                    bool is_probe,
                    ServoStyleContextBorrowedOrNull inherited_style,
                    RawServoStyleSetBorrowed set)
 SERVO_BINDING_FUNC(Servo_SetExplicitStyle, void,
                    RawGeckoElementBorrowed element,
@@ -532,18 +541,17 @@ SERVO_BINDING_FUNC(Servo_ResolveStyleLaz
 
 // Use ServoStyleSet::PrepareAndTraverseSubtree instead of calling this
 // directly
 SERVO_BINDING_FUNC(Servo_TraverseSubtree,
                    bool,
                    RawGeckoElementBorrowed root,
                    RawServoStyleSetBorrowed set,
                    const mozilla::ServoElementSnapshotTable* snapshots,
-                   mozilla::TraversalRootBehavior root_behavior,
-                   mozilla::TraversalRestyleBehavior restyle_behavior)
+                   mozilla::ServoTraversalFlags flags)
 
 // Assert that the tree has no pending or unconsumed restyles.
 SERVO_BINDING_FUNC(Servo_AssertTreeIsClean, void, RawGeckoElementBorrowed root)
 
 // Checks whether the rule tree has crossed its threshold for unused rule nodes,
 // and if so, frees them.
 SERVO_BINDING_FUNC(Servo_MaybeGCRuleTree, void, RawServoStyleSetBorrowed set)
 
@@ -568,17 +576,15 @@ SERVO_BINDING_FUNC(Servo_GetCustomProper
 
 SERVO_BINDING_FUNC(Servo_GetCustomPropertiesCount, uint32_t,
                    ServoStyleContextBorrowed computed_values)
 
 SERVO_BINDING_FUNC(Servo_GetCustomPropertyNameAt, bool,
                    ServoStyleContextBorrowed, uint32_t index,
                    nsAString* name)
 
-SERVO_BINDING_FUNC(Servo_GetEmptyVariables, const nsStyleVariables*)
-
 
 // AddRef / Release functions
 #define SERVO_ARC_TYPE(name_, type_)                                \
   SERVO_BINDING_FUNC(Servo_##name_##_AddRef, void, type_##Borrowed) \
   SERVO_BINDING_FUNC(Servo_##name_##_Release, void, type_##Borrowed)
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -232,17 +232,18 @@ ServoComputedData::ServoComputedData(
     const ServoComputedDataForgotten aValue)
 {
   PodAssign(this, aValue.mPtr);
 }
 
 const nsStyleVariables*
 ServoComputedData::GetStyleVariables() const
 {
-  return Servo_GetEmptyVariables();
+  MOZ_CRASH("ServoComputedData::GetStyleVariables should never need to be "
+            "called");
 }
 
 void
 Gecko_ServoStyleContext_Destroy(ServoStyleContext* aContext)
 {
   aContext->~ServoStyleContext();
 }
 
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -88,16 +88,17 @@ hide-types = [
 bitfield-enums = [
     "nsChangeHint",
     "nsRestyleHint",
 ]
 constified-enums = [
     "UpdateAnimationsTasks",
     "ParsingMode",
     "ThemeWidgetType",
+    "ServoTraversalFlags",
 ]
 constified-enum-variants = [
     { enum = "nsCSSPropertyID", variants = ["eCSSProperty_COUNT.*"] },
 ]
 whitelist-vars = [
     "NS_AUTHOR_SPECIFIED_.*",
     "NS_THEME_.*",
     "NODE_.*",
@@ -121,24 +122,25 @@ whitelist-types = [
     "mozilla::ComputedTiming",
     "mozilla::ComputedTimingFunction",
     "mozilla::ComputedTimingFunction::BeforeFlag",
     "mozilla::ServoElementSnapshot.*",
     "mozilla::ServoStyleContext",
     "mozilla::ServoStyleSheetInner",
     "mozilla::CSSPseudoClassType",
     "mozilla::css::ErrorReporter",
+    "mozilla::css::LoaderReusableStyleSheets",
     "mozilla::css::SheetParsingMode",
     "mozilla::css::URLMatchingFunction",
     "mozilla::dom::IterationCompositeOperation",
     "mozilla::dom::StyleChildrenIterator",
     "mozilla::HalfCorner",
+    "mozilla::MallocSizeOf",
     "mozilla::PropertyStyleAnimationValuePair",
-    "mozilla::TraversalRestyleBehavior",
-    "mozilla::TraversalRootBehavior",
+    "mozilla::ServoTraversalFlags",
     "mozilla::StyleShapeRadius",
     "mozilla::StyleGrid.*",
     "mozilla::UpdateAnimationsTasks",
     "mozilla::LookAndFeel",
     "mozilla::gfx::Float",
     "mozilla::gfx::FontVariation",
     ".*ThreadSafe.*Holder",
     "AnonymousContent",
@@ -164,16 +166,17 @@ whitelist-types = [
     "Image",
     "ImageURL",
     "Keyframe",
     "nsAttrName",
     "nsAttrValue",
     "nsBorderColors",
     "nscolor",
     "nsChangeHint",
+    "nsCSSCounterDesc",
     "nsCSSCounterStyleRule",
     "nsCSSFontFaceRule",
     "nsCSSKeyword",
     "nsCSSPropertyID",
     "nsCSSPropertyIDSet",
     "nsCSSProps",
     "nsCSSRect",
     "nsCSSRect_heap",
@@ -381,18 +384,17 @@ structs-types = [
     "RawGeckoStyleAnimationList",
     "RawGeckoStyleChildrenIteratorBorrowedMut",
     "RawGeckoServoStyleRuleList",
     "RawGeckoURLExtraData",
     "RawGeckoXBLBinding",
     "RefPtr",
     "CSSPseudoClassType",
     "CSSPseudoElementType",
-    "TraversalRestyleBehavior",
-    "TraversalRootBehavior",
+    "ServoTraversalFlags",
     "ComputedTimingFunction_BeforeFlag",
     "CounterStylePtr",
     "FontFamilyList",
     "FontFamilyType",
     "FontSizePrefs",
     "GeckoFontMetrics",
     "IterationCompositeOperation",
     "Keyframe",
--- a/layout/style/ServoCSSRuleList.cpp
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -7,16 +7,17 @@
 /* representation of CSSRuleList for stylo */
 
 #include "mozilla/ServoCSSRuleList.h"
 
 #include "mozilla/IntegerRange.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/ServoDocumentRule.h"
 #include "mozilla/ServoImportRule.h"
+#include "mozilla/ServoFontFeatureValuesRule.h"
 #include "mozilla/ServoKeyframesRule.h"
 #include "mozilla/ServoMediaRule.h"
 #include "mozilla/ServoNamespaceRule.h"
 #include "mozilla/ServoPageRule.h"
 #include "mozilla/ServoStyleRule.h"
 #include "mozilla/ServoStyleSheet.h"
 #include "mozilla/ServoSupportsRule.h"
 #include "nsCSSCounterStyleRule.h"
@@ -103,16 +104,17 @@ ServoCSSRuleList::GetRule(uint32_t aInde
       CASE_RULE(STYLE, Style)
       CASE_RULE(KEYFRAMES, Keyframes)
       CASE_RULE(MEDIA, Media)
       CASE_RULE(NAMESPACE, Namespace)
       CASE_RULE(PAGE, Page)
       CASE_RULE(SUPPORTS, Supports)
       CASE_RULE(DOCUMENT, Document)
       CASE_RULE(IMPORT, Import)
+      CASE_RULE(FONT_FEATURE_VALUES, FontFeatureValues)
 #undef CASE_RULE
       // For @font-face and @counter-style rules, the function returns
       // a borrowed Gecko rule object directly, so we don't need to
       // create anything here. But we still need to have the style sheet
       // and parent rule set properly.
       case nsIDOMCSSRule::FONT_FACE_RULE: {
         ruleObj = Servo_CssRules_GetFontFaceRuleAt(mRawRules, aIndex);
         break;
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoFontFeatureValuesRule.cpp
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* representation of CSSFontFeatureValuesRule for stylo */
+
+#include "mozilla/ServoFontFeatureValuesRule.h"
+
+#include "mozilla/ServoBindings.h"
+
+using namespace mozilla::dom;
+
+namespace mozilla {
+
+ServoFontFeatureValuesRule::ServoFontFeatureValuesRule(
+  RefPtr<RawServoFontFeatureValuesRule> aRawRule,
+  uint32_t aLine, uint32_t aColumn)
+  : CSSFontFeatureValuesRule(aLine, aColumn)
+  , mRawRule(Move(aRawRule))
+{
+}
+
+ServoFontFeatureValuesRule::~ServoFontFeatureValuesRule()
+{
+}
+
+NS_IMPL_ADDREF_INHERITED(ServoFontFeatureValuesRule, CSSFontFeatureValuesRule)
+NS_IMPL_RELEASE_INHERITED(ServoFontFeatureValuesRule, CSSFontFeatureValuesRule)
+
+// QueryInterface implementation for FontFeatureValuesRule
+NS_INTERFACE_MAP_BEGIN(ServoFontFeatureValuesRule)
+NS_INTERFACE_MAP_END_INHERITING(CSSFontFeatureValuesRule)
+
+already_AddRefed<css::Rule>
+ServoFontFeatureValuesRule::Clone() const
+{
+  // Rule::Clone is only used when CSSStyleSheetInner is cloned in
+  // preparation of being mutated. However, ServoStyleSheet never clones
+  // anything, so this method should never be called.
+  MOZ_ASSERT_UNREACHABLE("Shouldn't be cloning ServoFontFeatureValuesRule");
+  return nullptr;
+}
+
+size_t
+ServoFontFeatureValuesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
+#ifdef DEBUG
+void
+ServoFontFeatureValuesRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_FontFeatureValuesRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+/* CSSRule implementation */
+
+void
+ServoFontFeatureValuesRule::GetCssTextImpl(nsAString& aCssText) const
+{
+  Servo_FontFeatureValuesRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* CSSFontFeatureValuesRule implementation */
+
+NS_IMETHODIMP
+ServoFontFeatureValuesRule::GetFontFamily(nsAString& aFamilyListStr)
+{
+  Servo_FontFeatureValuesRule_GetFontFamily(mRawRule, &aFamilyListStr);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ServoFontFeatureValuesRule::GetValueText(nsAString& aValueText)
+{
+  Servo_FontFeatureValuesRule_GetValueText(mRawRule, &aValueText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ServoFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+ServoFontFeatureValuesRule::SetValueText(const nsAString& aValueText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/style/ServoFontFeatureValuesRule.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* representation of CSSFontFeatureValuesRule for stylo */
+
+#ifndef mozilla_ServoFontFeatureValuesRule_h
+#define mozilla_ServoFontFeatureValuesRule_h
+
+#include "mozilla/dom/CSSFontFeatureValuesRule.h"
+#include "mozilla/ServoBindingTypes.h"
+
+namespace mozilla {
+
+class ServoFontFeatureValuesRule final : public dom::CSSFontFeatureValuesRule
+{
+public:
+  ServoFontFeatureValuesRule(RefPtr<RawServoFontFeatureValuesRule> aRawRule,
+                             uint32_t aLine, uint32_t aColumn);
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  RawServoFontFeatureValuesRule* Raw() const { return mRawRule; }
+
+  // nsIDOMCSSFontFeatureValuesRule interface
+  NS_DECL_NSIDOMCSSFONTFEATUREVALUESRULE
+
+  // WebIDL interface
+  void GetCssTextImpl(nsAString& aCssText) const override;
+
+  // Methods of mozilla::css::Rule
+  already_AddRefed<css::Rule> Clone() const final;
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
+    const final;
+
+  #ifdef DEBUG
+    void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+  #endif
+
+private:
+  ~ServoFontFeatureValuesRule();
+
+  RefPtr<RawServoFontFeatureValuesRule> mRawRule;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_ServoFontFeatureValuesRule_h
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -177,17 +177,17 @@ ServoStyleSet::ResolveStyleFor(Element* 
 {
   RefPtr<ServoStyleContext> computedValues;
   if (aMayCompute == LazyComputeBehavior::Allow) {
     PreTraverseSync();
     return ResolveStyleLazily(
         aElement, CSSPseudoElementType::NotPseudo, nullptr, aParentContext);
   }
 
-  return ResolveServoStyle(aElement, TraversalRestyleBehavior::Normal);
+  return ResolveServoStyle(aElement, ServoTraversalFlags::Empty);
 }
 
 
 const ServoElementSnapshotTable&
 ServoStyleSet::Snapshots()
 {
   return mPresContext->RestyleManager()->AsServo()->Snapshots();
 }
@@ -265,46 +265,38 @@ ServoStyleSet::PreTraverse(Element* aRoo
       smilController->PreTraverse();
     }
   }
 }
 
 bool
 ServoStyleSet::PrepareAndTraverseSubtree(
   RawGeckoElementBorrowed aRoot,
-  TraversalRootBehavior aRootBehavior,
-  TraversalRestyleBehavior aRestyleBehavior)
+  ServoTraversalFlags aFlags)
 {
-  bool forThrottledAnimationFlush =
-    aRestyleBehavior == TraversalRestyleBehavior::ForThrottledAnimationFlush;
+  MOZ_ASSERT(MayTraverseFrom(const_cast<Element*>(aRoot)));
+  bool forThrottledAnimationFlush = !!(aFlags & ServoTraversalFlags::AnimationOnly);
 
-  AutoRestyleTimelineMarker marker(
-    mPresContext->GetDocShell(), forThrottledAnimationFlush);
+  AutoRestyleTimelineMarker marker(mPresContext->GetDocShell(), forThrottledAnimationFlush);
 
   // Get the Document's root element to ensure that the cache is valid before
   // calling into the (potentially-parallel) Servo traversal, where a cache hit
   // is necessary to avoid a data race when updating the cache.
   mozilla::Unused << aRoot->OwnerDoc()->GetRootElement();
 
   MOZ_ASSERT(!StylistNeedsUpdate());
   AutoSetInServoTraversal guard(this);
 
   const SnapshotTable& snapshots = Snapshots();
 
   bool isInitial = !aRoot->HasServoData();
-  bool forReconstruct =
-    aRestyleBehavior == TraversalRestyleBehavior::ForReconstruct;
-#ifdef DEBUG
-  bool forNewlyBoundElement =
-    aRestyleBehavior == TraversalRestyleBehavior::ForNewlyBoundElement;
-#endif
-  bool postTraversalRequired = Servo_TraverseSubtree(
-    aRoot, mRawSet.get(), &snapshots, aRootBehavior, aRestyleBehavior);
-  MOZ_ASSERT(!(isInitial || forReconstruct || forNewlyBoundElement) ||
-             !postTraversalRequired);
+  bool forReconstruct = !!(aFlags & ServoTraversalFlags::AggressivelyForgetful);
+  bool postTraversalRequired =
+    Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags);
+  MOZ_ASSERT(!(isInitial || forReconstruct) || !postTraversalRequired);
 
   // We don't need to trigger a second traversal if this restyle only for
   // flushing throttled animations. That's because the first traversal only
   // performs the animation-only restyle, skipping the normal restyle, and so
   // will not generate any SequentialTask that could update animation state
   // requiring a subsequent traversal.
   if (forThrottledAnimationFlush) {
     return postTraversalRequired;
@@ -319,18 +311,17 @@ ServoStyleSet::PrepareAndTraverseSubtree
   // values once at the begin of a tick. As a result, even if the previous
   // traversal caused, for example, the font-size to change, the SMIL style
   // won't be updated until the next tick anyway.
   EffectCompositor* compositor = mPresContext->EffectCompositor();
   EffectCompositor::AnimationRestyleType restyleType =
     EffectCompositor::AnimationRestyleType::Throttled;
   if (forReconstruct ? compositor->PreTraverseInSubtree(root, restyleType)
                      : compositor->PreTraverse(restyleType)) {
-    if (Servo_TraverseSubtree(
-          aRoot, mRawSet.get(), &snapshots, aRootBehavior, aRestyleBehavior)) {
+    if (Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, aFlags)) {
       MOZ_ASSERT(!forReconstruct);
       if (isInitial) {
         // We're doing initial styling, and the additional animation
         // traversal changed the styles that were set by the first traversal.
         // This would normally require a post-traversal to update the style
         // contexts, and the DOM now has dirty descendant bits and RestyleData
         // in expectation of that post-traversal. But since this is actually
         // the initial styling, there are no style contexts to update and no
@@ -415,17 +406,17 @@ ServoStyleSet::ResolvePseudoElementStyle
 
   RefPtr<ServoStyleContext> computedValues;
 
   if (aPseudoElement) {
     MOZ_ASSERT(aType == aPseudoElement->GetPseudoElementType());
     computedValues =
       Servo_ResolveStyle(aPseudoElement,
                          mRawSet.get(),
-                         TraversalRestyleBehavior::Normal).Consume();
+                         ServoTraversalFlags::Empty).Consume();
   } else {
     computedValues =
       Servo_ResolvePseudoStyle(aOriginatingElement,
                                aType,
                                /* is_probe = */ false,
                                aParentContext,
                                mRawSet.get()).Consume();
   }
@@ -777,121 +768,88 @@ ServoStyleSet::HasStateDependentStyle(do
                                       dom::Element* aPseudoElement,
                                       EventStates aStateMask)
 {
   NS_WARNING("stylo: HasStateDependentStyle always returns zero!");
   return nsRestyleHint(0);
 }
 
 bool
-ServoStyleSet::StyleDocument(TraversalRestyleBehavior aRestyleBehavior)
+ServoStyleSet::StyleDocument(ServoTraversalFlags aFlags)
 {
-  MOZ_ASSERT(
-    aRestyleBehavior == TraversalRestyleBehavior::Normal ||
-    aRestyleBehavior == TraversalRestyleBehavior::ForCSSRuleChanges,
-    "StyleDocument() should be only called for normal traversal or CSS rule "
-    "changes");
-
-  PreTraverse();
+  if (!!(aFlags & ServoTraversalFlags::AnimationOnly)) {
+    PreTraverse(nullptr, EffectCompositor::AnimationRestyleType::Full);
+  } else {
+    PreTraverse();
+  }
 
   // Restyle the document from the root element and each of the document level
   // NAC subtree roots.
   bool postTraversalRequired = false;
   DocumentStyleRootIterator iter(mPresContext->Document());
   while (Element* root = iter.GetNextStyleRoot()) {
-    if (PrepareAndTraverseSubtree(root,
-                                  TraversalRootBehavior::Normal,
-                                  aRestyleBehavior)) {
-      postTraversalRequired = true;
-    }
-  }
-  return postTraversalRequired;
-}
-
-bool
-ServoStyleSet::StyleDocumentForThrottledAnimationFlush()
-{
-  PreTraverse(nullptr, EffectCompositor::AnimationRestyleType::Full);
-
-  bool postTraversalRequired = false;
-  DocumentStyleRootIterator iter(mPresContext->Document());
-  while (Element* root = iter.GetNextStyleRoot()) {
-    if (PrepareAndTraverseSubtree(
-          root,
-          TraversalRootBehavior::Normal,
-          TraversalRestyleBehavior::ForThrottledAnimationFlush)) {
+    if (PrepareAndTraverseSubtree(root, aFlags)) {
       postTraversalRequired = true;
     }
   }
   return postTraversalRequired;
 }
 
 void
 ServoStyleSet::StyleNewSubtree(Element* aRoot)
 {
   MOZ_ASSERT(!aRoot->HasServoData());
 
   PreTraverse();
 
   DebugOnly<bool> postTraversalRequired =
-    PrepareAndTraverseSubtree(aRoot,
-                              TraversalRootBehavior::Normal,
-                              TraversalRestyleBehavior::Normal);
+    PrepareAndTraverseSubtree(aRoot, ServoTraversalFlags::Empty);
   MOZ_ASSERT(!postTraversalRequired);
 }
 
 void
 ServoStyleSet::StyleNewChildren(Element* aParent)
 {
   PreTraverse();
 
-  PrepareAndTraverseSubtree(aParent,
-                            TraversalRootBehavior::UnstyledChildrenOnly,
-                            TraversalRestyleBehavior::Normal);
+  PrepareAndTraverseSubtree(aParent, ServoTraversalFlags::UnstyledChildrenOnly);
   // We can't assert that Servo_TraverseSubtree returns false, since aParent
   // or some of its other children might have pending restyles.
 }
 
 void
 ServoStyleSet::StyleNewlyBoundElement(Element* aElement)
 {
   PreTraverse();
 
   // In general the element is always styled by the time we're applying XBL
   // bindings, because we need to style the element to know what the binding
   // URI is. However, programmatic consumers of the XBL service (like the
   // XML pretty printer) _can_ apply bindings without having styled the bound
   // element. We could assert against this and require the callers manually
   // resolve the style first, but it's easy enough to just handle here.
-  //
-  // Also, when applying XBL bindings to elements within a display:none or
-  // unstyled subtree (for example, when <object> elements are wrapped to be
-  // exposed to JS), we need to tell the traversal that it is OK to
-  // skip restyling, rather than panic when trying to unwrap the styles
-  // it expects to have just computed.
 
-  TraversalRootBehavior rootBehavior =
-    MOZ_UNLIKELY(!aElement->HasServoData())
-      ? TraversalRootBehavior::Normal
-      : TraversalRootBehavior::UnstyledChildrenOnly;
+  ServoTraversalFlags flags = (MOZ_UNLIKELY(!aElement->HasServoData())
+      ? ServoTraversalFlags::Empty
+      : ServoTraversalFlags::UnstyledChildrenOnly);
 
-  PrepareAndTraverseSubtree(aElement,
-                            rootBehavior,
-                            TraversalRestyleBehavior::ForNewlyBoundElement);
+  PrepareAndTraverseSubtree(aElement, flags);
 }
 
 void
 ServoStyleSet::StyleSubtreeForReconstruct(Element* aRoot)
 {
   PreTraverse(aRoot);
 
+  auto flags = ServoTraversalFlags::Forgetful |
+               ServoTraversalFlags::AggressivelyForgetful |
+               ServoTraversalFlags::ClearDirtyDescendants |
+               ServoTraversalFlags::ClearAnimationOnlyDirtyDescendants;
   DebugOnly<bool> postTraversalRequired =
-    PrepareAndTraverseSubtree(aRoot,
-                              TraversalRootBehavior::Normal,
-                              TraversalRestyleBehavior::ForReconstruct);
+    PrepareAndTraverseSubtree(aRoot, flags);
   MOZ_ASSERT(!postTraversalRequired);
 }
 
 void
 ServoStyleSet::ForceAllStyleDirty()
 {
   SetStylistStyleSheetsDirty();
   Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get(), mAuthorStyleDisabled);
@@ -1080,24 +1038,23 @@ UpdateBodyTextColorIfNeeded(
   // NOTE(emilio): We do the ComputedData() dance to avoid triggering the
   // IsInServoTraversal() assertion in StyleColor(), which seems useful enough
   // in the general case, I guess...
   aPresContext.SetBodyTextColor(
       aStyleContext.ComputedData()->GetStyleColor()->mColor);
 }
 
 already_AddRefed<ServoStyleContext>
-ServoStyleSet::ResolveServoStyle(Element* aElement,
-                                 TraversalRestyleBehavior aRestyleBehavior)
+ServoStyleSet::ResolveServoStyle(Element* aElement, ServoTraversalFlags aFlags)
 {
   UpdateStylistIfNeeded();
   RefPtr<ServoStyleContext> result =
     Servo_ResolveStyle(aElement,
                        mRawSet.get(),
-                       aRestyleBehavior).Consume();
+                       aFlags).Consume();
   UpdateBodyTextColorIfNeeded(*aElement, *result, *mPresContext);
   return result.forget();
 }
 
 void
 ServoStyleSet::ClearNonInheritingStyleContexts()
 {
   for (RefPtr<ServoStyleContext>& ptr : mNonInheritingStyleContexts) {
@@ -1224,16 +1181,33 @@ ServoStyleSet::UpdateStylist()
 
 void
 ServoStyleSet::MaybeGCRuleTree()
 {
   MOZ_ASSERT(NS_IsMainThread());
   Servo_MaybeGCRuleTree(mRawSet.get());
 }
 
+bool
+ServoStyleSet::MayTraverseFrom(Element* aElement)
+{
+  MOZ_ASSERT(aElement->IsInComposedDoc());
+  Element* parent = aElement->GetFlattenedTreeParentElementForStyle();
+  if (!parent) {
+    return true;
+  }
+
+  if (!parent->HasServoData()) {
+    return false;
+  }
+
+  RefPtr<ServoStyleContext> sc = Servo_ResolveStyleAllowStale(parent).Consume();
+  return sc->StyleDisplay()->mDisplay != StyleDisplay::None;
+}
+
 void
 ServoStyleSet::PrependSheetOfType(SheetType aType,
                                   ServoStyleSheet* aSheet)
 {
   aSheet->AddStyleSet(this);
   mSheets[aType].InsertElementAt(0, aSheet);
 }
 
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -259,33 +259,23 @@ public:
 
   /**
    * Performs a Servo traversal to compute style for all dirty nodes in the
    * document.
    *
    * This will traverse all of the document's style roots (that is, its document
    * element, and the roots of the document-level native anonymous content).
    *
-   * |aRestyleBehavior| should be `Normal` or `ForCSSRuleChanges`.
-   * We need to specify |ForCSSRuleChanges| to try to update all CSS animations
+   * We specify |ForCSSRuleChanges| to try to update all CSS animations
    * when we call this function due to CSS rule changes since @keyframes rules
    * may have changed.
    *
    * Returns true if a post-traversal is required.
    */
-  bool StyleDocument(TraversalRestyleBehavior aRestyleBehavior);
-
-  /**
-   * Performs a Servo animation-only traversal to compute style for all nodes
-   * with the animation-only dirty bit in the document.
-   *
-   * This will traverse all of the document's style roots (that is, its document
-   * element, and the roots of the document-level native anonymous content).
-   */
-  bool StyleDocumentForThrottledAnimationFlush();
+  bool StyleDocument(ServoTraversalFlags aFlags);
 
   /**
    * Eagerly styles a subtree of unstyled nodes that was just appended to the
    * tree. This is used in situations where we need the style immediately and
    * cannot wait for a future batch restyle.
    */
   void StyleNewSubtree(dom::Element* aRoot);
 
@@ -334,16 +324,25 @@ public:
   }
 
   /**
    * Checks whether the rule tree has crossed its threshold for unused nodes,
    * and if so, frees them.
    */
   void MaybeGCRuleTree();
 
+  /**
+   * Returns true if the given element may be used as the root of a style
+   * traversal. Reasons for false include having an unstyled parent, or having
+   * a parent that is display:none.
+   *
+   * Most traversal callsites don't need to check this, but some do.
+   */
+  bool MayTraverseFrom(dom::Element* aElement);
+
 #ifdef DEBUG
   void AssertTreeIsClean();
 #else
   void AssertTreeIsClean() {}
 #endif
 
   /**
    * Clears the style data, both style sheet data and cached non-inheriting
@@ -359,18 +358,17 @@ public:
 
   /**
    * Resolve style for the given element, and return it as a
    * ServoStyleContext.
    *
    * FIXME(emilio): Is there a point in this after bug 1367904?
    */
   already_AddRefed<ServoStyleContext>
-  ResolveServoStyle(dom::Element* aElement,
-                    TraversalRestyleBehavior aRestyleBehavior);
+  ResolveServoStyle(dom::Element* aElement, ServoTraversalFlags aFlags);
 
   bool GetKeyframesForName(const nsString& aName,
                            const nsTimingFunction& aTimingFunction,
                            nsTArray<Keyframe>& aKeyframes);
 
   nsTArray<ComputedKeyframeValues>
   GetComputedKeyframeValuesFor(const nsTArray<Keyframe>& aKeyframes,
                                dom::Element* aElement,
@@ -502,18 +500,17 @@ private:
 
   /**
    * Perform all lazy operations required before traversing
    * a subtree.
    *
    * Returns whether a post-traversal is required.
    */
   bool PrepareAndTraverseSubtree(RawGeckoElementBorrowed aRoot,
-                                 TraversalRootBehavior aRootBehavior,
-                                 TraversalRestyleBehavior aRestyleBehavior);
+                                 ServoTraversalFlags aFlags);
 
   /**
    * Clear our cached mNonInheritingStyleContexts.
    *
    * We do this when we want to make sure those style contexts won't live too
    * long (e.g. when rebuilding all style data or when shutting down the style
    * set).
    */
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -44,51 +44,40 @@ struct ServoCell {
 // Indicates whether the Servo style system should expect the style on an element
 // to have already been resolved (i.e. via a parallel traversal), or whether it
 // may be lazily computed.
 enum class LazyComputeBehavior {
   Allow,
   Assert,
 };
 
-// Indicates whether the Servo style system should perform normal processing or
-// whether it should only process unstyled children of the root and their
-// descendants.
-enum class TraversalRootBehavior {
-  Normal,
-  UnstyledChildrenOnly,
+// Various flags for the servo traversal.
+enum class ServoTraversalFlags : uint32_t {
+  Empty = 0,
+  // Perform animation processing but not regular styling.
+  AnimationOnly = 1 << 0,
+  // Traverses as normal mode but tries to update all CSS animations.
+  ForCSSRuleChanges = 1 << 1,
+  // Traverse only unstyled children of the root (and their descendants).
+  UnstyledChildrenOnly = 1 << 2,
+  // A forgetful traversal ignores the previous state of the frame tree, and
+  // thus does not compute damage or maintain other state describing the styles
+  // pre-traversal. A forgetful traversal is usually the right thing if you
+  // aren't going to do a post-traversal.
+  Forgetful = 1 << 3,
+  // Actively seeks out and clears change hints that may have been posted into
+  // the tree. Nonsensical without also passing Forgetful.
+  AggressivelyForgetful = 1 << 4,
+  // Clears the dirty descendants bit in the subtree.
+  ClearDirtyDescendants = 1 << 5,
+  // Clears the animation-only dirty descendants bit in the subtree.
+  ClearAnimationOnlyDirtyDescendants = 1 << 6,
 };
 
-// Indicates whether the Servo style system should perform normal processing,
-// animation-only processing (so we can flush any throttled animation styles),
-// or whether it should traverse in a mode that doesn't generate any change
-// hints, which is what's required when handling frame reconstruction.
-// The change hints in this case are unneeded, since the old frames have
-// already been destroyed.
-// Indicates how the Servo style system should perform.
-enum class TraversalRestyleBehavior {
-  // Normal processing.
-  Normal,
-  // Normal processing, but tolerant to calls to restyle elements in unstyled
-  // or display:none subtrees (which can occur when styling elements with
-  // newly applied XBL bindings).
-  ForNewlyBoundElement,
-  // Traverses in a mode that doesn't generate any change hints, which is what's
-  // required when handling frame reconstruction.  The change hints in this case
-  // are unneeded, since the old frames have already been destroyed.
-  ForReconstruct,
-  // Processes just the traversal for animation-only restyles and skips the
-  // normal traversal for other restyles unrelated to animations.
-  // This is used to bring throttled animations up-to-date such as when we need
-  // to get correct position for transform animations that are throttled because
-  // they are running on the compositor.
-  ForThrottledAnimationFlush,
-  // Traverses as normal mode but tries to update all CSS animations.
-  ForCSSRuleChanges,
-};
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoTraversalFlags)
 
 // Indicates which rules should be included when performing selecting matching
 // on an element.  DefaultOnly is used to exclude all rules except for those
 // that come from UA style sheets, and is used to implemented
 // getDefaultComputedStyle.
 enum class StyleRuleInclusion {
   All,
   DefaultOnly,
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1383981-2.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<style>
+div { padding: 1px; }
+.test div { padding: 2px; }
+.test div ~ div { padding: 3px; }
+.test div ~ div ~ div { background: orange; }
+.test div ~ div ~ div ~ div { background: white; }
+.test div ~ div ~ div ~ div ~ div { background: red; }
+</style>
+<body>
+<script>
+let root = document.createElement('div');
+for (let i = 0; i < 1000; ++i) {
+  let div = root.appendChild(document.createElement('div'));
+  div.appendChild(document.createTextNode(i));
+}
+document.body.appendChild(root);
+document.body.offsetTop;
+root.className = 'test';
+</script>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1383981.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<style>
+div { padding: 1px; }
+.test div { padding: 2px; }
+.test div div { padding: 3px; }
+.test div div div { background: orange; }
+.test div div div div { background: white; }
+.test div div div div div { background: red; }
+</style>
+<body>
+<script>
+let root = document.createElement('div');
+let p = root;
+for (let i = 0; i < 1000; ++i) {
+  p = p.appendChild(document.createElement('div'));
+  p.appendChild(document.createTextNode(i));
+}
+document.body.appendChild(root);
+document.body.offsetTop;
+root.className = 'test';
+</script>
+</body>
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -189,8 +189,10 @@ pref(dom.animations-api.core.enabled,tru
 load 1383975.html
 load border-image-visited-link.html
 load content-only-on-link-before.html
 load content-only-on-visited-before.html
 load font-face-truncated-src.html
 load large_border_image_width.html
 load link-transition-before.html
 load long-url-list-stack-overflow.html
+load 1383981.html
+load 1383981-2.html
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -104,16 +104,17 @@ EXPORTS.mozilla += [
     'ServoBindingList.h',
     'ServoBindings.h',
     'ServoBindingTypes.h',
     'ServoCSSRuleList.h',
     'ServoDeclarationBlock.h',
     'ServoDocumentRule.h',
     'ServoElementSnapshot.h',
     'ServoElementSnapshotTable.h',
+    'ServoFontFeatureValuesRule.h',
     'ServoImportRule.h',
     'ServoKeyframeRule.h',
     'ServoKeyframesRule.h',
     'ServoMediaList.h',
     'ServoMediaRule.h',
     'ServoNamespaceRule.h',
     'ServoPageRule.h',
     'ServoPropPrefList.h',
@@ -135,16 +136,17 @@ EXPORTS.mozilla += [
     'StyleSheet.h',
     'StyleSheetInfo.h',
     'StyleSheetInlines.h',
     'URLExtraData.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'CSS.h',
+    'CSSFontFeatureValuesRule.h',
     'CSSImportRule.h',
     'CSSKeyframeRule.h',
     'CSSKeyframesRule.h',
     'CSSLexer.h',
     'CSSMediaRule.h',
     'CSSMozDocumentRule.h',
     'CSSNamespaceRule.h',
     'CSSPageRule.h',
@@ -172,16 +174,17 @@ EXPORTS.mozilla.css += [
     'URLMatchingFunction.h',
 ]
 
 UNIFIED_SOURCES += [
     'AnimationCollection.cpp',
     'BindingStyleRule.cpp',
     'CounterStyleManager.cpp',
     'CSS.cpp',
+    'CSSFontFeatureValuesRule.cpp',
     'CSSImportRule.cpp',
     'CSSKeyframeRule.cpp',
     'CSSKeyframesRule.cpp',
     'CSSLexer.cpp',
     'CSSMediaRule.cpp',
     'CSSMozDocumentRule.cpp',
     'CSSPageRule.cpp',
     'CSSRuleList.cpp',
@@ -243,16 +246,17 @@ UNIFIED_SOURCES += [
     'PreloadedStyleSheet.cpp',
     'RuleNodeCacheConditions.cpp',
     'RuleProcessorCache.cpp',
     'ServoBindings.cpp',
     'ServoCSSRuleList.cpp',
     'ServoDeclarationBlock.cpp',
     'ServoDocumentRule.cpp',
     'ServoElementSnapshot.cpp',
+    'ServoFontFeatureValuesRule.cpp',
     'ServoImportRule.cpp',
     'ServoKeyframeRule.cpp',
     'ServoKeyframesRule.cpp',
     'ServoMediaList.cpp',
     'ServoMediaRule.cpp',
     'ServoNamespaceRule.cpp',
     'ServoPageRule.cpp',
     'ServoSpecifiedValues.cpp',
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -1260,31 +1260,24 @@ nsCSSFontFaceRule::WrapObject(JSContext*
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSFontFeatureValuesRule::Clone() const
 {
   RefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this);
   return clone.forget();
 }
 
-NS_IMPL_ADDREF_INHERITED(nsCSSFontFeatureValuesRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSFontFeatureValuesRule, mozilla::css::Rule)
+NS_IMPL_ADDREF_INHERITED(nsCSSFontFeatureValuesRule, dom::CSSFontFeatureValuesRule)
+NS_IMPL_RELEASE_INHERITED(nsCSSFontFeatureValuesRule, dom::CSSFontFeatureValuesRule)
 
 // QueryInterface implementation for nsCSSFontFeatureValuesRule
 // If this ever gets its own cycle-collection bits, reevaluate our IsCCLeaf
 // implementation.
 NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
-NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
-
-bool
-nsCSSFontFeatureValuesRule::IsCCLeaf() const
-{
-  return Rule::IsCCLeaf();
-}
+NS_INTERFACE_MAP_END_INHERITING(dom::CSSFontFeatureValuesRule)
 
 static void
 FeatureValuesToString(
   const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
   nsAString& aOutStr)
 {
   uint32_t i, n;
 
@@ -1358,74 +1351,48 @@ nsCSSFontFeatureValuesRule::List(FILE* o
   nsAutoCString indentStr;
   for (i = aIndent; --i >= 0; ) {
     indentStr.AppendLiteral("  ");
   }
   fprintf_stderr(out, "%s%s\n", indentStr.get(), utf8.get());
 }
 #endif
 
-/* virtual */ int32_t
-nsCSSFontFeatureValuesRule::GetType() const
-{
-  return Rule::FONT_FEATURE_VALUES_RULE;
-}
-
-uint16_t
-nsCSSFontFeatureValuesRule::Type() const
-{
-  return nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE;
-}
-
-void
-nsCSSFontFeatureValuesRule::GetCssTextImpl(nsAString& aCssText) const
-{
-  FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText);
-}
-
-void
-nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFamily,
-                                          ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
-void
-nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aFamily,
-                                         ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
 NS_IMETHODIMP
 nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFamilyListStr)
 {
   nsStyleUtil::AppendEscapedCSSFontFamilyList(mFamilyList, aFamilyListStr);
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText)
+{
+  FeatureValuesToString(mFeatureValues, aValueText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsCSSFontFeatureValuesRule::GetValueText(nsAString& aValueText)
-{
-  FeatureValuesToString(mFeatureValues, aValueText);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+void
+nsCSSFontFeatureValuesRule::GetCssTextImpl(nsAString& aCssText) const
+{
+  FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText);
+}
+
 struct MakeFamilyArray {
   explicit MakeFamilyArray(nsTArray<nsString>& aFamilyArray)
     : familyArray(aFamilyArray), hasGeneric(false)
   {}
 
   static bool
   AddFamily(const nsString& aFamily, bool aGeneric, void* aData)
   {
@@ -1478,23 +1445,16 @@ nsCSSFontFeatureValuesRule::AddValueList
 
 size_t
 nsCSSFontFeatureValuesRule::SizeOfIncludingThis(
   MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
-/* virtual */ JSObject*
-nsCSSFontFeatureValuesRule::WrapObject(JSContext* aCx,
-                                       JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSFontFeatureValuesRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 // -------------------------------------------
 // nsCSSKeyframeStyleDeclaration
 //
 
 nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule)
   : mRule(aRule)
 {
 }
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -13,16 +13,17 @@
 #include "StyleRule.h"
 #include "gfxFontFeatures.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Move.h"
 #include "mozilla/SheetType.h"
 #include "mozilla/css/GroupRule.h"
 #include "mozilla/css/URLMatchingFunction.h"
+#include "mozilla/dom/CSSFontFeatureValuesRule.h"
 #include "mozilla/dom/CSSKeyframeRule.h"
 #include "mozilla/dom/CSSKeyframesRule.h"
 #include "mozilla/dom/CSSMediaRule.h"
 #include "mozilla/dom/CSSPageRule.h"
 #include "mozilla/dom/CSSSupportsRule.h"
 #include "mozilla/dom/CSSMozDocumentRule.h"
 #include "nsAutoPtr.h"
 #include "nsCSSPropertyID.h"
@@ -155,70 +156,58 @@ protected:
 
   nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
 };
 
 } // namespace css
 
 } // namespace mozilla
 
-class nsCSSFontFeatureValuesRule final : public mozilla::css::Rule,
-                                         public nsIDOMCSSFontFeatureValuesRule
+class nsCSSFontFeatureValuesRule final : public mozilla::dom::CSSFontFeatureValuesRule
 {
 public:
   nsCSSFontFeatureValuesRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    : mozilla::dom::CSSFontFeatureValuesRule(aLineNumber, aColumnNumber)
   {
   }
 
   nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
     // copy everything except our reference count
-    : mozilla::css::Rule(aCopy),
+    : mozilla::dom::CSSFontFeatureValuesRule(aCopy),
       mFamilyList(aCopy.mFamilyList),
       mFeatureValues(aCopy.mFeatureValues)
   {
   }
 
   NS_DECL_ISUPPORTS_INHERITED
-  virtual bool IsCCLeaf() const override;
 
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
-  virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
-  // nsIDOMCSSFontFaceRule interface
+  // nsIDOMCSSFontFeatureValuesRule interface
   NS_DECL_NSIDOMCSSFONTFEATUREVALUESRULE
 
   // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // The XPCOM GetFontFamily is fine
-  void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv);
-  // The XPCOM GetValueText is fine
-  void SetValueText(const nsAString& aFamily, mozilla::ErrorResult& aRv);
+  void GetCssTextImpl(nsAString& aCssText) const final;
 
   const mozilla::FontFamilyList& GetFamilyList() { return mFamilyList; }
   void SetFamilyList(const mozilla::FontFamilyList& aFamilyList);
 
   void AddValueList(int32_t aVariantAlternate,
                     nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList);
 
   const nsTArray<gfxFontFeatureValueSet::FeatureValues>& GetFeatureValues()
   {
     return mFeatureValues;
   }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 protected:
   ~nsCSSFontFeatureValuesRule() {}
 
   mozilla::FontFamilyList mFamilyList;
   nsTArray<gfxFontFeatureValueSet::FeatureValues> mFeatureValues;
 };
 
 class nsCSSKeyframeRule;
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -214,17 +214,16 @@ skip-if = stylo # bug 1339656
 support-files =
   BitPattern.woff
   file_font_loading_api_vframe.html
 [test_garbage_at_end_of_declarations.html]
 [test_grid_container_shorthands.html]
 [test_grid_item_shorthands.html]
 [test_grid_shorthand_serialization.html]
 [test_grid_computed_values.html]
-skip-if = stylo # bug 1339656
 [test_group_insertRule.html]
 [test_hover_quirk.html]
 [test_html_attribute_computed_values.html]
 [test_ident_escaping.html]
 [test_inherit_computation.html]
 skip-if = toolkit == 'android'
 [test_inherit_storage.html]
 [test_initial_computation.html]
@@ -331,11 +330,12 @@ skip-if = toolkit == 'android' # TIMED_O
 [test_visited_lying.html]
 skip-if = toolkit == 'android' # TIMED_OUT for android
 [test_visited_pref.html]
 skip-if = toolkit == 'android' # TIMED_OUT for android
 [test_visited_reftests.html]
 skip-if = toolkit == 'android' # TIMED_OUT for android
 [test_webkit_device_pixel_ratio.html]
 [test_webkit_flex_display.html]
+skip-if = stylo && os == "linux" && debug
 [test_first_letter_restrictions.html]
 [test_first_line_restrictions.html]
 [test_placeholder_restrictions.html]
--- a/layout/style/test/stylo-failures.md
+++ b/layout/style/test/stylo-failures.md
@@ -32,17 +32,17 @@ to mochitest command.
 * Media query support:
   * "layout.css.prefixes.device-pixel-ratio-webkit" support bug 1366956
     * test_media_queries.html `-device-pixel-ratio` [27]
     * test_webkit_device_pixel_ratio.html [3]
   * test_media_queries_dynamic_xbl.html: xbl support bug 1382078 [1]
 * Animation support:
   * SMIL Animation
     * test_restyles_in_smil_animation.html [2]
-* test_font_feature_values_parsing.html: \@font-feature-values support bug 1355721 [107]
+* test_font_feature_values_parsing.html: \@font-feature-values support bug 1355721 [3]
 * Unsupported values
   * SVG-in-OpenType values not supported servo/servo#15211 bug 1338764
     * test_value_storage.html `context-` [7]
     * test_bug798843_pref.html [3]
 * Incorrect serialization
   * place-{content,items,self} shorthands bug 1363971
     * test_align_shorthand_serialization.html [6]
   * radial gradients are not serialized using modern unprefixed style bug 1380259
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -100,17 +100,17 @@ load 515288-1.html
 load 522394-1.svg
 load 522394-2.svg
 load 522394-3.svg
 load 566216-1.svg
 load 587336-1.html
 load 590291-1.svg
 load 601999-1.html
 load 605626-1.svg
-asserts(2) load 606914.xhtml # bug 606914
+asserts-if(!stylo,2) load 606914.xhtml # bug 606914, bug 718883
 load 610594-1.html
 load 610954-1.html
 load 612662-1.svg
 load 612662-2.svg
 load 612736-1.svg
 load 612736-2.svg
 load 614367-1.svg
 load 620034-1.html
--- a/layout/xul/crashtests/crashtests.list
+++ b/layout/xul/crashtests/crashtests.list
@@ -72,17 +72,17 @@ load 432058-1.xul
 load 432068-1.xul
 load 432068-2.xul
 load 433296-1.xul
 load 433429.xul
 load 434458-1.xul
 load 452185.html
 load 460900-1.xul
 load 464149-1.xul
-asserts-if(winWidget,1) asserts-if(Android,0-1) load 464407-1.xhtml # Bug 450974 on win, Bug 1267054 on Android
+asserts-if(winWidget,1) asserts-if(Android,0-1) asserts-if(stylo,0-1) load 464407-1.xhtml # Bug 450974 on win, Bug 1267054 on Android, bug 718883 for stylo
 load 467080.xul
 load 467481-1.xul
 load 470063-1.html
 load 470272.html
 load 472189.xul
 load 475133.html
 load 488210-1.xhtml
 load 495728-1.xul
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1325,18 +1325,18 @@ pref("dom.forms.datetime", false);
 
 // Support for input type=month, type=week and type=datetime-local. By default,
 // disabled.
 pref("dom.forms.datetime.others", false);
 
 // Enable time picker UI. By default, disabled.
 pref("dom.forms.datetime.timepicker", false);
 
-// Support for new @autocomplete values
-pref("dom.forms.autocomplete.experimental", false);
+// Support @autocomplete values for form autofill feature.
+pref("dom.forms.autocomplete.formautofill", false);
 
 // Enable search in <select> dropdowns (more than 40 options)
 pref("dom.forms.selectSearch", false);
 // Allow for webpages to provide custom styling for <select>
 // popups. Disabled on Linux due to bug 1338283.
 #ifdef XP_LINUX
 pref("dom.forms.select.customstyling", false);
 #else
--- a/moz.configure
+++ b/moz.configure
@@ -360,16 +360,52 @@ check_prog('GMAKE', possible_makes)
 def tup_progs(build_backends):
     for backend in build_backends:
         if 'Tup' in backend:
             return ['tup']
     return None
 
 tup = check_prog('TUP', tup_progs)
 
+# watchman detection
+# ==============================================================
+
+watchman = check_prog('WATCHMAN', ('watchman',), allow_missing=True)
+
+@depends_if(watchman)
+@checking('for watchman version')
+@imports('json')
+def watchman_version(watchman):
+    out = check_cmd_output(watchman, 'version')
+    res = json.loads(out)
+    return Version(res['version'])
+
+@depends_all(hg_version, hg_config, watchman)
+@checking('for watchman Mercurial integration')
+@imports('os')
+def watchman_hg(hg_version, hg_config, watchman):
+    if hg_version < Version('3.8'):
+        return 'no (Mercurial 3.8+ required)'
+
+    ext_enabled = False
+    mode_disabled = False
+
+    for k in ('extensions.fsmonitor', 'extensions.hgext.fsmonitor'):
+        if k in hg_config and hg_config[k] != '!':
+            ext_enabled = True
+
+    mode_disabled = hg_config.get('fsmonitor.mode') == 'off'
+
+    if not ext_enabled:
+        return 'no (fsmonitor extension not enabled)'
+    if mode_disabled:
+        return 'no (fsmonitor.mode=off disables fsmonitor)'
+
+    return True
+
 # Miscellaneous programs
 # ==============================================================
 check_prog('DOXYGEN', ('doxygen',), allow_missing=True)
 check_prog('XARGS', ('xargs',))
 
 @depends(target)
 def extra_programs(target):
     if target.kernel == 'Darwin':
--- a/netwerk/base/SimpleChannel.cpp
+++ b/netwerk/base/SimpleChannel.cpp
@@ -1,33 +1,44 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* 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 "SimpleChannel.h"
+
 #include "nsBaseChannel.h"
+#include "nsIChannel.h"
+#include "nsIChildChannel.h"
 #include "nsIInputStream.h"
 #include "nsIRequest.h"
-#include "SimpleChannel.h"
+#include "nsISupportsImpl.h"
+#include "nsNetUtil.h"
+
+#include "mozilla/Unused.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/net/NeckoChild.h"
+#include "mozilla/net/PSimpleChannelChild.h"
 
 namespace mozilla {
 namespace net {
 
 // Like MOZ_TRY, but returns the unwrapped error value rather than a
 // GenericErrorResult on failure.
 #define TRY_VAR(target, expr) \
   do { \
     auto result = (expr); \
     if (result.isErr()) { \
       return result.unwrapErr(); \
     } \
     (target) = result.unwrap(); \
   } while (0)
 
-class SimpleChannel final : public nsBaseChannel
+
+class SimpleChannel : public nsBaseChannel
 {
 public:
   explicit SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
 
 protected:
   virtual ~SimpleChannel() {}
 
   virtual nsresult OpenContentStream(bool async, nsIInputStream **streamOut,
@@ -73,20 +84,106 @@ SimpleChannel::BeginAsyncRead(nsIStreamL
   mCallbacks = nullptr;
 
   req.forget(request);
   return NS_OK;
 }
 
 #undef TRY_VAR
 
+class SimpleChannelChild final : public SimpleChannel
+                               , public nsIChildChannel
+                               , public PSimpleChannelChild
+{
+public:
+  explicit SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSICHILDCHANNEL
+
+protected:
+  virtual void ActorDestroy(ActorDestroyReason why) override;
+
+private:
+  virtual ~SimpleChannelChild() = default;
+
+  void AddIPDLReference();
+
+  RefPtr<SimpleChannelChild> mIPDLRef;
+};
+
+NS_IMPL_ISUPPORTS_INHERITED(SimpleChannelChild, SimpleChannel, nsIChildChannel)
+
+SimpleChannelChild::SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
+  : SimpleChannel(Move(aCallbacks))
+  , mIPDLRef(nullptr)
+{
+}
+
+NS_IMETHODIMP
+SimpleChannelChild::ConnectParent(uint32_t aId)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  mozilla::dom::ContentChild* cc =
+    static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
+  if (cc->IsShuttingDown()) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if (!gNeckoChild->SendPSimpleChannelConstructor(this, aId)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  // IPC now has a ref to us.
+  mIPDLRef = this;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SimpleChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener,
+                                          nsISupports* aContext)
+{
+  if (mIPDLRef) {
+    MOZ_ASSERT(NS_IsMainThread());
+  }
+
+  nsresult rv;
+  if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
+    MOZ_ASSERT(!aContext, "aContext should be null!");
+    rv = AsyncOpen2(aListener);
+  } else {
+    rv = AsyncOpen(aListener, aContext);
+  }
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  if (mIPDLRef) {
+    Unused << Send__delete__(this);
+  }
+  return NS_OK;
+}
+
+void
+SimpleChannelChild::ActorDestroy(ActorDestroyReason why)
+{
+  MOZ_ASSERT(mIPDLRef);
+  mIPDLRef = nullptr;
+}
+
+
 already_AddRefed<nsIChannel>
 NS_NewSimpleChannelInternal(nsIURI* aURI, nsILoadInfo* aLoadInfo, UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
 {
-  RefPtr<SimpleChannel> chan = new SimpleChannel(Move(aCallbacks));
+  RefPtr<SimpleChannel> chan;
+  if (IsNeckoChild()) {
+    chan = new SimpleChannelChild(Move(aCallbacks));
+  } else {
+    chan = new SimpleChannel(Move(aCallbacks));
+  }
 
   chan->SetURI(aURI);
 
   MOZ_ALWAYS_SUCCEEDS(chan->SetLoadInfo(aLoadInfo));
 
   return chan.forget();
 }
 
new file mode 100644
--- /dev/null
+++ b/netwerk/base/SimpleChannelParent.cpp
@@ -0,0 +1,101 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=4 sw=4 sts=4 et tw=80: */
+/* 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 "SimpleChannelParent.h"
+#include "mozilla/Assertions.h"
+#include "nsNetUtil.h"
+#include "nsIChannel.h"
+
+namespace mozilla {
+namespace net {
+
+NS_IMPL_ISUPPORTS(SimpleChannelParent, nsIParentChannel, nsIStreamListener)
+
+bool
+SimpleChannelParent::Init(const uint32_t &channelId)
+{
+  nsCOMPtr<nsIChannel> channel;
+  MOZ_ALWAYS_SUCCEEDS(
+    NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel)));
+
+  return true;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::SetParentListener(HttpChannelParentListener* aListener)
+{
+  // Nothing to do.
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::NotifyTrackingProtectionDisabled()
+{
+  // Nothing to do.
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::NotifyTrackingResource()
+{
+  // Nothing to do.
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
+                                              const nsACString& aProvider,
+                                              const nsACString& aPrefix)
+{
+  // nothing to do
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::Delete()
+{
+  // Nothing to do.
+  return NS_OK;
+}
+
+void
+SimpleChannelParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::OnStartRequest(nsIRequest* aRequest,
+                                    nsISupports* aContext)
+{
+  // We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
+  // the created nsSimpleChannel. We don't have anywhere to send the data in the
+  // parent, so abort the binding.
+  return NS_BINDING_ABORTED;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::OnStopRequest(nsIRequest* aRequest,
+                                   nsISupports* aContext,
+                                   nsresult aStatusCode)
+{
+  // See above.
+  MOZ_ASSERT(NS_FAILED(aStatusCode));
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+SimpleChannelParent::OnDataAvailable(nsIRequest* aRequest,
+                                     nsISupports* aContext,
+                                     nsIInputStream* aInputStream,
+                                     uint64_t aOffset,
+                                     uint32_t aCount)
+{
+  // See above.
+  MOZ_CRASH("Should never be called");
+}
+
+} // namespace net
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/base/SimpleChannelParent.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set ts=4 sw=4 sts=4 et tw=80: */
+/* 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 NS_SIMPLECHANNELPARENT_H
+#define NS_SIMPLECHANNELPARENT_H
+
+#include "nsIParentChannel.h"
+#include "nsISupportsImpl.h"
+
+#include "mozilla/net/PSimpleChannelParent.h"
+
+namespace mozilla {
+namespace net {
+
+// In order to support HTTP redirects, we need to implement the HTTP
+// redirection API, which requires a class that implements nsIParentChannel
+// and which calls NS_LinkRedirectChannels.
+class SimpleChannelParent : public nsIParentChannel
+                          , public PSimpleChannelParent
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIPARENTCHANNEL
+  NS_DECL_NSIREQUESTOBSERVER
+  NS_DECL_NSISTREAMLISTENER
+
+  MOZ_MUST_USE bool Init(const uint32_t& aArgs);
+
+private:
+  ~SimpleChannelParent() = default;
+
+  virtual void ActorDestroy(ActorDestroyReason why) override;
+};
+
+} // namespace net
+} // namespace mozilla
+
+#endif /* NS_SIMPLECHANNELPARENT_H */
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -174,16 +174,17 @@ EXPORTS.mozilla.net += [
     'CaptivePortalService.h',
     'ChannelDiverterChild.h',
     'ChannelDiverterParent.h',
     'Dashboard.h',
     'DashboardTypes.h',
     'MemoryDownloader.h',
     'Predictor.h',
     'ReferrerPolicy.h',
+    'SimpleChannelParent.h',
     'TCPFastOpen.h',
 ]
 
 UNIFIED_SOURCES += [
     'ArrayBufferInputStream.cpp',
     'BackgroundFileSaver.cpp',
     'CaptivePortalService.cpp',
     'ChannelDiverterChild.cpp',
@@ -244,16 +245,17 @@ UNIFIED_SOURCES += [
     'nsURLParsers.cpp',
     'PollableEvent.cpp',
     'Predictor.cpp',
     'ProxyAutoConfig.cpp',
     'RedirectChannelRegistrar.cpp',
     'RequestContextService.cpp',
     'SimpleBuffer.cpp',
     'SimpleChannel.cpp',
+    'SimpleChannelParent.cpp',
     'StreamingProtocolService.cpp',
     'TCPFastOpenLayer.cpp',
     'ThrottleQueue.cpp',
     'Tickler.cpp',
     'TLSServerSocket.cpp',
 ]
 
 if CONFIG['MOZ_RUST_URLPARSE']:
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -256,16 +256,30 @@ NeckoChild::AllocPFileChannelChild(const
 
 bool
 NeckoChild::DeallocPFileChannelChild(PFileChannelChild* child)
 {
   // NB: See FileChannelChild::ActorDestroy.
   return true;
 }
 
+PSimpleChannelChild*
+NeckoChild::AllocPSimpleChannelChild(const uint32_t& channelId)
+{
+  MOZ_ASSERT_UNREACHABLE("Should never get here");
+  return nullptr;
+}
+
+bool
+NeckoChild::DeallocPSimpleChannelChild(PSimpleChannelChild* child)
+{
+  // NB: See SimpleChannelChild::ActorDestroy.
+  return true;
+}
+
 PRtspControllerChild*
 NeckoChild::AllocPRtspControllerChild()
 {
   NS_NOTREACHED("AllocPRtspController should not be called");
   return nullptr;
 }
 
 bool
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -66,16 +66,18 @@ protected:
                                                   const OriginAttributes& aOriginAttributes,
                                                   const uint32_t& aFlags,
                                                   const nsCString& aNetworkInterface) override;
   virtual bool DeallocPDNSRequestChild(PDNSRequestChild*) override;
   virtual PDataChannelChild* AllocPDataChannelChild(const uint32_t& channelId) override;
   virtual bool DeallocPDataChannelChild(PDataChannelChild* child) override;
   virtual PFileChannelChild* AllocPFileChannelChild(const uint32_t& channelId) override;
   virtual bool DeallocPFileChannelChild(PFileChannelChild* child) override;
+  virtual PSimpleChannelChild* AllocPSimpleChannelChild(const uint32_t& channelId) override;
+  virtual bool DeallocPSimpleChannelChild(PSimpleChannelChild* child) override;
   virtual PRtspControllerChild* AllocPRtspControllerChild() override;
   virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) override;
   virtual PRtspChannelChild*
     AllocPRtspChannelChild(const RtspChannelConnectArgs& aArgs)
                            override;
   virtual bool DeallocPRtspChannelChild(PRtspChannelChild*) override;
   virtual PChannelDiverterChild*
   AllocPChannelDiverterChild(const ChannelDiverterArgs& channel) override;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -13,16 +13,17 @@
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/net/HttpChannelParent.h"
 #include "mozilla/net/CookieServiceParent.h"
 #include "mozilla/net/WyciwygChannelParent.h"
 #include "mozilla/net/FTPChannelParent.h"
 #include "mozilla/net/WebSocketChannelParent.h"
 #include "mozilla/net/WebSocketEventListenerParent.h"
 #include "mozilla/net/DataChannelParent.h"
+#include "mozilla/net/SimpleChannelParent.h"
 #include "mozilla/net/AltDataOutputStreamParent.h"
 #include "mozilla/Unused.h"
 #include "mozilla/net/FileChannelParent.h"
 #ifdef NECKO_PROTOCOL_rtsp
 #include "mozilla/net/RtspControllerParent.h"
 #include "mozilla/net/RtspChannelParent.h"
 #endif
 #include "mozilla/net/DNSRequestParent.h"
@@ -525,16 +526,39 @@ NeckoParent::RecvPDataChannelConstructor
                                          const uint32_t& channelId)
 {
   DataChannelParent* p = static_cast<DataChannelParent*>(actor);
   DebugOnly<bool> rv = p->Init(channelId);
   MOZ_ASSERT(rv);
   return IPC_OK();
 }
 
+PSimpleChannelParent*
+NeckoParent::AllocPSimpleChannelParent(const uint32_t &channelId)
+{
+  RefPtr<SimpleChannelParent> p = new SimpleChannelParent();
+  return p.forget().take();
+}
+
+bool
+NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor)
+{
+  RefPtr<SimpleChannelParent> p = dont_AddRef(actor).downcast<SimpleChannelParent>();
+  return true;
+}
+
+mozilla::ipc::IPCResult
+NeckoParent::RecvPSimpleChannelConstructor(PSimpleChannelParent* actor,
+                                           const uint32_t& channelId)
+{
+  SimpleChannelParent* p = static_cast<SimpleChannelParent*>(actor);
+  MOZ_ALWAYS_TRUE(p->Init(channelId));
+  return IPC_OK();
+}
+
 PFileChannelParent*
 NeckoParent::AllocPFileChannelParent(const uint32_t &channelId)
 {
   RefPtr<FileChannelParent> p = new FileChannelParent();
   return p.forget().take();
 }
 
 bool
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -177,16 +177,23 @@ protected:
 
   virtual PDataChannelParent*
     AllocPDataChannelParent(const uint32_t& channelId) override;
   virtual bool DeallocPDataChannelParent(PDataChannelParent* parent) override;
 
   virtual mozilla::ipc::IPCResult RecvPDataChannelConstructor(PDataChannelParent* aActor,
                                                               const uint32_t& channelId) override;
 
+  virtual PSimpleChannelParent*
+    AllocPSimpleChannelParent(const uint32_t& channelId) override;
+  virtual bool DeallocPSimpleChannelParent(PSimpleChannelParent* parent) override;
+
+  virtual mozilla::ipc::IPCResult RecvPSimpleChannelConstructor(PSimpleChannelParent* aActor,
+                                                              const uint32_t& channelId) override;
+
   virtual PFileChannelParent*
     AllocPFileChannelParent(const uint32_t& channelId) override;
   virtual bool DeallocPFileChannelParent(PFileChannelParent* parent) override;
 
   virtual mozilla::ipc::IPCResult RecvPFileChannelConstructor(PFileChannelParent* aActor,
                                                               const uint32_t& channelId) override;
 
   virtual PRtspControllerParent* AllocPRtspControllerParent() override;
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -15,16 +15,17 @@ include protocol PWebSocket;
 include protocol PWebSocketEventListener;
 include protocol PTCPSocket;
 include protocol PTCPServerSocket;
 include protocol PUDPSocket;
 include protocol PDNSRequest;
 include protocol PChannelDiverter;
 include protocol PFileDescriptorSet;
 include protocol PDataChannel;
+include protocol PSimpleChannel;
 include protocol PTransportProvider;
 include protocol PChildToParentStream; //FIXME: bug #792908
 include protocol PParentToChildStream; //FIXME: bug #792908
 include protocol PStunAddrsRequest;
 include protocol PFileChannel;
 
 include protocol PRtspController;
 include protocol PRtspChannel;
@@ -51,16 +52,17 @@ nested(upto inside_cpow) sync protocol P
   manages PFTPChannel;
   manages PWebSocket;
   manages PWebSocketEventListener;
   manages PTCPSocket;
   manages PTCPServerSocket;
   manages PUDPSocket;
   manages PDNSRequest;
   manages PDataChannel;
+  manages PSimpleChannel;
   manages PFileChannel;
   manages PRtspController;
   manages PRtspChannel;
   manages PChannelDiverter;
   manages PTransportProvider;
   manages PAltDataOutputStream;
   manages PStunAddrsRequest;
 
@@ -99,17 +101,17 @@ parent:
   async CancelHTMLDNSPrefetch(nsString hostname, OriginAttributes originAttributes,
                               uint16_t flags, nsresult reason);
 
   /**
    * channelId is used to establish a connection between redirect channels in
    * the parent and the child when we're redirecting to a data: URI.
    */
   async PDataChannel(uint32_t channelId);
-
+  async PSimpleChannel(uint32_t channelId);
   async PFileChannel(uint32_t channelId);
 
   async PRtspController();
   async PRtspChannel(RtspChannelConnectArgs args);
   async PChannelDiverter(ChannelDiverterArgs channel);
 
   /**
    * These are called from the child with the results of the auth prompt.
new file mode 100644
--- /dev/null
+++ b/netwerk/ipc/PSimpleChannel.ipdl
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
+
+/* 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 protocol PNecko;
+include URIParams;
+
+namespace mozilla {
+namespace net {
+
+async protocol PSimpleChannel
+{
+  manager PNecko;
+
+parent:
+  // Note: channels are opened during construction, so no open method here:
+  // see PNecko.ipdl
+  async __delete__();
+};
+
+} // namespace net
+} // namespace mozilla
--- a/netwerk/ipc/moz.build
+++ b/netwerk/ipc/moz.build
@@ -24,16 +24,17 @@ UNIFIED_SOURCES += [
 IPDL_SOURCES = [
     'NeckoChannelParams.ipdlh',
     'PChannelDiverter.ipdl',
     'PDataChannel.ipdl',
     'PFileChannel.ipdl',
     'PNecko.ipdl',
     'PRtspChannel.ipdl',
     'PRtspController.ipdl',
+    'PSimpleChannel.ipdl',
 ]
 
 # needed so --disable-webrtc builds work (yes, a bit messy)
 if not CONFIG['MOZ_WEBRTC']:
   IPDL_SOURCES += [
       '../../media/mtransport/ipc/PStunAddrsRequest.ipdl',
   ]
   EXPORTS.mozilla.net += [
--- a/netwerk/protocol/http/UserAgentOverrides.jsm
+++ b/netwerk/protocol/http/UserAgentOverrides.jsm
@@ -62,16 +62,17 @@ this.UserAgentOverrides = {
       });
 
       buildOverrides();
     } catch (e) {
       // UserAgentOverrides is initialized before profile is ready.
       // UA override might not work correctly.
     }
 
+    Services.obs.notifyObservers(null, "useragentoverrides-initialized");
     gInitialized = true;
   },
 
   addComplexOverride: function uao_addComplexOverride(callback) {
     // Add to front of array so complex overrides have precedence
     gOverrideFunctions.unshift(callback);
   },
 
--- a/old-configure.in
+++ b/old-configure.in
@@ -530,16 +530,23 @@ if test "$GNU_CC"; then
 
     AC_MSG_CHECKING([for -z text option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,-z,text"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
+    AC_MSG_CHECKING([for -z relro option to ld])
+    _SAVE_LDFLAGS=$LDFLAGS
+    LDFLAGS="$LDFLAGS -Wl,-z,relro"
+    AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
+                  AC_MSG_RESULT([no])
+                  LDFLAGS=$_SAVE_LDFLAGS)
+
     AC_MSG_CHECKING([for --build-id option to ld])
     _SAVE_LDFLAGS=$LDFLAGS
     LDFLAGS="$LDFLAGS -Wl,--build-id"
     AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
                   AC_MSG_RESULT([no])
                   LDFLAGS=$_SAVE_LDFLAGS)
 
     AC_MSG_CHECKING([for --ignore-unresolved-symbol option to ld])
--- a/security/sandbox/common/SandboxSettings.cpp
+++ b/security/sandbox/common/SandboxSettings.cpp
@@ -35,34 +35,67 @@ bool IsDevelopmentBuild()
 /*
  * Helper function to read a string value for a given key from the .app's
  * Info.plist.
  */
 static nsresult
 GetStringValueFromBundlePlist(const nsAString& aKey, nsAutoCString& aValue)
 {
   CFBundleRef mainBundle = CFBundleGetMainBundle();
+  if (mainBundle == nullptr) {
+    return NS_ERROR_FAILURE;
+  }
 
   // Read this app's bundle Info.plist as a dictionary
   CFDictionaryRef bundleInfoDict = CFBundleGetInfoDictionary(mainBundle);
-  if (bundleInfoDict == NULL) {
+  if (bundleInfoDict == nullptr) {
     return NS_ERROR_FAILURE;
   }
 
   nsAutoCString keyAutoCString = NS_ConvertUTF16toUTF8(aKey);
   CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault,
                                               keyAutoCString.get(),
                                               kCFStringEncodingUTF8);
+  if (key == nullptr) {
+    return NS_ERROR_FAILURE;
+  }
 
   CFStringRef value = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, key);
+  CFRelease(key);
+  if (value == nullptr) {
+    return NS_ERROR_FAILURE;
+  }
+
+  CFIndex valueLength = CFStringGetLength(value);
+  if (valueLength == 0) {
+    return NS_ERROR_FAILURE;
+  }
+
   const char* valueCString = CFStringGetCStringPtr(value,
                                                    kCFStringEncodingUTF8);
-  aValue.Assign(valueCString);
-  CFRelease(key);
+  if (valueCString) {
+    aValue.Assign(valueCString);
+    return NS_OK;
+  }
 
+  CFIndex maxLength =
+    CFStringGetMaximumSizeForEncoding(valueLength, kCFStringEncodingUTF8) + 1;
+  char* valueBuffer = static_cast<char*>(moz_xmalloc(maxLength));
+  if (!valueBuffer) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  if (!CFStringGetCString(value, valueBuffer, maxLength,
+                          kCFStringEncodingUTF8)) {
+    free(valueBuffer);
+    return NS_ERROR_FAILURE;
+  }
+
+  aValue.Assign(valueBuffer);
+  free(valueBuffer);
   return NS_OK;
 }
 
 /*
  * Helper function for reading a path string from the .app's Info.plist
  * and returning a directory object for that path with symlinks resolved.
  */
 static nsresult
--- a/services/sync/services-sync.js
+++ b/services/sync/services-sync.js
@@ -77,20 +77,25 @@ pref("services.sync.log.logger.identity"
 pref("services.sync.log.cryptoDebug", false);
 
 pref("services.sync.fxa.termsURL", "https://accounts.firefox.com/legal/terms");
 pref("services.sync.fxa.privacyURL", "https://accounts.firefox.com/legal/privacy");
 
 pref("services.sync.telemetry.submissionInterval", 43200); // 12 hours in seconds
 pref("services.sync.telemetry.maxPayloadCount", 500);
 
-#ifndef RELEASE_OR_BETA
-// Enable the (fairly costly) client/server validation on nightly/aurora only.
+#ifdef EARLY_BETA_OR_EARLIER
+// Enable the (fairly costly) client/server validation through early Beta, but
+// not release candidates or Release.
 pref("services.sync.engine.bookmarks.validation.enabled", true);
-// Enable repair of bookmarks - requires validation also be enabled.
+#endif
+
+#if defined(NIGHTLY_BUILD)
+// Enable repair of bookmarks on Nightly only - requires validation also be
+// enabled.
 pref("services.sync.engine.bookmarks.repair.enabled", true);
 #endif
 
 // We consider validation this frequently. After considering validation, even
 // if we don't end up validating, we won't try again unless this much time has passed.
 pref("services.sync.engine.bookmarks.validation.interval", 86400); // 24 hours in seconds
 
 // We only run validation `services.sync.validation.percentageChance` percent of
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -51,17 +51,17 @@ source = "registry+https://github.com/ru
 
 [[package]]
 name = "antidote"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "app_units"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -167,23 +167,23 @@ source = "registry+https://github.com/ru
 dependencies = [
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bindgen"
-version = "0.26.1"
+version = "0.29.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -377,20 +377,20 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clang-sys"
-version = "0.18.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "libloading 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "clap"
 version = "2.20.5"
@@ -1035,17 +1035,17 @@ dependencies = [
 name = "getopts"
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "gfx"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (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-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1434,17 +1434,17 @@ source = "registry+https://github.com/ru
 name = "language-tags"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "layout"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "canvas_traits 0.0.1",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx 0.0.1",
  "gfx_traits 0.0.1",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1484,17 +1484,17 @@ dependencies = [
  "layout 0.0.1",
  "size_of_test 0.0.1",
 ]
 
 [[package]]
 name = "layout_thread"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx 0.0.1",
  "gfx_traits 0.0.1",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2443,17 +2443,17 @@ name = "scopeguard"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "script"
 version = "0.0.1"
 dependencies = [
  "angle 0.2.0 (git+https://github.com/servo/angle?branch=servo)",
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "audio-video-metadata 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bluetooth_traits 0.0.1",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "canvas_traits 0.0.1",
  "caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2523,17 +2523,17 @@ dependencies = [
  "webvr_traits 0.0.1",
  "xml5ever 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "script_layout_interface"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "canvas_traits 0.0.1",
  "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx_traits 0.0.1",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2834,17 +2834,17 @@ version = "0.0.1"
 dependencies = [
  "servo_config 0.0.1",
 ]
 
 [[package]]
 name = "servo_geometry"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo_rand"
 version = "0.0.1"
 dependencies = [
@@ -2990,32 +2990,33 @@ source = "registry+https://github.com/ru
 name = "strsim"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "style"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "bindgen 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-vec 0.4.3 (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)",
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "nsstring_vendor 0.1.0",
  "num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3051,17 +3052,17 @@ dependencies = [
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "style_tests"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
@@ -3073,17 +3074,17 @@ dependencies = [
  "style 0.0.1",
  "style_traits 0.0.1",
 ]
 
 [[package]]
 name = "style_traits"
 version = "0.0.1"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.19.0",
  "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3462,17 +3463,17 @@ dependencies = [
  "webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender"
 version = "0.48.0"
 source = "git+https://github.com/servo/webrender#283192c41743a59da87b065cbc14c659d94c90b5"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.8.0 (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.9.1 (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.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3491,17 +3492,17 @@ dependencies = [
  "webrender_api 0.48.0 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "webrender_api"
 version = "0.48.0"
 source = "git+https://github.com/servo/webrender#283192c41743a59da87b065cbc14c659d94c90b5"
 dependencies = [
- "app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3628,29 +3629,29 @@ dependencies = [
 "checksum adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ff33fe13a08dbce05bcefa2c68eea4844941437e33d6f808240b54d7157b9cd"
 "checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
 "checksum alloc-no-stdlib 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b21f6ad9c9957eb5d70c3dee16d31c092b3cab339628f821766b05e6833d72b8"
 "checksum android_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d8289e9637439939cc92b1995b0972117905be88bc28116c86b64d6e589bcd38"
 "checksum android_injected_glue 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ec08bc5e100186b5223a24dcfe5655d1488aed9eafeb44fb9a0f67a4f53d0fc"
 "checksum angle 0.2.0 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
 "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
 "checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
-"checksum app_units 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99f3af85d0c7c054d95da6405117b523284a97484494b44a6dec58b9617eabf6"
+"checksum app_units 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f30531df49d388ac6efbc8fb25652d54df5cc2bca653361f683c6dd2f075"
 "checksum arraydeque 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "96e774cadb24c2245225280c6799793f9802b918a58a79615e9490607489a717"
 "checksum arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "699e63a93b79d717e8c3b5eb1b28b7780d0d6d9e59a72eb769291c83b0c8dc67"
 "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
 "checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
 "checksum audio-video-metadata 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3b6ef29ee98ad95a37f34547fd7fb40724772294110ed6ca0445fc2e964c29d1"
 "checksum azure 0.20.0 (git+https://github.com/servo/rust-azure)" = "<none>"
 "checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
 "checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
 "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557"
 "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
 "checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
-"checksum bindgen 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04488a91af8f15eec4d88eb59e2c4e982c03ff31582acf2f5623e2e6d8ae9e0b"
+"checksum bindgen 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0c338079dafc81bef7d581f494b906603d12359c4306979eae6ca081925a4984"
 "checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
 "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
 "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
 "checksum bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1370e9fc2a6ae53aea8b7a5110edbd08836ed87c88736dfabccade1c2b44bff4"
 "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
 "checksum bitreader 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "80b13e2ab064ff3aa0bdbf1eff533f9822dc37899821f5f98c67f263eab51707"
 "checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
@@ -3662,17 +3663,17 @@ dependencies = [
 "checksum brotli-decompressor 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e80402aa0457c3c03d3996a36af7c1e7efa2ad97ee8ec7c2761b07666bab5566"
 "checksum browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)" = "<none>"
 "checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
 "checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
 "checksum caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8950b075cff75cdabadee97148a8b5816c7cf62e5948a6005b5255d564b42fe7"
 "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum cgl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86765cb42c2a2c497e142af72517c1b4d7ae5bb2f25dfa77a5c69642f2342d89"
-"checksum clang-sys 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff7c2d1502c65748c7221f43ce670b3ba5c697acebfeb85a580827daca6975fc"
+"checksum clang-sys 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "611ec2e3a7623afd8a8c0d027887b6b55759d894abbf5fe11b9dc11b50d5b49a"
 "checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
 "checksum clipboard 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd3a9a938558f33ec1baaa6ca631a69c104aafaacbc66868d9ad28cf5f30564f"
 "checksum clipboard-win 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "693b1280c514045382dfdbb78d1594b1b03cdb66320aeb7ebd2bd38d49bae959"
 "checksum cmake 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "d18d68987ed4c516dcc3e7913659bfa4076f5182eea4a7e0038bb060953e76ac"
 "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd"
 "checksum cocoa 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4047fed6536f40cc2ae5e7834fb38e382c788270191c4cd69196f89686d076ce"
 "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
 "checksum compiletest_rs 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "617b23d0ed4f57b3bcff6b5fe0a78f0010f1efb636298317665a960b6dbc0533"
--- a/servo/components/atoms/Cargo.toml
+++ b/servo/components/atoms/Cargo.toml
@@ -1,16 +1,15 @@
 [package]
 name = "servo_atoms"
 version = "0.0.1"
 authors = ["The Servo Project Developers"]
 license = "MPL-2.0"
 publish = false
 build = "build.rs"
-workspace = "../.."
 
 [lib]
 path = "lib.rs"
 
 [dependencies]
 string_cache = {version = "0.6", features = ["heapsize"]}
 
 [build-dependencies]
--- a/servo/components/layout_thread/lib.rs
+++ b/servo/components/layout_thread/lib.rs
@@ -130,17 +130,18 @@ use style::media_queries::{Device, Media
 use style::properties::PropertyId;
 use style::selector_parser::SnapshotMap;
 use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
 use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
 use style::stylesheets::{Origin, Stylesheet, StylesheetInDocument, UserAgentStylesheets};
 use style::stylist::{ExtraStyleData, Stylist};
 use style::thread_state;
 use style::timer::Timer;
-use style::traversal::{DomTraversal, TraversalDriver, TraversalFlags};
+use style::traversal::{DomTraversal, TraversalDriver};
+use style::traversal_flags::TraversalFlags;
 
 /// Information needed by the layout thread.
 pub struct LayoutThread {
     /// The ID of the pipeline that we belong to.
     id: PipelineId,
 
     /// The ID of the top-level browsing context that we belong to.
     top_level_browsing_context_id: TopLevelBrowsingContextId,
--- a/servo/components/script/dom/cssrule.rs
+++ b/servo/components/script/dom/cssrule.rs
@@ -73,16 +73,17 @@ impl CSSRule {
     // CSSRule based on which rule it is
     pub fn new_specific(window: &Window, parent_stylesheet: &CSSStyleSheet,
                         rule: StyleCssRule) -> Root<CSSRule> {
         // be sure to update the match in as_specific when this is updated
         match rule {
             StyleCssRule::Import(s) => Root::upcast(CSSImportRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Style(s) => Root::upcast(CSSStyleRule::new(window, parent_stylesheet, s)),
             StyleCssRule::FontFace(s) => Root::upcast(CSSFontFaceRule::new(window, parent_stylesheet, s)),
+            StyleCssRule::FontFeatureValues(_) => unimplemented!(),
             StyleCssRule::CounterStyle(_) => unimplemented!(),
             StyleCssRule::Keyframes(s) => Root::upcast(CSSKeyframesRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Media(s) => Root::upcast(CSSMediaRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Namespace(s) => Root::upcast(CSSNamespaceRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Viewport(s) => Root::upcast(CSSViewportRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Supports(s) => Root::upcast(CSSSupportsRule::new(window, parent_stylesheet, s)),
             StyleCssRule::Page(_) => unreachable!(),
             StyleCssRule::Document(_) => unimplemented!(), // TODO
--- a/servo/components/style/Cargo.toml
+++ b/servo/components/style/Cargo.toml
@@ -25,30 +25,31 @@ servo = ["serde", "heapsize", "heapsize_
          # FIXME: Uncomment when https://github.com/servo/servo/pull/16953 has landed:
          #"arrayvec/use_union"
 
          "servo_url"]
 testing = []
 gecko_debug = ["nsstring_vendor/gecko_debug"]
 
 [dependencies]
-app_units = "0.5"
+app_units = "0.5.1"
 arrayvec = "0.3.20"
 arraydeque = "0.2.3"
 atomic_refcell = "0.1"
 bitflags = "0.7"
 bit-vec = "0.4.3"
 byteorder = "1.0"
 cfg-if = "0.1.0"
 cssparser = "0.18"
 encoding = {version = "0.2", optional = true}
 euclid = "0.15"
 fnv = "1.0"
 heapsize = {version = "0.4", optional = true}
 heapsize_derive = {version = "0.1", optional = true}
+itertools = "0.5"
 itoa = "0.3"
 html5ever = {version = "0.18", optional = true}
 lazy_static = "0.2"
 log = "0.3"
 matches = "0.1"
 nsstring_vendor = {path = "gecko_bindings/nsstring_vendor", optional = true}
 num_cpus = {version = "1.1.0", optional = true}
 num-integer = "0.1.32"
@@ -73,12 +74,12 @@ unicode-bidi = "0.3"
 unicode-segmentation = "1.0"
 
 [target.'cfg(windows)'.dependencies]
 kernel32-sys = "0.2"
 
 [build-dependencies]
 lazy_static = "0.2"
 log = "0.3"
-bindgen = { version = "0.26.1", optional = true }
+bindgen = { version = "0.29", optional = true }
 regex = {version = "0.2", optional = true}
 walkdir = "1.0"
 toml = {version = "0.2.1", optional = true, default-features = false}
--- a/servo/components/style/context.rs
+++ b/servo/components/style/context.rs
@@ -29,17 +29,18 @@ use std::ops;
 #[cfg(feature = "servo")] use std::sync::Mutex;
 #[cfg(feature = "servo")] use std::sync::mpsc::Sender;
 use style_traits::CSSPixel;
 use style_traits::DevicePixel;
 use stylist::Stylist;
 use thread_state;
 use time;
 use timer::Timer;
-use traversal::{DomTraversal, TraversalFlags};
+use traversal::DomTraversal;
+use traversal_flags::TraversalFlags;
 
 pub use selectors::matching::QuirksMode;
 
 /// This structure is used to create a local style context from a shared one.
 #[cfg(feature = "servo")]
 pub struct ThreadLocalStyleContextCreationInfo {
     new_animations_sender: Sender<Animation>,
 }
--- a/servo/components/style/dom.rs
+++ b/servo/components/style/dom.rs
@@ -28,17 +28,17 @@ use shared_lock::Locked;
 use smallvec::VecLike;
 use std::fmt;
 #[cfg(feature = "gecko")] use std::collections::HashMap;
 use std::fmt::Debug;
 use std::hash::Hash;
 use std::ops::Deref;
 use stylist::Stylist;
 use thread_state;
-use traversal::TraversalFlags;
+use traversal_flags::TraversalFlags;
 
 pub use style_traits::UnsafeNode;
 
 /// An opaque handle to a node, which, unlike UnsafeNode, cannot be transformed
 /// back into a non-opaque representation. The only safe operation that can be
 /// performed on this node is to compare it to another opaque handle or to another
 /// OpaqueNode.
 ///
--- a/servo/components/style/error_reporting.rs
+++ b/servo/components/style/error_reporting.rs
@@ -13,18 +13,22 @@ use style_traits::ParseError;
 use stylesheets::UrlExtraData;
 
 /// Errors that can be encountered while parsing CSS.
 pub enum ContextualParseError<'a> {
     /// A property declaration was not recognized.
     UnsupportedPropertyDeclaration(&'a str, ParseError<'a>),
     /// A font face descriptor was not recognized.
     UnsupportedFontFaceDescriptor(&'a str, ParseError<'a>),
+    /// A font feature values descroptor was not recognized.
+    UnsupportedFontFeatureValuesDescriptor(&'a str, ParseError<'a>),
     /// A keyframe rule was not valid.
     InvalidKeyframeRule(&'a str, ParseError<'a>),
+    /// A font feature values rule was not valid.
+    InvalidFontFeatureValuesRule(&'a str, ParseError<'a>),
     /// A keyframe property declaration was not recognized.
     UnsupportedKeyframePropertyDeclaration(&'a str, ParseError<'a>),
     /// A rule was invalid for some reason.
     InvalidRule(&'a str, ParseError<'a>),
     /// A rule was not recognized.
     UnsupportedRule(&'a str, ParseError<'a>),
     /// A viewport descriptor declaration was not recognized.
     UnsupportedViewportDescriptorDeclaration(&'a str, ParseError<'a>),
@@ -103,19 +107,25 @@ impl<'a> ContextualParseError<'a> {
 
         match *self {
             ContextualParseError::UnsupportedPropertyDeclaration(decl, ref err) =>
                 format!("Unsupported property declaration: '{}', {}", decl,
                         parse_error_to_str(err)),
             ContextualParseError::UnsupportedFontFaceDescriptor(decl, ref err) =>
                 format!("Unsupported @font-face descriptor declaration: '{}', {}", decl,
                         parse_error_to_str(err)),
+            ContextualParseError::UnsupportedFontFeatureValuesDescriptor(decl, ref err) =>
+            format!("Unsupported @font-feature-values descriptor declaration: '{}', {}", decl,
+                    parse_error_to_str(err)),
             ContextualParseError::InvalidKeyframeRule(rule, ref err) =>
                 format!("Invalid keyframe rule: '{}', {}", rule,
                         parse_error_to_str(err)),
+            ContextualParseError::InvalidFontFeatureValuesRule(rule, ref err) =>
+            format!("Invalid font feature value rule: '{}', {}", rule,
+                    parse_error_to_str(err)),
             ContextualParseError::UnsupportedKeyframePropertyDeclaration(decl, ref err) =>
                 format!("Unsupported keyframe property declaration: '{}', {}", decl,
                         parse_error_to_str(err)),
             ContextualParseError::InvalidRule(rule, ref err) =>
                 format!("Invalid rule: '{}', {}", rule, parse_error_to_str(err)),
             ContextualParseError::UnsupportedRule(rule, ref err) =>
                 format!("Unsupported rule: '{}', {}", rule, parse_error_to_str(err)),
             ContextualParseError::UnsupportedViewportDescriptorDeclaration(decl, ref err) =>
--- a/servo/components/style/gecko/arc_types.rs
+++ b/servo/components/style/gecko/arc_types.rs
@@ -3,33 +3,33 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 //! This file lists all arc FFI types and defines corresponding addref
 //! and release functions. This list corresponds to ServoArcTypeList.h
 //! file in Gecko.
 
 #![allow(non_snake_case, missing_docs)]
 
-use gecko_bindings::bindings::{RawServoImportRule, RawServoSupportsRule};
+use gecko_bindings::bindings::{RawServoFontFeatureValuesRule, RawServoImportRule, RawServoSupportsRule};
 use gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframesRule};
 use gecko_bindings::bindings::{RawServoMediaRule, RawServoNamespaceRule, RawServoPageRule};
 use gecko_bindings::bindings::{RawServoRuleNode, RawServoRuleNodeStrong, RawServoDocumentRule};
 use gecko_bindings::bindings::ServoCssRules;
 use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock, RawServoStyleRule};
 use gecko_bindings::structs::{RawServoMediaList, RawServoStyleSheetContents};
 use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
 use media_queries::MediaList;
 use properties::{ComputedValues, PropertyDeclarationBlock};
 use properties::animated_properties::AnimationValue;
 use rule_tree::StrongRuleNode;
 use servo_arc::{Arc, ArcBorrow};
 use shared_lock::Locked;
 use std::{mem, ptr};
 use stylesheets::{CssRules, StylesheetContents, StyleRule, ImportRule, KeyframesRule, MediaRule};
-use stylesheets::{NamespaceRule, PageRule, SupportsRule, DocumentRule};
+use stylesheets::{FontFeatureValuesRule, NamespaceRule, PageRule, SupportsRule, DocumentRule};
 use stylesheets::keyframes_rule::Keyframe;
 
 macro_rules! impl_arc_ffi {
     ($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
         unsafe impl HasFFI for $servo_type {
             type FFIType = $gecko_type;
         }
         unsafe impl HasArcFFI for $servo_type {}
@@ -83,16 +83,19 @@ impl_arc_ffi!(Locked<PageRule> => RawSer
               [Servo_PageRule_AddRef, Servo_PageRule_Release]);
 
 impl_arc_ffi!(Locked<SupportsRule> => RawServoSupportsRule
               [Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]);
 
 impl_arc_ffi!(Locked<DocumentRule> => RawServoDocumentRule
               [Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]);
 
+impl_arc_ffi!(Locked<FontFeatureValuesRule> => RawServoFontFeatureValuesRule
+              [Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]);
+
 // RuleNode is a Arc-like type but it does not use Arc.
 
 impl StrongRuleNode {
     pub fn into_strong(self) -> RawServoRuleNodeStrong {
         let ptr = self.ptr();
         mem::forget(self);
         unsafe { mem::transmute(ptr) }
     }
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -39,18 +39,17 @@ use gecko_bindings::structs::RawGeckoPre
 use gecko_bindings::structs::RawGeckoStyleAnimationList;
 use gecko_bindings::structs::RawGeckoStyleChildrenIteratorBorrowedMut;
 use gecko_bindings::structs::RawGeckoServoStyleRuleList;
 use gecko_bindings::structs::RawGeckoURLExtraData;
 use gecko_bindings::structs::RawGeckoXBLBinding;
 use gecko_bindings::structs::RefPtr;
 use gecko_bindings::structs::CSSPseudoClassType;
 use gecko_bindings::structs::CSSPseudoElementType;
-use gecko_bindings::structs::TraversalRestyleBehavior;
-use gecko_bindings::structs::TraversalRootBehavior;
+use gecko_bindings::structs::ServoTraversalFlags;
 use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag;
 use gecko_bindings::structs::CounterStylePtr;
 use gecko_bindings::structs::FontFamilyList;
 use gecko_bindings::structs::FontFamilyType;
 use gecko_bindings::structs::FontSizePrefs;
 use gecko_bindings::structs::GeckoFontMetrics;
 use gecko_bindings::structs::IterationCompositeOperation;
 use gecko_bindings::structs::Keyframe;
@@ -373,16 +372,21 @@ pub type RawServoSupportsRuleBorrowed<'a
 pub type RawServoSupportsRuleBorrowedOrNull<'a> = Option<&'a RawServoSupportsRule>;
 enum RawServoSupportsRuleVoid { }
 pub struct RawServoSupportsRule(RawServoSupportsRuleVoid);
 pub type RawServoDocumentRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoDocumentRule>;
 pub type RawServoDocumentRuleBorrowed<'a> = &'a RawServoDocumentRule;
 pub type RawServoDocumentRuleBorrowedOrNull<'a> = Option<&'a RawServoDocumentRule>;
 enum RawServoDocumentRuleVoid { }
 pub struct RawServoDocumentRule(RawServoDocumentRuleVoid);
+pub type RawServoFontFeatureValuesRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoFontFeatureValuesRule>;
+pub type RawServoFontFeatureValuesRuleBorrowed<'a> = &'a RawServoFontFeatureValuesRule;
+pub type RawServoFontFeatureValuesRuleBorrowedOrNull<'a> = Option<&'a RawServoFontFeatureValuesRule>;
+enum RawServoFontFeatureValuesRuleVoid { }
+pub struct RawServoFontFeatureValuesRule(RawServoFontFeatureValuesRuleVoid);
 pub type RawServoRuleNodeStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoRuleNode>;
 pub type RawServoRuleNodeBorrowed<'a> = &'a RawServoRuleNode;
 pub type RawServoRuleNodeBorrowedOrNull<'a> = Option<&'a RawServoRuleNode>;
 enum RawServoRuleNodeVoid { }
 pub struct RawServoRuleNode(RawServoRuleNodeVoid);
 
 extern "C" {
     pub fn Gecko_EnsureTArrayCapacity(aArray: *mut ::std::os::raw::c_void,
@@ -476,16 +480,24 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_DocumentRule_AddRef(ptr: RawServoDocumentRuleBorrowed);
 }
 extern "C" {
     pub fn Servo_DocumentRule_Release(ptr: RawServoDocumentRuleBorrowed);
 }
 extern "C" {
+    pub fn Servo_FontFeatureValuesRule_AddRef(ptr:
+                                                  RawServoFontFeatureValuesRuleBorrowed);
+}
+extern "C" {
+    pub fn Servo_FontFeatureValuesRule_Release(ptr:
+                                                   RawServoFontFeatureValuesRuleBorrowed);
+}
+extern "C" {
     pub fn Servo_RuleNode_AddRef(ptr: RawServoRuleNodeBorrowed);
 }
 extern "C" {
     pub fn Servo_RuleNode_Release(ptr: RawServoRuleNodeBorrowed);
 }
 extern "C" {
     pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned);
 }
@@ -2155,16 +2167,34 @@ extern "C" {
     pub fn Servo_DocumentRule_GetCssText(rule: RawServoDocumentRuleBorrowed,
                                          result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_DocumentRule_GetRules(rule: RawServoDocumentRuleBorrowed)
      -> ServoCssRulesStrong;
 }
 extern "C" {
+    pub fn Servo_CssRules_GetFontFeatureValuesRuleAt(rules:
+                                                         ServoCssRulesBorrowed,
+                                                     index: u32,
+                                                     line: *mut u32,
+                                                     column: *mut u32)
+     -> RawServoFontFeatureValuesRuleStrong;
+}
+extern "C" {
+    pub fn Servo_FontFeatureValuesRule_Debug(rule:
+                                                 RawServoFontFeatureValuesRuleBorrowed,
+                                             result: *mut nsACString);
+}
+extern "C" {
+    pub fn Servo_FontFeatureValuesRule_GetCssText(rule:
+                                                      RawServoFontFeatureValuesRuleBorrowed,
+                                                  result: *mut nsAString);
+}
+extern "C" {
     pub fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed,
                                             index: u32)
      -> *mut nsCSSFontFaceRule;
 }
 extern "C" {
     pub fn Servo_CssRules_GetCounterStyleRuleAt(rules: ServoCssRulesBorrowed,
                                                 index: u32)
      -> *mut nsCSSCounterStyleRule;
@@ -2292,16 +2322,26 @@ extern "C" {
                                                result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_DocumentRule_GetConditionText(rule:
                                                    RawServoDocumentRuleBorrowed,
                                                result: *mut nsAString);
 }
 extern "C" {
+    pub fn Servo_FontFeatureValuesRule_GetFontFamily(rule:
+                                                         RawServoFontFeatureValuesRuleBorrowed,
+                                                     result: *mut nsAString);
+}
+extern "C" {
+    pub fn Servo_FontFeatureValuesRule_GetValueText(rule:
+                                                        RawServoFontFeatureValuesRuleBorrowed,
+                                                    result: *mut nsAString);
+}
+extern "C" {
     pub fn Servo_ParseProperty(property: nsCSSPropertyID,
                                value: *const nsACString,
                                data: *mut RawGeckoURLExtraData,
                                parsing_mode: ParsingMode,
                                quirks_mode: nsCompatibility,
                                loader: *mut Loader)
      -> RawServoDeclarationBlockStrong;
 }
@@ -2735,23 +2775,27 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed,
                                    restyle_hint: nsRestyleHint,
                                    change_hint: nsChangeHint);
 }
 extern "C" {
     pub fn Servo_TakeChangeHint(element: RawGeckoElementBorrowed,
-                                restyle_behavior: TraversalRestyleBehavior,
+                                flags: ServoTraversalFlags,
                                 was_restyled: *mut bool) -> nsChangeHint;
 }
 extern "C" {
     pub fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
                               set: RawServoStyleSetBorrowed,
-                              restyle_behavior: TraversalRestyleBehavior)
+                              flags: ServoTraversalFlags)
+     -> ServoStyleContextStrong;
+}
+extern "C" {
+    pub fn Servo_ResolveStyleAllowStale(element: RawGeckoElementBorrowed)
      -> ServoStyleContextStrong;
 }
 extern "C" {
     pub fn Servo_ResolvePseudoStyle(element: RawGeckoElementBorrowed,
                                     pseudo_type: CSSPseudoElementType,
                                     is_probe: bool,
                                     inherited_style:
                                         ServoStyleContextBorrowedOrNull,
@@ -2775,19 +2819,17 @@ extern "C" {
                                         *const ServoElementSnapshotTable,
                                     set: RawServoStyleSetBorrowed)
      -> ServoStyleContextStrong;
 }
 extern "C" {
     pub fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed,
                                  set: RawServoStyleSetBorrowed,
                                  snapshots: *const ServoElementSnapshotTable,
-                                 root_behavior: TraversalRootBehavior,
-                                 restyle_behavior: TraversalRestyleBehavior)
-     -> bool;
+                                 flags: ServoTraversalFlags) -> bool;
 }
 extern "C" {
     pub fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed);
 }
 extern "C" {
     pub fn Servo_MaybeGCRuleTree(set: RawServoStyleSetBorrowed);
 }
 extern "C" {
@@ -2841,10 +2883,11 @@ extern "C" {
                                               *const ::std::os::raw::c_char,
                                           param:
                                               *const ::std::os::raw::c_char,
                                           paramLen: u32,
                                           source:
                                               *const ::std::os::raw::c_char,
                                           sourceLen: u32, lineNumber: u32,
                                           colNumber: u32, aURI: *mut nsIURI,
-                                          followup: *const ::std::os::raw::c_char);
-}
+                                          followup:
+                                              *const ::std::os::raw::c_char);
+}
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -1047,16 +1047,18 @@ pub mod root {
         pub struct pair<_T1, _T2> {
             pub first: _T1,
             pub second: _T2,
             pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<_T1>>,
             pub _phantom_1: ::std::marker::PhantomData<::std::cell::UnsafeCell<_T2>>,
         }
         pub type pair_first_type<_T1> = _T1;
         pub type pair_second_type<_T2> = _T2;
+        pub type pair__PCCP = u8;
+        pub type pair__PCCFP = u8;
         #[repr(C)]
         #[derive(Debug, Copy)]
         pub struct input_iterator_tag {
             pub _address: u8,
         }
         #[test]
         fn bindgen_test_layout_input_iterator_tag() {
             assert_eq!(::std::mem::size_of::<input_iterator_tag>() , 1usize ,
@@ -1076,20 +1078,27 @@ pub mod root {
             pub _address: u8,
         }
         pub type iterator_iterator_category<_Category> = _Category;
         pub type iterator_value_type<_Tp> = _Tp;
         pub type iterator_difference_type<_Distance> = _Distance;
         pub type iterator_pointer<_Pointer> = _Pointer;
         pub type iterator_reference<_Reference> = _Reference;
         #[repr(C)]
+        #[derive(Debug, Copy, Clone)]
+        pub struct __iterator_traits {
+            pub _address: u8,
+        }
+        #[repr(C)]
+        #[derive(Debug, Copy, Clone)]
         pub struct iterator_traits {
             pub _address: u8,
         }
         #[repr(C)]
+        #[derive(Debug, Copy, Clone)]
         pub struct reverse_iterator<_Iterator> {
             pub current: _Iterator,
             pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<_Iterator>>,
         }
         pub type reverse_iterator___traits_type = root::std::iterator_traits;
         pub type reverse_iterator_iterator_type<_Iterator> = _Iterator;
         pub type reverse_iterator_difference_type =
             root::std::reverse_iterator___traits_type;
@@ -1288,17 +1297,17 @@ pub mod root {
                 VOIDED = 2,
                 SHARED = 4,
                 OWNED = 8,
                 FIXED = 16,
                 LITERAL = 32,
             }
             #[repr(u16)]
             #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-            pub enum StringClassFlags { FIXED = 1, }
+            pub enum StringClassFlags { FIXED = 1, NULL_TERMINATED = 2, }
             /**
  * LinkedList supports refcounted elements using this adapter class. Clients
  * using LinkedList<RefPtr<T>> will get a data structure that holds a strong
  * reference to T as long as T is in the list.
  */
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct LinkedListElementTraits {
@@ -1383,19 +1392,19 @@ pub mod root {
                             "Alignment of field: " , stringify ! ( MutexImpl )
                             , "::" , stringify ! ( platformData_ ) ));
             }
         }
         #[repr(u32)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum ArenaObjectID {
             eArenaObjectID_DummyBeforeFirstObjectID = 173,
-            eArenaObjectID_nsLineBox = 174,
-            eArenaObjectID_nsRuleNode = 175,
-            eArenaObjectID_GeckoStyleContext = 176,
+            eArenaObjectID_GeckoStyleContext = 174,
+            eArenaObjectID_nsLineBox = 175,
+            eArenaObjectID_nsRuleNode = 176,
             eArenaObjectID_DisplayItemData = 177,
             eArenaObjectID_nsInheritedStyleData = 178,
             eArenaObjectID_nsResetStyleData = 179,
             eArenaObjectID_nsConditionalResetStyleData = 180,
             eArenaObjectID_nsConditionalResetStyleDataEntry = 181,
             eArenaObjectID_nsFrameList = 182,
             eArenaObjectID_CustomCounterStyle = 183,
             eArenaObjectID_DependentBuiltinCounterStyle = 184,
@@ -2503,16 +2512,26 @@ pub mod root {
             #[derive(Debug, Copy, Clone)]
             pub struct Path {
                 _unused: [u8; 0],
             }
         }
         pub mod layers {
             #[allow(unused_imports)]
             use self::super::super::super::root;
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
+            pub struct LayerManager {
+                _unused: [u8; 0],
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
+            pub struct ContainerLayer {
+                _unused: [u8; 0],
+            }
             /**
  * The viewport and displayport metrics for the painted frame at the
  * time of a layer-tree transaction.  These metrics are especially
  * useful for shadow layers, because the metrics values are updated
  * atomically with new pixels.
  */
             #[repr(C)]
             #[derive(Debug, Copy)]
@@ -3336,158 +3355,16 @@ pub mod root {
                           } |
                               ((mUsesContainerScrolling as u8 as u8) <<
                                    3usize) & (8u64 as u8))
                      } |
                          ((mForceDisableApz as u8 as u8) << 4usize) &
                              (16u64 as u8))
                 }
             }
-            /**
- * This class is used for communicating information about the currently focused
- * element of a document and the scrollable frames to use when keyboard scrolling
- * it. It is created on the main thread at paint-time, but is then passed over
- * IPC to the compositor/APZ code.
- */
-            #[repr(C)]
-            #[derive(Debug, Copy)]
-            pub struct FocusTarget {
-                pub mSequenceNumber: u64,
-                pub mFocusHasKeyEventListeners: bool,
-                pub mType: root::mozilla::layers::FocusTarget_FocusTargetType,
-                pub mData: root::mozilla::layers::FocusTarget_FocusTargetData,
-            }
-            #[repr(C)]
-            #[derive(Debug, Copy)]
-            pub struct FocusTarget_ScrollTargets {
-                pub mHorizontal: root::mozilla::layers::FrameMetrics_ViewID,
-                pub mVertical: root::mozilla::layers::FrameMetrics_ViewID,
-            }
-            #[test]
-            fn bindgen_test_layout_FocusTarget_ScrollTargets() {
-                assert_eq!(::std::mem::size_of::<FocusTarget_ScrollTargets>()
-                           , 16usize , concat ! (
-                           "Size of: " , stringify ! (
-                           FocusTarget_ScrollTargets ) ));
-                assert_eq! (::std::mem::align_of::<FocusTarget_ScrollTargets>()
-                            , 8usize , concat ! (
-                            "Alignment of " , stringify ! (
-                            FocusTarget_ScrollTargets ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget_ScrollTargets ) )
-                            . mHorizontal as * const _ as usize } , 0usize ,
-                            concat ! (
-                            "Alignment of field: " , stringify ! (
-                            FocusTarget_ScrollTargets ) , "::" , stringify ! (
-                            mHorizontal ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget_ScrollTargets ) )
-                            . mVertical as * const _ as usize } , 8usize ,
-                            concat ! (
-                            "Alignment of field: " , stringify ! (
-                            FocusTarget_ScrollTargets ) , "::" , stringify ! (
-                            mVertical ) ));
-            }
-            impl Clone for FocusTarget_ScrollTargets {
-                fn clone(&self) -> Self { *self }
-            }
-            #[repr(u32)]
-            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-            pub enum FocusTarget_FocusTargetType {
-                eNone = 0,
-                eRefLayer = 1,
-                eScrollLayer = 2,
-            }
-            #[repr(C)]
-            #[derive(Debug, Copy)]
-            pub struct FocusTarget_FocusTargetData {
-                pub mRefLayerId: root::__BindgenUnionField<u64>,
-                pub mScrollTargets: root::__BindgenUnionField<root::mozilla::layers::FocusTarget_ScrollTargets>,
-                pub bindgen_union_field: [u64; 2usize],
-            }
-            #[test]
-            fn bindgen_test_layout_FocusTarget_FocusTargetData() {
-                assert_eq!(::std::mem::size_of::<FocusTarget_FocusTargetData>()
-                           , 16usize , concat ! (
-                           "Size of: " , stringify ! (
-                           FocusTarget_FocusTargetData ) ));
-                assert_eq! (::std::mem::align_of::<FocusTarget_FocusTargetData>()
-                            , 8usize , concat ! (
-                            "Alignment of " , stringify ! (
-                            FocusTarget_FocusTargetData ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget_FocusTargetData )
-                            ) . mRefLayerId as * const _ as usize } , 0usize ,
-                            concat ! (
-                            "Alignment of field: " , stringify ! (
-                            FocusTarget_FocusTargetData ) , "::" , stringify !
-                            ( mRefLayerId ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget_FocusTargetData )
-                            ) . mScrollTargets as * const _ as usize } ,
-                            0usize , concat ! (
-                            "Alignment of field: " , stringify ! (
-                            FocusTarget_FocusTargetData ) , "::" , stringify !
-                            ( mScrollTargets ) ));
-            }
-            impl Clone for FocusTarget_FocusTargetData {
-                fn clone(&self) -> Self { *self }
-            }
-            pub const FocusTarget_sFocusTargetTypeCount: usize = 3;
-            extern "C" {
-                #[link_name =
-                      "_ZN7mozilla6layers11FocusTarget23sHighestFocusTargetTypeE"]
-                pub static FocusTarget_sHighestFocusTargetType:
-                           root::mozilla::layers::FocusTarget_FocusTargetType;
-            }
-            #[test]
-            fn bindgen_test_layout_FocusTarget() {
-                assert_eq!(::std::mem::size_of::<FocusTarget>() , 32usize ,
-                           concat ! (
-                           "Size of: " , stringify ! ( FocusTarget ) ));
-                assert_eq! (::std::mem::align_of::<FocusTarget>() , 8usize ,
-                            concat ! (
-                            "Alignment of " , stringify ! ( FocusTarget ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget ) ) .
-                            mSequenceNumber as * const _ as usize } , 0usize ,
-                            concat ! (
-                            "Alignment of field: " , stringify ! ( FocusTarget
-                            ) , "::" , stringify ! ( mSequenceNumber ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget ) ) .
-                            mFocusHasKeyEventListeners as * const _ as usize }
-                            , 8usize , concat ! (
-                            "Alignment of field: " , stringify ! ( FocusTarget
-                            ) , "::" , stringify ! (
-                            mFocusHasKeyEventListeners ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget ) ) . mType as *
-                            const _ as usize } , 12usize , concat ! (
-                            "Alignment of field: " , stringify ! ( FocusTarget
-                            ) , "::" , stringify ! ( mType ) ));
-                assert_eq! (unsafe {
-                            & ( * ( 0 as * const FocusTarget ) ) . mData as *
-                            const _ as usize } , 16usize , concat ! (
-                            "Alignment of field: " , stringify ! ( FocusTarget
-                            ) , "::" , stringify ! ( mData ) ));
-            }
-            impl Clone for FocusTarget {
-                fn clone(&self) -> Self { *self }
-            }
-            #[repr(C)]
-            #[derive(Debug, Copy, Clone)]
-            pub struct LayerManager {
-                _unused: [u8; 0],
-            }
-            #[repr(C)]
-            #[derive(Debug, Copy, Clone)]
-            pub struct ContainerLayer {
-                _unused: [u8; 0],
-            }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct Layer {
                 _unused: [u8; 0],
             }
         }
         pub mod dom {
             #[allow(unused_imports)]
@@ -4573,16 +4450,21 @@ pub mod root {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct UnionMember {
                 pub mStorage: root::mozilla::AlignedStorage2,
             }
             #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
+            pub struct TabGroup {
+                _unused: [u8; 0],
+            }
+            #[repr(C)]
             pub struct DispatcherTrait__bindgen_vtable(::std::os::raw::c_void);
             #[repr(C)]
             #[derive(Debug, Copy)]
             pub struct DispatcherTrait {
                 pub vtable_: *const DispatcherTrait__bindgen_vtable,
             }
             #[test]
             fn bindgen_test_layout_DispatcherTrait() {
@@ -5976,67 +5858,67 @@ pub mod root {
      * An object implementing the .classList property for this element.
      */
                 pub mClassList: root::RefPtr<root::nsDOMTokenList>,
                 pub mExtendedSlots: root::mozilla::UniquePtr<root::mozilla::dom::FragmentOrElement_nsExtendedDOMSlots>,
             }
             #[test]
             fn bindgen_test_layout_FragmentOrElement_nsDOMSlots() {
                 assert_eq!(::std::mem::size_of::<FragmentOrElement_nsDOMSlots>()
-                           , 96usize , concat ! (
+                           , 104usize , concat ! (
                            "Size of: " , stringify ! (
                            FragmentOrElement_nsDOMSlots ) ));
                 assert_eq! (::std::mem::align_of::<FragmentOrElement_nsDOMSlots>()
                             , 8usize , concat ! (
                             "Alignment of " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) ));
                 assert_eq! (unsafe {
                             & (
                             * ( 0 as * const FragmentOrElement_nsDOMSlots ) )
-                            . mStyle as * const _ as usize } , 48usize ,
+                            . mStyle as * const _ as usize } , 56usize ,
                             concat ! (
                             "Alignment of field: " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) , "::" , stringify
                             ! ( mStyle ) ));
                 assert_eq! (unsafe {
                             & (
                             * ( 0 as * const FragmentOrElement_nsDOMSlots ) )
-                            . mDataset as * const _ as usize } , 56usize ,
+                            . mDataset as * const _ as usize } , 64usize ,
                             concat ! (
                             "Alignment of field: " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) , "::" , stringify
                             ! ( mDataset ) ));
                 assert_eq! (unsafe {
                             & (
                             * ( 0 as * const FragmentOrElement_nsDOMSlots ) )
-                            . mAttributeMap as * const _ as usize } , 64usize
+                            . mAttributeMap as * const _ as usize } , 72usize
                             , concat ! (
                             "Alignment of field: " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) , "::" , stringify
                             ! ( mAttributeMap ) ));
                 assert_eq! (unsafe {
                             & (
                             * ( 0 as * const FragmentOrElement_nsDOMSlots ) )
-                            . mChildrenList as * const _ as usize } , 72usize
+                            . mChildrenList as * const _ as usize } , 80usize
                             , concat ! (
                             "Alignment of field: " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) , "::" , stringify
                             ! ( mChildrenList ) ));
                 assert_eq! (unsafe {
                             & (
                             * ( 0 as * const FragmentOrElement_nsDOMSlots ) )
-                            . mClassList as * const _ as usize } , 80usize ,
+                            . mClassList as * const _ as usize } , 88usize ,
                             concat ! (
                             "Alignment of field: " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) , "::" , stringify
                             ! ( mClassList ) ));
                 assert_eq! (unsafe {
                             & (
                             * ( 0 as * const FragmentOrElement_nsDOMSlots ) )
-                            . mExtendedSlots as * const _ as usize } , 88usize
+                            . mExtendedSlots as * const _ as usize } , 96usize
                             , concat ! (
                             "Alignment of field: " , stringify ! (
                             FragmentOrElement_nsDOMSlots ) , "::" , stringify
                             ! ( mExtendedSlots ) ));
             }
             extern "C" {
                 #[link_name =
                       "_ZN7mozilla3dom17FragmentOrElement21_cycleCollectorGlobalE"]
@@ -7292,231 +7174,16 @@ pub mod root {
                         mFlushAnimations as * const _ as usize } , 1usize ,
                         concat ! (
                         "Alignment of field: " , stringify ! ( ChangesToFlush
                         ) , "::" , stringify ! ( mFlushAnimations ) ));
         }
         impl Clone for ChangesToFlush {
             fn clone(&self) -> Self { *self }
         }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct CSSPixel {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_CSSPixel() {
-            assert_eq!(::std::mem::size_of::<CSSPixel>() , 1usize , concat ! (
-                       "Size of: " , stringify ! ( CSSPixel ) ));
-            assert_eq! (::std::mem::align_of::<CSSPixel>() , 1usize , concat !
-                        ( "Alignment of " , stringify ! ( CSSPixel ) ));
-        }
-        impl Clone for CSSPixel {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct LayoutDevicePixel {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_LayoutDevicePixel() {
-            assert_eq!(::std::mem::size_of::<LayoutDevicePixel>() , 1usize ,
-                       concat ! (
-                       "Size of: " , stringify ! ( LayoutDevicePixel ) ));
-            assert_eq! (::std::mem::align_of::<LayoutDevicePixel>() , 1usize ,
-                        concat ! (
-                        "Alignment of " , stringify ! ( LayoutDevicePixel )
-                        ));
-        }
-        impl Clone for LayoutDevicePixel {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct LayerPixel {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_LayerPixel() {
-            assert_eq!(::std::mem::size_of::<LayerPixel>() , 1usize , concat !
-                       ( "Size of: " , stringify ! ( LayerPixel ) ));
-            assert_eq! (::std::mem::align_of::<LayerPixel>() , 1usize , concat
-                        ! ( "Alignment of " , stringify ! ( LayerPixel ) ));
-        }
-        impl Clone for LayerPixel {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct ScreenPixel {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_ScreenPixel() {
-            assert_eq!(::std::mem::size_of::<ScreenPixel>() , 1usize , concat
-                       ! ( "Size of: " , stringify ! ( ScreenPixel ) ));
-            assert_eq! (::std::mem::align_of::<ScreenPixel>() , 1usize ,
-                        concat ! (
-                        "Alignment of " , stringify ! ( ScreenPixel ) ));
-        }
-        impl Clone for ScreenPixel {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct ParentLayerPixel {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_ParentLayerPixel() {
-            assert_eq!(::std::mem::size_of::<ParentLayerPixel>() , 1usize ,
-                       concat ! (
-                       "Size of: " , stringify ! ( ParentLayerPixel ) ));
-            assert_eq! (::std::mem::align_of::<ParentLayerPixel>() , 1usize ,
-                        concat ! (
-                        "Alignment of " , stringify ! ( ParentLayerPixel ) ));
-        }
-        impl Clone for ParentLayerPixel {
-            fn clone(&self) -> Self { *self }
-        }
-        pub type CSSPoint = [u32; 2usize];
-        pub type CSSIntPoint = [u32; 2usize];
-        pub type CSSSize = [u32; 2usize];
-        pub type CSSRect = [u32; 4usize];
-        pub type LayoutDeviceIntPoint = [u32; 2usize];
-        pub type LayoutDeviceIntSize = [u32; 2usize];
-        pub type LayoutDeviceIntRect = [u32; 4usize];
-        pub type ScreenIntSize = u8;
-        pub type ScreenMargin = [u32; 4usize];
-        pub type ParentLayerRect = [u32; 4usize];
-        pub type ParentLayerIntRect = [u32; 4usize];
-        pub type CSSToLayoutDeviceScale = u32;
-        pub type CSSToParentLayerScale2D = [u32; 2usize];
-        pub type LayoutDeviceToLayerScale2D = [u32; 2usize];
-        pub type ScreenToLayerScale2D = [u32; 2usize];
-        pub type TimeStampValue = u64;
-        /**
- * Instances of this class represent moments in time, or a special
- * "null" moment. We do not use the non-monotonic system clock or
- * local time, since they can be reset, causing apparent backward
- * travel in time, which can confuse algorithms. Instead we measure
- * elapsed time according to the system.  This time can never go
- * backwards (i.e. it never wraps around, at least not in less than
- * five million years of system elapsed time). It might not advance
- * while the system is sleeping. If TimeStamp::SetNow() is not called
- * at all for hours or days, we might not notice the passage of some
- * of that time.
- *
- * We deliberately do not expose a way to convert TimeStamps to some
- * particular unit. All you can do is compute a difference between two
- * TimeStamps to get a TimeDuration. You can also add a TimeDuration
- * to a TimeStamp to get a new TimeStamp. You can't do something
- * meaningless like add two TimeStamps.
- *
- * Internally this is implemented as either a wrapper around
- *   - high-resolution, monotonic, system clocks if they exist on this
- *     platform
- *   - PRIntervalTime otherwise.  We detect wraparounds of
- *     PRIntervalTime and work around them.
- *
- * This class is similar to C++11's time_point, however it is
- * explicitly nullable and provides an IsNull() method. time_point
- * is initialized to the clock's epoch and provides a
- * time_since_epoch() method that functions similiarly. i.e.
- * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero();
- */
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct TimeStamp {
-            /**
-   * When built with PRIntervalTime, a value of 0 means this instance
-   * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
-   * and the high 32 bits represent a counter of the number of
-   * rollovers of PRIntervalTime that we've seen. This counter starts
-   * at 1 to avoid a real time colliding with the "null" value.
-   *
-   * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
-   * time to wrap around is about 2^64/100000 seconds, i.e. about
-   * 5,849,424 years.
-   *
-   * When using a system clock, a value is system dependent.
-   */
-            pub mValue: root::mozilla::TimeStampValue,
-        }
-        #[test]
-        fn bindgen_test_layout_TimeStamp() {
-            assert_eq!(::std::mem::size_of::<TimeStamp>() , 8usize , concat !
-                       ( "Size of: " , stringify ! ( TimeStamp ) ));
-            assert_eq! (::std::mem::align_of::<TimeStamp>() , 8usize , concat
-                        ! ( "Alignment of " , stringify ! ( TimeStamp ) ));
-            assert_eq! (unsafe {
-                        & ( * ( 0 as * const TimeStamp ) ) . mValue as * const
-                        _ as usize } , 0usize , concat ! (
-                        "Alignment of field: " , stringify ! ( TimeStamp ) ,
-                        "::" , stringify ! ( mValue ) ));
-        }
-        impl Clone for TimeStamp {
-            fn clone(&self) -> Self { *self }
-        }
-        /**
- * Instances of this class represent the length of an interval of time.
- * Negative durations are allowed, meaning the end is before the start.
- *
- * Internally the duration is stored as a int64_t in units of
- * PR_TicksPerSecond() when building with NSPR interval timers, or a
- * system-dependent unit when building with system clocks.  The
- * system-dependent unit must be constant, otherwise the semantics of
- * this class would be broken.
- *
- * The ValueCalculator template parameter determines how arithmetic
- * operations are performed on the integer count of ticks (mValue).
- */
-        #[repr(C)]
-        #[derive(Debug, Copy, Clone)]
-        pub struct BaseTimeDuration {
-            pub mValue: i64,
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy, Clone)]
-        pub struct BaseTimeDuration__SomethingVeryRandomHere {
-            pub _address: u8,
-        }
-        /**
- * Perform arithmetic operations on the value of a BaseTimeDuration without
- * doing strict checks on the range of values.
- */
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct TimeDurationValueCalculator {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_TimeDurationValueCalculator() {
-            assert_eq!(::std::mem::size_of::<TimeDurationValueCalculator>() ,
-                       1usize , concat ! (
-                       "Size of: " , stringify ! ( TimeDurationValueCalculator
-                       ) ));
-            assert_eq! (::std::mem::align_of::<TimeDurationValueCalculator>()
-                        , 1usize , concat ! (
-                        "Alignment of " , stringify ! (
-                        TimeDurationValueCalculator ) ));
-        }
-        impl Clone for TimeDurationValueCalculator {
-            fn clone(&self) -> Self { *self }
-        }
-        /**
- * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for
- * arithmetic on the mValue member.
- *
- * Use this class for time durations that are *not* expected to hold values of
- * Forever (or the negative equivalent) or when such time duration are *not*
- * expected to be used in arithmetic operations.
- */
-        pub type TimeDuration = root::mozilla::BaseTimeDuration;
         /**
  * EventStates is the class used to represent the event states of nsIContent
  * instances. These states are calculated by IntrinsicState() and
  * ContentStatesChanged() has to be called when one of them changes thus
  * informing the layout/style engine of the change.
  * Event states are associated with pseudo-classes.
  */
         #[repr(C)]
@@ -7540,31 +7207,41 @@ pub mod root {
                         "::" , stringify ! ( mStates ) ));
         }
         impl Clone for EventStates {
             fn clone(&self) -> Self { *self }
         }
         #[repr(i32)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum LazyComputeBehavior { Allow = 0, Assert = 1, }
-        #[repr(i32)]
-        #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-        pub enum TraversalRootBehavior {
-            Normal = 0,
-            UnstyledChildrenOnly = 1,
-        }
-        #[repr(i32)]
-        #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-        pub enum TraversalRestyleBehavior {
-            Normal = 0,
-            ForNewlyBoundElement = 1,
-            ForReconstruct = 2,
-            ForThrottledAnimationFlush = 3,
-            ForCSSRuleChanges = 4,
-        }
+        pub const ServoTraversalFlags_Empty:
+                  root::mozilla::ServoTraversalFlags =
+            0;
+        pub const ServoTraversalFlags_AnimationOnly:
+                  root::mozilla::ServoTraversalFlags =
+            1;
+        pub const ServoTraversalFlags_ForCSSRuleChanges:
+                  root::mozilla::ServoTraversalFlags =
+            2;
+        pub const ServoTraversalFlags_UnstyledChildrenOnly:
+                  root::mozilla::ServoTraversalFlags =
+            4;
+        pub const ServoTraversalFlags_Forgetful:
+                  root::mozilla::ServoTraversalFlags =
+            8;
+        pub const ServoTraversalFlags_AggressivelyForgetful:
+                  root::mozilla::ServoTraversalFlags =
+            16;
+        pub const ServoTraversalFlags_ClearDirtyDescendants:
+                  root::mozilla::ServoTraversalFlags =
+            32;
+        pub const ServoTraversalFlags_ClearAnimationOnlyDirtyDescendants:
+                  root::mozilla::ServoTraversalFlags =
+            64;
+        pub type ServoTraversalFlags = u32;
         #[repr(i32)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum StyleRuleInclusion { All = 0, DefaultOnly = 1, }
         pub const UpdateAnimationsTasks_CSSAnimations:
                   root::mozilla::UpdateAnimationsTasks =
             1;
         pub const UpdateAnimationsTasks_CSSTransitions:
                   root::mozilla::UpdateAnimationsTasks =
@@ -8058,16 +7735,135 @@ pub mod root {
                         , "::" , stringify ! ( gecko ) ));
         }
         #[repr(u8)]
         /**
  * Enumeration that represents one of the two supported style system backends.
  */
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum StyleBackendType { None = 0, Gecko = 1, Servo = 2, }
+        pub type TimeStampValue = u64;
+        /**
+ * Instances of this class represent moments in time, or a special
+ * "null" moment. We do not use the non-monotonic system clock or
+ * local time, since they can be reset, causing apparent backward
+ * travel in time, which can confuse algorithms. Instead we measure
+ * elapsed time according to the system.  This time can never go
+ * backwards (i.e. it never wraps around, at least not in less than
+ * five million years of system elapsed time). It might not advance
+ * while the system is sleeping. If TimeStamp::SetNow() is not called
+ * at all for hours or days, we might not notice the passage of some
+ * of that time.
+ *
+ * We deliberately do not expose a way to convert TimeStamps to some
+ * particular unit. All you can do is compute a difference between two
+ * TimeStamps to get a TimeDuration. You can also add a TimeDuration
+ * to a TimeStamp to get a new TimeStamp. You can't do something
+ * meaningless like add two TimeStamps.
+ *
+ * Internally this is implemented as either a wrapper around
+ *   - high-resolution, monotonic, system clocks if they exist on this
+ *     platform
+ *   - PRIntervalTime otherwise.  We detect wraparounds of
+ *     PRIntervalTime and work around them.
+ *
+ * This class is similar to C++11's time_point, however it is
+ * explicitly nullable and provides an IsNull() method. time_point
+ * is initialized to the clock's epoch and provides a
+ * time_since_epoch() method that functions similiarly. i.e.
+ * t.IsNull() is equivalent to t.time_since_epoch() == decltype(t)::duration::zero();
+ */
+        #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct TimeStamp {
+            /**
+   * When built with PRIntervalTime, a value of 0 means this instance
+   * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
+   * and the high 32 bits represent a counter of the number of
+   * rollovers of PRIntervalTime that we've seen. This counter starts
+   * at 1 to avoid a real time colliding with the "null" value.
+   *
+   * PR_INTERVAL_MAX is set at 100,000 ticks per second. So the minimum
+   * time to wrap around is about 2^64/100000 seconds, i.e. about
+   * 5,849,424 years.
+   *
+   * When using a system clock, a value is system dependent.
+   */
+            pub mValue: root::mozilla::TimeStampValue,
+        }
+        #[test]
+        fn bindgen_test_layout_TimeStamp() {
+            assert_eq!(::std::mem::size_of::<TimeStamp>() , 8usize , concat !
+                       ( "Size of: " , stringify ! ( TimeStamp ) ));
+            assert_eq! (::std::mem::align_of::<TimeStamp>() , 8usize , concat
+                        ! ( "Alignment of " , stringify ! ( TimeStamp ) ));
+            assert_eq! (unsafe {
+                        & ( * ( 0 as * const TimeStamp ) ) . mValue as * const
+                        _ as usize } , 0usize , concat ! (
+                        "Alignment of field: " , stringify ! ( TimeStamp ) ,
+                        "::" , stringify ! ( mValue ) ));
+        }
+        impl Clone for TimeStamp {
+            fn clone(&self) -> Self { *self }
+        }
+        /**
+ * Instances of this class represent the length of an interval of time.
+ * Negative durations are allowed, meaning the end is before the start.
+ *
+ * Internally the duration is stored as a int64_t in units of
+ * PR_TicksPerSecond() when building with NSPR interval timers, or a
+ * system-dependent unit when building with system clocks.  The
+ * system-dependent unit must be constant, otherwise the semantics of
+ * this class would be broken.
+ *
+ * The ValueCalculator template parameter determines how arithmetic
+ * operations are performed on the integer count of ticks (mValue).
+ */
+        #[repr(C)]
+        #[derive(Debug, Copy, Clone)]
+        pub struct BaseTimeDuration {
+            pub mValue: i64,
+        }
+        #[repr(C)]
+        #[derive(Debug, Copy, Clone)]
+        pub struct BaseTimeDuration__SomethingVeryRandomHere {
+            pub _address: u8,
+        }
+        /**
+ * Perform arithmetic operations on the value of a BaseTimeDuration without
+ * doing strict checks on the range of values.
+ */
+        #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct TimeDurationValueCalculator {
+            pub _address: u8,
+        }
+        #[test]
+        fn bindgen_test_layout_TimeDurationValueCalculator() {
+            assert_eq!(::std::mem::size_of::<TimeDurationValueCalculator>() ,
+                       1usize , concat ! (
+                       "Size of: " , stringify ! ( TimeDurationValueCalculator
+                       ) ));
+            assert_eq! (::std::mem::align_of::<TimeDurationValueCalculator>()
+                        , 1usize , concat ! (
+                        "Alignment of " , stringify ! (
+                        TimeDurationValueCalculator ) ));
+        }
+        impl Clone for TimeDurationValueCalculator {
+            fn clone(&self) -> Self { *self }
+        }
+        /**
+ * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for
+ * arithmetic on the mValue member.
+ *
+ * Use this class for time durations that are *not* expected to hold values of
+ * Forever (or the negative equivalent) or when such time duration are *not*
+ * expected to be used in arithmetic operations.
+ */
+        pub type TimeDuration = root::mozilla::BaseTimeDuration;
         #[repr(C)]
         #[derive(Debug, Copy)]
         pub struct ErrorResult {
             pub _bindgen_opaque_blob: [u64; 4usize],
         }
         pub type ErrorResult_BaseErrorResult =
             root::mozilla::binding_danger::TErrorResult;
         #[test]
@@ -8914,16 +8710,112 @@ pub mod root {
             eIMEConvertedClause = 16,
             eIMESelectedClause = 32,
             eAccessibility = 64,
             eFind = 128,
             eURLSecondary = 256,
             eURLStrikeout = 512,
         }
         #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct CSSPixel {
+            pub _address: u8,
+        }
+        #[test]
+        fn bindgen_test_layout_CSSPixel() {
+            assert_eq!(::std::mem::size_of::<CSSPixel>() , 1usize , concat ! (
+                       "Size of: " , stringify ! ( CSSPixel ) ));
+            assert_eq! (::std::mem::align_of::<CSSPixel>() , 1usize , concat !
+                        ( "Alignment of " , stringify ! ( CSSPixel ) ));
+        }
+        impl Clone for CSSPixel {
+            fn clone(&self) -> Self { *self }
+        }
+        #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct LayoutDevicePixel {
+            pub _address: u8,
+        }
+        #[test]
+        fn bindgen_test_layout_LayoutDevicePixel() {
+            assert_eq!(::std::mem::size_of::<LayoutDevicePixel>() , 1usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( LayoutDevicePixel ) ));
+            assert_eq! (::std::mem::align_of::<LayoutDevicePixel>() , 1usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( LayoutDevicePixel )
+                        ));
+        }
+        impl Clone for LayoutDevicePixel {
+            fn clone(&self) -> Self { *self }
+        }
+        #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct LayerPixel {
+            pub _address: u8,
+        }
+        #[test]
+        fn bindgen_test_layout_LayerPixel() {
+            assert_eq!(::std::mem::size_of::<LayerPixel>() , 1usize , concat !
+                       ( "Size of: " , stringify ! ( LayerPixel ) ));
+            assert_eq! (::std::mem::align_of::<LayerPixel>() , 1usize , concat
+                        ! ( "Alignment of " , stringify ! ( LayerPixel ) ));
+        }
+        impl Clone for LayerPixel {
+            fn clone(&self) -> Self { *self }
+        }
+        #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct ScreenPixel {
+            pub _address: u8,
+        }
+        #[test]
+        fn bindgen_test_layout_ScreenPixel() {
+            assert_eq!(::std::mem::size_of::<ScreenPixel>() , 1usize , concat
+                       ! ( "Size of: " , stringify ! ( ScreenPixel ) ));
+            assert_eq! (::std::mem::align_of::<ScreenPixel>() , 1usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( ScreenPixel ) ));
+        }
+        impl Clone for ScreenPixel {
+            fn clone(&self) -> Self { *self }
+        }
+        #[repr(C)]
+        #[derive(Debug, Copy)]
+        pub struct ParentLayerPixel {
+            pub _address: u8,
+        }
+        #[test]
+        fn bindgen_test_layout_ParentLayerPixel() {
+            assert_eq!(::std::mem::size_of::<ParentLayerPixel>() , 1usize ,
+                       concat ! (
+                       "Size of: " , stringify ! ( ParentLayerPixel ) ));
+            assert_eq! (::std::mem::align_of::<ParentLayerPixel>() , 1usize ,
+                        concat ! (
+                        "Alignment of " , stringify ! ( ParentLayerPixel ) ));
+        }
+        impl Clone for ParentLayerPixel {
+            fn clone(&self) -> Self { *self }
+        }
+        pub type CSSPoint = [u32; 2usize];
+        pub type CSSIntPoint = [u32; 2usize];
+        pub type CSSSize = [u32; 2usize];
+        pub type CSSRect = [u32; 4usize];
+        pub type LayoutDeviceIntPoint = [u32; 2usize];
+        pub type LayoutDeviceIntSize = [u32; 2usize];
+        pub type LayoutDeviceIntRect = [u32; 4usize];
+        pub type ScreenIntSize = u8;
+        pub type ScreenMargin = [u32; 4usize];
+        pub type ParentLayerRect = [u32; 4usize];
+        pub type ParentLayerIntRect = [u32; 4usize];
+        pub type CSSToLayoutDeviceScale = u32;
+        pub type CSSToParentLayerScale2D = [u32; 2usize];
+        pub type LayoutDeviceToLayerScale2D = [u32; 2usize];
+        pub type ScreenToLayerScale2D = [u32; 2usize];
+        #[repr(C)]
         #[derive(Debug, Copy, Clone)]
         pub struct AccessibleCaretEventHub {
             _unused: [u8; 0],
         }
         pub mod a11y {
             #[allow(unused_imports)]
             use self::super::super::super::root;
             #[repr(C)]
@@ -9045,17 +8937,17 @@ pub mod root {
             eUseCounter_MozGetAsFile = 66,
             eUseCounter_UseOfCaptureEvents = 67,
             eUseCounter_UseOfReleaseEvents = 68,
             eUseCounter_UseOfDOM3LoadMethod = 69,
             eUseCounter_ChromeUseOfDOM3LoadMethod = 70,
             eUseCounter_ShowModalDialog = 71,
             eUseCounter_Window_Content = 72,
             eUseCounter_SyncXMLHttpRequest = 73,
-            eUseCounter_Window_Controllers = 74,
+            eUseCounter_Window_Cc_ontrollers = 74,
             eUseCounter_ImportXULIntoContent = 75,
             eUseCounter_PannerNodeDoppler = 76,
             eUseCounter_NavigatorGetUserMedia = 77,
             eUseCounter_WebrtcDeprecatedPrefix = 78,
             eUseCounter_RTCPeerConnectionGetStreams = 79,
             eUseCounter_AppCache = 80,
             eUseCounter_PrefixedImageSmoothingEnabled = 81,
             eUseCounter_PrefixedFullscreenAPI = 82,
@@ -9549,16 +9441,17 @@ pub mod root {
             pub mAcquired: root::mozilla::BlockingResourceBase_AcquisitionState,
         }
         #[repr(u32)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum BlockingResourceBase_BlockingResourceType {
             eMutex = 0,
             eReentrantMonitor = 1,
             eCondVar = 2,
+            eRecursiveMutex = 3,
         }
         pub type BlockingResourceBase_DDT = root::mozilla::DeadlockDetector;
         pub type BlockingResourceBase_AcquisitionState = bool;
         extern "C" {
             #[link_name =
                   "_ZN7mozilla20BlockingResourceBase17kResourceTypeNameE"]
             pub static mut BlockingResourceBase_kResourceTypeName:
                        [*const ::std::os::raw::c_char; 0usize];
@@ -17483,1387 +17376,16 @@ pub mod root {
  */
     #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     pub enum nsEventStatus {
         nsEventStatus_eIgnore = 0,
         nsEventStatus_eConsumeNoDefault = 1,
         nsEventStatus_eConsumeDoDefault = 2,
         nsEventStatus_eSentinel = 3,
     }
-    pub type gfxSize = [u64; 2usize];
-    pub type nsIntRect = root::mozilla::gfx::IntRect;
-    #[repr(C)]
-    #[derive(Debug, Copy)]
-    pub struct pixman_region32_data {
-        pub size: ::std::os::raw::c_long,
-        pub numRects: ::std::os::raw::c_long,
-    }
-    #[test]
-    fn bindgen_test_layout_pixman_region32_data() {
-        assert_eq!(::std::mem::size_of::<pixman_region32_data>() , 16usize ,
-                   concat ! (
-                   "Size of: " , stringify ! ( pixman_region32_data ) ));
-        assert_eq! (::std::mem::align_of::<pixman_region32_data>() , 8usize ,
-                    concat ! (
-                    "Alignment of " , stringify ! ( pixman_region32_data ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_region32_data ) ) . size as *
-                    const _ as usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! (
-                    pixman_region32_data ) , "::" , stringify ! ( size ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_region32_data ) ) . numRects
-                    as * const _ as usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! (
-                    pixman_region32_data ) , "::" , stringify ! ( numRects )
-                    ));
-    }
-    impl Clone for pixman_region32_data {
-        fn clone(&self) -> Self { *self }
-    }
-    pub type pixman_region32_data_t = root::pixman_region32_data;
-    #[repr(C)]
-    #[derive(Debug, Copy)]
-    pub struct pixman_box32 {
-        pub x1: i32,
-        pub y1: i32,
-        pub x2: i32,
-        pub y2: i32,
-    }
-    #[test]
-    fn bindgen_test_layout_pixman_box32() {
-        assert_eq!(::std::mem::size_of::<pixman_box32>() , 16usize , concat !
-                   ( "Size of: " , stringify ! ( pixman_box32 ) ));
-        assert_eq! (::std::mem::align_of::<pixman_box32>() , 4usize , concat !
-                    ( "Alignment of " , stringify ! ( pixman_box32 ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_box32 ) ) . x1 as * const _ as
-                    usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( pixman_box32 ) ,
-                    "::" , stringify ! ( x1 ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_box32 ) ) . y1 as * const _ as
-                    usize } , 4usize , concat ! (
-                    "Alignment of field: " , stringify ! ( pixman_box32 ) ,
-                    "::" , stringify ! ( y1 ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_box32 ) ) . x2 as * const _ as
-                    usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( pixman_box32 ) ,
-                    "::" , stringify ! ( x2 ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_box32 ) ) . y2 as * const _ as
-                    usize } , 12usize , concat ! (
-                    "Alignment of field: " , stringify ! ( pixman_box32 ) ,
-                    "::" , stringify ! ( y2 ) ));
-    }
-    impl Clone for pixman_box32 {
-        fn clone(&self) -> Self { *self }
-    }
-    pub type pixman_box32_t = root::pixman_box32;
-    #[repr(C)]
-    #[derive(Debug, Copy)]
-    pub struct pixman_region32 {
-        pub extents: root::pixman_box32_t,
-        pub data: *mut root::pixman_region32_data_t,
-    }
-    #[test]
-    fn bindgen_test_layout_pixman_region32() {
-        assert_eq!(::std::mem::size_of::<pixman_region32>() , 24usize , concat
-                   ! ( "Size of: " , stringify ! ( pixman_region32 ) ));
-        assert_eq! (::std::mem::align_of::<pixman_region32>() , 8usize ,
-                    concat ! (
-                    "Alignment of " , stringify ! ( pixman_region32 ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_region32 ) ) . extents as *
-                    const _ as usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( pixman_region32 ) ,
-                    "::" , stringify ! ( extents ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const pixman_region32 ) ) . data as * const
-                    _ as usize } , 16usize , concat ! (
-                    "Alignment of field: " , stringify ! ( pixman_region32 ) ,
-                    "::" , stringify ! ( data ) ));
-    }
-    impl Clone for pixman_region32 {
-        fn clone(&self) -> Self { *self }
-    }
-    pub type pixman_region32_t = root::pixman_region32;
-    #[repr(i32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum VisitSide { TOP = 0, BOTTOM = 1, LEFT = 2, RIGHT = 3, }
-    /**
- * Presentation shell interface. Presentation shells are the
- * controlling point for managing the presentation of a document. The
- * presentation shell holds a live reference to the document, the
- * presentation context, the style manager, the style set and the root
- * frame. <p>
- *
- * When this object is Release'd, it will release the document, the
- * presentation context, the style manager, the style set and the root
- * frame.
- */
-    #[repr(C)]
-    pub struct nsIPresShell {
-        pub _base: root::nsISupports,
-        pub mDocument: root::nsCOMPtr<root::nsIDocument>,
-        pub mPresContext: root::RefPtr<root::nsPresContext>,
-        pub mStyleSet: root::mozilla::StyleSetHandle,
-        pub mFrameConstructor: *mut root::nsCSSFrameConstructor,
-        pub mViewManager: *mut root::nsViewManager,
-        pub mFrameArena: root::nsPresArena,
-        pub mSelection: root::RefPtr<root::nsFrameSelection>,
-        pub mFrameManager: *mut root::nsFrameManagerBase,
-        pub mForwardingContainer: u64,
-        pub mDocAccessible: *mut root::mozilla::a11y::DocAccessible,
-        pub mReflowContinueTimer: root::nsCOMPtr<root::nsITimer>,
-        pub mDrawEventTargetFrame: *mut root::nsIFrame,
-        pub mAllocatedPointers: [u64; 6usize],
-        pub mPaintCount: u64,
-        pub mScrollPositionClampingScrollPortSize: root::nsSize,
-        pub mAutoWeakFrames: *mut root::AutoWeakFrame,
-        pub mWeakFrames: [u64; 6usize],
-        pub mCanvasBackgroundColor: root::nscolor,
-        pub mResolution: [u32; 2usize],
-        pub mSelectionFlags: i16,
-        pub mRenderFlags: root::nsIPresShell_RenderFlags,
-        pub _bitfield_1: [u8; 2usize],
-        pub mPresShellId: u32,
-        pub mFontSizeInflationEmPerLine: u32,
-        pub mFontSizeInflationMinTwips: u32,
-        pub mFontSizeInflationLineThreshold: u32,
-        pub mFontSizeInflationForceEnabled: bool,
-        pub mFontSizeInflationDisabledInMasterProcess: bool,
-        pub mFontSizeInflationEnabled: bool,
-        pub mFontSizeInflationEnabledIsDirty: bool,
-        pub mPaintingIsFrozen: bool,
-        pub mIsNeverPainting: bool,
-        pub mInFlush: bool,
-    }
-    #[repr(C)]
-    #[derive(Debug, Copy, Clone)]
-    pub struct nsIPresShell_COMTypeInfo {
-        pub _address: u8,
-    }
-    pub type nsIPresShell_FocusTarget = root::mozilla::layers::FocusTarget;
-    pub type nsIPresShell_LayerManager = root::mozilla::layers::LayerManager;
-    pub type nsIPresShell_SourceSurface = root::mozilla::gfx::SourceSurface;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsIPresShell_eRenderFlag {
-        STATE_IGNORING_VIEWPORT_SCROLLING = 1,
-        STATE_DRAWWINDOW_NOT_FLUSHING = 2,
-    }
-    pub type nsIPresShell_RenderFlags = u8;
-    #[repr(u32)]
-    /**
-   * Gets nearest scrollable frame from the specified content node. The frame
-   * is scrollable with overflow:scroll or overflow:auto in some direction when
-   * aDirection is eEither.  Otherwise, this returns a nearest frame that is
-   * scrollable in the specified direction.
-   */
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsIPresShell_ScrollDirection {
-        eHorizontal = 0,
-        eVertical = 1,
-        eEither = 2,
-    }
-    #[repr(u32)]
-    /**
-   * Tell the pres shell that a frame needs to be marked dirty and needs
-   * Reflow.  It's OK if this is an ancestor of the frame needing reflow as
-   * long as the ancestor chain between them doesn't cross a reflow root.
-   *
-   * The bit to add should be NS_FRAME_IS_DIRTY, NS_FRAME_HAS_DIRTY_CHILDREN
-   * or nsFrameState(0); passing 0 means that dirty bits won't be set on the
-   * frame or its ancestors/descendants, but that intrinsic widths will still
-   * be marked dirty.  Passing aIntrinsicDirty = eResize and aBitToAdd = 0
-   * would result in no work being done, so don't do that.
-   */
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsIPresShell_IntrinsicDirty {
-        eResize = 0,
-        eTreeChange = 1,
-        eStyleChange = 2,
-    }
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsIPresShell_ReflowRootHandling {
-        ePositionOrSizeChange = 0,
-        eNoPositionOrSizeChange = 1,
-        eInferFromBitToAdd = 2,
-    }
-    pub const nsIPresShell_SCROLL_TOP: root::nsIPresShell__bindgen_ty_1 =
-        nsIPresShell__bindgen_ty_1::SCROLL_TOP;
-    pub const nsIPresShell_SCROLL_BOTTOM: root::nsIPresShell__bindgen_ty_1 =
-        nsIPresShell__bindgen_ty_1::SCROLL_BOTTOM;
-    pub const nsIPresShell_SCROLL_LEFT: root::nsIPresShell__bindgen_ty_1 =
-        nsIPresShell__bindgen_ty_1::SCROLL_TOP;
-    pub const nsIPresShell_SCROLL_RIGHT: root::nsIPresShell__bindgen_ty_1 =
-        nsIPresShell__bindgen_ty_1::SCROLL_BOTTOM;
-    pub const nsIPresShell_SCROLL_CENTER: root::nsIPresShell__bindgen_ty_1 =
-        nsIPresShell__bindgen_ty_1::SCROLL_CENTER;
-    pub const nsIPresShell_SCROLL_MINIMUM: root::nsIPresShell__bindgen_ty_1 =
-        nsIPresShell__bindgen_ty_1::SCROLL_MINIMUM;
-    #[repr(i32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsIPresShell__bindgen_ty_1 {
-        SCROLL_TOP = 0,
-        SCROLL_BOTTOM = 100,
-        SCROLL_CENTER = 50,
-        SCROLL_MINIMUM = -1,
-    }
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsIPresShell_WhenToScroll {
-        SCROLL_ALWAYS = 0,
-        SCROLL_IF_NOT_VISIBLE = 1,
-        SCROLL_IF_NOT_FULLY_VISIBLE = 2,
-    }
-    #[repr(C)]
-    #[derive(Debug, Copy)]
-    pub struct nsIPresShell_ScrollAxis {
-        pub _bindgen_opaque_blob: u32,
-    }
-    #[test]
-    fn bindgen_test_layout_nsIPresShell_ScrollAxis() {
-        assert_eq!(::std::mem::size_of::<nsIPresShell_ScrollAxis>() , 4usize ,
-                   concat ! (
-                   "Size of: " , stringify ! ( nsIPresShell_ScrollAxis ) ));
-        assert_eq! (::std::mem::align_of::<nsIPresShell_ScrollAxis>() , 4usize
-                    , concat ! (
-                    "Alignme