Merge autoland to central, a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 17 Mar 2017 10:59:49 -0700
changeset 500856 85ead1312fe6ca35789595f455788b599f599c9f
parent 500751 b7ba1d2827750be9bc599ca5365aa350ae3995d3 (current diff)
parent 500855 0d33d81b075fc1cdc2c497efdd43346b89864604 (diff)
child 500857 23a4b7430dd7e83a2809bf3dc41471f154301eda
push id49816
push userbmo:tchiovoloni@mozilla.com
push dateFri, 17 Mar 2017 20:44:02 +0000
reviewersmerge
milestone55.0a1
Merge autoland to central, a=merge MozReview-Commit-ID: EtI9SIdmuhQ
browser/themes/shared/undoCloseTab.png
browser/themes/shared/undoCloseTab@2x.png
dom/animation/AnimationRule.h
dom/animation/ServoAnimationRule.cpp
dom/animation/ServoAnimationRule.h
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -612,17 +612,16 @@
                      class="toolbarbutton-1 chromeclass-toolbar-additional tabs-alltabs-button"
                      type="menu"
                      label="&listAllTabs.label;"
                      tooltiptext="&listAllTabs.label;"
                      removable="false">
         <menupopup id="alltabs-popup"
                    position="after_end">
           <menuitem id="alltabs_undoCloseTab"
-                    class="menuitem-iconic"
                     key="key_undoCloseTab"
                     label="&undoCloseTab.label;"
                     observes="History:UndoCloseTab"/>
           <menuseparator id="alltabs-popup-separator-1"/>
           <menu id="alltabs_containersTab"
                 label="&newUserContext.label;">
             <menupopup id="alltabs_containersMenuTab" />
           </menu>
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -533,21 +533,16 @@ menuitem.bookmark-item {
   transition-delay: 100s;
 }
 
 @conditionalForwardWithUrlbar@:not(:hover) > #forward-button[disabled] {
   /* when not hovered anymore, trigger a new transition to hide the forward button immediately */
   margin-left: calc(-0.01px - var(--forwardbutton-width) - var(--backbutton-urlbar-overlap));
 }
 
-/* undo close tab menu item */
-#alltabs_undoCloseTab {
-  list-style-image: url(chrome://browser/skin/undoCloseTab.png);
-}
-
 .unified-nav-back[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu") !important;
 }
 .unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
   list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu") !important;
 }
 .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu") !important;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1350,30 +1350,16 @@ toolbar .toolbarbutton-1 > .toolbarbutto
   list-style-image: url("chrome://browser/skin/menu-back.png") !important;
 }
 
 .unified-nav-forward[_moz-menuactive]:-moz-locale-dir(ltr),
 .unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
 }
 
-/* undo close tab menu item */
-#alltabs_undoCloseTab {
-  list-style-image: url(chrome://browser/skin/undoCloseTab.png);
-}
-
-@media (min-resolution: 2dppx) {
-  #alltabs_undoCloseTab {
-    list-style-image: url(chrome://browser/skin/undoCloseTab@2x.png);
-  }
-  #alltabs_undoCloseTab > .toolbarbutton-icon {
-    width: 16px;
-  }
-}
-
 #cut-button {
   margin-inline-end: 0;
 }
 
 #edit-controls[cui-areatype="toolbar"] > #cut-button {
   border-inline-end: 0;
 }
 
--- a/browser/themes/shared/jar.inc.mn
+++ b/browser/themes/shared/jar.inc.mn
@@ -105,18 +105,16 @@
   skin/classic/browser/tabbrowser/tab-audio.svg                (../shared/tabbrowser/tab-audio.svg)
   skin/classic/browser/tabbrowser/tab-audio-small.svg          (../shared/tabbrowser/tab-audio-small.svg)
   skin/classic/browser/tabbrowser/tab-overflow-indicator.png   (../shared/tabbrowser/tab-overflow-indicator.png)
   skin/classic/browser/toolbarbutton-dropdown-arrow.png        (../shared/toolbarbutton-dropdown-arrow.png)
   skin/classic/browser/translating-16.png                      (../shared/translation/translating-16.png)
   skin/classic/browser/translating-16@2x.png                   (../shared/translation/translating-16@2x.png)
   skin/classic/browser/translation-16.png                      (../shared/translation/translation-16.png)
   skin/classic/browser/translation-16@2x.png                   (../shared/translation/translation-16@2x.png)
-  skin/classic/browser/undoCloseTab.png                        (../shared/undoCloseTab.png)
-  skin/classic/browser/undoCloseTab@2x.png                     (../shared/undoCloseTab@2x.png)
   skin/classic/browser/update-badge.svg                        (../shared/update-badge.svg)
   skin/classic/browser/update-badge-failed.svg                 (../shared/update-badge-failed.svg)
   skin/classic/browser/warning.svg                             (../shared/warning.svg)
   skin/classic/browser/warning-white.svg                       (../shared/warning-white.svg)
   skin/classic/browser/cert-error.svg                          (../shared/incontent-icons/cert-error.svg)
   skin/classic/browser/wifi.svg                                (../shared/incontent-icons/wifi.svg)
   skin/classic/browser/session-restore.svg                     (../shared/incontent-icons/session-restore.svg)
   skin/classic/browser/tab-crashed.svg                         (../shared/incontent-icons/tab-crashed.svg)
deleted file mode 100644
index 1d629c82c5818662686be1164bdc8965684b0964..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 4854c5681dafc13817511d3c5dbe343dab332810..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -916,30 +916,16 @@ toolbar[brighttext] .toolbarbutton-1 > .
   list-style-image: url("chrome://browser/skin/menu-back.png") !important;
 }
 
 .unified-nav-forward[_moz-menuactive]:-moz-locale-dir(ltr),
 .unified-nav-back[_moz-menuactive]:-moz-locale-dir(rtl) {
   list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
 }
 
-/* undo close tab menu item */
-#alltabs_undoCloseTab {
-  list-style-image: url(chrome://browser/skin/undoCloseTab.png);
-}
-
-@media (min-resolution: 1.1dppx) {
-  #alltabs_undoCloseTab {
-    list-style-image: url(chrome://browser/skin/undoCloseTab@2x.png);
-  }
-  #alltabs_undoCloseTab > .toolbarbutton-icon {
-    width: 16px;
-  }
-}
-
 /* zoom control text (reset) button special case: */
 
 #nav-bar #zoom-reset-button > .toolbarbutton-text {
   /* To make this line up with the icons, it needs the same height (18px) +
    * padding (2 * 2px) + border (2 * 1px), but as a minimum because otherwise
    * increase in text sizes would break things...
    */
   min-height: 24px;
--- a/devtools/client/inspector/grids/components/GridItem.js
+++ b/devtools/client/inspector/grids/components/GridItem.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { addons, createClass, createFactory, DOM: dom, PropTypes } = require("devtools/client/shared/vendor/react");
 const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
 
 // Reps
-const { REPS } = require("devtools/client/shared/components/reps/reps");
+const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
 const Rep = createFactory(REPS.Rep);
 const ElementNode = REPS.ElementNode;
 
 const Types = require("../types");
 
 module.exports = createClass({
 
   displayName: "GridItem",
@@ -128,16 +128,17 @@ module.exports = createClass({
             value: grid.id,
             checked: grid.highlighted,
             onChange: this.onGridCheckboxClick,
           }
         ),
         Rep(
           {
             defaultRep: ElementNode,
+            mode: MODE.TINY,
             object: this.translateNodeFrontToGrip(nodeFront),
             onDOMNodeMouseOut: () => onHideBoxModelHighlighter(),
             onDOMNodeMouseOver: () => onShowBoxModelHighlighterForNode(nodeFront),
             onInspectIconClick: () => setSelectedNode(nodeFront),
           }
         )
       ),
       dom.div(
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -1139,17 +1139,17 @@ Inspector.prototype = {
       hidden: !this._supportsScrollIntoView,
       disabled: !isSelectionElement,
       click: () => this.scrollNodeIntoView(),
     }));
     menu.append(new MenuItem({
       id: "node-menu-screenshotnode",
       label: INSPECTOR_L10N.getStr("inspectorScreenshotNode.label"),
       disabled: !isScreenshotable,
-      click: () => this.screenshotNode(),
+      click: () => this.screenshotNode().catch(console.error),
     }));
     menu.append(new MenuItem({
       id: "node-menu-useinconsole",
       label: INSPECTOR_L10N.getStr("inspectorUseInConsole.label"),
       click: () => this.useInConsole(),
     }));
     menu.append(new MenuItem({
       id: "node-menu-showdomproperties",
@@ -1762,26 +1762,33 @@ Inspector.prototype = {
     this.selection.nodeFront.getCssPath().then(path => {
       clipboardHelper.copyString(path);
     }).catch(e => console.error);
   },
 
   /**
    * Initiate gcli screenshot command on selected node.
    */
-  screenshotNode: function () {
+  screenshotNode: Task.async(function* () {
     const command = Services.prefs.getBoolPref("devtools.screenshot.clipboard.enabled") ?
       "screenshot --file --clipboard --selector" :
       "screenshot --file --selector";
+
+    // Bug 1332936 - it's possible to call `screenshotNode` while the BoxModel highlighter
+    // is still visible, therefore showing it in the picture.
+    // To avoid that, we have to hide it before taking the screenshot. The `hideBoxModel`
+    // will do that, calling `hide` for the highlighter only if previously shown.
+    yield this.highlighter.hideBoxModel();
+
     // Bug 1180314 -  CssSelector might contain white space so need to make sure it is
     // passed to screenshot as a single parameter.  More work *might* be needed if
     // CssSelector could contain escaped single- or double-quotes, backslashes, etc.
     CommandUtils.executeOnTarget(this._target,
       `${command} '${this.selectionCssSelector}'`);
-  },
+  }),
 
   /**
    * Scroll the node into view.
    */
   scrollNodeIntoView: function () {
     if (!this.selection.isNode()) {
       return;
     }
--- a/devtools/client/inspector/markup/markup.js
+++ b/devtools/client/inspector/markup/markup.js
@@ -158,20 +158,24 @@ MarkupView.prototype = {
   _handleRejectionIfNotDestroyed: function (e) {
     if (!this._destroyer) {
       console.error(e);
     }
   },
 
   _initTooltips: function () {
     // The tooltips will be attached to the toolbox document.
-    this.eventDetailsTooltip = new HTMLTooltip(this.toolbox.doc,
-      {type: "arrow"});
-    this.imagePreviewTooltip = new HTMLTooltip(this.toolbox.doc,
-      {type: "arrow", useXulWrapper: "true"});
+    this.eventDetailsTooltip = new HTMLTooltip(this.toolbox.doc, {
+      type: "arrow",
+      consumeOutsideClicks: false,
+    });
+    this.imagePreviewTooltip = new HTMLTooltip(this.toolbox.doc, {
+      type: "arrow",
+      useXulWrapper: true,
+    });
     this._enableImagePreviewTooltip();
   },
 
   _enableImagePreviewTooltip: function () {
     this.imagePreviewTooltip.startTogglingOnHover(this._elt,
       this._isImagePreviewTarget);
   },
 
@@ -413,30 +417,32 @@ MarkupView.prototype = {
    *
    * @param  {NodeFront} nodeFront
    *         The node to show the highlighter for
    * @return {Promise} Resolves when the highlighter for this nodeFront is
    *         shown, taking into account that there could already be highlighter
    *         requests queued up
    */
   _showBoxModel: function (nodeFront) {
-    return this.toolbox.highlighterUtils.highlightNodeFront(nodeFront);
+    return this.toolbox.highlighterUtils.highlightNodeFront(nodeFront)
+      .catch(this._handleRejectionIfNotDestroyed);
   },
 
   /**
    * Hide the box model highlighter on a given node front
    *
    * @param  {Boolean} forceHide
    *         See toolbox-highlighter-utils/unhighlight
    * @return {Promise} Resolves when the highlighter for this nodeFront is
    *         hidden, taking into account that there could already be highlighter
    *         requests queued up
    */
   _hideBoxModel: function (forceHide) {
-    return this.toolbox.highlighterUtils.unhighlight(forceHide);
+    return this.toolbox.highlighterUtils.unhighlight(forceHide)
+      .catch(this._handleRejectionIfNotDestroyed);
   },
 
   _briefBoxModelTimer: null,
 
   _clearBriefBoxModelTimer: function () {
     if (this._briefBoxModelTimer) {
       clearTimeout(this._briefBoxModelTimer);
       this._briefBoxModelPromise.resolve();
--- a/devtools/client/inspector/markup/test/browser.ini
+++ b/devtools/client/inspector/markup/test/browser.ini
@@ -92,16 +92,17 @@ skip-if = (os == 'linux' && bits == 32 &
 [browser_markup_dragdrop_escapeKeyPress.js]
 [browser_markup_dragdrop_invalidNodes.js]
 [browser_markup_dragdrop_reorder.js]
 [browser_markup_dragdrop_tooltip.js]
 [browser_markup_events_01.js]
 [browser_markup_events_02.js]
 [browser_markup_events_03.js]
 [browser_markup_events_04.js]
+[browser_markup_events_click_to_close.js]
 [browser_markup_events_form.js]
 [browser_markup_events_jquery_1.0.js]
 [browser_markup_events_jquery_1.1.js]
 [browser_markup_events_jquery_1.2.js]
 [browser_markup_events_jquery_1.3.js]
 [browser_markup_events_jquery_1.4.js]
 [browser_markup_events_jquery_1.6.js]
 [browser_markup_events_jquery_1.7.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/inspector/markup/test/browser_markup_events_click_to_close.js
@@ -0,0 +1,68 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+/* import-globals-from helper_events_test_runner.js */
+
+"use strict";
+
+// Tests that click events that close the current event tooltip are still propagated to
+// the target underneath.
+
+const TEST_URL = `
+  <body>
+    <div id="d1" onclick="console.log(1)">test</div>
+    <!--                                        -->
+    <!-- adding some comments to make sure      -->
+    <!-- the second event icon is not hidden by -->
+    <!-- the tooltip of the first event icon    -->
+    <!--                                        -->
+    <div id="d2" onclick="console.log(2)">test</div>
+  </body>
+`;
+
+add_task(function* () {
+  let {inspector, toolbox} = yield openInspectorForURL(
+    "data:text/html;charset=utf-8," + encodeURI(TEST_URL));
+
+  yield inspector.markup.expandAll();
+
+  let container1 = yield getContainerForSelector("#d1", inspector);
+  let evHolder1 = container1.elt.querySelector(".markupview-events");
+
+  let container2 = yield getContainerForSelector("#d2", inspector);
+  let evHolder2 = container2.elt.querySelector(".markupview-events");
+
+  let tooltip = inspector.markup.eventDetailsTooltip;
+
+  info("Click the event icon for the first element");
+  let onShown = tooltip.once("shown");
+  EventUtils.synthesizeMouseAtCenter(evHolder1, {},
+    inspector.markup.doc.defaultView);
+  yield onShown;
+  info("event tooltip for the first div is shown");
+
+  info("Click the event icon for the second element");
+  let onHidden = tooltip.once("hidden");
+  onShown = tooltip.once("shown");
+  EventUtils.synthesizeMouseAtCenter(evHolder2, {},
+    inspector.markup.doc.defaultView);
+
+  yield onHidden;
+  info("previous tooltip hidden");
+
+  yield onShown;
+  info("event tooltip for the second div is shown");
+
+  info("Click on the animation inspector tab");
+  let onHighlighterHidden = toolbox.once("node-unhighlight");
+  let onTabInspectorSelected = inspector.sidebar.once("animationinspector-selected");
+  let animationInspectorTab = inspector.panelDoc.querySelector("#animationinspector-tab");
+  EventUtils.synthesizeMouseAtCenter(animationInspectorTab, {},
+    inspector.panelDoc.defaultView);
+
+  yield onTabInspectorSelected;
+  info("animation inspector was selected");
+
+  yield onHighlighterHidden;
+  info("box model highlighter hidden after moving the mouse out of the markup view");
+});
--- a/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
+++ b/devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js
@@ -112,18 +112,17 @@ SwatchColorPickerTooltip.prototype = Her
       this._originalColor = this.currentSwatchColor.textContent;
       let color = this.activeSwatch.style.backgroundColor;
       this.spectrum.off("changed", this._onSpectrumColorChange);
       this.spectrum.rgb = this._colorToRgba(color);
       this.spectrum.on("changed", this._onSpectrumColorChange);
       this.spectrum.updateUI();
     }
 
-    let tooltipDoc = this.tooltip.doc;
-    let eyeButton = tooltipDoc.querySelector("#eyedropper-button");
+    let eyeButton = this.tooltip.container.querySelector("#eyedropper-button");
     let canShowEyeDropper = yield this.inspector.supportsEyeDropper();
     if (canShowEyeDropper) {
       eyeButton.disabled = false;
       eyeButton.removeAttribute("title");
       eyeButton.addEventListener("click", this._openEyeDropper);
     } else {
       eyeButton.disabled = true;
       eyeButton.title = L10N.getStr("eyedropper.disabled.title");
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -8,17 +8,17 @@
 #include "AnimationUtils.h"
 #include "mozilla/dom/AnimationBinding.h"
 #include "mozilla/dom/AnimationPlaybackEvent.h"
 #include "mozilla/dom/DocumentTimeline.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/AsyncEventDispatcher.h" // For AsyncEventDispatcher
 #include "mozilla/Maybe.h" // For Maybe
-#include "mozilla/AnimationRule.h" // For AnimationRule
+#include "mozilla/TypeTraits.h" // For Forward<>
 #include "nsAnimationManager.h" // For CSSAnimation
 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIDocument.h" // For nsIDocument
 #include "nsIPresShell.h" // For nsIPresShell
 #include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr
 #include "nsTransitionManager.h" // For CSSTransition
 #include "PendingAnimationTracker.h" // For PendingAnimationTracker
 
@@ -937,18 +937,19 @@ Animation::WillComposeStyle()
   MOZ_ASSERT(mEffect);
 
   KeyframeEffectReadOnly* keyframeEffect = mEffect->AsKeyframeEffect();
   if (keyframeEffect) {
     keyframeEffect->WillComposeStyle();
   }
 }
 
+template<typename ComposeAnimationResult>
 void
-Animation::ComposeStyle(AnimationRule& aStyleRule,
+Animation::ComposeStyle(ComposeAnimationResult&& aComposeResult,
                         const nsCSSPropertyIDSet& aPropertiesToSkip)
 {
   if (!mEffect) {
     return;
   }
 
   // In order to prevent flicker, there are a few cases where we want to use
   // a different time for rendering that would otherwise be returned by
@@ -1000,17 +1001,18 @@ Animation::ComposeStyle(AnimationRule& a
       if (!timeToUse.IsNull()) {
         mHoldTime.SetValue((timeToUse.Value() - mStartTime.Value())
                             .MultDouble(mPlaybackRate));
       }
     }
 
     KeyframeEffectReadOnly* keyframeEffect = mEffect->AsKeyframeEffect();
     if (keyframeEffect) {
-      keyframeEffect->ComposeStyle(aStyleRule, aPropertiesToSkip);
+      keyframeEffect->ComposeStyle(Forward<ComposeAnimationResult>(aComposeResult),
+                                   aPropertiesToSkip);
     }
   }
 
   MOZ_ASSERT(playState == PlayState(),
              "Play state should not change during the course of compositing");
 }
 
 void
@@ -1501,10 +1503,22 @@ Animation::DispatchPlaybackEvent(const n
 bool
 Animation::IsRunningOnCompositor() const
 {
   return mEffect &&
          mEffect->AsKeyframeEffect() &&
          mEffect->AsKeyframeEffect()->IsRunningOnCompositor();
 }
 
+template
+void
+Animation::ComposeStyle<RefPtr<AnimValuesStyleRule>&>(
+  RefPtr<AnimValuesStyleRule>& aAnimationRule,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
+template
+void
+Animation::ComposeStyle<const RawServoAnimationValueMap&>(
+  const RawServoAnimationValueMap& aAnimationValues,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/Animation.h
+++ b/dom/animation/Animation.h
@@ -316,22 +316,23 @@ public:
   /**
    * Updates various bits of state that we need to update as the result of
    * running ComposeStyle().
    * See the comment of KeyframeEffectReadOnly::WillComposeStyle for more detail.
    */
   void WillComposeStyle();
 
   /**
-   * Updates |aStyleRule| with the animation values of this animation's effect,
-   * if any.
+   * Updates |aComposeResult| with the animation values of this animation's
+   * effect, if any.
    * Any properties contained in |aPropertiesToSkip| will not be added or
-   * updated in |aStyleRule|.
+   * updated in |aComposeResult|.
    */
-  void ComposeStyle(AnimationRule& aStyleRule,
+  template<typename ComposeAnimationResult>
+  void ComposeStyle(ComposeAnimationResult&& aComposeResult,
                     const nsCSSPropertyIDSet& aPropertiesToSkip);
 
   void NotifyEffectTimingUpdated();
   void NotifyGeometricAnimationsStartingThisFrame();
 
   /**
    * Used by subclasses to synchronously queue a cancel event in situations
    * where the Animation may have been cancelled.
deleted file mode 100644
--- a/dom/animation/AnimationRule.h
+++ /dev/null
@@ -1,24 +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_AnimationRule_h
-#define mozilla_AnimationRule_h
-
-#include "AnimValuesStyleRule.h"
-#include "ServoAnimationRule.h"
-
-namespace mozilla {
-
-// A wrapper for animation rules.
-struct AnimationRule
-{
-  RefPtr<AnimValuesStyleRule> mGecko;
-  RefPtr<ServoAnimationRule> mServo;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_AnimationRule_h
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -447,17 +447,17 @@ EffectCompositor::GetAnimationRule(dom::
   }
 #endif
 
   EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effectSet) {
     return nullptr;
   }
 
-  return effectSet->AnimationRule(aCascadeLevel).mGecko;
+  return effectSet->AnimationRule(aCascadeLevel);
 }
 
 namespace {
   class EffectCompositeOrderComparator {
   public:
     bool Equals(const KeyframeEffectReadOnly* a,
                 const KeyframeEffectReadOnly* b) const
     {
@@ -472,56 +472,54 @@ namespace {
         Equals(a, b) ||
         a->GetAnimation()->HasLowerCompositeOrderThan(*b->GetAnimation()) !=
           b->GetAnimation()->HasLowerCompositeOrderThan(*a->GetAnimation()));
       return a->GetAnimation()->HasLowerCompositeOrderThan(*b->GetAnimation());
     }
   };
 }
 
-ServoAnimationRule*
-EffectCompositor::GetServoAnimationRule(const dom::Element* aElement,
-                                        CSSPseudoElementType aPseudoType,
-                                        CascadeLevel aCascadeLevel)
+bool
+EffectCompositor::GetServoAnimationRule(
+  const dom::Element* aElement,
+  CSSPseudoElementType aPseudoType,
+  CascadeLevel aCascadeLevel,
+  RawServoAnimationValueMapBorrowed aAnimationValues)
 {
-  if (!mPresContext || !mPresContext->IsDynamic()) {
-    // For print or print preview, ignore animations.
-    return nullptr;
-  }
+  MOZ_ASSERT(aAnimationValues);
+  MOZ_ASSERT(mPresContext && mPresContext->IsDynamic(),
+             "Should not be in print preview");
 
   EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effectSet) {
-    return nullptr;
+    return false;
   }
 
   // Get a list of effects sorted by composite order.
   nsTArray<KeyframeEffectReadOnly*> sortedEffectList(effectSet->Count());
   for (KeyframeEffectReadOnly* effect : *effectSet) {
     sortedEffectList.AppendElement(effect);
   }
   sortedEffectList.Sort(EffectCompositeOrderComparator());
 
-  AnimationRule& animRule = effectSet->AnimationRule(aCascadeLevel);
-  animRule.mServo = nullptr;
-
   // If multiple animations affect the same property, animations with higher
   // composite order (priority) override or add or animations with lower
   // priority.
   const nsCSSPropertyIDSet propertiesToSkip =
     aCascadeLevel == CascadeLevel::Animations
       ? effectSet->PropertiesForAnimationsLevel().Inverse()
       : effectSet->PropertiesForAnimationsLevel();
   for (KeyframeEffectReadOnly* effect : sortedEffectList) {
-    effect->GetAnimation()->ComposeStyle(animRule, propertiesToSkip);
+    effect->GetAnimation()->ComposeStyle(*aAnimationValues, propertiesToSkip);
   }
 
   MOZ_ASSERT(effectSet == EffectSet::GetEffectSet(aElement, aPseudoType),
              "EffectSet should not change while composing style");
 
-  return animRule.mServo;
+  return true;
 }
 
 /* static */ dom::Element*
 EffectCompositor::GetElementToRestyle(dom::Element* aElement,
                                       CSSPseudoElementType aPseudoType)
 {
   if (aPseudoType == CSSPseudoElementType::NotPseudo) {
     return aElement;
@@ -768,18 +766,18 @@ EffectCompositor::ComposeAnimationRule(d
 
   // Get a list of effects sorted by composite order.
   nsTArray<KeyframeEffectReadOnly*> sortedEffectList(effects->Count());
   for (KeyframeEffectReadOnly* effect : *effects) {
     sortedEffectList.AppendElement(effect);
   }
   sortedEffectList.Sort(EffectCompositeOrderComparator());
 
-  AnimationRule& animRule = effects->AnimationRule(aCascadeLevel);
-  animRule.mGecko = nullptr;
+  RefPtr<AnimValuesStyleRule>& animRule = effects->AnimationRule(aCascadeLevel);
+  animRule = nullptr;
 
   // If multiple animations affect the same property, animations with higher
   // composite order (priority) override or add or animations with lower
   // priority except properties in propertiesToSkip.
   const nsCSSPropertyIDSet& propertiesToSkip =
     aCascadeLevel == CascadeLevel::Animations
     ? effects->PropertiesForAnimationsLevel().Inverse()
     : effects->PropertiesForAnimationsLevel();
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -19,23 +19,24 @@
 #include "nsTArray.h"
 
 class nsCSSPropertyIDSet;
 class nsIAtom;
 class nsIFrame;
 class nsIStyleRule;
 class nsPresContext;
 class nsStyleContext;
+struct RawServoAnimationValueMap;
+typedef RawServoAnimationValueMap const* RawServoAnimationValueMapBorrowed;
 
 namespace mozilla {
 
 class EffectSet;
 class RestyleTracker;
 class StyleAnimationValue;
-class ServoAnimationRule;
 struct AnimationPerformanceWarning;
 struct AnimationProperty;
 struct NonOwningAnimationTarget;
 
 namespace dom {
 class Animation;
 class Element;
 }
@@ -148,21 +149,25 @@ public:
   // will use a style context associated with the primary frame of the specified
   // (pseudo-)element.
   nsIStyleRule* GetAnimationRule(dom::Element* aElement,
                                  CSSPseudoElementType aPseudoType,
                                  CascadeLevel aCascadeLevel,
                                  nsStyleContext* aStyleContext);
 
   // Get animation rule for stylo. This is an equivalent of GetAnimationRule
-  // and will be called from servo side. We need to be careful while doing any
-  // modification because it may case some thread-safe issues.
-  ServoAnimationRule* GetServoAnimationRule(const dom::Element* aElement,
-                                            CSSPseudoElementType aPseudoType,
-                                            CascadeLevel aCascadeLevel);
+  // and will be called from servo side.
+  // The animation rule is stored in |RawServoAnimationValueMapBorrowed|.
+  // We need to be careful while doing any modification because it may cause
+  // some thread-safe issues.
+  bool GetServoAnimationRule(
+    const dom::Element* aElement,
+    CSSPseudoElementType aPseudoType,
+    CascadeLevel aCascadeLevel,
+    RawServoAnimationValueMapBorrowed aAnimationValues);
 
   bool HasPendingStyleUpdates() const;
   bool HasThrottledStyleUpdates() const;
 
   // Tell the restyle tracker about all the animated styles that have
   // pending updates so that it can update the animation rule for these
   // elements.
   void AddStyleUpdatesTo(RestyleTracker& aTracker);
--- a/dom/animation/EffectSet.h
+++ b/dom/animation/EffectSet.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_EffectSet_h
 #define mozilla_EffectSet_h
 
-#include "mozilla/AnimationRule.h" // For AnimationRule
+#include "mozilla/AnimValuesStyleRule.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
 #include "nsHashKeys.h" // For nsPtrHashKey
 #include "nsTHashtable.h" // For nsTHashtable
 
@@ -158,17 +158,17 @@ public:
 #ifdef DEBUG
   bool IsBeingEnumerated() const { return mActiveIterators != 0; }
 #endif
 
   bool IsEmpty() const { return mEffects.IsEmpty(); }
 
   size_t Count() const { return mEffects.Count(); }
 
-  struct AnimationRule&
+  RefPtr<AnimValuesStyleRule>&
   AnimationRule(EffectCompositor::CascadeLevel aCascadeLevel)
   {
     return mAnimationRule[aCascadeLevel];
   }
 
   const TimeStamp& LastTransformSyncTime() const
   {
     return mLastTransformSyncTime;
@@ -208,17 +208,17 @@ private:
   // These style rules contain the style data for currently animating
   // values.  They only match when styling with animation.  When we
   // style without animation, we need to not use them so that we can
   // detect any new changes; if necessary we restyle immediately
   // afterwards with animation.
   EnumeratedArray<EffectCompositor::CascadeLevel,
                   EffectCompositor::CascadeLevel(
                     EffectCompositor::kCascadeLevelCount),
-                  mozilla::AnimationRule> mAnimationRule;
+                  RefPtr<AnimValuesStyleRule>> mAnimationRule;
 
   // Refresh driver timestamp from the moment when transform animations in this
   // effect set were last updated and sent to the compositor. This is used for
   // transform animations that run on the compositor but need to be updated on
   // the main thread periodically (e.g. so scrollbars can be updated).
   TimeStamp mLastTransformSyncTime;
 
   // Dirty flag to represent when the mPropertiesWithImportantRules and
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/KeyframeEffectReadOnly.h"
 
 #include "mozilla/dom/KeyframeAnimationOptionsBinding.h"
   // For UnrestrictedDoubleOrKeyframeAnimationOptions;
 #include "mozilla/dom/CSSPseudoElement.h"
 #include "mozilla/dom/KeyframeEffectBinding.h"
-#include "mozilla/AnimationRule.h"
+#include "mozilla/AnimValuesStyleRule.h"
 #include "mozilla/AnimationUtils.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/EffectSet.h"
 #include "mozilla/FloatingPoint.h" // For IsFinite
 #include "mozilla/LookAndFeel.h" // For LookAndFeel::GetInt
 #include "mozilla/KeyframeUtils.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/TypeTraits.h"
@@ -435,17 +435,17 @@ KeyframeEffectReadOnly::ResolveBaseStyle
 
 StyleAnimationValue
 KeyframeEffectReadOnly::GetUnderlyingStyle(
   nsCSSPropertyID aProperty,
   const RefPtr<AnimValuesStyleRule>& aAnimationRule)
 {
   StyleAnimationValue result;
 
-  if (aAnimationRule->HasValue(aProperty)) {
+  if (aAnimationRule && aAnimationRule->HasValue(aProperty)) {
     // If we have already composed style for the property, we use the style
     // as the underlying style.
     DebugOnly<bool> success = aAnimationRule->GetValue(aProperty, result);
     MOZ_ASSERT(success, "AnimValuesStyleRule::GetValue should not fail");
   } else {
     // If we are composing with composite operation that is not 'replace'
     // and we have not composed style for the property yet, we have to get
     // the base style for the property.
@@ -505,18 +505,164 @@ void
 KeyframeEffectReadOnly::WillComposeStyle()
 {
   ComputedTiming computedTiming = GetComputedTiming();
   mProgressOnLastCompose = computedTiming.mProgress;
   mCurrentIterationOnLastCompose = computedTiming.mCurrentIteration;
 }
 
 void
+KeyframeEffectReadOnly::ComposeStyleRule(
+  RefPtr<AnimValuesStyleRule>& aStyleRule,
+  const AnimationProperty& aProperty,
+  const AnimationPropertySegment& aSegment,
+  const ComputedTiming& aComputedTiming)
+{
+  StyleAnimationValue fromValue =
+    CompositeValue(aProperty.mProperty, aStyleRule,
+                   aSegment.mFromValue.mGecko,
+                   aSegment.mFromComposite);
+  StyleAnimationValue toValue =
+    CompositeValue(aProperty.mProperty, aStyleRule,
+                   aSegment.mToValue.mGecko,
+                   aSegment.mToComposite);
+  if (fromValue.IsNull() || toValue.IsNull()) {
+    return;
+  }
+
+  if (!aStyleRule) {
+    // Allocate the style rule now that we know we have animation data.
+    aStyleRule = new AnimValuesStyleRule();
+  }
+
+  // Iteration composition for accumulate
+  if (mEffectOptions.mIterationComposite ==
+      IterationCompositeOperation::Accumulate &&
+      aComputedTiming.mCurrentIteration > 0) {
+    const AnimationPropertySegment& lastSegment =
+      aProperty.mSegments.LastElement();
+    // FIXME: Bug 1293492: Add a utility function to calculate both of
+    // below StyleAnimationValues.
+    StyleAnimationValue lastValue = lastSegment.mToValue.mGecko.IsNull()
+      ? GetUnderlyingStyle(aProperty.mProperty, aStyleRule)
+      : lastSegment.mToValue.mGecko;
+    fromValue =
+      StyleAnimationValue::Accumulate(aProperty.mProperty,
+                                      lastValue,
+                                      Move(fromValue),
+                                      aComputedTiming.mCurrentIteration);
+    toValue =
+      StyleAnimationValue::Accumulate(aProperty.mProperty,
+                                      lastValue,
+                                      Move(toValue),
+                                      aComputedTiming.mCurrentIteration);
+  }
+
+  // Special handling for zero-length segments
+  if (aSegment.mToKey == aSegment.mFromKey) {
+    if (aComputedTiming.mProgress.Value() < 0) {
+      aStyleRule->AddValue(aProperty.mProperty, Move(fromValue));
+    } else {
+      aStyleRule->AddValue(aProperty.mProperty, Move(toValue));
+    }
+    return;
+  }
+
+  double positionInSegment =
+    (aComputedTiming.mProgress.Value() - aSegment.mFromKey) /
+    (aSegment.mToKey - aSegment.mFromKey);
+  double valuePosition =
+    ComputedTimingFunction::GetPortion(aSegment.mTimingFunction,
+                                       positionInSegment,
+                                       aComputedTiming.mBeforeFlag);
+
+  MOZ_ASSERT(IsFinite(valuePosition), "Position value should be finite");
+
+  StyleAnimationValue val;
+  if (StyleAnimationValue::Interpolate(aProperty.mProperty,
+                                       fromValue,
+                                       toValue,
+                                       valuePosition, val)) {
+    aStyleRule->AddValue(aProperty.mProperty, Move(val));
+  } else if (valuePosition < 0.5) {
+    aStyleRule->AddValue(aProperty.mProperty, Move(fromValue));
+  } else {
+    aStyleRule->AddValue(aProperty.mProperty, Move(toValue));
+  }
+}
+
+// Bug 1333311 - We use two branches for Gecko and Stylo. However, it's
+// better to remove the duplicated code.
+void
+KeyframeEffectReadOnly::ComposeStyleRule(
+  const RawServoAnimationValueMap& aAnimationValues,
+  const AnimationProperty& aProperty,
+  const AnimationPropertySegment& aSegment,
+  const ComputedTiming& aComputedTiming)
+{
+  // Bug 1329878 - Stylo: Implement accumulate and addition on Servo
+  // AnimationValue.
+  RawServoAnimationValue* servoFromValue = aSegment.mFromValue.mServo;
+  RawServoAnimationValue* servoToValue = aSegment.mToValue.mServo;
+
+  // For unsupported or non-animatable animation types, we get nullptrs.
+  if (!servoFromValue || !servoToValue) {
+    NS_ERROR("Compose style for unsupported or non-animatable property, "
+             "so get invalid RawServoAnimationValues");
+    return;
+  }
+
+  // Special handling for zero-length segments
+  if (aSegment.mToKey == aSegment.mFromKey) {
+    if (aComputedTiming.mProgress.Value() < 0) {
+      Servo_AnimationValueMap_Push(&aAnimationValues,
+                                   aProperty.mProperty,
+                                   servoFromValue);
+    } else {
+      Servo_AnimationValueMap_Push(&aAnimationValues,
+                                   aProperty.mProperty,
+                                   servoToValue);
+    }
+    return;
+  }
+
+  double positionInSegment =
+    (aComputedTiming.mProgress.Value() - aSegment.mFromKey) /
+    (aSegment.mToKey - aSegment.mFromKey);
+  double valuePosition =
+    ComputedTimingFunction::GetPortion(aSegment.mTimingFunction,
+                                       positionInSegment,
+                                       aComputedTiming.mBeforeFlag);
+
+  MOZ_ASSERT(IsFinite(valuePosition), "Position value should be finite");
+
+  RefPtr<RawServoAnimationValue> interpolated =
+    Servo_AnimationValues_Interpolate(servoFromValue,
+                                      servoToValue,
+                                      valuePosition).Consume();
+
+  if (interpolated) {
+    Servo_AnimationValueMap_Push(&aAnimationValues,
+                                 aProperty.mProperty,
+                                 interpolated);
+  } else if (valuePosition < 0.5) {
+    Servo_AnimationValueMap_Push(&aAnimationValues,
+                                 aProperty.mProperty,
+                                 servoFromValue);
+  } else {
+    Servo_AnimationValueMap_Push(&aAnimationValues,
+                                 aProperty.mProperty,
+                                 servoToValue);
+  }
+}
+
+template<typename ComposeAnimationResult>
+void
 KeyframeEffectReadOnly::ComposeStyle(
-  AnimationRule& aStyleRule,
+  ComposeAnimationResult&& aComposeResult,
   const nsCSSPropertyIDSet& aPropertiesToSkip)
 {
   MOZ_DIAGNOSTIC_ASSERT(!mIsComposingStyle,
                         "Should not be called recursively");
   if (mIsComposingStyle) {
     return;
   }
 
@@ -526,18 +672,16 @@ KeyframeEffectReadOnly::ComposeStyle(
   ComputedTiming computedTiming = GetComputedTiming();
 
   // If the progress is null, we don't have fill data for the current
   // time so we shouldn't animate.
   if (computedTiming.mProgress.IsNull()) {
     return;
   }
 
-  bool isServoBackend = mDocument->IsStyledByServo();
-
   for (size_t propIdx = 0, propEnd = mProperties.Length();
        propIdx != propEnd; ++propIdx)
   {
     const AnimationProperty& prop = mProperties[propIdx];
 
     MOZ_ASSERT(prop.mSegments[0].mFromKey == 0.0, "incorrect first from key");
     MOZ_ASSERT(prop.mSegments[prop.mSegments.Length() - 1].mToKey == 1.0,
                "incorrect last to key");
@@ -561,145 +705,20 @@ KeyframeEffectReadOnly::ComposeStyle(
       MOZ_ASSERT(segment->mFromKey == (segment-1)->mToKey, "incorrect keys");
     }
     MOZ_ASSERT(segment->mFromKey <= segment->mToKey, "incorrect keys");
     MOZ_ASSERT(segment >= prop.mSegments.Elements() &&
                size_t(segment - prop.mSegments.Elements()) <
                  prop.mSegments.Length(),
                "out of array bounds");
 
-    // Bug 1333311 - We use two branches for Gecko and Stylo. However, it's
-    // better to remove the duplicated code.
-    if (isServoBackend) {
-      // Servo backend
-
-      // Bug 1329878 - Stylo: Implement accumulate and addition on Servo
-      // AnimationValue.
-      RawServoAnimationValue* servoFromValue = segment->mFromValue.mServo;
-      RawServoAnimationValue* servoToValue = segment->mToValue.mServo;
-
-      // For unsupported or non-animatable animation types, we get nullptrs.
-      if (!servoFromValue || !servoToValue) {
-        NS_ERROR("Compose style for unsupported or non-animatable property, "
-                 "so get invalid RawServoAnimationValues");
-        continue;
-      }
-
-      if (!aStyleRule.mServo) {
-        // Allocate the style rule now that we know we have animation data.
-        aStyleRule.mServo = new ServoAnimationRule();
-      }
-
-      // Special handling for zero-length segments
-      if (segment->mToKey == segment->mFromKey) {
-        if (computedTiming.mProgress.Value() < 0) {
-          aStyleRule.mServo->AddValue(prop.mProperty, servoFromValue);
-        } else {
-          aStyleRule.mServo->AddValue(prop.mProperty, servoToValue);
-        }
-        continue;
-      }
-
-      double positionInSegment =
-        (computedTiming.mProgress.Value() - segment->mFromKey) /
-        (segment->mToKey - segment->mFromKey);
-      double valuePosition =
-        ComputedTimingFunction::GetPortion(segment->mTimingFunction,
-                                           positionInSegment,
-                                           computedTiming.mBeforeFlag);
-
-      MOZ_ASSERT(IsFinite(valuePosition), "Position value should be finite");
-
-      RefPtr<RawServoAnimationValue> interpolated =
-        Servo_AnimationValues_Interpolate(servoFromValue,
-                                          servoToValue,
-                                          valuePosition).Consume();
-
-      if (interpolated) {
-        aStyleRule.mServo->AddValue(prop.mProperty, interpolated);
-      } else if (valuePosition < 0.5) {
-        aStyleRule.mServo->AddValue(prop.mProperty, servoFromValue);
-      } else {
-        aStyleRule.mServo->AddValue(prop.mProperty, servoToValue);
-      }
-    } else {
-      // Gecko backend
-
-      if (!aStyleRule.mGecko) {
-        // Allocate the style rule now that we know we have animation data.
-        aStyleRule.mGecko = new AnimValuesStyleRule();
-      }
-
-      StyleAnimationValue fromValue =
-        CompositeValue(prop.mProperty, aStyleRule.mGecko,
-                       segment->mFromValue.mGecko,
-                       segment->mFromComposite);
-      StyleAnimationValue toValue =
-        CompositeValue(prop.mProperty, aStyleRule.mGecko,
-                       segment->mToValue.mGecko,
-                       segment->mToComposite);
-      if (fromValue.IsNull() || toValue.IsNull()) {
-        continue;
-      }
-
-      // Iteration composition for accumulate
-      if (mEffectOptions.mIterationComposite ==
-          IterationCompositeOperation::Accumulate &&
-          computedTiming.mCurrentIteration > 0) {
-        const AnimationPropertySegment& lastSegment =
-          prop.mSegments.LastElement();
-        // FIXME: Bug 1293492: Add a utility function to calculate both of
-        // below StyleAnimationValues.
-        StyleAnimationValue lastValue = lastSegment.mToValue.mGecko.IsNull()
-          ? GetUnderlyingStyle(prop.mProperty, aStyleRule.mGecko)
-          : lastSegment.mToValue.mGecko;
-        fromValue =
-          StyleAnimationValue::Accumulate(prop.mProperty,
-                                          lastValue,
-                                          Move(fromValue),
-                                          computedTiming.mCurrentIteration);
-        toValue =
-          StyleAnimationValue::Accumulate(prop.mProperty,
-                                          lastValue,
-                                          Move(toValue),
-                                          computedTiming.mCurrentIteration);
-      }
-
-      // Special handling for zero-length segments
-      if (segment->mToKey == segment->mFromKey) {
-        if (computedTiming.mProgress.Value() < 0) {
-          aStyleRule.mGecko->AddValue(prop.mProperty, Move(fromValue));
-        } else {
-          aStyleRule.mGecko->AddValue(prop.mProperty, Move(toValue));
-        }
-        continue;
-      }
-
-      double positionInSegment =
-        (computedTiming.mProgress.Value() - segment->mFromKey) /
-        (segment->mToKey - segment->mFromKey);
-      double valuePosition =
-        ComputedTimingFunction::GetPortion(segment->mTimingFunction,
-                                           positionInSegment,
-                                           computedTiming.mBeforeFlag);
-
-      MOZ_ASSERT(IsFinite(valuePosition), "Position value should be finite");
-
-      StyleAnimationValue val;
-      if (StyleAnimationValue::Interpolate(prop.mProperty,
-                                           fromValue,
-                                           toValue,
-                                           valuePosition, val)) {
-        aStyleRule.mGecko->AddValue(prop.mProperty, Move(val));
-      } else if (valuePosition < 0.5) {
-        aStyleRule.mGecko->AddValue(prop.mProperty, Move(fromValue));
-      } else {
-        aStyleRule.mGecko->AddValue(prop.mProperty, Move(toValue));
-      }
-    }
+    ComposeStyleRule(Forward<ComposeAnimationResult>(aComposeResult),
+                     prop,
+                     *segment,
+                     computedTiming);
   }
 }
 
 bool
 KeyframeEffectReadOnly::IsRunningOnCompositor() const
 {
   // We consider animation is running on compositor if there is at least
   // one property running on compositor.
@@ -1794,10 +1813,22 @@ KeyframeEffectReadOnly::ContainsAnimated
         }
       }
     }
   }
 
   return false;
 }
 
+template
+void
+KeyframeEffectReadOnly::ComposeStyle<RefPtr<AnimValuesStyleRule>&>(
+  RefPtr<AnimValuesStyleRule>& aAnimationRule,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
+template
+void
+KeyframeEffectReadOnly::ComposeStyle<const RawServoAnimationValueMap&>(
+  const RawServoAnimationValueMap& aAnimationValues,
+  const nsCSSPropertyIDSet& aPropertiesToSkip);
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -250,20 +250,21 @@ public:
   void UpdateProperties(const ServoComputedStyleValues& aServoValues);
 
   // Update various bits of state related to running ComposeStyle().
   // We need to update this outside ComposeStyle() because we should avoid
   // mutating any state in ComposeStyle() since it might be called during
   // parallel traversal.
   void WillComposeStyle();
 
-  // Updates |aStyleRule| with the animation values produced by this
+  // Updates |aComposeResult| with the animation values produced by this
   // AnimationEffect for the current time except any properties contained
   // in |aPropertiesToSkip|.
-  void ComposeStyle(AnimationRule& aStyleRule,
+  template<typename ComposeAnimationResult>
+  void ComposeStyle(ComposeAnimationResult&& aRestultContainer,
                     const nsCSSPropertyIDSet& aPropertiesToSkip);
 
   // Composite |aValueToComposite| on |aUnderlyingValue| with
   // |aCompositeOperation|.
   // Returns |aValueToComposite| if |aCompositeOperation| is Replace.
   static StyleAnimationValue CompositeValue(
     nsCSSPropertyID aProperty,
     const StyleAnimationValue& aValueToComposite,
@@ -453,16 +454,26 @@ private:
   nsChangeHint mCumulativeChangeHint;
 
   template<typename StyleType>
   void DoSetKeyframes(nsTArray<Keyframe>&& aKeyframes, StyleType&& aStyle);
 
   template<typename StyleType>
   void DoUpdateProperties(StyleType&& aStyle);
 
+  void ComposeStyleRule(RefPtr<AnimValuesStyleRule>& aStyleRule,
+                        const AnimationProperty& aProperty,
+                        const AnimationPropertySegment& aSegment,
+                        const ComputedTiming& aComputedTiming);
+
+  void ComposeStyleRule(const RawServoAnimationValueMap& aAnimationValues,
+                        const AnimationProperty& aProperty,
+                        const AnimationPropertySegment& aSegment,
+                        const ComputedTiming& aComputedTiming);
+
   nsIFrame* GetAnimationFrame() const;
 
   bool CanThrottle() const;
   bool CanThrottleTransformChanges(nsIFrame& aFrame) const;
 
   // Returns true if the computedTiming has changed since the last
   // composition.
   bool HasComputedTimingChanged() const;
deleted file mode 100644
--- a/dom/animation/ServoAnimationRule.cpp
+++ /dev/null
@@ -1,32 +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 "ServoAnimationRule.h"
-
-namespace mozilla {
-
-void
-ServoAnimationRule::AddValue(nsCSSPropertyID aProperty,
-                             RawServoAnimationValue* aValue)
-{
-  MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN,
-             "Unexpected css property");
-  mAnimationValues.Put(aProperty, aValue);
-}
-
-RawServoDeclarationBlockStrong
-ServoAnimationRule::GetValues() const
-{
-  // FIXME: Pass the hash table into the FFI directly.
-  nsTArray<const RawServoAnimationValue*> values(mAnimationValues.Count());
-  auto iter = mAnimationValues.ConstIter();
-  for (; !iter.Done(); iter.Next()) {
-    values.AppendElement(iter.Data());
-  }
-  return Servo_AnimationValues_Uncompute(&values);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/dom/animation/ServoAnimationRule.h
+++ /dev/null
@@ -1,39 +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_ServoAnimationRule_h
-#define mozilla_ServoAnimationRule_h
-
-#include "nsCSSPropertyID.h"
-#include "nsHashKeys.h" // For nsUint32HashKey
-#include "nsRefPtrHashtable.h"
-#include "ServoBindings.h"
-
-namespace mozilla {
-
-/**
- * A rule for Stylo Animation Rule.
- */
-class ServoAnimationRule
-{
-public:
-  ServoAnimationRule() = default;
-
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ServoAnimationRule)
-
-  void AddValue(nsCSSPropertyID aProperty,
-                RawServoAnimationValue* aValue);
-  MOZ_MUST_USE RawServoDeclarationBlockStrong GetValues() const;
-
-private:
-  ~ServoAnimationRule() = default;
-
-  nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue> mAnimationValues;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_ServoAnimationRule_h
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -20,30 +20,28 @@ EXPORTS.mozilla.dom += [
     'DocumentTimeline.h',
     'KeyframeEffect.h',
     'KeyframeEffectReadOnly.h',
 ]
 
 EXPORTS.mozilla += [
     'AnimationComparator.h',
     'AnimationPerformanceWarning.h',
-    'AnimationRule.h',
     'AnimationTarget.h',
     'AnimationUtils.h',
     'AnimValuesStyleRule.h',
     'ComputedTiming.h',
     'ComputedTimingFunction.h',
     'EffectCompositor.h',
     'EffectSet.h',
     'Keyframe.h',
     'KeyframeEffectParams.h',
     'KeyframeUtils.h',
     'PendingAnimationTracker.h',
     'PseudoElementHashEntry.h',
-    'ServoAnimationRule.h',
     'TimingParams.h',
 ]
 
 UNIFIED_SOURCES += [
     'Animation.cpp',
     'AnimationEffectReadOnly.cpp',
     'AnimationEffectTiming.cpp',
     'AnimationEffectTimingReadOnly.cpp',
@@ -56,17 +54,16 @@ UNIFIED_SOURCES += [
     'DocumentTimeline.cpp',
     'EffectCompositor.cpp',
     'EffectSet.cpp',
     'KeyframeEffect.cpp',
     'KeyframeEffectParams.cpp',
     'KeyframeEffectReadOnly.cpp',
     'KeyframeUtils.cpp',
     'PendingAnimationTracker.cpp',
-    'ServoAnimationRule.cpp',
     'TimingParams.cpp',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/layout/base',
     '/layout/style',
 ]
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -116,16 +116,18 @@ static mozilla::LazyLogModule gMediaElem
 #include "nsDocShell.h"
 
 #include "mozilla/EventStateManager.h"
 
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "mozilla/dom/VideoPlaybackQuality.h"
 #include "HTMLMediaElement.h"
 
+#include "GMPCrashHelper.h"
+
 using namespace mozilla::layers;
 using mozilla::net::nsMediaFragmentURIParser;
 
 namespace mozilla {
 namespace dom {
 
 // Number of milliseconds between progress events as defined by spec
 static const uint32_t PROGRESS_MS = 350;
@@ -3716,16 +3718,17 @@ HTMLMediaElement::HTMLMediaElement(alrea
     mDownloadSuspendedByCache(false, "HTMLMediaElement::mDownloadSuspendedByCache"),
     mAudioChannel(AudioChannelService::GetDefaultAudioChannel()),
     mDisableVideo(false),
     mHasUserInteraction(false),
     mFirstFrameLoaded(false),
     mDefaultPlaybackStartPosition(0.0),
     mIsAudioTrackAudible(false),
     mHasSuspendTaint(false),
+    mMediaTracksConstructed(false),
     mVisibilityState(Visibility::APPROXIMATELY_NONVISIBLE),
     mErrorSink(new ErrorSink(this)),
     mAudioChannelWrapper(new AudioChannelAgentCallback(this, mAudioChannel))
 {
   ErrorResult rv;
 
   double defaultVolume = Preferences::GetFloat("media.default_volume", 1.0);
   SetVolume(defaultVolume, rv);
@@ -7405,16 +7408,93 @@ HTMLMediaElement::NotifyDecoderActivityC
 {
   if (mDecoder) {
     mDecoder->NotifyOwnerActivityChanged(!IsHidden(),
                                          mVisibilityState == Visibility::APPROXIMATELY_VISIBLE,
                                          IsInUncomposedDoc());
   }
 }
 
+nsIDocument*
+HTMLMediaElement::GetDocument() const
+{
+  return OwnerDoc();
+}
+
+void
+HTMLMediaElement::ConstructMediaTracks(const MediaInfo* aInfo)
+{
+  if (mMediaTracksConstructed || !aInfo) {
+    return;
+  }
+
+  mMediaTracksConstructed = true;
+
+  AudioTrackList* audioList = AudioTracks();
+  if (audioList && aInfo->HasAudio()) {
+    const TrackInfo& info = aInfo->mAudio;
+    RefPtr<AudioTrack> track = MediaTrackList::CreateAudioTrack(
+    info.mId, info.mKind, info.mLabel, info.mLanguage, info.mEnabled);
+
+    audioList->AddTrack(track);
+  }
+
+  VideoTrackList* videoList = VideoTracks();
+  if (videoList && aInfo->HasVideo()) {
+    const TrackInfo& info = aInfo->mVideo;
+    RefPtr<VideoTrack> track = MediaTrackList::CreateVideoTrack(
+    info.mId, info.mKind, info.mLabel, info.mLanguage);
+
+    videoList->AddTrack(track);
+    track->SetEnabledInternal(info.mEnabled, MediaTrack::FIRE_NO_EVENTS);
+  }
+}
+
+void
+HTMLMediaElement::RemoveMediaTracks()
+{
+  AudioTrackList* audioList = AudioTracks();
+  if (audioList) {
+    audioList->RemoveTracks();
+  }
+
+  VideoTrackList* videoList = VideoTracks();
+  if (videoList) {
+    videoList->RemoveTracks();
+  }
+
+  mMediaTracksConstructed = false;
+}
+
+class MediaElementGMPCrashHelper : public GMPCrashHelper
+{
+public:
+  explicit MediaElementGMPCrashHelper(HTMLMediaElement* aElement)
+    : mElement(aElement)
+  {
+    MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
+  }
+  already_AddRefed<nsPIDOMWindowInner> GetPluginCrashedEventTarget() override
+  {
+    MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
+    if (!mElement) {
+      return nullptr;
+    }
+    return do_AddRef(mElement->OwnerDoc()->GetInnerWindow());
+  }
+private:
+  WeakPtr<HTMLMediaElement> mElement;
+};
+
+already_AddRefed<GMPCrashHelper>
+HTMLMediaElement::CreateGMPCrashHelper()
+{
+  return MakeAndAddRef<MediaElementGMPCrashHelper>(this);
+}
+
 bool HasDebuggerPrivilege(JSContext* aCx, JSObject* aObj)
 {
   return nsContentUtils::CallerHasPermission(aCx,
                                              NS_LITERAL_STRING("debugger"));
  }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -769,16 +769,24 @@ public:
   enum class CallerAPI {
     DRAW_IMAGE,
     CREATE_PATTERN,
     CREATE_IMAGEBITMAP,
     CAPTURE_STREAM,
   };
   void MarkAsContentSource(CallerAPI aAPI);
 
+  nsIDocument* GetDocument() const override;
+
+  void ConstructMediaTracks(const MediaInfo* aInfo) override;
+
+  void RemoveMediaTracks() override;
+
+  already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() override;
+
 protected:
   virtual ~HTMLMediaElement();
 
   class AudioChannelAgentCallback;
   class ChannelLoader;
   class ErrorSink;
   class MediaLoadListener;
   class MediaStreamTracksAvailableCallback;
@@ -1728,16 +1736,20 @@ private:
 
   // True if the audio track is not silent.
   bool mIsAudioTrackAudible;
 
   // True if media element has been marked as 'tainted' and can't
   // participate in video decoder suspending.
   bool mHasSuspendTaint;
 
+  // True if audio tracks and video tracks are constructed and added into the
+  // track list, false if all tracks are removed from the track list.
+  bool mMediaTracksConstructed;
+
   Visibility mVisibilityState;
 
   UniquePtr<ErrorSink> mErrorSink;
 
   // This wrapper will handle all audio channel related stuffs, eg. the operations
   // of tab audio indicator, Fennec's media control.
   // Note: mAudioChannelWrapper might be null after GC happened.
   RefPtr<AudioChannelAgentCallback> mAudioChannelWrapper;
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -27,17 +27,16 @@
 #include "mozilla/dom/AudioTrack.h"
 #include "mozilla/dom/AudioTrackList.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/VideoTrack.h"
 #include "mozilla/dom/VideoTrackList.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Telemetry.h"
-#include "GMPCrashHelper.h"
 #include "Layers.h"
 #include "mozilla/layers/ShadowLayers.h"
 
 #ifdef MOZ_ANDROID_OMX
 #include "AndroidBridge.h"
 #endif
 
 using namespace mozilla::dom;
@@ -247,20 +246,20 @@ MediaDecoder::ResourceCallback::NotifyDa
 {
   RefPtr<ResourceCallback> self = this;
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
     if (!self->mDecoder) {
       return;
     }
     self->mDecoder->NotifyDownloadEnded(aStatus);
     if (NS_SUCCEEDED(aStatus)) {
-      HTMLMediaElement* element = self->GetMediaOwner()->GetMediaElement();
-      if (element) {
-        element->DownloadSuspended();
-      }
+      MediaDecoderOwner* owner = self->GetMediaOwner();
+      MOZ_ASSERT(owner);
+      owner->DownloadSuspended();
+
       // NotifySuspendedStatusChanged will tell the element that download
       // has been suspended "by the cache", which is true since we never
       // download anything. The element can then transition to HAVE_ENOUGH_DATA.
       self->mDecoder->NotifySuspendedStatusChanged();
     }
   });
   mAbstractMainThread->Dispatch(r.forget());
 }
@@ -389,17 +388,16 @@ MediaDecoder::MediaDecoder(MediaDecoderO
   , mInfiniteStream(false)
   , mOwner(aOwner)
   , mAbstractMainThread(aOwner->AbstractMainThread())
   , mFrameStats(new FrameStatistics())
   , mVideoFrameContainer(aOwner->GetVideoFrameContainer())
   , mPlaybackStatistics(new MediaChannelStatistics())
   , mPinnedForSeek(false)
   , mMinimizePreroll(false)
-  , mMediaTracksConstructed(false)
   , mFiredMetadataLoaded(false)
   , mIsDocumentVisible(false)
   , mIsElementVisible(false)
   , mIsElementInTree(false)
   , mForcedHidden(false)
   , mHasSuspendTaint(false)
   , INIT_MIRROR(mStateMachineIsShutdown, true)
   , INIT_MIRROR(mBuffered, TimeIntervals())
@@ -584,21 +582,17 @@ MediaDecoder::OnPlaybackErrorEvent(const
 }
 
 void
 MediaDecoder::OnDecoderDoctorEvent(DecoderDoctorEvent aEvent)
 {
   MOZ_ASSERT(NS_IsMainThread());
   // OnDecoderDoctorEvent is disconnected at shutdown time.
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
-  HTMLMediaElement* element = GetOwner()->GetMediaElement();
-  if (!element) {
-    return;
-  }
-  nsIDocument* doc = element->OwnerDoc();
+  nsIDocument* doc = GetOwner()->GetDocument();
   if (!doc) {
     return;
   }
   DecoderDoctorDiagnostics diags;
   diags.StoreEvent(doc, aEvent, __func__);
 }
 
 void
@@ -807,17 +801,17 @@ MediaDecoder::GetCurrentPrincipal()
   MOZ_ASSERT(NS_IsMainThread());
   return mResource ? mResource->GetCurrentPrincipal() : nullptr;
 }
 
 void
 MediaDecoder::OnMetadataUpdate(TimedMetadata&& aMetadata)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  RemoveMediaTracks();
+  GetOwner()->RemoveMediaTracks();
   MetadataLoaded(nsAutoPtr<MediaInfo>(new MediaInfo(*aMetadata.mInfo)),
                  Move(aMetadata.mTags),
                  MediaDecoderEventVisibility::Observable);
   FirstFrameLoaded(Move(aMetadata.mInfo),
                    MediaDecoderEventVisibility::Observable);
 }
 
 void
@@ -830,17 +824,17 @@ MediaDecoder::MetadataLoaded(nsAutoPtr<M
 
   DECODER_LOG("MetadataLoaded, channels=%u rate=%u hasAudio=%d hasVideo=%d",
               aInfo->mAudio.mChannels, aInfo->mAudio.mRate,
               aInfo->HasAudio(), aInfo->HasVideo());
 
   mMediaSeekable = aInfo->mMediaSeekable;
   mMediaSeekableOnlyInBufferedRanges = aInfo->mMediaSeekableOnlyInBufferedRanges;
   mInfo = aInfo.forget();
-  ConstructMediaTracks();
+  GetOwner()->ConstructMediaTracks(mInfo);
 
   // Make sure the element and the frame (if any) are told about
   // our new size.
   if (aEventVisibility != MediaDecoderEventVisibility::Suppressed) {
     mFiredMetadataLoaded = true;
     GetOwner()->MetadataLoaded(mInfo,
                                nsAutoPtr<const MetadataTags>(aTags.forget()));
   }
@@ -965,44 +959,21 @@ MediaDecoder::IsSeeking() const
 bool
 MediaDecoder::OwnerHasError() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
   return GetOwner()->HasError();
 }
 
-class MediaElementGMPCrashHelper : public GMPCrashHelper
-{
-public:
-  explicit MediaElementGMPCrashHelper(HTMLMediaElement* aElement)
-    : mElement(aElement)
-  {
-    MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
-  }
-  already_AddRefed<nsPIDOMWindowInner> GetPluginCrashedEventTarget() override
-  {
-    MOZ_ASSERT(NS_IsMainThread()); // WeakPtr isn't thread safe.
-    if (!mElement) {
-      return nullptr;
-    }
-    return do_AddRef(mElement->OwnerDoc()->GetInnerWindow());
-  }
-private:
-  WeakPtr<HTMLMediaElement> mElement;
-};
-
 already_AddRefed<GMPCrashHelper>
 MediaDecoder::GetCrashHelper()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  return GetOwner()->GetMediaElement()
-         ? MakeAndAddRef<MediaElementGMPCrashHelper>(
-             GetOwner()->GetMediaElement())
-         : nullptr;
+  return GetOwner()->CreateGMPCrashHelper();
 }
 
 bool
 MediaDecoder::IsEnded() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   return mPlayState == PLAY_STATE_ENDED;
 }
@@ -1218,19 +1189,19 @@ MediaDecoder::ChangeState(PlayState aSta
   if (mNextState == aState) {
     mNextState = PLAY_STATE_PAUSED;
   }
 
   DECODER_LOG("ChangeState %s => %s", PlayStateStr(), ToPlayStateStr(aState));
   mPlayState = aState;
 
   if (mPlayState == PLAY_STATE_PLAYING) {
-    ConstructMediaTracks();
+    GetOwner()->ConstructMediaTracks(mInfo);
   } else if (IsEnded()) {
-    RemoveMediaTracks();
+    GetOwner()->RemoveMediaTracks();
   }
 }
 
 void
 MediaDecoder::UpdateLogicalPositionInternal()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
@@ -1292,21 +1263,21 @@ MediaDecoder::DurationChanged()
 }
 
 void
 MediaDecoder::NotifyCompositor()
 {
   MediaDecoderOwner* owner = GetOwner();
   NS_ENSURE_TRUE_VOID(owner);
 
-  dom::HTMLMediaElement* element = owner->GetMediaElement();
-  NS_ENSURE_TRUE_VOID(element);
+  nsIDocument* ownerDoc = owner->GetDocument();
+  NS_ENSURE_TRUE_VOID(ownerDoc);
 
   RefPtr<LayerManager> layerManager =
-    nsContentUtils::LayerManagerForDocument(element->OwnerDoc());
+    nsContentUtils::LayerManagerForDocument(ownerDoc);
   if (layerManager) {
     RefPtr<KnowsCompositor> knowsCompositor = layerManager->AsShadowForwarder();
     mCompositorUpdatedEvent.Notify(knowsCompositor);
   }
 }
 
 void
 MediaDecoder::SetElementVisibility(bool aIsDocumentVisible,
@@ -1780,77 +1751,16 @@ MediaDecoder::GetOwner() const
 {
   MOZ_ASSERT(NS_IsMainThread());
   // Check object lifetime when mOwner points to a media element.
   MOZ_DIAGNOSTIC_ASSERT(!mOwner || !mIsMediaElement || mElement);
   // mOwner is valid until shutdown.
   return mOwner;
 }
 
-void
-MediaDecoder::ConstructMediaTracks()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
-
-  if (mMediaTracksConstructed || !mInfo) {
-    return;
-  }
-
-  HTMLMediaElement* element = GetOwner()->GetMediaElement();
-  if (!element) {
-    return;
-  }
-
-  mMediaTracksConstructed = true;
-
-  AudioTrackList* audioList = element->AudioTracks();
-  if (audioList && mInfo->HasAudio()) {
-    const TrackInfo& info = mInfo->mAudio;
-    RefPtr<AudioTrack> track = MediaTrackList::CreateAudioTrack(
-    info.mId, info.mKind, info.mLabel, info.mLanguage, info.mEnabled);
-
-    audioList->AddTrack(track);
-  }
-
-  VideoTrackList* videoList = element->VideoTracks();
-  if (videoList && mInfo->HasVideo()) {
-    const TrackInfo& info = mInfo->mVideo;
-    RefPtr<VideoTrack> track = MediaTrackList::CreateVideoTrack(
-    info.mId, info.mKind, info.mLabel, info.mLanguage);
-
-    videoList->AddTrack(track);
-    track->SetEnabledInternal(info.mEnabled, MediaTrack::FIRE_NO_EVENTS);
-  }
-}
-
-void
-MediaDecoder::RemoveMediaTracks()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!IsShutdown());
-
-  HTMLMediaElement* element = GetOwner()->GetMediaElement();
-  if (!element) {
-    return;
-  }
-
-  AudioTrackList* audioList = element->AudioTracks();
-  if (audioList) {
-    audioList->RemoveTracks();
-  }
-
-  VideoTrackList* videoList = element->VideoTracks();
-  if (videoList) {
-    videoList->RemoveTracks();
-  }
-
-  mMediaTracksConstructed = false;
-}
-
 MediaDecoderOwner::NextFrameStatus
 MediaDecoder::NextFrameBufferedStatus()
 {
   MOZ_ASSERT(NS_IsMainThread());
   // Next frame hasn't been decoded yet.
   // Use the buffered range to consider if we have the next frame available.
   media::TimeUnit currentPosition =
     media::TimeUnit::FromMicroseconds(CurrentPosition());
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -394,25 +394,16 @@ private:
    * thread.
    ******/
 
   // Change to a new play state. This updates the mState variable and
   // notifies any thread blocking on this object's monitor of the
   // change. Call on the main thread only.
   virtual void ChangeState(PlayState aState);
 
-  // Called from MetadataLoaded(). Creates audio tracks and adds them to its
-  // owner's audio track list, and implies to video tracks respectively.
-  // Call on the main thread only.
-  void ConstructMediaTracks();
-
-  // Removes all audio tracks and video tracks that are previously added into
-  // the track list. Call on the main thread only.
-  void RemoveMediaTracks();
-
   // Called when the video has completed playing.
   // Call on the main thread only.
   void PlaybackEnded();
 
   void OnSeekRejected();
   void OnSeekResolved();
 
   void SeekingChanged()
@@ -697,20 +688,16 @@ protected:
   dom::AudioChannel mAudioChannel;
 
   // True if the decoder has been directed to minimize its preroll before
   // playback starts. After the first time playback starts, we don't attempt
   // to minimize preroll, as we assume the user is likely to keep playing,
   // or play the media again.
   bool mMinimizePreroll;
 
-  // True if audio tracks and video tracks are constructed and added into the
-  // track list, false if all tracks are removed from the track list.
-  bool mMediaTracksConstructed;
-
   // True if we've already fired metadataloaded.
   bool mFiredMetadataLoaded;
 
   // True if the media is seekable (i.e. supports random access).
   bool mMediaSeekable = true;
 
   // True if the media is only seekable within its buffered ranges
   // like WebMs with no cues.
--- a/dom/media/MediaDecoderOwner.h
+++ b/dom/media/MediaDecoderOwner.h
@@ -6,17 +6,19 @@
 #ifndef MediaDecoderOwner_h_
 #define MediaDecoderOwner_h_
 #include "AbstractMediaDecoder.h"
 #include "nsAutoPtr.h"
 
 namespace mozilla {
 
 class AbstractThread;
+class GMPCrashHelper;
 class VideoFrameContainer;
+class MediaInfo;
 class MediaResult;
 
 namespace dom {
 class HTMLMediaElement;
 } // namespace dom
 
 class MediaDecoderOwner
 {
@@ -152,14 +154,28 @@ public:
   // reference to the decoder to prevent further calls into the decoder.
   virtual void NotifyXPCOMShutdown() = 0;
 
   // Dispatches a "encrypted" event to the HTMLMediaElement, with the
   // provided init data. Actual dispatch may be delayed until HAVE_METADATA.
   // Main thread only.
   virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                                  const nsAString& aInitDataType) = 0;
+
+  // Return the decoder owner's owner document.
+  virtual nsIDocument* GetDocument() const = 0;
+
+  // Called by the media decoder to create audio/video tracks and add to its
+  // owner's track list.
+  virtual void ConstructMediaTracks(const MediaInfo* aInfo) = 0;
+
+  // Called by the media decoder to removes all audio/video tracks from its
+  // owner's track list.
+  virtual void RemoveMediaTracks() = 0;
+
+  // Called by the media decoder to create a GMPCrashHelper.
+  virtual already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() = 0;
 };
 
 } // namespace mozilla
 
 #endif
 
--- a/dom/media/gtest/MockMediaDecoderOwner.h
+++ b/dom/media/gtest/MockMediaDecoderOwner.h
@@ -49,12 +49,16 @@ public:
   }
   void SetAudibleState(bool aAudible) override {}
   void NotifyXPCOMShutdown() override {}
   AbstractThread* AbstractMainThread() const override
   {
     // Non-DocGroup version for Mock.
     return AbstractThread::MainThread();
   }
+  nsIDocument* GetDocument() const { return nullptr; }
+  void ConstructMediaTracks(const MediaInfo* aInfo) {}
+  void RemoveMediaTracks() {}
+  already_AddRefed<GMPCrashHelper> CreateGMPCrashHelper() { return nullptr; }
 };
 }
 
 #endif
--- a/layout/style/ServoArcTypeList.h
+++ b/layout/style/ServoArcTypeList.h
@@ -8,11 +8,12 @@
 
 SERVO_ARC_TYPE(CssRules, ServoCssRules)
 SERVO_ARC_TYPE(StyleSheet, RawServoStyleSheet)
 SERVO_ARC_TYPE(ComputedValues, ServoComputedValues)
 SERVO_ARC_TYPE(DeclarationBlock, RawServoDeclarationBlock)
 SERVO_ARC_TYPE(StyleRule, RawServoStyleRule)
 SERVO_ARC_TYPE(ImportRule, RawServoImportRule)
 SERVO_ARC_TYPE(AnimationValue, RawServoAnimationValue)
+SERVO_ARC_TYPE(AnimationValueMap, RawServoAnimationValueMap)
 SERVO_ARC_TYPE(MediaList, RawServoMediaList)
 SERVO_ARC_TYPE(MediaRule, RawServoMediaRule)
 SERVO_ARC_TYPE(NamespaceRule, RawServoNamespaceRule)
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -119,26 +119,27 @@ SERVO_BINDING_FUNC(Servo_ParseProperty,
                    const nsACString* base,
                    const GeckoParserExtraData* data)
 SERVO_BINDING_FUNC(Servo_GetComputedKeyframeValues, void,
                    RawGeckoKeyframeListBorrowed keyframes,
                    ServoComputedValuesBorrowed style,
                    ServoComputedValuesBorrowedOrNull parent_style,
                    RawServoStyleSetBorrowed set,
                    RawGeckoComputedKeyframeValuesListBorrowedMut result)
+SERVO_BINDING_FUNC(Servo_AnimationValueMap_Push, void,
+                   RawServoAnimationValueMapBorrowed,
+                   nsCSSPropertyID property,
+                   RawServoAnimationValueBorrowed value)
 
 // AnimationValues handling
 SERVO_BINDING_FUNC(Servo_AnimationValues_Interpolate,
                    RawServoAnimationValueStrong,
                    RawServoAnimationValueBorrowed from,
                    RawServoAnimationValueBorrowed to,
                    double progress)
-SERVO_BINDING_FUNC(Servo_AnimationValues_Uncompute,
-                   RawServoDeclarationBlockStrong,
-                   RawServoAnimationValueBorrowedListBorrowed value)
 SERVO_BINDING_FUNC(Servo_AnimationValue_Serialize, void,
                    RawServoAnimationValueBorrowed value,
                    nsCSSPropertyID property,
                    nsAString* buffer)
 SERVO_BINDING_FUNC(Servo_AnimationValue_GetOpacity, float,
                    RawServoAnimationValueBorrowed value)
 SERVO_BINDING_FUNC(Servo_AnimationValue_GetTransform, void,
                    RawServoAnimationValueBorrowed value,
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -8,17 +8,16 @@
 #define mozilla_ServoBindingTypes_h
 
 #include "mozilla/RefPtr.h"
 #include "mozilla/ServoTypes.h"
 #include "mozilla/UniquePtr.h"
 #include "nsStyleAutoArray.h"
 #include "nsTArray.h"
 
-struct RawServoAnimationValue;
 struct RawServoStyleSet;
 
 #define SERVO_ARC_TYPE(name_, type_) struct type_;
 #include "mozilla/ServoArcTypeList.h"
 #undef SERVO_ARC_TYPE
 
 namespace mozilla {
   class ServoElementSnapshot;
@@ -42,17 +41,16 @@ using mozilla::ServoElementSnapshot;
 
 typedef nsINode RawGeckoNode;
 typedef mozilla::dom::Element RawGeckoElement;
 typedef nsIDocument RawGeckoDocument;
 typedef nsPresContext RawGeckoPresContext;
 typedef nsTArray<mozilla::Keyframe> RawGeckoKeyframeList;
 typedef nsTArray<mozilla::ComputedKeyframeValues> RawGeckoComputedKeyframeValuesList;
 typedef nsTArray<mozilla::PropertyStyleAnimationValuePair> RawGeckoAnimationValueList;
-typedef nsTArray<const RawServoAnimationValue*> RawServoAnimationValueBorrowedList;
 typedef nsStyleAutoArray<mozilla::StyleAnimation> RawGeckoStyleAnimationList;
 
 // We have these helper types so that we can directly generate
 // things like &T or Borrowed<T> on the Rust side in the function, providing
 // additional safety benefits.
 //
 // FFI has a problem with templated types, so we just use raw pointers here.
 //
@@ -114,17 +112,16 @@ DECL_BORROWED_REF_TYPE_FOR(RawGeckoDocum
 DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
 DECL_BORROWED_MUT_REF_TYPE_FOR(StyleChildrenIterator)
 DECL_BORROWED_MUT_REF_TYPE_FOR(ServoElementSnapshot)
 DECL_BORROWED_REF_TYPE_FOR(nsCSSValue)
 DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSValue)
 DECL_OWNED_REF_TYPE_FOR(RawGeckoPresContext)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoPresContext)
 DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoAnimationValueList)
-DECL_BORROWED_REF_TYPE_FOR(RawServoAnimationValueBorrowedList)
 DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoKeyframeList)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoKeyframeList)
 DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoComputedKeyframeValuesList)
 DECL_BORROWED_REF_TYPE_FOR(RawGeckoStyleAnimationList)
 
 #undef DECL_ARC_REF_TYPE_FOR
 #undef DECL_OWNED_REF_TYPE_FOR
 #undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -33,17 +33,16 @@
 #include "nsString.h"
 #include "nsStyleStruct.h"
 #include "nsStyleUtil.h"
 #include "nsTArray.h"
 
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Keyframe.h"
-#include "mozilla/ServoAnimationRule.h"
 #include "mozilla/ServoElementSnapshot.h"
 #include "mozilla/ServoRestyleManager.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ElementInlines.h"
 #include "mozilla/LookAndFeel.h"
 
@@ -383,52 +382,46 @@ Gecko_GetHTMLPresentationAttrDeclaration
     }
     return nullptr;
   }
 
   const RefPtr<RawServoDeclarationBlock>& servo = attrs->GetServoStyle();
   return reinterpret_cast<const RawServoDeclarationBlockStrong*>(&servo);
 }
 
-RawServoDeclarationBlockStrong
+bool
 Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
                        nsIAtom* aPseudoTag,
-                       EffectCompositor::CascadeLevel aCascadeLevel)
+                       EffectCompositor::CascadeLevel aCascadeLevel,
+                       RawServoAnimationValueMapBorrowed aAnimationValues)
 {
   MOZ_ASSERT(aElement, "Invalid GeckoElement");
+  MOZ_ASSERT(!aPseudoTag ||
+             aPseudoTag == nsCSSPseudoElements::before ||
+             aPseudoTag == nsCSSPseudoElements::after);
 
-  const RawServoDeclarationBlockStrong emptyDeclarationBlock{ nullptr };
   nsIDocument* doc = aElement->GetComposedDoc();
   if (!doc || !doc->GetShell()) {
-    return emptyDeclarationBlock;
+    return false;
   }
   nsPresContext* presContext = doc->GetShell()->GetPresContext();
-  if (!presContext) {
-    return emptyDeclarationBlock;
+  if (!presContext || !presContext->IsDynamic()) {
+    // For print or print preview, ignore animations.
+    return false;
   }
 
   CSSPseudoElementType pseudoType =
-    aPseudoTag
-    ? nsCSSPseudoElements::GetPseudoType(
-        aPseudoTag,
-        nsCSSProps::EnabledState::eIgnoreEnabledState)
-    : CSSPseudoElementType::NotPseudo;
-  if (pseudoType != CSSPseudoElementType::NotPseudo &&
-      pseudoType != CSSPseudoElementType::before &&
-      pseudoType != CSSPseudoElementType::after) {
-    return emptyDeclarationBlock;
-  }
+    nsCSSPseudoElements::GetPseudoType(
+      aPseudoTag,
+      nsCSSProps::EnabledState::eIgnoreEnabledState);
 
-  ServoAnimationRule* rule =
-    presContext->EffectCompositor()
-               ->GetServoAnimationRule(aElement, pseudoType, aCascadeLevel);
-  if (!rule) {
-    return emptyDeclarationBlock;
-  }
-  return rule->GetValues();
+  return presContext->EffectCompositor()
+    ->GetServoAnimationRule(aElement, pseudoType,
+                            aCascadeLevel,
+                            aAnimationValues);
 }
 
 bool
 Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
                             RawGeckoStyleAnimationListBorrowed aB)
 {
   return *aA == *aB;
 }
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -182,20 +182,21 @@ SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNC
 
 // Style attributes.
 RawServoDeclarationBlockStrongBorrowedOrNull
 Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed element);
 RawServoDeclarationBlockStrongBorrowedOrNull
 Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed element);
 
 // Animations
-RawServoDeclarationBlockStrong
+bool
 Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
                        nsIAtom* aPseudoTag,
-                       mozilla::EffectCompositor::CascadeLevel aCascadeLevel);
+                       mozilla::EffectCompositor::CascadeLevel aCascadeLevel,
+                       RawServoAnimationValueMapBorrowed aAnimationValues);
 bool Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed,
                                  RawGeckoStyleAnimationListBorrowed);
 void Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
                             nsIAtom* aPseudoTagOrNull,
                             ServoComputedValuesBorrowedOrNull aComputedValues,
                             ServoComputedValuesBorrowedOrNull aParentComputedValues);
 bool Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElement,
                                    nsIAtom* aPseudoTagOrNull);
--- a/layout/style/test/chrome/chrome.ini
+++ b/layout/style/test/chrome/chrome.ini
@@ -14,9 +14,10 @@ support-files =
 [test_bug1157097.html]
 [test_bug1160724.xul]
 [test_bug535806.xul]
 [test_display_mode.html]
 tags = fullscreen
 [test_display_mode_reflow.html]
 tags = fullscreen
 [test_hover.html]
+skip-if = stylo # bug 1346353
 [test_moz_document_rules.html]
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -364,17 +364,17 @@ name = "cmake"
 version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cocoa"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -676,17 +676,17 @@ dependencies = [
  "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "embedding"
 version = "0.0.1"
 dependencies = [
- "cocoa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cocoa 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "compositing 0.0.1",
  "devtools 0.0.1",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "glutin_app 0.0.1",
  "libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
  "libservo 0.0.1",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2487,17 +2487,17 @@ dependencies = [
 
 [[package]]
 name = "servo-glutin"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "android_glue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "cocoa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cocoa 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gl_generator 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3351,17 +3351,17 @@ dependencies = [
 "checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
 "checksum caseless 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8950b075cff75cdabadee97148a8b5816c7cf62e5948a6005b5255d564b42fe7"
 "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
 "checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
 "checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10"
 "checksum clang-sys 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f98f0715ff67f27ca6a2f8f0ffc2a56f8edbc7acd57489c29eadc3a15c4eafe"
 "checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
 "checksum cmake 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "a3a6805df695087e7c1bcd9a82e03ad6fb864c8e67ac41b1348229ce5b7f0407"
-"checksum cocoa 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d55b620aff4da7d4b9d85f2974cc62a097146623b75e3f36734fe68d8cef493e"
+"checksum cocoa 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a5d0bcb4d345adf9b4ada6c5bb3e2b87c8150b79c46f3f26446de5f4d48de4b"
 "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d"
 "checksum compiletest_rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f344389765ad7bec166f64c1b39ed6dd2b54d81c4c5dd8af789169351d380c"
 "checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626"
 "checksum core-foundation 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f51ce3b8ebe311c56de14231eb57572c15abebd2d32b3bcb99bcdb9c101f5ac3"
 "checksum core-foundation-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "41115a6aa5d3e1e5ef98148373f25971d1fad53818553f216495f9e67e90a624"
 "checksum core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ead017dcf77f503dc991f6b52de6084eeea60a94b0a652baa9bf88654a28e83f"
 "checksum core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9719616a10f717628e074744f8c55df7b450f7a34d29c196d14f4498aad05d"
 "checksum cssparser 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "35e3e110221f306501253d8d34857040de365ce2d92ac0abb2f06dedc845d9d0"
--- a/servo/components/canvas/canvas_paint_thread.rs
+++ b/servo/components/canvas/canvas_paint_thread.rs
@@ -741,17 +741,17 @@ fn crop_image(image_data: Vec<u8>,
               crop_rect: Rect<f64>) -> Vec<u8>{
     // We're going to iterate over a pixel values array so we need integers
     let crop_rect = crop_rect.to_i32();
     let image_size = image_size.to_i32();
     // Assuming 4 bytes per pixel and row-major order for storage
     // (consecutive elements in a pixel row of the image are contiguous in memory)
     let stride = image_size.width * 4;
     let image_bytes_length = image_size.height * image_size.width * 4;
-    let crop_area_bytes_length = crop_rect.size.height * crop_rect.size.height * 4;
+    let crop_area_bytes_length = crop_rect.size.height * crop_rect.size.width * 4;
     // If the image size is less or equal than the crop area we do nothing
     if image_bytes_length <= crop_area_bytes_length {
         return image_data;
     }
 
     let mut new_image_data = Vec::new();
     let mut src = (crop_rect.origin.y * stride + crop_rect.origin.x * 4) as usize;
     for _ in 0..crop_rect.size.height {
--- a/servo/components/script/dom/servoparser/mod.rs
+++ b/servo/components/script/dom/servoparser/mod.rs
@@ -652,17 +652,22 @@ pub struct FragmentContext<'a> {
 
 #[allow(unrooted_must_root)]
 fn insert(parent: &Node, reference_child: Option<&Node>, child: NodeOrText<JS<Node>>) {
     match child {
         NodeOrText::AppendNode(n) => {
             parent.InsertBefore(&n, reference_child).unwrap();
         },
         NodeOrText::AppendText(t) => {
-            if let Some(text) = parent.GetLastChild().and_then(Root::downcast::<Text>) {
+            let text = reference_child
+                .and_then(Node::GetPreviousSibling)
+                .or_else(|| parent.GetLastChild())
+                .and_then(Root::downcast::<Text>);
+
+            if let Some(text) = text {
                 text.upcast::<CharacterData>().append_data(&t);
             } else {
                 let text = Text::new(String::from(t).into(), &parent.owner_doc());
                 parent.InsertBefore(text.upcast(), reference_child).unwrap();
             }
         },
     }
 }
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -415,17 +415,17 @@ mod bindings {
             "StyleBasicShapeType",
             "StyleGeometryBox",
             "StyleShapeSource",
             "StyleTransition",
             "mozilla::UniquePtr",
             "mozilla::DefaultDelete",
             "mozilla::Side",
             "mozilla::binding_danger::AssertAndSuppressCleanupPolicy",
-            "RawServoAnimationValueBorrowedListBorrowed",
+            "RawServoAnimationValueMapBorrowed",
         ];
         let opaque_types = [
             "std::pair__PCCP",
             "std::namespace::atomic___base", "std::atomic__My_base",
             "std::atomic___base",
             "mozilla::gfx::.*",
             "FallibleTArray",
             "mozilla::dom::Sequence",
@@ -536,16 +536,17 @@ mod bindings {
             "mozilla::css::URLValue",
             "RawGeckoDocument",
             "RawGeckoElement",
             "RawGeckoKeyframeList",
             "RawGeckoComputedKeyframeValuesList",
             "RawGeckoNode",
             "RawGeckoAnimationValueList",
             "RawServoAnimationValue",
+            "RawServoAnimationValueMap",
             "RawServoDeclarationBlock",
             "RawGeckoPresContext",
             "RawGeckoPresContextOwned",
             "RawGeckoStyleAnimationList",
             "GeckoParserExtraData",
             "RefPtr",
             "ThreadSafeURIHolder",
             "ThreadSafePrincipalHolder",
@@ -615,17 +616,16 @@ mod bindings {
             "nsStyleXUL",
             "nsTimingFunction",
             "nscolor",
             "nscoord",
             "nsresult",
             "Loader",
             "ServoStyleSheet",
             "EffectCompositor_CascadeLevel",
-            "RawServoAnimationValueBorrowedListBorrowed",
         ];
         struct ArrayType {
             cpp_type: &'static str,
             rust_type: &'static str
         }
         let array_types = [
             ArrayType { cpp_type: "uintptr_t", rust_type: "usize" },
         ];
--- a/servo/components/style/dom.rs
+++ b/servo/components/style/dom.rs
@@ -254,16 +254,28 @@ pub trait TElement : PartialEq + Debug +
     /// Get this element's style attribute.
     fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>>;
 
     /// Get this element's animation rules.
     fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules {
         AnimationRules(None, None)
     }
 
+    /// Get this element's animation rule.
+    fn get_animation_rule(&self, _pseudo: Option<&PseudoElement>)
+                          -> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
+        None
+    }
+
+    /// Get this element's transition rule.
+    fn get_transition_rule(&self, _pseudo: Option<&PseudoElement>)
+                           -> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
+        None
+    }
+
     /// Get this element's state, for non-tree-structural pseudos.
     fn get_state(&self) -> ElementState;
 
     /// Whether this element has an attribute with a given namespace.
     fn has_attr(&self, namespace: &Namespace, attr: &LocalName) -> bool;
 
     /// Whether an attribute value equals `value`.
     fn attr_equals(&self, namespace: &Namespace, attr: &LocalName, value: &Atom) -> bool;
--- a/servo/components/style/gecko/arc_types.rs
+++ b/servo/components/style/gecko/arc_types.rs
@@ -6,22 +6,22 @@
 //! and release functions. This list corresponds to ServoArcTypeList.h
 //! file in Gecko.
 
 #![allow(non_snake_case, missing_docs)]
 
 use gecko_bindings::bindings::{RawServoMediaList, RawServoMediaRule, RawServoNamespaceRule};
 use gecko_bindings::bindings::{RawServoStyleSheet, RawServoStyleRule, RawServoImportRule};
 use gecko_bindings::bindings::{ServoComputedValues, ServoCssRules};
-use gecko_bindings::structs::{RawServoAnimationValue, RawServoDeclarationBlock};
+use gecko_bindings::structs::{RawServoAnimationValue, RawServoAnimationValueMap, RawServoDeclarationBlock};
 use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI};
 use media_queries::MediaList;
 use parking_lot::RwLock;
 use properties::{ComputedValues, PropertyDeclarationBlock};
-use properties::animated_properties::AnimationValue;
+use properties::animated_properties::{AnimationValue, AnimationValueMap};
 use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule, MediaRule, NamespaceRule};
 
 macro_rules! impl_arc_ffi {
     ($servo_type:ty => $gecko_type:ty [$addref:ident, $release:ident]) => {
         unsafe impl HasFFI for $servo_type {
             type FFIType = $gecko_type;
         }
         unsafe impl HasArcFFI for $servo_type {}
@@ -54,16 +54,19 @@ impl_arc_ffi!(RwLock<StyleRule> => RawSe
               [Servo_StyleRule_AddRef, Servo_StyleRule_Release]);
 
 impl_arc_ffi!(RwLock<ImportRule> => RawServoImportRule
               [Servo_ImportRule_AddRef, Servo_ImportRule_Release]);
 
 impl_arc_ffi!(AnimationValue => RawServoAnimationValue
               [Servo_AnimationValue_AddRef, Servo_AnimationValue_Release]);
 
+impl_arc_ffi!(RwLock<AnimationValueMap> => RawServoAnimationValueMap
+              [Servo_AnimationValueMap_AddRef, Servo_AnimationValueMap_Release]);
+
 impl_arc_ffi!(RwLock<MediaList> => RawServoMediaList
               [Servo_MediaList_AddRef, Servo_MediaList_Release]);
 
 impl_arc_ffi!(RwLock<MediaRule> => RawServoMediaRule
               [Servo_MediaRule_AddRef, Servo_MediaRule_Release]);
 
 impl_arc_ffi!(RwLock<NamespaceRule> => RawServoNamespaceRule
               [Servo_NamespaceRule_AddRef, Servo_NamespaceRule_Release]);
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -41,16 +41,17 @@ use gecko_bindings::structs::{nsIAtom, n
 use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
 use gecko_bindings::structs::NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO;
 use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
 use gecko_bindings::sugar::ownership::HasArcFFI;
 use parking_lot::RwLock;
 use parser::ParserContextExtraData;
 use properties::{ComputedValues, parse_style_attribute};
 use properties::PropertyDeclarationBlock;
+use properties::animated_properties::AnimationValueMap;
 use rule_tree::CascadeLevel as ServoCascadeLevel;
 use selector_parser::{ElementExt, Snapshot};
 use selectors::Element;
 use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_complex_selector};
 use selectors::parser::{AttrSelector, NamespaceConstraint};
 use servo_url::ServoUrl;
 use sink::Push;
 use std::fmt;
@@ -398,35 +399,55 @@ fn selector_flags_to_node_flags(flags: E
     }
     if flags.contains(HAS_EMPTY_SELECTOR) {
         gecko_flags |= NODE_HAS_EMPTY_SELECTOR as u32;
     }
 
     gecko_flags
 }
 
+fn get_animation_rule(element: &GeckoElement,
+                      pseudo: Option<&PseudoElement>,
+                      cascade_level: CascadeLevel)
+                      -> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
+    let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo);
+    let animation_values = Arc::new(RwLock::new(AnimationValueMap::new()));
+    if unsafe { Gecko_GetAnimationRule(element.0, atom_ptr, cascade_level,
+                                       HasArcFFI::arc_as_borrowed(&animation_values)) } {
+        Some(Arc::new(RwLock::new(PropertyDeclarationBlock::from_animation_value_map(&animation_values.read()))))
+    } else {
+        None
+    }
+}
+
 impl<'le> TElement for GeckoElement<'le> {
     type ConcreteNode = GeckoNode<'le>;
 
     fn as_node(&self) -> Self::ConcreteNode {
         unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) }
     }
 
     fn style_attribute(&self) -> Option<&Arc<RwLock<PropertyDeclarationBlock>>> {
         let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) };
         declarations.map(|s| s.as_arc_opt()).unwrap_or(None)
     }
 
     fn get_animation_rules(&self, pseudo: Option<&PseudoElement>) -> AnimationRules {
-        let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo);
-        unsafe {
-            AnimationRules(
-                Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Animations).into_arc_opt(),
-                Gecko_GetAnimationRule(self.0, atom_ptr, CascadeLevel::Transitions).into_arc_opt())
-        }
+        AnimationRules(self.get_animation_rule(pseudo),
+                       self.get_transition_rule(pseudo))
+    }
+
+    fn get_animation_rule(&self, pseudo: Option<&PseudoElement>)
+                          -> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
+        get_animation_rule(self, pseudo, CascadeLevel::Animations)
+    }
+
+    fn get_transition_rule(&self, pseudo: Option<&PseudoElement>)
+                           -> Option<Arc<RwLock<PropertyDeclarationBlock>>> {
+        get_animation_rule(self, pseudo, CascadeLevel::Transitions)
     }
 
     fn get_state(&self) -> ElementState {
         unsafe {
             ElementState::from_bits_truncate(Gecko_ElementState(self.0))
         }
     }
 
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -1,26 +1,22 @@
 /* automatically generated by rust-bindgen */
 
 pub use nsstring::{nsACString, nsAString, nsString};
 type nsACString_internal = nsACString;
 type nsAString_internal = nsAString;
 use gecko_bindings::structs::mozilla::css::URLValue;
-pub type RawServoNamespaceRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoNamespaceRule>;
-pub type RawServoNamespaceRuleBorrowedOrNull<'a> = Option<&'a RawServoNamespaceRule>;
-pub type RawServoNamespaceRuleBorrowed<'a> = &'a RawServoNamespaceRule;
-enum RawServoNamespaceRuleVoid{ }
-pub struct RawServoNamespaceRule(RawServoNamespaceRuleVoid);
 use gecko_bindings::structs::RawGeckoDocument;
 use gecko_bindings::structs::RawGeckoElement;
 use gecko_bindings::structs::RawGeckoKeyframeList;
 use gecko_bindings::structs::RawGeckoComputedKeyframeValuesList;
 use gecko_bindings::structs::RawGeckoNode;
 use gecko_bindings::structs::RawGeckoAnimationValueList;
 use gecko_bindings::structs::RawServoAnimationValue;
+use gecko_bindings::structs::RawServoAnimationValueMap;
 use gecko_bindings::structs::RawServoDeclarationBlock;
 use gecko_bindings::structs::RawGeckoPresContext;
 use gecko_bindings::structs::RawGeckoPresContextOwned;
 use gecko_bindings::structs::RawGeckoStyleAnimationList;
 use gecko_bindings::structs::GeckoParserExtraData;
 use gecko_bindings::structs::RefPtr;
 use gecko_bindings::structs::ThreadSafeURIHolder;
 use gecko_bindings::structs::ThreadSafePrincipalHolder;
@@ -174,17 +170,16 @@ unsafe impl Send for nsStyleXUL {}
 unsafe impl Sync for nsStyleXUL {}
 use gecko_bindings::structs::nsTimingFunction;
 use gecko_bindings::structs::nscolor;
 use gecko_bindings::structs::nscoord;
 use gecko_bindings::structs::nsresult;
 use gecko_bindings::structs::Loader;
 use gecko_bindings::structs::ServoStyleSheet;
 use gecko_bindings::structs::EffectCompositor_CascadeLevel;
-use gecko_bindings::structs::RawServoAnimationValueBorrowedListBorrowed;
 pub type nsTArrayBorrowed_uintptr_t<'a> = &'a mut ::gecko_bindings::structs::nsTArray<usize>;
 pub type ServoCssRulesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoCssRules>;
 pub type ServoCssRulesBorrowed<'a> = &'a ServoCssRules;
 pub type ServoCssRulesBorrowedOrNull<'a> = Option<&'a ServoCssRules>;
 enum ServoCssRulesVoid { }
 pub struct ServoCssRules(ServoCssRulesVoid);
 pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>;
 pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet;
@@ -207,26 +202,34 @@ pub struct RawServoStyleRule(RawServoSty
 pub type RawServoImportRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoImportRule>;
 pub type RawServoImportRuleBorrowed<'a> = &'a RawServoImportRule;
 pub type RawServoImportRuleBorrowedOrNull<'a> = Option<&'a RawServoImportRule>;
 enum RawServoImportRuleVoid { }
 pub struct RawServoImportRule(RawServoImportRuleVoid);
 pub type RawServoAnimationValueStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoAnimationValue>;
 pub type RawServoAnimationValueBorrowed<'a> = &'a RawServoAnimationValue;
 pub type RawServoAnimationValueBorrowedOrNull<'a> = Option<&'a RawServoAnimationValue>;
+pub type RawServoAnimationValueMapStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoAnimationValueMap>;
+pub type RawServoAnimationValueMapBorrowed<'a> = &'a RawServoAnimationValueMap;
+pub type RawServoAnimationValueMapBorrowedOrNull<'a> = Option<&'a RawServoAnimationValueMap>;
 pub type RawServoMediaListStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaList>;
 pub type RawServoMediaListBorrowed<'a> = &'a RawServoMediaList;
 pub type RawServoMediaListBorrowedOrNull<'a> = Option<&'a RawServoMediaList>;
 enum RawServoMediaListVoid { }
 pub struct RawServoMediaList(RawServoMediaListVoid);
 pub type RawServoMediaRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoMediaRule>;
 pub type RawServoMediaRuleBorrowed<'a> = &'a RawServoMediaRule;
 pub type RawServoMediaRuleBorrowedOrNull<'a> = Option<&'a RawServoMediaRule>;
 enum RawServoMediaRuleVoid { }
 pub struct RawServoMediaRule(RawServoMediaRuleVoid);
+pub type RawServoNamespaceRuleStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoNamespaceRule>;
+pub type RawServoNamespaceRuleBorrowed<'a> = &'a RawServoNamespaceRule;
+pub type RawServoNamespaceRuleBorrowedOrNull<'a> = Option<&'a RawServoNamespaceRule>;
+enum RawServoNamespaceRuleVoid { }
+pub struct RawServoNamespaceRule(RawServoNamespaceRuleVoid);
 pub type RawServoStyleSetOwned = ::gecko_bindings::sugar::ownership::Owned<RawServoStyleSet>;
 pub type RawServoStyleSetOwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<RawServoStyleSet>;
 pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet;
 pub type RawServoStyleSetBorrowedOrNull<'a> = Option<&'a RawServoStyleSet>;
 pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet;
 pub type RawServoStyleSetBorrowedMutOrNull<'a> = Option<&'a mut RawServoStyleSet>;
 enum RawServoStyleSetVoid { }
 pub struct RawServoStyleSet(RawServoStyleSetVoid);
@@ -321,28 +324,42 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_AnimationValue_AddRef(ptr: RawServoAnimationValueBorrowed);
 }
 extern "C" {
     pub fn Servo_AnimationValue_Release(ptr: RawServoAnimationValueBorrowed);
 }
 extern "C" {
+    pub fn Servo_AnimationValueMap_AddRef(ptr:
+                                              RawServoAnimationValueMapBorrowed);
+}
+extern "C" {
+    pub fn Servo_AnimationValueMap_Release(ptr:
+                                               RawServoAnimationValueMapBorrowed);
+}
+extern "C" {
     pub fn Servo_MediaList_AddRef(ptr: RawServoMediaListBorrowed);
 }
 extern "C" {
     pub fn Servo_MediaList_Release(ptr: RawServoMediaListBorrowed);
 }
 extern "C" {
     pub fn Servo_MediaRule_AddRef(ptr: RawServoMediaRuleBorrowed);
 }
 extern "C" {
     pub fn Servo_MediaRule_Release(ptr: RawServoMediaRuleBorrowed);
 }
 extern "C" {
+    pub fn Servo_NamespaceRule_AddRef(ptr: RawServoNamespaceRuleBorrowed);
+}
+extern "C" {
+    pub fn Servo_NamespaceRule_Release(ptr: RawServoNamespaceRuleBorrowed);
+}
+extern "C" {
     pub fn Servo_StyleSet_Drop(ptr: RawServoStyleSetOwned);
 }
 extern "C" {
     pub fn Gecko_AddRefPrincipalArbitraryThread(aPtr:
                                                     *mut ThreadSafePrincipalHolder);
 }
 extern "C" {
     pub fn Gecko_ReleasePrincipalArbitraryThread(aPtr:
@@ -559,18 +576,20 @@ extern "C" {
     pub fn Gecko_GetHTMLPresentationAttrDeclarationBlock(element:
                                                              RawGeckoElementBorrowed)
      -> RawServoDeclarationBlockStrongBorrowedOrNull;
 }
 extern "C" {
     pub fn Gecko_GetAnimationRule(aElement: RawGeckoElementBorrowed,
                                   aPseudoTag: *mut nsIAtom,
                                   aCascadeLevel:
-                                      EffectCompositor_CascadeLevel)
-     -> RawServoDeclarationBlockStrong;
+                                      EffectCompositor_CascadeLevel,
+                                  aAnimationValues:
+                                      RawServoAnimationValueMapBorrowed)
+     -> bool;
 }
 extern "C" {
     pub fn Gecko_StyleAnimationsEquals(arg1:
                                            RawGeckoStyleAnimationListBorrowed,
                                        arg2:
                                            RawGeckoStyleAnimationListBorrowed)
      -> bool;
 }
@@ -1291,37 +1310,36 @@ extern "C" {
 extern "C" {
     pub fn Servo_StyleSheet_Empty(parsing_mode: SheetParsingMode)
      -> RawServoStyleSheetStrong;
 }
 extern "C" {
     pub fn Servo_StyleSheet_FromUTF8Bytes(loader: *mut Loader,
                                           gecko_stylesheet:
                                               *mut ServoStyleSheet,
-                                          data: *const nsACString_internal,
+                                          data: *const nsACString,
                                           parsing_mode: SheetParsingMode,
-                                          base_url:
-                                              *const nsACString_internal,
+                                          base_url: *const nsACString,
                                           base: *mut ThreadSafeURIHolder,
                                           referrer: *mut ThreadSafeURIHolder,
                                           principal:
                                               *mut ThreadSafePrincipalHolder)
      -> RawServoStyleSheetStrong;
 }
 extern "C" {
     pub fn Servo_ImportRule_GetSheet(import_rule: RawServoImportRuleBorrowed)
      -> RawServoStyleSheetStrong;
 }
 extern "C" {
     pub fn Servo_StyleSheet_ClearAndUpdate(stylesheet:
                                                RawServoStyleSheetBorrowed,
                                            loader: *mut Loader,
                                            gecko_stylesheet:
                                                *mut ServoStyleSheet,
-                                           data: *const nsACString_internal,
+                                           data: *const nsACString,
                                            base: *mut ThreadSafeURIHolder,
                                            referrer: *mut ThreadSafeURIHolder,
                                            principal:
                                                *mut ThreadSafePrincipalHolder);
 }
 extern "C" {
     pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed)
      -> bool;
@@ -1365,136 +1383,145 @@ extern "C" {
     pub fn Servo_StyleSet_FlushStyleSheets(set: RawServoStyleSetBorrowed);
 }
 extern "C" {
     pub fn Servo_StyleSet_NoteStyleSheetsChanged(set:
                                                      RawServoStyleSetBorrowed);
 }
 extern "C" {
     pub fn Servo_StyleSet_FillKeyframesForName(set: RawServoStyleSetBorrowed,
-                                               property:
-                                                   *const nsACString_internal,
+                                               property: *const nsACString,
                                                timing_function:
                                                    *const nsTimingFunction,
                                                computed_values:
                                                    ServoComputedValuesBorrowed,
                                                keyframe_list:
                                                    RawGeckoKeyframeListBorrowedMut)
      -> bool;
 }
 extern "C" {
     pub fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
                                     result: nsTArrayBorrowed_uintptr_t);
 }
 extern "C" {
+    pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
+                                     sheet: RawServoStyleSheetBorrowed,
+                                     rule: *const nsACString, index: u32,
+                                     nested: bool, rule_type: *mut u16)
+     -> nsresult;
+}
+extern "C" {
+    pub fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32)
+     -> nsresult;
+}
+extern "C" {
     pub fn Servo_CssRules_GetStyleRuleAt(rules: ServoCssRulesBorrowed,
                                          index: u32)
      -> RawServoStyleRuleStrong;
 }
 extern "C" {
+    pub fn Servo_StyleRule_Debug(rule: RawServoStyleRuleBorrowed,
+                                 result: *mut nsACString);
+}
+extern "C" {
+    pub fn Servo_StyleRule_GetCssText(rule: RawServoStyleRuleBorrowed,
+                                      result: *mut nsAString);
+}
+extern "C" {
     pub fn Servo_CssRules_GetMediaRuleAt(rules: ServoCssRulesBorrowed,
                                          index: u32)
      -> RawServoMediaRuleStrong;
 }
 extern "C" {
+    pub fn Servo_MediaRule_Debug(rule: RawServoMediaRuleBorrowed,
+                                 result: *mut nsACString);
+}
+extern "C" {
+    pub fn Servo_MediaRule_GetCssText(rule: RawServoMediaRuleBorrowed,
+                                      result: *mut nsAString);
+}
+extern "C" {
     pub fn Servo_CssRules_GetNamespaceRuleAt(rules: ServoCssRulesBorrowed,
                                              index: u32)
      -> RawServoNamespaceRuleStrong;
 }
 extern "C" {
-    pub fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed,
-                                     sheet: RawServoStyleSheetBorrowed,
-                                     rule: *const nsACString_internal,
-                                     index: u32, nested: bool,
-                                     rule_type: *mut u16) -> nsresult;
+    pub fn Servo_NamespaceRule_Debug(rule: RawServoNamespaceRuleBorrowed,
+                                     result: *mut nsACString);
 }
 extern "C" {
-    pub fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32)
-     -> nsresult;
-}
-extern "C" {
-    pub fn Servo_StyleRule_Debug(rule: RawServoStyleRuleBorrowed,
-                                 result: *mut nsACString_internal);
+    pub fn Servo_NamespaceRule_GetCssText(rule: RawServoNamespaceRuleBorrowed,
+                                          result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_StyleRule_SetStyle(rule: RawServoStyleRuleBorrowed,
                                     declarations:
                                         RawServoDeclarationBlockBorrowed);
 }
 extern "C" {
-    pub fn Servo_StyleRule_GetCssText(rule: RawServoStyleRuleBorrowed,
-                                      result: *mut nsAString_internal);
-}
-extern "C" {
     pub fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed,
-                                           result: *mut nsAString_internal);
-}
-extern "C" {
-    pub fn Servo_MediaRule_Debug(rule: RawServoMediaRuleBorrowed,
-                                 result: *mut nsACString_internal);
+                                           result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_MediaRule_GetMedia(rule: RawServoMediaRuleBorrowed)
      -> RawServoMediaListStrong;
 }
 extern "C" {
     pub fn Servo_MediaRule_GetRules(rule: RawServoMediaRuleBorrowed)
      -> ServoCssRulesStrong;
 }
 extern "C" {
-    pub fn Servo_MediaRule_GetCssText(rule: RawServoMediaRuleBorrowed,
-                                      result: *mut nsAString_internal);
-}
-extern "C" {
-    pub fn Servo_NamespaceRule_Debug(rule: RawServoNamespaceRuleBorrowed,
-                                     result: *mut nsACString_internal);
+    pub fn Servo_NamespaceRule_GetPrefix(rule: RawServoNamespaceRuleBorrowed)
+     -> *mut nsIAtom;
 }
 extern "C" {
-    pub fn Servo_NamespaceRule_GetCssText(rule: RawServoNamespaceRuleBorrowed,
-                                          result: *mut nsAString_internal);
+    pub fn Servo_NamespaceRule_GetURI(rule: RawServoNamespaceRuleBorrowed)
+     -> *mut nsIAtom;
 }
 extern "C" {
-    pub fn Servo_ParseProperty(property: *const nsACString_internal,
-                               value: *const nsACString_internal,
-                               base: *const nsACString_internal,
+    pub fn Servo_ParseProperty(property: *const nsACString,
+                               value: *const nsACString,
+                               base: *const nsACString,
                                data: *const GeckoParserExtraData)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_GetComputedKeyframeValues(keyframes:
                                                RawGeckoKeyframeListBorrowed,
                                            style: ServoComputedValuesBorrowed,
                                            parent_style:
                                                ServoComputedValuesBorrowedOrNull,
                                            set: RawServoStyleSetBorrowed,
                                            result:
                                                RawGeckoComputedKeyframeValuesListBorrowedMut);
 }
 extern "C" {
+    pub fn Servo_AnimationValueMap_Push(arg1:
+                                            RawServoAnimationValueMapBorrowed,
+                                        property: nsCSSPropertyID,
+                                        value:
+                                            RawServoAnimationValueBorrowed);
+}
+extern "C" {
     pub fn Servo_AnimationValues_Interpolate(from:
                                                  RawServoAnimationValueBorrowed,
                                              to:
                                                  RawServoAnimationValueBorrowed,
                                              progress: f64)
      -> RawServoAnimationValueStrong;
 }
 extern "C" {
-    pub fn Servo_AnimationValues_Uncompute(value:
-                                               RawServoAnimationValueBorrowedListBorrowed)
-     -> RawServoDeclarationBlockStrong;
-}
-extern "C" {
     pub fn Servo_AnimationValue_Serialize(value:
                                               RawServoAnimationValueBorrowed,
                                           property: nsCSSPropertyID,
-                                          buffer: *mut nsAString_internal);
+                                          buffer: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_AnimationValue_GetOpacity(value:
                                                RawServoAnimationValueBorrowed)
      -> f32;
 }
 extern "C" {
     pub fn Servo_AnimationValue_GetTransform(value:
@@ -1505,18 +1532,18 @@ extern "C" {
 extern "C" {
     pub fn Servo_AnimationValue_DeepEqual(arg1:
                                               RawServoAnimationValueBorrowed,
                                           arg2:
                                               RawServoAnimationValueBorrowed)
      -> bool;
 }
 extern "C" {
-    pub fn Servo_ParseStyleAttribute(data: *const nsACString_internal,
-                                     base: *const nsACString_internal,
+    pub fn Servo_ParseStyleAttribute(data: *const nsACString,
+                                     base: *const nsACString,
                                      extraData: *const GeckoParserExtraData)
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_CreateEmpty()
      -> RawServoDeclarationBlockStrong;
 }
 extern "C" {
@@ -1527,93 +1554,83 @@ extern "C" {
 extern "C" {
     pub fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed,
                                          b: RawServoDeclarationBlockBorrowed)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_GetCssText(declarations:
                                                  RawServoDeclarationBlockBorrowed,
-                                             result: *mut nsAString_internal);
+                                             result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SerializeOneValue(declarations:
                                                         RawServoDeclarationBlockBorrowed,
                                                     property: nsCSSPropertyID,
-                                                    buffer:
-                                                        *mut nsAString_internal);
+                                                    buffer: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_Count(declarations:
                                             RawServoDeclarationBlockBorrowed)
      -> u32;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_GetNthProperty(declarations:
                                                      RawServoDeclarationBlockBorrowed,
                                                  index: u32,
-                                                 result:
-                                                     *mut nsAString_internal)
+                                                 result: *mut nsAString)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_GetPropertyValue(declarations:
                                                        RawServoDeclarationBlockBorrowed,
                                                    property:
-                                                       *const nsACString_internal,
-                                                   value:
-                                                       *mut nsAString_internal);
+                                                       *const nsACString,
+                                                   value: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_GetPropertyValueById(declarations:
                                                            RawServoDeclarationBlockBorrowed,
                                                        property:
                                                            nsCSSPropertyID,
-                                                       value:
-                                                           *mut nsAString_internal);
+                                                       value: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations:
                                                              RawServoDeclarationBlockBorrowed,
                                                          property:
-                                                             *const nsACString_internal)
+                                                             *const nsACString)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SetProperty(declarations:
                                                   RawServoDeclarationBlockBorrowed,
-                                              property:
-                                                  *const nsACString_internal,
-                                              value:
-                                                  *const nsACString_internal,
+                                              property: *const nsACString,
+                                              value: *const nsACString,
                                               is_important: bool,
-                                              base:
-                                                  *const nsACString_internal,
+                                              base: *const nsACString,
                                               data:
                                                   *const GeckoParserExtraData)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SetPropertyById(declarations:
                                                       RawServoDeclarationBlockBorrowed,
                                                   property: nsCSSPropertyID,
-                                                  value:
-                                                      *const nsACString_internal,
+                                                  value: *const nsACString,
                                                   is_important: bool,
-                                                  base:
-                                                      *const nsACString_internal,
+                                                  base: *const nsACString,
                                                   data:
                                                       *const GeckoParserExtraData)
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_RemoveProperty(declarations:
                                                      RawServoDeclarationBlockBorrowed,
-                                                 property:
-                                                     *const nsACString_internal);
+                                                 property: *const nsACString);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_RemovePropertyById(declarations:
                                                          RawServoDeclarationBlockBorrowed,
                                                      property:
                                                          nsCSSPropertyID);
 }
 extern "C" {
@@ -1667,57 +1684,53 @@ extern "C" {
     pub fn Servo_DeclarationBlock_SetColorValue(declarations:
                                                     RawServoDeclarationBlockBorrowed,
                                                 property: nsCSSPropertyID,
                                                 value: nscolor);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SetFontFamily(declarations:
                                                     RawServoDeclarationBlockBorrowed,
-                                                value:
-                                                    *const nsAString_internal);
+                                                value: *const nsAString);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarations:
                                                                      RawServoDeclarationBlockBorrowed);
 }
 extern "C" {
     pub fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed,
-                                   result: *mut nsAString_internal);
+                                   result: *mut nsAString);
 }
 extern "C" {
     pub fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed,
-                                   text: *const nsACString_internal);
+                                   text: *const nsACString);
 }
 extern "C" {
     pub fn Servo_MediaList_GetLength(list: RawServoMediaListBorrowed) -> u32;
 }
 extern "C" {
     pub fn Servo_MediaList_GetMediumAt(list: RawServoMediaListBorrowed,
-                                       index: u32,
-                                       result: *mut nsAString_internal)
+                                       index: u32, result: *mut nsAString)
      -> bool;
 }
 extern "C" {
     pub fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed,
-                                        new_medium:
-                                            *const nsACString_internal);
+                                        new_medium: *const nsACString);
 }
 extern "C" {
     pub fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed,
-                                        old_medium:
-                                            *const nsACString_internal)
+                                        old_medium: *const nsACString)
      -> bool;
 }
 extern "C" {
-    pub fn Servo_CSSSupports2(name: *const nsACString_internal,
-                              value: *const nsACString_internal) -> bool;
+    pub fn Servo_CSSSupports2(name: *const nsACString,
+                              value: *const nsACString) -> bool;
 }
 extern "C" {
-    pub fn Servo_CSSSupports(cond: *const nsACString_internal) -> bool;
+    pub fn Servo_CSSSupports(cond: *const nsACString) -> bool;
 }
 extern "C" {
     pub fn Servo_ComputedValues_GetForAnonymousBox(parent_style_or_null:
                                                        ServoComputedValuesBorrowedOrNull,
                                                    pseudoTag: *mut nsIAtom,
                                                    skip_display_fixup: bool,
                                                    set:
                                                        RawServoStyleSetBorrowed)
--- a/servo/components/style/gecko_bindings/structs_debug.rs
+++ b/servo/components/style/gecko_bindings/structs_debug.rs
@@ -1439,16 +1439,202 @@ pub mod root {
             pub struct LinkedListElementTraits<T> {
                 pub _address: u8,
                 pub _phantom_0: ::std::marker::PhantomData<T>,
             }
             pub type LinkedListElementTraits_RawType<T> = *mut T;
             pub type LinkedListElementTraits_ConstRawType<T> = *mut T;
             pub type LinkedListElementTraits_ClientType<T> = *mut T;
             pub type LinkedListElementTraits_ConstClientType<T> = *mut T;
+            #[repr(C)]
+            #[derive(Debug, Copy)]
+            pub struct nsStringRepr {
+                pub mData: *mut root::mozilla::detail::nsStringRepr_char_type,
+                pub mLength: root::mozilla::detail::nsStringRepr_size_type,
+                pub mFlags: u32,
+            }
+            pub type nsStringRepr_fallible_t = root::mozilla::fallible_t;
+            pub type nsStringRepr_char_type = u16;
+            pub type nsStringRepr_self_type =
+                root::mozilla::detail::nsStringRepr;
+            pub type nsStringRepr_base_string_type =
+                root::mozilla::detail::nsStringRepr_self_type;
+            pub type nsStringRepr_substring_type = root::nsAString;
+            pub type nsStringRepr_substring_tuple_type =
+                root::nsSubstringTuple;
+            pub type nsStringRepr_string_type = ::nsstring::nsStringRepr;
+            pub type nsStringRepr_const_iterator =
+                root::nsReadingIterator<u16>;
+            pub type nsStringRepr_iterator = root::nsWritingIterator<u16>;
+            pub type nsStringRepr_comparator_type = root::nsStringComparator;
+            pub type nsStringRepr_char_iterator =
+                *mut root::mozilla::detail::nsStringRepr_char_type;
+            pub type nsStringRepr_const_char_iterator =
+                *const root::mozilla::detail::nsStringRepr_char_type;
+            pub type nsStringRepr_index_type = u32;
+            pub type nsStringRepr_size_type = u32;
+            pub const nsStringRepr_F_NONE:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_NONE;
+            pub const nsStringRepr_F_TERMINATED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_TERMINATED;
+            pub const nsStringRepr_F_VOIDED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_VOIDED;
+            pub const nsStringRepr_F_SHARED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_SHARED;
+            pub const nsStringRepr_F_OWNED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_OWNED;
+            pub const nsStringRepr_F_FIXED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_FIXED;
+            pub const nsStringRepr_F_LITERAL:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_LITERAL;
+            pub const nsStringRepr_F_CLASS_FIXED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_CLASS_FIXED;
+            #[repr(u32)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum nsStringRepr__bindgen_ty_1 {
+                F_NONE = 0,
+                F_TERMINATED = 1,
+                F_VOIDED = 2,
+                F_SHARED = 4,
+                F_OWNED = 8,
+                F_FIXED = 16,
+                F_LITERAL = 32,
+                F_CLASS_FIXED = 65536,
+            }
+            #[test]
+            fn bindgen_test_layout_nsStringRepr() {
+                assert_eq!(::std::mem::size_of::<nsStringRepr>() , 16usize ,
+                           concat ! (
+                           "Size of: " , stringify ! ( nsStringRepr ) ));
+                assert_eq! (::std::mem::align_of::<nsStringRepr>() , 8usize ,
+                            concat ! (
+                            "Alignment of " , stringify ! ( nsStringRepr ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsStringRepr ) ) . mData as *
+                            const _ as usize } , 0usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsStringRepr ) , "::" , stringify ! ( mData ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsStringRepr ) ) . mLength as
+                            * const _ as usize } , 8usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsStringRepr ) , "::" , stringify ! ( mLength )
+                            ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsStringRepr ) ) . mFlags as
+                            * const _ as usize } , 12usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsStringRepr ) , "::" , stringify ! ( mFlags ) ));
+            }
+            impl Clone for nsStringRepr {
+                fn clone(&self) -> Self { *self }
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy)]
+            pub struct nsCStringRepr {
+                pub mData: *mut root::mozilla::detail::nsCStringRepr_char_type,
+                pub mLength: root::mozilla::detail::nsCStringRepr_size_type,
+                pub mFlags: u32,
+            }
+            pub type nsCStringRepr_fallible_t = root::mozilla::fallible_t;
+            pub type nsCStringRepr_char_type = ::std::os::raw::c_char;
+            pub type nsCStringRepr_self_type =
+                root::mozilla::detail::nsCStringRepr;
+            pub type nsCStringRepr_base_string_type =
+                root::mozilla::detail::nsCStringRepr_self_type;
+            pub type nsCStringRepr_substring_type = root::nsACString;
+            pub type nsCStringRepr_substring_tuple_type =
+                root::nsCSubstringTuple;
+            pub type nsCStringRepr_string_type = root::nsCString;
+            pub type nsCStringRepr_const_iterator =
+                root::nsReadingIterator<::std::os::raw::c_char>;
+            pub type nsCStringRepr_iterator =
+                root::nsWritingIterator<::std::os::raw::c_char>;
+            pub type nsCStringRepr_comparator_type =
+                root::nsCStringComparator;
+            pub type nsCStringRepr_char_iterator =
+                *mut root::mozilla::detail::nsCStringRepr_char_type;
+            pub type nsCStringRepr_const_char_iterator =
+                *const root::mozilla::detail::nsCStringRepr_char_type;
+            pub type nsCStringRepr_index_type = u32;
+            pub type nsCStringRepr_size_type = u32;
+            pub const nsCStringRepr_F_NONE:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_NONE;
+            pub const nsCStringRepr_F_TERMINATED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_TERMINATED;
+            pub const nsCStringRepr_F_VOIDED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_VOIDED;
+            pub const nsCStringRepr_F_SHARED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_SHARED;
+            pub const nsCStringRepr_F_OWNED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_OWNED;
+            pub const nsCStringRepr_F_FIXED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_FIXED;
+            pub const nsCStringRepr_F_LITERAL:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_LITERAL;
+            pub const nsCStringRepr_F_CLASS_FIXED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_CLASS_FIXED;
+            #[repr(u32)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum nsCStringRepr__bindgen_ty_1 {
+                F_NONE = 0,
+                F_TERMINATED = 1,
+                F_VOIDED = 2,
+                F_SHARED = 4,
+                F_OWNED = 8,
+                F_FIXED = 16,
+                F_LITERAL = 32,
+                F_CLASS_FIXED = 65536,
+            }
+            #[test]
+            fn bindgen_test_layout_nsCStringRepr() {
+                assert_eq!(::std::mem::size_of::<nsCStringRepr>() , 16usize ,
+                           concat ! (
+                           "Size of: " , stringify ! ( nsCStringRepr ) ));
+                assert_eq! (::std::mem::align_of::<nsCStringRepr>() , 8usize ,
+                            concat ! (
+                            "Alignment of " , stringify ! ( nsCStringRepr )
+                            ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsCStringRepr ) ) . mData as
+                            * const _ as usize } , 0usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsCStringRepr ) , "::" , stringify ! ( mData ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsCStringRepr ) ) . mLength
+                            as * const _ as usize } , 8usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsCStringRepr ) , "::" , stringify ! ( mLength )
+                            ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsCStringRepr ) ) . mFlags as
+                            * const _ as usize } , 12usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsCStringRepr ) , "::" , stringify ! ( mFlags )
+                            ));
+            }
+            impl Clone for nsCStringRepr {
+                fn clone(&self) -> Self { *self }
+            }
         }
         pub type MallocSizeOf =
             ::std::option::Option<unsafe extern "C" fn(p:
                                                            *const ::std::os::raw::c_void)
                                       -> ::std::os::raw::c_ulong>;
         #[repr(C)]
         #[derive(Debug)]
         pub struct OwningNonNull<T> {
@@ -1986,20 +2172,20 @@ pub mod root {
                                ));
                     assert_eq! (::std::mem::align_of::<FastErrorResult>() ,
                                 8usize , concat ! (
                                 "Alignment of " , stringify ! (
                                 FastErrorResult ) ));
                 }
                 #[repr(C)]
                 pub struct FakeString {
-                    pub mData: *mut root::nsAString_internal_char_type,
-                    pub mLength: root::nsAString_internal_size_type,
+                    pub mData: *mut root::mozilla::detail::nsStringRepr_char_type,
+                    pub mLength: root::mozilla::detail::nsStringRepr_size_type,
                     pub mFlags: u32,
-                    pub mInlineStorage: [root::nsAString_internal_char_type; 64usize],
+                    pub mInlineStorage: [root::mozilla::detail::nsStringRepr_char_type; 64usize],
                 }
                 #[repr(C)]
                 #[derive(Debug)]
                 pub struct FakeString_StringAsserter {
                     pub _base: ::nsstring::nsStringRepr,
                 }
                 #[test]
                 fn bindgen_test_layout_FakeString_StringAsserter() {
@@ -2944,17 +3130,17 @@ pub mod root {
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct NodeInfo_NodeInfoInner {
                 pub mName: root::nsCOMPtr<root::nsIAtom>,
                 pub mPrefix: root::nsCOMPtr<root::nsIAtom>,
                 pub mNamespaceID: i32,
                 pub mNodeType: u16,
-                pub mNameString: *const root::nsAString_internal,
+                pub mNameString: *const root::nsAString,
                 pub mExtraName: root::nsCOMPtr<root::nsIAtom>,
             }
             #[test]
             fn bindgen_test_layout_NodeInfo_NodeInfoInner() {
                 assert_eq!(::std::mem::size_of::<NodeInfo_NodeInfoInner>() ,
                            40usize , concat ! (
                            "Size of: " , stringify ! ( NodeInfo_NodeInfoInner
                            ) ));
@@ -4108,16 +4294,17 @@ pub mod root {
                 pub _base_1: root::nsWrapperCache,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
                 pub _mOwningThread: root::nsAutoOwningThread,
                 pub mOwner: root::nsCOMPtr<root::nsISupports>,
                 pub mTime: root::DOMHighResTimeStamp,
                 pub mRootBounds: root::RefPtr<root::mozilla::dom::DOMRect>,
                 pub mBoundingClientRect: root::RefPtr<root::mozilla::dom::DOMRect>,
                 pub mIntersectionRect: root::RefPtr<root::mozilla::dom::DOMRect>,
+                pub mIsIntersecting: bool,
                 pub mTarget: root::RefPtr<root::mozilla::dom::Element>,
                 pub mIntersectionRatio: f64,
             }
             pub type DOMIntersectionObserverEntry_HasThreadSafeRefCnt =
                 root::mozilla::FalseType;
             #[repr(C)]
             #[derive(Debug, Copy)]
             pub struct DOMIntersectionObserverEntry_cycleCollection {
@@ -4142,17 +4329,17 @@ pub mod root {
                       "_ZN7mozilla3dom28DOMIntersectionObserverEntry21_cycleCollectorGlobalE"]
                 pub static mut
                            DOMIntersectionObserverEntry__cycleCollectorGlobal:
                            root::mozilla::dom::DOMIntersectionObserverEntry_cycleCollection;
             }
             #[test]
             fn bindgen_test_layout_DOMIntersectionObserverEntry() {
                 assert_eq!(::std::mem::size_of::<DOMIntersectionObserverEntry>()
-                           , 104usize , concat ! (
+                           , 112usize , concat ! (
                            "Size of: " , stringify ! (
                            DOMIntersectionObserverEntry ) ));
                 assert_eq! (::std::mem::align_of::<DOMIntersectionObserverEntry>()
                             , 8usize , concat ! (
                             "Alignment of " , stringify ! (
                             DOMIntersectionObserverEntry ) ));
             }
             #[repr(C)]
@@ -8022,19 +8209,16 @@ pub mod root {
                         "Alignment of " , stringify ! ( StyleAnimationValue )
                         ));
         }
         impl Clone for StyleAnimationValue {
             fn clone(&self) -> Self { *self }
         }
         #[repr(C)]
         #[derive(Debug, Copy, Clone)]
-        pub struct ServoAnimationRule([u8; 0]);
-        #[repr(C)]
-        #[derive(Debug, Copy, Clone)]
         pub struct AnimationPerformanceWarning([u8; 0]);
         pub type CSSPseudoClassTypeBase = u8;
         #[repr(u8)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum CSSPseudoClassType {
             empty = 0,
             mozOnlyWhitespace = 1,
             mozEmptyExceptChildrenWithLocalname = 2,
@@ -8164,22 +8348,16 @@ pub mod root {
         #[derive(Debug, Copy, Clone)]
         pub struct pair<_T1, _T2> {
             pub first: _T1,
             pub second: _T2,
         }
         pub type pair_first_type<_T1> = _T1;
         pub type pair_second_type<_T2> = _T2;
         #[repr(C)]
-        pub struct atomic<_Tp> {
-            pub _base: (),
-            pub _phantom_0: ::std::marker::PhantomData<_Tp>,
-        }
-        pub type atomic___base = [u8; 0usize];
-        #[repr(C)]
         #[derive(Debug, Copy)]
         pub struct input_iterator_tag {
             pub _address: u8,
         }
         #[test]
         fn bindgen_test_layout_input_iterator_tag() {
             assert_eq!(::std::mem::size_of::<input_iterator_tag>() , 1usize ,
                        concat ! (
@@ -8188,284 +8366,269 @@ pub mod root {
                         , concat ! (
                         "Alignment of " , stringify ! ( input_iterator_tag )
                         ));
         }
         impl Clone for input_iterator_tag {
             fn clone(&self) -> Self { *self }
         }
         #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct forward_iterator_tag {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_forward_iterator_tag() {
-            assert_eq!(::std::mem::size_of::<forward_iterator_tag>() , 1usize
-                       , concat ! (
-                       "Size of: " , stringify ! ( forward_iterator_tag ) ));
-            assert_eq! (::std::mem::align_of::<forward_iterator_tag>() ,
-                        1usize , concat ! (
-                        "Alignment of " , stringify ! ( forward_iterator_tag )
-                        ));
-        }
-        impl Clone for forward_iterator_tag {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct bidirectional_iterator_tag {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_bidirectional_iterator_tag() {
-            assert_eq!(::std::mem::size_of::<bidirectional_iterator_tag>() ,
-                       1usize , concat ! (
-                       "Size of: " , stringify ! ( bidirectional_iterator_tag
-                       ) ));
-            assert_eq! (::std::mem::align_of::<bidirectional_iterator_tag>() ,
-                        1usize , concat ! (
-                        "Alignment of " , stringify ! (
-                        bidirectional_iterator_tag ) ));
-        }
-        impl Clone for bidirectional_iterator_tag {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct random_access_iterator_tag {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_random_access_iterator_tag() {
-            assert_eq!(::std::mem::size_of::<random_access_iterator_tag>() ,
-                       1usize , concat ! (
-                       "Size of: " , stringify ! ( random_access_iterator_tag
-                       ) ));
-            assert_eq! (::std::mem::align_of::<random_access_iterator_tag>() ,
-                        1usize , concat ! (
-                        "Alignment of " , stringify ! (
-                        random_access_iterator_tag ) ));
-        }
-        impl Clone for random_access_iterator_tag {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
         #[derive(Debug, Copy, Clone)]
         pub struct iterator<_Category, _Tp, _Distance, _Pointer, _Reference> {
             pub _address: u8,
             pub _phantom_0: ::std::marker::PhantomData<_Category>,
             pub _phantom_1: ::std::marker::PhantomData<_Tp>,
             pub _phantom_2: ::std::marker::PhantomData<_Distance>,
             pub _phantom_3: ::std::marker::PhantomData<_Pointer>,
             pub _phantom_4: ::std::marker::PhantomData<_Reference>,
         }
+        pub type iterator_iterator_category<_Category> = _Category;
         pub type iterator_value_type<_Tp> = _Tp;
         pub type iterator_difference_type<_Distance> = _Distance;
         pub type iterator_pointer<_Pointer> = _Pointer;
         pub type iterator_reference<_Reference> = _Reference;
-        pub type iterator_iterator_category<_Category> = _Category;
-        #[repr(C)]
-        #[derive(Debug, Copy, Clone)]
-        pub struct __bit_const_reference<_Cp> {
-            pub __seg_: root::std::__bit_const_reference___storage_pointer<_Cp>,
-            pub __mask_: root::std::__bit_const_reference___storage_type<_Cp>,
-        }
-        pub type __bit_const_reference___storage_type<_Cp> = _Cp;
-        pub type __bit_const_reference___storage_pointer<_Cp> = _Cp;
-    }
-    pub type __int64_t = ::std::os::raw::c_longlong;
-    pub type __darwin_va_list = root::__builtin_va_list;
-    pub type __darwin_off_t = root::__int64_t;
-    pub type va_list = root::__darwin_va_list;
-    pub type fpos_t = root::__darwin_off_t;
-    #[repr(C)]
-    #[derive(Debug, Copy)]
-    pub struct __sbuf {
-        pub _base: *mut ::std::os::raw::c_uchar,
-        pub _size: ::std::os::raw::c_int,
-    }
-    #[test]
-    fn bindgen_test_layout___sbuf() {
-        assert_eq!(::std::mem::size_of::<__sbuf>() , 16usize , concat ! (
-                   "Size of: " , stringify ! ( __sbuf ) ));
-        assert_eq! (::std::mem::align_of::<__sbuf>() , 8usize , concat ! (
-                    "Alignment of " , stringify ! ( __sbuf ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sbuf ) ) . _base as * const _ as
-                    usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sbuf ) , "::" ,
-                    stringify ! ( _base ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sbuf ) ) . _size as * const _ as
-                    usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sbuf ) , "::" ,
-                    stringify ! ( _size ) ));
-    }
-    impl Clone for __sbuf {
-        fn clone(&self) -> Self { *self }
-    }
-    #[repr(C)]
-    #[derive(Debug, Copy, Clone)]
-    pub struct __sFILEX([u8; 0]);
-    #[repr(C)]
-    #[derive(Debug, Copy)]
-    pub struct __sFILE {
-        pub _p: *mut ::std::os::raw::c_uchar,
-        pub _r: ::std::os::raw::c_int,
-        pub _w: ::std::os::raw::c_int,
-        pub _flags: ::std::os::raw::c_short,
-        pub _file: ::std::os::raw::c_short,
-        pub _bf: root::__sbuf,
-        pub _lbfsize: ::std::os::raw::c_int,
-        pub _cookie: *mut ::std::os::raw::c_void,
-        pub _close: ::std::option::Option<unsafe extern "C" fn(arg1:
-                                                                   *mut ::std::os::raw::c_void)
-                                              -> ::std::os::raw::c_int>,
-        pub _read: ::std::option::Option<unsafe extern "C" fn(arg1:
-                                                                  *mut ::std::os::raw::c_void,
-                                                              arg2:
-                                                                  *mut ::std::os::raw::c_char,
-                                                              arg3:
-                                                                  ::std::os::raw::c_int)
-                                             -> ::std::os::raw::c_int>,
-        pub _seek: ::std::option::Option<unsafe extern "C" fn(arg1:
-                                                                  *mut ::std::os::raw::c_void,
-                                                              arg2:
-                                                                  root::fpos_t,
-                                                              arg3:
-                                                                  ::std::os::raw::c_int)
-                                             -> ::std::os::raw::c_longlong>,
-        pub _write: ::std::option::Option<unsafe extern "C" fn(arg1:
-                                                                   *mut ::std::os::raw::c_void,
-                                                               arg2:
-                                                                   *const ::std::os::raw::c_char,
-                                                               arg3:
-                                                                   ::std::os::raw::c_int)
-                                              -> ::std::os::raw::c_int>,
-        pub _ub: root::__sbuf,
-        pub _extra: *mut root::__sFILEX,
-        pub _ur: ::std::os::raw::c_int,
-        pub _ubuf: [::std::os::raw::c_uchar; 3usize],
-        pub _nbuf: [::std::os::raw::c_uchar; 1usize],
-        pub _lb: root::__sbuf,
-        pub _blksize: ::std::os::raw::c_int,
-        pub _offset: root::fpos_t,
-    }
-    #[test]
-    fn bindgen_test_layout___sFILE() {
-        assert_eq!(::std::mem::size_of::<__sFILE>() , 152usize , concat ! (
-                   "Size of: " , stringify ! ( __sFILE ) ));
-        assert_eq! (::std::mem::align_of::<__sFILE>() , 8usize , concat ! (
-                    "Alignment of " , stringify ! ( __sFILE ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _p as * const _ as
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct atomic<_Tp> {
+            pub _M_i: _Tp,
+        }
+        pub mod chrono {
+            #[allow(unused_imports)]
+            use self::super::super::super::root;
+        }
+    }
+    pub mod __gnu_cxx {
+        #[allow(unused_imports)]
+        use self::super::super::root;
+    }
+    pub type __off_t = ::std::os::raw::c_long;
+    pub type __off64_t = ::std::os::raw::c_long;
+    #[repr(C)]
+    #[derive(Debug, Copy)]
+    pub struct _IO_FILE {
+        pub _flags: ::std::os::raw::c_int,
+        pub _IO_read_ptr: *mut ::std::os::raw::c_char,
+        pub _IO_read_end: *mut ::std::os::raw::c_char,
+        pub _IO_read_base: *mut ::std::os::raw::c_char,
+        pub _IO_write_base: *mut ::std::os::raw::c_char,
+        pub _IO_write_ptr: *mut ::std::os::raw::c_char,
+        pub _IO_write_end: *mut ::std::os::raw::c_char,
+        pub _IO_buf_base: *mut ::std::os::raw::c_char,
+        pub _IO_buf_end: *mut ::std::os::raw::c_char,
+        pub _IO_save_base: *mut ::std::os::raw::c_char,
+        pub _IO_backup_base: *mut ::std::os::raw::c_char,
+        pub _IO_save_end: *mut ::std::os::raw::c_char,
+        pub _markers: *mut root::_IO_marker,
+        pub _chain: *mut root::_IO_FILE,
+        pub _fileno: ::std::os::raw::c_int,
+        pub _flags2: ::std::os::raw::c_int,
+        pub _old_offset: root::__off_t,
+        pub _cur_column: ::std::os::raw::c_ushort,
+        pub _vtable_offset: ::std::os::raw::c_char,
+        pub _shortbuf: [::std::os::raw::c_char; 1usize],
+        pub _lock: *mut root::_IO_lock_t,
+        pub _offset: root::__off64_t,
+        pub __pad1: *mut ::std::os::raw::c_void,
+        pub __pad2: *mut ::std::os::raw::c_void,
+        pub __pad3: *mut ::std::os::raw::c_void,
+        pub __pad4: *mut ::std::os::raw::c_void,
+        pub __pad5: usize,
+        pub _mode: ::std::os::raw::c_int,
+        pub _unused2: [::std::os::raw::c_char; 20usize],
+    }
+    #[test]
+    fn bindgen_test_layout__IO_FILE() {
+        assert_eq!(::std::mem::size_of::<_IO_FILE>() , 216usize , concat ! (
+                   "Size of: " , stringify ! ( _IO_FILE ) ));
+        assert_eq! (::std::mem::align_of::<_IO_FILE>() , 8usize , concat ! (
+                    "Alignment of " , stringify ! ( _IO_FILE ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _flags as * const _ as
                     usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _p ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _r as * const _ as
-                    usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _r ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _w as * const _ as
-                    usize } , 12usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _w ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _flags as * const _ as
-                    usize } , 16usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
                     stringify ! ( _flags ) ));
         assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _file as * const _ as
-                    usize } , 18usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _file ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _bf as * const _ as
-                    usize } , 24usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _bf ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _lbfsize as * const _
-                    as usize } , 40usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _lbfsize ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _cookie as * const _ as
-                    usize } , 48usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _cookie ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _close as * const _ as
-                    usize } , 56usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _close ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _read as * const _ as
-                    usize } , 64usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _read ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _seek as * const _ as
-                    usize } , 72usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _seek ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _write as * const _ as
-                    usize } , 80usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _write ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _ub as * const _ as
-                    usize } , 88usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _ub ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _extra as * const _ as
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_read_ptr as *
+                    const _ as usize } , 8usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_read_ptr ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_read_end as *
+                    const _ as usize } , 16usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_read_end ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_read_base as *
+                    const _ as usize } , 24usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_read_base ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_write_base as *
+                    const _ as usize } , 32usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_write_base ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_write_ptr as *
+                    const _ as usize } , 40usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_write_ptr ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_write_end as *
+                    const _ as usize } , 48usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_write_end ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_buf_base as *
+                    const _ as usize } , 56usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_buf_base ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_buf_end as * const
+                    _ as usize } , 64usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_buf_end ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_save_base as *
+                    const _ as usize } , 72usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_save_base ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_backup_base as *
+                    const _ as usize } , 80usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_backup_base ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _IO_save_end as *
+                    const _ as usize } , 88usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _IO_save_end ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _markers as * const _
+                    as usize } , 96usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _markers ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _chain as * const _ as
                     usize } , 104usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _extra ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _ur as * const _ as
-                    usize } , 112usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _ur ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _ubuf as * const _ as
-                    usize } , 116usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _ubuf ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _nbuf as * const _ as
-                    usize } , 119usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _nbuf ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _lb as * const _ as
-                    usize } , 120usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _lb ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _blksize as * const _
-                    as usize } , 136usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
-                    stringify ! ( _blksize ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const __sFILE ) ) . _offset as * const _ as
-                    usize } , 144usize , concat ! (
-                    "Alignment of field: " , stringify ! ( __sFILE ) , "::" ,
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _chain ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _fileno as * const _
+                    as usize } , 112usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _fileno ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _flags2 as * const _
+                    as usize } , 116usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _flags2 ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _old_offset as * const
+                    _ as usize } , 120usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _old_offset ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _cur_column as * const
+                    _ as usize } , 128usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _cur_column ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _vtable_offset as *
+                    const _ as usize } , 130usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _vtable_offset ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _shortbuf as * const _
+                    as usize } , 131usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _shortbuf ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _lock as * const _ as
+                    usize } , 136usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _lock ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _offset as * const _
+                    as usize } , 144usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
                     stringify ! ( _offset ) ));
-    }
-    impl Clone for __sFILE {
-        fn clone(&self) -> Self { *self }
-    }
-    pub type FILE = root::__sFILE;
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . __pad1 as * const _ as
+                    usize } , 152usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( __pad1 ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . __pad2 as * const _ as
+                    usize } , 160usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( __pad2 ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . __pad3 as * const _ as
+                    usize } , 168usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( __pad3 ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . __pad4 as * const _ as
+                    usize } , 176usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( __pad4 ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . __pad5 as * const _ as
+                    usize } , 184usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( __pad5 ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _mode as * const _ as
+                    usize } , 192usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _mode ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_FILE ) ) . _unused2 as * const _
+                    as usize } , 196usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_FILE ) , "::" ,
+                    stringify ! ( _unused2 ) ));
+    }
+    impl Clone for _IO_FILE {
+        fn clone(&self) -> Self { *self }
+    }
+    pub type FILE = root::_IO_FILE;
+    pub type va_list = root::__builtin_va_list;
+    pub type _IO_lock_t = ::std::os::raw::c_void;
+    #[repr(C)]
+    #[derive(Debug, Copy)]
+    pub struct _IO_marker {
+        pub _next: *mut root::_IO_marker,
+        pub _sbuf: *mut root::_IO_FILE,
+        pub _pos: ::std::os::raw::c_int,
+    }
+    #[test]
+    fn bindgen_test_layout__IO_marker() {
+        assert_eq!(::std::mem::size_of::<_IO_marker>() , 24usize , concat ! (
+                   "Size of: " , stringify ! ( _IO_marker ) ));
+        assert_eq! (::std::mem::align_of::<_IO_marker>() , 8usize , concat ! (
+                    "Alignment of " , stringify ! ( _IO_marker ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_marker ) ) . _next as * const _
+                    as usize } , 0usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_marker ) , "::"
+                    , stringify ! ( _next ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_marker ) ) . _sbuf as * const _
+                    as usize } , 8usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_marker ) , "::"
+                    , stringify ! ( _sbuf ) ));
+        assert_eq! (unsafe {
+                    & ( * ( 0 as * const _IO_marker ) ) . _pos as * const _ as
+                    usize } , 16usize , concat ! (
+                    "Alignment of field: " , stringify ! ( _IO_marker ) , "::"
+                    , stringify ! ( _pos ) ));
+    }
+    impl Clone for _IO_marker {
+        fn clone(&self) -> Self { *self }
+    }
     /**
  * MozRefCountType is Mozilla's reference count type.
  *
  * We use the same type to represent the refcount of RefCounted objects
  * as well, in order to be able to use the leak detection facilities
  * that are implemented by XPCOM.
  *
  * Note that this type is not in the mozilla namespace so that it is
@@ -9798,114 +9961,43 @@ pub mod root {
         JS_HASH_KEY_EMPTY = 11,
         JS_ION_ERROR = 12,
         JS_ION_BAILOUT = 13,
         JS_OPTIMIZED_OUT = 14,
         JS_UNINITIALIZED_LEXICAL = 15,
         JS_GENERIC_MAGIC = 16,
         JS_WHY_MAGIC_COUNT = 17,
     }
-    #[repr(C)]
-    #[derive(Debug)]
-    pub struct nsAString_internal {
-        pub mData: *mut root::nsAString_internal_char_type,
-        pub mLength: root::nsAString_internal_size_type,
-        pub mFlags: u32,
-    }
-    pub type nsAString_internal_fallible_t = root::mozilla::fallible_t;
-    pub type nsAString_internal_char_type = u16;
-    pub type nsAString_internal_self_type = root::nsAString_internal;
-    pub type nsAString_internal_abstract_string_type =
-        root::nsAString_internal_self_type;
-    pub type nsAString_internal_base_string_type =
-        root::nsAString_internal_self_type;
-    pub type nsAString_internal_substring_type =
-        root::nsAString_internal_self_type;
-    pub type nsAString_internal_substring_tuple_type = root::nsSubstringTuple;
-    pub type nsAString_internal_string_type = ::nsstring::nsStringRepr;
-    pub type nsAString_internal_const_iterator = root::nsReadingIterator<u16>;
-    pub type nsAString_internal_iterator = root::nsWritingIterator<u16>;
-    pub type nsAString_internal_comparator_type = root::nsStringComparator;
-    pub type nsAString_internal_char_iterator =
-        *mut root::nsAString_internal_char_type;
-    pub type nsAString_internal_const_char_iterator =
-        *const root::nsAString_internal_char_type;
-    pub type nsAString_internal_size_type = u32;
-    pub type nsAString_internal_index_type = u32;
-    pub const nsAString_internal_F_NONE:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_NONE;
-    pub const nsAString_internal_F_TERMINATED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_TERMINATED;
-    pub const nsAString_internal_F_VOIDED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_VOIDED;
-    pub const nsAString_internal_F_SHARED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_SHARED;
-    pub const nsAString_internal_F_OWNED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_OWNED;
-    pub const nsAString_internal_F_FIXED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_FIXED;
-    pub const nsAString_internal_F_LITERAL:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_LITERAL;
-    pub const nsAString_internal_F_CLASS_FIXED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_CLASS_FIXED;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsAString_internal__bindgen_ty_1 {
-        F_NONE = 0,
-        F_TERMINATED = 1,
-        F_VOIDED = 2,
-        F_SHARED = 4,
-        F_OWNED = 8,
-        F_FIXED = 16,
-        F_LITERAL = 32,
-        F_CLASS_FIXED = 65536,
-    }
-    #[test]
-    fn bindgen_test_layout_nsAString_internal() {
-        assert_eq!(::std::mem::size_of::<nsAString_internal>() , 16usize ,
-                   concat ! ( "Size of: " , stringify ! ( nsAString_internal )
-                   ));
-        assert_eq! (::std::mem::align_of::<nsAString_internal>() , 8usize ,
-                    concat ! (
-                    "Alignment of " , stringify ! ( nsAString_internal ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsAString_internal ) ) . mData as *
-                    const _ as usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsAString_internal
-                    ) , "::" , stringify ! ( mData ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsAString_internal ) ) . mLength as *
-                    const _ as usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsAString_internal
-                    ) , "::" , stringify ! ( mLength ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsAString_internal ) ) . mFlags as *
-                    const _ as usize } , 12usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsAString_internal
-                    ) , "::" , stringify ! ( mFlags ) ));
+    /**
+ * double-byte (char16_t) string types
+ */
+    #[repr(C)]
+    #[derive(Debug)]
+    pub struct nsAString {
+        pub _base: root::mozilla::detail::nsStringRepr,
+    }
+    pub type nsAString_self_type = root::nsAString;
+    #[test]
+    fn bindgen_test_layout_nsAString() {
+        assert_eq!(::std::mem::size_of::<nsAString>() , 16usize , concat ! (
+                   "Size of: " , stringify ! ( nsAString ) ));
+        assert_eq! (::std::mem::align_of::<nsAString>() , 8usize , concat ! (
+                    "Alignment of " , stringify ! ( nsAString ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsSubstringTuple {
         pub mHead: *const root::nsSubstringTuple_self_type,
         pub mFragA: *const root::nsSubstringTuple_base_string_type,
         pub mFragB: *const root::nsSubstringTuple_base_string_type,
     }
     pub type nsSubstringTuple_char_type = u16;
     pub type nsSubstringTuple_self_type = root::nsSubstringTuple;
-    pub type nsSubstringTuple_substring_type = root::nsAString_internal;
-    pub type nsSubstringTuple_base_string_type = root::nsAString_internal;
+    pub type nsSubstringTuple_base_string_type =
+        root::mozilla::detail::nsStringRepr;
     pub type nsSubstringTuple_size_type = u32;
     #[test]
     fn bindgen_test_layout_nsSubstringTuple() {
         assert_eq!(::std::mem::size_of::<nsSubstringTuple>() , 24usize ,
                    concat ! ( "Size of: " , stringify ! ( nsSubstringTuple )
                    ));
         assert_eq! (::std::mem::align_of::<nsSubstringTuple>() , 8usize ,
                     concat ! (
@@ -9927,17 +10019,17 @@ pub mod root {
                     , "::" , stringify ! ( mFragB ) ));
     }
     impl Clone for nsSubstringTuple {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     pub struct nsAutoString {
         pub _base: root::nsFixedString,
-        pub mStorage: [root::nsAString_internal_char_type; 64usize],
+        pub mStorage: [root::mozilla::detail::nsStringRepr_char_type; 64usize],
     }
     pub type nsAutoString_self_type = root::nsAutoString;
     pub const nsAutoString_kDefaultStorageSize:
               root::nsAutoString__bindgen_ty_1 =
         nsAutoString__bindgen_ty_1::kDefaultStorageSize;
     #[repr(u32)]
     #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     pub enum nsAutoString__bindgen_ty_1 { kDefaultStorageSize = 64, }
@@ -9951,17 +10043,17 @@ pub mod root {
                     & ( * ( 0 as * const nsAutoString ) ) . mStorage as *
                     const _ as usize } , 32usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsAutoString ) ,
                     "::" , stringify ! ( mStorage ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsDependentSubstring {
-        pub _base: root::nsAString_internal,
+        pub _base: root::nsAString,
     }
     pub type nsDependentSubstring_self_type = root::nsDependentSubstring;
     #[test]
     fn bindgen_test_layout_nsDependentSubstring() {
         assert_eq!(::std::mem::size_of::<nsDependentSubstring>() , 16usize ,
                    concat ! (
                    "Size of: " , stringify ! ( nsDependentSubstring ) ));
         assert_eq! (::std::mem::align_of::<nsDependentSubstring>() , 8usize ,
@@ -9984,117 +10076,43 @@ pub mod root {
                    ));
         assert_eq! (::std::mem::align_of::<nsStringComparator>() , 8usize ,
                     concat ! (
                     "Alignment of " , stringify ! ( nsStringComparator ) ));
     }
     impl Clone for nsStringComparator {
         fn clone(&self) -> Self { *self }
     }
-    #[repr(C)]
-    #[derive(Debug)]
-    pub struct nsACString_internal {
-        pub mData: *mut root::nsACString_internal_char_type,
-        pub mLength: root::nsACString_internal_size_type,
-        pub mFlags: u32,
-    }
-    pub type nsACString_internal_fallible_t = root::mozilla::fallible_t;
-    pub type nsACString_internal_char_type = ::std::os::raw::c_char;
-    pub type nsACString_internal_self_type = root::nsACString_internal;
-    pub type nsACString_internal_abstract_string_type =
-        root::nsACString_internal_self_type;
-    pub type nsACString_internal_base_string_type =
-        root::nsACString_internal_self_type;
-    pub type nsACString_internal_substring_type =
-        root::nsACString_internal_self_type;
-    pub type nsACString_internal_substring_tuple_type =
-        root::nsCSubstringTuple;
-    pub type nsACString_internal_string_type = root::nsCString;
-    pub type nsACString_internal_const_iterator =
-        root::nsReadingIterator<::std::os::raw::c_char>;
-    pub type nsACString_internal_iterator =
-        root::nsWritingIterator<::std::os::raw::c_char>;
-    pub type nsACString_internal_comparator_type = root::nsCStringComparator;
-    pub type nsACString_internal_char_iterator =
-        *mut root::nsACString_internal_char_type;
-    pub type nsACString_internal_const_char_iterator =
-        *const root::nsACString_internal_char_type;
-    pub type nsACString_internal_size_type = u32;
-    pub type nsACString_internal_index_type = u32;
-    pub const nsACString_internal_F_NONE:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_NONE;
-    pub const nsACString_internal_F_TERMINATED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_TERMINATED;
-    pub const nsACString_internal_F_VOIDED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_VOIDED;
-    pub const nsACString_internal_F_SHARED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_SHARED;
-    pub const nsACString_internal_F_OWNED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_OWNED;
-    pub const nsACString_internal_F_FIXED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_FIXED;
-    pub const nsACString_internal_F_LITERAL:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_LITERAL;
-    pub const nsACString_internal_F_CLASS_FIXED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_CLASS_FIXED;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsACString_internal__bindgen_ty_1 {
-        F_NONE = 0,
-        F_TERMINATED = 1,
-        F_VOIDED = 2,
-        F_SHARED = 4,
-        F_OWNED = 8,
-        F_FIXED = 16,
-        F_LITERAL = 32,
-        F_CLASS_FIXED = 65536,
-    }
-    #[test]
-    fn bindgen_test_layout_nsACString_internal() {
-        assert_eq!(::std::mem::size_of::<nsACString_internal>() , 16usize ,
-                   concat ! (
-                   "Size of: " , stringify ! ( nsACString_internal ) ));
-        assert_eq! (::std::mem::align_of::<nsACString_internal>() , 8usize ,
-                    concat ! (
-                    "Alignment of " , stringify ! ( nsACString_internal ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsACString_internal ) ) . mData as *
-                    const _ as usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsACString_internal
-                    ) , "::" , stringify ! ( mData ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsACString_internal ) ) . mLength as
-                    * const _ as usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsACString_internal
-                    ) , "::" , stringify ! ( mLength ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsACString_internal ) ) . mFlags as *
-                    const _ as usize } , 12usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsACString_internal
-                    ) , "::" , stringify ! ( mFlags ) ));
+    /**
+ * single-byte (char) string types
+ */
+    #[repr(C)]
+    #[derive(Debug)]
+    pub struct nsACString {
+        pub _base: root::mozilla::detail::nsCStringRepr,
+    }
+    pub type nsACString_self_type = root::nsACString;
+    #[test]
+    fn bindgen_test_layout_nsACString() {
+        assert_eq!(::std::mem::size_of::<nsACString>() , 16usize , concat ! (
+                   "Size of: " , stringify ! ( nsACString ) ));
+        assert_eq! (::std::mem::align_of::<nsACString>() , 8usize , concat ! (
+                    "Alignment of " , stringify ! ( nsACString ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsCSubstringTuple {
         pub mHead: *const root::nsCSubstringTuple_self_type,
         pub mFragA: *const root::nsCSubstringTuple_base_string_type,
         pub mFragB: *const root::nsCSubstringTuple_base_string_type,
     }
     pub type nsCSubstringTuple_char_type = ::std::os::raw::c_char;
     pub type nsCSubstringTuple_self_type = root::nsCSubstringTuple;
-    pub type nsCSubstringTuple_substring_type = root::nsACString_internal;
-    pub type nsCSubstringTuple_base_string_type = root::nsACString_internal;
+    pub type nsCSubstringTuple_base_string_type =
+        root::mozilla::detail::nsCStringRepr;
     pub type nsCSubstringTuple_size_type = u32;
     #[test]
     fn bindgen_test_layout_nsCSubstringTuple() {
         assert_eq!(::std::mem::size_of::<nsCSubstringTuple>() , 24usize ,
                    concat ! ( "Size of: " , stringify ! ( nsCSubstringTuple )
                    ));
         assert_eq! (::std::mem::align_of::<nsCSubstringTuple>() , 8usize ,
                     concat ! (
@@ -10116,17 +10134,17 @@ pub mod root {
                     , "::" , stringify ! ( mFragB ) ));
     }
     impl Clone for nsCSubstringTuple {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsCString {
-        pub _base: root::nsACString_internal,
+        pub _base: root::nsACString,
     }
     pub type nsCString_self_type = root::nsCString;
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsCString_Segment {
         pub mBegin: u32,
         pub mLength: u32,
     }
@@ -10157,17 +10175,17 @@ pub mod root {
         assert_eq!(::std::mem::size_of::<nsCString>() , 16usize , concat ! (
                    "Size of: " , stringify ! ( nsCString ) ));
         assert_eq! (::std::mem::align_of::<nsCString>() , 8usize , concat ! (
                     "Alignment of " , stringify ! ( nsCString ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsDependentCSubstring {
-        pub _base: root::nsACString_internal,
+        pub _base: root::nsACString,
     }
     pub type nsDependentCSubstring_self_type = root::nsDependentCSubstring;
     #[test]
     fn bindgen_test_layout_nsDependentCSubstring() {
         assert_eq!(::std::mem::size_of::<nsDependentCSubstring>() , 16usize ,
                    concat ! (
                    "Size of: " , stringify ! ( nsDependentCSubstring ) ));
         assert_eq! (::std::mem::align_of::<nsDependentCSubstring>() , 8usize ,
@@ -10194,17 +10212,17 @@ pub mod root {
                     "Alignment of " , stringify ! ( nsCStringComparator ) ));
     }
     impl Clone for nsCStringComparator {
         fn clone(&self) -> Self { *self }
     }
     /**
  * typedefs for backwards compatibility
  */
-    pub type nsSubstring = root::nsAString_internal;
+    pub type nsSubstring = root::nsAString;
     pub type nsAFlatCString = root::nsCString;
     #[repr(C)]
     pub struct nsISupports__bindgen_vtable {
     }
     /**
  * Basic component object model interface. Objects which implement
  * this interface support runtime interface discovery (QueryInterface)
  * and a reference counted memory model (AddRef/Release). This is
@@ -10330,26 +10348,26 @@ pub mod root {
     pub type nsWritingIterator_difference_type = isize;
     pub type nsWritingIterator_size_type = usize;
     pub type nsWritingIterator_value_type<CharT> = CharT;
     pub type nsWritingIterator_pointer<CharT> = *mut CharT;
     pub type nsWritingIterator_reference = [u8; 0usize];
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsSubstringSplitter {
-        pub mStr: *const root::nsAString_internal,
+        pub mStr: *const root::nsAString,
         pub mArray: root::mozilla::UniquePtr<[root::nsDependentSubstring; 0usize],
                                              root::mozilla::DefaultDelete<[root::nsDependentSubstring; 0usize]>>,
         pub mArraySize: root::nsSubstringSplitter_size_type,
         pub mDelim: root::nsSubstringSplitter_char_type,
     }
     pub type nsSubstringSplitter_size_type =
-        root::nsAString_internal_size_type;
+        root::mozilla::detail::nsStringRepr_size_type;
     pub type nsSubstringSplitter_char_type =
-        root::nsAString_internal_char_type;
+        root::mozilla::detail::nsStringRepr_char_type;
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsSubstringSplitter_nsTSubstringSplit_Iter {
         pub mObj: *const root::nsSubstringSplitter,
         pub mPos: root::nsSubstringSplitter_size_type,
     }
     #[test]
     fn bindgen_test_layout_nsSubstringSplitter_nsTSubstringSplit_Iter() {
@@ -10408,26 +10426,26 @@ pub mod root {
                     & ( * ( 0 as * const nsSubstringSplitter ) ) . mDelim as *
                     const _ as usize } , 20usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsSubstringSplitter
                     ) , "::" , stringify ! ( mDelim ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsCSubstringSplitter {
-        pub mStr: *const root::nsACString_internal,
+        pub mStr: *const root::nsACString,
         pub mArray: root::mozilla::UniquePtr<[root::nsDependentCSubstring; 0usize],
                                              root::mozilla::DefaultDelete<[root::nsDependentCSubstring; 0usize]>>,
         pub mArraySize: root::nsCSubstringSplitter_size_type,
         pub mDelim: root::nsCSubstringSplitter_char_type,
     }
     pub type nsCSubstringSplitter_size_type =
-        root::nsACString_internal_size_type;
+        root::mozilla::detail::nsCStringRepr_size_type;
     pub type nsCSubstringSplitter_char_type =
-        root::nsACString_internal_char_type;
+        root::mozilla::detail::nsCStringRepr_char_type;
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsCSubstringSplitter_nsTSubstringSplit_Iter {
         pub mObj: *const root::nsCSubstringSplitter,
         pub mPos: root::nsCSubstringSplitter_size_type,
     }
     #[test]
     fn bindgen_test_layout_nsCSubstringSplitter_nsTSubstringSplit_Iter() {
@@ -10488,18 +10506,18 @@ pub mod root {
                     * const _ as usize } , 20usize , concat ! (
                     "Alignment of field: " , stringify ! (
                     nsCSubstringSplitter ) , "::" , stringify ! ( mDelim ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsFixedString {
         pub _base: ::nsstring::nsStringRepr,
-        pub mFixedCapacity: root::nsAString_internal_size_type,
-        pub mFixedBuf: *mut root::nsAString_internal_char_type,
+        pub mFixedCapacity: root::mozilla::detail::nsStringRepr_size_type,
+        pub mFixedBuf: *mut root::mozilla::detail::nsStringRepr_char_type,
     }
     pub type nsFixedString_self_type = root::nsFixedString;
     pub type nsFixedString_fixed_string_type = root::nsFixedString;
     #[test]
     fn bindgen_test_layout_nsFixedString() {
         assert_eq!(::std::mem::size_of::<nsFixedString>() , 32usize , concat !
                    ( "Size of: " , stringify ! ( nsFixedString ) ));
         assert_eq! (::std::mem::align_of::<nsFixedString>() , 8usize , concat
@@ -15615,73 +15633,73 @@ pub mod root {
                     & ( * ( 0 as * const nsNodeWeakReference ) ) . mNode as *
                     const _ as usize } , 24usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsNodeWeakReference
                     ) , "::" , stringify ! ( mNode ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
     pub struct nsDOMMutationObserver([u8; 0]);
-    pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_LISTENERMANAGER;
-    pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_PROPERTIES;
-    pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_ANONYMOUS_ROOT;
-    pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
-    pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS_ROOT;
-    pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_FORCE_XBL_BINDINGS;
-    pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_MAY_BE_IN_BINDING_MNGR;
-    pub const NODE_IS_EDITABLE: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_EDITABLE;
-    pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS;
-    pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_IN_SHADOW_TREE;
-    pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_EMPTY_SELECTOR;
-    pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_SLOW_SELECTOR;
-    pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_EDGE_CHILD_SELECTOR;
-    pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
-    pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_ALL_SELECTOR_FLAGS;
-    pub const NODE_NEEDS_FRAME: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_NEEDS_FRAME;
-    pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_DESCENDANTS_NEED_FRAMES;
-    pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_ACCESSKEY;
-    pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_DIRECTION_RTL;
-    pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_DIRECTION_LTR;
-    pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_ALL_DIRECTION_FLAGS;
-    pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_CHROME_ONLY_ACCESS;
-    pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
-    pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
-    pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_2;
-    pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
-    pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_TYPE_SPECIFIC_BITS_OFFSET;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum _bindgen_ty_28 {
+    pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_LISTENERMANAGER;
+    pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_PROPERTIES;
+    pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_ANONYMOUS_ROOT;
+    pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
+    pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_NATIVE_ANONYMOUS_ROOT;
+    pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_FORCE_XBL_BINDINGS;
+    pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_MAY_BE_IN_BINDING_MNGR;
+    pub const NODE_IS_EDITABLE: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_EDITABLE;
+    pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_NATIVE_ANONYMOUS;
+    pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_IN_SHADOW_TREE;
+    pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_EMPTY_SELECTOR;
+    pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_SLOW_SELECTOR;
+    pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_EDGE_CHILD_SELECTOR;
+    pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
+    pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_ALL_SELECTOR_FLAGS;
+    pub const NODE_NEEDS_FRAME: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_NEEDS_FRAME;
+    pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_DESCENDANTS_NEED_FRAMES;
+    pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_ACCESSKEY;
+    pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_DIRECTION_RTL;
+    pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_HAS_DIRECTION_LTR;
+    pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_ALL_DIRECTION_FLAGS;
+    pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_CHROME_ONLY_ACCESS;
+    pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
+    pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_SHARED_RESTYLE_BIT_1;
+    pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_SHARED_RESTYLE_BIT_2;
+    pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_SHARED_RESTYLE_BIT_1;
+    pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_118 =
+        _bindgen_ty_118::NODE_TYPE_SPECIFIC_BITS_OFFSET;
+    #[repr(u32)]
+    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+    pub enum _bindgen_ty_118 {
         NODE_HAS_LISTENERMANAGER = 4,
         NODE_HAS_PROPERTIES = 8,
         NODE_IS_ANONYMOUS_ROOT = 16,
         NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = 32,
         NODE_IS_NATIVE_ANONYMOUS_ROOT = 64,
         NODE_FORCE_XBL_BINDINGS = 128,
         NODE_MAY_BE_IN_BINDING_MNGR = 256,
         NODE_IS_EDITABLE = 512,
@@ -25813,46 +25831,47 @@ pub mod root {
                     "Alignment of field: " , stringify ! ( LookAndFeelInt ) ,
                     "::" , stringify ! ( value ) ));
     }
     impl Clone for LookAndFeelInt {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
+    pub struct RawServoStyleSet([u8; 0]);
+    #[repr(C)]
+    #[derive(Debug, Copy, Clone)]
     pub struct RawServoAnimationValue([u8; 0]);
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
-    pub struct RawServoStyleSet([u8; 0]);
+    pub struct RawServoAnimationValueMap([u8; 0]);
     pub type RawGeckoNode = root::nsINode;
     pub type RawGeckoElement = root::mozilla::dom::Element;
     pub type RawGeckoDocument = root::nsIDocument;
     pub type RawGeckoPresContext = root::nsPresContext;
     pub type RawGeckoKeyframeList = root::nsTArray<root::mozilla::Keyframe>;
     pub type RawGeckoComputedKeyframeValuesList =
         root::nsTArray<root::nsTArray<root::mozilla::PropertyStyleAnimationValuePair>>;
     pub type RawGeckoAnimationValueList =
         root::nsTArray<root::mozilla::PropertyStyleAnimationValuePair>;
-    pub type RawServoAnimationValueBorrowedList =
-        root::nsTArray<*const root::RawServoAnimationValue>;
     pub type RawGeckoStyleAnimationList =
         root::nsStyleAutoArray<root::mozilla::StyleAnimation>;
+    pub type RawServoAnimationValueMapBorrowed =
+        *const root::RawServoAnimationValueMap;
     pub type RawGeckoNodeBorrowed = *const root::RawGeckoNode;
     pub type RawGeckoNodeBorrowedOrNull = *const root::RawGeckoNode;
     pub type RawGeckoElementBorrowed = *const root::RawGeckoElement;
     pub type RawGeckoElementBorrowedOrNull = *const root::RawGeckoElement;
     pub type RawGeckoDocumentBorrowed = *const root::RawGeckoDocument;
     pub type RawGeckoDocumentBorrowedOrNull = *const root::RawGeckoDocument;
     pub type RawGeckoPresContextOwned = *mut root::RawGeckoPresContext;
     pub type RawGeckoPresContextBorrowed = *const root::RawGeckoPresContext;
     pub type RawGeckoPresContextBorrowedMut = *mut root::RawGeckoPresContext;
     pub type RawGeckoAnimationValueListBorrowedMut =
         *mut root::RawGeckoAnimationValueList;
-    pub type RawServoAnimationValueBorrowedListBorrowed =
-        *const root::RawServoAnimationValueBorrowedList;
     pub type RawGeckoKeyframeListBorrowedMut =
         *mut root::RawGeckoKeyframeList;
     pub type RawGeckoKeyframeListBorrowed = *const root::RawGeckoKeyframeList;
     pub type RawGeckoComputedKeyframeValuesListBorrowedMut =
         *mut root::RawGeckoComputedKeyframeValuesList;
     pub type RawGeckoStyleAnimationListBorrowed =
         *const root::RawGeckoStyleAnimationList;
     #[repr(C)]
--- a/servo/components/style/gecko_bindings/structs_release.rs
+++ b/servo/components/style/gecko_bindings/structs_release.rs
@@ -1439,16 +1439,202 @@ pub mod root {
             pub struct LinkedListElementTraits<T> {
                 pub _address: u8,
                 pub _phantom_0: ::std::marker::PhantomData<T>,
             }
             pub type LinkedListElementTraits_RawType<T> = *mut T;
             pub type LinkedListElementTraits_ConstRawType<T> = *mut T;
             pub type LinkedListElementTraits_ClientType<T> = *mut T;
             pub type LinkedListElementTraits_ConstClientType<T> = *mut T;
+            #[repr(C)]
+            #[derive(Debug, Copy)]
+            pub struct nsStringRepr {
+                pub mData: *mut root::mozilla::detail::nsStringRepr_char_type,
+                pub mLength: root::mozilla::detail::nsStringRepr_size_type,
+                pub mFlags: u32,
+            }
+            pub type nsStringRepr_fallible_t = root::mozilla::fallible_t;
+            pub type nsStringRepr_char_type = u16;
+            pub type nsStringRepr_self_type =
+                root::mozilla::detail::nsStringRepr;
+            pub type nsStringRepr_base_string_type =
+                root::mozilla::detail::nsStringRepr_self_type;
+            pub type nsStringRepr_substring_type = root::nsAString;
+            pub type nsStringRepr_substring_tuple_type =
+                root::nsSubstringTuple;
+            pub type nsStringRepr_string_type = ::nsstring::nsStringRepr;
+            pub type nsStringRepr_const_iterator =
+                root::nsReadingIterator<u16>;
+            pub type nsStringRepr_iterator = root::nsWritingIterator<u16>;
+            pub type nsStringRepr_comparator_type = root::nsStringComparator;
+            pub type nsStringRepr_char_iterator =
+                *mut root::mozilla::detail::nsStringRepr_char_type;
+            pub type nsStringRepr_const_char_iterator =
+                *const root::mozilla::detail::nsStringRepr_char_type;
+            pub type nsStringRepr_index_type = u32;
+            pub type nsStringRepr_size_type = u32;
+            pub const nsStringRepr_F_NONE:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_NONE;
+            pub const nsStringRepr_F_TERMINATED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_TERMINATED;
+            pub const nsStringRepr_F_VOIDED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_VOIDED;
+            pub const nsStringRepr_F_SHARED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_SHARED;
+            pub const nsStringRepr_F_OWNED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_OWNED;
+            pub const nsStringRepr_F_FIXED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_FIXED;
+            pub const nsStringRepr_F_LITERAL:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_LITERAL;
+            pub const nsStringRepr_F_CLASS_FIXED:
+                      root::mozilla::detail::nsStringRepr__bindgen_ty_1 =
+                nsStringRepr__bindgen_ty_1::F_CLASS_FIXED;
+            #[repr(u32)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum nsStringRepr__bindgen_ty_1 {
+                F_NONE = 0,
+                F_TERMINATED = 1,
+                F_VOIDED = 2,
+                F_SHARED = 4,
+                F_OWNED = 8,
+                F_FIXED = 16,
+                F_LITERAL = 32,
+                F_CLASS_FIXED = 65536,
+            }
+            #[test]
+            fn bindgen_test_layout_nsStringRepr() {
+                assert_eq!(::std::mem::size_of::<nsStringRepr>() , 16usize ,
+                           concat ! (
+                           "Size of: " , stringify ! ( nsStringRepr ) ));
+                assert_eq! (::std::mem::align_of::<nsStringRepr>() , 8usize ,
+                            concat ! (
+                            "Alignment of " , stringify ! ( nsStringRepr ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsStringRepr ) ) . mData as *
+                            const _ as usize } , 0usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsStringRepr ) , "::" , stringify ! ( mData ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsStringRepr ) ) . mLength as
+                            * const _ as usize } , 8usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsStringRepr ) , "::" , stringify ! ( mLength )
+                            ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsStringRepr ) ) . mFlags as
+                            * const _ as usize } , 12usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsStringRepr ) , "::" , stringify ! ( mFlags ) ));
+            }
+            impl Clone for nsStringRepr {
+                fn clone(&self) -> Self { *self }
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy)]
+            pub struct nsCStringRepr {
+                pub mData: *mut root::mozilla::detail::nsCStringRepr_char_type,
+                pub mLength: root::mozilla::detail::nsCStringRepr_size_type,
+                pub mFlags: u32,
+            }
+            pub type nsCStringRepr_fallible_t = root::mozilla::fallible_t;
+            pub type nsCStringRepr_char_type = ::std::os::raw::c_char;
+            pub type nsCStringRepr_self_type =
+                root::mozilla::detail::nsCStringRepr;
+            pub type nsCStringRepr_base_string_type =
+                root::mozilla::detail::nsCStringRepr_self_type;
+            pub type nsCStringRepr_substring_type = root::nsACString;
+            pub type nsCStringRepr_substring_tuple_type =
+                root::nsCSubstringTuple;
+            pub type nsCStringRepr_string_type = root::nsCString;
+            pub type nsCStringRepr_const_iterator =
+                root::nsReadingIterator<::std::os::raw::c_char>;
+            pub type nsCStringRepr_iterator =
+                root::nsWritingIterator<::std::os::raw::c_char>;
+            pub type nsCStringRepr_comparator_type =
+                root::nsCStringComparator;
+            pub type nsCStringRepr_char_iterator =
+                *mut root::mozilla::detail::nsCStringRepr_char_type;
+            pub type nsCStringRepr_const_char_iterator =
+                *const root::mozilla::detail::nsCStringRepr_char_type;
+            pub type nsCStringRepr_index_type = u32;
+            pub type nsCStringRepr_size_type = u32;
+            pub const nsCStringRepr_F_NONE:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_NONE;
+            pub const nsCStringRepr_F_TERMINATED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_TERMINATED;
+            pub const nsCStringRepr_F_VOIDED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_VOIDED;
+            pub const nsCStringRepr_F_SHARED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_SHARED;
+            pub const nsCStringRepr_F_OWNED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_OWNED;
+            pub const nsCStringRepr_F_FIXED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_FIXED;
+            pub const nsCStringRepr_F_LITERAL:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_LITERAL;
+            pub const nsCStringRepr_F_CLASS_FIXED:
+                      root::mozilla::detail::nsCStringRepr__bindgen_ty_1 =
+                nsCStringRepr__bindgen_ty_1::F_CLASS_FIXED;
+            #[repr(u32)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum nsCStringRepr__bindgen_ty_1 {
+                F_NONE = 0,
+                F_TERMINATED = 1,
+                F_VOIDED = 2,
+                F_SHARED = 4,
+                F_OWNED = 8,
+                F_FIXED = 16,
+                F_LITERAL = 32,
+                F_CLASS_FIXED = 65536,
+            }
+            #[test]
+            fn bindgen_test_layout_nsCStringRepr() {
+                assert_eq!(::std::mem::size_of::<nsCStringRepr>() , 16usize ,
+                           concat ! (
+                           "Size of: " , stringify ! ( nsCStringRepr ) ));
+                assert_eq! (::std::mem::align_of::<nsCStringRepr>() , 8usize ,
+                            concat ! (
+                            "Alignment of " , stringify ! ( nsCStringRepr )
+                            ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsCStringRepr ) ) . mData as
+                            * const _ as usize } , 0usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsCStringRepr ) , "::" , stringify ! ( mData ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsCStringRepr ) ) . mLength
+                            as * const _ as usize } , 8usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsCStringRepr ) , "::" , stringify ! ( mLength )
+                            ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const nsCStringRepr ) ) . mFlags as
+                            * const _ as usize } , 12usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            nsCStringRepr ) , "::" , stringify ! ( mFlags )
+                            ));
+            }
+            impl Clone for nsCStringRepr {
+                fn clone(&self) -> Self { *self }
+            }
         }
         pub type MallocSizeOf =
             ::std::option::Option<unsafe extern "C" fn(p:
                                                            *const ::std::os::raw::c_void)
                                       -> ::std::os::raw::c_ulong>;
         #[repr(C)]
         #[derive(Debug)]
         pub struct OwningNonNull<T> {
@@ -1985,20 +2171,20 @@ pub mod root {
                                ));
                     assert_eq! (::std::mem::align_of::<FastErrorResult>() ,
                                 8usize , concat ! (
                                 "Alignment of " , stringify ! (
                                 FastErrorResult ) ));
                 }
                 #[repr(C)]
                 pub struct FakeString {
-                    pub mData: *mut root::nsAString_internal_char_type,
-                    pub mLength: root::nsAString_internal_size_type,
+                    pub mData: *mut root::mozilla::detail::nsStringRepr_char_type,
+                    pub mLength: root::mozilla::detail::nsStringRepr_size_type,
                     pub mFlags: u32,
-                    pub mInlineStorage: [root::nsAString_internal_char_type; 64usize],
+                    pub mInlineStorage: [root::mozilla::detail::nsStringRepr_char_type; 64usize],
                 }
                 #[repr(C)]
                 #[derive(Debug)]
                 pub struct FakeString_StringAsserter {
                     pub _base: ::nsstring::nsStringRepr,
                 }
                 #[test]
                 fn bindgen_test_layout_FakeString_StringAsserter() {
@@ -2933,17 +3119,17 @@ pub mod root {
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct NodeInfo_NodeInfoInner {
                 pub mName: root::nsCOMPtr<root::nsIAtom>,
                 pub mPrefix: root::nsCOMPtr<root::nsIAtom>,
                 pub mNamespaceID: i32,
                 pub mNodeType: u16,
-                pub mNameString: *const root::nsAString_internal,
+                pub mNameString: *const root::nsAString,
                 pub mExtraName: root::nsCOMPtr<root::nsIAtom>,
             }
             #[test]
             fn bindgen_test_layout_NodeInfo_NodeInfoInner() {
                 assert_eq!(::std::mem::size_of::<NodeInfo_NodeInfoInner>() ,
                            40usize , concat ! (
                            "Size of: " , stringify ! ( NodeInfo_NodeInfoInner
                            ) ));
@@ -4079,16 +4265,17 @@ pub mod root {
                 pub _base: root::nsISupports,
                 pub _base_1: root::nsWrapperCache,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
                 pub mOwner: root::nsCOMPtr<root::nsISupports>,
                 pub mTime: root::DOMHighResTimeStamp,
                 pub mRootBounds: root::RefPtr<root::mozilla::dom::DOMRect>,
                 pub mBoundingClientRect: root::RefPtr<root::mozilla::dom::DOMRect>,
                 pub mIntersectionRect: root::RefPtr<root::mozilla::dom::DOMRect>,
+                pub mIsIntersecting: bool,
                 pub mTarget: root::RefPtr<root::mozilla::dom::Element>,
                 pub mIntersectionRatio: f64,
             }
             pub type DOMIntersectionObserverEntry_HasThreadSafeRefCnt =
                 root::mozilla::FalseType;
             #[repr(C)]
             #[derive(Debug, Copy)]
             pub struct DOMIntersectionObserverEntry_cycleCollection {
@@ -4113,17 +4300,17 @@ pub mod root {
                       "_ZN7mozilla3dom28DOMIntersectionObserverEntry21_cycleCollectorGlobalE"]
                 pub static mut
                            DOMIntersectionObserverEntry__cycleCollectorGlobal:
                            root::mozilla::dom::DOMIntersectionObserverEntry_cycleCollection;
             }
             #[test]
             fn bindgen_test_layout_DOMIntersectionObserverEntry() {
                 assert_eq!(::std::mem::size_of::<DOMIntersectionObserverEntry>()
-                           , 96usize , concat ! (
+                           , 104usize , concat ! (
                            "Size of: " , stringify ! (
                            DOMIntersectionObserverEntry ) ));
                 assert_eq! (::std::mem::align_of::<DOMIntersectionObserverEntry>()
                             , 8usize , concat ! (
                             "Alignment of " , stringify ! (
                             DOMIntersectionObserverEntry ) ));
             }
             #[repr(C)]
@@ -7834,19 +8021,16 @@ pub mod root {
                         "Alignment of " , stringify ! ( StyleAnimationValue )
                         ));
         }
         impl Clone for StyleAnimationValue {
             fn clone(&self) -> Self { *self }
         }
         #[repr(C)]
         #[derive(Debug, Copy, Clone)]
-        pub struct ServoAnimationRule([u8; 0]);
-        #[repr(C)]
-        #[derive(Debug, Copy, Clone)]
         pub struct AnimationPerformanceWarning([u8; 0]);
         pub type CSSPseudoClassTypeBase = u8;
         #[repr(u8)]
         #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
         pub enum CSSPseudoClassType {
             empty = 0,
             mozOnlyWhitespace = 1,
             mozEmptyExceptChildrenWithLocalname = 2,
@@ -7976,22 +8160,16 @@ pub mod root {
         #[derive(Debug, Copy, Clone)]
         pub struct pair<_T1, _T2> {
             pub first: _T1,
             pub second: _T2,
         }
         pub type pair_first_type<_T1> = _T1;
         pub type pair_second_type<_T2> = _T2;
         #[repr(C)]
-        pub struct atomic<_Tp> {
-            pub _base: (),
-            pub _phantom_0: ::std::marker::PhantomData<_Tp>,
-        }
-        pub type atomic___base = [u8; 0usize];
-        #[repr(C)]
         #[derive(Debug, Copy)]
         pub struct input_iterator_tag {
             pub _address: u8,
         }
         #[test]
         fn bindgen_test_layout_input_iterator_tag() {
             assert_eq!(::std::mem::size_of::<input_iterator_tag>() , 1usize ,
                        concat ! (
@@ -8000,97 +8178,41 @@ pub mod root {
                         , concat ! (
                         "Alignment of " , stringify ! ( input_iterator_tag )
                         ));
         }
         impl Clone for input_iterator_tag {
             fn clone(&self) -> Self { *self }
         }
         #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct forward_iterator_tag {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_forward_iterator_tag() {
-            assert_eq!(::std::mem::size_of::<forward_iterator_tag>() , 1usize
-                       , concat ! (
-                       "Size of: " , stringify ! ( forward_iterator_tag ) ));
-            assert_eq! (::std::mem::align_of::<forward_iterator_tag>() ,
-                        1usize , concat ! (
-                        "Alignment of " , stringify ! ( forward_iterator_tag )
-                        ));
-        }
-        impl Clone for forward_iterator_tag {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct bidirectional_iterator_tag {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_bidirectional_iterator_tag() {
-            assert_eq!(::std::mem::size_of::<bidirectional_iterator_tag>() ,
-                       1usize , concat ! (
-                       "Size of: " , stringify ! ( bidirectional_iterator_tag
-                       ) ));
-            assert_eq! (::std::mem::align_of::<bidirectional_iterator_tag>() ,
-                        1usize , concat ! (
-                        "Alignment of " , stringify ! (
-                        bidirectional_iterator_tag ) ));
-        }
-        impl Clone for bidirectional_iterator_tag {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
-        #[derive(Debug, Copy)]
-        pub struct random_access_iterator_tag {
-            pub _address: u8,
-        }
-        #[test]
-        fn bindgen_test_layout_random_access_iterator_tag() {
-            assert_eq!(::std::mem::size_of::<random_access_iterator_tag>() ,
-                       1usize , concat ! (
-                       "Size of: " , stringify ! ( random_access_iterator_tag
-                       ) ));
-            assert_eq! (::std::mem::align_of::<random_access_iterator_tag>() ,
-                        1usize , concat ! (
-                        "Alignment of " , stringify ! (
-                        random_access_iterator_tag ) ));
-        }
-        impl Clone for random_access_iterator_tag {
-            fn clone(&self) -> Self { *self }
-        }
-        #[repr(C)]
         #[derive(Debug, Copy, Clone)]
         pub struct iterator<_Category, _Tp, _Distance, _Pointer, _Reference> {
             pub _address: u8,
             pub _phantom_0: ::std::marker::PhantomData<_Category>,
             pub _phantom_1: ::std::marker::PhantomData<_Tp>,
             pub _phantom_2: ::std::marker::PhantomData<_Distance>,
             pub _phantom_3: ::std::marker::PhantomData<_Pointer>,
             pub _phantom_4: ::std::marker::PhantomData<_Reference>,
         }
+        pub type iterator_iterator_category<_Category> = _Category;
         pub type iterator_value_type<_Tp> = _Tp;
         pub type iterator_difference_type<_Distance> = _Distance;
         pub type iterator_pointer<_Pointer> = _Pointer;
         pub type iterator_reference<_Reference> = _Reference;
-        pub type iterator_iterator_category<_Category> = _Category;
-        #[repr(C)]
-        #[derive(Debug, Copy, Clone)]
-        pub struct __bit_const_reference<_Cp> {
-            pub __seg_: root::std::__bit_const_reference___storage_pointer<_Cp>,
-            pub __mask_: root::std::__bit_const_reference___storage_type<_Cp>,
-        }
-        pub type __bit_const_reference___storage_type<_Cp> = _Cp;
-        pub type __bit_const_reference___storage_pointer<_Cp> = _Cp;
-    }
-    pub type __darwin_va_list = root::__builtin_va_list;
-    pub type va_list = root::__darwin_va_list;
+        #[repr(C)]
+        #[derive(Debug)]
+        pub struct atomic<_Tp> {
+            pub _M_i: _Tp,
+        }
+    }
+    pub mod __gnu_cxx {
+        #[allow(unused_imports)]
+        use self::super::super::root;
+    }
+    pub type va_list = root::__builtin_va_list;
     /**
  * MozRefCountType is Mozilla's reference count type.
  *
  * We use the same type to represent the refcount of RefCounted objects
  * as well, in order to be able to use the leak detection facilities
  * that are implemented by XPCOM.
  *
  * Note that this type is not in the mozilla namespace so that it is
@@ -9417,114 +9539,43 @@ pub mod root {
         JS_HASH_KEY_EMPTY = 11,
         JS_ION_ERROR = 12,
         JS_ION_BAILOUT = 13,
         JS_OPTIMIZED_OUT = 14,
         JS_UNINITIALIZED_LEXICAL = 15,
         JS_GENERIC_MAGIC = 16,
         JS_WHY_MAGIC_COUNT = 17,
     }
-    #[repr(C)]
-    #[derive(Debug)]
-    pub struct nsAString_internal {
-        pub mData: *mut root::nsAString_internal_char_type,
-        pub mLength: root::nsAString_internal_size_type,
-        pub mFlags: u32,
-    }
-    pub type nsAString_internal_fallible_t = root::mozilla::fallible_t;
-    pub type nsAString_internal_char_type = u16;
-    pub type nsAString_internal_self_type = root::nsAString_internal;
-    pub type nsAString_internal_abstract_string_type =
-        root::nsAString_internal_self_type;
-    pub type nsAString_internal_base_string_type =
-        root::nsAString_internal_self_type;
-    pub type nsAString_internal_substring_type =
-        root::nsAString_internal_self_type;
-    pub type nsAString_internal_substring_tuple_type = root::nsSubstringTuple;
-    pub type nsAString_internal_string_type = ::nsstring::nsStringRepr;
-    pub type nsAString_internal_const_iterator = root::nsReadingIterator<u16>;
-    pub type nsAString_internal_iterator = root::nsWritingIterator<u16>;
-    pub type nsAString_internal_comparator_type = root::nsStringComparator;
-    pub type nsAString_internal_char_iterator =
-        *mut root::nsAString_internal_char_type;
-    pub type nsAString_internal_const_char_iterator =
-        *const root::nsAString_internal_char_type;
-    pub type nsAString_internal_size_type = u32;
-    pub type nsAString_internal_index_type = u32;
-    pub const nsAString_internal_F_NONE:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_NONE;
-    pub const nsAString_internal_F_TERMINATED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_TERMINATED;
-    pub const nsAString_internal_F_VOIDED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_VOIDED;
-    pub const nsAString_internal_F_SHARED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_SHARED;
-    pub const nsAString_internal_F_OWNED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_OWNED;
-    pub const nsAString_internal_F_FIXED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_FIXED;
-    pub const nsAString_internal_F_LITERAL:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_LITERAL;
-    pub const nsAString_internal_F_CLASS_FIXED:
-              root::nsAString_internal__bindgen_ty_1 =
-        nsAString_internal__bindgen_ty_1::F_CLASS_FIXED;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsAString_internal__bindgen_ty_1 {
-        F_NONE = 0,
-        F_TERMINATED = 1,
-        F_VOIDED = 2,
-        F_SHARED = 4,
-        F_OWNED = 8,
-        F_FIXED = 16,
-        F_LITERAL = 32,
-        F_CLASS_FIXED = 65536,
-    }
-    #[test]
-    fn bindgen_test_layout_nsAString_internal() {
-        assert_eq!(::std::mem::size_of::<nsAString_internal>() , 16usize ,
-                   concat ! ( "Size of: " , stringify ! ( nsAString_internal )
-                   ));
-        assert_eq! (::std::mem::align_of::<nsAString_internal>() , 8usize ,
-                    concat ! (
-                    "Alignment of " , stringify ! ( nsAString_internal ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsAString_internal ) ) . mData as *
-                    const _ as usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsAString_internal
-                    ) , "::" , stringify ! ( mData ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsAString_internal ) ) . mLength as *
-                    const _ as usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsAString_internal
-                    ) , "::" , stringify ! ( mLength ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsAString_internal ) ) . mFlags as *
-                    const _ as usize } , 12usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsAString_internal
-                    ) , "::" , stringify ! ( mFlags ) ));
+    /**
+ * double-byte (char16_t) string types
+ */
+    #[repr(C)]
+    #[derive(Debug)]
+    pub struct nsAString {
+        pub _base: root::mozilla::detail::nsStringRepr,
+    }
+    pub type nsAString_self_type = root::nsAString;
+    #[test]
+    fn bindgen_test_layout_nsAString() {
+        assert_eq!(::std::mem::size_of::<nsAString>() , 16usize , concat ! (
+                   "Size of: " , stringify ! ( nsAString ) ));
+        assert_eq! (::std::mem::align_of::<nsAString>() , 8usize , concat ! (
+                    "Alignment of " , stringify ! ( nsAString ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsSubstringTuple {
         pub mHead: *const root::nsSubstringTuple_self_type,
         pub mFragA: *const root::nsSubstringTuple_base_string_type,
         pub mFragB: *const root::nsSubstringTuple_base_string_type,
     }
     pub type nsSubstringTuple_char_type = u16;
     pub type nsSubstringTuple_self_type = root::nsSubstringTuple;
-    pub type nsSubstringTuple_substring_type = root::nsAString_internal;
-    pub type nsSubstringTuple_base_string_type = root::nsAString_internal;
+    pub type nsSubstringTuple_base_string_type =
+        root::mozilla::detail::nsStringRepr;
     pub type nsSubstringTuple_size_type = u32;
     #[test]
     fn bindgen_test_layout_nsSubstringTuple() {
         assert_eq!(::std::mem::size_of::<nsSubstringTuple>() , 24usize ,
                    concat ! ( "Size of: " , stringify ! ( nsSubstringTuple )
                    ));
         assert_eq! (::std::mem::align_of::<nsSubstringTuple>() , 8usize ,
                     concat ! (
@@ -9546,17 +9597,17 @@ pub mod root {
                     , "::" , stringify ! ( mFragB ) ));
     }
     impl Clone for nsSubstringTuple {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     pub struct nsAutoString {
         pub _base: root::nsFixedString,
-        pub mStorage: [root::nsAString_internal_char_type; 64usize],
+        pub mStorage: [root::mozilla::detail::nsStringRepr_char_type; 64usize],
     }
     pub type nsAutoString_self_type = root::nsAutoString;
     pub const nsAutoString_kDefaultStorageSize:
               root::nsAutoString__bindgen_ty_1 =
         nsAutoString__bindgen_ty_1::kDefaultStorageSize;
     #[repr(u32)]
     #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
     pub enum nsAutoString__bindgen_ty_1 { kDefaultStorageSize = 64, }
@@ -9570,17 +9621,17 @@ pub mod root {
                     & ( * ( 0 as * const nsAutoString ) ) . mStorage as *
                     const _ as usize } , 32usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsAutoString ) ,
                     "::" , stringify ! ( mStorage ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsDependentSubstring {
-        pub _base: root::nsAString_internal,
+        pub _base: root::nsAString,
     }
     pub type nsDependentSubstring_self_type = root::nsDependentSubstring;
     #[test]
     fn bindgen_test_layout_nsDependentSubstring() {
         assert_eq!(::std::mem::size_of::<nsDependentSubstring>() , 16usize ,
                    concat ! (
                    "Size of: " , stringify ! ( nsDependentSubstring ) ));
         assert_eq! (::std::mem::align_of::<nsDependentSubstring>() , 8usize ,
@@ -9603,117 +9654,43 @@ pub mod root {
                    ));
         assert_eq! (::std::mem::align_of::<nsStringComparator>() , 8usize ,
                     concat ! (
                     "Alignment of " , stringify ! ( nsStringComparator ) ));
     }
     impl Clone for nsStringComparator {
         fn clone(&self) -> Self { *self }
     }
-    #[repr(C)]
-    #[derive(Debug)]
-    pub struct nsACString_internal {
-        pub mData: *mut root::nsACString_internal_char_type,
-        pub mLength: root::nsACString_internal_size_type,
-        pub mFlags: u32,
-    }
-    pub type nsACString_internal_fallible_t = root::mozilla::fallible_t;
-    pub type nsACString_internal_char_type = ::std::os::raw::c_char;
-    pub type nsACString_internal_self_type = root::nsACString_internal;
-    pub type nsACString_internal_abstract_string_type =
-        root::nsACString_internal_self_type;
-    pub type nsACString_internal_base_string_type =
-        root::nsACString_internal_self_type;
-    pub type nsACString_internal_substring_type =
-        root::nsACString_internal_self_type;
-    pub type nsACString_internal_substring_tuple_type =
-        root::nsCSubstringTuple;
-    pub type nsACString_internal_string_type = root::nsCString;
-    pub type nsACString_internal_const_iterator =
-        root::nsReadingIterator<::std::os::raw::c_char>;
-    pub type nsACString_internal_iterator =
-        root::nsWritingIterator<::std::os::raw::c_char>;
-    pub type nsACString_internal_comparator_type = root::nsCStringComparator;
-    pub type nsACString_internal_char_iterator =
-        *mut root::nsACString_internal_char_type;
-    pub type nsACString_internal_const_char_iterator =
-        *const root::nsACString_internal_char_type;
-    pub type nsACString_internal_size_type = u32;
-    pub type nsACString_internal_index_type = u32;
-    pub const nsACString_internal_F_NONE:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_NONE;
-    pub const nsACString_internal_F_TERMINATED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_TERMINATED;
-    pub const nsACString_internal_F_VOIDED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_VOIDED;
-    pub const nsACString_internal_F_SHARED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_SHARED;
-    pub const nsACString_internal_F_OWNED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_OWNED;
-    pub const nsACString_internal_F_FIXED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_FIXED;
-    pub const nsACString_internal_F_LITERAL:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_LITERAL;
-    pub const nsACString_internal_F_CLASS_FIXED:
-              root::nsACString_internal__bindgen_ty_1 =
-        nsACString_internal__bindgen_ty_1::F_CLASS_FIXED;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum nsACString_internal__bindgen_ty_1 {
-        F_NONE = 0,
-        F_TERMINATED = 1,
-        F_VOIDED = 2,
-        F_SHARED = 4,
-        F_OWNED = 8,
-        F_FIXED = 16,
-        F_LITERAL = 32,
-        F_CLASS_FIXED = 65536,
-    }
-    #[test]
-    fn bindgen_test_layout_nsACString_internal() {
-        assert_eq!(::std::mem::size_of::<nsACString_internal>() , 16usize ,
-                   concat ! (
-                   "Size of: " , stringify ! ( nsACString_internal ) ));
-        assert_eq! (::std::mem::align_of::<nsACString_internal>() , 8usize ,
-                    concat ! (
-                    "Alignment of " , stringify ! ( nsACString_internal ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsACString_internal ) ) . mData as *
-                    const _ as usize } , 0usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsACString_internal
-                    ) , "::" , stringify ! ( mData ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsACString_internal ) ) . mLength as
-                    * const _ as usize } , 8usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsACString_internal
-                    ) , "::" , stringify ! ( mLength ) ));
-        assert_eq! (unsafe {
-                    & ( * ( 0 as * const nsACString_internal ) ) . mFlags as *
-                    const _ as usize } , 12usize , concat ! (
-                    "Alignment of field: " , stringify ! ( nsACString_internal
-                    ) , "::" , stringify ! ( mFlags ) ));
+    /**
+ * single-byte (char) string types
+ */
+    #[repr(C)]
+    #[derive(Debug)]
+    pub struct nsACString {
+        pub _base: root::mozilla::detail::nsCStringRepr,
+    }
+    pub type nsACString_self_type = root::nsACString;
+    #[test]
+    fn bindgen_test_layout_nsACString() {
+        assert_eq!(::std::mem::size_of::<nsACString>() , 16usize , concat ! (
+                   "Size of: " , stringify ! ( nsACString ) ));
+        assert_eq! (::std::mem::align_of::<nsACString>() , 8usize , concat ! (
+                    "Alignment of " , stringify ! ( nsACString ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsCSubstringTuple {
         pub mHead: *const root::nsCSubstringTuple_self_type,
         pub mFragA: *const root::nsCSubstringTuple_base_string_type,
         pub mFragB: *const root::nsCSubstringTuple_base_string_type,
     }
     pub type nsCSubstringTuple_char_type = ::std::os::raw::c_char;
     pub type nsCSubstringTuple_self_type = root::nsCSubstringTuple;
-    pub type nsCSubstringTuple_substring_type = root::nsACString_internal;
-    pub type nsCSubstringTuple_base_string_type = root::nsACString_internal;
+    pub type nsCSubstringTuple_base_string_type =
+        root::mozilla::detail::nsCStringRepr;
     pub type nsCSubstringTuple_size_type = u32;
     #[test]
     fn bindgen_test_layout_nsCSubstringTuple() {
         assert_eq!(::std::mem::size_of::<nsCSubstringTuple>() , 24usize ,
                    concat ! ( "Size of: " , stringify ! ( nsCSubstringTuple )
                    ));
         assert_eq! (::std::mem::align_of::<nsCSubstringTuple>() , 8usize ,
                     concat ! (
@@ -9735,17 +9712,17 @@ pub mod root {
                     , "::" , stringify ! ( mFragB ) ));
     }
     impl Clone for nsCSubstringTuple {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsCString {
-        pub _base: root::nsACString_internal,
+        pub _base: root::nsACString,
     }
     pub type nsCString_self_type = root::nsCString;
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsCString_Segment {
         pub mBegin: u32,
         pub mLength: u32,
     }
@@ -9776,17 +9753,17 @@ pub mod root {
         assert_eq!(::std::mem::size_of::<nsCString>() , 16usize , concat ! (
                    "Size of: " , stringify ! ( nsCString ) ));
         assert_eq! (::std::mem::align_of::<nsCString>() , 8usize , concat ! (
                     "Alignment of " , stringify ! ( nsCString ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsDependentCSubstring {
-        pub _base: root::nsACString_internal,
+        pub _base: root::nsACString,
     }
     pub type nsDependentCSubstring_self_type = root::nsDependentCSubstring;
     #[test]
     fn bindgen_test_layout_nsDependentCSubstring() {
         assert_eq!(::std::mem::size_of::<nsDependentCSubstring>() , 16usize ,
                    concat ! (
                    "Size of: " , stringify ! ( nsDependentCSubstring ) ));
         assert_eq! (::std::mem::align_of::<nsDependentCSubstring>() , 8usize ,
@@ -9813,17 +9790,17 @@ pub mod root {
                     "Alignment of " , stringify ! ( nsCStringComparator ) ));
     }
     impl Clone for nsCStringComparator {
         fn clone(&self) -> Self { *self }
     }
     /**
  * typedefs for backwards compatibility
  */
-    pub type nsSubstring = root::nsAString_internal;
+    pub type nsSubstring = root::nsAString;
     pub type nsAFlatCString = root::nsCString;
     #[repr(C)]
     pub struct nsISupports__bindgen_vtable {
     }
     /**
  * Basic component object model interface. Objects which implement
  * this interface support runtime interface discovery (QueryInterface)
  * and a reference counted memory model (AddRef/Release). This is
@@ -9949,26 +9926,26 @@ pub mod root {
     pub type nsWritingIterator_difference_type = isize;
     pub type nsWritingIterator_size_type = usize;
     pub type nsWritingIterator_value_type<CharT> = CharT;
     pub type nsWritingIterator_pointer<CharT> = *mut CharT;
     pub type nsWritingIterator_reference = [u8; 0usize];
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsSubstringSplitter {
-        pub mStr: *const root::nsAString_internal,
+        pub mStr: *const root::nsAString,
         pub mArray: root::mozilla::UniquePtr<[root::nsDependentSubstring; 0usize],
                                              root::mozilla::DefaultDelete<[root::nsDependentSubstring; 0usize]>>,
         pub mArraySize: root::nsSubstringSplitter_size_type,
         pub mDelim: root::nsSubstringSplitter_char_type,
     }
     pub type nsSubstringSplitter_size_type =
-        root::nsAString_internal_size_type;
+        root::mozilla::detail::nsStringRepr_size_type;
     pub type nsSubstringSplitter_char_type =
-        root::nsAString_internal_char_type;
+        root::mozilla::detail::nsStringRepr_char_type;
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsSubstringSplitter_nsTSubstringSplit_Iter {
         pub mObj: *const root::nsSubstringSplitter,
         pub mPos: root::nsSubstringSplitter_size_type,
     }
     #[test]
     fn bindgen_test_layout_nsSubstringSplitter_nsTSubstringSplit_Iter() {
@@ -10027,26 +10004,26 @@ pub mod root {
                     & ( * ( 0 as * const nsSubstringSplitter ) ) . mDelim as *
                     const _ as usize } , 20usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsSubstringSplitter
                     ) , "::" , stringify ! ( mDelim ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsCSubstringSplitter {
-        pub mStr: *const root::nsACString_internal,
+        pub mStr: *const root::nsACString,
         pub mArray: root::mozilla::UniquePtr<[root::nsDependentCSubstring; 0usize],
                                              root::mozilla::DefaultDelete<[root::nsDependentCSubstring; 0usize]>>,
         pub mArraySize: root::nsCSubstringSplitter_size_type,
         pub mDelim: root::nsCSubstringSplitter_char_type,
     }
     pub type nsCSubstringSplitter_size_type =
-        root::nsACString_internal_size_type;
+        root::mozilla::detail::nsCStringRepr_size_type;
     pub type nsCSubstringSplitter_char_type =
-        root::nsACString_internal_char_type;
+        root::mozilla::detail::nsCStringRepr_char_type;
     #[repr(C)]
     #[derive(Debug, Copy)]
     pub struct nsCSubstringSplitter_nsTSubstringSplit_Iter {
         pub mObj: *const root::nsCSubstringSplitter,
         pub mPos: root::nsCSubstringSplitter_size_type,
     }
     #[test]
     fn bindgen_test_layout_nsCSubstringSplitter_nsTSubstringSplit_Iter() {
@@ -10107,18 +10084,18 @@ pub mod root {
                     * const _ as usize } , 20usize , concat ! (
                     "Alignment of field: " , stringify ! (
                     nsCSubstringSplitter ) , "::" , stringify ! ( mDelim ) ));
     }
     #[repr(C)]
     #[derive(Debug)]
     pub struct nsFixedString {
         pub _base: ::nsstring::nsStringRepr,
-        pub mFixedCapacity: root::nsAString_internal_size_type,
-        pub mFixedBuf: *mut root::nsAString_internal_char_type,
+        pub mFixedCapacity: root::mozilla::detail::nsStringRepr_size_type,
+        pub mFixedBuf: *mut root::mozilla::detail::nsStringRepr_char_type,
     }
     pub type nsFixedString_self_type = root::nsFixedString;
     pub type nsFixedString_fixed_string_type = root::nsFixedString;
     #[test]
     fn bindgen_test_layout_nsFixedString() {
         assert_eq!(::std::mem::size_of::<nsFixedString>() , 32usize , concat !
                    ( "Size of: " , stringify ! ( nsFixedString ) ));
         assert_eq! (::std::mem::align_of::<nsFixedString>() , 8usize , concat
@@ -15083,73 +15060,73 @@ pub mod root {
                     & ( * ( 0 as * const nsNodeWeakReference ) ) . mNode as *
                     const _ as usize } , 16usize , concat ! (
                     "Alignment of field: " , stringify ! ( nsNodeWeakReference
                     ) , "::" , stringify ! ( mNode ) ));
     }
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
     pub struct nsDOMMutationObserver([u8; 0]);
-    pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_LISTENERMANAGER;
-    pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_PROPERTIES;
-    pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_ANONYMOUS_ROOT;
-    pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
-    pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS_ROOT;
-    pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_FORCE_XBL_BINDINGS;
-    pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_MAY_BE_IN_BINDING_MNGR;
-    pub const NODE_IS_EDITABLE: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_EDITABLE;
-    pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_NATIVE_ANONYMOUS;
-    pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_IN_SHADOW_TREE;
-    pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_EMPTY_SELECTOR;
-    pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_SLOW_SELECTOR;
-    pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_EDGE_CHILD_SELECTOR;
-    pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
-    pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_ALL_SELECTOR_FLAGS;
-    pub const NODE_NEEDS_FRAME: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_NEEDS_FRAME;
-    pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_DESCENDANTS_NEED_FRAMES;
-    pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_ACCESSKEY;
-    pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_DIRECTION_RTL;
-    pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_HAS_DIRECTION_LTR;
-    pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_ALL_DIRECTION_FLAGS;
-    pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_CHROME_ONLY_ACCESS;
-    pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
-    pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
-    pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_2;
-    pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_SHARED_RESTYLE_BIT_1;
-    pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_28 =
-        _bindgen_ty_28::NODE_TYPE_SPECIFIC_BITS_OFFSET;
-    #[repr(u32)]
-    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-    pub enum _bindgen_ty_28 {
+    pub const NODE_HAS_LISTENERMANAGER: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_LISTENERMANAGER;
+    pub const NODE_HAS_PROPERTIES: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_PROPERTIES;
+    pub const NODE_IS_ANONYMOUS_ROOT: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_ANONYMOUS_ROOT;
+    pub const NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
+    pub const NODE_IS_NATIVE_ANONYMOUS_ROOT: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_NATIVE_ANONYMOUS_ROOT;
+    pub const NODE_FORCE_XBL_BINDINGS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_FORCE_XBL_BINDINGS;
+    pub const NODE_MAY_BE_IN_BINDING_MNGR: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_MAY_BE_IN_BINDING_MNGR;
+    pub const NODE_IS_EDITABLE: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_EDITABLE;
+    pub const NODE_IS_NATIVE_ANONYMOUS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_NATIVE_ANONYMOUS;
+    pub const NODE_IS_IN_SHADOW_TREE: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_IN_SHADOW_TREE;
+    pub const NODE_HAS_EMPTY_SELECTOR: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_EMPTY_SELECTOR;
+    pub const NODE_HAS_SLOW_SELECTOR: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_SLOW_SELECTOR;
+    pub const NODE_HAS_EDGE_CHILD_SELECTOR: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_EDGE_CHILD_SELECTOR;
+    pub const NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_SLOW_SELECTOR_LATER_SIBLINGS;
+    pub const NODE_ALL_SELECTOR_FLAGS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_ALL_SELECTOR_FLAGS;
+    pub const NODE_NEEDS_FRAME: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_NEEDS_FRAME;
+    pub const NODE_DESCENDANTS_NEED_FRAMES: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_DESCENDANTS_NEED_FRAMES;
+    pub const NODE_HAS_ACCESSKEY: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_ACCESSKEY;
+    pub const NODE_HAS_DIRECTION_RTL: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_DIRECTION_RTL;
+    pub const NODE_HAS_DIRECTION_LTR: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_HAS_DIRECTION_LTR;
+    pub const NODE_ALL_DIRECTION_FLAGS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_ALL_DIRECTION_FLAGS;
+    pub const NODE_CHROME_ONLY_ACCESS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_CHROME_ONLY_ACCESS;
+    pub const NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_IS_ROOT_OF_CHROME_ONLY_ACCESS;
+    pub const NODE_SHARED_RESTYLE_BIT_1: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_SHARED_RESTYLE_BIT_1;
+    pub const NODE_SHARED_RESTYLE_BIT_2: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_SHARED_RESTYLE_BIT_2;
+    pub const NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_SHARED_RESTYLE_BIT_1;
+    pub const NODE_TYPE_SPECIFIC_BITS_OFFSET: root::_bindgen_ty_105 =
+        _bindgen_ty_105::NODE_TYPE_SPECIFIC_BITS_OFFSET;
+    #[repr(u32)]
+    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+    pub enum _bindgen_ty_105 {
         NODE_HAS_LISTENERMANAGER = 4,
         NODE_HAS_PROPERTIES = 8,
         NODE_IS_ANONYMOUS_ROOT = 16,
         NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE = 32,
         NODE_IS_NATIVE_ANONYMOUS_ROOT = 64,
         NODE_FORCE_XBL_BINDINGS = 128,
         NODE_MAY_BE_IN_BINDING_MNGR = 256,
         NODE_IS_EDITABLE = 512,
@@ -25212,46 +25189,47 @@ pub mod root {
                     "Alignment of field: " , stringify ! ( LookAndFeelInt ) ,
                     "::" , stringify ! ( value ) ));
     }
     impl Clone for LookAndFeelInt {
         fn clone(&self) -> Self { *self }
     }
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
+    pub struct RawServoStyleSet([u8; 0]);
+    #[repr(C)]
+    #[derive(Debug, Copy, Clone)]
     pub struct RawServoAnimationValue([u8; 0]);
     #[repr(C)]
     #[derive(Debug, Copy, Clone)]
-    pub struct RawServoStyleSet([u8; 0]);
+    pub struct RawServoAnimationValueMap([u8; 0]);
     pub type RawGeckoNode = root::nsINode;
     pub type RawGeckoElement = root::mozilla::dom::Element;
     pub type RawGeckoDocument = root::nsIDocument;
     pub type RawGeckoPresContext = root::nsPresContext;
     pub type RawGeckoKeyframeList = root::nsTArray<root::mozilla::Keyframe>;
     pub type RawGeckoComputedKeyframeValuesList =
         root::nsTArray<root::nsTArray<root::mozilla::PropertyStyleAnimationValuePair>>;
     pub type RawGeckoAnimationValueList =
         root::nsTArray<root::mozilla::PropertyStyleAnimationValuePair>;
-    pub type RawServoAnimationValueBorrowedList =
-        root::nsTArray<*const root::RawServoAnimationValue>;
     pub type RawGeckoStyleAnimationList =
         root::nsStyleAutoArray<root::mozilla::StyleAnimation>;
+    pub type RawServoAnimationValueMapBorrowed =
+        *const root::RawServoAnimationValueMap;
     pub type RawGeckoNodeBorrowed = *const root::RawGeckoNode;
     pub type RawGeckoNodeBorrowedOrNull = *const root::RawGeckoNode;
     pub type RawGeckoElementBorrowed = *const root::RawGeckoElement;
     pub type RawGeckoElementBorrowedOrNull = *const root::RawGeckoElement;
     pub type RawGeckoDocumentBorrowed = *const root::RawGeckoDocument;
     pub type RawGeckoDocumentBorrowedOrNull = *const root::RawGeckoDocument;
     pub type RawGeckoPresContextOwned = *mut root::RawGeckoPresContext;
     pub type RawGeckoPresContextBorrowed = *const root::RawGeckoPresContext;
     pub type RawGeckoPresContextBorrowedMut = *mut root::RawGeckoPresContext;
     pub type RawGeckoAnimationValueListBorrowedMut =
         *mut root::RawGeckoAnimationValueList;
-    pub type RawServoAnimationValueBorrowedListBorrowed =
-        *const root::RawServoAnimationValueBorrowedList;
     pub type RawGeckoKeyframeListBorrowedMut =
         *mut root::RawGeckoKeyframeList;
     pub type RawGeckoKeyframeListBorrowed = *const root::RawGeckoKeyframeList;
     pub type RawGeckoComputedKeyframeValuesListBorrowedMut =
         *mut root::RawGeckoComputedKeyframeValuesList;
     pub type RawGeckoStyleAnimationListBorrowed =
         *const root::RawGeckoStyleAnimationList;
     #[repr(C)]
--- a/servo/components/style/matching.rs
+++ b/servo/components/style/matching.rs
@@ -9,17 +9,17 @@
 
 use {Atom, LocalName};
 use animation::{self, Animation, PropertyAnimation};
 use atomic_refcell::AtomicRefMut;
 use cache::{LRUCache, LRUCacheMutIterator};
 use cascade_info::CascadeInfo;
 use context::{SequentialTask, SharedStyleContext, StyleContext};
 use data::{ComputedStyle, ElementData, ElementStyles, RestyleData};
-use dom::{SendElement, TElement, TNode};
+use dom::{AnimationRules, SendElement, TElement, TNode};
 use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
 use properties::longhands::display::computed_value as display;
 use restyle_hints::{RESTYLE_STYLE_ATTRIBUTE, RestyleHint};
 use rule_tree::{CascadeLevel, StrongRuleNode};
 use selector_parser::{PseudoElement, RestyleDamage, SelectorImpl};
 use selectors::MatchAttr;
 use selectors::bloom::BloomFilter;
 use selectors::matching::{ElementSelectorFlags, StyleRelations};
@@ -795,17 +795,21 @@ pub trait MatchMethods : TElement {
             rule_nodes_changed = true;
         }
 
         // Compute rule nodes for eagerly-cascaded pseudo-elements.
         let mut matches_different_pseudos = false;
         SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| {
             let mut per_pseudo = &mut data.styles_mut().pseudos;
             debug_assert!(applicable_declarations.is_empty());
-            let pseudo_animation_rules = self.get_animation_rules(Some(&pseudo));
+            let pseudo_animation_rules = if <Self as MatchAttr>::Impl::pseudo_is_before_or_after(&pseudo) {
+                self.get_animation_rules(Some(&pseudo))
+            } else {
+                AnimationRules(None, None)
+            };
             stylist.push_applicable_declarations(self,
                                                  Some(context.thread_local.bloom_filter.filter()),
                                                  None, pseudo_animation_rules,
                                                  Some(&pseudo),
                                                  &mut applicable_declarations,
                                                  &mut flags);
 
             if !applicable_declarations.is_empty() {
--- a/servo/components/style/properties/declaration_block.rs
+++ b/servo/components/style/properties/declaration_block.rs
@@ -10,16 +10,17 @@ use cssparser::{DeclarationListParser, p
 use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
 use error_reporting::ParseErrorReporter;
 use parser::{ParserContext, ParserContextExtraData, log_css_error};
 use servo_url::ServoUrl;
 use std::fmt;
 use style_traits::ToCss;
 use stylesheets::Origin;
 use super::*;
+#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;
 
 /// A declaration [importance][importance].
 ///
 /// [importance]: https://drafts.csswg.org/css-cascade/#importance
 #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub enum Importance {
     /// Indicates a declaration without `!important`.
@@ -336,16 +337,34 @@ impl PropertyDeclarationBlock {
                     Some(AppendableValue::DeclarationsForShorthand(_, decls)) => {
                         shorthand.longhands_to_css(decls, dest)
                     }
                     _ => Ok(())
                 }
             }
         }
     }
+
+    /// Convert AnimationValueMap to PropertyDeclarationBlock.
+    #[cfg(feature = "gecko")]
+    pub fn from_animation_value_map(animation_value_map: &AnimationValueMap) -> Self {
+        let mut declarations = vec![];
+        let mut longhands = LonghandIdSet::new();
+
+        for (property, animation_value) in animation_value_map.iter() {
+          longhands.set_transition_property_bit(property);
+          declarations.push((animation_value.uncompute(), Importance::Normal));
+        }
+
+        PropertyDeclarationBlock {
+            declarations: declarations,
+            important_count: 0,
+            longhands: longhands,
+        }
+    }
 }
 
 impl ToCss for PropertyDeclarationBlock {
     // https://drafts.csswg.org/cssom/#serialize-a-css-declaration-block
     fn to_css<W>(&self, dest: &mut W) -> fmt::Result
         where W: fmt::Write,
     {
         let mut is_first_serialization = true; // trailing serializations should have a prepended space
--- a/servo/components/style/properties/helpers/animated_properties.mako.rs
+++ b/servo/components/style/properties/helpers/animated_properties.mako.rs
@@ -20,16 +20,17 @@ use properties::longhands::box_shadow::s
 use properties::longhands::transform::computed_value::ComputedMatrix;
 use properties::longhands::transform::computed_value::ComputedOperation as TransformOperation;
 use properties::longhands::transform::computed_value::T as TransformList;
 use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
 use properties::longhands::visibility::computed_value::T as Visibility;
 use properties::longhands::z_index::computed_value::T as ZIndex;
 #[cfg(feature = "gecko")] use properties::{PropertyDeclarationId, LonghandId};
 use std::cmp;
+#[cfg(feature = "gecko")] use std::collections::HashMap;
 use std::fmt;
 use style_traits::ToCss;
 use super::ComputedValues;
 use values::CSSFloat;
 use values::{Auto, Either};
 use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
 use values::computed::{BorderRadiusSize, ClipRect, LengthOrNone};
 use values::computed::{CalcLengthOrPercentage, Context, LengthOrPercentage};
@@ -247,16 +248,22 @@ impl AnimatedProperty {
                             new_style.get_${prop.style_struct.ident.strip("_")}().clone_${prop.ident}())
                     }
                 % endif
             % endfor
         }
     }
 }
 
+/// A collection of AnimationValue that were composed on an element.
+/// This HashMap stores the values that are the last AnimationValue to be
+/// composed for each TransitionProperty.
+#[cfg(feature = "gecko")]
+pub type AnimationValueMap = HashMap<TransitionProperty, AnimationValue>;
+
 /// An enum to represent a single computed value belonging to an animated
 /// property in order to be interpolated with another one. When interpolating,
 /// both values need to belong to the same property.
 ///
 /// This is different to AnimatedProperty in the sense that AnimatedProperty
 /// also knows the final value to be used during the animation.
 ///
 /// This is to be used in Gecko integration code.
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -40,27 +40,27 @@ use style::gecko_bindings::bindings::{Ra
 use style::gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed};
 use style::gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong};
 use style::gecko_bindings::bindings::{ServoCssRulesBorrowed, ServoCssRulesStrong};
 use style::gecko_bindings::bindings::{nsACString, nsAString};
 use style::gecko_bindings::bindings::Gecko_AnimationAppendKeyframe;
 use style::gecko_bindings::bindings::RawGeckoComputedKeyframeValuesListBorrowedMut;
 use style::gecko_bindings::bindings::RawGeckoElementBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueBorrowed;
+use style::gecko_bindings::bindings::RawServoAnimationValueMapBorrowed;
 use style::gecko_bindings::bindings::RawServoAnimationValueStrong;
 use style::gecko_bindings::bindings::RawServoImportRuleBorrowed;
 use style::gecko_bindings::bindings::ServoComputedValuesBorrowedOrNull;
 use style::gecko_bindings::bindings::nsTArrayBorrowed_uintptr_t;
 use style::gecko_bindings::structs;
 use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
 use style::gecko_bindings::structs::{ThreadSafePrincipalHolder, ThreadSafeURIHolder};
 use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint};
 use style::gecko_bindings::structs::Loader;
 use style::gecko_bindings::structs::RawGeckoPresContextOwned;
-use style::gecko_bindings::structs::RawServoAnimationValueBorrowedListBorrowed;
 use style::gecko_bindings::structs::ServoStyleSheet;
 use style::gecko_bindings::structs::nsCSSValueSharedList;
 use style::gecko_bindings::structs::nsTimingFunction;
 use style::gecko_bindings::structs::nsresult;
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasBoxFFI};
 use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
 use style::gecko_bindings::sugar::refptr::{GeckoArcPrincipal, GeckoArcURI};
 use style::gecko_properties::{self, style_structs};
@@ -243,27 +243,25 @@ pub extern "C" fn Servo_AnimationValues_
     if let Ok(value) = from_value.interpolate(to_value, progress) {
         Arc::new(value).into_strong()
     } else {
         RawServoAnimationValueStrong::null()
     }
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_AnimationValues_Uncompute(value: RawServoAnimationValueBorrowedListBorrowed)
-     -> RawServoDeclarationBlockStrong
+pub extern "C" fn Servo_AnimationValueMap_Push(value_map: RawServoAnimationValueMapBorrowed,
+                                               property: nsCSSPropertyID,
+                                               value: RawServoAnimationValueBorrowed)
 {
-    let value = unsafe { value.as_ref().unwrap() };
-    let mut block = PropertyDeclarationBlock::new();
-    for v in value.iter() {
-        let raw_anim = unsafe { v.as_ref().unwrap() };
-        let anim = AnimationValue::as_arc(&raw_anim);
-        block.push(anim.uncompute(), Importance::Normal);
-    }
-    Arc::new(RwLock::new(block)).into_strong()
+    use style::properties::animated_properties::AnimationValueMap;
+
+    let value_map = RwLock::<AnimationValueMap>::as_arc(&value_map);
+    let value = AnimationValue::as_arc(&value).as_ref();
+    value_map.write().insert(property.into(), value.clone());
 }
 
 macro_rules! get_property_id_from_nscsspropertyid {
     ($property_id: ident, $ret: expr) => {{
         match PropertyId::from_nscsspropertyid($property_id) {
             Ok(property_id) => property_id,
             Err(()) => { return $ret; }
         }
--- a/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierStreamUpdater.cpp
@@ -94,17 +94,16 @@ nsUrlClassifierStreamUpdater::DownloadDo
   LOG(("nsUrlClassifierStreamUpdater::DownloadDone [this=%p]", this));
   mIsUpdating = false;
 
   mPendingUpdates.Clear();
   mDownloadError = false;
   mSuccessCallback = nullptr;
   mUpdateErrorCallback = nullptr;
   mDownloadErrorCallback = nullptr;
-  mTelemetryProvider.Truncate();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // nsIUrlClassifierStreamUpdater implementation
 
 nsresult
 nsUrlClassifierStreamUpdater::FetchUpdate(nsIURI *aUpdateUrl,
                                           const nsACString & aRequestPayload,
@@ -776,16 +775,17 @@ nsUrlClassifierStreamUpdater::OnStopRequ
   } else {
     LOG(("OnStopRequest::Finishing update [this=%p]", this));
     // The fetch failed, but we didn't start the stream (probably a
     // server or connection error).  We can commit what we've applied
     // so far, and request again later.
     rv = mDBService->FinishUpdate();
   }
 
+  mTelemetryProvider.Truncate();
   mChannel = nullptr;
 
   // If the fetch failed, return the network status rather than NS_OK, the
   // result of finishing a possibly-empty update
   if (NS_SUCCEEDED(aStatus)) {
     return rv;
   }
   return aStatus;