Merge mozilla-central to inbound. a=merge CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Thu, 14 Jun 2018 12:46:52 +0300
changeset 422541 3c88a15bdd51
parent 422540 24142d07f73e (current diff)
parent 422525 91db0c695f02 (diff)
child 422542 ebe097110cd2
push id34138
push userdluca@mozilla.com
push dateFri, 15 Jun 2018 02:39:59 +0000
treeherdermozilla-central@e51f8dbf0397 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.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 inbound. a=merge CLOSED TREE
build/build-clang/clang-4-linux64.json
build/build-clang/clang-macosx64.json
build/build-clang/pr28831-r280042.patch
layout/style/ServoCounterStyleRule.cpp
layout/style/ServoCounterStyleRule.h
layout/style/ServoDocumentRule.cpp
layout/style/ServoDocumentRule.h
layout/style/ServoFontFaceRule.cpp
layout/style/ServoFontFaceRule.h
layout/style/ServoFontFeatureValuesRule.cpp
layout/style/ServoFontFeatureValuesRule.h
layout/style/ServoImportRule.cpp
layout/style/ServoImportRule.h
layout/style/ServoKeyframeRule.cpp
layout/style/ServoKeyframeRule.h
layout/style/ServoKeyframesRule.cpp
layout/style/ServoKeyframesRule.h
layout/style/ServoMediaRule.cpp
layout/style/ServoMediaRule.h
layout/style/ServoNamespaceRule.cpp
layout/style/ServoNamespaceRule.h
layout/style/ServoPageRule.cpp
layout/style/ServoPageRule.h
layout/style/ServoStyleRule.cpp
layout/style/ServoStyleRule.h
layout/style/ServoSupportsRule.cpp
layout/style/ServoSupportsRule.h
taskcluster/scripts/misc/build-clang-4-linux.sh
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2456,16 +2456,22 @@ function BrowserOpenFileWindow() {
 
 function BrowserCloseTabOrWindow(event) {
   // If we're not a browser window, just close the window.
   if (window.location.href != getBrowserURL()) {
     closeWindow(true);
     return;
   }
 
+  // In a multi-select context, close all selected tabs
+  if (gBrowser.multiSelectedTabsCount) {
+    gBrowser.removeMultiSelectedTabs();
+    return;
+  }
+
   // Keyboard shortcuts that would close a tab that is pinned select the first
   // unpinned tab instead.
   if (event &&
       (event.ctrlKey || event.metaKey || event.altKey) &&
       gBrowser.selectedTab.pinned) {
     if (gBrowser.visibleTabs.length > gBrowser._numPinnedTabs) {
       gBrowser.tabContainer.selectedIndex = gBrowser._numPinnedTabs;
     }
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -3768,19 +3768,22 @@ window._gBrowser = {
           this.moveTabForward();
           aEvent.preventDefault();
           return;
       }
     }
 
     if (AppConstants.platform != "macosx") {
       if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
-          aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
-          !this.selectedTab.pinned) {
-        this.removeCurrentTab({ animate: true });
+          aEvent.keyCode == KeyEvent.DOM_VK_F4) {
+        if (gBrowser.multiSelectedTabsCount) {
+          gBrowser.removeMultiSelectedTabs();
+        } else if (!this.selectedTab.pinned) {
+          this.removeCurrentTab({ animate: true });
+        }
         aEvent.preventDefault();
       }
     }
   },
 
   _handleKeyPressEventMac(aEvent) {
     if (!aEvent.isTrusted) {
       // Don't let untrusted events mess with tabs.
--- a/browser/base/content/test/tabs/browser.ini
+++ b/browser/base/content/test/tabs/browser.ini
@@ -44,8 +44,9 @@ skip-if = (debug && os == 'mac') || (deb
 [browser_visibleTabs_bookmarkAllTabs.js]
 [browser_visibleTabs_contextMenu.js]
 [browser_open_newtab_start_observer_notification.js]
 [browser_bug_1387976_restore_lazy_tab_browser_muted_state.js]
 [browser_multiselect_tabs_using_Ctrl.js]
 [browser_multiselect_tabs_using_Shift.js]
 [browser_multiselect_tabs_close.js]
 [browser_multiselect_tabs_positional_attrs.js]
+[browser_multiselect_tabs_close_using_shortcuts.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabs/browser_multiselect_tabs_close_using_shortcuts.js
@@ -0,0 +1,67 @@
+const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
+const PREF_WARN_ON_CLOSE = "browser.tabs.warnOnCloseOtherTabs";
+
+add_task(async function setPref() {
+  await SpecialPowers.pushPrefEnv({
+    set: [
+      [PREF_MULTISELECT_TABS, true],
+      [PREF_WARN_ON_CLOSE, false]
+    ]
+  });
+});
+
+add_task(async function using_Ctrl_W() {
+  for (let key of ["w", "VK_F4"]) {
+    let tab1 = await addTab();
+    let tab2 = await addTab();
+    let tab3 = await addTab();
+    let tab4 = await addTab();
+
+    await BrowserTestUtils.switchTab(gBrowser, triggerClickOn(tab1, {}));
+
+    is(gBrowser.multiSelectedTabsCount, 0, "Zero multiselected tabs");
+
+    await triggerClickOn(tab2, { ctrlKey: true });
+    await triggerClickOn(tab3, { ctrlKey: true });
+
+    is(gBrowser.selectedTab, tab1, "Tab1 is focused");
+    ok(!tab1.multiselected, "Tab1 is not multiselected");
+    ok(tab2.multiselected, "Tab2 is multiselected");
+    ok(tab3.multiselected, "Tab3 is multiselected");
+    ok(!tab4.multiselected, "Tab4 is not multiselected");
+    is(gBrowser.multiSelectedTabsCount, 2, "Two multiselected tabs");
+
+    let tab2Closing = BrowserTestUtils.waitForTabClosing(tab2);
+    let tab3Closing = BrowserTestUtils.waitForTabClosing(tab3);
+
+    EventUtils.synthesizeKey(key, { accelKey: true });
+
+    // On OSX, Cmd+F4 should not close tabs.
+    const shouldBeClosing = key == "w" || AppConstants.platform != "macosx";
+
+    if (shouldBeClosing) {
+      await tab2Closing;
+      await tab3Closing;
+    }
+
+    is(gBrowser.selectedTab, tab1, "Tab1 is still focused");
+    ok(!tab1.closing, "Tab1 is not closing");
+    ok(!tab4.closing, "Tab4 is not closing");
+
+    if (shouldBeClosing) {
+      ok(tab2.closing, "Tab2 is closing");
+      ok(tab3.closing, "Tab3 is closing");
+      is(gBrowser.multiSelectedTabsCount, 0, "Zero multiselected tabs");
+    } else {
+      ok(!tab2.closing, "Tab2 is not closing");
+      ok(!tab3.closing, "Tab3 is not closing");
+      is(gBrowser.multiSelectedTabsCount, 2, "Still Two multiselected tabs");
+
+      BrowserTestUtils.removeTab(tab2);
+      BrowserTestUtils.removeTab(tab3);
+    }
+
+    BrowserTestUtils.removeTab(tab1);
+    BrowserTestUtils.removeTab(tab4);
+  }
+});
--- a/browser/components/payments/content/paymentDialogFrameScript.js
+++ b/browser/components/payments/content/paymentDialogFrameScript.js
@@ -57,22 +57,16 @@ let PaymentFrameScript = {
     let contentLogObject = Cu.waiveXrays(content).log;
     for (let name of ["error", "warn", "info", "debug"]) {
       Cu.exportFunction(privilegedLogger[name].bind(privilegedLogger), contentLogObject, {
         defineAs: name,
       });
     }
   },
 
-  setupL10n() {
-    // Until we have bug 1446164 and bug 1407418 we use form autofill's temporary
-    // shim for data-localization* attributes.
-    Services.scriptloader.loadSubScript("chrome://formautofill/content/l10n.js");
-  },
-
   /**
    * Expose privileged utility functions to the unprivileged page.
    */
   exposeUtilityFunctions() {
     let waivedContent = Cu.waiveXrays(content);
     let PaymentDialogUtils = {
       DEFAULT_REGION: FormAutofillUtils.DEFAULT_REGION,
       supportedCountries: FormAutofillUtils.supportedCountries,
@@ -94,17 +88,16 @@ let PaymentFrameScript = {
       cloneFunctions: true,
     });
   },
 
   sendToChrome({detail}) {
     let {messageType} = detail;
     if (messageType == "initializeRequest") {
       this.setupContentConsole();
-      this.setupL10n();
       this.exposeUtilityFunctions();
     }
     this.log.debug("sendToChrome:", messageType, detail);
     this.sendMessageToChrome(messageType, detail);
   },
 
   sendToContent(messageType, detail = {}) {
     this.log.debug("sendToContent", messageType, detail);
--- a/browser/components/payments/content/paymentDialogWrapper.js
+++ b/browser/components/payments/content/paymentDialogWrapper.js
@@ -188,16 +188,19 @@ var paymentDialogWrapper = {
     if (!this.request) {
       throw new Error(`PaymentRequest not found: ${requestId}`);
     }
 
     this.frame = frame;
     this.mm = frame.frameLoader.messageManager;
     this.mm.addMessageListener("paymentContentToChrome", this);
     this.mm.loadFrameScript("chrome://payments/content/paymentDialogFrameScript.js", true);
+    // Until we have bug 1446164 and bug 1407418 we use form autofill's temporary
+    // shim for data-localization* attributes.
+    this.mm.loadFrameScript("chrome://formautofill/content/l10n.js", true);
     if (AppConstants.platform == "win") {
       this.frame.setAttribute("selectmenulist", "ContentSelectDropdown-windows");
     }
     this.frame.loadURI("resource://payments/paymentRequest.xhtml");
 
     this.temporaryStore = {
       addresses: new TempCollection(),
       creditCards: new TempCollection(),
--- a/browser/components/payments/res/components/rich-select.css
+++ b/browser/components/payments/res/components/rich-select.css
@@ -23,11 +23,10 @@ rich-select[open] > .rich-select-popup-b
 .rich-select-popup-box > .rich-option[selected] {
   background-color: #ffa;
 }
 
 .rich-option {
   display: grid;
   border-bottom: 1px solid #ddd;
   background: #fff; /* TODO: system colors */
-  padding: 5px 20px;
-  font-size: .8em;
+  padding: 8px;
 }
--- a/browser/components/payments/res/components/shipping-option.css
+++ b/browser/components/payments/res/components/shipping-option.css
@@ -1,24 +1,12 @@
 /* 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/. */
 
-shipping-option {
-  grid-row-gap: 5px;
-  grid-column-gap: 10px;
-  grid-template-areas:
-    "label amount";
-}
-
-shipping-option > .label {
-  grid-area: label;
-  font-weight: bold;
-}
-
-shipping-option > .amount {
-  grid-area: amount;
+shipping-option.rich-option {
+  display: block;
 }
 
 shipping-option > .label,
 shipping-option > .amount {
   white-space: nowrap;
 }
--- a/browser/components/payments/res/components/shipping-option.js
+++ b/browser/components/payments/res/components/shipping-option.js
@@ -28,16 +28,17 @@ export default class ShippingOption exte
     this._currencyAmount = new CurrencyAmount();
     this._currencyAmount.classList.add("amount");
     this._label = document.createElement("span");
     this._label.classList.add("label");
   }
 
   connectedCallback() {
     this.appendChild(this._currencyAmount);
+    this.append(" ");
     this.appendChild(this._label);
     super.connectedCallback();
   }
 
   render() {
     this._label.textContent = this.label;
     this._currencyAmount.currency = this.amountCurrency;
     this._currencyAmount.value = this.amountValue;
--- a/browser/components/payments/res/containers/address-form.js
+++ b/browser/components/payments/res/containers/address-form.js
@@ -14,29 +14,29 @@ import paymentRequest from "../paymentRe
  * XXX: Bug 1446164 - This form isn't localized when used via this custom element
  * as it will be much easier to share the logic once we switch to Fluent.
  */
 
 export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement) {
   constructor() {
     super();
 
-    this.pageTitle = document.createElement("h1");
+    this.pageTitle = document.createElement("h2");
     this.genericErrorText = document.createElement("div");
 
     this.cancelButton = document.createElement("button");
     this.cancelButton.className = "cancel-button";
     this.cancelButton.addEventListener("click", this);
 
     this.backButton = document.createElement("button");
     this.backButton.className = "back-button";
     this.backButton.addEventListener("click", this);
 
     this.saveButton = document.createElement("button");
-    this.saveButton.className = "save-button";
+    this.saveButton.className = "save-button primary";
     this.saveButton.addEventListener("click", this);
 
     this.persistCheckbox = new LabelledCheckbox();
 
     this._errorFieldMap = {
       addressLine: "#street-address-container",
       city: "#address-level2-container",
       country: "#country-container",
--- a/browser/components/payments/res/containers/basic-card-form.js
+++ b/browser/components/payments/res/containers/basic-card-form.js
@@ -15,17 +15,17 @@ import paymentRequest from "../paymentRe
  * XXX: Bug 1446164 - This form isn't localized when used via this custom element
  * as it will be much easier to share the logic once we switch to Fluent.
  */
 
 export default class BasicCardForm extends PaymentStateSubscriberMixin(HTMLElement) {
   constructor() {
     super();
 
-    this.pageTitle = document.createElement("h1");
+    this.pageTitle = document.createElement("h2");
     this.genericErrorText = document.createElement("div");
 
     this.cancelButton = document.createElement("button");
     this.cancelButton.className = "cancel-button";
     this.cancelButton.addEventListener("click", this);
 
     this.addressAddLink = document.createElement("a");
     this.addressAddLink.className = "add-link";
@@ -36,17 +36,17 @@ export default class BasicCardForm exten
     this.addressEditLink.href = "javascript:void(0)";
     this.addressEditLink.addEventListener("click", this);
 
     this.backButton = document.createElement("button");
     this.backButton.className = "back-button";
     this.backButton.addEventListener("click", this);
 
     this.saveButton = document.createElement("button");
-    this.saveButton.className = "save-button";
+    this.saveButton.className = "save-button primary";
     this.saveButton.addEventListener("click", this);
 
     this.persistCheckbox = new LabelledCheckbox();
 
     // The markup is shared with form autofill preferences.
     let url = "formautofill/editCreditCard.xhtml";
     this.promiseReady = this._fetchMarkup(url).then(doc => {
       this.form = doc.getElementById("form");
--- a/browser/components/payments/res/containers/order-details.css
+++ b/browser/components/payments/res/containers/order-details.css
@@ -42,10 +42,10 @@ order-details > .details-total {
   margin: 0;
   font-size: large;
   grid-column-start: 2;
   grid-column-end: 3;
   text-align: end;
 }
 .details-total > currency-amount {
   font-size: large;
-  text-align: start;
+  text-align: end;
 }
--- a/browser/components/payments/res/debugging.css
+++ b/browser/components/payments/res/debugging.css
@@ -1,11 +1,21 @@
 /* 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/. */
 
+html {
+  /* Based on global.css styles for top-level XUL windows */
+  -moz-appearance: dialog;
+  background-color: -moz-Dialog;
+  color: -moz-DialogText;
+  font: message-box;
+  /* Make sure the background ends to the bottom if there is unused space */
+  height: 100%;
+}
+
 h1 {
   font-size: 1em;
 }
 
 fieldset > label {
   white-space: nowrap;
 }
--- a/browser/components/payments/res/debugging.js
+++ b/browser/components/payments/res/debugging.js
@@ -117,17 +117,17 @@ let REQUEST_2 = {
         },
         selected: true,
       },
       {
         id: "947",
         label: "Slow",
         amount: {
           currency: "USD",
-          value: 10,
+          value: 1,
         },
         selected: false,
       },
     ],
     modifiers: [
       {
         supportedMethods: "basic-card",
         total: {
--- a/browser/components/payments/res/paymentRequest.css
+++ b/browser/components/payments/res/paymentRequest.css
@@ -1,39 +1,59 @@
 /* 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/. */
 
 html {
-  background: -moz-dialog;
+  /* Based on global.css styles for top-level XUL windows */
+  color: -moz-DialogText;
+  font: message-box;
   height: 100%;
 }
 
 body {
+  /* Override font-size from in-content/common.css which is too large */
+  font-size: inherit;
+}
+
+#order-details-overlay,
+html {
+  /* Based on global.css styles for top-level XUL windows */
+  -moz-appearance: dialog;
+  background-color: -moz-Dialog;
+}
+
+body {
   height: 100%;
   margin: 0;
   overflow: hidden;
 }
 
 [hidden] {
   display: none !important;
 }
 
 #debugging-console {
+  /* include the default borders in the max-height */
+  box-sizing: border-box;
   float: right;
+  /* avoid causing the body to scroll */
+  max-height: 100vh;
   /* Float above the other overlays */
   position: relative;
   z-index: 99;
 }
 
 payment-dialog {
+  box-sizing: border-box;
   display: grid;
   grid-template-rows: fit-content(10%) auto;
   height: 100%;
   margin: 0 10%;
+  padding: 1em;
 }
 
 payment-dialog > header {
   display: flex;
 }
 
 #main-container {
   display: flex;
@@ -47,17 +67,16 @@ payment-dialog > header {
   position: relative;
 }
 
 #error-text {
   text-align: center;
 }
 
 #order-details-overlay {
-  background-color: -moz-dialog;
   overflow: auto;
   position: absolute;
   top: 0;
   right: 0;
   bottom: 0;
   left: 0;
   z-index: 1;
 }
@@ -75,22 +94,16 @@ payment-dialog > footer {
   flex: 0 1 auto;
 }
 
 #total .label {
   font-size: 15px;
   font-weight: bold;
 }
 
-#pay {
-  background-color: #0060df;
-  color: white;
-  border: none;
-}
-
 payment-dialog[changes-prevented][completion-state="fail"] #pay,
 payment-dialog[changes-prevented][completion-state="unknown"] #pay,
 payment-dialog[changes-prevented][completion-state="processing"] #pay,
 payment-dialog[changes-prevented][completion-state="success"] #pay {
   /* Show the pay button above #disabled-overlay */
   position: relative;
   z-index: 1;
 }
--- a/browser/components/payments/res/paymentRequest.xhtml
+++ b/browser/components/payments/res/paymentRequest.xhtml
@@ -56,16 +56,17 @@
 ]>
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
   <title>&paymentSummaryTitle;</title>
 
   <!-- chrome: is needed for global.dtd -->
   <meta http-equiv="Content-Security-Policy" content="default-src 'self' chrome:"/>
 
+  <link rel="stylesheet" href="chrome://global/skin/in-content/common.css"/>
   <link rel="stylesheet" href="paymentRequest.css"/>
   <link rel="stylesheet" href="components/rich-select.css"/>
   <link rel="stylesheet" href="components/address-option.css"/>
   <link rel="stylesheet" href="components/basic-card-option.css"/>
   <link rel="stylesheet" href="components/shipping-option.css"/>
   <link rel="stylesheet" href="components/payment-details-item.css"/>
   <link rel="stylesheet" href="containers/address-form.css"/>
   <link rel="stylesheet" href="containers/order-details.css"/>
@@ -86,17 +87,17 @@
       </div>
       <div id="top-buttons" >
         <button id="view-all" class="closed">&viewAllItems;</button>
       </div>
     </header>
 
     <div id="main-container">
       <section id="payment-summary" class="page">
-        <h1>&paymentSummaryTitle;</h1>
+        <h2>&paymentSummaryTitle;</h2>
 
         <section>
           <div id="error-text"></div>
 
           <div class="shipping-related"
                id="shipping-type-label"
                data-shipping-address-label="&shippingAddressLabel;"
                data-delivery-address-label="&deliveryAddressLabel;"
@@ -122,25 +123,26 @@
                           data-edit-link-label="&payer.editLink.label;"
                           selected-state-key="selectedPayerAddress"></address-picker>
           <div id="error-text"></div>
         </section>
 
         <footer id="controls-container">
           <button id="cancel">&cancelPaymentButton.label;</button>
           <button id="pay"
+                  class="primary"
                   data-initial-label="&approvePaymentButton.label;"
                   data-processing-label="&processingPaymentButton.label;"
                   data-fail-label="&failPaymentButton.label;"
                   data-unknown-label="&unknownPaymentButton.label;"
                   data-success-label="&successPaymentButton.label;"></button>
         </footer>
       </section>
       <section id="order-details-overlay" hidden="hidden">
-        <h1>&orderDetailsLabel;</h1>
+        <h2>&orderDetailsLabel;</h2>
         <order-details></order-details>
       </section>
 
       <basic-card-form id="basic-card-page"
                        class="page"
                        data-add-basic-card-title="&basicCard.addPage.title;"
                        data-edit-basic-card-title="&basicCard.editPage.title;"
                        data-error-generic-save="&basicCardPage.error.genericSave;"
--- a/browser/components/payments/test/browser/browser_address_edit.js
+++ b/browser/components/payments/test/browser/browser_address_edit.js
@@ -39,17 +39,17 @@ add_task(async function test_add_link() 
       is(addLink.textContent, "Add", "Add link text");
 
       addLink.click();
 
       state = await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "address-page" && !state["address-page"].guid;
       }, "Check add page state");
 
-      let title = content.document.querySelector("address-form h1");
+      let title = content.document.querySelector("address-form h2");
       is(title.textContent, "Add Shipping Address", "Page title should be set");
 
       let persistCheckbox = content.document.querySelector("address-form labelled-checkbox");
       ok(!persistCheckbox.hidden, "checkbox should be visible when adding a new address");
       ok(Cu.waiveXrays(persistCheckbox).checked, "persist checkbox should be checked by default");
 
       info("filling fields");
       for (let [key, val] of Object.entries(address)) {
@@ -130,17 +130,17 @@ add_task(async function test_edit_link()
       is(editLink.textContent, "Edit", "Edit link text");
 
       editLink.click();
 
       state = await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "address-page" && !!state["address-page"].guid;
       }, "Check edit page state");
 
-      let title = content.document.querySelector("address-form h1");
+      let title = content.document.querySelector("address-form h2");
       is(title.textContent, "Edit Shipping Address", "Page title should be set");
 
       let persistCheckbox = content.document.querySelector("address-form labelled-checkbox");
       ok(persistCheckbox.hidden, "checkbox should be hidden when editing an address");
 
       info("overwriting field values");
       for (let [key, val] of Object.entries(address)) {
         let field = content.document.getElementById(key);
@@ -215,17 +215,17 @@ add_task(async function test_add_payer_c
       is(addLink.textContent, "Add", "Add link text");
 
       addLink.click();
 
       state = await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "address-page" && !state["address-page"].guid;
       }, "Check add page state");
 
-      let title = content.document.querySelector("address-form h1");
+      let title = content.document.querySelector("address-form h2");
       is(title.textContent, "Add Payer Contact", "Page title should be set");
 
       let persistCheckbox = content.document.querySelector("address-form labelled-checkbox");
       ok(!persistCheckbox.hidden, "checkbox should be visible when adding a new address");
       ok(Cu.waiveXrays(persistCheckbox).checked, "persist checkbox should be checked by default");
 
       info("filling fields");
       for (let [key, val] of Object.entries(address)) {
@@ -302,17 +302,17 @@ add_task(async function test_edit_payer_
       is(editLink.textContent, "Edit", "Edit link text");
 
       editLink.click();
 
       state = await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "address-page" && !!state["address-page"].guid;
       }, "Check edit page state");
 
-      let title = content.document.querySelector("address-form h1");
+      let title = content.document.querySelector("address-form h2");
       is(title.textContent, "Edit Payer Contact", "Page title should be set");
 
       let persistCheckbox = content.document.querySelector("address-form labelled-checkbox");
       ok(persistCheckbox.hidden, "checkbox should be hidden when editing an address");
 
       info("overwriting field values");
       for (let [key, val] of Object.entries(address)) {
         let field = content.document.getElementById(key);
--- a/browser/components/payments/test/browser/browser_card_edit.js
+++ b/browser/components/payments/test/browser/browser_card_edit.js
@@ -21,17 +21,17 @@ add_task(async function test_add_link() 
       return state.page.id == "basic-card-page" && !state["basic-card-page"].guid;
     }, "Check add page state");
 
     state = await PTU.DialogContentUtils.waitForState(content, (state) => {
       return Object.keys(state.savedBasicCards).length == 0 &&
              Object.keys(state.savedAddresses).length == 0;
     }, "Check no cards or addresses present at beginning of test");
 
-    let title = content.document.querySelector("basic-card-form h1");
+    let title = content.document.querySelector("basic-card-form h2");
     is(title.textContent, "Add Credit Card", "Add title should be set");
 
     ok(!state.isPrivate,
        "isPrivate flag is not set when paymentrequest is shown from a non-private session");
     let persistCheckbox = content.document.querySelector("basic-card-form labelled-checkbox");
     ok(Cu.waiveXrays(persistCheckbox).checked, "persist checkbox should be checked by default");
 
     let card = Object.assign({}, PTU.BasicCards.JohnDoe);
@@ -52,17 +52,17 @@ add_task(async function test_add_link() 
        "The only option should be the blank/empty option");
 
     let addressAddLink = content.document.querySelector(".billingAddressRow .add-link");
     addressAddLink.click();
     state = await PTU.DialogContentUtils.waitForState(content, (state) => {
       return state.page.id == "address-page" && !state["address-page"].guid;
     }, "Check address page state");
 
-    let addressTitle = content.document.querySelector("address-form h1");
+    let addressTitle = content.document.querySelector("address-form h2");
     is(addressTitle.textContent, "Add Billing Address",
        "Address on add address page should be correct");
 
     state = await PTU.DialogContentUtils.waitForState(content, (state) => {
       return Object.keys(state.savedBasicCards).length == 0;
     }, "Check card was not added when clicking the 'add' address button");
 
     let addressBackButton = content.document.querySelector("address-form .back-button");
@@ -161,17 +161,17 @@ add_task(async function test_edit_link()
       return state.page.id == "basic-card-page" && state["basic-card-page"].guid;
     }, "Check edit page state");
 
     state = await PTU.DialogContentUtils.waitForState(content, (state) => {
       return Object.keys(state.savedBasicCards).length == 1 &&
              Object.keys(state.savedAddresses).length == 1;
     }, "Check card and address present at beginning of test");
 
-    let title = content.document.querySelector("basic-card-form h1");
+    let title = content.document.querySelector("basic-card-form h2");
     is(title.textContent, "Edit Credit Card", "Edit title should be set");
 
     let card = Object.assign({}, PTU.BasicCards.JohnDoe);
     // cc-number cannot be modified
     delete card["cc-number"];
     card["cc-exp-year"]++;
     card["cc-exp-month"]++;
 
@@ -193,17 +193,17 @@ add_task(async function test_edit_link()
     billingAddressSelect.selectedIndex = 0;
 
     let addressEditLink = content.document.querySelector(".billingAddressRow .edit-link");
     addressEditLink.click();
     state = await PTU.DialogContentUtils.waitForState(content, (state) => {
       return state.page.id == "address-page" && !state["address-page"].guid;
     }, "Clicking edit button when the empty option is selected will go to 'add' page (no guid)");
 
-    let addressTitle = content.document.querySelector("address-form h1");
+    let addressTitle = content.document.querySelector("address-form h2");
     is(addressTitle.textContent, "Add Billing Address",
        "Address on add address page should be correct");
 
     let addressBackButton = content.document.querySelector("address-form .back-button");
     addressBackButton.click();
     state = await PTU.DialogContentUtils.waitForState(content, (state) => {
       return state.page.id == "basic-card-page" && state["basic-card-page"].guid &&
              Object.keys(state.savedAddresses).length == 1;
--- a/browser/components/payments/test/browser/browser_payments_onboarding_wizard.js
+++ b/browser/components/payments/test/browser/browser_payments_onboarding_wizard.js
@@ -46,17 +46,17 @@ add_task(async function test_onboarding_
 
       info("Check if the total header is visible on the address page during on-boarding");
       let header = content.document.querySelector("header");
       ok(content.isVisible(header),
          "Total Header is visible on the address page during on-boarding");
       ok(header.textContent, "Total Header contains text");
 
       info("Check if the page title is visible on the address page");
-      let addressPageTitle = content.document.querySelector("address-form h1");
+      let addressPageTitle = content.document.querySelector("address-form h2");
       ok(content.isVisible(addressPageTitle), "Address page title is visible");
       is(addressPageTitle.textContent, "Add Shipping Address",
          "Address page title is correctly shown");
 
       let addressCancelButton = content.document.querySelector("address-form .cancel-button");
       ok(content.isVisible(addressCancelButton),
          "The cancel button on the address page is visible");
 
@@ -72,17 +72,17 @@ add_task(async function test_onboarding_
 
       await PTU.DialogContentUtils.waitForState(content, (state) => {
         return state.page.id == "basic-card-page";
       }, "Basic card page is shown after the address page during on boarding");
 
       let cardSaveButton = content.document.querySelector("basic-card-form .save-button");
       ok(content.isVisible(cardSaveButton), "Basic card page is rendered");
 
-      let basicCardTitle = content.document.querySelector("basic-card-form h1");
+      let basicCardTitle = content.document.querySelector("basic-card-form h2");
       ok(content.isVisible(basicCardTitle), "Basic card page title is visible");
       is(basicCardTitle.textContent, "Add Credit Card", "Basic card page title is correctly shown");
 
       info("Check if the correct billing address is selected in the basic card page");
       PTU.DialogContentUtils.waitForState((state) => {
         let billingAddressSelect = content.document.querySelector("#billingAddressGUID");
         return state.selectedShippingAddress == billingAddressSelect.value;
       }, "Shipping address is selected as the billing address");
@@ -319,17 +319,17 @@ add_task(async function test_onboarding_
       }, "Billing address page is shown first during on-boarding if requestShipping is turned off");
 
       info("Checking if the billing address page has been rendered");
       let addressSaveButton = content.document.querySelector("address-form .save-button");
       ok(content.isVisible(addressSaveButton),
          "Address save button is rendered");
 
       info("Check if the page title is visible on the address page");
-      let addressPageTitle = content.document.querySelector("address-form h1");
+      let addressPageTitle = content.document.querySelector("address-form h2");
       ok(content.isVisible(addressPageTitle), "Address page title is visible");
       is(addressPageTitle.textContent, "Add Billing Address",
          "Address page title is correctly shown");
 
       for (let [key, val] of Object.entries(PTU.Addresses.TimBL2)) {
         let field = content.document.getElementById(key);
         if (!field) {
           ok(false, `${key} field not found`);
--- a/browser/extensions/formautofill/content/l10n.js
+++ b/browser/extensions/formautofill/content/l10n.js
@@ -9,32 +9,33 @@
  * the edit dialog code with the unprivileged PaymentRequest dialog before the
  * Fluent conversion
  */
 
 /* global content */
 
 ChromeUtils.import("resource://formautofill/FormAutofillUtils.jsm");
 
-const CONTENT_WIN = typeof(window) != "undefined" ? window : content.window;
+const CONTENT_WIN = typeof(window) != "undefined" ? window : this;
 
 const L10N_ATTRIBUTES = ["data-localization", "data-localization-region"];
 
-let mutationObserver = new CONTENT_WIN.MutationObserver(function onMutation(mutations) {
-  for (let mutation of mutations) {
-    if (!mutation.target.hasAttribute(mutation.attributeName)) {
-      // The attribute was removed in the meantime.
-      continue;
+// eslint-disable-next-line mozilla/balanced-listeners
+CONTENT_WIN.addEventListener("DOMContentLoaded", function onDCL(evt) {
+  let doc = evt.target;
+  FormAutofillUtils.localizeMarkup(doc);
+
+  let mutationObserver = new doc.ownerGlobal.MutationObserver(function onMutation(mutations) {
+    for (let mutation of mutations) {
+      if (!mutation.target.hasAttribute(mutation.attributeName)) {
+        // The attribute was removed in the meantime.
+        continue;
+      }
+      FormAutofillUtils.localizeAttributeForElement(mutation.target, mutation.attributeName);
     }
-    FormAutofillUtils.localizeAttributeForElement(mutation.target, mutation.attributeName);
-  }
-});
+  });
 
-CONTENT_WIN.document.addEventListener("DOMContentLoaded", function onDCL() {
-  FormAutofillUtils.localizeMarkup(CONTENT_WIN.document);
-  mutationObserver.observe(CONTENT_WIN.document, {
+  mutationObserver.observe(doc, {
     attributes: true,
     attributeFilter: L10N_ATTRIBUTES,
     subtree: true,
   });
-}, {
-  once: true,
 });
deleted file mode 100644
--- a/build/build-clang/clang-4-linux64.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-    "llvm_revision": "305830",
-    "stages": "3",
-    "build_libcxx": true,
-    "build_type": "Release",
-    "assertions": false,
-    "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_401/final",
-    "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_401/final",
-    "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_401/final",
-    "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_401/final",
-    "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_401/final",
-    "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
-    "patches": [
-      "llvm-debug-frame.patch",
-      "hide-gcda-profiling-symbols.patch",
-      "pr_set_ptracer.patch"
-    ]
-}
deleted file mode 100644
--- a/build/build-clang/clang-macosx64.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    "llvm_revision": "289595",
-    "stages": "1",
-    "build_libcxx": true,
-    "build_type": "Release",
-    "assertions": false,
-    "osx_cross_compile": true,
-    "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_391/final",
-    "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_391/final",
-    "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_391/final",
-    "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_391/final",
-    "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_391/final",
-    "python_path": "/usr/bin/python2.7",
-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
-    "cc": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "cxx": "/builds/worker/workspace/build/src/clang/bin/clang++",
-    "as": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "ar": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-ar",
-    "ranlib": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-ranlib",
-    "libtool": "/builds/worker/workspace/build/src/cctools/bin/x86_64-apple-darwin11-libtool",
-    "ld": "/builds/worker/workspace/build/src/clang/bin/clang",
-    "patches":[
-      "llvm-debug-frame.patch",
-      "compiler-rt-cross-compile.patch",
-      "pr28831-r280042.patch",
-      "r277806.patch",
-      "r285657.patch"
-    ]
-}
deleted file mode 100644
--- a/build/build-clang/pr28831-r280042.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-Backport the fix to PR28831 plus its follow-up (r280042)
-
-diff --git a/libcxx/lib/CMakeLists.txt b/libcxx/lib/CMakeLists.txt
-index afc388e76..4f43f3711 100644
---- a/libcxx/lib/CMakeLists.txt
-+++ b/libcxx/lib/CMakeLists.txt
-@@ -115,9 +115,9 @@ if ( APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL "libcxxabi" OR
-       "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++unexp.exp"
-       "/usr/lib/libSystem.B.dylib")
-   else()
--    if ( ${CMAKE_OSX_SYSROOT} )
--      list(FIND ${CMAKE_OSX_ARCHITECTURES} "armv7" OSX_HAS_ARMV7)
--      if (OSX_HAS_ARMV7)
-+    if (DEFINED CMAKE_OSX_SYSROOT)
-+      list(FIND CMAKE_OSX_ARCHITECTURES "armv7" OSX_HAS_ARMV7)
-+      if (NOT OSX_HAS_ARMV7 EQUAL -1)
-         set(OSX_RE_EXPORT_LINE
-           "${CMAKE_OSX_SYSROOT}/usr/lib/libc++abi.dylib"
-           "-Wl,-reexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/libc++sjlj-abi.exp")
--- a/build/clang-plugin/moz.build
+++ b/build/clang-plugin/moz.build
@@ -93,8 +93,12 @@ COMPILE_FLAGS['OS_COMPILE_CXXFLAGS'] = [
 LINK_FLAGS['OS'] = CONFIG['LLVM_LDFLAGS'] + CONFIG['CLANG_LDFLAGS']
 # The ldflags above override most other categories.
 for var in ('LINKER', 'OPTIMIZE'):
     LINK_FLAGS[var] = []
 
 if CONFIG['HOST_OS_ARCH'] == 'Linux' and CONFIG['OS_ARCH'] == 'Darwin':
     # Don't pass OSX linker arguments.
     LINK_FLAGS['FIX_LINK_PATHS'] = []
+
+# Avoid -DDEBUG=1 on the command line, which conflicts with a #define
+# DEBUG(...) in llvm headers.
+DEFINES['DEBUG'] = False
--- a/build/clang-plugin/mozsearch-plugin/MozsearchIndexer.cpp
+++ b/build/clang-plugin/mozsearch-plugin/MozsearchIndexer.cpp
@@ -266,17 +266,20 @@ private:
     for (const DeclContext *DC : Contexts) {
       if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
         Result += Spec->getNameAsString();
 
         if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization) {
           std::string Backing;
           llvm::raw_string_ostream Stream(Backing);
           const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-#if CLANG_VERSION_MAJOR > 3 ||                                                 \
+#if CLANG_VERSION_MAJOR > 5
+          printTemplateArgumentList(
+              Stream, TemplateArgs.asArray(), PrintingPolicy(CI.getLangOpts()));
+#elif CLANG_VERSION_MAJOR > 3 ||                                                 \
     (CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR >= 9)
           TemplateSpecializationType::PrintTemplateArgumentList(
               Stream, TemplateArgs.asArray(), PrintingPolicy(CI.getLangOpts()));
 #else
           TemplateSpecializationType::PrintTemplateArgumentList(
               stream, templateArgs.data(), templateArgs.size(),
               PrintingPolicy(CI.getLangOpts()));
 #endif
@@ -355,30 +358,35 @@ private:
         } else {
           Ctx->mangleName(Decl, Out);
         }
         return Out.str().str();
       } else {
         return std::string("V_") + mangleLocation(Decl->getLocation()) +
                std::string("_") + hash(Decl->getName());
       }
-    } else if (isa<TagDecl>(Decl) || isa<TypedefNameDecl>(Decl)) {
+    } else if (isa<TagDecl>(Decl) || isa<TypedefNameDecl>(Decl) ||
+               isa<ObjCInterfaceDecl>(Decl)) {
       if (!Decl->getIdentifier()) {
         // Anonymous.
         return std::string("T_") + mangleLocation(Decl->getLocation());
       }
 
       return std::string("T_") + mangleQualifiedName(getQualifiedName(Decl));
     } else if (isa<NamespaceDecl>(Decl) || isa<NamespaceAliasDecl>(Decl)) {
       if (!Decl->getIdentifier()) {
         // Anonymous.
         return std::string("NS_") + mangleLocation(Decl->getLocation());
       }
 
       return std::string("NS_") + mangleQualifiedName(getQualifiedName(Decl));
+    } else if (const ObjCIvarDecl *D2 = dyn_cast<ObjCIvarDecl>(Decl)) {
+      const ObjCInterfaceDecl *Iface = D2->getContainingInterface();
+      return std::string("F_<") + getMangledName(Ctx, Iface) + ">_" +
+             D2->getNameAsString();
     } else if (const FieldDecl *D2 = dyn_cast<FieldDecl>(Decl)) {
       const RecordDecl *Record = D2->getParent();
       return std::string("F_<") + getMangledName(Ctx, Record) + ">_" +
              toString(D2->getFieldIndex());
     } else if (const EnumConstantDecl *D2 = dyn_cast<EnumConstantDecl>(Decl)) {
       const DeclContext *DC = Decl->getDeclContext();
       if (const NamedDecl *Named = dyn_cast<NamedDecl>(DC)) {
         return std::string("E_<") + getMangledName(Ctx, Named) + ">_" +
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -168,26 +168,16 @@ DOMInterfaces = {
 },
 
 'CSSConditionRule': {
     'concrete': False,
     'nativeType': 'mozilla::css::ConditionRule',
     'headerFile': 'mozilla/css/GroupRule.h',
 },
 
-'CSSCounterStyleRule': {
-    'nativeType': 'mozilla::ServoCounterStyleRule',
-    'headerFile': 'mozilla/ServoCounterStyleRule.h',
-},
-
-'CSSFontFaceRule': {
-    'nativeType': 'mozilla::ServoFontFaceRule',
-    'headerFile': 'mozilla/ServoFontFaceRule.h',
-},
-
 'CSSGroupingRule': {
     'concrete': False,
     'nativeType': 'mozilla::css::GroupRule',
 },
 
 'CSSLexer': {
     'wrapperCache': False
 },
--- a/layout/base/AccessibleCaretEventHub.cpp
+++ b/layout/base/AccessibleCaretEventHub.cpp
@@ -20,16 +20,19 @@
 #include "nsCanvasFrame.h"
 #include "nsDocShell.h"
 #include "nsFocusManager.h"
 #include "nsFrameSelection.h"
 #include "nsIDocument.h"
 #include "nsITimer.h"
 #include "nsPresContext.h"
 
+using namespace mozilla;
+using namespace mozilla::dom;
+
 namespace mozilla {
 
 #undef AC_LOG
 #define AC_LOG(message, ...)                                                   \
   AC_LOG_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__);
 
 #undef AC_LOGV
 #define AC_LOGV(message, ...)                                                  \
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -18,16 +18,19 @@
 #include "mozilla/dom/Element.h"
 #include "nsRegion.h"
 #include "nsDeviceContext.h"
 #include "nsIContentInlines.h"
 #include "nsIFrame.h"
 #include <algorithm>
 #include "LayersLogging.h"
 
+using namespace mozilla;
+using namespace mozilla::dom;
+
 // If debugging this code you may wish to enable this logging, and also
 // uncomment the DumpFrameTree call near the bottom of the file.
 #define PET_LOG(...)
 // #define PET_LOG(...) printf_stderr("PET: " __VA_ARGS__);
 
 namespace mozilla {
 
 /*
--- a/layout/base/ShapeUtils.h
+++ b/layout/base/ShapeUtils.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_ShapeUtils_h
 #define mozilla_ShapeUtils_h
 
 #include "nsCoord.h"
 #include "nsSize.h"
 #include "nsStyleConsts.h"
+#include "nsTArray.h"
 
 struct nsPoint;
 struct nsRect;
 
 namespace mozilla {
 class StyleBasicShape;
 
 // ShapeUtils is a namespace class containing utility functions related to
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -64,16 +64,17 @@
 #include "gfxTypes.h"
 #include "nsTArray.h"
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "nsICanvasRenderingContextInternal.h"
 #include "gfxPlatform.h"
 #include <algorithm>
 #include <limits>
 #include "mozilla/dom/AnonymousContent.h"
+#include "mozilla/dom/HTMLBodyElement.h"
 #include "mozilla/dom/HTMLMediaElementBinding.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/DOMRect.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "mozilla/dom/KeyframeEffect.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "imgIRequest.h"
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -179,17 +179,29 @@ ViewportFrame::BuildDisplayListForTopLay
       BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
     }
   }
 
   nsIPresShell* shell = PresShell();
   if (nsCanvasFrame* canvasFrame = shell->GetCanvasFrame()) {
     if (Element* container = canvasFrame->GetCustomContentContainer()) {
       if (nsIFrame* frame = container->GetPrimaryFrame()) {
-        BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
+        // Enter this frame for display list building, but only if it is
+        // actually a top layer frame. There is a bug affecting SVG documents
+        // that makes the custom content container not be a top layer frame in
+        // them, because SVG documents don't load `ua.css` when the custom
+        // content container is created. `ua.css` contains the rule that makes
+        // this a top layer frame. This bug is being fixed in bug 1157592.
+        // We have to do this workaround because otherwise we risk building
+        // display items for this frame twice; if the custom content container
+        // frame is not a top layer frame, it's not out-of-flow, so we'll have
+        // built display items for it already when we entered its parent frame.
+        if (frame->StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE) {
+          BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
+        }
       }
     }
   }
 }
 
 #ifdef DEBUG
 void
 ViewportFrame::AppendFrames(ChildListID     aListID,
--- a/layout/inspector/InspectorFontFace.cpp
+++ b/layout/inspector/InspectorFontFace.cpp
@@ -8,19 +8,19 @@
 
 #include "gfxPlatformFontList.h"
 #include "gfxTextRun.h"
 #include "gfxUserFontSet.h"
 #include "nsFontFaceLoader.h"
 #include "mozilla/gfx/2D.h"
 #include "brotli/decode.h"
 #include "zlib.h"
+#include "mozilla/dom/CSSFontFaceRule.h"
 #include "mozilla/dom/FontFaceSet.h"
 #include "mozilla/ServoBindings.h"
-#include "mozilla/ServoFontFaceRule.h"
 #include "mozilla/Unused.h"
 
 namespace mozilla {
 namespace dom {
 
 bool
 InspectorFontFace::FromFontGroup()
 {
@@ -64,17 +64,17 @@ InspectorFontFace::GetCSSGeneric(nsAStri
   if (genericType >= FontFamilyType::eFamily_generic_first &&
       genericType <= FontFamilyType::eFamily_generic_last) {
     aName.AssignASCII(gfxPlatformFontList::GetGenericName(genericType));
   } else {
     aName.Truncate(0);
   }
 }
 
-ServoFontFaceRule*
+CSSFontFaceRule*
 InspectorFontFace::GetRule()
 {
   if (!mRule) {
     // check whether this font entry is associated with an @font-face rule
     // in the relevant font group's user font set
     RawServoFontFaceRule* rule = nullptr;
     if (mFontEntry->IsUserFont()) {
       FontFaceSet::UserFontSet* fontSet =
@@ -89,17 +89,17 @@ InspectorFontFace::GetRule()
     if (rule) {
       // XXX It would be better if we can share this with CSSOM tree,
       // but that may require us to create another map, which is not
       // great either. As far as they would use the same backend, and
       // we don't really support mutating @font-face rule via CSSOM,
       // it's probably fine for now.
       uint32_t line, column;
       Servo_FontFaceRule_GetSourceLocation(rule, &line, &column);
-      mRule = new ServoFontFaceRule(do_AddRef(rule), line, column);
+      mRule = new CSSFontFaceRule(do_AddRef(rule), line, column);
     }
   }
   return mRule;
 }
 
 int32_t
 InspectorFontFace::SrcIndex()
 {
--- a/layout/inspector/InspectorFontFace.h
+++ b/layout/inspector/InspectorFontFace.h
@@ -2,17 +2,17 @@
 /* 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_InspectorFontFace_h
 #define mozilla_InspectorFontFace_h
 
-#include "mozilla/ServoFontFaceRule.h"
+#include "mozilla/dom/CSSFontFaceRule.h"
 #include "mozilla/dom/InspectorUtilsBinding.h"
 #include "mozilla/dom/NonRefcountedDOMObject.h"
 #include "nsRange.h"
 #include "gfxFont.h"
 
 class gfxFontGroup;
 
 namespace mozilla {
@@ -52,17 +52,17 @@ public:
 
   // Web IDL
   bool FromFontGroup();
   bool FromLanguagePrefs();
   bool FromSystemFallback();
   void GetName(nsAString& aName);
   void GetCSSFamilyName(nsAString& aCSSFamilyName);
   void GetCSSGeneric(nsAString& aGeneric);
-  ServoFontFaceRule* GetRule();
+  CSSFontFaceRule* GetRule();
   int32_t SrcIndex();
   void GetURI(nsAString& aURI);
   void GetLocalName(nsAString& aLocalName);
   void GetFormat(nsAString& aFormat);
   void GetMetadata(nsAString& aMetadata);
 
   void GetVariationAxes(nsTArray<InspectorVariationAxis>& aResult,
                         ErrorResult& aRV);
@@ -78,17 +78,17 @@ public:
                   JS::MutableHandle<JSObject*> aReflector)
   {
     return InspectorFontFaceBinding::Wrap(aCx, this, aGivenProto, aReflector);
   }
 
 protected:
   RefPtr<gfxFontEntry> mFontEntry;
   RefPtr<gfxFontGroup> mFontGroup;
-  RefPtr<ServoFontFaceRule> mRule;
+  RefPtr<CSSFontFaceRule> mRule;
   gfxTextRange::MatchType mMatchType;
 
   nsTArray<RefPtr<nsRange>> mRanges;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/layout/inspector/InspectorUtils.cpp
+++ b/layout/inspector/InspectorUtils.cpp
@@ -26,26 +26,26 @@
 #include "nsComputedDOMStyle.h"
 #include "mozilla/EventStateManager.h"
 #include "nsAtom.h"
 #include "nsRange.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/dom/CharacterData.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/CSSLexer.h"
+#include "mozilla/dom/CSSStyleRule.h"
 #include "mozilla/dom/InspectorUtilsBinding.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsColor.h"
 #include "mozilla/ServoStyleSet.h"
 #include "nsStyleUtil.h"
 #include "nsQueryObject.h"
 #include "mozilla/ServoBindings.h"
-#include "mozilla/ServoStyleRule.h"
 #include "mozilla/ServoStyleRuleMap.h"
 #include "mozilla/ServoCSSParser.h"
 #include "mozilla/dom/InspectorUtils.h"
 #include "mozilla/dom/InspectorFontFace.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
@@ -218,17 +218,17 @@ InspectorUtils::GetCSSStyleRules(GlobalO
   for (auto* shadow = aElement.GetContainingShadow();
        shadow;
        shadow = shadow->Host()->GetContainingShadow()) {
     maps.AppendElement(&shadow->ServoStyleRuleMap());
   }
 
   // Find matching rules in the table.
   for (const RawServoStyleRule* rawRule : Reversed(rawRuleList)) {
-    ServoStyleRule* rule = nullptr;
+    CSSStyleRule* rule = nullptr;
     for (ServoStyleRuleMap* map : maps) {
       rule = map->Lookup(rawRule);
       if (rule) {
         break;
       }
     }
     if (rule) {
       aResult.AppendElement(rule);
--- a/layout/inspector/ServoStyleRuleMap.cpp
+++ b/layout/inspector/ServoStyleRuleMap.cpp
@@ -2,21 +2,21 @@
 /* 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/ServoStyleRuleMap.h"
 
 #include "mozilla/css/GroupRule.h"
+#include "mozilla/dom/CSSImportRule.h"
 #include "mozilla/dom/CSSRuleBinding.h"
+#include "mozilla/dom/CSSStyleRule.h"
 #include "mozilla/IntegerRange.h"
-#include "mozilla/ServoStyleRule.h"
 #include "mozilla/ServoStyleSet.h"
-#include "mozilla/ServoImportRule.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "nsDocument.h"
 #include "nsStyleSheetService.h"
 
 namespace mozilla {
 
 void
 ServoStyleRuleMap::EnsureTable(ServoStyleSet& aStyleSet)
@@ -87,17 +87,17 @@ ServoStyleRuleMap::RuleRemoved(StyleShee
                                css::Rule& aStyleRule)
 {
   if (IsEmpty()) {
     return;
   }
 
   switch (aStyleRule.Type()) {
     case CSSRuleBinding::STYLE_RULE: {
-      auto& rule = static_cast<ServoStyleRule&>(aStyleRule);
+      auto& rule = static_cast<CSSStyleRule&>(aStyleRule);
       mTable.Remove(rule.Raw());
       break;
     }
     case CSSRuleBinding::IMPORT_RULE:
     case CSSRuleBinding::MEDIA_RULE:
     case CSSRuleBinding::SUPPORTS_RULE:
     case CSSRuleBinding::DOCUMENT_RULE: {
       // See the comment in StyleSheetRemoved.
@@ -125,30 +125,30 @@ ServoStyleRuleMap::SizeOfIncludingThis(M
   return n;
 }
 
 void
 ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule)
 {
   switch (aRule.Type()) {
     case CSSRuleBinding::STYLE_RULE: {
-      auto& rule = static_cast<ServoStyleRule&>(aRule);
+      auto& rule = static_cast<CSSStyleRule&>(aRule);
       mTable.Put(rule.Raw(), &rule);
       break;
     }
     case CSSRuleBinding::MEDIA_RULE:
     case CSSRuleBinding::SUPPORTS_RULE:
     case CSSRuleBinding::DOCUMENT_RULE: {
       auto& rule = static_cast<css::GroupRule&>(aRule);
       auto ruleList = static_cast<ServoCSSRuleList*>(rule.CssRules());
       FillTableFromRuleList(*ruleList);
       break;
     }
     case CSSRuleBinding::IMPORT_RULE: {
-      auto& rule = static_cast<ServoImportRule&>(aRule);
+      auto& rule = static_cast<CSSImportRule&>(aRule);
       MOZ_ASSERT(aRule.GetStyleSheet());
       FillTableFromStyleSheet(*rule.GetStyleSheet());
       break;
     }
   }
 }
 
 void
--- a/layout/inspector/ServoStyleRuleMap.h
+++ b/layout/inspector/ServoStyleRuleMap.h
@@ -2,17 +2,17 @@
 /* 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_ServoStyleRuleMap_h
 #define mozilla_ServoStyleRuleMap_h
 
-#include "mozilla/ServoStyleRule.h"
+#include "mozilla/dom/CSSStyleRule.h"
 #include "mozilla/StyleSheet.h"
 
 #include "nsDataHashtable.h"
 
 struct RawServoStyleRule;
 class nsXBLPrototypeResources;
 
 namespace mozilla {
@@ -28,17 +28,17 @@ class ServoStyleRuleMap
 {
 public:
   ServoStyleRuleMap() = default;
 
   void EnsureTable(ServoStyleSet&);
   void EnsureTable(nsXBLPrototypeResources&);
   void EnsureTable(dom::ShadowRoot&);
 
-  ServoStyleRule* Lookup(const RawServoStyleRule* aRawRule) const
+  dom::CSSStyleRule* Lookup(const RawServoStyleRule* aRawRule) const
   {
     return mTable.Get(aRawRule);
   }
 
   void SheetAdded(StyleSheet&);
   void SheetRemoved(StyleSheet&);
 
   void RuleAdded(StyleSheet& aStyleSheet, css::Rule&);
@@ -54,15 +54,15 @@ private:
   // all stylesheets to fill the table.
   bool IsEmpty() const { return mTable.Count() == 0; }
 
   void FillTableFromRule(css::Rule&);
   void FillTableFromRuleList(ServoCSSRuleList&);
   void FillTableFromStyleSheet(StyleSheet&);
 
   typedef nsDataHashtable<nsPtrHashKey<const RawServoStyleRule>,
-                          WeakPtr<ServoStyleRule>> Hashtable;
+                          WeakPtr<dom::CSSStyleRule>> Hashtable;
   Hashtable mTable;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_ServoStyleRuleMap_h
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3748,18 +3748,18 @@ nsCSSBorderImageRenderer::CreateWebRende
                                wr::ToRepeatMode(mRepeatModeHorizontal),
                                wr::ToRepeatMode(mRepeatModeVertical));
       break;
     }
     case eStyleImageType_Gradient:
     {
       RefPtr<nsStyleGradient> gradientData = mImageRenderer.GetGradientData();
       nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(aForFrame->PresContext(), gradientData,
-                                      mImageSize);
+        nsCSSGradientRenderer::Create(aForFrame->PresContext(), aForFrame->Style(),
+                                      gradientData, mImageSize);
 
       wr::ExtendMode extendMode;
       nsTArray<wr::GradientStop> stops;
       LayoutDevicePoint lineStart;
       LayoutDevicePoint lineEnd;
       LayoutDeviceSize gradientRadius;
       renderer.BuildWebRenderParameters(1.0, extendMode, stops, lineStart, lineEnd, gradientRadius);
 
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -564,17 +564,18 @@ GetSpecifiedGradientPosition(const nsSty
     }
     default:
       MOZ_ASSERT_UNREACHABLE("Unknown unit in gradient color stop position?");
       return Nothing();
   }
 }
 
 static nsTArray<ColorStop>
-ComputeColorStops(const nsStyleGradient& aGradient,
+ComputeColorStops(ComputedStyle* aComputedStyle,
+                  const nsStyleGradient& aGradient,
                   int32_t aAppUnitsPerPixel,
                   gfxFloat aLineLength)
 {
   MOZ_ASSERT(aGradient.mStops.Length() >= 2,
              "The parser should reject gradients with less than two stops");
 
   nsTArray<ColorStop> stops(aGradient.mStops.Length());
 
@@ -602,31 +603,33 @@ ComputeColorStops(const nsStyleGradient&
     } else {
       // Other stops with no specified position get their position assigned
       // later by interpolation, see below.
       // Remember where the run of stops with no specified position starts,
       // if it starts here.
       if (firstUnsetPosition < 0) {
         firstUnsetPosition = i;
       }
+      auto stopColor = stop.mColor.CalcColor(aComputedStyle);
       stops.AppendElement(ColorStop(0, stop.mIsInterpolationHint,
-                                    Color::FromABGR(stop.mColor)));
+                                    Color::FromABGR(stopColor)));
       continue;
     }
 
     if (i > 0) {
       // Prevent decreasing stop positions by advancing this position
       // to the previous stop position, if necessary
       double previousPosition = firstUnsetPosition > 0
         ? stops[firstUnsetPosition - 1].mPosition
         : stops[i - 1].mPosition;
       position = std::max(position, previousPosition);
     }
+    auto stopColor = stop.mColor.CalcColor(aComputedStyle);
     stops.AppendElement(ColorStop(position, stop.mIsInterpolationHint,
-                                  Color::FromABGR(stop.mColor)));
+                                  Color::FromABGR(stopColor)));
     if (firstUnsetPosition > 0) {
       // Interpolate positions for all stops that didn't have a specified position
       double p = stops[firstUnsetPosition - 1].mPosition;
       double d = (stops[i].mPosition - p)/(i - firstUnsetPosition + 1);
       for (uint32_t j = firstUnsetPosition; j < i; ++j) {
         p += d;
         stops[j].mPosition = p;
       }
@@ -634,18 +637,19 @@ ComputeColorStops(const nsStyleGradient&
     }
   }
 
   return stops;
 }
 
 nsCSSGradientRenderer
 nsCSSGradientRenderer::Create(nsPresContext* aPresContext,
-                             nsStyleGradient* aGradient,
-                             const nsSize& aIntrinsicSize)
+                              ComputedStyle* aComputedStyle,
+                              nsStyleGradient* aGradient,
+                              const nsSize& aIntrinsicSize)
 {
   nscoord appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
   gfxSize srcSize = gfxSize(gfxFloat(aIntrinsicSize.width)/appUnitsPerDevPixel,
                             gfxFloat(aIntrinsicSize.height)/appUnitsPerDevPixel);
 
   // Compute "gradient line" start and end relative to the intrinsic size of
   // the gradient.
   gfxPoint lineStart, lineEnd;
@@ -661,17 +665,17 @@ nsCSSGradientRenderer::Create(nsPresCont
   if (!lineStart.IsFinite() || !lineEnd.IsFinite()) {
     lineStart = lineEnd = gfxPoint(0, 0);
   }
   gfxFloat lineLength = NS_hypot(lineEnd.x - lineStart.x,
                                   lineEnd.y - lineStart.y);
 
   // Build color stop array and compute stop positions
   nsTArray<ColorStop> stops =
-    ComputeColorStops(*aGradient, appUnitsPerDevPixel, lineLength);
+    ComputeColorStops(aComputedStyle, *aGradient, appUnitsPerDevPixel, lineLength);
 
   ResolveMidpoints(stops);
 
   nsCSSGradientRenderer renderer;
   renderer.mPresContext = aPresContext;
   renderer.mGradient = aGradient;
   renderer.mStops = std::move(stops);
   renderer.mLineStart = lineStart;
--- a/layout/painting/nsCSSRenderingGradients.h
+++ b/layout/painting/nsCSSRenderingGradients.h
@@ -36,16 +36,17 @@ struct ColorStop {
 
 class nsCSSGradientRenderer final {
 public:
   /**
    * Prepare a nsCSSGradientRenderer for a gradient for an element.
    * aIntrinsicSize - the size of the source gradient.
    */
   static nsCSSGradientRenderer Create(nsPresContext* aPresContext,
+                                      ComputedStyle* aComputedStyle,
                                       nsStyleGradient* aGradient,
                                       const nsSize& aIntrinsiceSize);
 
   /**
    * Draw the gradient to aContext
    * aDest - where the first tile of gradient is
    * aFill - the area to be filled with tiles of aDest
    * aSrc - the area of the gradient that will fill aDest
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5438,18 +5438,18 @@ nsDisplayBorder::CreateBorderImageWebRen
                                wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeHorizontal),
                                wr::ToRepeatMode(mBorderImageRenderer->mRepeatModeVertical));
       break;
     }
     case eStyleImageType_Gradient:
     {
       RefPtr<nsStyleGradient> gradientData = mBorderImageRenderer->mImageRenderer.GetGradientData();
       nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(mFrame->PresContext(), gradientData,
-                                      mBorderImageRenderer->mImageSize);
+        nsCSSGradientRenderer::Create(mFrame->PresContext(), mFrame->Style(),
+                                      gradientData, mBorderImageRenderer->mImageSize);
 
       wr::ExtendMode extendMode;
       nsTArray<wr::GradientStop> stops;
       LayoutDevicePoint lineStart;
       LayoutDevicePoint lineEnd;
       LayoutDeviceSize gradientRadius;
       renderer.BuildWebRenderParameters(1.0, extendMode, stops, lineStart, lineEnd, gradientRadius);
 
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -504,17 +504,18 @@ nsImageRenderer::Draw(nsPresContext*    
                                            aAnchor, aDirtyRect,
                                            ConvertImageRendererToDrawFlags(mFlags),
                                            mExtendMode, aOpacity);
       break;
     }
     case eStyleImageType_Gradient:
     {
       nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
+        nsCSSGradientRenderer::Create(aPresContext, mForFrame->Style(),
+                                      mGradientData, mSize);
 
       renderer.Paint(*ctx, aDest, aFill, aRepeatSize, aSrc, aDirtyRect, aOpacity);
       break;
     }
     case eStyleImageType_Element:
     {
       RefPtr<gfxDrawable> drawable = DrawableForElement(aDest, *ctx);
       if (!drawable) {
@@ -581,17 +582,18 @@ nsImageRenderer::BuildWebRenderDisplayIt
       mSize.width <= 0 || mSize.height <= 0) {
     return ImgDrawResult::SUCCESS;
   }
 
   switch (mType) {
     case eStyleImageType_Gradient:
     {
       nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
+        nsCSSGradientRenderer::Create(aPresContext, mForFrame->Style(),
+                                      mGradientData, mSize);
 
       renderer.BuildWebRenderDisplayItems(aBuilder, aSc, aDest, aFill,
                                           aRepeatSize, aSrc, !aItem->BackfaceIsHidden(), aOpacity);
       break;
     }
     case eStyleImageType_Image:
     {
       uint32_t containerFlags = imgIContainer::FLAG_ASYNC_NOTIFY;
@@ -992,17 +994,18 @@ nsImageRenderer::DrawShapeImage(nsPresCo
                                               dest, dest, Nothing(),
                                               drawFlags,
                                               nullptr, nullptr);
       break;
     }
 
     case eStyleImageType_Gradient: {
       nsCSSGradientRenderer renderer =
-        nsCSSGradientRenderer::Create(aPresContext, mGradientData, mSize);
+        nsCSSGradientRenderer::Create(aPresContext, mForFrame->Style(),
+                                      mGradientData, mSize);
       nsRect dest(nsPoint(0, 0), mSize);
 
       renderer.Paint(aRenderingContext, dest, dest, mSize,
                      CSSIntRect::FromAppUnitsRounded(dest),
                      dest, 1.0);
       break;
     }
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/images3/color-stop-currentcolor-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>CSS Reftest Reference</title>
+    <link rel="author" title="Dan Glastonbury" href="mailto:dglastonbury@mozilla.com" />
+    <style type="text/css">
+     body {
+         background: linear-gradient(to right, currentcolor, limegreen);
+     }
+
+     div {
+         width: 100vw;
+         height: 100vh;
+         background: linear-gradient(to right, limegreen, limegreen);
+     }
+    </style>
+  </head>
+  <body>
+    <!-- content of test -->
+    <div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/w3c-css/submitted/images3/color-stop-currentcolor.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>CSS Test: 'color-stop' on linear-gradient respects 'currentcolor'</title>
+    <link rel="author" title="Dan Glastonbury" href="mailto:dglastonbury@mozilla.com" />
+    <link rel="help" href="https://www.w3.org/TR/css3-images/#color-stop-syntax" />
+    <link rel="help" href="https://www.w3.org/TR/css-color-3/#currentcolor" />
+    <link rel="match" href="color-stop-currentcolor-ref.html" />
+    <style type="text/css">
+     body {
+         background: linear-gradient(to right, currentcolor, limegreen);
+     }
+
+     div {
+         width: 100vw;
+         height: 100vh;
+         color: limegreen;
+         background: inherit;
+     }
+    </style>
+  </head>
+  <body>
+    <!-- content of test -->
+    <div>
+  </body>
+</html>
--- a/layout/reftests/w3c-css/submitted/images3/reftest.list
+++ b/layout/reftests/w3c-css/submitted/images3/reftest.list
@@ -184,8 +184,11 @@ fails-if(!webrender) == object-position-
 fails-if(!webrender) == object-position-svg-001e.html object-position-svg-001-ref.html # bug 1103286
 == object-position-svg-001i.html object-position-svg-001-ref.html
 fails-if(!webrender) == object-position-svg-001o.html object-position-svg-001-ref.html # bug 1103286
 == object-position-svg-001p.html object-position-svg-001-ref.html
 fails-if(!webrender) == object-position-svg-002e.html object-position-svg-002-ref.html # bug 1103286
 == object-position-svg-002i.html object-position-svg-002-ref.html
 fails-if(!webrender) == object-position-svg-002o.html object-position-svg-002-ref.html # bug 1103286
 == object-position-svg-002p.html object-position-svg-002-ref.html
+
+# Tests for gradient color stops with 'currentcolor'
+== color-stop-currentcolor.html color-stop-currentcolor-ref.html
\ No newline at end of file
rename from layout/style/ServoCounterStyleRule.cpp
rename to layout/style/CSSCounterStyleRule.cpp
--- a/layout/style/ServoCounterStyleRule.cpp
+++ b/layout/style/CSSCounterStyleRule.cpp
@@ -1,102 +1,104 @@
 /* -*- 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/ServoCounterStyleRule.h"
+#include "mozilla/dom/CSSCounterStyleRule.h"
 
 #include "mozAutoDocUpdate.h"
 #include "mozilla/dom/CSSCounterStyleRuleBinding.h"
 #include "mozilla/ServoBindings.h"
 #include "nsStyleUtil.h"
 
 namespace mozilla {
+namespace dom {
 
 bool
-ServoCounterStyleRule::IsCCLeaf() const
+CSSCounterStyleRule::IsCCLeaf() const
 {
   return Rule::IsCCLeaf();
 }
 
 #ifdef DEBUG
 void
-ServoCounterStyleRule::List(FILE* out, int32_t aIndent) const
+CSSCounterStyleRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t i = 0; i < aIndent; i++) {
     str.AppendLiteral("  ");
   }
   Servo_CounterStyleRule_Debug(mRawRule, &str);
   fprintf_stderr(out, "%s\n", str.get());
 }
 #endif
 
 uint16_t
-ServoCounterStyleRule::Type() const
+CSSCounterStyleRule::Type() const
 {
   return CSSRuleBinding::COUNTER_STYLE_RULE;
 }
 
 void
-ServoCounterStyleRule::GetCssText(nsAString& aCssText) const
+CSSCounterStyleRule::GetCssText(nsAString& aCssText) const
 {
   Servo_CounterStyleRule_GetCssText(mRawRule, &aCssText);
 }
 
 void
-ServoCounterStyleRule::GetName(nsAString& aName)
+CSSCounterStyleRule::GetName(nsAString& aName)
 {
   aName.Truncate();
   nsAtom* name = Servo_CounterStyleRule_GetName(mRawRule);
   nsDependentAtomString nameStr(name);
   nsStyleUtil::AppendEscapedCSSIdent(nameStr, aName);
 }
 
 void
-ServoCounterStyleRule::SetName(const nsAString& aName)
+CSSCounterStyleRule::SetName(const nsAString& aName)
 {
   NS_ConvertUTF16toUTF8 name(aName);
   if (Servo_CounterStyleRule_SetName(mRawRule, &name)) {
     if (StyleSheet* sheet = GetStyleSheet()) {
       sheet->RuleChanged(this);
     }
   }
 }
 
 #define CSS_COUNTER_DESC(name_, method_)                        \
   void                                                          \
-  ServoCounterStyleRule::Get##method_(nsAString& aValue)        \
+  CSSCounterStyleRule::Get##method_(nsAString& aValue)          \
   {                                                             \
     aValue.Truncate();                                          \
     Servo_CounterStyleRule_GetDescriptorCssText(                \
       mRawRule, eCSSCounterDesc_##method_, &aValue);            \
   }                                                             \
   void                                                          \
-  ServoCounterStyleRule::Set##method_(const nsAString& aValue)  \
+  CSSCounterStyleRule::Set##method_(const nsAString& aValue)    \
   {                                                             \
     NS_ConvertUTF16toUTF8 value(aValue);                        \
     if (Servo_CounterStyleRule_SetDescriptor(                   \
           mRawRule, eCSSCounterDesc_##method_, &value)) {       \
       if (StyleSheet* sheet = GetStyleSheet()) {                \
         sheet->RuleChanged(this);                               \
       }                                                         \
     }                                                           \
   }
 #include "nsCSSCounterDescList.h"
 #undef CSS_COUNTER_DESC
 
 /* virtual */ size_t
-ServoCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+CSSCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
 /* virtual */ JSObject*
-ServoCounterStyleRule::WrapObject(JSContext* aCx,
-                                  JS::Handle<JSObject*> aGivenProto)
+CSSCounterStyleRule::WrapObject(JSContext* aCx,
+                                JS::Handle<JSObject*> aGivenProto)
 {
   return CSSCounterStyleRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
+} // namespace dom
 } // namespace mozilla
rename from layout/style/ServoCounterStyleRule.h
rename to layout/style/CSSCounterStyleRule.h
--- a/layout/style/ServoCounterStyleRule.h
+++ b/layout/style/CSSCounterStyleRule.h
@@ -1,37 +1,38 @@
 /* -*- 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_ServoCounterStyleRule_h
-#define mozilla_ServoCounterStyleRule_h
+#ifndef mozilla_CSSCounterStyleRule_h
+#define mozilla_CSSCounterStyleRule_h
 
 #include "mozilla/css/Rule.h"
 #include "mozilla/ServoBindingTypes.h"
 
 struct RawServoCounterStyleRule;
 
 namespace mozilla {
+namespace dom {
 
-class ServoCounterStyleRule final : public css::Rule
+class CSSCounterStyleRule final : public css::Rule
 {
 public:
-  ServoCounterStyleRule(already_AddRefed<RawServoCounterStyleRule> aRawRule,
-                        uint32_t aLine, uint32_t aColumn)
+  CSSCounterStyleRule(already_AddRefed<RawServoCounterStyleRule> aRawRule,
+                      uint32_t aLine, uint32_t aColumn)
     : mozilla::css::Rule(aLine, aColumn)
     , mRawRule(std::move(aRawRule))
   {
   }
 
 private:
-  ServoCounterStyleRule(const ServoCounterStyleRule& aCopy) = delete;
-  ~ServoCounterStyleRule() = default;
+  CSSCounterStyleRule(const CSSCounterStyleRule& aCopy) = delete;
+  ~CSSCounterStyleRule() = default;
 
 public:
   bool IsCCLeaf() const final;
 
 #ifdef DEBUG
   void List(FILE* out = stdout, int32_t aIndent = 0) const final;
 #endif
 
@@ -49,11 +50,12 @@ public:
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
 
 private:
   RefPtr<RawServoCounterStyleRule> mRawRule;
 };
 
+} // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_ServoCounterStyleRule_h
+#endif // mozilla_CSSCounterStyleRule_h
rename from layout/style/ServoFontFaceRule.cpp
rename to layout/style/CSSFontFaceRule.cpp
--- a/layout/style/ServoFontFaceRule.cpp
+++ b/layout/style/CSSFontFaceRule.cpp
@@ -1,230 +1,230 @@
 /* -*- 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/ServoFontFaceRule.h"
+#include "mozilla/dom/CSSFontFaceRule.h"
 
 #include "mozilla/dom/CSSFontFaceRuleBinding.h"
 #include "mozilla/dom/CSSStyleDeclarationBinding.h"
 #include "nsCSSProps.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // -------------------------------------------
-// ServoFontFaceRuleDecl and related routines
+// CSSFontFaceRuleDecl and related routines
 //
 
-// QueryInterface implementation for ServoFontFaceRuleDecl
-NS_INTERFACE_MAP_BEGIN(ServoFontFaceRuleDecl)
+// QueryInterface implementation for CSSFontFaceRuleDecl
+NS_INTERFACE_MAP_BEGIN(CSSFontFaceRuleDecl)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   // We forward the cycle collection interfaces to ContainingRule(), which is
   // never null (in fact, we're part of that object!)
   if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
       aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
     return ContainingRule()->QueryInterface(aIID, aInstancePtr);
   }
   else
 NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF_USING_AGGREGATOR(ServoFontFaceRuleDecl, ContainingRule())
-NS_IMPL_RELEASE_USING_AGGREGATOR(ServoFontFaceRuleDecl, ContainingRule())
+NS_IMPL_ADDREF_USING_AGGREGATOR(CSSFontFaceRuleDecl, ContainingRule())
+NS_IMPL_RELEASE_USING_AGGREGATOR(CSSFontFaceRuleDecl, ContainingRule())
 
 // helper for string GetPropertyValue and RemovePropertyValue
 void
-ServoFontFaceRuleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
-                                        nsAString& aResult) const
+CSSFontFaceRuleDecl::GetPropertyValue(nsCSSFontDesc aFontDescID,
+                                      nsAString& aResult) const
 {
   MOZ_ASSERT(aResult.IsEmpty());
   Servo_FontFaceRule_GetDescriptorCssText(mRawRule, aFontDescID, &aResult);
 }
 
 void
-ServoFontFaceRuleDecl::GetCssText(nsAString& aCssText)
+CSSFontFaceRuleDecl::GetCssText(nsAString& aCssText)
 {
   aCssText.Truncate();
   Servo_FontFaceRule_GetDeclCssText(mRawRule, &aCssText);
 }
 
 void
-ServoFontFaceRuleDecl::SetCssText(const nsAString& aCssText,
-                                  nsIPrincipal* aSubjectPrincipal,
-                                  ErrorResult& aRv)
+CSSFontFaceRuleDecl::SetCssText(const nsAString& aCssText,
+                                nsIPrincipal* aSubjectPrincipal,
+                                ErrorResult& aRv)
 {
   aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); // bug 443978
 }
 
 NS_IMETHODIMP
-ServoFontFaceRuleDecl::GetPropertyValue(const nsAString& aPropName,
-                                        nsAString& aResult)
+CSSFontFaceRuleDecl::GetPropertyValue(const nsAString& aPropName,
+                                      nsAString& aResult)
 {
   aResult.Truncate();
   GetPropertyValue(nsCSSProps::LookupFontDesc(aPropName), aResult);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-ServoFontFaceRuleDecl::RemoveProperty(const nsAString& aPropName,
-                                      nsAString& aResult)
+CSSFontFaceRuleDecl::RemoveProperty(const nsAString& aPropName,
+                                    nsAString& aResult)
 {
   nsCSSFontDesc descID = nsCSSProps::LookupFontDesc(aPropName);
   NS_ASSERTION(descID >= eCSSFontDesc_UNKNOWN &&
                descID < eCSSFontDesc_COUNT,
                "LookupFontDesc returned value out of range");
 
   aResult.Truncate();
   if (descID != eCSSFontDesc_UNKNOWN) {
     GetPropertyValue(descID, aResult);
     Servo_FontFaceRule_ResetDescriptor(mRawRule, descID);
   }
   return NS_OK;
 }
 
 void
-ServoFontFaceRuleDecl::GetPropertyPriority(const nsAString& aPropName,
-                                           nsAString& aResult)
+CSSFontFaceRuleDecl::GetPropertyPriority(const nsAString& aPropName,
+                                         nsAString& aResult)
 {
   // font descriptors do not have priorities at present
   aResult.Truncate();
 }
 
 NS_IMETHODIMP
-ServoFontFaceRuleDecl::SetProperty(const nsAString& aPropName,
-                                   const nsAString& aValue,
-                                   const nsAString& aPriority,
-                                   nsIPrincipal* aSubjectPrincipal)
+CSSFontFaceRuleDecl::SetProperty(const nsAString& aPropName,
+                                 const nsAString& aValue,
+                                 const nsAString& aPriority,
+                                 nsIPrincipal* aSubjectPrincipal)
 {
   // FIXME(heycam): If we are changing unicode-range, then a FontFace object
   // representing this rule must have its mUnicodeRange value invalidated.
 
   return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
 }
 
 uint32_t
-ServoFontFaceRuleDecl::Length()
+CSSFontFaceRuleDecl::Length()
 {
   return Servo_FontFaceRule_Length(mRawRule);
 }
 
 void
-ServoFontFaceRuleDecl::IndexedGetter(uint32_t aIndex, bool& aFound,
-                                     nsAString& aResult)
+CSSFontFaceRuleDecl::IndexedGetter(uint32_t aIndex, bool& aFound,
+                                   nsAString& aResult)
 {
   nsCSSFontDesc id = Servo_FontFaceRule_IndexGetter(mRawRule, aIndex);
   if (id != eCSSFontDesc_UNKNOWN) {
     aFound = true;
     aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
   } else {
     aFound = false;
   }
 }
 
 css::Rule*
-ServoFontFaceRuleDecl::GetParentRule()
+CSSFontFaceRuleDecl::GetParentRule()
 {
   return ContainingRule();
 }
 
 nsINode*
-ServoFontFaceRuleDecl::GetParentObject()
+CSSFontFaceRuleDecl::GetParentObject()
 {
   return ContainingRule()->GetParentObject();
 }
 
 JSObject*
-ServoFontFaceRuleDecl::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
+CSSFontFaceRuleDecl::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
 {
   return CSSStyleDeclarationBinding::Wrap(cx, this, aGivenProto);
 }
 
 // -------------------------------------------
-// ServoFontFaceRule
+// CSSFontFaceRule
 //
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoFontFaceRule)
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSFontFaceRule)
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServoFontFaceRule,
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSFontFaceRule,
                                                mozilla::css::Rule)
   // Keep this in sync with IsCCLeaf.
 
   // Trace the wrapper for our declaration.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecl.TraceWrapper(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoFontFaceRule,
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSFontFaceRule,
                                                 mozilla::css::Rule)
   // Keep this in sync with IsCCLeaf.
 
   // Unlink the wrapper for our declaraton.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p));
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoFontFaceRule,
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSFontFaceRule,
                                                   mozilla::css::Rule)
   // Keep this in sync with IsCCLeaf.
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 bool
-ServoFontFaceRule::IsCCLeaf() const
+CSSFontFaceRule::IsCCLeaf() const
 {
   if (!Rule::IsCCLeaf()) {
     return false;
   }
 
   return !mDecl.PreservingWrapper();
 }
 
-NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ServoFontFaceRule, mozilla::css::Rule)
+NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSFontFaceRule, mozilla::css::Rule)
 
 #ifdef DEBUG
 void
-ServoFontFaceRule::List(FILE* out, int32_t aIndent) const
+CSSFontFaceRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t i = 0; i < aIndent; i++) {
     str.AppendLiteral("  ");
   }
   Servo_FontFaceRule_Debug(Raw(), &str);
   fprintf_stderr(out, "%s\n", str.get());
 }
 #endif
 
 uint16_t
-ServoFontFaceRule::Type() const
+CSSFontFaceRule::Type() const
 {
   return CSSRuleBinding::FONT_FACE_RULE;
 }
 
 void
-ServoFontFaceRule::GetCssText(nsAString& aCssText) const
+CSSFontFaceRule::GetCssText(nsAString& aCssText) const
 {
   aCssText.Truncate();
   Servo_FontFaceRule_GetCssText(Raw(), &aCssText);
 }
 
 nsICSSDeclaration*
-ServoFontFaceRule::Style()
+CSSFontFaceRule::Style()
 {
   return &mDecl;
 }
 
 /* virtual */ size_t
-ServoFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+CSSFontFaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
 /* virtual */ JSObject*
-ServoFontFaceRule::WrapObject(JSContext* aCx,
-                              JS::Handle<JSObject*> aGivenProto)
+CSSFontFaceRule::WrapObject(JSContext* aCx,
+                            JS::Handle<JSObject*> aGivenProto)
 {
   return CSSFontFaceRuleBinding::Wrap(aCx, this, aGivenProto);
 }
rename from layout/style/ServoFontFaceRule.h
rename to layout/style/CSSFontFaceRule.h
--- a/layout/style/ServoFontFaceRule.h
+++ b/layout/style/CSSFontFaceRule.h
@@ -1,70 +1,72 @@
 /* -*- 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_ServoFontFaceRule_h
-#define mozilla_ServoFontFaceRule_h
+#ifndef mozilla_CSSFontFaceRule_h
+#define mozilla_CSSFontFaceRule_h
 
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/css/Rule.h"
 #include "nsICSSDeclaration.h"
 
 namespace mozilla {
+namespace dom {
 
-// A ServoFontFaceRuleDecl is always embeded in a ServoFontFaceRule.
-class ServoFontFaceRule;
-class ServoFontFaceRuleDecl final : public nsICSSDeclaration
+
+// A CSSFontFaceRuleDecl is always embeded in a CSSFontFaceRule.
+class CSSFontFaceRule;
+class CSSFontFaceRuleDecl final : public nsICSSDeclaration
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMCSSSTYLEDECLARATION_HELPER
 
   nsINode* GetParentObject() final;
   void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) final;
 
   void GetPropertyValue(nsCSSFontDesc aFontDescID, nsAString& aResult) const;
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
 
 protected:
   // For accessing the constructor.
-  friend class ServoFontFaceRule;
+  friend class CSSFontFaceRule;
 
-  explicit ServoFontFaceRuleDecl(already_AddRefed<RawServoFontFaceRule> aDecl)
+  explicit CSSFontFaceRuleDecl(already_AddRefed<RawServoFontFaceRule> aDecl)
     : mRawRule(std::move(aDecl)) {}
 
-  ~ServoFontFaceRuleDecl() = default;
+  ~CSSFontFaceRuleDecl() = default;
 
-  inline ServoFontFaceRule* ContainingRule();
-  inline const ServoFontFaceRule* ContainingRule() const;
+  inline CSSFontFaceRule* ContainingRule();
+  inline const CSSFontFaceRule* ContainingRule() const;
 
   RefPtr<RawServoFontFaceRule> mRawRule;
 
 private:
   void* operator new(size_t size) CPP_THROW_NEW = delete;
 };
 
-class ServoFontFaceRule final : public css::Rule
+class CSSFontFaceRule final : public css::Rule
 {
 public:
-  ServoFontFaceRule(already_AddRefed<RawServoFontFaceRule> aRawRule,
+  CSSFontFaceRule(already_AddRefed<RawServoFontFaceRule> aRawRule,
                     uint32_t aLine, uint32_t aColumn)
     : css::Rule(aLine, aColumn)
     , mDecl(std::move(aRawRule))
   {}
 
-  ServoFontFaceRule(const ServoFontFaceRule&) = delete;
+  CSSFontFaceRule(const CSSFontFaceRule&) = delete;
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
-      ServoFontFaceRule, css::Rule)
+      CSSFontFaceRule, css::Rule)
   bool IsCCLeaf() const final;
 
   RawServoFontFaceRule* Raw() const { return mDecl.mRawRule; }
 
   // WebIDL interface
   uint16_t Type() const final;
   void GetCssText(nsAString& aCssText) const final;
   nsICSSDeclaration* Style();
@@ -75,33 +77,34 @@ public:
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
 
 #ifdef DEBUG
   void List(FILE* out = stdout, int32_t aIndent = 0) const final;
 #endif
 
 private:
-  virtual ~ServoFontFaceRule() = default;
+  virtual ~CSSFontFaceRule() = default;
 
   // For computing the offset of mDecl.
-  friend class ServoFontFaceRuleDecl;
+  friend class CSSFontFaceRuleDecl;
 
-  ServoFontFaceRuleDecl mDecl;
+  CSSFontFaceRuleDecl mDecl;
 };
 
-inline ServoFontFaceRule*
-ServoFontFaceRuleDecl::ContainingRule()
+inline CSSFontFaceRule*
+CSSFontFaceRuleDecl::ContainingRule()
 {
-  return reinterpret_cast<ServoFontFaceRule*>
-    (reinterpret_cast<char*>(this) - offsetof(ServoFontFaceRule, mDecl));
+  return reinterpret_cast<CSSFontFaceRule*>
+    (reinterpret_cast<char*>(this) - offsetof(CSSFontFaceRule, mDecl));
 }
 
-inline const ServoFontFaceRule*
-ServoFontFaceRuleDecl::ContainingRule() const
+inline const CSSFontFaceRule*
+CSSFontFaceRuleDecl::ContainingRule() const
 {
-  return reinterpret_cast<const ServoFontFaceRule*>
-    (reinterpret_cast<const char*>(this) - offsetof(ServoFontFaceRule, mDecl));
+  return reinterpret_cast<const CSSFontFaceRule*>
+    (reinterpret_cast<const char*>(this) - offsetof(CSSFontFaceRule, mDecl));
 }
 
+} // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_ServoFontFaceRule_h
+#endif // mozilla_CSSFontFaceRule_h
--- a/layout/style/CSSFontFeatureValuesRule.cpp
+++ b/layout/style/CSSFontFeatureValuesRule.cpp
@@ -5,26 +5,90 @@
  * 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 {
 
+CSSFontFeatureValuesRule::CSSFontFeatureValuesRule(
+  RefPtr<RawServoFontFeatureValuesRule> aRawRule,
+  uint32_t aLine, uint32_t aColumn)
+  : Rule(aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+{
+}
+
+size_t
+CSSFontFeatureValuesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
+#ifdef DEBUG
+void
+CSSFontFeatureValuesRule::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
+CSSFontFeatureValuesRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_FontFeatureValuesRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* CSSFontFeatureValuesRule implementation */
+
+void
+CSSFontFeatureValuesRule::GetFontFamily(nsAString& aFamilyListStr)
+{
+  Servo_FontFeatureValuesRule_GetFontFamily(mRawRule, &aFamilyListStr);
+}
+
+void
+CSSFontFeatureValuesRule::GetValueText(nsAString& aValueText)
+{
+  Servo_FontFeatureValuesRule_GetValueText(mRawRule, &aValueText);
+}
+
+void
+CSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily,
+                                        ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void
+CSSFontFeatureValuesRule::SetValueText(const nsAString& aValueText,
+                                       ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
 // If this ever gets its own cycle-collection bits, reevaluate our IsCCLeaf
 // implementation.
 
 bool
 CSSFontFeatureValuesRule::IsCCLeaf() const
 {
   return Rule::IsCCLeaf();
 }
 
 /* virtual */ JSObject*
 CSSFontFeatureValuesRule::WrapObject(JSContext* aCx,
-                                       JS::Handle<JSObject*> aGivenProto)
+                                     JS::Handle<JSObject*> aGivenProto)
 {
   return CSSFontFeatureValuesRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/layout/style/CSSFontFeatureValuesRule.h
+++ b/layout/style/CSSFontFeatureValuesRule.h
@@ -3,43 +3,52 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CSSFontFeatureValuesRule_h
 #define mozilla_dom_CSSFontFeatureValuesRule_h
 
 #include "mozilla/css/Rule.h"
+#include "mozilla/ServoBindingTypes.h"
 
 #include "nsICSSDeclaration.h"
 
 namespace mozilla {
 namespace dom {
 
-class CSSFontFeatureValuesRule : public css::Rule
+class CSSFontFeatureValuesRule final : public css::Rule
 {
 public:
+  CSSFontFeatureValuesRule(RefPtr<RawServoFontFeatureValuesRule> aRawRule,
+                           uint32_t aLine, uint32_t aColumn);
+
   virtual bool IsCCLeaf() const override;
 
+  RawServoFontFeatureValuesRule* Raw() const { return mRawRule; }
+
   // WebIDL interfaces
   uint16_t Type() const final { return CSSRuleBinding::FONT_FEATURE_VALUES_RULE; }
-  virtual void GetCssText(nsAString& aCssText) const override = 0;
-  virtual void GetFontFamily(nsAString& aFamily) = 0;
-  virtual void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv) = 0;
-  virtual void GetValueText(nsAString& aValueText) = 0;
-  virtual void SetValueText(const nsAString& aValueText, mozilla::ErrorResult& aRv) = 0;
+  void GetCssText(nsAString& aCssText) const override;
+  void GetFontFamily(nsAString& aFamily);
+  void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv);
+  void GetValueText(nsAString& aValueText);
+  void SetValueText(const nsAString& aValueText, mozilla::ErrorResult& aRv);
 
-  virtual size_t
-  SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
+
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
 
   JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
-protected:
-  using Rule::Rule;
+private:
+  ~CSSFontFeatureValuesRule() = default;
 
-  virtual ~CSSFontFeatureValuesRule() {};
+  RefPtr<RawServoFontFeatureValuesRule> mRawRule;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSFontFeatureValuesRule_h
--- a/layout/style/CSSImportRule.cpp
+++ b/layout/style/CSSImportRule.cpp
@@ -3,20 +3,109 @@
 /* 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/CSSImportRule.h"
 
 #include "mozilla/dom/CSSImportRuleBinding.h"
 #include "mozilla/dom/MediaList.h"
+#include "mozilla/ServoBindings.h"
+#include "mozilla/StyleSheet.h"
 
 namespace mozilla {
 namespace dom {
 
+CSSImportRule::CSSImportRule(RefPtr<RawServoImportRule> aRawRule,
+                             uint32_t aLine,
+                             uint32_t aColumn)
+  : Rule(aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+{
+  const auto* sheet = Servo_ImportRule_GetSheet(mRawRule.get());
+  MOZ_ASSERT(sheet);
+  mChildSheet = const_cast<StyleSheet*>(sheet);
+  mChildSheet->SetOwnerRule(this);
+}
+
+CSSImportRule::~CSSImportRule()
+{
+  if (mChildSheet) {
+    mChildSheet->SetOwnerRule(nullptr);
+  }
+}
+
+// QueryInterface implementation for CSSImportRule
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSImportRule)
+NS_INTERFACE_MAP_END_INHERITING(css::Rule)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSImportRule)
+
+NS_IMPL_ADDREF_INHERITED(CSSImportRule, css::Rule)
+NS_IMPL_RELEASE_INHERITED(CSSImportRule, css::Rule)
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSImportRule,
+                                                  css::Rule)
+  // Note the child sheet twice, since the Servo rule also holds a strong
+  // reference to it.
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildSheet");
+  cb.NoteXPCOMChild(tmp->mChildSheet);
+  MOZ_ASSERT_IF(tmp->mRawRule,
+                Servo_ImportRule_GetSheet(tmp->mRawRule) == tmp->mChildSheet);
+  cb.NoteXPCOMChild(tmp->mChildSheet);
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRawRule.stylesheet");
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSImportRule)
+  if (tmp->mChildSheet) {
+    tmp->mChildSheet->SetOwnerRule(nullptr);
+    tmp->mChildSheet = nullptr;
+  }
+  tmp->mRawRule = nullptr;
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(css::Rule)
+
+#ifdef DEBUG
+/* virtual */ void
+CSSImportRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_ImportRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+dom::MediaList*
+CSSImportRule::GetMedia() const
+{
+  // When Bug 1326509 is fixed, we can assert mChildSheet instead.
+  return mChildSheet ? mChildSheet->Media() : nullptr;
+}
+
+void
+CSSImportRule::GetHref(nsAString& aHref) const
+{
+  Servo_ImportRule_GetHref(mRawRule, &aHref);
+}
+
+/* virtual */ void
+CSSImportRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_ImportRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* virtual */ size_t
+CSSImportRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
 bool
 CSSImportRule::IsCCLeaf() const
 {
   // We're not a leaf.
   return false;
 }
 
 /* virtual */ JSObject*
--- a/layout/style/CSSImportRule.h
+++ b/layout/style/CSSImportRule.h
@@ -5,36 +5,52 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CSSImportRule_h
 #define mozilla_dom_CSSImportRule_h
 
 #include "mozilla/css/Rule.h"
 
 namespace mozilla {
+
+class StyleSheet;
+
 namespace dom {
 
-class CSSImportRule : public css::Rule
+class CSSImportRule final : public css::Rule
 {
-protected:
-  using Rule::Rule;
-  virtual ~CSSImportRule() {}
+public:
+  CSSImportRule(RefPtr<RawServoImportRule> aRawRule,
+                uint32_t aLine, uint32_t aColumn);
 
-public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSImportRule, css::Rule)
+
   bool IsCCLeaf() const final;
 
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override = 0;
+    const override;
 
   // WebIDL interface
   uint16_t Type() const final { return CSSRuleBinding::IMPORT_RULE; }
-  virtual void GetHref(nsAString& aHref) const = 0;
-  virtual dom::MediaList* GetMedia() const = 0;
-  virtual StyleSheet* GetStyleSheet() const = 0;
+  void GetCssText(nsAString& aCssText) const override;
+  void GetHref(nsAString& aHref) const;
+  dom::MediaList* GetMedia() const;
+  StyleSheet* GetStyleSheet() const { return mChildSheet; }
 
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
+
+private:
+  ~CSSImportRule();
+
+  RefPtr<RawServoImportRule> mRawRule;
+  RefPtr<StyleSheet> mChildSheet;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSImportRule_h
--- a/layout/style/CSSKeyframeRule.cpp
+++ b/layout/style/CSSKeyframeRule.cpp
@@ -1,22 +1,211 @@
 /* -*- 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/CSSKeyframeRule.h"
 
+#include "mozilla/DeclarationBlock.h"
 #include "mozilla/dom/CSSKeyframeRuleBinding.h"
-#include "nsICSSDeclaration.h"
+#include "nsDOMCSSDeclaration.h"
 
 namespace mozilla {
 namespace dom {
 
+// -------------------------------------------
+// CSSKeyframeDeclaration
+//
+
+class CSSKeyframeDeclaration : public nsDOMCSSDeclaration
+{
+public:
+  explicit CSSKeyframeDeclaration(CSSKeyframeRule* aRule)
+    : mRule(aRule)
+  {
+    mDecls = new DeclarationBlock(
+      Servo_Keyframe_GetStyle(aRule->Raw()).Consume());
+  }
+
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
+    CSSKeyframeDeclaration, nsICSSDeclaration)
+
+  css::Rule* GetParentRule() final { return mRule; }
+
+  void DropReference() {
+    mRule = nullptr;
+    mDecls->SetOwningRule(nullptr);
+  }
+
+  DeclarationBlock* GetCSSDeclaration(Operation aOperation) final
+  {
+    return mDecls;
+  }
+  nsresult SetCSSDeclaration(DeclarationBlock* aDecls) final
+  {
+    if (!mRule) {
+      return NS_OK;
+    }
+    mRule->UpdateRule([this, aDecls]() {
+      if (mDecls != aDecls) {
+        mDecls->SetOwningRule(nullptr);
+        mDecls = aDecls;
+        mDecls->SetOwningRule(mRule);
+        Servo_Keyframe_SetStyle(mRule->Raw(), mDecls->Raw());
+      }
+    });
+    return NS_OK;
+  }
+  ParsingEnvironment GetParsingEnvironment(
+      nsIPrincipal* aSubjectPrincipal) const final
+  {
+    return GetParsingEnvironmentForRule(mRule);
+  }
+  nsIDocument* DocToUpdate() final { return nullptr; }
+
+  nsINode* GetParentObject() final
+  {
+    return mRule ? mRule->GetParentObject() : nullptr;
+  }
+
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+  {
+    size_t n = aMallocSizeOf(this);
+    // TODO we may want to add size of mDecls as well
+    return n;
+  }
+
+private:
+  virtual ~CSSKeyframeDeclaration() {
+    MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
+  }
+
+  CSSKeyframeRule* mRule;
+  RefPtr<DeclarationBlock> mDecls;
+};
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(CSSKeyframeDeclaration)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(CSSKeyframeDeclaration)
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(CSSKeyframeDeclaration)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeDeclaration)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
+
+// -------------------------------------------
+// CSSKeyframeRule
+//
+
+CSSKeyframeRule::CSSKeyframeRule(already_AddRefed<RawServoKeyframe> aRaw,
+                                 uint32_t aLine, uint32_t aColumn)
+    : css::Rule(aLine, aColumn)
+    , mRaw(aRaw) {}
+
+CSSKeyframeRule::~CSSKeyframeRule()
+{
+  if (mDeclaration) {
+    mDeclaration->DropReference();
+  }
+}
+
+NS_IMPL_ADDREF_INHERITED(CSSKeyframeRule, css::Rule)
+NS_IMPL_RELEASE_INHERITED(CSSKeyframeRule, css::Rule)
+
+// QueryInterface implementation for nsCSSKeyframeRule
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeRule)
+NS_INTERFACE_MAP_END_INHERITING(css::Rule)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeRule)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframeRule,
+                                                css::Rule)
+  if (tmp->mDeclaration) {
+    tmp->mDeclaration->DropReference();
+    tmp->mDeclaration = nullptr;
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeRule,
+                                                  css::Rule)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+bool
+CSSKeyframeRule::IsCCLeaf() const
+{
+  return Rule::IsCCLeaf() && !mDeclaration;
+}
+
+#ifdef DEBUG
+/* virtual */ void
+CSSKeyframeRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_Keyframe_Debug(mRaw, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+template<typename Func>
+void
+CSSKeyframeRule::UpdateRule(Func aCallback)
+{
+  aCallback();
+
+  if (StyleSheet* sheet = GetStyleSheet()) {
+    sheet->RuleChanged(this);
+  }
+}
+
+void
+CSSKeyframeRule::GetKeyText(nsAString& aKeyText)
+{
+  Servo_Keyframe_GetKeyText(mRaw, &aKeyText);
+}
+
+void
+CSSKeyframeRule::SetKeyText(const nsAString& aKeyText)
+{
+  NS_ConvertUTF16toUTF8 keyText(aKeyText);
+  UpdateRule([this, &keyText]() {
+    Servo_Keyframe_SetKeyText(mRaw, &keyText);
+  });
+}
+
+void
+CSSKeyframeRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_Keyframe_GetCssText(mRaw, &aCssText);
+}
+
+nsICSSDeclaration*
+CSSKeyframeRule::Style()
+{
+  if (!mDeclaration) {
+    mDeclaration = new CSSKeyframeDeclaration(this);
+  }
+  return mDeclaration;
+}
+
+size_t
+CSSKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  size_t n = aMallocSizeOf(this);
+  if (mDeclaration) {
+    n += mDeclaration->SizeOfIncludingThis(aMallocSizeOf);
+  }
+  return n;
+}
+
 /* virtual */ JSObject*
 CSSKeyframeRule::WrapObject(JSContext* aCx,
                             JS::Handle<JSObject*> aGivenProto)
 {
   return CSSKeyframeRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
--- a/layout/style/CSSKeyframeRule.h
+++ b/layout/style/CSSKeyframeRule.h
@@ -3,38 +3,63 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CSSKeyframeRule_h
 #define mozilla_dom_CSSKeyframeRule_h
 
 #include "mozilla/css/Rule.h"
+#include "mozilla/ServoBindingTypes.h"
 
 class nsICSSDeclaration;
+class DeclarationBlock;
 
 namespace mozilla {
 namespace dom {
 
-class CSSKeyframeRule : public css::Rule
+class CSSKeyframeDeclaration;
+
+class CSSKeyframeRule final : public css::Rule
 {
-protected:
-  using css::Rule::Rule;
-  virtual ~CSSKeyframeRule() {}
+public:
+  CSSKeyframeRule(already_AddRefed<RawServoKeyframe> aRaw,
+                  uint32_t aLine, uint32_t aColumn);
 
-public:
-  bool IsCCLeaf() const override { return Rule::IsCCLeaf(); }
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSKeyframeRule,
+                                           css::Rule)
+  bool IsCCLeaf() const final;
+
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
+  RawServoKeyframe* Raw() const { return mRaw; }
 
   // WebIDL interface
   uint16_t Type() const final { return CSSRuleBinding::KEYFRAME_RULE; }
-  virtual void GetKeyText(nsAString& aKey) = 0;
-  virtual void SetKeyText(const nsAString& aKey) = 0;
-  virtual nsICSSDeclaration* Style() = 0;
+  void GetCssText(nsAString& aCssText) const final;
+  void GetKeyText(nsAString& aKey);
+  void SetKeyText(const nsAString& aKey);
+  nsICSSDeclaration* Style();
 
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
+
+private:
+  virtual ~CSSKeyframeRule();
+
+  friend class CSSKeyframeDeclaration;
+
+  template<typename Func>
+  void UpdateRule(Func aCallback);
+
+  RefPtr<RawServoKeyframe> mRaw;
+  // lazily created when needed
+  RefPtr<CSSKeyframeDeclaration> mDeclaration;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSKeyframeRule_h
--- a/layout/style/CSSKeyframesRule.cpp
+++ b/layout/style/CSSKeyframesRule.cpp
@@ -2,20 +2,344 @@
 /* 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/CSSKeyframesRule.h"
 
 #include "mozilla/dom/CSSKeyframesRuleBinding.h"
+#include "mozilla/dom/CSSRuleList.h"
+#include "mozilla/ServoBindings.h"
+
+#include <limits>
 
 namespace mozilla {
 namespace dom {
 
+// -------------------------------------------
+// CSSKeyframeList
+//
+
+class CSSKeyframeList : public dom::CSSRuleList
+{
+public:
+  explicit CSSKeyframeList(already_AddRefed<RawServoKeyframesRule> aRawRule)
+    : mRawRule(aRawRule)
+  {
+    mRules.SetCount(Servo_KeyframesRule_GetCount(mRawRule));
+  }
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSKeyframeList, dom::CSSRuleList)
+
+  void SetParentRule(CSSKeyframesRule* aParentRule)
+  {
+    mParentRule = aParentRule;
+    for (css::Rule* rule : mRules) {
+      if (rule) {
+        rule->SetParentRule(aParentRule);
+      }
+    }
+  }
+  void SetStyleSheet(StyleSheet* aSheet)
+  {
+    mStyleSheet = aSheet;
+    for (css::Rule* rule : mRules) {
+      if (rule) {
+        rule->SetStyleSheet(aSheet);
+      }
+    }
+  }
+
+  StyleSheet* GetParentObject() final { return mStyleSheet; }
+
+  CSSKeyframeRule* GetRule(uint32_t aIndex) {
+    if (!mRules[aIndex]) {
+      uint32_t line = 0, column = 0;
+      RefPtr<RawServoKeyframe> rule =
+        Servo_KeyframesRule_GetKeyframeAt(mRawRule, aIndex,
+                                          &line, &column).Consume();
+      CSSKeyframeRule* ruleObj =
+        new CSSKeyframeRule(rule.forget(), line, column);
+      mRules.ReplaceObjectAt(ruleObj, aIndex);
+      ruleObj->SetStyleSheet(mStyleSheet);
+      ruleObj->SetParentRule(mParentRule);
+    }
+    return static_cast<CSSKeyframeRule*>(mRules[aIndex]);
+  }
+
+  CSSKeyframeRule* IndexedGetter(uint32_t aIndex, bool& aFound) final
+  {
+    if (aIndex >= mRules.Length()) {
+      aFound = false;
+      return nullptr;
+    }
+    aFound = true;
+    return GetRule(aIndex);
+  }
+
+  void AppendRule() {
+    mRules.AppendObject(nullptr);
+  }
+
+  void RemoveRule(uint32_t aIndex) {
+    mRules.RemoveObjectAt(aIndex);
+  }
+
+  uint32_t Length() final { return mRules.Length(); }
+
+  void DropReference()
+  {
+    mStyleSheet = nullptr;
+    mParentRule = nullptr;
+    for (css::Rule* rule : mRules) {
+      if (rule) {
+        rule->SetStyleSheet(nullptr);
+        rule->SetParentRule(nullptr);
+      }
+    }
+  }
+
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+  {
+    size_t n = aMallocSizeOf(this);
+    for (const css::Rule* rule : mRules) {
+      n += rule ? rule->SizeOfIncludingThis(aMallocSizeOf) : 0;
+    }
+    return n;
+  }
+
+private:
+  virtual ~CSSKeyframeList() {
+    MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
+    MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
+    DropAllRules();
+  }
+
+  void DropAllRules()
+  {
+    if (mParentRule || mStyleSheet) {
+      DropReference();
+    }
+    mRules.Clear();
+    mRawRule = nullptr;
+  }
+
+  // may be nullptr when the style sheet drops the reference to us.
+  StyleSheet* mStyleSheet = nullptr;
+  CSSKeyframesRule* mParentRule = nullptr;
+  RefPtr<RawServoKeyframesRule> mRawRule;
+  nsCOMArray<css::Rule> mRules;
+};
+
+// QueryInterface implementation for CSSKeyframeList
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframeList)
+NS_INTERFACE_MAP_END_INHERITING(dom::CSSRuleList)
+
+NS_IMPL_ADDREF_INHERITED(CSSKeyframeList, dom::CSSRuleList)
+NS_IMPL_RELEASE_INHERITED(CSSKeyframeList, dom::CSSRuleList)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframeList)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CSSKeyframeList)
+  tmp->DropAllRules();
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframeList,
+                                                  dom::CSSRuleList)
+  for (css::Rule* rule : tmp->mRules) {
+    if (rule) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
+      cb.NoteXPCOMChild(rule);
+    }
+  }
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+// -------------------------------------------
+// CSSKeyframesRule
+//
+
+CSSKeyframesRule::CSSKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
+                                   uint32_t aLine, uint32_t aColumn)
+  : css::Rule(aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+{
+}
+
+CSSKeyframesRule::~CSSKeyframesRule()
+{
+  if (mKeyframeList) {
+    mKeyframeList->DropReference();
+  }
+}
+
+NS_IMPL_ADDREF_INHERITED(CSSKeyframesRule, css::Rule)
+NS_IMPL_RELEASE_INHERITED(CSSKeyframesRule, css::Rule)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSKeyframesRule)
+NS_INTERFACE_MAP_END_INHERITING(css::Rule)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSKeyframesRule)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSKeyframesRule,
+                                                css::Rule)
+  if (tmp->mKeyframeList) {
+    tmp->mKeyframeList->DropReference();
+    tmp->mKeyframeList = nullptr;
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSKeyframesRule, Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mKeyframeList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+/* virtual */ bool
+CSSKeyframesRule::IsCCLeaf() const
+{
+  // If we don't have rule list constructed, we are a leaf.
+  return Rule::IsCCLeaf() && !mKeyframeList;
+}
+
+#ifdef DEBUG
+/* virtual */ void
+CSSKeyframesRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_KeyframesRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+/* virtual */ void
+CSSKeyframesRule::SetStyleSheet(StyleSheet* aSheet)
+{
+  if (mKeyframeList) {
+    mKeyframeList->SetStyleSheet(aSheet);
+  }
+  css::Rule::SetStyleSheet(aSheet);
+}
+
+static const uint32_t kRuleNotFound = std::numeric_limits<uint32_t>::max();
+
+uint32_t
+CSSKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
+{
+  NS_ConvertUTF16toUTF8 key(aKey);
+  return Servo_KeyframesRule_FindRule(mRawRule, &key);
+}
+
+template<typename Func>
+void
+CSSKeyframesRule::UpdateRule(Func aCallback)
+{
+  aCallback();
+  if (StyleSheet* sheet = GetStyleSheet()) {
+    sheet->RuleChanged(this);
+  }
+}
+
+void
+CSSKeyframesRule::GetName(nsAString& aName) const
+{
+  nsAtom* name = Servo_KeyframesRule_GetName(mRawRule);
+  aName = nsDependentAtomString(name);
+}
+
+void
+CSSKeyframesRule::SetName(const nsAString& aName)
+{
+  RefPtr<nsAtom> name = NS_Atomize(aName);
+  nsAtom* oldName = Servo_KeyframesRule_GetName(mRawRule);
+  if (name == oldName) {
+    return;
+  }
+
+  UpdateRule([this, &name]() {
+    Servo_KeyframesRule_SetName(mRawRule, name.forget().take());
+  });
+}
+
+void
+CSSKeyframesRule::AppendRule(const nsAString& aRule)
+{
+  StyleSheet* sheet = GetStyleSheet();
+  if (!sheet) {
+    // We cannot parse the rule if we don't have a stylesheet.
+    return;
+  }
+
+  NS_ConvertUTF16toUTF8 rule(aRule);
+  UpdateRule([this, sheet, &rule]() {
+    bool parsedOk = Servo_KeyframesRule_AppendRule(
+      mRawRule, sheet->RawContents(), &rule);
+    if (parsedOk && mKeyframeList) {
+      mKeyframeList->AppendRule();
+    }
+  });
+}
+
+void
+CSSKeyframesRule::DeleteRule(const nsAString& aKey)
+{
+  auto index = FindRuleIndexForKey(aKey);
+  if (index == kRuleNotFound) {
+    return;
+  }
+
+  UpdateRule([this, index]() {
+    Servo_KeyframesRule_DeleteRule(mRawRule, index);
+    if (mKeyframeList) {
+      mKeyframeList->RemoveRule(index);
+    }
+  });
+}
+
+/* virtual */ void
+CSSKeyframesRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_KeyframesRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* virtual */ dom::CSSRuleList*
+CSSKeyframesRule::CssRules()
+{
+  if (!mKeyframeList) {
+    mKeyframeList = new CSSKeyframeList(do_AddRef(mRawRule));
+    mKeyframeList->SetParentRule(this);
+    if (StyleSheet* sheet = GetStyleSheet()) {
+      mKeyframeList->SetStyleSheet(sheet);
+    }
+  }
+  return mKeyframeList;
+}
+
+/* virtual */ dom::CSSKeyframeRule*
+CSSKeyframesRule::FindRule(const nsAString& aKey)
+{
+  auto index = FindRuleIndexForKey(aKey);
+  if (index != kRuleNotFound) {
+    // Construct mKeyframeList but ignore the result.
+    CssRules();
+    return mKeyframeList->GetRule(index);
+  }
+  return nullptr;
+}
+
+/* virtual */ size_t
+CSSKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  size_t n = aMallocSizeOf(this);
+  if (mKeyframeList) {
+    n += mKeyframeList->SizeOfIncludingThis(aMallocSizeOf);
+  }
+  return n;
+}
 
 /* virtual */ JSObject*
 CSSKeyframesRule::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return CSSKeyframesRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
--- a/layout/style/CSSKeyframesRule.h
+++ b/layout/style/CSSKeyframesRule.h
@@ -8,37 +8,58 @@
 #define mozilla_dom_CSSKeyframesRule_h
 
 #include "mozilla/css/Rule.h"
 #include "mozilla/dom/CSSKeyframeRule.h"
 
 namespace mozilla {
 namespace dom {
 
-class CSSKeyframesRule : public css::Rule
+class CSSKeyframeList;
+
+class CSSKeyframesRule final : public css::Rule
 {
-protected:
-  using css::Rule::Rule;
-  virtual ~CSSKeyframesRule() {}
+public:
+  CSSKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
+                   uint32_t aLine, uint32_t aColumn);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSKeyframesRule,
+                                           css::Rule)
 
-public:
-  // Let's not worry for now about sorting out whether we're a leaf or not.
-  bool IsCCLeaf() const override { return false; }
+  bool IsCCLeaf() const final;
+
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
+  void SetStyleSheet(StyleSheet* aSheet) final;
 
   // WebIDL interface
   uint16_t Type() const final { return CSSRuleBinding::KEYFRAMES_RULE; }
-  virtual void GetName(nsAString& aName) const = 0;
-  virtual void SetName(const nsAString& aName) = 0;
-  virtual CSSRuleList* CssRules() = 0;
-  virtual void AppendRule(const nsAString& aRule) = 0;
-  virtual void DeleteRule(const nsAString& aKey) = 0;
-  virtual CSSKeyframeRule* FindRule(const nsAString& aKey) = 0;
+  void GetCssText(nsAString& aCssText) const final;
+  void GetName(nsAString& aName) const;
+  void SetName(const nsAString& aName);
+  CSSRuleList* CssRules();
+  void AppendRule(const nsAString& aRule);
+  void DeleteRule(const nsAString& aKey);
+  CSSKeyframeRule* FindRule(const nsAString& aKey);
 
-
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
 
   JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
+
+private:
+  uint32_t FindRuleIndexForKey(const nsAString& aKey);
+
+  template<typename Func>
+  void UpdateRule(Func aCallback);
+
+  virtual ~CSSKeyframesRule();
+
+  RefPtr<RawServoKeyframesRule> mRawRule;
+  RefPtr<CSSKeyframeList> mKeyframeList; // lazily constructed
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSKeyframesRule_h
--- a/layout/style/CSSMediaRule.cpp
+++ b/layout/style/CSSMediaRule.cpp
@@ -7,16 +7,108 @@
 #include "mozilla/dom/CSSMediaRule.h"
 
 #include "mozilla/dom/CSSMediaRuleBinding.h"
 #include "mozilla/dom/MediaList.h"
 
 namespace mozilla {
 namespace dom {
 
+CSSMediaRule::CSSMediaRule(RefPtr<RawServoMediaRule> aRawRule,
+                           uint32_t aLine, uint32_t aColumn)
+  : ConditionRule(Servo_MediaRule_GetRules(aRawRule).Consume(), aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+{
+}
+
+CSSMediaRule::~CSSMediaRule()
+{
+  if (mMediaList) {
+    mMediaList->SetStyleSheet(nullptr);
+  }
+}
+
+NS_IMPL_ADDREF_INHERITED(CSSMediaRule, css::ConditionRule)
+NS_IMPL_RELEASE_INHERITED(CSSMediaRule, css::ConditionRule)
+
+// QueryInterface implementation for MediaRule
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSMediaRule)
+NS_INTERFACE_MAP_END_INHERITING(css::ConditionRule)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSMediaRule)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSMediaRule, css::ConditionRule)
+  if (tmp->mMediaList) {
+    tmp->mMediaList->SetStyleSheet(nullptr);
+    tmp->mMediaList = nullptr;
+  }
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSMediaRule, css::ConditionRule)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+/* virtual */ void
+CSSMediaRule::SetStyleSheet(StyleSheet* aSheet)
+{
+  if (mMediaList) {
+    mMediaList->SetStyleSheet(aSheet);
+  }
+  ConditionRule::SetStyleSheet(aSheet);
+}
+
+#ifdef DEBUG
+/* virtual */ void
+CSSMediaRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_MediaRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+void
+CSSMediaRule::GetConditionText(nsAString& aConditionText)
+{
+  Media()->GetMediaText(aConditionText);
+}
+
+void
+CSSMediaRule::SetConditionText(const nsAString& aConditionText,
+                               ErrorResult& aRv)
+{
+  Media()->SetMediaText(aConditionText);
+}
+
+/* virtual */ void
+CSSMediaRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_MediaRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* virtual */ dom::MediaList*
+CSSMediaRule::Media()
+{
+  if (!mMediaList) {
+    mMediaList = new MediaList(Servo_MediaRule_GetMedia(mRawRule).Consume());
+    mMediaList->SetStyleSheet(GetStyleSheet());
+  }
+  return mMediaList;
+}
+
+/* virtual */ size_t
+CSSMediaRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
 /* virtual */ JSObject*
 CSSMediaRule::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return CSSMediaRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/layout/style/CSSMediaRule.h
+++ b/layout/style/CSSMediaRule.h
@@ -3,31 +3,56 @@
 /* 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_CSSMediaRule_h
 #define mozilla_dom_CSSMediaRule_h
 
 #include "mozilla/css/GroupRule.h"
+#include "mozilla/ServoBindingTypes.h"
 
 namespace mozilla {
 namespace dom {
 
-class CSSMediaRule : public css::ConditionRule
+class CSSMediaRule final : public css::ConditionRule
 {
-protected:
-  using ConditionRule::ConditionRule;
-  virtual ~CSSMediaRule() {}
+public:
+  CSSMediaRule(RefPtr<RawServoMediaRule> aRawRule,
+               uint32_t aLine, uint32_t aColumn);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CSSMediaRule, css::ConditionRule)
 
-public:
+  void SetStyleSheet(StyleSheet* aSheet) override;
+
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
+  RawServoMediaRule* Raw() const { return mRawRule; }
+
   // WebIDL interface
   uint16_t Type() const override { return CSSRuleBinding::MEDIA_RULE; }
-  virtual MediaList* Media() = 0;
+  // WebIDL interface
+  void GetCssText(nsAString& aCssText) const final;
+  void GetConditionText(nsAString& aConditionText) final;
+  void SetConditionText(const nsAString& aConditionText,
+                        ErrorResult& aRv) final;
+  dom::MediaList* Media();
+
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
+    const override;
 
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
+
+private:
+  virtual ~CSSMediaRule();
+
+  RefPtr<RawServoMediaRule> mRawRule;
+  RefPtr<dom::MediaList> mMediaList;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSMediaRule_h
--- a/layout/style/CSSMozDocumentRule.cpp
+++ b/layout/style/CSSMozDocumentRule.cpp
@@ -62,10 +62,64 @@ CSSMozDocumentRule::Match(nsIDocument* a
         return true;
       }
     } break;
   }
 
   return false;
 }
 
+CSSMozDocumentRule::CSSMozDocumentRule(RefPtr<RawServoMozDocumentRule> aRawRule,
+                                       uint32_t aLine, uint32_t aColumn)
+  : css::ConditionRule(Servo_MozDocumentRule_GetRules(aRawRule).Consume(),
+                       aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+{
+}
+
+NS_IMPL_ADDREF_INHERITED(CSSMozDocumentRule, css::ConditionRule)
+NS_IMPL_RELEASE_INHERITED(CSSMozDocumentRule, css::ConditionRule)
+
+// QueryInterface implementation for MozDocumentRule
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSMozDocumentRule)
+NS_INTERFACE_MAP_END_INHERITING(css::ConditionRule)
+
+#ifdef DEBUG
+/* virtual */ void
+CSSMozDocumentRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_MozDocumentRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+void
+CSSMozDocumentRule::GetConditionText(nsAString& aConditionText)
+{
+  Servo_MozDocumentRule_GetConditionText(mRawRule, &aConditionText);
+}
+
+void
+CSSMozDocumentRule::SetConditionText(const nsAString& aConditionText,
+                                     ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+/* virtual */ void
+CSSMozDocumentRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_MozDocumentRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* virtual */ size_t
+CSSMozDocumentRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/layout/style/CSSMozDocumentRule.h
+++ b/layout/style/CSSMozDocumentRule.h
@@ -4,36 +4,56 @@
  * 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_CSSMozDocumentRule_h
 #define mozilla_dom_CSSMozDocumentRule_h
 
 #include "mozilla/css/GroupRule.h"
 #include "mozilla/css/URLMatchingFunction.h"
+#include "mozilla/ServoBindingTypes.h"
 
 namespace mozilla {
 namespace dom {
 
-class CSSMozDocumentRule : public css::ConditionRule
+class CSSMozDocumentRule final : public css::ConditionRule
 {
-protected:
-  using ConditionRule::ConditionRule;
-  virtual ~CSSMozDocumentRule() {}
+public:
+  CSSMozDocumentRule(RefPtr<RawServoMozDocumentRule> aRawRule,
+                     uint32_t aLine, uint32_t aColumn);
 
-public:
+  NS_DECL_ISUPPORTS_INHERITED
+
   static bool Match(nsIDocument* aDoc,
                     nsIURI* aDocURI,
                     const nsACString& aDocURISpec,
                     const nsACString& aPattern,
                     css::URLMatchingFunction aUrlMatchingFunction);
 
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
+  RawServoMozDocumentRule* Raw() const { return mRawRule; }
+
   // WebIDL interface
   uint16_t Type() const final { return CSSRuleBinding::DOCUMENT_RULE; }
+  void GetCssText(nsAString& aCssText) const final;
+  void GetConditionText(nsAString& aConditionText) final;
+  void SetConditionText(const nsAString& aConditionText,
+                        ErrorResult& aRv) final;
+
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
+    const override;
 
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
+
+private:
+  ~CSSMozDocumentRule() = default;
+
+  RefPtr<RawServoMozDocumentRule> mRawRule;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSMozDocumentRule_h
rename from layout/style/ServoNamespaceRule.cpp
rename to layout/style/CSSNamespaceRule.cpp
--- a/layout/style/ServoNamespaceRule.cpp
+++ b/layout/style/CSSNamespaceRule.cpp
@@ -1,57 +1,57 @@
 /* -*- 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/ServoNamespaceRule.h"
+#include "mozilla/dom/CSSNamespaceRule.h"
 
 #include "mozilla/ServoBindings.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
-ServoNamespaceRule::~ServoNamespaceRule()
+CSSNamespaceRule::~CSSNamespaceRule()
 {
 }
 
 #ifdef DEBUG
 void
-ServoNamespaceRule::List(FILE* out, int32_t aIndent) const
+CSSNamespaceRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t i = 0; i < aIndent; i++) {
     str.AppendLiteral("  ");
   }
   Servo_NamespaceRule_Debug(mRawRule, &str);
   fprintf_stderr(out, "%s\n", str.get());
 }
 #endif
 
 nsAtom*
-ServoNamespaceRule::GetPrefix() const
+CSSNamespaceRule::GetPrefix() const
 {
   return Servo_NamespaceRule_GetPrefix(mRawRule);
 }
 
 void
-ServoNamespaceRule::GetURLSpec(nsString& aURLSpec) const
+CSSNamespaceRule::GetURLSpec(nsString& aURLSpec) const
 {
   nsAtom* atom = Servo_NamespaceRule_GetURI(mRawRule);
   atom->ToString(aURLSpec);
 }
 
 void
-ServoNamespaceRule::GetCssText(nsAString& aCssText) const
+CSSNamespaceRule::GetCssText(nsAString& aCssText) const
 {
   Servo_NamespaceRule_GetCssText(mRawRule, &aCssText);
 }
 
 size_t
-ServoNamespaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+CSSNamespaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
 } // namespace mozilla
--- a/layout/style/CSSNamespaceRule.h
+++ b/layout/style/CSSNamespaceRule.h
@@ -4,48 +4,66 @@
  * 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_CSSNamespaceRule_h
 #define mozilla_dom_CSSNamespaceRule_h
 
 #include "mozilla/css/Rule.h"
 #include "mozilla/dom/CSSNamespaceRuleBinding.h"
+#include "mozilla/ServoBindingTypes.h"
 
 class nsAtom;
 
 namespace mozilla {
 namespace dom {
 
-class CSSNamespaceRule : public css::Rule
+class CSSNamespaceRule final : public css::Rule
 {
-protected:
-  using Rule::Rule;
+public:
+  CSSNamespaceRule(already_AddRefed<RawServoNamespaceRule> aRule,
+                   uint32_t aLine, uint32_t aColumn)
+    : css::Rule(aLine, aColumn)
+    , mRawRule(std::move(aRule))
+  {
+  }
 
-public:
   bool IsCCLeaf() const final {
     return Rule::IsCCLeaf();
   }
 
-  virtual nsAtom* GetPrefix() const = 0;
-  virtual void GetURLSpec(nsString& aURLSpec) const = 0;
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
+  nsAtom* GetPrefix() const;
+  void GetURLSpec(nsString& aURLSpec) const;
+
+  // WebIDL interface
+  void GetCssText(nsAString& aCssText) const final;
 
   // WebIDL interfaces
   uint16_t Type() const final { return CSSRuleBinding::NAMESPACE_RULE; }
+
   void GetNamespaceURI(nsString& aNamespaceURI) {
     GetURLSpec(aNamespaceURI);
   }
+
   void GetPrefix(DOMString& aPrefix) {
     aPrefix.SetKnownLiveAtom(GetPrefix(), DOMString::eTreatNullAsEmpty);
   }
 
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
+  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
 
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) final {
     return CSSNamespaceRuleBinding::Wrap(aCx, this, aGivenProto);
   }
+
+private:
+  ~CSSNamespaceRule();
+  RefPtr<RawServoNamespaceRule> mRawRule;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSNamespaceRule_h
--- a/layout/style/CSSPageRule.cpp
+++ b/layout/style/CSSPageRule.cpp
@@ -1,21 +1,189 @@
 /* -*- 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/CSSPageRule.h"
+#include "mozilla/dom/CSSPageRuleBinding.h"
 
-#include "mozilla/dom/CSSPageRuleBinding.h"
+#include "mozilla/DeclarationBlock.h"
+#include "mozilla/ServoBindings.h"
 
 namespace mozilla {
 namespace dom {
 
+// -- CSSPageRuleDeclaration ---------------------------------------
+
+CSSPageRuleDeclaration::CSSPageRuleDeclaration(
+  already_AddRefed<RawServoDeclarationBlock> aDecls)
+  : mDecls(new DeclarationBlock(std::move(aDecls)))
+{
+}
+
+CSSPageRuleDeclaration::~CSSPageRuleDeclaration()
+{
+  mDecls->SetOwningRule(nullptr);
+}
+
+// QueryInterface implementation for CSSPageRuleDeclaration
+NS_INTERFACE_MAP_BEGIN(CSSPageRuleDeclaration)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  // We forward the cycle collection interfaces to Rule(), which is
+  // never null (in fact, we're part of that object!)
+  if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
+      aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
+    return Rule()->QueryInterface(aIID, aInstancePtr);
+  }
+  else
+NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
+
+NS_IMPL_ADDREF_USING_AGGREGATOR(CSSPageRuleDeclaration, Rule())
+NS_IMPL_RELEASE_USING_AGGREGATOR(CSSPageRuleDeclaration, Rule())
+
+/* nsDOMCSSDeclaration implementation */
+
+css::Rule*
+CSSPageRuleDeclaration::GetParentRule()
+{
+  return Rule();
+}
+
+nsINode*
+CSSPageRuleDeclaration::GetParentObject()
+{
+  return Rule()->GetParentObject();
+}
+
+DeclarationBlock*
+CSSPageRuleDeclaration::GetCSSDeclaration(Operation aOperation)
+{
+  return mDecls;
+}
+
+nsresult
+CSSPageRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
+{
+  MOZ_ASSERT(aDecl, "must be non-null");
+  CSSPageRule* rule = Rule();
+
+  if (aDecl != mDecls) {
+    mDecls->SetOwningRule(nullptr);
+    RefPtr<DeclarationBlock> decls = aDecl;
+    Servo_PageRule_SetStyle(rule->Raw(), decls->Raw());
+    mDecls = decls.forget();
+    mDecls->SetOwningRule(rule);
+  }
+
+  return NS_OK;
+}
+
+nsIDocument*
+CSSPageRuleDeclaration::DocToUpdate()
+{
+  return nullptr;
+}
+
+nsDOMCSSDeclaration::ParsingEnvironment
+CSSPageRuleDeclaration::GetParsingEnvironment(
+  nsIPrincipal* aSubjectPrincipal) const
+{
+  return GetParsingEnvironmentForRule(Rule());
+}
+
+// -- CSSPageRule --------------------------------------------------
+
+CSSPageRule::CSSPageRule(RefPtr<RawServoPageRule> aRawRule,
+                         uint32_t aLine, uint32_t aColumn)
+  : Rule(aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+  , mDecls(Servo_PageRule_GetStyle(mRawRule).Consume())
+{
+}
+
+NS_IMPL_ADDREF_INHERITED(CSSPageRule, css::Rule)
+NS_IMPL_RELEASE_INHERITED(CSSPageRule, css::Rule)
+
+// QueryInterface implementation for PageRule
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSPageRule)
+NS_INTERFACE_MAP_END_INHERITING(css::Rule)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSPageRule)
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSPageRule, css::Rule)
+  // Keep this in sync with IsCCLeaf.
+
+  // Trace the wrapper for our declaration.  This just expands out
+  // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
+  // directly because the wrapper is on the declaration, not on us.
+  tmp->mDecls.TraceWrapper(aCallbacks, aClosure);
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSPageRule, css::Rule)
+  // Keep this in sync with IsCCLeaf.
+
+  // Unlink the wrapper for our declaraton.  This just expands out
+  // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
+  // directly because the wrapper is on the declaration, not on us.
+  tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
+  tmp->mDecls.mDecls->SetOwningRule(nullptr);
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSPageRule, css::Rule)
+  // Keep this in sync with IsCCLeaf.
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+bool
+CSSPageRule::IsCCLeaf() const
+{
+  if (!Rule::IsCCLeaf()) {
+    return false;
+  }
+
+  return !mDecls.PreservingWrapper();
+}
+
+size_t
+CSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
+#ifdef DEBUG
+void
+CSSPageRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_PageRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+/* CSSRule implementation */
+
+void
+CSSPageRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_PageRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* CSSPageRule implementation */
+
+nsICSSDeclaration*
+CSSPageRule::Style()
+{
+  return &mDecls;
+}
+
 JSObject*
 CSSPageRule::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return CSSPageRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/layout/style/CSSPageRule.h
+++ b/layout/style/CSSPageRule.h
@@ -3,39 +3,107 @@
 /* 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_CSSPageRule_h
 #define mozilla_dom_CSSPageRule_h
 
 #include "mozilla/css/Rule.h"
+#include "mozilla/ServoBindingTypes.h"
 
+#include "nsDOMCSSDeclaration.h"
 #include "nsICSSDeclaration.h"
 
 namespace mozilla {
+class DeclarationBlock;
+
 namespace dom {
+class DocGroup;
+class CSSPageRule;
 
-class CSSPageRule : public css::Rule
+class CSSPageRuleDeclaration final : public nsDOMCSSDeclaration
 {
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+
+  css::Rule* GetParentRule() final;
+  nsINode* GetParentObject() final;
+
 protected:
-  using Rule::Rule;
-  virtual ~CSSPageRule() {};
+  DeclarationBlock* GetCSSDeclaration(Operation aOperation) final;
+  nsresult SetCSSDeclaration(DeclarationBlock* aDecl) final;
+  nsIDocument* DocToUpdate() final;
+  nsDOMCSSDeclaration::ParsingEnvironment
+  GetParsingEnvironment(nsIPrincipal* aSubjectPrincipal) const final;
+
+private:
+  // For accessing the constructor.
+  friend class CSSPageRule;
+
+  explicit CSSPageRuleDeclaration(
+    already_AddRefed<RawServoDeclarationBlock> aDecls);
+  ~CSSPageRuleDeclaration();
+
+  inline CSSPageRule* Rule();
+  inline const CSSPageRule* Rule() const;
 
+  RefPtr<DeclarationBlock> mDecls;
+};
+
+class CSSPageRule final : public css::Rule
+{
 public:
-  virtual bool IsCCLeaf() const override = 0;
+  CSSPageRule(RefPtr<RawServoPageRule> aRawRule,
+                uint32_t aLine, uint32_t aColumn);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
+    CSSPageRule, css::Rule
+  )
+
+  bool IsCCLeaf() const final;
+
+  RawServoPageRule* Raw() const { return mRawRule; }
 
   // WebIDL interfaces
   uint16_t Type() const final { return CSSRuleBinding::PAGE_RULE; }
-  virtual void GetCssText(nsAString& aCssText) const override = 0;
-  virtual nsICSSDeclaration* Style() = 0;
+  void GetCssText(nsAString& aCssText) const final;
+  nsICSSDeclaration* Style();
 
-  virtual size_t
-  SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override = 0;
+  size_t
+  SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
+
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
 
   JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
+
+private:
+  ~CSSPageRule() = default;
+
+  // For computing the offset of mDecls.
+  friend class CSSPageRuleDeclaration;
+
+  RefPtr<RawServoPageRule> mRawRule;
+  CSSPageRuleDeclaration mDecls;
 };
 
+CSSPageRule*
+CSSPageRuleDeclaration::Rule()
+{
+  return reinterpret_cast<CSSPageRule*>(
+    reinterpret_cast<uint8_t*>(this) - offsetof(CSSPageRule, mDecls));
+}
+
+const CSSPageRule*
+CSSPageRuleDeclaration::Rule() const
+{
+  return reinterpret_cast<const CSSPageRule*>(
+    reinterpret_cast<const uint8_t*>(this) - offsetof(CSSPageRule, mDecls));
+}
+
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSPageRule_h
rename from layout/style/ServoStyleRule.cpp
rename to layout/style/CSSStyleRule.cpp
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/CSSStyleRule.cpp
@@ -1,240 +1,239 @@
 /* -*- 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 CSSStyleRule for stylo */
-
-#include "mozilla/ServoStyleRule.h"
+#include "mozilla/dom/CSSStyleRule.h"
 
 #include "mozilla/DeclarationBlock.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/dom/CSSStyleRuleBinding.h"
 
 #include "mozAutoDocUpdate.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
+namespace dom {
 
-// -- ServoStyleRuleDeclaration ---------------------------------------
+// -- CSSStyleRuleDeclaration ---------------------------------------
 
-ServoStyleRuleDeclaration::ServoStyleRuleDeclaration(
+CSSStyleRuleDeclaration::CSSStyleRuleDeclaration(
   already_AddRefed<RawServoDeclarationBlock> aDecls)
   : mDecls(new DeclarationBlock(std::move(aDecls)))
 {
 }
 
-ServoStyleRuleDeclaration::~ServoStyleRuleDeclaration()
+CSSStyleRuleDeclaration::~CSSStyleRuleDeclaration()
 {
   mDecls->SetOwningRule(nullptr);
 }
 
-// QueryInterface implementation for ServoStyleRuleDeclaration
-NS_INTERFACE_MAP_BEGIN(ServoStyleRuleDeclaration)
+// QueryInterface implementation for CSSStyleRuleDeclaration
+NS_INTERFACE_MAP_BEGIN(CSSStyleRuleDeclaration)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   // We forward the cycle collection interfaces to Rule(), which is
   // never null (in fact, we're part of that object!)
   if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
       aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
     return Rule()->QueryInterface(aIID, aInstancePtr);
   }
   else
 NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
 
-NS_IMPL_ADDREF_USING_AGGREGATOR(ServoStyleRuleDeclaration, Rule())
-NS_IMPL_RELEASE_USING_AGGREGATOR(ServoStyleRuleDeclaration, Rule())
+NS_IMPL_ADDREF_USING_AGGREGATOR(CSSStyleRuleDeclaration, Rule())
+NS_IMPL_RELEASE_USING_AGGREGATOR(CSSStyleRuleDeclaration, Rule())
 
 /* nsDOMCSSDeclaration implementation */
 
 css::Rule*
-ServoStyleRuleDeclaration::GetParentRule()
+CSSStyleRuleDeclaration::GetParentRule()
 {
   return Rule();
 }
 
 nsINode*
-ServoStyleRuleDeclaration::GetParentObject()
+CSSStyleRuleDeclaration::GetParentObject()
 {
   return Rule()->GetParentObject();
 }
 
 DeclarationBlock*
-ServoStyleRuleDeclaration::GetCSSDeclaration(Operation aOperation)
+CSSStyleRuleDeclaration::GetCSSDeclaration(Operation aOperation)
 {
   return mDecls;
 }
 
 nsresult
-ServoStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
+CSSStyleRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
 {
-  ServoStyleRule* rule = Rule();
+  CSSStyleRule* rule = Rule();
   if (RefPtr<StyleSheet> sheet = rule->GetStyleSheet()) {
     if (aDecl != mDecls) {
       mDecls->SetOwningRule(nullptr);
       RefPtr<DeclarationBlock> decls = aDecl;
       Servo_StyleRule_SetStyle(rule->Raw(), decls->Raw());
       mDecls = decls.forget();
       mDecls->SetOwningRule(rule);
     }
     sheet->RuleChanged(rule);
   }
   return NS_OK;
 }
 
 nsIDocument*
-ServoStyleRuleDeclaration::DocToUpdate()
+CSSStyleRuleDeclaration::DocToUpdate()
 {
   return nullptr;
 }
 
 nsDOMCSSDeclaration::ParsingEnvironment
-ServoStyleRuleDeclaration::GetParsingEnvironment(
+CSSStyleRuleDeclaration::GetParsingEnvironment(
   nsIPrincipal* aSubjectPrincipal) const
 {
   return GetParsingEnvironmentForRule(Rule());
 }
 
-// -- ServoStyleRule --------------------------------------------------
+// -- CSSStyleRule --------------------------------------------------
 
-ServoStyleRule::ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule,
+CSSStyleRule::CSSStyleRule(already_AddRefed<RawServoStyleRule> aRawRule,
                                uint32_t aLine, uint32_t aColumn)
   : BindingStyleRule(aLine, aColumn)
   , mRawRule(aRawRule)
   , mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume())
 {
 }
 
-NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(ServoStyleRule, css::Rule)
+NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED_0(CSSStyleRule, css::Rule)
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoStyleRule)
+NS_IMPL_CYCLE_COLLECTION_CLASS(CSSStyleRule)
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CSSStyleRule, css::Rule)
   // Keep this in sync with IsCCLeaf.
 
   // Trace the wrapper for our declaration.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecls.TraceWrapper(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CSSStyleRule, css::Rule)
   // Keep this in sync with IsCCLeaf.
 
   // Unlink the wrapper for our declaraton.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CSSStyleRule, css::Rule)
   // Keep this in sync with IsCCLeaf.
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 bool
-ServoStyleRule::IsCCLeaf() const
+CSSStyleRule::IsCCLeaf() const
 {
   if (!Rule::IsCCLeaf()) {
     return false;
   }
 
   return !mDecls.PreservingWrapper();
 }
 
 size_t
-ServoStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+CSSStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mRawRule
   // - mDecls
 
   return n;
 }
 
 #ifdef DEBUG
 void
-ServoStyleRule::List(FILE* out, int32_t aIndent) const
+CSSStyleRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t i = 0; i < aIndent; i++) {
     str.AppendLiteral("  ");
   }
   Servo_StyleRule_Debug(mRawRule, &str);
   fprintf_stderr(out, "%s\n", str.get());
 }
 #endif
 
 /* CSSRule implementation */
 
 void
-ServoStyleRule::GetCssText(nsAString& aCssText) const
+CSSStyleRule::GetCssText(nsAString& aCssText) const
 {
   Servo_StyleRule_GetCssText(mRawRule, &aCssText);
 }
 
 nsICSSDeclaration*
-ServoStyleRule::Style()
+CSSStyleRule::Style()
 {
   return &mDecls;
 }
 
 /* CSSStyleRule implementation */
 
 void
-ServoStyleRule::GetSelectorText(nsAString& aSelectorText)
+CSSStyleRule::GetSelectorText(nsAString& aSelectorText)
 {
   Servo_StyleRule_GetSelectorText(mRawRule, &aSelectorText);
 }
 
 void
-ServoStyleRule::SetSelectorText(const nsAString& aSelectorText)
+CSSStyleRule::SetSelectorText(const nsAString& aSelectorText)
 {
   if (RefPtr<StyleSheet> sheet = GetStyleSheet()) {
     // StyleRule lives inside of the Inner, it is unsafe to call WillDirty
     // if sheet does not already have a unique Inner.
     sheet->AssertHasUniqueInner();
     sheet->WillDirty();
 
     const RawServoStyleSheetContents* contents = sheet->RawContents();
     if (Servo_StyleRule_SetSelectorText(contents, mRawRule, &aSelectorText)) {
       sheet->RuleChanged(this);
     }
   }
 }
 
 uint32_t
-ServoStyleRule::GetSelectorCount()
+CSSStyleRule::GetSelectorCount()
 {
   uint32_t aCount;
   Servo_StyleRule_GetSelectorCount(mRawRule, &aCount);
   return aCount;
 }
 
 nsresult
-ServoStyleRule::GetSelectorText(uint32_t aSelectorIndex, nsAString& aText)
+CSSStyleRule::GetSelectorText(uint32_t aSelectorIndex, nsAString& aText)
 {
   Servo_StyleRule_GetSelectorTextAtIndex(mRawRule, aSelectorIndex, &aText);
   return NS_OK;
 }
 
 nsresult
-ServoStyleRule::GetSpecificity(uint32_t aSelectorIndex, uint64_t* aSpecificity)
+CSSStyleRule::GetSpecificity(uint32_t aSelectorIndex, uint64_t* aSpecificity)
 {
   Servo_StyleRule_GetSpecificityAtIndex(mRawRule, aSelectorIndex, aSpecificity);
   return NS_OK;
 }
 
 nsresult
-ServoStyleRule::SelectorMatchesElement(Element* aElement,
+CSSStyleRule::SelectorMatchesElement(Element* aElement,
                                        uint32_t aSelectorIndex,
                                        const nsAString& aPseudo,
                                        bool* aMatches)
 {
   CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
   if (!aPseudo.IsEmpty()) {
     RefPtr<nsAtom> pseudoElt = NS_Atomize(aPseudo);
     pseudoType = nsCSSPseudoElements::GetPseudoType(
@@ -248,14 +247,15 @@ ServoStyleRule::SelectorMatchesElement(E
 
   *aMatches = Servo_StyleRule_SelectorMatchesElement(mRawRule, aElement,
                                                      aSelectorIndex, pseudoType);
 
   return NS_OK;
 }
 
 NotNull<DeclarationBlock*>
-ServoStyleRule::GetDeclarationBlock() const
+CSSStyleRule::GetDeclarationBlock() const
 {
   return WrapNotNull(mDecls.mDecls);
 }
 
+} // namespace dom
 } // namespace mozilla
rename from layout/style/ServoStyleRule.h
rename to layout/style/CSSStyleRule.h
--- a/layout/style/ServoStyleRule.h
+++ b/layout/style/CSSStyleRule.h
@@ -1,76 +1,73 @@
 /* -*- 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 CSSStyleRule for stylo */
-
-#ifndef mozilla_ServoStyleRule_h
-#define mozilla_ServoStyleRule_h
+#ifndef mozilla_CSSStyleRule_h
+#define mozilla_CSSStyleRule_h
 
 #include "mozilla/BindingStyleRule.h"
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/WeakPtr.h"
 
 #include "nsDOMCSSDeclaration.h"
 
 namespace mozilla {
 
+class DeclarationBlock;
+
 namespace dom {
 class DocGroup;
-} // namespace dom
+class CSSStyleRule;
 
-class DeclarationBlock;
-class ServoStyleRule;
-
-class ServoStyleRuleDeclaration final : public nsDOMCSSDeclaration
+class CSSStyleRuleDeclaration final : public nsDOMCSSDeclaration
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   css::Rule* GetParentRule() final;
   nsINode* GetParentObject() final;
 
 protected:
   DeclarationBlock* GetCSSDeclaration(Operation aOperation) final;
   nsresult SetCSSDeclaration(DeclarationBlock* aDecl) final;
   nsIDocument* DocToUpdate() final;
   ParsingEnvironment
   GetParsingEnvironment(nsIPrincipal* aSubjectPrincipal) const final;
 
 private:
   // For accessing the constructor.
-  friend class ServoStyleRule;
+  friend class CSSStyleRule;
 
-  explicit ServoStyleRuleDeclaration(
+  explicit CSSStyleRuleDeclaration(
     already_AddRefed<RawServoDeclarationBlock> aDecls);
-  ~ServoStyleRuleDeclaration();
+  ~CSSStyleRuleDeclaration();
 
-  inline ServoStyleRule* Rule();
-  inline const ServoStyleRule* Rule() const;
+  inline CSSStyleRule* Rule();
+  inline const CSSStyleRule* Rule() const;
 
   RefPtr<DeclarationBlock> mDecls;
 };
 
-class ServoStyleRule final : public BindingStyleRule
-                           , public SupportsWeakPtr<ServoStyleRule>
+class CSSStyleRule final : public BindingStyleRule
+                           , public SupportsWeakPtr<CSSStyleRule>
 {
 public:
-  ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule,
+  CSSStyleRule(already_AddRefed<RawServoStyleRule> aRawRule,
                  uint32_t aLine, uint32_t aColumn);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ServoStyleRule,
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CSSStyleRule,
                                                          css::Rule)
   bool IsCCLeaf() const final MOZ_MUST_OVERRIDE;
 
-  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(ServoStyleRule)
+  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(CSSStyleRule)
 
   uint32_t GetSelectorCount() override;
   nsresult GetSelectorText(uint32_t aSelectorIndex,
                            nsAString& aText) override;
   nsresult GetSpecificity(uint32_t aSelectorIndex,
                           uint64_t* aSpecificity) override;
   nsresult SelectorMatchesElement(dom::Element* aElement,
                                   uint32_t aSelectorIndex,
@@ -89,34 +86,35 @@ public:
 
   // Methods of mozilla::css::Rule
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
 #ifdef DEBUG
   void List(FILE* out = stdout, int32_t aIndent = 0) const final;
 #endif
 
 private:
-  ~ServoStyleRule() {}
+  ~CSSStyleRule() {}
 
   // For computing the offset of mDecls.
-  friend class ServoStyleRuleDeclaration;
+  friend class CSSStyleRuleDeclaration;
 
   RefPtr<RawServoStyleRule> mRawRule;
-  ServoStyleRuleDeclaration mDecls;
+  CSSStyleRuleDeclaration mDecls;
 };
 
-ServoStyleRule*
-ServoStyleRuleDeclaration::Rule()
+CSSStyleRule*
+CSSStyleRuleDeclaration::Rule()
 {
-  return reinterpret_cast<ServoStyleRule*>(
-    reinterpret_cast<uint8_t*>(this) - offsetof(ServoStyleRule, mDecls));
+  return reinterpret_cast<CSSStyleRule*>(
+    reinterpret_cast<uint8_t*>(this) - offsetof(CSSStyleRule, mDecls));
 }
 
-const ServoStyleRule*
-ServoStyleRuleDeclaration::Rule() const
+const CSSStyleRule*
+CSSStyleRuleDeclaration::Rule() const
 {
-  return reinterpret_cast<const ServoStyleRule*>(
-    reinterpret_cast<const uint8_t*>(this) - offsetof(ServoStyleRule, mDecls));
+  return reinterpret_cast<const CSSStyleRule*>(
+    reinterpret_cast<const uint8_t*>(this) - offsetof(CSSStyleRule, mDecls));
 }
 
+} // namespace dom
 } // namespace mozilla
 
-#endif // mozilla_ServoStyleRule_h
+#endif // mozilla_CSSStyleRule_h
--- a/layout/style/CSSSupportsRule.cpp
+++ b/layout/style/CSSSupportsRule.cpp
@@ -1,23 +1,79 @@
 /* -*- 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/CSSSupportsRule.h"
 
+#include "mozilla/css/GroupRule.h"
 #include "mozilla/dom/CSSSupportsRuleBinding.h"
+#include "mozilla/ServoBindings.h"
 
 using namespace mozilla::css;
 
 namespace mozilla {
 namespace dom {
 
+CSSSupportsRule::CSSSupportsRule(RefPtr<RawServoSupportsRule> aRawRule,
+                                 uint32_t aLine, uint32_t aColumn)
+  : css::ConditionRule(Servo_SupportsRule_GetRules(aRawRule).Consume(),
+                       aLine, aColumn)
+  , mRawRule(std::move(aRawRule))
+{
+}
+
+NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, ConditionRule)
+NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, ConditionRule)
+
+// QueryInterface implementation for SupportsRule
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CSSSupportsRule)
+NS_INTERFACE_MAP_END_INHERITING(ConditionRule)
+
+#ifdef DEBUG
+/* virtual */ void
+CSSSupportsRule::List(FILE* out, int32_t aIndent) const
+{
+  nsAutoCString str;
+  for (int32_t i = 0; i < aIndent; i++) {
+    str.AppendLiteral("  ");
+  }
+  Servo_SupportsRule_Debug(mRawRule, &str);
+  fprintf_stderr(out, "%s\n", str.get());
+}
+#endif
+
+void
+CSSSupportsRule::GetConditionText(nsAString& aConditionText)
+{
+  Servo_SupportsRule_GetConditionText(mRawRule, &aConditionText);
+}
+
+void
+CSSSupportsRule::SetConditionText(const nsAString& aConditionText,
+                                  ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+/* virtual */ void
+CSSSupportsRule::GetCssText(nsAString& aCssText) const
+{
+  Servo_SupportsRule_GetCssText(mRawRule, &aCssText);
+}
+
+/* virtual */ size_t
+CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
+{
+  // TODO Implement this!
+  return aMallocSizeOf(this);
+}
+
 /* virtual */ JSObject*
 CSSSupportsRule::WrapObject(JSContext* aCx,
                             JS::Handle<JSObject*> aGivenProto)
 {
   return CSSSupportsRuleBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
--- a/layout/style/CSSSupportsRule.h
+++ b/layout/style/CSSSupportsRule.h
@@ -3,30 +3,49 @@
 /* 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_CSSSupportsRule_h
 #define mozilla_dom_CSSSupportsRule_h
 
 #include "mozilla/css/GroupRule.h"
+#include "mozilla/ServoBindingTypes.h"
 
 namespace mozilla {
 namespace dom {
 
 class CSSSupportsRule : public css::ConditionRule
 {
-protected:
-  using ConditionRule::ConditionRule;
-  virtual ~CSSSupportsRule() {}
+public:
+  CSSSupportsRule(RefPtr<RawServoSupportsRule> aRawRule,
+                  uint32_t aLine, uint32_t aColumn);
+
+  NS_DECL_ISUPPORTS_INHERITED
 
-public:
+#ifdef DEBUG
+  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
+#endif
+
+  RawServoSupportsRule* Raw() const { return mRawRule; }
+
   // WebIDL interface
   uint16_t Type() const override { return CSSRuleBinding::SUPPORTS_RULE; }
+  void GetCssText(nsAString& aCssText) const final;
+  void GetConditionText(nsAString& aConditionText) final;
+  void SetConditionText(const nsAString& aConditionText,
+                        ErrorResult& aRv) final;
 
+  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
+    const override;
   JSObject* WrapObject(JSContext* aCx,
                        JS::Handle<JSObject*> aGivenProto) override;
+
+private:
+  ~CSSSupportsRule() = default;
+
+  RefPtr<RawServoSupportsRule> mRawRule;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_CSSSupportsRule_h
--- a/layout/style/FontFace.cpp
+++ b/layout/style/FontFace.cpp
@@ -2,25 +2,25 @@
 /* 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/FontFace.h"
 
 #include <algorithm>
+#include "mozilla/dom/CSSFontFaceRule.h"
 #include "mozilla/dom/FontFaceBinding.h"
 #include "mozilla/dom/FontFaceSet.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/dom/UnionTypes.h"
 #include "mozilla/CycleCollectedJSContext.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/ServoCSSParser.h"
-#include "mozilla/ServoFontFaceRule.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/ServoUtils.h"
 #include "mozilla/StaticPrefs.h"
 #include "nsIDocument.h"
 #include "nsStyleUtil.h"
 
 namespace mozilla {
 namespace dom {
--- a/layout/style/FontFace.h
+++ b/layout/style/FontFace.h
@@ -16,18 +16,18 @@
 #include "nsWrapperCache.h"
 
 class gfxFontFaceBufferSource;
 struct RawServoFontFaceRule;
 
 namespace mozilla {
 struct CSSFontFaceDescriptors;
 class PostTraversalTask;
-class ServoFontFaceRule;
 namespace dom {
+class CSSFontFaceRule;
 class FontFaceBufferSource;
 struct FontFaceDescriptors;
 class FontFaceSet;
 class Promise;
 class StringOrArrayBufferOrArrayBufferView;
 } // namespace dom
 } // namespace mozilla
 
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -5,29 +5,29 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "FontFaceSet.h"
 
 #include "gfxFontConstants.h"
 #include "gfxFontSrcPrincipal.h"
 #include "gfxFontSrcURI.h"
 #include "mozilla/css/Loader.h"
+#include "mozilla/dom/CSSFontFaceRule.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/FontFaceSetBinding.h"
 #include "mozilla/dom/FontFaceSetIterator.h"
 #include "mozilla/dom/FontFaceSetLoadEvent.h"
 #include "mozilla/dom/FontFaceSetLoadEventBinding.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/FontPropertyTypes.h"
 #include "mozilla/net/ReferrerPolicy.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ServoCSSParser.h"
-#include "mozilla/ServoFontFaceRule.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/ServoUtils.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/LoadInfo.h"
 #include "nsAutoPtr.h"
 #include "nsContentPolicyUtils.h"
--- a/layout/style/ServoArcTypeList.h
+++ b/layout/style/ServoArcTypeList.h
@@ -14,13 +14,13 @@ SERVO_ARC_TYPE(ImportRule, RawServoImpor
 SERVO_ARC_TYPE(AnimationValue, RawServoAnimationValue)
 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(DocumentRule, RawServoMozDocumentRule)
 SERVO_ARC_TYPE(FontFeatureValuesRule, RawServoFontFeatureValuesRule)
 SERVO_ARC_TYPE(RuleNode, RawServoRuleNode)
 SERVO_ARC_TYPE(FontFaceRule, RawServoFontFaceRule)
 SERVO_ARC_TYPE(CounterStyleRule, RawServoCounterStyleRule)
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -259,25 +259,26 @@ SERVO_BINDING_FUNC(Servo_CssRules_Delete
                      RawServo##type_##RuleStrong, \
                      ServoCssRulesBorrowed rules, uint32_t index, \
                      uint32_t* line, uint32_t* column) \
   BASIC_RULE_FUNCS_WITHOUT_GETTER(type_##Rule)
 #define GROUP_RULE_FUNCS(type_) \
   BASIC_RULE_FUNCS(type_) \
   SERVO_BINDING_FUNC(Servo_##type_##Rule_GetRules, ServoCssRulesStrong, \
                      RawServo##type_##RuleBorrowed rule)
+
 BASIC_RULE_FUNCS(Style)
 BASIC_RULE_FUNCS(Import)
 BASIC_RULE_FUNCS_WITHOUT_GETTER(Keyframe)
 BASIC_RULE_FUNCS(Keyframes)
 GROUP_RULE_FUNCS(Media)
+GROUP_RULE_FUNCS(MozDocument)
 BASIC_RULE_FUNCS(Namespace)
 BASIC_RULE_FUNCS(Page)
 GROUP_RULE_FUNCS(Supports)
-GROUP_RULE_FUNCS(Document)
 BASIC_RULE_FUNCS(FontFeatureValues)
 BASIC_RULE_FUNCS(FontFace)
 BASIC_RULE_FUNCS(CounterStyle)
 #undef GROUP_RULE_FUNCS
 #undef BASIC_RULE_FUNCS
 #undef BASIC_RULE_FUNCS_WITHOUT_GETTER
 SERVO_BINDING_FUNC(Servo_StyleRule_GetStyle, RawServoDeclarationBlockStrong,
                    RawServoStyleRuleBorrowed rule)
@@ -347,18 +348,18 @@ SERVO_BINDING_FUNC(Servo_NamespaceRule_G
                    RawServoNamespaceRuleBorrowed rule)
 SERVO_BINDING_FUNC(Servo_PageRule_GetStyle, RawServoDeclarationBlockStrong,
                    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_MozDocumentRule_GetConditionText, void,
+                   RawServoMozDocumentRuleBorrowed 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)
 SERVO_BINDING_FUNC(Servo_FontFaceRule_CreateEmpty, RawServoFontFaceRuleStrong)
 SERVO_BINDING_FUNC(Servo_FontFaceRule_Clone, RawServoFontFaceRuleStrong,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1644,20 +1644,21 @@ Gecko_CreateGradient(uint8_t aShape,
   result->mMozLegacySyntax = aMozLegacySyntax;
 
   result->mAngle.SetNoneValue();
   result->mBgPosX.SetNoneValue();
   result->mBgPosY.SetNoneValue();
   result->mRadiusX.SetNoneValue();
   result->mRadiusY.SetNoneValue();
 
-  nsStyleGradientStop dummyStop;
-  dummyStop.mLocation.SetNoneValue();
-  dummyStop.mColor = NS_RGB(0, 0, 0);
-  dummyStop.mIsInterpolationHint = 0;
+  nsStyleGradientStop dummyStop = {
+    nsStyleCoord(eStyleUnit_None),
+    StyleComplexColor::FromColor(NS_RGB(0, 0, 0)),
+    0
+  };
 
   for (uint32_t i = 0; i < aStopCount; i++) {
     result->mStops.AppendElement(dummyStop);
   }
 
   return result;
 }
 
--- a/layout/style/ServoCSSRuleList.cpp
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -3,29 +3,29 @@
 /* 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 CSSRuleList for stylo */
 
 #include "mozilla/ServoCSSRuleList.h"
 
+#include "mozilla/dom/CSSCounterStyleRule.h"
+#include "mozilla/dom/CSSFontFaceRule.h"
+#include "mozilla/dom/CSSFontFeatureValuesRule.h" 
+#include "mozilla/dom/CSSImportRule.h"
+#include "mozilla/dom/CSSKeyframesRule.h"
+#include "mozilla/dom/CSSMediaRule.h"
+#include "mozilla/dom/CSSMozDocumentRule.h"
+#include "mozilla/dom/CSSNamespaceRule.h"
+#include "mozilla/dom/CSSPageRule.h"
+#include "mozilla/dom/CSSStyleRule.h"
+#include "mozilla/dom/CSSSupportsRule.h"
 #include "mozilla/IntegerRange.h"
 #include "mozilla/ServoBindings.h"
-#include "mozilla/ServoCounterStyleRule.h"
-#include "mozilla/ServoDocumentRule.h"
-#include "mozilla/ServoImportRule.h"
-#include "mozilla/ServoFontFaceRule.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/ServoSupportsRule.h"
 #include "mozilla/StyleSheet.h"
 
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 ServoCSSRuleList::ServoCSSRuleList(already_AddRefed<ServoCssRules> aRawRules,
                                    StyleSheet* aDirectOwnerStyleSheet)
@@ -85,26 +85,26 @@ ServoCSSRuleList::GetRule(uint32_t aInde
 #define CASE_RULE(const_, name_)                                            \
       case CSSRuleBinding::const_##_RULE: {                                 \
         uint32_t line = 0, column = 0;                                      \
         RefPtr<RawServo##name_##Rule> rule =                                \
           Servo_CssRules_Get##name_##RuleAt(                                \
               mRawRules, aIndex, &line, &column                             \
           ).Consume();                                                      \
         MOZ_ASSERT(rule);                                                   \
-        ruleObj = new Servo##name_##Rule(rule.forget(), line, column);      \
+        ruleObj = new CSS##name_##Rule(rule.forget(), line, column);        \
         break;                                                              \
       }
       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(DOCUMENT, MozDocument)
       CASE_RULE(IMPORT, Import)
       CASE_RULE(FONT_FEATURE_VALUES, FontFeatureValues)
       CASE_RULE(FONT_FACE, FontFace)
       CASE_RULE(COUNTER_STYLE, CounterStyle)
 #undef CASE_RULE
       case CSSRuleBinding::KEYFRAME_RULE:
         MOZ_ASSERT_UNREACHABLE("keyframe rule cannot be here");
         return nullptr;
--- a/layout/style/ServoCSSRuleList.h
+++ b/layout/style/ServoCSSRuleList.h
@@ -10,17 +10,19 @@
 #define mozilla_ServoCSSRuleList_h
 
 #include "mozilla/ServoBindingTypes.h"
 #include "mozilla/dom/CSSRuleList.h"
 #include "nsDataHashtable.h"
 
 namespace mozilla {
 
-class ServoStyleRule;
+namespace dom {
+class CSSStyleRule;
+} // namespace dom
 class StyleSheet;
 namespace css {
 class GroupRule;
 class Rule;
 } // namespace css
 
 class ServoCSSRuleList final : public dom::CSSRuleList
 {
deleted file mode 100644
--- a/layout/style/ServoDocumentRule.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/* -*- 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 CSSMozDocumentRule for stylo */
-
-#include "mozilla/ServoBindings.h"
-#include "mozilla/ServoDocumentRule.h"
-
-using namespace mozilla::dom;
-
-namespace mozilla {
-
-ServoDocumentRule::ServoDocumentRule(RefPtr<RawServoDocumentRule> aRawRule,
-                                     uint32_t aLine, uint32_t aColumn)
-  : CSSMozDocumentRule(Servo_DocumentRule_GetRules(aRawRule).Consume(),
-                       aLine, aColumn)
-  , mRawRule(std::move(aRawRule))
-{
-}
-
-ServoDocumentRule::~ServoDocumentRule()
-{
-}
-
-NS_IMPL_ADDREF_INHERITED(ServoDocumentRule, CSSMozDocumentRule)
-NS_IMPL_RELEASE_INHERITED(ServoDocumentRule, CSSMozDocumentRule)
-
-// QueryInterface implementation for MozDocumentRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoDocumentRule)
-NS_INTERFACE_MAP_END_INHERITING(CSSMozDocumentRule)
-
-#ifdef DEBUG
-/* virtual */ void
-ServoDocumentRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_DocumentRule_Debug(mRawRule, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-void
-ServoDocumentRule::GetConditionText(nsAString& aConditionText)
-{
-  Servo_DocumentRule_GetConditionText(mRawRule, &aConditionText);
-}
-
-void
-ServoDocumentRule::SetConditionText(const nsAString& aConditionText,
-                                    ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
-/* virtual */ void
-ServoDocumentRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_DocumentRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* virtual */ size_t
-ServoDocumentRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-  const
-{
-  // TODO Implement this!
-  return aMallocSizeOf(this);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoDocumentRule.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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 CSSMozDocumentRule for stylo */
-
-#ifndef mozilla_ServoMozDocumentRule_h
-#define mozilla_ServoMozDocumentRule_h
-
-#include "mozilla/dom/CSSMozDocumentRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-namespace mozilla {
-
-class ServoDocumentRule final : public dom::CSSMozDocumentRule
-{
-public:
-  ServoDocumentRule(RefPtr<RawServoDocumentRule> aRawRule,
-                    uint32_t aLine, uint32_t aColumn);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-
-  RawServoDocumentRule* Raw() const { return mRawRule; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetConditionText(nsAString& aConditionText) final;
-  void SetConditionText(const nsAString& aConditionText,
-                        ErrorResult& aRv) final;
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override;
-
-private:
-  virtual ~ServoDocumentRule();
-
-  RefPtr<RawServoDocumentRule> mRawRule;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoDocumentRule_h
deleted file mode 100644
--- a/layout/style/ServoFontFeatureValuesRule.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- 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(std::move(aRawRule))
-{
-}
-
-ServoFontFeatureValuesRule::~ServoFontFeatureValuesRule()
-{
-}
-
-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::GetCssText(nsAString& aCssText) const
-{
-  Servo_FontFeatureValuesRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* CSSFontFeatureValuesRule implementation */
-
-void
-ServoFontFeatureValuesRule::GetFontFamily(nsAString& aFamilyListStr)
-{
-  Servo_FontFeatureValuesRule_GetFontFamily(mRawRule, &aFamilyListStr);
-}
-
-void
-ServoFontFeatureValuesRule::GetValueText(nsAString& aValueText)
-{
-  Servo_FontFeatureValuesRule_GetValueText(mRawRule, &aValueText);
-}
-
-void
-ServoFontFeatureValuesRule::SetFontFamily(const nsAString& aFontFamily,
-                                          ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
-void
-ServoFontFeatureValuesRule::SetValueText(const nsAString& aValueText,
-                                         ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoFontFeatureValuesRule.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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);
-
-  RawServoFontFeatureValuesRule* Raw() const { return mRawRule; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const override;
-  void GetFontFamily(nsAString& aFamily) final;
-  void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv) final;
-  void GetValueText(nsAString& aValueText) final;
-  void SetValueText(const nsAString& aValueText, mozilla::ErrorResult& aRv) final;
-
-  // Methods of mozilla::css::Rule
-  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
deleted file mode 100644
--- a/layout/style/ServoImportRule.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- 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 CSSImportRule for stylo */
-
-#include "mozilla/ServoImportRule.h"
-
-#include "mozilla/ServoBindings.h"
-#include "mozilla/StyleSheet.h"
-
-namespace mozilla {
-
-ServoImportRule::ServoImportRule(RefPtr<RawServoImportRule> aRawRule,
-                                 uint32_t aLine,
-                                 uint32_t aColumn)
-  : CSSImportRule(aLine, aColumn)
-  , mRawRule(std::move(aRawRule))
-{
-  const auto* sheet = Servo_ImportRule_GetSheet(mRawRule.get());
-  MOZ_ASSERT(sheet);
-  mChildSheet = const_cast<StyleSheet*>(sheet);
-  mChildSheet->SetOwnerRule(this);
-}
-
-ServoImportRule::~ServoImportRule()
-{
-  if (mChildSheet) {
-    mChildSheet->SetOwnerRule(nullptr);
-  }
-}
-
-// QueryInterface implementation for ServoImportRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoImportRule)
-NS_INTERFACE_MAP_END_INHERITING(dom::CSSImportRule)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoImportRule)
-
-NS_IMPL_ADDREF_INHERITED(ServoImportRule, dom::CSSImportRule)
-NS_IMPL_RELEASE_INHERITED(ServoImportRule, dom::CSSImportRule)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoImportRule,
-                                                  dom::CSSImportRule)
-  // Note the child sheet twice, since the Servo rule also holds a strong
-  // reference to it.
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildSheet");
-  cb.NoteXPCOMChild(tmp->mChildSheet);
-  MOZ_ASSERT_IF(tmp->mRawRule,
-                Servo_ImportRule_GetSheet(tmp->mRawRule) == tmp->mChildSheet);
-  cb.NoteXPCOMChild(tmp->mChildSheet);
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRawRule.stylesheet");
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ServoImportRule)
-  if (tmp->mChildSheet) {
-    tmp->mChildSheet->SetOwnerRule(nullptr);
-    tmp->mChildSheet = nullptr;
-  }
-  tmp->mRawRule = nullptr;
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSImportRule)
-
-#ifdef DEBUG
-/* virtual */ void
-ServoImportRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_ImportRule_Debug(mRawRule, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-dom::MediaList*
-ServoImportRule::GetMedia() const
-{
-  // When Bug 1326509 is fixed, we can assert mChildSheet instead.
-  return mChildSheet ? mChildSheet->Media() : nullptr;
-}
-
-StyleSheet*
-ServoImportRule::GetStyleSheet() const
-{
-  return mChildSheet;
-}
-
-void
-ServoImportRule::GetHref(nsAString& aHref) const
-{
-  Servo_ImportRule_GetHref(mRawRule, &aHref);
-}
-
-/* virtual */ void
-ServoImportRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_ImportRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* virtual */ size_t
-ServoImportRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
-{
-  // TODO Implement this!
-  return aMallocSizeOf(this);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoImportRule.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- 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 CSSImportRule for stylo */
-
-#ifndef mozilla_ServoImportRule_h
-#define mozilla_ServoImportRule_h
-
-#include "mozilla/dom/CSSImportRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-namespace mozilla {
-
-class ServoMediaList;
-class StyleSheet;
-
-class ServoImportRule final : public dom::CSSImportRule
-{
-public:
-  ServoImportRule(RefPtr<RawServoImportRule> aRawRule,
-                  uint32_t aLine, uint32_t aColumn);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoImportRule, dom::CSSImportRule)
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const override;
-  void GetHref(nsAString& aHref) const final;
-  dom::MediaList* GetMedia() const final;
-  StyleSheet* GetStyleSheet() const final;
-
-private:
-  ~ServoImportRule();
-
-  RefPtr<RawServoImportRule> mRawRule;
-  RefPtr<StyleSheet> mChildSheet;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoImportRule_h
deleted file mode 100644
--- a/layout/style/ServoKeyframeRule.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- 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/ServoKeyframeRule.h"
-
-#include "mozilla/DeclarationBlock.h"
-#include "nsDOMCSSDeclaration.h"
-#include "mozAutoDocUpdate.h"
-
-namespace mozilla {
-
-// -------------------------------------------
-// ServoKeyframeDeclaration
-//
-
-class ServoKeyframeDeclaration : public nsDOMCSSDeclaration
-{
-public:
-  explicit ServoKeyframeDeclaration(ServoKeyframeRule* aRule)
-    : mRule(aRule)
-  {
-    mDecls = new DeclarationBlock(
-      Servo_Keyframe_GetStyle(aRule->Raw()).Consume());
-  }
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
-    ServoKeyframeDeclaration, nsICSSDeclaration)
-
-  css::Rule* GetParentRule() final { return mRule; }
-
-  void DropReference() {
-    mRule = nullptr;
-    mDecls->SetOwningRule(nullptr);
-  }
-
-  DeclarationBlock* GetCSSDeclaration(Operation aOperation) final
-  {
-    return mDecls;
-  }
-  nsresult SetCSSDeclaration(DeclarationBlock* aDecls) final
-  {
-    if (!mRule) {
-      return NS_OK;
-    }
-    mRule->UpdateRule([this, aDecls]() {
-      if (mDecls != aDecls) {
-        mDecls->SetOwningRule(nullptr);
-        mDecls = aDecls;
-        mDecls->SetOwningRule(mRule);
-        Servo_Keyframe_SetStyle(mRule->Raw(), mDecls->Raw());
-      }
-    });
-    return NS_OK;
-  }
-  ParsingEnvironment GetParsingEnvironment(
-      nsIPrincipal* aSubjectPrincipal) const final
-  {
-    return GetParsingEnvironmentForRule(mRule);
-  }
-  nsIDocument* DocToUpdate() final { return nullptr; }
-
-  nsINode* GetParentObject() final
-  {
-    return mRule ? mRule->GetParentObject() : nullptr;
-  }
-
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
-  {
-    size_t n = aMallocSizeOf(this);
-    // TODO we may want to add size of mDecls as well
-    return n;
-  }
-
-private:
-  virtual ~ServoKeyframeDeclaration() {
-    MOZ_ASSERT(!mRule, "Backpointer should have been cleared");
-  }
-
-  ServoKeyframeRule* mRule;
-  RefPtr<DeclarationBlock> mDecls;
-};
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(ServoKeyframeDeclaration)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(ServoKeyframeDeclaration)
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(ServoKeyframeDeclaration)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframeDeclaration)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
-
-// -------------------------------------------
-// ServoKeyframeRule
-//
-
-ServoKeyframeRule::~ServoKeyframeRule()
-{
-  if (mDeclaration) {
-    mDeclaration->DropReference();
-  }
-}
-
-NS_IMPL_ADDREF_INHERITED(ServoKeyframeRule, dom::CSSKeyframeRule)
-NS_IMPL_RELEASE_INHERITED(ServoKeyframeRule, dom::CSSKeyframeRule)
-
-// QueryInterface implementation for nsCSSKeyframeRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframeRule)
-NS_INTERFACE_MAP_END_INHERITING(dom::CSSKeyframeRule)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframeRule)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoKeyframeRule,
-                                                dom::CSSKeyframeRule)
-  if (tmp->mDeclaration) {
-    tmp->mDeclaration->DropReference();
-    tmp->mDeclaration = nullptr;
-  }
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframeRule,
-                                                  dom::CSSKeyframeRule)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-bool
-ServoKeyframeRule::IsCCLeaf() const
-{
-  return Rule::IsCCLeaf() && !mDeclaration;
-}
-
-#ifdef DEBUG
-/* virtual */ void
-ServoKeyframeRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_Keyframe_Debug(mRaw, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-template<typename Func>
-void
-ServoKeyframeRule::UpdateRule(Func aCallback)
-{
-  aCallback();
-
-  if (StyleSheet* sheet = GetStyleSheet()) {
-    sheet->RuleChanged(this);
-  }
-}
-
-void
-ServoKeyframeRule::GetKeyText(nsAString& aKeyText)
-{
-  Servo_Keyframe_GetKeyText(mRaw, &aKeyText);
-}
-
-void
-ServoKeyframeRule::SetKeyText(const nsAString& aKeyText)
-{
-  NS_ConvertUTF16toUTF8 keyText(aKeyText);
-  UpdateRule([this, &keyText]() {
-    Servo_Keyframe_SetKeyText(mRaw, &keyText);
-  });
-}
-
-void
-ServoKeyframeRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_Keyframe_GetCssText(mRaw, &aCssText);
-}
-
-nsICSSDeclaration*
-ServoKeyframeRule::Style()
-{
-  if (!mDeclaration) {
-    mDeclaration = new ServoKeyframeDeclaration(this);
-  }
-  return mDeclaration;
-}
-
-size_t
-ServoKeyframeRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
-{
-  size_t n = aMallocSizeOf(this);
-  if (mDeclaration) {
-    n += mDeclaration->SizeOfIncludingThis(aMallocSizeOf);
-  }
-  return n;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoKeyframeRule.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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_ServoKeyframeRule_h
-#define mozilla_ServoKeyframeRule_h
-
-#include "mozilla/dom/CSSKeyframeRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-class nsICSSDeclaration;
-
-namespace mozilla {
-
-class DeclarationBlock;
-class ServoKeyframeDeclaration;
-
-class ServoKeyframeRule final : public dom::CSSKeyframeRule
-{
-public:
-  ServoKeyframeRule(already_AddRefed<RawServoKeyframe> aRaw,
-                    uint32_t aLine, uint32_t aColumn)
-    : CSSKeyframeRule(aLine, aColumn)
-    , mRaw(aRaw) {}
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframeRule,
-                                           dom::CSSKeyframeRule)
-
-  bool IsCCLeaf() const final;
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-
-  RawServoKeyframe* Raw() const { return mRaw; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetKeyText(nsAString& aKeyText) final;
-  void SetKeyText(const nsAString& aKeyText) final;
-  nsICSSDeclaration* Style() final;
-
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
-
-private:
-  virtual ~ServoKeyframeRule();
-
-  friend class ServoKeyframeDeclaration;
-
-  template<typename Func>
-  void UpdateRule(Func aCallback);
-
-  RefPtr<RawServoKeyframe> mRaw;
-  // lazily created when needed
-  RefPtr<ServoKeyframeDeclaration> mDeclaration;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoKeyframeRule_h
deleted file mode 100644
--- a/layout/style/ServoKeyframesRule.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/* -*- 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/ServoKeyframesRule.h"
-
-#include "mozAutoDocUpdate.h"
-#include "mozilla/ServoBindings.h"
-#include "mozilla/ServoKeyframeRule.h"
-
-#include <limits>
-
-namespace mozilla {
-
-// -------------------------------------------
-// ServoKeyframeList
-//
-
-class ServoKeyframeList : public dom::CSSRuleList
-{
-public:
-  explicit ServoKeyframeList(already_AddRefed<RawServoKeyframesRule> aRawRule)
-    : mRawRule(aRawRule)
-  {
-    mRules.SetCount(Servo_KeyframesRule_GetCount(mRawRule));
-  }
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframeList, dom::CSSRuleList)
-
-  void SetParentRule(ServoKeyframesRule* aParentRule)
-  {
-    mParentRule = aParentRule;
-    for (css::Rule* rule : mRules) {
-      if (rule) {
-        rule->SetParentRule(aParentRule);
-      }
-    }
-  }
-  void SetStyleSheet(StyleSheet* aSheet)
-  {
-    mStyleSheet = aSheet;
-    for (css::Rule* rule : mRules) {
-      if (rule) {
-        rule->SetStyleSheet(aSheet);
-      }
-    }
-  }
-
-  StyleSheet* GetParentObject() final { return mStyleSheet; }
-
-  ServoKeyframeRule* GetRule(uint32_t aIndex) {
-    if (!mRules[aIndex]) {
-      uint32_t line = 0, column = 0;
-      RefPtr<RawServoKeyframe> rule =
-        Servo_KeyframesRule_GetKeyframeAt(mRawRule, aIndex,
-                                          &line, &column).Consume();
-      ServoKeyframeRule* ruleObj =
-        new ServoKeyframeRule(rule.forget(), line, column);
-      mRules.ReplaceObjectAt(ruleObj, aIndex);
-      ruleObj->SetStyleSheet(mStyleSheet);
-      ruleObj->SetParentRule(mParentRule);
-    }
-    return static_cast<ServoKeyframeRule*>(mRules[aIndex]);
-  }
-
-  ServoKeyframeRule* IndexedGetter(uint32_t aIndex, bool& aFound) final
-  {
-    if (aIndex >= mRules.Length()) {
-      aFound = false;
-      return nullptr;
-    }
-    aFound = true;
-    return GetRule(aIndex);
-  }
-
-  void AppendRule() {
-    mRules.AppendObject(nullptr);
-  }
-
-  void RemoveRule(uint32_t aIndex) {
-    mRules.RemoveObjectAt(aIndex);
-  }
-
-  uint32_t Length() final { return mRules.Length(); }
-
-  void DropReference()
-  {
-    mStyleSheet = nullptr;
-    mParentRule = nullptr;
-    for (css::Rule* rule : mRules) {
-      if (rule) {
-        rule->SetStyleSheet(nullptr);
-        rule->SetParentRule(nullptr);
-      }
-    }
-  }
-
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
-  {
-    size_t n = aMallocSizeOf(this);
-    for (const css::Rule* rule : mRules) {
-      n += rule ? rule->SizeOfIncludingThis(aMallocSizeOf) : 0;
-    }
-    return n;
-  }
-
-private:
-  virtual ~ServoKeyframeList() {
-    MOZ_ASSERT(!mParentRule, "Backpointer should have been cleared");
-    MOZ_ASSERT(!mStyleSheet, "Backpointer should have been cleared");
-    DropAllRules();
-  }
-
-  void DropAllRules()
-  {
-    if (mParentRule || mStyleSheet) {
-      DropReference();
-    }
-    mRules.Clear();
-    mRawRule = nullptr;
-  }
-
-  // may be nullptr when the style sheet drops the reference to us.
-  StyleSheet* mStyleSheet = nullptr;
-  ServoKeyframesRule* mParentRule = nullptr;
-  RefPtr<RawServoKeyframesRule> mRawRule;
-  nsCOMArray<css::Rule> mRules;
-};
-
-// QueryInterface implementation for ServoKeyframeList
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframeList)
-NS_INTERFACE_MAP_END_INHERITING(dom::CSSRuleList)
-
-NS_IMPL_ADDREF_INHERITED(ServoKeyframeList, dom::CSSRuleList)
-NS_IMPL_RELEASE_INHERITED(ServoKeyframeList, dom::CSSRuleList)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframeList)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ServoKeyframeList)
-  tmp->DropAllRules();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframeList,
-                                                  dom::CSSRuleList)
-  for (css::Rule* rule : tmp->mRules) {
-    if (rule) {
-      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
-      cb.NoteXPCOMChild(rule);
-    }
-  }
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-// -------------------------------------------
-// ServoKeyframesRule
-//
-
-ServoKeyframesRule::ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
-                                       uint32_t aLine, uint32_t aColumn)
-  : dom::CSSKeyframesRule(aLine, aColumn)
-  , mRawRule(std::move(aRawRule))
-{
-}
-
-ServoKeyframesRule::~ServoKeyframesRule()
-{
-  if (mKeyframeList) {
-    mKeyframeList->DropReference();
-  }
-}
-
-NS_IMPL_ADDREF_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
-NS_IMPL_RELEASE_INHERITED(ServoKeyframesRule, dom::CSSKeyframesRule)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoKeyframesRule)
-NS_INTERFACE_MAP_END_INHERITING(dom::CSSKeyframesRule)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoKeyframesRule)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoKeyframesRule,
-                                                dom::CSSKeyframesRule)
-  if (tmp->mKeyframeList) {
-    tmp->mKeyframeList->DropReference();
-    tmp->mKeyframeList = nullptr;
-  }
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoKeyframesRule, Rule)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mKeyframeList)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-/* virtual */ bool
-ServoKeyframesRule::IsCCLeaf() const
-{
-  // If we don't have rule list constructed, we are a leaf.
-  return Rule::IsCCLeaf() && !mKeyframeList;
-}
-
-#ifdef DEBUG
-/* virtual */ void
-ServoKeyframesRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_KeyframesRule_Debug(mRawRule, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-/* virtual */ void
-ServoKeyframesRule::SetStyleSheet(StyleSheet* aSheet)
-{
-  if (mKeyframeList) {
-    mKeyframeList->SetStyleSheet(aSheet);
-  }
-  dom::CSSKeyframesRule::SetStyleSheet(aSheet);
-}
-
-static const uint32_t kRuleNotFound = std::numeric_limits<uint32_t>::max();
-
-uint32_t
-ServoKeyframesRule::FindRuleIndexForKey(const nsAString& aKey)
-{
-  NS_ConvertUTF16toUTF8 key(aKey);
-  return Servo_KeyframesRule_FindRule(mRawRule, &key);
-}
-
-template<typename Func>
-void
-ServoKeyframesRule::UpdateRule(Func aCallback)
-{
-  aCallback();
-  if (StyleSheet* sheet = GetStyleSheet()) {
-    sheet->RuleChanged(this);
-  }
-}
-
-void
-ServoKeyframesRule::GetName(nsAString& aName) const
-{
-  nsAtom* name = Servo_KeyframesRule_GetName(mRawRule);
-  aName = nsDependentAtomString(name);
-}
-
-void
-ServoKeyframesRule::SetName(const nsAString& aName)
-{
-  RefPtr<nsAtom> name = NS_Atomize(aName);
-  nsAtom* oldName = Servo_KeyframesRule_GetName(mRawRule);
-  if (name == oldName) {
-    return;
-  }
-
-  UpdateRule([this, &name]() {
-    Servo_KeyframesRule_SetName(mRawRule, name.forget().take());
-  });
-}
-
-void
-ServoKeyframesRule::AppendRule(const nsAString& aRule)
-{
-  StyleSheet* sheet = GetStyleSheet();
-  if (!sheet) {
-    // We cannot parse the rule if we don't have a stylesheet.
-    return;
-  }
-
-  NS_ConvertUTF16toUTF8 rule(aRule);
-  UpdateRule([this, sheet, &rule]() {
-    bool parsedOk = Servo_KeyframesRule_AppendRule(
-      mRawRule, sheet->RawContents(), &rule);
-    if (parsedOk && mKeyframeList) {
-      mKeyframeList->AppendRule();
-    }
-  });
-}
-
-void
-ServoKeyframesRule::DeleteRule(const nsAString& aKey)
-{
-  auto index = FindRuleIndexForKey(aKey);
-  if (index == kRuleNotFound) {
-    return;
-  }
-
-  UpdateRule([this, index]() {
-    Servo_KeyframesRule_DeleteRule(mRawRule, index);
-    if (mKeyframeList) {
-      mKeyframeList->RemoveRule(index);
-    }
-  });
-}
-
-/* virtual */ void
-ServoKeyframesRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_KeyframesRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* virtual */ dom::CSSRuleList*
-ServoKeyframesRule::CssRules()
-{
-  if (!mKeyframeList) {
-    mKeyframeList = new ServoKeyframeList(do_AddRef(mRawRule));
-    mKeyframeList->SetParentRule(this);
-    if (StyleSheet* sheet = GetStyleSheet()) {
-      mKeyframeList->SetStyleSheet(sheet);
-    }
-  }
-  return mKeyframeList;
-}
-
-/* virtual */ dom::CSSKeyframeRule*
-ServoKeyframesRule::FindRule(const nsAString& aKey)
-{
-  auto index = FindRuleIndexForKey(aKey);
-  if (index != kRuleNotFound) {
-    // Construct mKeyframeList but ignore the result.
-    CssRules();
-    return mKeyframeList->GetRule(index);
-  }
-  return nullptr;
-}
-
-/* virtual */ size_t
-ServoKeyframesRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
-{
-  size_t n = aMallocSizeOf(this);
-  if (mKeyframeList) {
-    n += mKeyframeList->SizeOfIncludingThis(aMallocSizeOf);
-  }
-  return n;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoKeyframesRule.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- 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_ServoKeyframesRule_h
-#define mozilla_ServoKeyframesRule_h
-
-#include "mozilla/dom/CSSKeyframesRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-namespace mozilla {
-
-class ServoKeyframeList;
-
-class ServoKeyframesRule final : public dom::CSSKeyframesRule
-{
-public:
-  ServoKeyframesRule(RefPtr<RawServoKeyframesRule> aRawRule,
-                     uint32_t aLine, uint32_t aColumn);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoKeyframesRule,
-                                           dom::CSSKeyframesRule)
-  bool IsCCLeaf() const final;
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-  void SetStyleSheet(StyleSheet* aSheet) final;
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetName(nsAString& aName) const final;
-  void SetName(const nsAString& aName) final;
-  dom::CSSRuleList* CssRules() final;
-  void AppendRule(const nsAString& aRule) final;
-  void DeleteRule(const nsAString& aKey) final;
-  dom::CSSKeyframeRule* FindRule(const nsAString& aKey) final;
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const final;
-
-private:
-  uint32_t FindRuleIndexForKey(const nsAString& aKey);
-
-  template<typename Func>
-  void UpdateRule(Func aCallback);
-
-  virtual ~ServoKeyframesRule();
-
-  RefPtr<RawServoKeyframesRule> mRawRule;
-  RefPtr<ServoKeyframeList> mKeyframeList; // lazily constructed
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoKeyframesRule_h
deleted file mode 100644
--- a/layout/style/ServoMediaRule.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/* -*- 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 CSSMediaRule for stylo */
-
-#include "mozilla/ServoMediaRule.h"
-
-#include "mozilla/ServoBindings.h"
-#include "mozilla/dom/MediaList.h"
-
-using namespace mozilla::dom;
-
-namespace mozilla {
-
-ServoMediaRule::ServoMediaRule(RefPtr<RawServoMediaRule> aRawRule,
-                               uint32_t aLine, uint32_t aColumn)
-  : CSSMediaRule(Servo_MediaRule_GetRules(aRawRule).Consume(), aLine, aColumn)
-  , mRawRule(std::move(aRawRule))
-{
-}
-
-ServoMediaRule::~ServoMediaRule()
-{
-  if (mMediaList) {
-    mMediaList->SetStyleSheet(nullptr);
-  }
-}
-
-NS_IMPL_ADDREF_INHERITED(ServoMediaRule, CSSMediaRule)
-NS_IMPL_RELEASE_INHERITED(ServoMediaRule, CSSMediaRule)
-
-// QueryInterface implementation for MediaRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoMediaRule)
-NS_INTERFACE_MAP_END_INHERITING(CSSMediaRule)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoMediaRule)
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoMediaRule, CSSMediaRule)
-  if (tmp->mMediaList) {
-    tmp->mMediaList->SetStyleSheet(nullptr);
-    tmp->mMediaList = nullptr;
-  }
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoMediaRule, CSSMediaRule)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaList)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-/* virtual */ void
-ServoMediaRule::SetStyleSheet(StyleSheet* aSheet)
-{
-  if (mMediaList) {
-    mMediaList->SetStyleSheet(aSheet);
-  }
-  CSSMediaRule::SetStyleSheet(aSheet);
-}
-
-#ifdef DEBUG
-/* virtual */ void
-ServoMediaRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_MediaRule_Debug(mRawRule, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-void
-ServoMediaRule::GetConditionText(nsAString& aConditionText)
-{
-  Media()->GetMediaText(aConditionText);
-}
-
-void
-ServoMediaRule::SetConditionText(const nsAString& aConditionText,
-                                 ErrorResult& aRv)
-{
-  Media()->SetMediaText(aConditionText);
-}
-
-/* virtual */ void
-ServoMediaRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_MediaRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* virtual */ dom::MediaList*
-ServoMediaRule::Media()
-{
-  if (!mMediaList) {
-    mMediaList = new MediaList(Servo_MediaRule_GetMedia(mRawRule).Consume());
-    mMediaList->SetStyleSheet(GetStyleSheet());
-  }
-  return mMediaList;
-}
-
-/* virtual */ size_t
-ServoMediaRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
-{
-  // TODO Implement this!
-  return aMallocSizeOf(this);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoMediaRule.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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 CSSMediaRule for stylo */
-
-#ifndef mozilla_ServoMediaRule_h
-#define mozilla_ServoMediaRule_h
-
-#include "mozilla/dom/CSSMediaRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-namespace mozilla {
-
-class ServoMediaRule final : public dom::CSSMediaRule
-{
-public:
-  ServoMediaRule(RefPtr<RawServoMediaRule> aRawRule,
-                 uint32_t aLine, uint32_t aColumn);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoMediaRule, dom::CSSMediaRule)
-
-  void SetStyleSheet(StyleSheet* aSheet) override;
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-
-  RawServoMediaRule* Raw() const { return mRawRule; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetConditionText(nsAString& aConditionText) final;
-  void SetConditionText(const nsAString& aConditionText,
-                        ErrorResult& aRv) final;
-  dom::MediaList* Media() final;
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override;
-
-private:
-  virtual ~ServoMediaRule();
-
-  RefPtr<RawServoMediaRule> mRawRule;
-  RefPtr<dom::MediaList> mMediaList;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoMediaRule_h
deleted file mode 100644
--- a/layout/style/ServoNamespaceRule.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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_ServoNamespaceRule_h
-#define mozilla_ServoNamespaceRule_h
-
-#include "mozilla/ServoBindingTypes.h"
-#include "mozilla/dom/CSSNamespaceRule.h"
-
-namespace mozilla {
-
-class ServoNamespaceRule : public dom::CSSNamespaceRule
-{
-public:
-  ServoNamespaceRule(already_AddRefed<RawServoNamespaceRule> aRule,
-                     uint32_t aLine, uint32_t aColumn)
-    : CSSNamespaceRule(aLine, aColumn)
-    , mRawRule(std::move(aRule))
-  {
-  }
-
-  NS_INLINE_DECL_REFCOUNTING_INHERITED(ServoNamespaceRule,
-                                       dom::CSSNamespaceRule)
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-
-  nsAtom* GetPrefix() const final;
-  void GetURLSpec(nsString& aURLSpec) const final;
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-
-  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
-
-private:
-  ~ServoNamespaceRule();
-
-  RefPtr<RawServoNamespaceRule> mRawRule;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoNamespaceRule_h
deleted file mode 100644
--- a/layout/style/ServoPageRule.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/* -*- 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 CSSPageRule for stylo */
-
-#include "mozilla/ServoPageRule.h"
-
-#include "mozilla/DeclarationBlock.h"
-#include "mozilla/ServoBindings.h"
-
-using namespace mozilla::dom;
-
-namespace mozilla {
-
-// -- ServoPageRuleDeclaration ---------------------------------------
-
-ServoPageRuleDeclaration::ServoPageRuleDeclaration(
-  already_AddRefed<RawServoDeclarationBlock> aDecls)
-  : mDecls(new DeclarationBlock(std::move(aDecls)))
-{
-}
-
-ServoPageRuleDeclaration::~ServoPageRuleDeclaration()
-{
-  mDecls->SetOwningRule(nullptr);
-}
-
-// QueryInterface implementation for ServoPageRuleDeclaration
-NS_INTERFACE_MAP_BEGIN(ServoPageRuleDeclaration)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  // We forward the cycle collection interfaces to Rule(), which is
-  // never null (in fact, we're part of that object!)
-  if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
-      aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
-    return Rule()->QueryInterface(aIID, aInstancePtr);
-  }
-  else
-NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
-
-NS_IMPL_ADDREF_USING_AGGREGATOR(ServoPageRuleDeclaration, Rule())
-NS_IMPL_RELEASE_USING_AGGREGATOR(ServoPageRuleDeclaration, Rule())
-
-/* nsDOMCSSDeclaration implementation */
-
-css::Rule*
-ServoPageRuleDeclaration::GetParentRule()
-{
-  return Rule();
-}
-
-nsINode*
-ServoPageRuleDeclaration::GetParentObject()
-{
-  return Rule()->GetParentObject();
-}
-
-DeclarationBlock*
-ServoPageRuleDeclaration::GetCSSDeclaration(Operation aOperation)
-{
-  return mDecls;
-}
-
-nsresult
-ServoPageRuleDeclaration::SetCSSDeclaration(DeclarationBlock* aDecl)
-{
-  MOZ_ASSERT(aDecl, "must be non-null");
-  ServoPageRule* rule = Rule();
-
-  if (aDecl != mDecls) {
-    mDecls->SetOwningRule(nullptr);
-    RefPtr<DeclarationBlock> decls = aDecl;
-    Servo_PageRule_SetStyle(rule->Raw(), decls->Raw());
-    mDecls = decls.forget();
-    mDecls->SetOwningRule(rule);
-  }
-
-  return NS_OK;
-}
-
-nsIDocument*
-ServoPageRuleDeclaration::DocToUpdate()
-{
-  return nullptr;
-}
-
-nsDOMCSSDeclaration::ParsingEnvironment
-ServoPageRuleDeclaration::GetParsingEnvironment(
-  nsIPrincipal* aSubjectPrincipal) const
-{
-  return GetParsingEnvironmentForRule(Rule());
-}
-
-// -- ServoPageRule --------------------------------------------------
-
-ServoPageRule::ServoPageRule(RefPtr<RawServoPageRule> aRawRule,
-                             uint32_t aLine, uint32_t aColumn)
-  : CSSPageRule(aLine, aColumn)
-  , mRawRule(std::move(aRawRule))
-  , mDecls(Servo_PageRule_GetStyle(mRawRule).Consume())
-{
-}
-
-ServoPageRule::~ServoPageRule()
-{
-}
-
-NS_IMPL_ADDREF_INHERITED(ServoPageRule, CSSPageRule)
-NS_IMPL_RELEASE_INHERITED(ServoPageRule, CSSPageRule)
-
-// QueryInterface implementation for PageRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoPageRule)
-NS_INTERFACE_MAP_END_INHERITING(CSSPageRule)
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(ServoPageRule)
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
-  // Keep this in sync with IsCCLeaf.
-
-  // Trace the wrapper for our declaration.  This just expands out
-  // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
-  // directly because the wrapper is on the declaration, not on us.
-  tmp->mDecls.TraceWrapper(aCallbacks, aClosure);
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
-  // Keep this in sync with IsCCLeaf.
-
-  // Unlink the wrapper for our declaraton.  This just expands out
-  // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
-  // directly because the wrapper is on the declaration, not on us.
-  tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
-  tmp->mDecls.mDecls->SetOwningRule(nullptr);
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoPageRule, CSSPageRule)
-  // Keep this in sync with IsCCLeaf.
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-bool
-ServoPageRule::IsCCLeaf() const
-{
-  if (!Rule::IsCCLeaf()) {
-    return false;
-  }
-
-  return !mDecls.PreservingWrapper();
-}
-
-size_t
-ServoPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
-{
-  // TODO Implement this!
-  return aMallocSizeOf(this);
-}
-
-#ifdef DEBUG
-void
-ServoPageRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_PageRule_Debug(mRawRule, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-/* CSSRule implementation */
-
-void
-ServoPageRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_PageRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* CSSPageRule implementation */
-
-nsICSSDeclaration*
-ServoPageRule::Style()
-{
-  return &mDecls;
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoPageRule.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/* -*- 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 CSSPageRule for stylo */
-
-#ifndef mozilla_ServoPageRule_h
-#define mozilla_ServoPageRule_h
-
-#include "mozilla/dom/CSSPageRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-#include "nsDOMCSSDeclaration.h"
-
-namespace mozilla {
-
-namespace dom {
-class DocGroup;
-} // namespace dom
-
-class DeclarationBlock;
-class ServoPageRule;
-
-class ServoPageRuleDeclaration final : public nsDOMCSSDeclaration
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  css::Rule* GetParentRule() final;
-  nsINode* GetParentObject() final;
-
-protected:
-  DeclarationBlock* GetCSSDeclaration(Operation aOperation) final;
-  nsresult SetCSSDeclaration(DeclarationBlock* aDecl) final;
-  nsIDocument* DocToUpdate() final;
-  nsDOMCSSDeclaration::ParsingEnvironment
-  GetParsingEnvironment(nsIPrincipal* aSubjectPrincipal) const final;
-
-private:
-  // For accessing the constructor.
-  friend class ServoPageRule;
-
-  explicit ServoPageRuleDeclaration(
-    already_AddRefed<RawServoDeclarationBlock> aDecls);
-  ~ServoPageRuleDeclaration();
-
-  inline ServoPageRule* Rule();
-  inline const ServoPageRule* Rule() const;
-
-  RefPtr<DeclarationBlock> mDecls;
-};
-
-class ServoPageRule final : public dom::CSSPageRule
-{
-public:
-  ServoPageRule(RefPtr<RawServoPageRule> aRawRule,
-                uint32_t aLine, uint32_t aColumn);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
-    ServoPageRule, dom::CSSPageRule
-  )
-  bool IsCCLeaf() const final;
-
-  RawServoPageRule* Raw() const { return mRawRule; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  nsICSSDeclaration* Style() final;
-
-  // Methods of mozilla::css::Rule
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const final;
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-
-private:
-  virtual ~ServoPageRule();
-
-  // For computing the offset of mDecls.
-  friend class ServoPageRuleDeclaration;
-
-  RefPtr<RawServoPageRule> mRawRule;
-  ServoPageRuleDeclaration mDecls;
-};
-
-ServoPageRule*
-ServoPageRuleDeclaration::Rule()
-{
-  return reinterpret_cast<ServoPageRule*>(
-    reinterpret_cast<uint8_t*>(this) - offsetof(ServoPageRule, mDecls));
-}
-
-const ServoPageRule*
-ServoPageRuleDeclaration::Rule() const
-{
-  return reinterpret_cast<const ServoPageRule*>(
-    reinterpret_cast<const uint8_t*>(this) - offsetof(ServoPageRule, mDecls));
-}
-
-} // namespace mozilla
-
-#endif // mozilla_ServoPageRule_h
deleted file mode 100644
--- a/layout/style/ServoSupportsRule.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- 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 CSSSupportsRule for stylo */
-
-#include "mozilla/ServoSupportsRule.h"
-
-#include "mozilla/ServoBindings.h"
-
-using namespace mozilla::dom;
-
-namespace mozilla {
-
-ServoSupportsRule::ServoSupportsRule(RefPtr<RawServoSupportsRule> aRawRule,
-                                     uint32_t aLine, uint32_t aColumn)
-  : CSSSupportsRule(Servo_SupportsRule_GetRules(aRawRule).Consume(),
-                    aLine, aColumn)
-  , mRawRule(std::move(aRawRule))
-{
-}
-
-ServoSupportsRule::~ServoSupportsRule()
-{
-}
-
-NS_IMPL_ADDREF_INHERITED(ServoSupportsRule, CSSSupportsRule)
-NS_IMPL_RELEASE_INHERITED(ServoSupportsRule, CSSSupportsRule)
-
-// QueryInterface implementation for SupportsRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoSupportsRule)
-NS_INTERFACE_MAP_END_INHERITING(CSSSupportsRule)
-
-#ifdef DEBUG
-/* virtual */ void
-ServoSupportsRule::List(FILE* out, int32_t aIndent) const
-{
-  nsAutoCString str;
-  for (int32_t i = 0; i < aIndent; i++) {
-    str.AppendLiteral("  ");
-  }
-  Servo_SupportsRule_Debug(mRawRule, &str);
-  fprintf_stderr(out, "%s\n", str.get());
-}
-#endif
-
-void
-ServoSupportsRule::GetConditionText(nsAString& aConditionText)
-{
-  Servo_SupportsRule_GetConditionText(mRawRule, &aConditionText);
-}
-
-void
-ServoSupportsRule::SetConditionText(const nsAString& aConditionText,
-                                    ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
-/* virtual */ void
-ServoSupportsRule::GetCssText(nsAString& aCssText) const
-{
-  Servo_SupportsRule_GetCssText(mRawRule, &aCssText);
-}
-
-/* virtual */ size_t
-ServoSupportsRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-  const
-{
-  // TODO Implement this!
-  return aMallocSizeOf(this);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/ServoSupportsRule.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- 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 CSSSupportsRule for stylo */
-
-#ifndef mozilla_ServoSupportsRule_h
-#define mozilla_ServoSupportsRule_h
-
-#include "mozilla/dom/CSSSupportsRule.h"
-#include "mozilla/ServoBindingTypes.h"
-
-namespace mozilla {
-
-class ServoSupportsRule final : public dom::CSSSupportsRule
-{
-public:
-  ServoSupportsRule(RefPtr<RawServoSupportsRule> aRawRule,
-                    uint32_t aLine, uint32_t aColumn);
-
-  NS_DECL_ISUPPORTS_INHERITED
-
-#ifdef DEBUG
-  void List(FILE* out = stdout, int32_t aIndent = 0) const final;
-#endif
-
-  RawServoSupportsRule* Raw() const { return mRawRule; }
-
-  // WebIDL interface
-  void GetCssText(nsAString& aCssText) const final;
-  void GetConditionText(nsAString& aConditionText) final;
-  void SetConditionText(const nsAString& aConditionText,
-                        ErrorResult& aRv) final;
-
-  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override;
-
-private:
-  virtual ~ServoSupportsRule();
-
-  RefPtr<RawServoSupportsRule> mRawRule;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoSupportsRule_h
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -10,26 +10,29 @@
 #include "mozilla/css/ErrorReporter.h"
 #include "mozilla/css/GroupRule.h"
 #include "mozilla/dom/CSSImportRule.h"
 #include "mozilla/dom/CSSRuleList.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/MediaList.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/ShadowRootBinding.h"
+#include "mozilla/ServoBindings.h"
 #include "mozilla/ServoCSSRuleList.h"
 #include "mozilla/ServoStyleSet.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/StyleSheetInlines.h"
 
 #include "mozAutoDocUpdate.h"
 #include "NullPrincipal.h"
 
 namespace mozilla {
 
+using namespace dom;
+
 StyleSheet::StyleSheet(css::SheetParsingMode aParsingMode,
                        CORSMode aCORSMode,
                        net::ReferrerPolicy aReferrerPolicy,
                        const dom::SRIMetadata& aIntegrity)
   : mParent(nullptr)
   , mDocumentOrShadowRoot(nullptr)
   , mOwningNode(nullptr)
   , mOwnerRule(nullptr)
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -77,59 +77,50 @@ EXPORTS.mozilla += [
     'PostTraversalTask.h',
     'PreloadedStyleSheet.h',
     'ServoArcTypeList.h',
     'ServoBindingList.h',
     'ServoBindings.h',
     'ServoBindingTypes.h',
     'ServoComputedData.h',
     'ServoComputedDataInlines.h',
-    'ServoCounterStyleRule.h',
     'ServoCSSParser.h',
     'ServoCSSRuleList.h',
-    'ServoDocumentRule.h',
     'ServoElementSnapshot.h',
     'ServoElementSnapshotTable.h',
-    'ServoFontFaceRule.h',
-    'ServoFontFeatureValuesRule.h',
-    'ServoImportRule.h',
-    'ServoKeyframeRule.h',
-    'ServoKeyframesRule.h',
-    'ServoMediaRule.h',
-    'ServoNamespaceRule.h',
-    'ServoPageRule.h',
     'ServoSpecifiedValues.h',
-    'ServoStyleRule.h',
     'ServoStyleSet.h',
     'ServoStyleSetInlines.h',
-    'ServoSupportsRule.h',
     'ServoTraversalStatistics.h',
     'ServoTypes.h',
     'ServoUtils.h',
     'SheetType.h',
     'StyleAnimationValue.h',
     'StyleComplexColor.h',
     'StyleSheet.h',
     'StyleSheetInfo.h',
     'StyleSheetInlines.h',
     'URLExtraData.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'CSS.h',
+    'CSSCounterStyleRule.h',
+    'CSSFontFaceRule.h',
     'CSSFontFeatureValuesRule.h',
     'CSSImportRule.h',
     'CSSKeyframeRule.h',
     'CSSKeyframesRule.h',
     'CSSLexer.h',
     'CSSMediaRule.h',
     'CSSMozDocumentRule.h',
     'CSSNamespaceRule.h',
     'CSSPageRule.h',
     'CSSRuleList.h',
+    'CSSStyleRule.h',
     'CSSSupportsRule.h',
     'CSSValue.h',
     'FontFace.h',
     'FontFaceSet.h',
     'FontFaceSetIterator.h',
     'MediaList.h',
     'MediaQueryList.h',
 ]
@@ -148,25 +139,29 @@ EXPORTS.mozilla.css += [
 
 UNIFIED_SOURCES += [
     'AnimationCollection.cpp',
     'BindingStyleRule.cpp',
     'CachedInheritingStyles.cpp',
     'ComputedStyle.cpp',
     'CounterStyleManager.cpp',
     'CSS.cpp',
+    'CSSCounterStyleRule.cpp',
+    'CSSFontFaceRule.cpp',
     'CSSFontFeatureValuesRule.cpp',
     'CSSImportRule.cpp',
     'CSSKeyframeRule.cpp',
     'CSSKeyframesRule.cpp',
     'CSSLexer.cpp',
     'CSSMediaRule.cpp',
     'CSSMozDocumentRule.cpp',
+    'CSSNamespaceRule.cpp',
     'CSSPageRule.cpp',
     'CSSRuleList.cpp',
+    'CSSStyleRule.cpp',
     'CSSSupportsRule.cpp',
     'DeclarationBlock.cpp',
     'DocumentStyleRootIterator.cpp',
     'ErrorReporter.cpp',
     'FontFace.cpp',
     'FontFaceSet.cpp',
     'FontFaceSetIterator.cpp',
     'GroupRule.cpp',
@@ -197,33 +192,21 @@ UNIFIED_SOURCES += [
     'nsStyleStruct.cpp',
     'nsStyleTransformMatrix.cpp',
     'nsStyleUtil.cpp',
     'nsTransitionManager.cpp',
     'PostTraversalTask.cpp',
     'PreloadedStyleSheet.cpp',
     'Rule.cpp',
     'ServoBindings.cpp',
-    'ServoCounterStyleRule.cpp',
     'ServoCSSParser.cpp',
     'ServoCSSRuleList.cpp',
-    'ServoDocumentRule.cpp',
     'ServoElementSnapshot.cpp',
-    'ServoFontFaceRule.cpp',
-    'ServoFontFeatureValuesRule.cpp',
-    'ServoImportRule.cpp',
-    'ServoKeyframeRule.cpp',
-    'ServoKeyframesRule.cpp',
-    'ServoMediaRule.cpp',
-    'ServoNamespaceRule.cpp',
-    'ServoPageRule.cpp',
     'ServoSpecifiedValues.cpp',
-    'ServoStyleRule.cpp',
     'ServoStyleSet.cpp',
-    'ServoSupportsRule.cpp',
     'StreamLoader.cpp',
     'StyleAnimationValue.cpp',
     'StyleComplexColor.cpp',
     'StyleSheet.cpp',
     'URLExtraData.cpp',
 ]
 
 SOURCES += [
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -15,16 +15,17 @@
 #include "mozilla/Casting.h"
 
 #include "nsCSSKeywords.h"
 #include "nsLayoutUtils.h"
 #include "nsStyleConsts.h"
 #include "nsIWidget.h"
 #include "nsThemeConstants.h"  // For system widget appearance types
 
+#include "mozilla/dom/Animation.h"
 #include "mozilla/dom/AnimationEffectBinding.h" // for PlaybackDirection
 #include "mozilla/LookAndFeel.h" // for system colors
 
 #include "nsString.h"
 #include "nsStaticNameTable.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticPrefs.h"
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2509,17 +2509,17 @@ nsComputedDOMStyle::GetCSSGradientString
   // color stops
   for (uint32_t i = 0; i < aGradient->mStops.Length(); ++i) {
     if (needSep) {
       aString.AppendLiteral(", ");
     }
 
     const auto& stop = aGradient->mStops[i];
     if (!stop.mIsInterpolationHint) {
-      SetToRGBAColor(tmpVal, stop.mColor);
+      SetValueFromComplexColor(tmpVal, stop.mColor);
       tmpVal->GetCssText(tokenString);
       aString.Append(tokenString);
     }
 
     if (stop.mLocation.GetUnit() != eStyleUnit_None) {
       if (!stop.mIsInterpolationHint) {
         aString.Append(' ');
       }
--- a/layout/style/nsDOMCSSRect.h
+++ b/layout/style/nsDOMCSSRect.h
@@ -9,17 +9,17 @@
 #ifndef nsDOMCSSRect_h_
 #define nsDOMCSSRect_h_
 
 #include "mozilla/Attributes.h"
 #include "mozilla/RefPtr.h"
 
 class nsROCSSPrimitiveValue;
 
-class nsDOMCSSRect final : public RefCounted<nsDOMCSSRect>
+class nsDOMCSSRect final : public mozilla::RefCounted<nsDOMCSSRect>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_TYPENAME(nsDOMCSSRect);
 
   nsDOMCSSRect(nsROCSSPrimitiveValue* aTop,
                nsROCSSPrimitiveValue* aRight,
                nsROCSSPrimitiveValue* aBottom,
                nsROCSSPrimitiveValue* aLeft);
--- a/layout/style/nsHTMLStyleSheet.cpp
+++ b/layout/style/nsHTMLStyleSheet.cpp
@@ -18,16 +18,17 @@
 #include "nsIPresShell.h"
 #include "nsStyleConsts.h"
 #include "nsError.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Element.h"
 #include "nsHashKeys.h"
 #include "mozilla/OperatorNewExtensions.h"
 #include "mozilla/RestyleManager.h"
+#include "mozilla/ServoBindings.h"
 #include "mozilla/ServoStyleSet.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 
 // -----------------------------------------------------------
 
--- a/layout/style/nsMediaFeatures.cpp
+++ b/layout/style/nsMediaFeatures.cpp
@@ -8,19 +8,17 @@
 
 #include "nsMediaFeatures.h"
 #include "nsGkAtoms.h"
 #include "nsCSSKeywords.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
-#ifdef XP_WIN
 #include "mozilla/LookAndFeel.h"
-#endif
 #include "nsDeviceContext.h"
 #include "nsIBaseWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIWidget.h"
 #include "nsContentUtils.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
--- a/layout/style/nsMediaFeatures.h
+++ b/layout/style/nsMediaFeatures.h
@@ -4,16 +4,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* the features that media queries can test */
 
 #ifndef nsMediaFeatures_h_
 #define nsMediaFeatures_h_
 
+#include <stdint.h>
+
 class nsAtom;
 class nsIDocument;
 struct nsCSSKTableEntry;
 class nsCSSValue;
 class nsStaticAtom;
 
 struct nsMediaFeature;
 typedef void (*nsMediaFeatureValueGetter)(nsIDocument* aDocument,
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2008,17 +2008,19 @@ nsStyleGradient::nsStyleGradient()
   , mMozLegacySyntax(false)
 {
 }
 
 bool
 nsStyleGradient::IsOpaque()
 {
   for (uint32_t i = 0; i < mStops.Length(); i++) {
-    if (NS_GET_A(mStops[i].mColor) < 255) {
+    if (mStops[i].mColor.MaybeTransparent()) {
+      // We don't know the foreground color here, so if it's being used
+      // we must assume it might be transparent.
       return false;
     }
   }
   return true;
 }
 
 bool
 nsStyleGradient::HasCalc()
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -156,17 +156,17 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsSt
   nscoord mScriptMinSize;        // [inherited] length
   float   mScriptSizeMultiplier; // [inherited]
   RefPtr<nsAtom> mLanguage;   // [inherited]
 };
 
 struct nsStyleGradientStop
 {
   nsStyleCoord mLocation; // percent, coord, calc, none
-  nscolor mColor;
+  mozilla::StyleComplexColor mColor;
   bool mIsInterpolationHint;
 
   // Use ==/!= on nsStyleGradient instead of on the gradient stop.
   bool operator==(const nsStyleGradientStop&) const = delete;
   bool operator!=(const nsStyleGradientStop&) const = delete;
 };
 
 class nsStyleGradient final
--- a/media/webrtc/signaling/gtest/sdp_unittests.cpp
+++ b/media/webrtc/signaling/gtest/sdp_unittests.cpp
@@ -1561,16 +1561,24 @@ class NewSdpTest : public ::testing::Tes
     std::string GetParseErrors() const {
       std::stringstream output;
       for (auto e: mSdpErrorHolder->GetParseErrors()) {
         output << e.first << ": " << e.second << std::endl;
       }
       return output.str();
     }
 
+    std::string GetParseWarnings() const {
+      std::stringstream output;
+      for (auto e: mSdpErrorHolder->GetParseWarnings()) {
+        output << e.first << ": " << e.second << std::endl;
+      }
+      return output.str();
+    }
+
     void CheckRtpmap(const std::string& expected_pt,
                      SdpRtpmapAttributeList::CodecType codec,
                      const std::string& name,
                      uint32_t clock,
                      uint16_t channels,
                      const std::string& search_pt,
                      const SdpRtpmapAttributeList& rtpmaps) const {
       ASSERT_TRUE(rtpmaps.HasEntry(search_pt));
@@ -1624,16 +1632,20 @@ class NewSdpTest : public ::testing::Tes
 
     void CheckSerialize(const std::string& expected,
                         const SdpAttribute& attr) const {
       std::stringstream str;
       attr.Serialize(str);
       ASSERT_EQ(expected, str.str());
     }
 
+    bool IsParsingWithSipccParser() const {
+      return ::testing::get<1>(GetParam());
+    }
+
     SdpErrorHolder* mSdpErrorHolder;
     SipccSdpParser mSipccParser;
     RsdparsaSdpParser mRustParser;
     mozilla::UniquePtr<Sdp> mSdp;
 }; // class NewSdpTest
 
 TEST_P(NewSdpTest, CreateDestroy) {
 }
@@ -1899,17 +1911,16 @@ const std::string kBasicAudioVideoOffer 
 "a=msid:noappdata" CRLF
 "a=bundle-only" CRLF;
 
 TEST_P(NewSdpTest, BasicAudioVideoSdpParse) {
   ParseSdp(kBasicAudioVideoOffer);
 }
 
 TEST_P(NewSdpTest, CheckRemoveFmtp) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kBasicAudioVideoOffer);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   SdpAttributeList& audioAttrList = mSdp->GetMediaSection(0).GetAttributeList();
 
   ASSERT_TRUE(audioAttrList.HasAttribute(SdpAttribute::kFmtpAttribute));
@@ -2253,17 +2264,16 @@ static const std::string kAudioWithTelep
   "a=ptime:20" CRLF
   "a=maxptime:20" CRLF
   "a=rtpmap:9 G722/8000" CRLF
   "a=rtpmap:0 PCMU/8000" CRLF
   "a=rtpmap:8 PCMA/8000" CRLF
   "a=rtpmap:101 telephone-event/8000" CRLF;
 
 TEST_P(NewSdpTest, CheckTelephoneEventNoFmtp) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
               SdpAttribute::kFmtpAttribute));
   auto audio_format_params =
@@ -2272,118 +2282,108 @@ TEST_P(NewSdpTest, CheckTelephoneEventNo
 
   // make sure we don't get a fmtp for codec 101
   for (size_t i = 0; i < audio_format_params.size(); ++i) {
     ASSERT_NE("101", audio_format_params[i].format);
   }
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventWithDefaultEvents) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 0-15" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventWithBadCharacter) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 0-5." CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventIncludingCommas) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 0-15,66,67" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("0-15,66,67");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventComplexEvents) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 0,1,2-4,5-15,66,67" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("0,1,2-4,5-15,66,67");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventNoHyphen) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 5,6,7" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("5,6,7");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventOnlyZero) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 0" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("0");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventOnlyOne) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 1" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   CheckDtmfFmtp("1");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadThreeDigit) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 123" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadThreeDigitWithHyphen) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 0-123" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadLeadingHyphen) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 -12" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
@@ -2395,89 +2395,82 @@ TEST_P(NewSdpTest, CheckTelephoneEventBa
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadTrailingHyphenInMiddle) {
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 1,12-,4" CRLF, false);
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadLeadingComma) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 ,2,3" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadMultipleLeadingComma) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 ,,,2,3" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadConsecutiveCommas) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 1,,,,,,,,3" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadTrailingComma) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 1,2,3," CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadTwoHyphens) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 1-2-3" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadSixDigit) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 112233" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
 }
 
 TEST_P(NewSdpTest, CheckTelephoneEventBadRangeReversed) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kAudioWithTelephoneEvent
            + "a=fmtp:101 33-2" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   // check for the default dtmf tones
   CheckDtmfFmtp("0-15");
@@ -2497,17 +2490,16 @@ static const std::string kVideoWithRedAn
   "a=rtpmap:120 VP8/90000" CRLF
   "a=fmtp:120 max-fs=3600;max-fr=30" CRLF
   "a=rtpmap:121 VP9/90000" CRLF
   "a=fmtp:121 max-fs=3600;max-fr=30" CRLF
   "a=rtpmap:122 red/90000" CRLF
   "a=rtpmap:123 ulpfec/90000" CRLF;
 
 TEST_P(NewSdpTest, CheckRedNoFmtp) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kVideoWithRedAndUlpfecSdp);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
               SdpAttribute::kFmtpAttribute));
   auto video_format_params =
@@ -2516,23 +2508,29 @@ TEST_P(NewSdpTest, CheckRedNoFmtp) {
 
   // make sure we don't get a fmtp for codec 122
   for (size_t i = 0; i < video_format_params.size(); ++i) {
     ASSERT_NE("122", video_format_params[i].format);
   }
 }
 
 TEST_P(NewSdpTest, CheckRedEmptyFmtp) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   // if serializing and re-parsing, we expect errors
   if (::testing::get<0>(GetParam())) {
     ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122" CRLF);
   } else {
     ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122" CRLF, false);
-    ASSERT_NE(0U, GetParseErrors().size());
+
+    if (IsParsingWithSipccParser()) {
+      ASSERT_NE(0U, GetParseErrors().size());
+    } else {
+      // This is the branch for the rust parser to check for warnings, as the
+      // rust parser will give a warning at that point instead of an error.
+      ASSERT_NE(0U, GetParseWarnings().size());
+    }
   }
 
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
               SdpAttribute::kFmtpAttribute));
@@ -2542,17 +2540,16 @@ TEST_P(NewSdpTest, CheckRedEmptyFmtp) {
 
   // make sure we don't get a fmtp for codec 122
   for (size_t i = 0; i < video_format_params.size(); ++i) {
     ASSERT_NE("122", video_format_params[i].format);
   }
 }
 
 TEST_P(NewSdpTest, CheckRedFmtpWith2Codecs) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122 120/121" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
               SdpAttribute::kFmtpAttribute));
   auto video_format_params =
@@ -2567,17 +2564,16 @@ TEST_P(NewSdpTest, CheckRedFmtpWith2Code
       static_cast<SdpFmtpAttributeList::RedParameters*>(
         video_format_params[3].parameters.get()));
   ASSERT_EQ(2U, red_parameters->encodings.size());
   ASSERT_EQ(120U, red_parameters->encodings[0]);
   ASSERT_EQ(121U, red_parameters->encodings[1]);
 }
 
 TEST_P(NewSdpTest, CheckRedFmtpWith3Codecs) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122 120/121/123" CRLF);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
               SdpAttribute::kFmtpAttribute));
   auto video_format_params =
@@ -2639,17 +2635,17 @@ const std::string kH264AudioVideoOffer =
 "a=candidate:6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340" CRLF
 "a=candidate:0 2 UDP 2130379006 10.0.0.36 55428 typ host" CRLF
 "m=video 9 RTP/SAVPF 97 98 120" CRLF
 "c=IN IP6 ::1" CRLF
 "a=mid:second" CRLF
 "a=rtpmap:97 H264/90000" CRLF
 "a=fmtp:97 profile-level-id=42a01e" CRLF
 "a=rtpmap:98 H264/90000" CRLF
-"a=fmtp:98 PROFILE=0;LEVEL=0;profile-level-id=42a00d;packetization-mode=1;level-asymmetry-allowed=1;max-mbps=42000;max-fs=1400;max-cpb=1000;max-dpb=1000;max-br=180000;parameter-add=1;usedtx=0;stereo=0;useinbandfec=0;cbr=0" CRLF
+"a=fmtp:98 PROFILE=0;LEVEL=0;parameter-add=1;profile-level-id=42a00d;packetization-mode=1;level-asymmetry-allowed=1;max-mbps=42000;max-fs=1400;max-cpb=1000;max-dpb=1000;max-br=180000;usedtx=0;stereo=0;useinbandfec=0;cbr=0" CRLF
 "a=rtpmap:120 VP8/90000" CRLF
 "a=fmtp:120 max-fs=3601;max-fr=31" CRLF
 "a=recvonly" CRLF
 "a=setup:active" CRLF
 "a=rtcp-mux" CRLF
 "a=msid:streama tracka" CRLF
 "a=msid:streamb trackb" CRLF
 "a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF
@@ -2661,17 +2657,16 @@ const std::string kH264AudioVideoOffer =
 "a=candidate:3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935" CRLF
 "a=candidate:3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026" CRLF
 "m=audio 9 RTP/SAVPF 0" CRLF
 "a=mid:third" CRLF
 "a=rtpmap:0 PCMU/8000" CRLF
 "a=msid:noappdata" CRLF;
 
 TEST_P(NewSdpTest, CheckFormatParameters) {
-  SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432918
   ParseSdp(kH264AudioVideoOffer);
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
   ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
     << "Wrong number of media sections";
 
   ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
       SdpAttribute::kFmtpAttribute));
   auto audio_format_params =
--- a/media/webrtc/signaling/src/sdp/RsdparsaSdpAttributeList.cpp
+++ b/media/webrtc/signaling/src/sdp/RsdparsaSdpAttributeList.cpp
@@ -693,29 +693,95 @@ RsdparsaSdpAttributeList::LoadRtpmap(Rus
                           rtpmap.frequency, channels);
   }
   SetAttribute(rtpmapList.release());
 }
 
 void
 RsdparsaSdpAttributeList::LoadFmtp(RustAttributeList* attributeList)
 {
-  // TODO: Not implemented, see Bug 1432918
-#if 0
   size_t numFmtp = sdp_get_fmtp_count(attributeList);
     if (numFmtp == 0) {
     return;
   }
   auto rustFmtps = MakeUnique<RustSdpAttributeFmtp[]>(numFmtp);
-  size_t numValidFmtp = sdp_get_fmtp(attributeList, numFmtp,
-                                        rustFmtps.get());
+  size_t numValidFmtp = sdp_get_fmtp(attributeList, numFmtp,rustFmtps.get());
+  auto fmtpList = MakeUnique<SdpFmtpAttributeList>();
   for(size_t i = 0; i < numValidFmtp; i++) {
-    RustSdpAttributeFmtp& fmtp = rustFmtps[i];
+    const RustSdpAttributeFmtp& fmtp = rustFmtps[i];
+    uint8_t payloadType = fmtp.payloadType;
+    std::string codecName = convertStringView(fmtp.codecName);
+    const RustSdpAttributeFmtpParameters& rustFmtpParameters = fmtp.parameters;
+
+    UniquePtr<SdpFmtpAttributeList::Parameters> fmtpParameters;
+
+    // use the upper case version of the codec name
+    std::transform(codecName.begin(), codecName.end(),
+                   codecName.begin(), ::toupper);
+
+    if(codecName == "H264"){
+      SdpFmtpAttributeList::H264Parameters h264Parameters;
+
+      h264Parameters.packetization_mode = rustFmtpParameters.packetization_mode;
+      h264Parameters.level_asymmetry_allowed =
+                                  rustFmtpParameters.level_asymmetry_allowed;
+      h264Parameters.profile_level_id = rustFmtpParameters.profile_level_id;
+      h264Parameters.max_mbps = rustFmtpParameters.max_mbps;
+      h264Parameters.max_fs = rustFmtpParameters.max_fs;
+      h264Parameters.max_cpb = rustFmtpParameters.max_cpb;
+      h264Parameters.max_dpb = rustFmtpParameters.max_dpb;
+      h264Parameters.max_br = rustFmtpParameters.max_br;
+
+      // TODO(bug 1466859): Support sprop-parameter-sets
+
+      fmtpParameters.reset(new SdpFmtpAttributeList::H264Parameters(
+                                                    std::move(h264Parameters)));
+    } else if(codecName == "OPUS"){
+      SdpFmtpAttributeList::OpusParameters opusParameters;
+
+      opusParameters.maxplaybackrate = rustFmtpParameters.maxplaybackrate;
+      opusParameters.stereo = rustFmtpParameters.stereo;
+      opusParameters.useInBandFec = rustFmtpParameters.useinbandfec;
+
+      fmtpParameters.reset(new SdpFmtpAttributeList::OpusParameters(
+                                                    std::move(opusParameters)));
+    } else if((codecName == "VP8") || (codecName == "VP9")){
+      SdpFmtpAttributeList::VP8Parameters
+                                    vp8Parameters(codecName == "VP8" ?
+                                                  SdpRtpmapAttributeList::kVP8 :
+                                                  SdpRtpmapAttributeList::kVP9);
+
+      vp8Parameters.max_fs = rustFmtpParameters.max_fs;
+      vp8Parameters.max_fr = rustFmtpParameters.max_fr;
+
+      fmtpParameters.reset(new SdpFmtpAttributeList::VP8Parameters(
+                                                     std::move(vp8Parameters)));
+    } else if(codecName == "TELEPHONE-EVENT"){
+      SdpFmtpAttributeList::TelephoneEventParameters telephoneEventParameters;
+
+      telephoneEventParameters.dtmfTones =
+                              convertStringView(rustFmtpParameters.dtmf_tones);
+
+      fmtpParameters.reset(new SdpFmtpAttributeList::TelephoneEventParameters(
+                                          std::move(telephoneEventParameters)));
+    } else if(codecName == "RED") {
+      SdpFmtpAttributeList::RedParameters redParameters;
+
+      redParameters.encodings = convertU8Vec(rustFmtpParameters.encodings);
+
+      fmtpParameters.reset(new SdpFmtpAttributeList::RedParameters(
+                                                     std::move(redParameters)));
+    } else{
+      // The parameter set is unknown so skip it
+      continue;
+    }
+
+    fmtpList->PushEntry(std::to_string(payloadType), std::move(fmtpParameters));
   }
-#endif
+  SetAttribute(fmtpList.release());
 }
 
 void
 RsdparsaSdpAttributeList::LoadPtime(RustAttributeList* attributeList)
 {
   int64_t ptime = sdp_get_ptime(attributeList);
   if (ptime >= 0) {
     SetAttribute(new SdpNumberAttribute(SdpAttribute::kPtimeAttribute,
--- a/media/webrtc/signaling/src/sdp/RsdparsaSdpGlue.cpp
+++ b/media/webrtc/signaling/src/sdp/RsdparsaSdpGlue.cpp
@@ -40,9 +40,23 @@ sdp::AddrType convertAddressType(RustSdp
       return sdp::kIPv4;
     case RustSdpAddrType::kRustAddrIp6:
       return sdp::kIPv6;
   }
 
   MOZ_CRASH("unknown address type");
 }
 
+std::vector<uint8_t> convertU8Vec(U8Vec* vec)
+{
+  std::vector<std::uint8_t> ret;
+
+  size_t len = u8_vec_len(vec);
+  for (size_t i = 0; i < len; i++) {
+    uint8_t byte;
+    u8_vec_get(vec, i, &byte);
+    ret.push_back(byte);
+  }
+
+  return ret;
 }
+
+}
--- a/media/webrtc/signaling/src/sdp/RsdparsaSdpGlue.h
+++ b/media/webrtc/signaling/src/sdp/RsdparsaSdpGlue.h
@@ -19,13 +19,14 @@ struct FreeRustSdpSession {
   void operator()(RustSdpSession* aSess) { sdp_free_session(aSess); }
 };
 
 typedef UniquePtr<RustSdpSession, FreeRustSdpSession> RsdparsaSessionHandle;
 
 std::string convertStringView(StringView str);
 std::vector<std::string> convertStringVec(StringVec* vec);
 sdp::AddrType convertAddressType(RustSdpAddrType addr);
+std::vector<uint8_t> convertU8Vec(U8Vec* vec);
 
 }
 
 
 #endif
--- a/media/webrtc/signaling/src/sdp/RsdparsaSdpInc.h
+++ b/media/webrtc/signaling/src/sdp/RsdparsaSdpInc.h
@@ -12,16 +12,17 @@
 #include <stdbool.h>
 
 struct BandwidthVec;
 struct RustSdpSession;
 struct RustSdpError;
 struct RustMediaSection;
 struct RustAttributeList;
 struct StringVec;
+struct U8Vec;
 struct U32Vec;
 struct RustHeapString;
 
 enum class RustSdpAddrType {
   kRustAddrNone,
   kRustAddrIp4,
   kRustAddrIp6
 };
@@ -96,20 +97,52 @@ struct RustSdpAttributeRtpmap {
 
 struct RustSdpAttributeRtcpFb {
   uint32_t payloadType;
   uint32_t feedbackType;
   StringView parameter;
   StringView extra;
 };
 
+struct RustSdpAttributeFmtpParameters {
+  // H264
+  uint32_t packetization_mode;
+  bool level_asymmetry_allowed;
+  uint32_t profile_level_id;
+  uint32_t max_fs;
+  uint32_t max_cpb;
+  uint32_t max_dpb;
+  uint32_t max_br;
+  uint32_t max_mbps;
+
+  // VP8 and VP9
+  // max_fs, already defined in H264
+  uint32_t max_fr;
+
+  // Opus
+  uint32_t maxplaybackrate;
+  bool usedtx;
+  bool stereo;
+  bool useinbandfec;
+  bool cbr;
+
+  // telephone-event
+  StringView dtmf_tones;
+
+  // Red codecs
+  U8Vec* encodings;
+
+  // Unknown
+  StringVec* unknown_tokens;
+};
+
 struct RustSdpAttributeFmtp {
   uint8_t payloadType;
   StringView codecName;
-  StringVec* tokens;
+  RustSdpAttributeFmtpParameters parameters;
 };
 
 struct RustSdpAttributeFlags {
   bool iceLite;
   bool rtcpMux;
   bool bundleOnly;
   bool endOfCandidates;
 };
@@ -175,16 +208,19 @@ extern "C" {
 
 size_t string_vec_len(const StringVec* vec);
 nsresult string_vec_get_view(const StringVec* vec, size_t index,
                              StringView* str);
 
 size_t u32_vec_len(const U32Vec* vec);
 nsresult u32_vec_get(const U32Vec* vec, size_t index, uint32_t* ret);
 
+size_t u8_vec_len(const U8Vec* vec);
+nsresult u8_vec_get(const U8Vec* vec, size_t index, uint8_t* ret);
+
 void sdp_free_string(char* string);
 
 nsresult parse_sdp(const char* sdp, uint32_t length, bool fail_on_warning,
                    RustSdpSession** ret, RustSdpError** err);
 RustSdpSession* sdp_new_reference(RustSdpSession* aSess);
 void sdp_free_session(RustSdpSession* ret);
 size_t sdp_get_error_line_num(const RustSdpError* err);
 StringView sdp_get_error_message(const RustSdpError* err);
--- a/media/webrtc/signaling/src/sdp/RsdparsaSdpParser.cpp
+++ b/media/webrtc/signaling/src/sdp/RsdparsaSdpParser.cpp
@@ -35,19 +35,28 @@ RsdparsaSdpParser::Parse(const std::stri
       std::string errMsg = convertStringView(sdp_get_error_message(err));
       sdp_free_error(err);
       AddParseError(line, errMsg);
     } else {
       AddParseError(0, "Unhandled Rsdparsa parsing error");
     }
     return nullptr;
   }
+
+  if(err) {
+    size_t line = sdp_get_error_line_num(err);
+    std::string warningMsg = convertStringView(sdp_get_error_message(err));
+    sdp_free_error(err);
+    AddParseWarnings(line, warningMsg);
+  }
+
   RsdparsaSessionHandle uniqueResult;
   uniqueResult.reset(result);
   RustSdpOrigin rustOrigin = sdp_get_origin(uniqueResult.get());
   sdp::AddrType addrType = convertAddressType(rustOrigin.addr.addrType);
   SdpOrigin origin(convertStringView(rustOrigin.username),
                    rustOrigin.sessionId, rustOrigin.sessionVersion,
                    addrType, std::string(rustOrigin.addr.unicastAddr));
-  return MakeUnique<RsdparsaSdp>(std::move(uniqueResult), origin);
+
+    return MakeUnique<RsdparsaSdp>(std::move(uniqueResult), origin);
 }
 
 } // namespace mozilla
--- a/media/webrtc/signaling/src/sdp/SdpErrorHolder.h
+++ b/media/webrtc/signaling/src/sdp/SdpErrorHolder.h
@@ -21,30 +21,49 @@ public:
 
   void
   AddParseError(size_t line, const std::string& message)
   {
     mErrors.push_back(std::make_pair(line, message));
   }
 
   void
+  AddParseWarnings(size_t line, const std::string& message)
+  {
+    mWarnings.push_back(std::make_pair(line, message));
+  }
+
+  void
   ClearParseErrors()
   {
     mErrors.clear();
   }
 
+  void
+  ClearParseWarnings()
+  {
+    mWarnings.clear();
+  }
+
   /**
    * Returns a reference to the list of parse errors.
    * This gets cleared out when you call Parse.
    */
   const std::vector<std::pair<size_t, std::string> >&
   GetParseErrors() const
   {
     return mErrors;
   }
 
+  const std::vector<std::pair<size_t, std::string> >&
+  GetParseWarnings() const
+  {
+    return mWarnings;
+  }
+
 private:
   std::vector<std::pair<size_t, std::string> > mErrors;
+  std::vector<std::pair<size_t, std::string> > mWarnings;
 };
 
 } // namespace mozilla
 
 #endif
--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs
@@ -235,19 +235,57 @@ pub struct SdpAttributeExtmap {
     pub id: u16,
     pub direction: Option<SdpAttributeDirection>,
     pub url: String,
     pub extension_attributes: Option<String>,
 }
 
 #[derive(Clone)]
 #[cfg_attr(feature="serialize", derive(Serialize))]
+pub struct SdpAttributeFmtpParameters {
+    // H264
+    // TODO(bug 1466859): Support sprop-parameter-sets
+    // pub static const max_sprop_len: u32 = 128,
+    // pub sprop_parameter_sets: [u8, max_sprop_len],
+    pub packetization_mode: u32,
+    pub level_asymmetry_allowed: bool,
+    pub profile_level_id: u32,
+    pub max_fs: u32,
+    pub max_cpb: u32,
+    pub max_dpb: u32,
+    pub max_br: u32,
+    pub max_mbps: u32,
+
+    // VP8 and VP9
+    // max_fs, already defined in H264
+    pub max_fr: u32,
+
+    // Opus
+    pub maxplaybackrate: u32,
+    pub usedtx: bool,
+    pub stereo: bool,
+    pub useinbandfec: bool,
+    pub cbr: bool,
+
+    // Red
+    pub encodings: Vec<u8>,
+
+    // telephone-event
+    pub dtmf_tones: String,
+
+    // Unknown
+    pub unknown_tokens: Vec<String>,
+}
+
+
+#[derive(Clone)]
+#[cfg_attr(feature="serialize", derive(Serialize))]
 pub struct SdpAttributeFmtp {
     pub payload_type: u8,
-    pub tokens: Vec<String>,
+    pub parameters: SdpAttributeFmtpParameters,
 }
 
 #[derive(Clone)]
 #[cfg_attr(feature="serialize", derive(Serialize))]
 pub struct SdpAttributeFingerprint {
     // TODO turn the supported hash algorithms into an enum?
     pub hash_algorithm: String,
     pub fingerprint: String,
@@ -865,29 +903,185 @@ fn parse_fingerprint(to_parse: &str) -> 
     }
     Ok(SdpAttribute::Fingerprint(SdpAttributeFingerprint {
                                      hash_algorithm: tokens[0].to_string(),
                                      fingerprint: tokens[1].to_string(),
                                  }))
 }
 
 fn parse_fmtp(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
-    let tokens: Vec<&str> = to_parse.split_whitespace().collect();
+    let tokens: Vec<&str> = to_parse.splitn(2," ").collect();
+
     if tokens.len() != 2 {
-        return Err(SdpParserInternalError::Generic("Fmtp needs to have two tokens".to_string()));
+        return Err(SdpParserInternalError::Unsupported(
+            "Fmtp attributes require a payload type and a parameter block.".to_string()
+        ));
     }
+
+    let payload_token = tokens[0];
+    let parameter_token = tokens[1];
+
+
+    // Default initiliaze SdpAttributeFmtpParameters
+    let mut parameters = SdpAttributeFmtpParameters{
+        packetization_mode: 0,
+        level_asymmetry_allowed: false,
+        profile_level_id: 0x420010,
+        max_fs: 0,
+        max_cpb: 0,
+        max_dpb: 0,
+        max_br: 0,
+        max_mbps: 0,
+        usedtx: false,
+        stereo: false,
+        useinbandfec: false,
+        cbr: false,
+        max_fr: 0,
+        maxplaybackrate: 48000,
+        encodings: Vec::new(),
+        dtmf_tones: "".to_string(),
+        unknown_tokens: Vec::new(),
+    };
+
+    if parameter_token.contains("=") {
+        let parameter_tokens: Vec<&str> = parameter_token.split(";").collect();
+
+        for parameter_token in parameter_tokens.iter() {
+            let name_value_pair: Vec<&str> = parameter_token.splitn(2,"=").collect();
+
+            if name_value_pair.len() != 2 {
+                return Err(SdpParserInternalError::Generic(
+                    "A fmtp parameter must be either a telephone event, a parameter list or
+                                                                    a red codec list".to_string()
+                ))
+            }
+
+            let parse_bool = |val: &str, param_name: &str| -> Result<bool,SdpParserInternalError> {
+                match val.parse::<u8>()? {
+                    0 => Ok(false),
+                    1 => Ok(true),
+                    _ => return Err(SdpParserInternalError::Generic(
+                        format!("The fmtp parameter '{:}' must be 0 or 1", param_name)
+                        .to_string()
+                    ))
+                }
+            };
+
+            let parameter_name = name_value_pair[0];
+            let parameter_val = name_value_pair[1];
+
+            match parameter_name.to_uppercase().as_str() {
+                // H264
+                "PROFILE-LEVEL-ID" => parameters.profile_level_id =
+                                                match u32::from_str_radix(parameter_val,16)? {
+                    x @ 0 ... 0xffffff => x,
+                    _ => return Err(SdpParserInternalError::Generic(
+                        "The fmtp parameter 'profile-level-id' must be in range [0,0xffffff]"
+                        .to_string()
+                    ))
+                },
+                "PACKETIZATION-MODE" => parameters.packetization_mode =
+                                                   match parameter_val.parse::<u32>()? {
+                    x @ 0...2 => x,
+                    _ => return Err(SdpParserInternalError::Generic(
+                        "The fmtp parameter 'packetization-mode' must be 0,1 or 2"
+                        .to_string()
+                    ))
+                },
+                "LEVEL-ASYMMETRY-ALLOWED" => parameters.level_asymmetry_allowed =
+                                             parse_bool(parameter_val,"level-asymmetry-allowed")?,
+                "MAX-MBPS" => parameters.max_mbps = parameter_val.parse::<u32>()?,
+                "MAX-FS" => parameters.max_fs = parameter_val.parse::<u32>()?,
+                "MAX-CPB" => parameters.max_cpb = parameter_val.parse::<u32>()?,
+                "MAX-DPB" => parameters.max_dpb = parameter_val.parse::<u32>()?,
+                "MAX-BR" => parameters.max_br = parameter_val.parse::<u32>()?,
+
+                // VP8 and VP9
+                "MAX-FR" => parameters.max_fr = parameter_val.parse::<u32>()?,
+
+                //Opus
+                "MAXPLAYBACKRATE" => parameters.maxplaybackrate = parameter_val.parse::<u32>()?,
+                "USEDTX" => parameters.usedtx = parse_bool(parameter_val,"usedtx")?,
+                "STEREO" => parameters.stereo = parse_bool(parameter_val,"stereo")?,
+                "USEINBANDFEC" => parameters.useinbandfec =
+                                             parse_bool(parameter_val,"useinbandfec")?,
+                "CBR" => parameters.cbr = parse_bool(parameter_val,"cbr")?,
+                _ => {
+                    parameters.unknown_tokens.push(parameter_token.to_string())
+                }
+            }
+        }
+    } else {
+        if parameter_token.contains("/") {
+            let encodings: Vec<&str> = parameter_token.split("/").collect();
+
+            for encoding in encodings {
+                match encoding.parse::<u8>()? {
+                    x @ 0...128 => parameters.encodings.push(x),
+                    _ => return Err(SdpParserInternalError::Generic(
+                        "Red codec must be in range [0,128]".to_string()
+                    ))
+                }
+            }
+        } else { // This is the case for the 'telephone-event' codec
+            let dtmf_tones: Vec<&str> = parameter_token.split(",").collect();
+            let mut dtmf_tone_is_ok = true;
+
+            // This closure verifies the output of some_number_as_string.parse::<u8>().ok() like calls
+            let validate_digits = |digit_option: Option<u8> | -> Option<u8> {
+                match digit_option{
+                    Some(x) => match x {
+                        0...100 => Some(x),
+                        _ => None,
+                    },
+                    None => None,
+                }
+            };
+
+            // This loop does some sanity checking on the passed dtmf tones
+            for dtmf_tone in dtmf_tones {
+                let dtmf_tone_range: Vec<&str> = dtmf_tone.splitn(2,"-").collect();
+
+                dtmf_tone_is_ok = match dtmf_tone_range.len() {
+                    // In this case the dtmf tone is a range
+                    2 => {
+                        match validate_digits(dtmf_tone_range[0].parse::<u8>().ok()) {
+                            Some(l) => match validate_digits(dtmf_tone_range[1].parse::<u8>().ok()) {
+                                Some(u) => {
+                                    // Check that the first part of the range is smaller than the second part
+                                    l < u
+                                },
+                                None => false
+                            },
+                            None => false,
+                        }
+                    },
+                     // In this case the dtmf tone is a single tone
+                    1 => validate_digits(dtmf_tone.parse::<u8>().ok()).is_some(),
+                    _ => false
+                };
+
+                if !dtmf_tone_is_ok {
+                    break ;
+                }
+            }
+
+            // Set the parsed dtmf tones or in case the parsing was insuccessfull, set it to the default "0-15"
+            parameters.dtmf_tones = match dtmf_tone_is_ok{
+                true => parameter_token.to_string(),
+                false => "0-15".to_string()
+            }
+        }
+    }
+
     Ok(SdpAttribute::Fmtp(SdpAttributeFmtp {
-                              // TODO check for dynamic PT range
-                              payload_type: tokens[0].parse::<u8>()?,
-                              // TODO this should probably be slit into known tokens
-                              // plus a list of unknown tokens
-                              tokens: to_parse.split(';').map(|x| x.to_string()).collect(),
+                              payload_type: payload_token.parse::<u8>()?,
+                              parameters: parameters,
                           }))
 }
-
 fn parse_group(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
     let mut tokens = to_parse.split_whitespace();
     let semantics = match tokens.next() {
         None => {
             return Err(SdpParserInternalError::Generic("Group attribute is missing semantics token"
                                                            .to_string()))
         }
         Some(x) => {
@@ -1400,17 +1594,28 @@ fn test_parse_attribute_extmap() {
 
 #[test]
 fn test_parse_attribute_fingerprint() {
     assert!(parse_attribute("fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:BF:2F:E3:91:CB:57:A9:9D:4A:A2:0B:40").is_ok())
 }
 
 #[test]
 fn test_parse_attribute_fmtp() {
-    assert!(parse_attribute("fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1").is_ok())
+    assert!(parse_attribute("fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1").is_ok());
+    assert!(parse_attribute("fmtp:66 0-15").is_ok());
+    assert!(parse_attribute("fmtp:109 0-15,66").is_ok());
+    assert!(parse_attribute("fmtp:66 111/115").is_ok());
+    assert!(parse_attribute("fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1").is_ok());
+    assert!(parse_attribute("fmtp:109 maxplaybackrate=48000; stereo=1; useinbandfec=1").is_ok());
+    assert!(parse_attribute("fmtp:109 maxplaybackrate=48000; stereo=1;useinbandfec=1").is_ok());
+    assert!(parse_attribute("fmtp:8 maxplaybackrate=48000").is_ok());
+
+    assert!(parse_attribute("fmtp:77 ").is_err());
+    assert!(parse_attribute("fmtp:109 maxplaybackrate=48000stereo=1;").is_err());
+    assert!(parse_attribute("fmtp:8 ;maxplaybackrate=48000").is_err());
 }
 
 #[test]
 fn test_parse_attribute_group() {
     assert!(parse_attribute("group:LS").is_ok());
     assert!(parse_attribute("group:LS 1 2").is_ok());
     assert!(parse_attribute("group:BUNDLE sdparta_0 sdparta_1 sdparta_2").is_ok());
 
--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/error.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/error.rs
@@ -2,17 +2,17 @@ use std::num::ParseIntError;
 use std::net::AddrParseError;
 use std::fmt;
 use std::error;
 use std::error::Error;
 #[cfg(feature = "serialize")]
 use serde::ser::{Serializer, Serialize, SerializeStruct};
 
 
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub enum SdpParserInternalError {
     Generic(String),
     Unsupported(String),
     Integer(ParseIntError),
     Address(AddrParseError),
 }
 
 impl fmt::Display for SdpParserInternalError {
@@ -94,17 +94,17 @@ fn test_sdp_parser_internal_error_addres
     assert!(addr.is_err());
     let addr_err = SdpParserInternalError::Address(addr.err().unwrap());
     assert_eq!(format!("{}", addr_err),
                "IP address parsing error: invalid IP address syntax");
     assert_eq!(addr_err.description(), "invalid IP address syntax");
     assert!(!addr_err.cause().is_none());
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 pub enum SdpParserError {
     Line {
         error: SdpParserInternalError,
         line: String,
         line_number: usize,
     },
     Unsupported {
         error: SdpParserInternalError,
--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs
@@ -96,16 +96,17 @@ pub struct SdpSession {
     pub version: u64,
     pub origin: SdpOrigin,
     pub session: String,
     pub connection: Option<SdpConnection>,
     pub bandwidth: Vec<SdpBandwidth>,
     pub timing: Option<SdpTiming>,
     pub attribute: Vec<SdpAttribute>,
     pub media: Vec<SdpMedia>,
+    pub warnings: Vec<SdpParserError>
     // unsupported values:
     // information: Option<String>,
     // uri: Option<String>,
     // email: Option<String>,
     // phone: Option<String>,
     // repeat: Option<String>,
     // zone: Option<String>,
     // key: Option<String>,
@@ -117,16 +118,17 @@ impl SdpSession {
             version,
             origin,
             session,
             connection: None,
             bandwidth: Vec::new(),
             timing: None,
             attribute: Vec::new(),
             media: Vec::new(),
+            warnings: Vec::new(),
         }
     }
 
     pub fn get_version(&self) -> u64 {
         self.version
     }
 
     pub fn get_origin(&self) -> &SdpOrigin {
@@ -880,28 +882,33 @@ pub fn parse_sdp(sdp: &str, fail_on_warn
                                         message,
                                         line_number,
                                     })
                     }
                 }
             }
         };
     }
-    for warning in warnings {
-        if fail_on_warning {
-            return Err(warning);
-        } else {
-            println!("Warning: {}", warning);
-        };
+
+    if fail_on_warning && (warnings.len() > 0) {
+        return Err(warnings[0].clone());
     }
+
     // We just return the last of the errors here
     if let Some(e) = errors.pop() {
         return Err(e);
     };
-    let session = parse_sdp_vector(&sdp_lines)?;
+
+    let mut session = parse_sdp_vector(&sdp_lines)?;
+    session.warnings = warnings;
+
+    for warning in &session.warnings {
+        println!("Warning: {}", &warning);
+    }
+
     Ok(session)
 }
 
 #[test]
 fn test_parse_sdp_zero_length_string_fails() {
     assert!(parse_sdp("", true).is_err());
 }
 
--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/attribute.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/attribute.rs
@@ -1,13 +1,20 @@
 use std::slice;
 use libc::{size_t, uint8_t, uint16_t, uint32_t, int64_t};
 
 use rsdparsa::SdpSession;
-use rsdparsa::attribute_type::{SdpAttribute, SdpAttributeType, SdpAttributePayloadType, SdpAttributeFingerprint, SdpAttributeSetup, SdpAttributeSsrc, SdpAttributeRtpmap, SdpAttributeMsid, SdpAttributeMsidSemantic, SdpAttributeGroupSemantic, SdpAttributeGroup, SdpAttributeRtcp, SdpAttributeRtcpFb, SdpAttributeSctpmap, SdpAttributeRemoteCandidate, SdpAttributeExtmap, SdpAttributeDirection};
+use rsdparsa::attribute_type::{SdpAttribute, SdpAttributeType, SdpAttributePayloadType,
+                               SdpAttributeFingerprint, SdpAttributeSetup, SdpAttributeSsrc,
+                               SdpAttributeRtpmap, SdpAttributeFmtpParameters,
+                               SdpAttributeMsid, SdpAttributeMsidSemantic,
+                               SdpAttributeGroupSemantic, SdpAttributeGroup, SdpAttributeRtcp,
+                               SdpAttributeRtcpFb, SdpAttributeSctpmap,
+                               SdpAttributeRemoteCandidate, SdpAttributeExtmap,
+                               SdpAttributeDirection};
 use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG};
 
 use types::StringView;
 use network::RustIpAddr;
 
 
 #[repr(C)]
 #[derive(Clone, Copy, PartialEq, Eq)]
@@ -314,20 +321,79 @@ pub unsafe extern "C" fn sdp_get_rtpmaps
         None
     }).collect();
     let rtpmaps = slice::from_raw_parts_mut(ret_rtpmaps, ret_size);
     rtpmaps.copy_from_slice(attrs.as_slice());
 }
 
 #[repr(C)]
 #[derive(Clone, Copy)]
+pub struct RustSdpAttributeFmtpParameters {
+
+    // H264
+    pub packetization_mode: uint32_t,
+    pub level_asymmetry_allowed: bool,
+    pub profile_level_id: uint32_t,
+    pub max_fs: uint32_t,
+    pub max_cpb: uint32_t,
+    pub max_dpb: uint32_t,
+    pub max_br: uint32_t,
+    pub max_mbps: uint32_t,
+
+    // VP8 and VP9
+    // max_fs, already defined in H264
+    pub max_fr: uint32_t,
+
+    // Opus
+    pub maxplaybackrate: uint32_t,
+    pub usedtx: bool,
+    pub stereo: bool,
+    pub useinbandfec: bool,
+    pub cbr: bool,
+
+    // telephone-event
+    pub dtmf_tones: StringView,
+
+    // Red
+    pub encodings: *const Vec<uint8_t>,
+
+    // Unknown
+    pub unknown_tokens: *const Vec<String>,
+}
+
+impl<'a> From<&'a SdpAttributeFmtpParameters> for RustSdpAttributeFmtpParameters {
+    fn from(other: &SdpAttributeFmtpParameters) -> Self {
+        RustSdpAttributeFmtpParameters{
+                packetization_mode: other.packetization_mode,
+                level_asymmetry_allowed: other.level_asymmetry_allowed,
+                profile_level_id: other.profile_level_id,
+                max_fs: other.max_fs,
+                max_cpb: other.max_cpb,
+                max_dpb: other.max_dpb,
+                max_br: other.max_br,
+                max_mbps: other.max_mbps,
+                usedtx: other.usedtx,
+                stereo: other.stereo,
+                useinbandfec: other.useinbandfec,
+                cbr: other.cbr,
+                max_fr: other.max_fr,
+                maxplaybackrate: other.maxplaybackrate,
+                dtmf_tones: StringView::from(other.dtmf_tones.as_str()),
+                encodings: &other.encodings,
+                unknown_tokens: &other.unknown_tokens,
+        }
+    }
+}
+
+#[repr(C)]
+#[derive(Clone, Copy)]
 pub struct RustSdpAttributeFmtp {
     pub payload_type: uint8_t,
     pub codec_name: StringView,
-    pub tokens: *const Vec<String>,
+    pub parameters: RustSdpAttributeFmtpParameters,
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn sdp_get_fmtp_count(attributes: *const Vec<SdpAttribute>) -> size_t {
     count_attribute((*attributes).as_slice(), RustSdpAttributeType::Fmtp)
 }
 
 fn find_payload_type(attributes: &[SdpAttribute], payload_type: u8) -> Option<&SdpAttributeRtpmap> {
@@ -338,30 +404,31 @@ fn find_payload_type(attributes: &[SdpAt
             None
         }
     } else {
         None
     }).next()
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn sdp_get_fmtp(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_fmtp: *mut RustSdpAttributeFmtp) -> size_t {
+pub unsafe extern "C" fn sdp_get_fmtp(attributes: *const Vec<SdpAttribute>, ret_size: size_t,
+                                                ret_fmtp: *mut RustSdpAttributeFmtp) -> size_t {
     let fmtps = (*attributes).iter().filter_map(|x| if let SdpAttribute::Fmtp(ref data) = *x {
         Some(data)
     } else {
         None
     });
     let mut rust_fmtps = Vec::new();
     for fmtp in fmtps {
         if let Some(rtpmap) = find_payload_type((*attributes).as_slice(), fmtp.payload_type) {
             rust_fmtps.push( RustSdpAttributeFmtp{
                 payload_type: fmtp.payload_type as u8,
                 codec_name: StringView::from(rtpmap.codec_name.as_str()),
-                tokens: &fmtp.tokens
-            }
+                parameters: RustSdpAttributeFmtpParameters::from(&fmtp.parameters),
+                }
             );
         }
     }
     let fmtps = if ret_size <= rust_fmtps.len() {
         slice::from_raw_parts_mut(ret_fmtp, ret_size)
     } else {
         slice::from_raw_parts_mut(ret_fmtp, rust_fmtps.len())
     };
--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs
@@ -52,18 +52,21 @@ pub unsafe extern "C" fn parse_sdp(sdp: 
             *error = ptr::null(); // TODO: Give more useful return value here
             debug!("Error converting string to utf8");
             return NS_ERROR_INVALID_ARG;
         }
     };
     let parser_result = rsdparsa::parse_sdp(sdp_str_slice, fail_on_warning);
     match parser_result {
         Ok(parsed) => {
+            *error = match parsed.warnings.len(){
+                0 => ptr::null(),
+                _ => Box::into_raw(Box::new(parsed.warnings[0].clone())),
+            };
             *session = Rc::into_raw(Rc::new(parsed));
-            *error = ptr::null();
             NS_OK
         },
         Err(e) => {
             *session = ptr::null();
             debug!("{:?}", e);
             debug!("Error parsing SDP in rust: {}", e.description());
             *error = Box::into_raw(Box::new(e));
             NS_ERROR_INVALID_ARG
--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/types.rs
+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/types.rs
@@ -1,9 +1,9 @@
-use libc::{size_t, uint32_t};
+use libc::{size_t, uint8_t, uint32_t};
 use std::ffi::CStr;
 use std::{str, slice};
 use std::error::Error;
 use std::boxed::Box;
 
 use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG};
 
 #[repr(C)]
@@ -88,8 +88,27 @@ pub unsafe extern "C" fn u32_vec_get(vec
     match (*vec).get(index) {
         Some(val) => {
             *ret = *val;
             NS_OK
         },
         None => NS_ERROR_INVALID_ARG
     }
 }
+
+
+#[no_mangle]
+pub unsafe extern "C" fn u8_vec_len(vec: *const Vec<u8>) -> size_t {
+    (*vec).len()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn u8_vec_get(vec: *const Vec<u8>,
+                                    index: size_t,
+                                    ret: *mut uint8_t) -> nsresult {
+    match (*vec).get(index) {
+        Some(val) => {
+            *ret = *val;
+            NS_OK
+        },
+        None => NS_ERROR_INVALID_ARG
+    }
+}
--- a/servo/components/style/gecko/arc_types.rs
+++ b/servo/components/style/gecko/arc_types.rs
@@ -4,22 +4,22 @@
 
 //! 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::RawServoCounterStyleRule;
-use gecko_bindings::bindings::RawServoDocumentRule;
 use gecko_bindings::bindings::RawServoFontFeatureValuesRule;
 use gecko_bindings::bindings::RawServoImportRule;
 use gecko_bindings::bindings::RawServoKeyframe;
 use gecko_bindings::bindings::RawServoKeyframesRule;
 use gecko_bindings::bindings::RawServoMediaRule;
+use gecko_bindings::bindings::RawServoMozDocumentRule;
 use gecko_bindings::bindings::RawServoNamespaceRule;
 use gecko_bindings::bindings::RawServoPageRule;
 use gecko_bindings::bindings::RawServoRuleNode;
 use gecko_bindings::bindings::RawServoRuleNodeStrong;
 use gecko_bindings::bindings::RawServoSupportsRule;
 use gecko_bindings::bindings::ServoCssRules;
 use gecko_bindings::structs::RawServoAnimationValue;
 use gecko_bindings::structs::RawServoDeclarationBlock;
@@ -93,17 +93,17 @@ impl_arc_ffi!(Locked<NamespaceRule> => R
               [Servo_NamespaceRule_AddRef, Servo_NamespaceRule_Release]);
 
 impl_arc_ffi!(Locked<PageRule> => RawServoPageRule
               [Servo_PageRule_AddRef, Servo_PageRule_Release]);
 
 impl_arc_ffi!(Locked<SupportsRule> => RawServoSupportsRule
               [Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]);
 
-impl_arc_ffi!(Locked<DocumentRule> => RawServoDocumentRule
+impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
               [Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]);
 
 impl_arc_ffi!(Locked<FontFeatureValuesRule> => RawServoFontFeatureValuesRule
               [Servo_FontFeatureValuesRule_AddRef, Servo_FontFeatureValuesRule_Release]);
 
 impl_arc_ffi!(Locked<FontFaceRule> => RawServoFontFaceRule
               [Servo_FontFaceRule_AddRef, Servo_FontFaceRule_Release]);
 
--- a/servo/components/style/gecko/conversions.rs
+++ b/servo/components/style/gecko/conversions.rs
@@ -4,17 +4,17 @@
 
 //! This module contains conversion helpers between Servo and Gecko types
 //! Ideally, it would be in geckolib itself, but coherence
 //! forces us to keep the traits and implementations here
 
 #![allow(unsafe_code)]
 
 use app_units::Au;
-use gecko::values::{convert_rgba_to_nscolor, GeckoStyleCoordConvertible};
+use gecko::values::GeckoStyleCoordConvertible;
 use gecko_bindings::bindings;
 use gecko_bindings::structs::{self, nsCSSUnit, nsStyleCoord_CalcValue};
 use gecko_bindings::structs::{nsresult, SheetType, nsStyleImage};
 use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue};
 use std::f32::consts::PI;
 use stylesheets::{Origin, RulesMutateError};
 use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image};
 use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto};
@@ -353,17 +353,17 @@ impl nsStyleImage {
             // NB: stops are guaranteed to be none in the gecko side by
             // default.
 
             let gecko_stop = unsafe { &mut (*gecko_gradient).mStops[index] };
             let mut coord = nsStyleCoord::null();
 
             match *item {
                 GradientItem::ColorStop(ref stop) => {
-                    gecko_stop.mColor = convert_rgba_to_nscolor(&stop.color);
+                    gecko_stop.mColor = stop.color.into();
                     gecko_stop.mIsInterpolationHint = false;
                     coord.set(stop.position);
                 },
                 GradientItem::InterpolationHint(hint) => {
                     gecko_stop.mIsInterpolationHint = true;
                     coord.set(Some(hint));
                 },
             }
@@ -428,17 +428,16 @@ impl nsStyleImage {
 
     unsafe fn get_image_url(&self) -> ComputedImageUrl {
         let image_request = bindings::Gecko_GetImageRequest(self)
             .as_ref().expect("Null image request?");
         ComputedImageUrl::from_image_request(image_request)
     }
 
     unsafe fn get_gradient(self: &nsStyleImage) -> Box<Gradient> {
-        use gecko::values::convert_nscolor_to_rgba;
         use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER;
         use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE;
         use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER;
         use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE;
         use values::computed::{Length, LengthOrPercentage};
         use values::computed::image::LineDirection;
         use values::computed::position::Position;
         use values::generics::image::{Circle, ColorStop, CompatMode, Ellipse};
@@ -596,17 +595,17 @@ impl nsStyleImage {
             .map(|ref stop| {
                 if stop.mIsInterpolationHint {
                     GradientItem::InterpolationHint(
                         LengthOrPercentage::from_gecko_style_coord(&stop.mLocation)
                             .expect("mLocation could not convert to LengthOrPercentage"),
                     )
                 } else {
                     GradientItem::ColorStop(ColorStop {
-                        color: convert_nscolor_to_rgba(stop.mColor),
+                        color: stop.mColor.into(),
                         position: LengthOrPercentage::from_gecko_style_coord(&stop.mLocation),
                     })
                 }
             })
             .collect();
 
         let compat_mode = if gecko_gradient.mMozLegacySyntax {
             CompatMode::Moz
--- a/servo/components/style/values/computed/image.rs
+++ b/servo/components/style/values/computed/image.rs
@@ -2,22 +2,21 @@
  * 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/. */
 
 //! CSS handling for the computed value of
 //! [`image`][image]s
 //!
 //! [image]: https://drafts.csswg.org/css-images/#image-values
 
-use cssparser::RGBA;
 use std::f32::consts::PI;
 use std::fmt::{self, Write};
 use style_traits::{CssWriter, ToCss};
 use values::{Either, None_};
-use values::computed::{Angle, Context};
+use values::computed::{Angle, Color, Context};
 use values::computed::{Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue};
 #[cfg(feature = "gecko")]
 use values::computed::Percentage;
 use values::computed::position::Position;
 use values::computed::url::ComputedImageUrl;
 use values::generics::image::{self as generic, CompatMode};
 use values::specified::image::LineDirection as SpecifiedLineDirection;
 use values::specified::position::{X, Y};
@@ -27,17 +26,17 @@ pub type ImageLayer = Either<None_, Imag
 
 /// Computed values for an image according to CSS-IMAGES.
 /// <https://drafts.csswg.org/css-images/#image-values>
 pub type Image = generic::Image<Gradient, MozImageRect, ComputedImageUrl>;
 
 /// Computed values for a CSS gradient.
 /// <https://drafts.csswg.org/css-images/#gradients>
 pub type Gradient =
-    generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, RGBA, Angle>;
+    generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, Color, Angle>;
 
 /// A computed gradient kind.
 pub type GradientKind =
     generic::GradientKind<LineDirection, Length, LengthOrPercentage, Position, Angle>;
 
 /// A computed gradient line direction.
 #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
 pub enum LineDirection {
@@ -53,20 +52,20 @@ pub enum LineDirection {
     #[cfg(feature = "gecko")]
     MozPosition(Option<Position>, Option<Angle>),
 }
 
 /// A computed radial gradient ending shape.
 pub type EndingShape = generic::EndingShape<Length, LengthOrPercentage>;
 
 /// A computed gradient item.
-pub type GradientItem = generic::GradientItem<RGBA, LengthOrPercentage>;
+pub type GradientItem = generic::GradientItem<Color, LengthOrPercentage>;
 
 /// A computed color stop.
-pub type ColorStop = generic::ColorStop<RGBA, LengthOrPercentage>;
+pub type ColorStop = generic::ColorStop<Color, LengthOrPercentage>;
 
 /// Computed values for `-moz-image-rect(...)`.
 pub type MozImageRect = generic::MozImageRect<NumberOrPercentage, ComputedImageUrl>;
 
 impl generic::LineDirection for LineDirection {
     fn points_downwards(&self, compat_mode: CompatMode) -> bool {
         match *self {
             LineDirection::Angle(angle) => angle.radians() == PI,
--- a/servo/components/style/values/specified/image.rs
+++ b/servo/components/style/values/specified/image.rs
@@ -21,44 +21,38 @@ use style_traits::{CssType, CssWriter, K
 use style_traits::{StyleParseErrorKind, SpecifiedValueInfo, ToCss};
 use values::{Either, None_};
 #[cfg(feature = "gecko")]
 use values::computed::{Context, Position as ComputedPosition, ToComputedValue};
 use values::generics::image::{self as generic, Circle, CompatMode, Ellipse, ShapeExtent};
 use values::generics::image::PaintWorklet;
 use values::generics::position::Position as GenericPosition;
 use values::specified::{Angle, Color, Length, LengthOrPercentage};
-use values::specified::{Number, NumberOrPercentage, Percentage, RGBAColor};
+use values::specified::{Number, NumberOrPercentage, Percentage};
 use values::specified::position::{LegacyPosition, Position, PositionComponent, Side, X, Y};
 use values::specified::url::SpecifiedImageUrl;
 
 /// A specified image layer.
 pub type ImageLayer = Either<None_, Image>;
 
 /// Specified values for an image according to CSS-IMAGES.
 /// <https://drafts.csswg.org/css-images/#image-values>
 pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>;
 
 /// Specified values for a CSS gradient.
 /// <https://drafts.csswg.org/css-images/#gradients>
 #[cfg(not(feature = "gecko"))]
 pub type Gradient =
-    generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, RGBAColor, Angle>;
+    generic::Gradient<LineDirection, Length, LengthOrPercentage, Position, Color, Angle>;
 
 /// Specified values for a CSS gradient.
 /// <https://drafts.csswg.org/css-images/#gradients>
 #[cfg(feature = "gecko")]
-pub type Gradient = generic::Gradient<
-    LineDirection,
-    Length,
-    LengthOrPercentage,
-    GradientPosition,
-    RGBAColor,
-    Angle,
->;
+pub type Gradient =
+    generic::Gradient<LineDirection, Length, LengthOrPercentage, GradientPosition, Color, Angle>;
 
 impl SpecifiedValueInfo for Gradient {
     const SUPPORTED_TYPES: u8 = CssType::GRADIENT;
 
     fn collect_completion_keywords(f: KeywordsCollectFn) {
         // This list here should keep sync with that in Gradient::parse.
         f(&[
           "linear-gradient",
@@ -116,20 +110,20 @@ pub enum GradientPosition {
     /// 1, 2-valued <position>.
     Legacy(LegacyPosition),
 }
 
 /// A specified ending shape.
 pub type EndingShape = generic::EndingShape<Length, LengthOrPercentage>;
 
 /// A specified gradient item.
-pub type GradientItem = generic::GradientItem<RGBAColor, LengthOrPercentage>;
+pub type GradientItem = generic::GradientItem<Color, LengthOrPercentage>;
 
 /// A computed color stop.
-pub type ColorStop = generic::ColorStop<RGBAColor, LengthOrPercentage>;
+pub type ColorStop = generic::ColorStop<Color, LengthOrPercentage>;
 
 /// Specified values for `moz-image-rect`
 /// -moz-image-rect(<uri>, top, right, bottom, left);
 pub type MozImageRect = generic::MozImageRect<NumberOrPercentage, SpecifiedImageUrl>;
 
 impl Parse for Image {
     fn parse<'i, 't>(
         context: &ParserContext,
@@ -952,17 +946,17 @@ impl GradientItem {
 }
 
 impl Parse for ColorStop {
     fn parse<'i, 't>(
         context: &ParserContext,
         input: &mut Parser<'i, 't>,
     ) -> Result<Self, ParseError<'i>> {
         Ok(ColorStop {
-            color: RGBAColor::parse(context, input)?,
+            color: Color::parse(context, input)?,
             position: input.try(|i| LengthOrPercentage::parse(context, i)).ok(),
         })
     }
 }
 
 impl Parse for PaintWorklet {
     fn parse<'i, 't>(
         _context: &ParserContext,
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -36,24 +36,24 @@ use style::gecko::traversal::RecalcStyle
 use style::gecko::wrapper::{GeckoElement, GeckoNode};
 use style::gecko_bindings::bindings;
 use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoElementBorrowedOrNull, RawGeckoNodeBorrowed};
 use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut};
 use style::gecko_bindings::bindings::{RawServoAuthorStyles, RawServoAuthorStylesBorrowed};
 use style::gecko_bindings::bindings::{RawServoAuthorStylesBorrowedMut, RawServoAuthorStylesOwned};
 use style::gecko_bindings::bindings::{RawServoCounterStyleRule, RawServoCounterStyleRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
-use style::gecko_bindings::bindings::{RawServoDocumentRule, RawServoDocumentRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoFontFaceRuleBorrowed, RawServoFontFaceRuleStrong};
 use style::gecko_bindings::bindings::{RawServoFontFeatureValuesRule, RawServoFontFeatureValuesRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoImportRule, RawServoImportRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
 use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoMediaListBorrowed, RawServoMediaListStrong};
 use style::gecko_bindings::bindings::{RawServoMediaRule, RawServoMediaRuleBorrowed};
+use style::gecko_bindings::bindings::{RawServoMozDocumentRule, RawServoMozDocumentRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoNamespaceRule, RawServoNamespaceRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoPageRule, RawServoPageRuleBorrowed};
 use style::gecko_bindings::bindings::{RawServoSelectorListBorrowed, RawServoSelectorListOwned};
 use style::gecko_bindings::bindings::{RawServoSourceSizeListBorrowedOrNull, RawServoSourceSizeListOwned};
 use style::gecko_bindings::bindings::{RawServoStyleSetBorrowed, RawServoStyleSetBorrowedOrNull, RawServoStyleSetOwned};
 use style::gecko_bindings::bindings::{RawServoStyleSheetContentsBorrowed, ServoComputedDataBorrowed};
 use style::gecko_bindings::bindings::{RawServoStyleSheetContentsStrong, ComputedStyleBorrowed};
 use style::gecko_bindings::bindings::{RawServoSupportsRule, RawServoSupportsRuleBorrowed};
@@ -1835,21 +1835,21 @@ impl_basic_rule_funcs! { (Page, PageRule
 
 impl_group_rule_funcs! { (Supports, SupportsRule, RawServoSupportsRule),
     get_rules: Servo_SupportsRule_GetRules,
     getter: Servo_CssRules_GetSupportsRuleAt,
     debug: Servo_SupportsRule_Debug,
     to_css: Servo_SupportsRule_GetCssText,
 }
 
-impl_group_rule_funcs! { (Document, DocumentRule, RawServoDocumentRule),
-    get_rules: Servo_DocumentRule_GetRules,
-    getter: Servo_CssRules_GetDocumentRuleAt,
-    debug: Servo_DocumentRule_Debug,
-    to_css: Servo_DocumentRule_GetCssText,
+impl_group_rule_funcs! { (Document, DocumentRule, RawServoMozDocumentRule),
+    get_rules: Servo_MozDocumentRule_GetRules,
+    getter: Servo_CssRules_GetMozDocumentRuleAt,
+    debug: Servo_MozDocumentRule_Debug,
+    to_css: Servo_MozDocumentRule_GetCssText,
 }
 
 impl_basic_rule_funcs! { (FontFeatureValues, FontFeatureValuesRule, RawServoFontFeatureValuesRule),
     getter: Servo_CssRules_GetFontFeatureValuesRuleAt,
     debug: Servo_FontFeatureValuesRule_Debug,
     to_css: Servo_FontFeatureValuesRule_GetCssText,
 }
 
@@ -2288,18 +2288,18 @@ pub extern "C" fn Servo_SupportsRule_Get
     result: *mut nsAString,
 ) {
     read_locked_arc(rule, |rule: &SupportsRule| {
         rule.condition.to_css(&mut CssWriter::new(unsafe { result.as_mut().unwrap() })).unwrap();
     })
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_DocumentRule_GetConditionText(
-    rule: RawServoDocumentRuleBorrowed,
+pub extern "C" fn Servo_MozDocumentRule_GetConditionText(
+    rule: RawServoMozDocumentRuleBorrowed,
     result: *mut nsAString,
 ) {
     read_locked_arc(rule, |rule: &DocumentRule| {
         rule.condition.to_css(&mut CssWriter::new(unsafe { result.as_mut().unwrap() })).unwrap();
     })
 }
 
 #[no_mangle]
--- a/taskcluster/ci/build/linux.yml
+++ b/taskcluster/ci/build/linux.yml
@@ -537,17 +537,17 @@ linux64-asan/opt:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: asan-tc
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-6
+        - linux64-clang
         - linux64-gcc
         - linux64-rust
         - linux64-sccache
 
 
 linux64-asan-fuzzing/opt:
     description: "Linux64 Fuzzing Opt ASAN"
     index:
@@ -568,17 +568,17 @@ linux64-asan-fuzzing/opt:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: fuzzing-asan-tc
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-6
+        - linux64-clang
         - linux64-gcc
         - linux64-rust
         - linux64-sccache
 
 linux64-asan-reporter-nightly/opt:
     description: "Linux64 Opt ASAN Reporter Nightly"
     attributes:
         nightly: true
@@ -602,17 +602,17 @@ linux64-asan-reporter-nightly/opt:
             - builds/releng_base_linux_64_builds.py
             - taskcluster_nightly.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: asan-reporter-tc
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-6
+        - linux64-clang
         - linux64-gcc
         - linux64-rust
         - linux64-sccache
 
 linux64-asan/debug:
     description: "Linux64 Debug ASAN"
     index:
         product: firefox
@@ -632,17 +632,17 @@ linux64-asan/debug:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: asan-tc-and-debug
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-6
+        - linux64-clang
         - linux64-gcc
         - linux64-rust
         - linux64-sccache
 
 linux64-lto/opt:
     description: "Linux64 Opt LTO"
     index:
         product: firefox
@@ -663,17 +663,17 @@ linux64-lto/opt:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: lto-tc
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-6
+        - linux64-clang
         - linux64-gcc
         - linux64-rust
         - linux64-sccache
 
 linux64-lto/debug:
     description: "Linux64 Debug LTO"
     index:
         product: firefox
@@ -694,17 +694,17 @@ linux64-lto/debug:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: lto-tc-and-debug
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-6
+        - linux64-clang
         - linux64-gcc
         - linux64-rust
         - linux64-sccache
 
 linux64-nightly/opt:
     description: "Linux64 Nightly"
     attributes:
         nightly: true
@@ -915,17 +915,17 @@ linux64-ccov/debug:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: code-coverage-debug
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-4
+        - linux64-clang
         - linux64-rust
         - linux64-gcc
 
 linux64-ccov/opt:
     description: "Linux64-CCov Opt"
     index:
         product: firefox
         job-name: linux64-ccov-opt
@@ -944,17 +944,17 @@ linux64-ccov/opt:
             - builds/releng_base_firefox.py
             - builds/releng_base_linux_64_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: code-coverage-opt
         tooltool-downloads: public
         need-xvfb: true
     toolchains:
-        - linux64-clang-4
+        - linux64-clang
         - linux64-rust
         - linux64-gcc
 
 linux64-add-on-devel/opt:
     description: "Linux64 add-on-devel"
     index:
         product: firefox
         job-name: linux64-add-on-devel
--- a/taskcluster/ci/build/macosx.yml
+++ b/taskcluster/ci/build/macosx.yml
@@ -84,17 +84,17 @@ macosx64-asan-fuzzing/opt:
             - builds/releng_base_firefox.py
             - builds/releng_base_mac_64_cross_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: cross-fuzzing-asan
         tooltool-downloads: internal
     toolchains:
         - linux64-cctools-port
-        - linux64-clang-6-macosx-cross
+        - linux64-clang-macosx-cross
         - linux64-hfsplus
         - linux64-libdmg
         - linux64-llvm-dsymutil
         - linux64-rust-macos
         - linux64-sccache
 
 macosx64-dmd/opt:
     description: "MacOS X x64 DMD Cross-compile"
@@ -300,14 +300,14 @@ macosx64-ccov/debug:
             - builds/releng_base_mac_64_cross_builds.py
         script: "mozharness/scripts/fx_desktop_build.py"
         secrets: true
         custom-build-variant-cfg: code-coverage-debug
         tooltool-downloads: internal
     run-on-projects: ['try']
     toolchains:
         - linux64-cctools-port
-        - linux64-clang-6-macosx-cross
+        - linux64-clang-macosx-cross
         - linux64-hfsplus
         - linux64-libdmg
         - linux64-llvm-dsymutil
         - linux64-rust-macos
         - linux64-sccache
--- a/taskcluster/ci/spidermonkey/linux.yml
+++ b/taskcluster/ci/spidermonkey/linux.yml
@@ -133,16 +133,18 @@ sm-tsan-linux64/opt:
     description: "Spidermonkey Thread Sanitizer"
     index:
         job-name: sm-tsan-linux64-opt
     treeherder:
         symbol: SM(tsan)
         platform: linux64/opt
     run:
         spidermonkey-variant: tsan
+    toolchains:
+        - linux64-clang-5
 
 sm-rootanalysis-linux64/debug:
     description: "Spidermonkey Root Analysis"
     index:
         job-name: sm-rootanalysis-linux64-debug
     treeherder:
         platform: linux64/debug
         symbol: SM(r)
@@ -163,12 +165,8 @@ sm-fuzzing-linux64/opt:
     description: "Spidermonkey Fuzzing"
     index:
         job-name: sm-fuzzing-linux64
     treeherder:
         platform: linux64/opt
         symbol: SM(f)
     run:
         spidermonkey-variant: fuzzing
-    toolchains:
-        - linux64-clang-6
-        - linux64-gcc
-        - linux64-rust
--- a/taskcluster/ci/test/web-platform.yml
+++ b/taskcluster/ci/test/web-platform.yml
@@ -26,17 +26,20 @@ web-platform-tests:
     max-run-time:
         by-test-platform:
             windows10-64-ccov/debug: 10800
             default: 7200
     e10s:
         by-test-platform:
             linux32/debug: both
             default: true
-    run-on-projects: built-projects
+    run-on-projects:
+        by-test-platform:
+            linux64-qr/.*: ['release', 'try']
+            default: built-projects
     mozharness:
         chunked: true
         extra-options:
             - --test-type=testharness
 
 web-platform-tests-headless:
     description: "Web platform test headless run"
     suite: web-platform-tests
@@ -73,17 +76,20 @@ web-platform-tests-reftests:
         by-test-platform:
             macosx.*: 1
             windows.*: 1
             default: 6
     e10s:
         by-test-platform:
             linux32/debug: both
             default: true
-    run-on-projects: built-projects
+    run-on-projects:
+        by-test-platform:
+            linux64-qr/.*: ['release', 'try']
+            default: built-projects
     mozharness:
         extra-options:
             - --test-type=reftest
 
 web-platform-tests-reftests-headless:
     description: "Web platform reftest headless run"
     suite: web-platform-tests-reftests
     treeherder-symbol: W(WrH)
@@ -110,17 +116,20 @@ web-platform-tests-reftests-headless:
 
 web-platform-tests-wdspec:
     description: "Web platform webdriver-spec run"
     suite: web-platform-tests-wdspec
     treeherder-symbol: W(Wd)
     mozharness:
         extra-options:
             - --test-type=wdspec
-    run-on-projects: built-projects
+    run-on-projects:
+        by-test-platform:
+            linux64-qr/.*: ['release', 'try']
+            default: built-projects
 
 web-platform-tests-wdspec-headless:
     description: "Web platform webdriver-spec headless run"
     suite: web-platform-tests-wdspec
     treeherder-symbol: W(WdH)
     run-on-projects: []  # disabled pending releng approval
     mozharness:
         extra-options:
--- a/taskcluster/ci/toolchain/linux.yml
+++ b/taskcluster/ci/toolchain/linux.yml
@@ -22,37 +22,16 @@ linux64-clang-3.9:
         resources:
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-3.9-linux64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
     toolchains:
         - linux64-gcc-4.9
 
-linux64-clang-4:
-    description: "Clang 4 toolchain build"
-    treeherder:
-        kind: build
-        platform: toolchains/opt
-        symbol: TL(clang4)
-        tier: 1
-    worker-type: aws-provisioner-v1/gecko-{level}-b-linux-large
-    worker:
-        max-run-time: 7200
-    run:
-        using: toolchain-script
-        script: build-clang-4-linux.sh
-        resources:
-            - 'build/build-clang/build-clang.py'
-            - 'build/build-clang/clang-4-linux64.json'
-            - 'taskcluster/scripts/misc/tooltool-download.sh'
-        toolchain-artifact: public/build/clang.tar.xz
-    toolchains:
-        - linux64-gcc-4.9
-
 linux64-clang-5:
     description: "Clang 5 toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(clang5)
         tier: 1
     worker-type: aws-provisioner-v1/gecko-{level}-b-linux-xlarge
@@ -60,17 +39,16 @@ linux64-clang-5:
         max-run-time: 7200
     run:
         using: toolchain-script
         script: build-clang-5-linux.sh
         resources:
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-5-linux64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
-        toolchain-alias: linux64-clang
         toolchain-artifact: public/build/clang.tar.xz
     toolchains:
         - linux64-gcc-4.9
 
 linux64-clang-6:
     description: "Clang 6 toolchain build"
     treeherder:
         kind: build
@@ -82,16 +60,17 @@ linux64-clang-6:
         max-run-time: 7200
     run:
         using: toolchain-script
         script: build-clang-6-linux.sh
         resources:
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-6-linux64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
+        toolchain-alias: linux64-clang
         toolchain-artifact: public/build/clang.tar.xz
     toolchains:
         - linux64-gcc-4.9
 
 linux64-clang-6-macosx-cross:
     description: "Clang 6 toolchain build with MacOS Compiler RT libs"
     treeherder:
         kind: build
@@ -105,16 +84,17 @@ linux64-clang-6-macosx-cross:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-clang.manifest"
     run:
         using: toolchain-script
         script: build-clang-6-linux-macosx-cross.sh
         resources:
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-6-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
+        toolchain-alias: linux64-clang-macosx-cross
         toolchain-artifact: public/build/clang.tar.xz
         tooltool-downloads: internal
     toolchains:
         - linux64-cctools-port
         - linux64-clang-6
         - linux64-gcc-4.9
 
 linux64-clang-tidy:
@@ -292,17 +272,17 @@ linux64-cctools-port:
         max-run-time: 36000
     run:
         using: toolchain-script
         script: build-cctools-port.sh
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/cctools.tar.xz
     toolchains:
-        - linux64-clang-3.9
+        - linux64-clang-6
 
 linux64-hfsplus:
     description: "hfsplus toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(hfs+)
         tier: 1
@@ -312,17 +292,17 @@ linux64-hfsplus:
     run:
         using: toolchain-script
         script: build-hfsplus-linux.sh
         resources:
             - 'build/unix/build-hfsplus/build-hfsplus.sh'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/hfsplus-tools.tar.xz
     toolchains:
-        - linux64-clang-3.9
+        - linux64-clang-6
 
 linux64-libdmg:
     description: "libdmg-hfsplus toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TL(libdmg-hfs+)
         tier: 1
--- a/taskcluster/ci/toolchain/macosx.yml
+++ b/taskcluster/ci/toolchain/macosx.yml
@@ -22,22 +22,22 @@ macosx64-clang:
         env:
             TOOLTOOL_MANIFEST: "browser/config/tooltool-manifests/macosx64/cross-clang.manifest"
     run:
         using: toolchain-script
         script: build-clang-macosx.sh
         tooltool-downloads: internal
         resources:
             - 'build/build-clang/build-clang.py'
-            - 'build/build-clang/clang-macosx64.json'
+            - 'build/build-clang/clang-6-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang.tar.xz
     toolchains:
         - linux64-cctools-port
-        - linux64-clang-3.9
+        - linux64-clang-6
         - linux64-gcc-4.9
 
 macosx64-clang-tidy:
     description: "Clang-tidy build"
     index:
         product: static-analysis
         job-name: macosx64-clang-tidy
     treeherder:
@@ -57,17 +57,17 @@ macosx64-clang-tidy:
         resources:
             - 'build/clang-plugin/**'
             - 'build/build-clang/build-clang.py'
             - 'build/build-clang/clang-tidy-macosx64.json'
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/clang-tidy.tar.xz
     toolchains:
         - linux64-cctools-port
-        - linux64-clang-3.9
+        - linux64-clang-6
         - linux64-gcc-4.9
 
 macosx64-cctools-port:
     description: "cctools-port toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TM(cctools)
@@ -81,17 +81,17 @@ macosx64-cctools-port:
         using: toolchain-script
         script: build-cctools-port-macosx.sh
         tooltool-downloads: internal
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
         toolchain-artifact: public/build/cctools.tar.bz2
     toolchains:
         - linux64-cctools-port
-        - linux64-clang-3.9
+        - linux64-clang-6
 
 macosx64-gn:
     description: "gn toolchain build"
     treeherder:
         kind: build
         platform: toolchains/opt
         symbol: TM(gn)
         tier: 1
@@ -105,9 +105,9 @@ macosx64-gn:
         script: build-gn-macosx.sh
         tooltool-downloads: internal
         resources:
             - 'taskcluster/scripts/misc/tooltool-download.sh'
             - 'taskcluster/scripts/misc/build-gn-common.sh'
         toolchain-artifact: public/build/gn.tar.xz
     toolchains:
         - linux64-cctools-port
-        - linux64-clang-3.9
+        - linux64-clang-6
deleted file mode 100755
--- a/taskcluster/scripts/misc/build-clang-4-linux.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-set -x -e -v
-
-# This script is for building clang for Linux.
-
-WORKSPACE=$HOME/workspace
-HOME_DIR=$WORKSPACE/build
-UPLOAD_DIR=$HOME/artifacts
-
-cd $HOME_DIR/src
-
-. taskcluster/scripts/misc/tooltool-download.sh
-
-# gets a bit too verbose here
-set +x
-
-cd build/build-clang
-# |mach python| sets up a virtualenv for us!
-../../mach python ./build-clang.py -c clang-4-linux64.json
-
-set -x
-
-# Put a tarball in the artifacts dir
-mkdir -p $UPLOAD_DIR
-cp clang.tar.* $UPLOAD_DIR
--- a/taskcluster/scripts/misc/build-clang-macosx.sh
+++ b/taskcluster/scripts/misc/build-clang-macosx.sh
@@ -19,15 +19,15 @@ export CROSS_SYSROOT=$HOME_DIR/src/MacOS
 export PATH=$PATH:$CROSS_CCTOOLS_PATH/bin
 ln -sf $CROSS_CCTOOLS_PATH/bin/x86_64-apple-darwin11-lipo $CROSS_CCTOOLS_PATH/bin/lipo
 
 # gets a bit too verbose here
 set +x
 
 cd build/build-clang
 # |mach python| sets up a virtualenv for us!
-../../mach python ./build-clang.py -c clang-macosx64.json
+../../mach python ./build-clang.py -c clang-6-macosx64.json
 
 set -x
 
 # Put a tarball in the artifacts dir
 mkdir -p $UPLOAD_DIR
 cp clang.tar.* $UPLOAD_DIR
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -263,17 +263,17 @@ const RECOMMENDED_PREFS = new Map([
   // Prevent starting into safe mode after application crashes
   ["toolkit.startup.max_resumed_crashes", -1],
 
 ]);
 
 const isRemote = Services.appinfo.processType ==
     Services.appinfo.PROCESS_TYPE_CONTENT;
 
-class MarionetteMainProcess {
+class MarionetteParentProcess {
   constructor() {
     this.server = null;
 
     // holds reference to ChromeWindow
     // used to run GFX sanity tests on Windows
     this.gfxWindow = null;
 
     // indicates that all pending window checks have been completed
@@ -303,28 +303,28 @@ class MarionetteMainProcess {
   }
 
   receiveMessage({name}) {
     switch (name) {
       case "Marionette:IsRunning":
         return this.running;
 
       default:
-        log.warn("Unknown IPC message to main process: " + name);
+        log.warn("Unknown IPC message to parent process: " + name);
         return null;
     }
   }
 
   observe(subject, topic) {
     log.debug(`Received observer notification ${topic}`);
 
     switch (topic) {
       case "nsPref:changed":
         if (this.enabled) {
-          this.init();
+          this.init(false);
         } else {
           this.uninit();
         }
         break;
 
       case "profile-after-change":
         Services.obs.addObserver(this, "command-line-startup");
         Services.obs.addObserver(this, "sessionstore-windows-restored");
@@ -408,17 +408,17 @@ class MarionetteMainProcess {
         log.debug("Safe mode detected, supressing dialog");
         win.setTimeout(() => {
           win.document.documentElement.getButton("accept").click();
         });
       }
     }, {once: true});
   }
 
-  init() {
+  init(quit = true) {
     if (this.running || !this.enabled || !this.finalUIStartup) {
       log.debug(`Init aborted (running=${this.running}, ` +
                 `enabled=${this.enabled}, finalUIStartup=${this.finalUIStartup})`);
       return;
     }
 
     log.debug(`Waiting for delayed startup...`);
     Services.tm.idleDispatchToMainThread(async () => {
@@ -443,17 +443,19 @@ class MarionetteMainProcess {
       try {
         const {TCPListener} = ChromeUtils.import("chrome://marionette/content/server.js", {});
         let listener = new TCPListener(MarionettePrefs.port);
         listener.start();
         this.server = listener;
       } catch (e) {
         log.fatal("Remote protocol server failed to start", e);
         this.uninit();
-        Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
+        if (quit) {
+          Services.startup.quit(Ci.nsIAppStartup.eForceQuit);
+        }
         return;
       }
 
       env.set(ENV_ENABLED, "1");
       Services.obs.notifyObservers(this, NOTIFY_RUNNING, true);
       log.debug("Remote service is active");
     });
   }
@@ -480,17 +482,17 @@ class MarionetteMainProcess {
     ]);
   }
 }
 
 class MarionetteContentProcess {
   get running() {
     let reply = Services.cpmm.sendSyncMessage("Marionette:IsRunning");
     if (reply.length == 0) {
-      log.warn("No reply from main process");
+      log.warn("No reply from parent process");
       return false;
     }
     return reply[0];
   }
 
   get QueryInterface() {
     return ChromeUtils.generateQI([Ci.nsIMarionette]);
   }
@@ -503,17 +505,17 @@ const MarionetteFactory = {
     if (outer) {
       throw Cr.NS_ERROR_NO_AGGREGATION;
     }
 
     if (!this.instance_) {
       if (isRemote) {
         this.instance_ = new MarionetteContentProcess();
       } else {
-        this.instance_ = new MarionetteMainProcess();
+        this.instance_ = new MarionetteParentProcess();
       }
     }
 
     return this.instance_.QueryInterface(iid);
   },
 };
 
 function Marionette() {}
--- a/testing/marionette/listener.js
+++ b/testing/marionette/listener.js
@@ -74,17 +74,17 @@ Object.defineProperty(this, "capabilitie
 });
 
 let legacyactions = new legacyaction.Chain();
 
 // last touch for each fingerId
 let multiLast = {};
 
 // TODO: Log.jsm is not e10s compatible (see https://bugzil.la/1411513),
-// query the main process for the current log level
+// query the parent process for the current log level
 const logger = Log.repository.getLogger("Marionette");
 if (logger.ownAppenders.length == 0) {
   let log = Services.cpmm.initialProcessData["Marionette:Log"];
   logger.level = log.level;
   logger.addAppender(new Log.DumpAppender());
 }
 
 // sandbox storage and name of the current sandbox