Bug 1353202 - Add support for iteration composite modes draft
authorBrian Birtles <birtles@gmail.com>
Tue, 23 May 2017 14:42:58 +0900
changeset 582817 a356414fd529253e85253455e97d268e0edf138b
parent 582816 c10a927bd320efdfe6dfb72a8bbe78e9bade8712
child 582818 dbbfa6cf8dd8c146941806fff5291f7e398dacd4
push id60186
push userbbirtles@mozilla.com
push dateTue, 23 May 2017 05:52:17 +0000
bugs1353202
milestone55.0a1
Bug 1353202 - Add support for iteration composite modes MozReview-Commit-ID: 6xMr86JKvLO
dom/animation/KeyframeEffectReadOnly.cpp
layout/reftests/web-animations/reftest.list
layout/style/ServoBindingList.h
layout/style/ServoBindings.h
layout/style/ServoBindings.toml
servo/components/style/gecko/generated/bindings.rs
servo/components/style/gecko/generated/structs_debug.rs
servo/components/style/gecko/generated/structs_release.rs
servo/ports/geckolib/glue.rs
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -650,33 +650,30 @@ KeyframeEffectReadOnly::ComposeStyleRule
     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(
   RawServoAnimationValueMap& aAnimationValues,
   const AnimationProperty& aProperty,
   const AnimationPropertySegment& aSegment,
   const ComputedTiming& aComputedTiming)
 {
-  // Bug 1329878 - Stylo: Implement accumulate and addition on Servo
-  // AnimationValue.
-
   Servo_AnimationCompose(&aAnimationValues,
                          &mBaseStyleValuesForServo,
                          aProperty.mProperty,
                          &aSegment,
-                         &aComputedTiming);
+                         &aProperty.mSegments.LastElement(),
+                         &aComputedTiming,
+                         mEffectOptions.mIterationComposite);
 }
 
 template<typename ComposeAnimationResult>
 void
 KeyframeEffectReadOnly::ComposeStyle(
   ComposeAnimationResult&& aComposeResult,
   const nsCSSPropertyIDSet& aPropertiesToSkip)
 {
--- a/layout/reftests/web-animations/reftest.list
+++ b/layout/reftests/web-animations/reftest.list
@@ -13,10 +13,10 @@ test-pref(dom.animations-api.core.enable
 test-pref(dom.animations-api.core.enabled,true) == stacking-context-transform-changing-keyframe-in-delay.html stacking-context-animation-ref.html
 test-pref(dom.animations-api.core.enabled,true) == stacking-context-transform-changing-target.html stacking-context-animation-changing-target-ref.html
 
 test-pref(dom.animations-api.core.enabled,true) == stacking-context-transform-changing-target-in-delay.html stacking-context-animation-changing-target-ref.html
 test-pref(dom.animations-api.core.enabled,true) == stacking-context-transform-changing-effect.html stacking-context-animation-ref.html
 test-pref(dom.animations-api.core.enabled,true) == stacking-context-transform-changing-display-property.html stacking-context-animation-ref.html
 test-pref(dom.animations-api.core.enabled,true) == stacking-context-transform-losing-css-animation-in-delay.html stacking-context-animation-ref.html
 test-pref(dom.animations-api.core.enabled,true) == style-updates-on-iteration-composition-changed-from-accumulate-to-replace.html style-updates-for-iteration-composite-ref.html
-test-pref(dom.animations-api.core.enabled,true) fails-if(stylo) == style-updates-on-iteration-composition-changed-from-replace-to-accumulate.html style-updates-for-iteration-composite-ref.html
-test-pref(dom.animations-api.core.enabled,true) fails-if(stylo) == style-updates-on-current-iteration-changed.html style-updates-for-iteration-composite-ref.html
+test-pref(dom.animations-api.core.enabled,true) == style-updates-on-iteration-composition-changed-from-replace-to-accumulate.html style-updates-for-iteration-composite-ref.html
+test-pref(dom.animations-api.core.enabled,true) == style-updates-on-current-iteration-changed.html style-updates-for-iteration-composite-ref.html
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -311,17 +311,19 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
 // Compose animation value for a given property.
 // |base_values| is nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>.
 // We use void* to avoid exposing nsRefPtrHashtable in FFI.
 SERVO_BINDING_FUNC(Servo_AnimationCompose, void,
                    RawServoAnimationValueMapBorrowedMut animation_values,
                    void* base_values,
                    nsCSSPropertyID property,
                    RawGeckoAnimationPropertySegmentBorrowed animation_segment,
-                   RawGeckoComputedTimingBorrowed computed_timing)
+                   RawGeckoAnimationPropertySegmentBorrowed last_segment,
+                   RawGeckoComputedTimingBorrowed computed_timing,
+                   mozilla::dom::IterationCompositeOperation iteration_composite)
 
 // presentation attributes
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_PropertyIsSet, bool,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetIdentStringValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsCSSPropertyID property,
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -38,16 +38,19 @@ namespace mozilla {
   enum class CSSPseudoElementType : uint8_t;
   struct Keyframe;
   enum Side;
   struct StyleTransition;
   namespace css {
     struct URLValue;
     struct ImageValue;
   };
+  namespace dom {
+    enum class IterationCompositeOperation : uint8_t;
+  };
   enum class UpdateAnimationsTasks : uint8_t;
   struct LangGroupFontPrefs;
   class ServoStyleSheet;
   class ServoElementSnapshotTable;
 }
 using mozilla::FontFamilyList;
 using mozilla::FontFamilyType;
 using mozilla::ServoElementSnapshot;
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -43,16 +43,17 @@ args = [
 [structs]
 headers = [
     "nsStyleStruct.h",
     "mozilla/ServoPropPrefList.h",
     "mozilla/StyleAnimationValue.h",
     "gfxFontConstants.h",
     "nsThemeConstants.h",
     "mozilla/dom/AnimationEffectReadOnlyBinding.h",
+    "mozilla/dom/KeyframeEffectBinding.h",
     "mozilla/AnimationPropertySegment.h",
     "mozilla/ComputedTiming.h",
     "mozilla/ComputedTimingFunction.h",
     "mozilla/Keyframe.h",
     "mozilla/ServoElementSnapshot.h",
     "mozilla/ServoElementSnapshotTable.h",
     "mozilla/dom/Element.h",
     "mozilla/dom/NameSpaceConstants.h",
@@ -113,16 +114,17 @@ whitelist-types = [
     "mozilla::ComputedTiming",
     "mozilla::ComputedTimingFunction",
     "mozilla::ComputedTimingFunction::BeforeFlag",
     "mozilla::ServoStyleSheet",
     "mozilla::ServoElementSnapshot.*",
     "mozilla::CSSPseudoClassType",
     "mozilla::css::SheetParsingMode",
     "mozilla::css::URLMatchingFunction",
+    "mozilla::dom::IterationCompositeOperation",
     "mozilla::HalfCorner",
     "mozilla::PropertyStyleAnimationValuePair",
     "mozilla::TraversalRestyleBehavior",
     "mozilla::TraversalRootBehavior",
     "mozilla::StyleShapeRadius",
     "mozilla::StyleGrid.*",
     "mozilla::UpdateAnimationsTasks",
     "mozilla::LookAndFeel",
@@ -337,16 +339,17 @@ structs-types = [
     "CSSPseudoElementType",
     "TraversalRestyleBehavior",
     "TraversalRootBehavior",
     "ComputedTimingFunction_BeforeFlag",
     "FontFamilyList",
     "FontFamilyType",
     "FontSizePrefs",
     "GeckoFontMetrics",
+    "IterationCompositeOperation",
     "Keyframe",
     "ServoBundledURI",
     "ServoElementSnapshot",
     "ServoElementSnapshotTable",
     "SheetParsingMode",
     "StyleBasicShape",
     "StyleBasicShapeType",
     "StyleShapeSource",
--- a/servo/components/style/gecko/generated/bindings.rs
+++ b/servo/components/style/gecko/generated/bindings.rs
@@ -31,16 +31,17 @@ use gecko_bindings::structs::CSSPseudoCl
 use gecko_bindings::structs::CSSPseudoElementType;
 use gecko_bindings::structs::TraversalRestyleBehavior;
 use gecko_bindings::structs::TraversalRootBehavior;
 use gecko_bindings::structs::ComputedTimingFunction_BeforeFlag;
 use gecko_bindings::structs::FontFamilyList;
 use gecko_bindings::structs::FontFamilyType;
 use gecko_bindings::structs::FontSizePrefs;
 use gecko_bindings::structs::GeckoFontMetrics;
+use gecko_bindings::structs::IterationCompositeOperation;
 use gecko_bindings::structs::Keyframe;
 use gecko_bindings::structs::ServoBundledURI;
 use gecko_bindings::structs::ServoElementSnapshot;
 use gecko_bindings::structs::ServoElementSnapshotTable;
 use gecko_bindings::structs::SheetParsingMode;
 use gecko_bindings::structs::StyleBasicShape;
 use gecko_bindings::structs::StyleBasicShapeType;
 use gecko_bindings::structs::StyleShapeSource;
@@ -2256,18 +2257,22 @@ extern "C" {
 }
 extern "C" {
     pub fn Servo_AnimationCompose(animation_values:
                                       RawServoAnimationValueMapBorrowedMut,
                                   base_values: *mut ::std::os::raw::c_void,
                                   property: nsCSSPropertyID,
                                   animation_segment:
                                       RawGeckoAnimationPropertySegmentBorrowed,
+                                  last_segment:
+                                      RawGeckoAnimationPropertySegmentBorrowed,
                                   computed_timing:
-                                      RawGeckoComputedTimingBorrowed);
+                                      RawGeckoComputedTimingBorrowed,
+                                  iteration_composite:
+                                      IterationCompositeOperation);
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_PropertyIsSet(declarations:
                                                     RawServoDeclarationBlockBorrowed,
                                                 property: nsCSSPropertyID)
      -> bool;
 }
 extern "C" {
--- a/servo/components/style/gecko/generated/structs_debug.rs
+++ b/servo/components/style/gecko/generated/structs_debug.rs
@@ -3336,16 +3336,23 @@ pub mod root {
                             mGlobalObject ) ));
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct Optional {
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
+            pub struct NonNull<T> {
+                pub ptr: *mut T,
+                pub inited: bool,
+                pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
             pub struct Sequence {
             }
             #[repr(C)]
             #[derive(Debug, Copy)]
             pub struct ParentObject {
                 pub mObject: *const root::nsISupports,
                 pub mWrapperCache: *const root::nsWrapperCache,
                 pub mUseXBLScope: bool,
@@ -5054,16 +5061,103 @@ pub mod root {
             pub enum CompositeOperation {
                 Replace = 0,
                 Add = 1,
                 Accumulate = 2,
                 EndGuard_ = 3,
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
+            pub struct CSSPseudoElement {
+                _unused: [u8; 0],
+            }
+            #[repr(u8)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum IterationCompositeOperation {
+                Replace = 0,
+                Accumulate = 1,
+                EndGuard_ = 2,
+            }
+            #[repr(C)]
+            #[derive(Debug)]
+            pub struct ElementOrCSSPseudoElement {
+                pub mType: root::mozilla::dom::ElementOrCSSPseudoElement_Type,
+                pub mValue: root::mozilla::dom::ElementOrCSSPseudoElement_Value,
+            }
+            #[repr(u32)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum ElementOrCSSPseudoElement_Type {
+                eUninitialized = 0,
+                eElement = 1,
+                eCSSPseudoElement = 2,
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy)]
+            pub struct ElementOrCSSPseudoElement_Value {
+                pub mElement: root::__BindgenUnionField<root::mozilla::dom::UnionMember>,
+                pub mCSSPseudoElement: root::__BindgenUnionField<root::mozilla::dom::UnionMember>,
+                pub bindgen_union_field: [u64; 2usize],
+            }
+            #[test]
+            fn bindgen_test_layout_ElementOrCSSPseudoElement_Value() {
+                assert_eq!(::std::mem::size_of::<ElementOrCSSPseudoElement_Value>()
+                           , 16usize , concat ! (
+                           "Size of: " , stringify ! (
+                           ElementOrCSSPseudoElement_Value ) ));
+                assert_eq! (::std::mem::align_of::<ElementOrCSSPseudoElement_Value>()
+                            , 8usize , concat ! (
+                            "Alignment of " , stringify ! (
+                            ElementOrCSSPseudoElement_Value ) ));
+                assert_eq! (unsafe {
+                            & (
+                            * ( 0 as * const ElementOrCSSPseudoElement_Value )
+                            ) . mElement as * const _ as usize } , 0usize ,
+                            concat ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement_Value ) , "::" ,
+                            stringify ! ( mElement ) ));
+                assert_eq! (unsafe {
+                            & (
+                            * ( 0 as * const ElementOrCSSPseudoElement_Value )
+                            ) . mCSSPseudoElement as * const _ as usize } ,
+                            0usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement_Value ) , "::" ,
+                            stringify ! ( mCSSPseudoElement ) ));
+            }
+            impl Clone for ElementOrCSSPseudoElement_Value {
+                fn clone(&self) -> Self { *self }
+            }
+            #[test]
+            fn bindgen_test_layout_ElementOrCSSPseudoElement() {
+                assert_eq!(::std::mem::size_of::<ElementOrCSSPseudoElement>()
+                           , 24usize , concat ! (
+                           "Size of: " , stringify ! (
+                           ElementOrCSSPseudoElement ) ));
+                assert_eq! (::std::mem::align_of::<ElementOrCSSPseudoElement>()
+                            , 8usize , concat ! (
+                            "Alignment of " , stringify ! (
+                            ElementOrCSSPseudoElement ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const ElementOrCSSPseudoElement ) )
+                            . mType as * const _ as usize } , 0usize , concat
+                            ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement ) , "::" , stringify ! (
+                            mType ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const ElementOrCSSPseudoElement ) )
+                            . mValue as * const _ as usize } , 8usize , concat
+                            ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement ) , "::" , stringify ! (
+                            mValue ) ));
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
             pub struct CustomElementData {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct FragmentOrElement {
                 pub _base: root::nsIContent,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
@@ -5114,17 +5208,17 @@ pub mod root {
                 pub mStyle: root::nsCOMPtr<root::nsICSSDeclaration>,
                 /**
      * The .dataset attribute.
      * @see nsGenericHTMLElement::GetDataset
      */
                 pub mDataset: *mut root::nsDOMStringMap,
                 /**
      * SMIL Overridde style rules (for SMIL animation of CSS properties)
-     * @see nsIContent::GetSMILOverrideStyle
+     * @see Element::GetSMILOverrideStyle
      */
                 pub mSMILOverrideStyle: root::nsCOMPtr<root::nsICSSDeclaration>,
                 /**
      * Holds any SMIL override style declaration for this element.
      */
                 pub mSMILOverrideStyleDeclaration: root::RefPtr<root::mozilla::DeclarationBlock>,
                 /**
      * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
@@ -5677,21 +5771,16 @@ pub mod root {
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct AnimationFilter {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
-            pub struct ElementOrCSSPseudoElement {
-                _unused: [u8; 0],
-            }
-            #[repr(C)]
-            #[derive(Debug, Copy, Clone)]
             pub struct UnrestrictedDoubleOrKeyframeAnimationOptions {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct DestinationInsertionPointList {
                 pub _base: root::nsINodeList,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
@@ -34187,26 +34276,26 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
         assert_eq!(::std::mem::align_of::<root::nsCharTraits>() , 1usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_210592_instantiation_99() {
+    fn __bindgen_test_layout__bindgen_ty_id_211464_instantiation_99() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_210628_instantiation_100() {
+    fn __bindgen_test_layout__bindgen_ty_id_211500_instantiation_100() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
@@ -36760,378 +36849,426 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::UniquePtr<root::nsCSSValuePairList> ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::UniquePtr<root::nsCSSValuePairList>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::UniquePtr<root::nsCSSValuePairList> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Maybe_instantiation_332() {
+    fn __bindgen_test_layout_NonNull_instantiation_332() {
+        assert_eq!(::std::mem::size_of::<root::mozilla::dom::NonNull<root::mozilla::dom::Element>>()
+                   , 16usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::Element> )
+                   ));
+        assert_eq!(::std::mem::align_of::<root::mozilla::dom::NonNull<root::mozilla::dom::Element>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::Element> )
+                   ));
+    }
+    #[test]
+    fn __bindgen_test_layout_NonNull_instantiation_333() {
+        assert_eq!(::std::mem::size_of::<root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>>()
+                   , 16usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>
+                   ) ));
+        assert_eq!(::std::mem::align_of::<root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>
+                   ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_Handle_instantiation_334() {
+        assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
+                   , 8usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::JS::Handle<*mut root::JSObject> ) ));
+        assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::JS::Handle<*mut root::JSObject> ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_MutableHandle_instantiation_335() {
+        assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
+                   , 8usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::JS::MutableHandle<root::JS::Value> ) ));
+        assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::JS::MutableHandle<root::JS::Value> ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_Maybe_instantiation_336() {
         assert_eq!(::std::mem::size_of::<[u64; 18usize]>() , 144usize , concat
                    ! (
                    "Size of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 18usize]>() , 8usize , concat
                    ! (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Maybe_instantiation_333() {
+    fn __bindgen_test_layout_Maybe_instantiation_337() {
         assert_eq!(::std::mem::size_of::<[u64; 18usize]>() , 144usize , concat
                    ! (
                    "Size of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 18usize]>() , 8usize , concat
                    ! (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_BaseTimeDuration_instantiation_334() {
+    fn __bindgen_test_layout_BaseTimeDuration_instantiation_338() {
         assert_eq!(::std::mem::size_of::<root::mozilla::BaseTimeDuration>() ,
                    8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::BaseTimeDuration ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::BaseTimeDuration>() ,
                    8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::BaseTimeDuration ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_335() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_339() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_336() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_340() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_337() {
+    fn __bindgen_test_layout_nsTArray_instantiation_341() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_338() {
+    fn __bindgen_test_layout_nsTArray_instantiation_342() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsCOMPtr_instantiation_339() {
+    fn __bindgen_test_layout_nsCOMPtr_instantiation_343() {
         assert_eq!(::std::mem::size_of::<root::nsCOMPtr<root::nsIContent>>() ,
                    8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsCOMPtr<root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::nsCOMPtr<root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCOMPtr<root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_340() {
+    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_344() {
         assert_eq!(::std::mem::size_of::<root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_341() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_345() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_342() {
+    fn __bindgen_test_layout_nsTArray_instantiation_346() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_343() {
+    fn __bindgen_test_layout_Handle_instantiation_347() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_344() {
+    fn __bindgen_test_layout_Handle_instantiation_348() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_RefPtr_instantiation_345() {
+    fn __bindgen_test_layout_RefPtr_instantiation_349() {
         assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMRect>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::RefPtr<root::mozilla::dom::DOMRect> ) ));
         assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMRect>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::RefPtr<root::mozilla::dom::DOMRect> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_346() {
+    fn __bindgen_test_layout_Handle_instantiation_350() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_MutableHandle_instantiation_347() {
+    fn __bindgen_test_layout_MutableHandle_instantiation_351() {
         assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Sequence_instantiation_348() {
+    fn __bindgen_test_layout_Sequence_instantiation_352() {
         assert_eq!(::std::mem::size_of::<u64>() , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u64 )
                    ));
         assert_eq!(::std::mem::align_of::<u64>() , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u64 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_349() {
+    fn __bindgen_test_layout_Handle_instantiation_353() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Sequence_instantiation_350() {
+    fn __bindgen_test_layout_Sequence_instantiation_354() {
         assert_eq!(::std::mem::size_of::<u64>() , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u64 )
                    ));
         assert_eq!(::std::mem::align_of::<u64>() , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u64 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Sequence_instantiation_351() {
+    fn __bindgen_test_layout_Sequence_instantiation_355() {
         assert_eq!(::std::mem::size_of::<u64>() , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u64 )
                    ));
         assert_eq!(::std::mem::align_of::<u64>() , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u64 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_352() {
+    fn __bindgen_test_layout_Handle_instantiation_356() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_353() {
+    fn __bindgen_test_layout_Handle_instantiation_357() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_MutableHandle_instantiation_354() {
+    fn __bindgen_test_layout_MutableHandle_instantiation_358() {
         assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_355() {
+    fn __bindgen_test_layout_Handle_instantiation_359() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_MutableHandle_instantiation_356() {
+    fn __bindgen_test_layout_MutableHandle_instantiation_360() {
         assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_357() {
+    fn __bindgen_test_layout_Handle_instantiation_361() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_358() {
+    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_362() {
         assert_eq!(::std::mem::size_of::<root::nsRefPtrHashKey<root::mozilla::dom::Element>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::Element> ) ));
         assert_eq!(::std::mem::align_of::<root::nsRefPtrHashKey<root::mozilla::dom::Element>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::Element> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsClassHashtable_instantiation_359() {
+    fn __bindgen_test_layout_nsClassHashtable_instantiation_363() {
         assert_eq!(::std::mem::size_of::<[u64; 6usize]>() , 48usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u64; 6usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 6usize]>() , 8usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 6usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_360() {
+    fn __bindgen_test_layout_Handle_instantiation_364() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_361() {
+    fn __bindgen_test_layout_nsTArray_instantiation_365() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<::nsstring::nsStringRepr>>() ,
                    8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<::nsstring::nsStringRepr> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<::nsstring::nsStringRepr>>() ,
                    8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<::nsstring::nsStringRepr> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_362() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_366() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::CSSValue>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::CSSValue> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::CSSValue>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::CSSValue> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_363() {
+    fn __bindgen_test_layout_Handle_instantiation_367() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_364() {
+    fn __bindgen_test_layout_nsTArray_instantiation_368() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::mozilla::css::DocumentRule>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::mozilla::css::DocumentRule> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::mozilla::css::DocumentRule>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::mozilla::css::DocumentRule> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsAutoPtr_instantiation_365() {
+    fn __bindgen_test_layout_nsAutoPtr_instantiation_369() {
         assert_eq!(::std::mem::size_of::<root::nsAutoPtr<root::nsMediaQuery>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsAutoPtr<root::nsMediaQuery> ) ));
         assert_eq!(::std::mem::align_of::<root::nsAutoPtr<root::nsMediaQuery>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsAutoPtr<root::nsMediaQuery> ) ));
--- a/servo/components/style/gecko/generated/structs_release.rs
+++ b/servo/components/style/gecko/generated/structs_release.rs
@@ -3242,16 +3242,22 @@ pub mod root {
                             mGlobalObject ) ));
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct Optional {
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
+            pub struct NonNull<T> {
+                pub ptr: *mut T,
+                pub _phantom_0: ::std::marker::PhantomData<::std::cell::UnsafeCell<T>>,
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
             pub struct Sequence {
             }
             #[repr(C)]
             #[derive(Debug, Copy)]
             pub struct ParentObject {
                 pub mObject: *const root::nsISupports,
                 pub mWrapperCache: *const root::nsWrapperCache,
                 pub mUseXBLScope: bool,
@@ -4942,16 +4948,103 @@ pub mod root {
             pub enum CompositeOperation {
                 Replace = 0,
                 Add = 1,
                 Accumulate = 2,
                 EndGuard_ = 3,
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
+            pub struct CSSPseudoElement {
+                _unused: [u8; 0],
+            }
+            #[repr(u8)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum IterationCompositeOperation {
+                Replace = 0,
+                Accumulate = 1,
+                EndGuard_ = 2,
+            }
+            #[repr(C)]
+            #[derive(Debug)]
+            pub struct ElementOrCSSPseudoElement {
+                pub mType: root::mozilla::dom::ElementOrCSSPseudoElement_Type,
+                pub mValue: root::mozilla::dom::ElementOrCSSPseudoElement_Value,
+            }
+            #[repr(u32)]
+            #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
+            pub enum ElementOrCSSPseudoElement_Type {
+                eUninitialized = 0,
+                eElement = 1,
+                eCSSPseudoElement = 2,
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy)]
+            pub struct ElementOrCSSPseudoElement_Value {
+                pub mElement: root::__BindgenUnionField<root::mozilla::dom::UnionMember>,
+                pub mCSSPseudoElement: root::__BindgenUnionField<root::mozilla::dom::UnionMember>,
+                pub bindgen_union_field: u64,
+            }
+            #[test]
+            fn bindgen_test_layout_ElementOrCSSPseudoElement_Value() {
+                assert_eq!(::std::mem::size_of::<ElementOrCSSPseudoElement_Value>()
+                           , 8usize , concat ! (
+                           "Size of: " , stringify ! (
+                           ElementOrCSSPseudoElement_Value ) ));
+                assert_eq! (::std::mem::align_of::<ElementOrCSSPseudoElement_Value>()
+                            , 8usize , concat ! (
+                            "Alignment of " , stringify ! (
+                            ElementOrCSSPseudoElement_Value ) ));
+                assert_eq! (unsafe {
+                            & (
+                            * ( 0 as * const ElementOrCSSPseudoElement_Value )
+                            ) . mElement as * const _ as usize } , 0usize ,
+                            concat ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement_Value ) , "::" ,
+                            stringify ! ( mElement ) ));
+                assert_eq! (unsafe {
+                            & (
+                            * ( 0 as * const ElementOrCSSPseudoElement_Value )
+                            ) . mCSSPseudoElement as * const _ as usize } ,
+                            0usize , concat ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement_Value ) , "::" ,
+                            stringify ! ( mCSSPseudoElement ) ));
+            }
+            impl Clone for ElementOrCSSPseudoElement_Value {
+                fn clone(&self) -> Self { *self }
+            }
+            #[test]
+            fn bindgen_test_layout_ElementOrCSSPseudoElement() {
+                assert_eq!(::std::mem::size_of::<ElementOrCSSPseudoElement>()
+                           , 16usize , concat ! (
+                           "Size of: " , stringify ! (
+                           ElementOrCSSPseudoElement ) ));
+                assert_eq! (::std::mem::align_of::<ElementOrCSSPseudoElement>()
+                            , 8usize , concat ! (
+                            "Alignment of " , stringify ! (
+                            ElementOrCSSPseudoElement ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const ElementOrCSSPseudoElement ) )
+                            . mType as * const _ as usize } , 0usize , concat
+                            ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement ) , "::" , stringify ! (
+                            mType ) ));
+                assert_eq! (unsafe {
+                            & ( * ( 0 as * const ElementOrCSSPseudoElement ) )
+                            . mValue as * const _ as usize } , 8usize , concat
+                            ! (
+                            "Alignment of field: " , stringify ! (
+                            ElementOrCSSPseudoElement ) , "::" , stringify ! (
+                            mValue ) ));
+            }
+            #[repr(C)]
+            #[derive(Debug, Copy, Clone)]
             pub struct CustomElementData {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct FragmentOrElement {
                 pub _base: root::nsIContent,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
@@ -5001,17 +5094,17 @@ pub mod root {
                 pub mStyle: root::nsCOMPtr,
                 /**
      * The .dataset attribute.
      * @see nsGenericHTMLElement::GetDataset
      */
                 pub mDataset: *mut root::nsDOMStringMap,
                 /**
      * SMIL Overridde style rules (for SMIL animation of CSS properties)
-     * @see nsIContent::GetSMILOverrideStyle
+     * @see Element::GetSMILOverrideStyle
      */
                 pub mSMILOverrideStyle: root::nsCOMPtr,
                 /**
      * Holds any SMIL override style declaration for this element.
      */
                 pub mSMILOverrideStyleDeclaration: root::RefPtr<root::mozilla::DeclarationBlock>,
                 /**
      * An object implementing nsIDOMMozNamedAttrMap for this content (attributes)
@@ -5555,21 +5648,16 @@ pub mod root {
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
             pub struct AnimationFilter {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug, Copy, Clone)]
-            pub struct ElementOrCSSPseudoElement {
-                _unused: [u8; 0],
-            }
-            #[repr(C)]
-            #[derive(Debug, Copy, Clone)]
             pub struct UnrestrictedDoubleOrKeyframeAnimationOptions {
                 _unused: [u8; 0],
             }
             #[repr(C)]
             #[derive(Debug)]
             pub struct DestinationInsertionPointList {
                 pub _base: root::nsINodeList,
                 pub mRefCnt: root::nsCycleCollectingAutoRefCnt,
@@ -33677,26 +33765,26 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
         assert_eq!(::std::mem::align_of::<root::nsCharTraits>() , 1usize ,
                    concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCharTraits ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_206919_instantiation_97() {
+    fn __bindgen_test_layout__bindgen_ty_id_207791_instantiation_97() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout__bindgen_ty_id_206955_instantiation_98() {
+    fn __bindgen_test_layout__bindgen_ty_id_207827_instantiation_98() {
         assert_eq!(::std::mem::size_of::<u8>() , 1usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u8 )
                    ));
         assert_eq!(::std::mem::align_of::<u8>() , 1usize , concat ! (
                    "Alignment of template specialization: " , stringify ! ( u8
                    ) ));
     }
     #[test]
@@ -36239,378 +36327,426 @@ pub mod root {
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::UniquePtr<root::nsCSSValuePairList> ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::UniquePtr<root::nsCSSValuePairList>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::UniquePtr<root::nsCSSValuePairList> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Maybe_instantiation_329() {
+    fn __bindgen_test_layout_NonNull_instantiation_329() {
+        assert_eq!(::std::mem::size_of::<root::mozilla::dom::NonNull<root::mozilla::dom::Element>>()
+                   , 8usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::Element> )
+                   ));
+        assert_eq!(::std::mem::align_of::<root::mozilla::dom::NonNull<root::mozilla::dom::Element>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::Element> )
+                   ));
+    }
+    #[test]
+    fn __bindgen_test_layout_NonNull_instantiation_330() {
+        assert_eq!(::std::mem::size_of::<root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>>()
+                   , 8usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>
+                   ) ));
+        assert_eq!(::std::mem::align_of::<root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::mozilla::dom::NonNull<root::mozilla::dom::CSSPseudoElement>
+                   ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_Handle_instantiation_331() {
+        assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
+                   , 8usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::JS::Handle<*mut root::JSObject> ) ));
+        assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::JS::Handle<*mut root::JSObject> ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_MutableHandle_instantiation_332() {
+        assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
+                   , 8usize , concat ! (
+                   "Size of template specialization: " , stringify ! (
+                   root::JS::MutableHandle<root::JS::Value> ) ));
+        assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
+                   , 8usize , concat ! (
+                   "Alignment of template specialization: " , stringify ! (
+                   root::JS::MutableHandle<root::JS::Value> ) ));
+    }
+    #[test]
+    fn __bindgen_test_layout_Maybe_instantiation_333() {
         assert_eq!(::std::mem::size_of::<[u64; 18usize]>() , 144usize , concat
                    ! (
                    "Size of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 18usize]>() , 8usize , concat
                    ! (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Maybe_instantiation_330() {
+    fn __bindgen_test_layout_Maybe_instantiation_334() {
         assert_eq!(::std::mem::size_of::<[u64; 18usize]>() , 144usize , concat
                    ! (
                    "Size of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 18usize]>() , 8usize , concat
                    ! (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 18usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_BaseTimeDuration_instantiation_331() {
+    fn __bindgen_test_layout_BaseTimeDuration_instantiation_335() {
         assert_eq!(::std::mem::size_of::<root::mozilla::BaseTimeDuration>() ,
                    8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::mozilla::BaseTimeDuration ) ));
         assert_eq!(::std::mem::align_of::<root::mozilla::BaseTimeDuration>() ,
                    8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::mozilla::BaseTimeDuration ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_332() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_336() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_333() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_337() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_334() {
+    fn __bindgen_test_layout_nsTArray_instantiation_338() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_335() {
+    fn __bindgen_test_layout_nsTArray_instantiation_339() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::nsIContent>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::nsIContent> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsCOMPtr_instantiation_336() {
+    fn __bindgen_test_layout_nsCOMPtr_instantiation_340() {
         assert_eq!(::std::mem::size_of::<root::nsCOMPtr>() , 8usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    root::nsCOMPtr ) ));
         assert_eq!(::std::mem::align_of::<root::nsCOMPtr>() , 8usize , concat
                    ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsCOMPtr ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_337() {
+    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_341() {
         assert_eq!(::std::mem::size_of::<root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::DOMIntersectionObserver>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_338() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_342() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::NodeInfo>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::NodeInfo> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_339() {
+    fn __bindgen_test_layout_nsTArray_instantiation_343() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>
                    ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<root::mozilla::DisplayItemClip_RoundedRect>
                    ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_340() {
+    fn __bindgen_test_layout_Handle_instantiation_344() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_341() {
+    fn __bindgen_test_layout_Handle_instantiation_345() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_RefPtr_instantiation_342() {
+    fn __bindgen_test_layout_RefPtr_instantiation_346() {
         assert_eq!(::std::mem::size_of::<root::RefPtr<root::mozilla::dom::DOMRect>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::RefPtr<root::mozilla::dom::DOMRect> ) ));
         assert_eq!(::std::mem::align_of::<root::RefPtr<root::mozilla::dom::DOMRect>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::RefPtr<root::mozilla::dom::DOMRect> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_343() {
+    fn __bindgen_test_layout_Handle_instantiation_347() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_MutableHandle_instantiation_344() {
+    fn __bindgen_test_layout_MutableHandle_instantiation_348() {
         assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Sequence_instantiation_345() {
+    fn __bindgen_test_layout_Sequence_instantiation_349() {
         assert_eq!(::std::mem::size_of::<u64>() , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u64 )
                    ));
         assert_eq!(::std::mem::align_of::<u64>() , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u64 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_346() {
+    fn __bindgen_test_layout_Handle_instantiation_350() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Sequence_instantiation_347() {
+    fn __bindgen_test_layout_Sequence_instantiation_351() {
         assert_eq!(::std::mem::size_of::<u64>() , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u64 )
                    ));
         assert_eq!(::std::mem::align_of::<u64>() , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u64 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Sequence_instantiation_348() {
+    fn __bindgen_test_layout_Sequence_instantiation_352() {
         assert_eq!(::std::mem::size_of::<u64>() , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! ( u64 )
                    ));
         assert_eq!(::std::mem::align_of::<u64>() , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    u64 ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_349() {
+    fn __bindgen_test_layout_Handle_instantiation_353() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_350() {
+    fn __bindgen_test_layout_Handle_instantiation_354() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_MutableHandle_instantiation_351() {
+    fn __bindgen_test_layout_MutableHandle_instantiation_355() {
         assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_352() {
+    fn __bindgen_test_layout_Handle_instantiation_356() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_MutableHandle_instantiation_353() {
+    fn __bindgen_test_layout_MutableHandle_instantiation_357() {
         assert_eq!(::std::mem::size_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::MutableHandle<root::JS::Value>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::MutableHandle<root::JS::Value> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_354() {
+    fn __bindgen_test_layout_Handle_instantiation_358() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_355() {
+    fn __bindgen_test_layout_nsRefPtrHashKey_instantiation_359() {
         assert_eq!(::std::mem::size_of::<root::nsRefPtrHashKey<root::mozilla::dom::Element>>()
                    , 16usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::Element> ) ));
         assert_eq!(::std::mem::align_of::<root::nsRefPtrHashKey<root::mozilla::dom::Element>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsRefPtrHashKey<root::mozilla::dom::Element> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsClassHashtable_instantiation_356() {
+    fn __bindgen_test_layout_nsClassHashtable_instantiation_360() {
         assert_eq!(::std::mem::size_of::<[u64; 5usize]>() , 40usize , concat !
                    (
                    "Size of template specialization: " , stringify ! (
                    [u64; 5usize] ) ));
         assert_eq!(::std::mem::align_of::<[u64; 5usize]>() , 8usize , concat !
                    (
                    "Alignment of template specialization: " , stringify ! (
                    [u64; 5usize] ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_357() {
+    fn __bindgen_test_layout_Handle_instantiation_361() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_358() {
+    fn __bindgen_test_layout_nsTArray_instantiation_362() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<::nsstring::nsStringRepr>>() ,
                    8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<::nsstring::nsStringRepr> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<::nsstring::nsStringRepr>>() ,
                    8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<::nsstring::nsStringRepr> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_already_AddRefed_instantiation_359() {
+    fn __bindgen_test_layout_already_AddRefed_instantiation_363() {
         assert_eq!(::std::mem::size_of::<root::already_AddRefed<root::mozilla::dom::CSSValue>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::CSSValue> ) ));
         assert_eq!(::std::mem::align_of::<root::already_AddRefed<root::mozilla::dom::CSSValue>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::already_AddRefed<root::mozilla::dom::CSSValue> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_Handle_instantiation_360() {
+    fn __bindgen_test_layout_Handle_instantiation_364() {
         assert_eq!(::std::mem::size_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
         assert_eq!(::std::mem::align_of::<root::JS::Handle<*mut root::JSObject>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::JS::Handle<*mut root::JSObject> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsTArray_instantiation_361() {
+    fn __bindgen_test_layout_nsTArray_instantiation_365() {
         assert_eq!(::std::mem::size_of::<root::nsTArray<*mut root::mozilla::css::DocumentRule>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::mozilla::css::DocumentRule> ) ));
         assert_eq!(::std::mem::align_of::<root::nsTArray<*mut root::mozilla::css::DocumentRule>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsTArray<*mut root::mozilla::css::DocumentRule> ) ));
     }
     #[test]
-    fn __bindgen_test_layout_nsAutoPtr_instantiation_362() {
+    fn __bindgen_test_layout_nsAutoPtr_instantiation_366() {
         assert_eq!(::std::mem::size_of::<root::nsAutoPtr<root::nsMediaQuery>>()
                    , 8usize , concat ! (
                    "Size of template specialization: " , stringify ! (
                    root::nsAutoPtr<root::nsMediaQuery> ) ));
         assert_eq!(::std::mem::align_of::<root::nsAutoPtr<root::nsMediaQuery>>()
                    , 8usize , concat ! (
                    "Alignment of template specialization: " , stringify ! (
                    root::nsAutoPtr<root::nsMediaQuery> ) ));
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -63,16 +63,17 @@ use style::gecko_bindings::bindings::nsT
 use style::gecko_bindings::bindings::nsTimingFunctionBorrowed;
 use style::gecko_bindings::bindings::nsTimingFunctionBorrowedMut;
 use style::gecko_bindings::structs;
 use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation};
 use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
 use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
 use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
 use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint};
+use style::gecko_bindings::structs::IterationCompositeOperation;
 use style::gecko_bindings::structs::Loader;
 use style::gecko_bindings::structs::RawGeckoPresContextOwned;
 use style::gecko_bindings::structs::ServoElementSnapshotTable;
 use style::gecko_bindings::structs::URLExtraData;
 use style::gecko_bindings::structs::nsCSSValueSharedList;
 use style::gecko_bindings::structs::nsCompatibility;
 use style::gecko_bindings::structs::nsresult;
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI, HasBoxFFI};
@@ -327,30 +328,38 @@ pub extern "C" fn Servo_AnimationValueMa
     value_map.insert(property.into(), value.clone());
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_AnimationCompose(raw_value_map: RawServoAnimationValueMapBorrowedMut,
                                          base_values: *mut ::std::os::raw::c_void,
                                          css_property: nsCSSPropertyID,
                                          segment: RawGeckoAnimationPropertySegmentBorrowed,
-                                         computed_timing: RawGeckoComputedTimingBorrowed)
+                                         last_segment: RawGeckoAnimationPropertySegmentBorrowed,
+                                         computed_timing: RawGeckoComputedTimingBorrowed,
+                                         iteration_composite: IterationCompositeOperation)
 {
     use style::gecko_bindings::bindings::Gecko_AnimationGetBaseStyle;
     use style::gecko_bindings::bindings::Gecko_GetPositionInSegment;
     use style::gecko_bindings::bindings::Gecko_GetProgressFromComputedTiming;
     use style::properties::animated_properties::AnimationValueMap;
 
     let property: TransitionProperty = css_property.into();
     let value_map = AnimationValueMap::from_ffi_mut(raw_value_map);
 
+    // We will need an underlying value if either of the endpoints is null...
     let need_underlying_value = segment.mFromValue.mServo.mRawPtr.is_null() ||
                                 segment.mToValue.mServo.mRawPtr.is_null() ||
+                                // ... or if they have a non-replace composite mode ...
                                 segment.mFromComposite != CompositeOperation::Replace ||
-                                segment.mToComposite != CompositeOperation::Replace;
+                                segment.mToComposite != CompositeOperation::Replace ||
+                                // ... or if we accumulate onto the last value and it is null.
+                                (iteration_composite == IterationCompositeOperation::Accumulate &&
+                                 computed_timing.mCurrentIteration > 0 &&
+                                 last_segment.mToValue.mServo.mRawPtr.is_null());
 
     // If either of the segment endpoints are null, get the underlying value to
     // use from the current value in the values map (set by a lower-priority
     // effect), or, if there is no current value, look up the cached base value
     // for this property.
     let underlying_value = if need_underlying_value {
         let previous_composed_value = value_map.get(&property).cloned();
         previous_composed_value.or_else(|| {
@@ -405,27 +414,60 @@ pub extern "C" fn Servo_AnimationCompose
             },
             None => {
                 debug_assert!(need_underlying_value,
                               "Should have detected we need an underlying value");
                 underlying_value.clone()
             },
         }
     };
-    let composited_from_value = composite_endpoint(keyframe_from_value, segment.mFromComposite);
-    let composited_to_value = composite_endpoint(keyframe_to_value, segment.mToComposite);
+    let mut composited_from_value = composite_endpoint(keyframe_from_value, segment.mFromComposite);
+    let mut composited_to_value = composite_endpoint(keyframe_to_value, segment.mToComposite);
 
     debug_assert!(keyframe_from_value.is_some() || composited_from_value.is_some(),
                   "Should have a suitable from value to use");
     debug_assert!(keyframe_to_value.is_some() || composited_to_value.is_some(),
                   "Should have a suitable to value to use");
 
+    // Apply iteration composite behavior.
+    if iteration_composite == IterationCompositeOperation::Accumulate &&
+       computed_timing.mCurrentIteration > 0 {
+        let raw_last_value;
+        let last_value = if !last_segment.mToValue.mServo.mRawPtr.is_null() {
+            raw_last_value = unsafe { &*last_segment.mToValue.mServo.mRawPtr };
+            AnimationValue::as_arc(&raw_last_value).as_ref()
+        } else {
+            debug_assert!(need_underlying_value,
+                          "Should have detected we need an underlying value");
+            underlying_value.as_ref().unwrap()
+        };
+
+        // As with composite_endpoint, a return value of None means, "Use keyframe_value as-is."
+        let apply_iteration_composite = |keyframe_value: Option<&Arc<AnimationValue>>,
+                                         composited_value: Option<AnimationValue>|
+                                        -> Option<AnimationValue> {
+            let count = computed_timing.mCurrentIteration;
+            match composited_value {
+                Some(endpoint) => last_value.accumulate(&endpoint, count)
+                                            .ok()
+                                            .or(Some(endpoint)),
+                None => last_value.accumulate(keyframe_value.unwrap(), count)
+                                  .ok(),
+            }
+        };
+
+        composited_from_value = apply_iteration_composite(keyframe_from_value,
+                                                          composited_from_value);
+        composited_to_value = apply_iteration_composite(keyframe_to_value,
+                                                        composited_to_value);
+    }
+
     // Use the composited value if there is one, otherwise, use the original keyframe value.
-    let from_value = composited_from_value.as_ref().unwrap_or(keyframe_from_value.unwrap());
-    let to_value   = composited_to_value.as_ref().unwrap_or(keyframe_to_value.unwrap());
+    let from_value = composited_from_value.as_ref().unwrap_or_else(|| keyframe_from_value.unwrap());
+    let to_value   = composited_to_value.as_ref().unwrap_or_else(|| keyframe_to_value.unwrap());
 
     let progress = unsafe { Gecko_GetProgressFromComputedTiming(computed_timing) };
     if segment.mToKey == segment.mFromKey {
         if progress < 0. {
             value_map.insert(property, from_value.clone());
         } else {
             value_map.insert(property, to_value.clone());
         }