Back out bug 851892 for Windows build bustage on CLOSED TREE
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 13 Jan 2017 11:47:22 -0500
changeset 374353 e8b32aaa2eec84c15f44cfd677142a0047481152
parent 374352 7a82c1099a05d9dfa32a3d04ab79db22b29a31ba
child 374354 83b1e97f352a360bd39442635ca0a963cc415ce0
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs851892
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Back out bug 851892 for Windows build bustage on CLOSED TREE
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoID.h
dom/base/nsDocument.cpp
dom/base/nsWrapperCache.h
dom/bindings/Bindings.conf
dom/interfaces/css/nsIDOMCSSCounterStyleRule.idl
dom/interfaces/css/nsIDOMCSSFontFaceRule.idl
dom/interfaces/css/nsIDOMCSSFontFeatureValuesRule.idl
dom/interfaces/css/nsIDOMCSSGroupingRule.idl
dom/interfaces/css/nsIDOMCSSImportRule.idl
dom/interfaces/css/nsIDOMCSSKeyframeRule.idl
dom/interfaces/css/nsIDOMCSSKeyframesRule.idl
dom/interfaces/css/nsIDOMCSSMediaRule.idl
dom/interfaces/css/nsIDOMCSSPageRule.idl
dom/interfaces/css/nsIDOMCSSStyleRule.idl
dom/interfaces/css/nsIDOMCSSUnknownRule.idl
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/CSSConditionRule.webidl
dom/webidl/CSSCounterStyleRule.webidl
dom/webidl/CSSFontFaceRule.webidl
dom/webidl/CSSFontFeatureValuesRule.webidl
dom/webidl/CSSGroupingRule.webidl
dom/webidl/CSSImportRule.webidl
dom/webidl/CSSKeyframeRule.webidl
dom/webidl/CSSKeyframesRule.webidl
dom/webidl/CSSMediaRule.webidl
dom/webidl/CSSMozDocumentRule.webidl
dom/webidl/CSSNamespaceRule.webidl
dom/webidl/CSSPageRule.webidl
dom/webidl/CSSRule.webidl
dom/webidl/CSSStyleDeclaration.webidl
dom/webidl/CSSStyleRule.webidl
dom/webidl/CSSStyleSheet.webidl
dom/webidl/CSSSupportsRule.webidl
dom/webidl/LegacyQueryInterface.webidl
dom/webidl/StyleRuleChangeEvent.webidl
dom/webidl/StyleSheet.webidl
dom/webidl/moz.build
js/xpconnect/tests/chrome/test_weakmaps.xul
js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html
js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html
layout/inspector/inCSSValueSearch.cpp
layout/inspector/inDOMUtils.cpp
layout/style/BindingStyleRule.cpp
layout/style/BindingStyleRule.h
layout/style/CSSRuleList.h
layout/style/CSSStyleSheet.cpp
layout/style/CSSStyleSheet.h
layout/style/GroupRule.h
layout/style/ImportRule.h
layout/style/NameSpaceRule.h
layout/style/Rule.h
layout/style/ServoCSSRuleList.cpp
layout/style/ServoCSSRuleList.h
layout/style/ServoStyleRule.cpp
layout/style/ServoStyleRule.h
layout/style/ServoStyleSheet.cpp
layout/style/ServoStyleSheet.h
layout/style/StyleRule.cpp
layout/style/StyleRule.h
layout/style/StyleSheet.h
layout/style/moz.build
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsICSSStyleRuleDOMWrapper.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -64,20 +64,31 @@
 #include "nsIDOMXULButtonElement.h"
 #include "nsIDOMXULCheckboxElement.h"
 #include "nsIDOMXULPopupElement.h"
 
 // Event related includes
 #include "nsIDOMEventTarget.h"
 
 // CSS related includes
+#include "nsCSSRules.h"
 #include "nsIDOMCSSRule.h"
 #include "nsMemory.h"
 
 // includes needed for the prototype chain interfaces
+#include "nsIDOMCSSKeyframeRule.h"
+#include "nsIDOMCSSKeyframesRule.h"
+#include "nsIDOMCSSImportRule.h"
+#include "nsIDOMCSSMediaRule.h"
+#include "nsIDOMCSSFontFaceRule.h"
+#include "nsIDOMCSSMozDocumentRule.h"
+#include "nsIDOMCSSSupportsRule.h"
+#include "nsIDOMCSSCounterStyleRule.h"
+#include "nsIDOMCSSPageRule.h"
+#include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIControllers.h"
 #ifdef MOZ_XUL
 #include "nsITreeSelection.h"
 #include "nsITreeContentView.h"
 #include "nsITreeView.h"
 #include "nsIXULTemplateBuilder.h"
 #endif
@@ -173,16 +184,26 @@ static nsDOMClassInfoData sClassInfoData
                            nsIXPCScriptable::WANT_RESOLVE |
                            nsIXPCScriptable::WANT_HASINSTANCE |
                            nsIXPCScriptable::WANT_CALL |
                            nsIXPCScriptable::WANT_CONSTRUCT |
                            nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
 
   // Misc Core related classes
 
+  // CSS classes
+  NS_DEFINE_CLASSINFO_DATA(CSSStyleRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSImportRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSMediaRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSNameSpaceRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   // XUL classes
 #ifdef MOZ_XUL
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCommandDispatcher, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControllers, nsNonDOMObjectSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
 #ifdef MOZ_XUL
@@ -195,32 +216,55 @@ static nsDOMClassInfoData sClassInfoData
 #ifdef MOZ_XUL
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTemplateBuilder, nsDOMGenericSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULTreeBuilder, nsDOMGenericSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
+  NS_DEFINE_CLASSINFO_DATA(CSSMozDocumentRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(CSSSupportsRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentFrameMessageManager,
                                        nsMessageManagerSH<nsEventTargetSH>,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS |
                                        nsIXPCScriptable::WANT_ENUMERATE |
                                        nsIXPCScriptable::IS_GLOBAL_OBJECT)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ContentProcessMessageManager,
                                        nsMessageManagerSH<nsDOMGenericSH>,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS |
                                        nsIXPCScriptable::WANT_ENUMERATE |
                                        nsIXPCScriptable::IS_GLOBAL_OBJECT)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageBroadcaster, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_ONLY_CLASSINFO_DATA(ChromeMessageSender, nsDOMGenericSH,
                                        DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
 
+  NS_DEFINE_CLASSINFO_DATA(CSSKeyframeRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(CSSKeyframesRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(CSSCounterStyleRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(CSSPageRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
+  NS_DEFINE_CLASSINFO_DATA(CSSFontFeatureValuesRule, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
+
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULLabeledControlElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULButtonElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCheckboxElement, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -463,16 +507,32 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMPrototype, nsIDOMDOMConstructor)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(DOMConstructor, nsIDOMDOMConstructor)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMConstructor)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(CSSStyleRule, nsIDOMCSSStyleRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSStyleRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSImportRule, nsIDOMCSSImportRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSImportRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSMediaRule, nsIDOMCSSMediaRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSMediaRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(CSSNameSpaceRule, nsIDOMCSSRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSRule)
+  DOM_CLASSINFO_MAP_END
+
 #ifdef MOZ_XUL
   DOM_CLASSINFO_MAP_BEGIN(XULCommandDispatcher, nsIDOMXULCommandDispatcher)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULCommandDispatcher)
   DOM_CLASSINFO_MAP_END
 #endif
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControllers, nsIControllers)
     DOM_CLASSINFO_MAP_ENTRY(nsIControllers)
@@ -496,16 +556,28 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN(XULTreeBuilder, nsIXULTreeBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTreeBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsIXULTemplateBuilder)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeView)
   DOM_CLASSINFO_MAP_END
 #endif
 
+  DOM_CLASSINFO_MAP_BEGIN(CSSMozDocumentRule, nsIDOMCSSMozDocumentRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSSupportsRule, nsIDOMCSSSupportsRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSSupportsRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ContentFrameMessageManager, nsISupports)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
     DOM_CLASSINFO_MAP_ENTRY(nsISyncMessageSender)
     DOM_CLASSINFO_MAP_ENTRY(nsIContentFrameMessageManager)
   DOM_CLASSINFO_MAP_END
 
@@ -526,16 +598,36 @@ nsDOMClassInfo::Init()
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ChromeMessageSender, nsISupports)
     DOM_CLASSINFO_MAP_ENTRY(nsIFrameScriptLoader)
     DOM_CLASSINFO_MAP_ENTRY(nsIProcessScriptLoader)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageListenerManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIMessageSender)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(CSSKeyframeRule, nsIDOMCSSKeyframeRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSKeyframeRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSKeyframesRule, nsIDOMCSSKeyframesRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSKeyframesRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSCounterStyleRule, nsIDOMCSSCounterStyleRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSCounterStyleRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSPageRule, nsIDOMCSSPageRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSPageRule)
+  DOM_CLASSINFO_MAP_END
+
+  DOM_CLASSINFO_MAP_BEGIN(CSSFontFeatureValuesRule, nsIDOMCSSFontFeatureValuesRule)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControlElement, nsIDOMXULControlElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULControlElement)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULLabeledControlElement, nsIDOMXULLabeledControlElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULLabeledControlElement)
   DOM_CLASSINFO_MAP_END
 
--- a/dom/base/nsDOMClassInfoID.h
+++ b/dom/base/nsDOMClassInfoID.h
@@ -14,36 +14,58 @@
 
 #include "nsIXPCScriptable.h"
 
 enum nsDOMClassInfoID
 {
   eDOMClassInfo_DOMPrototype_id,
   eDOMClassInfo_DOMConstructor_id,
 
+  // CSS classes
+  eDOMClassInfo_CSSStyleRule_id,
+  eDOMClassInfo_CSSImportRule_id,
+  eDOMClassInfo_CSSMediaRule_id,
+  eDOMClassInfo_CSSNameSpaceRule_id,
+
   // XUL classes
 #ifdef MOZ_XUL
   eDOMClassInfo_XULCommandDispatcher_id,
 #endif
   eDOMClassInfo_XULControllers_id,
 #ifdef MOZ_XUL
   eDOMClassInfo_TreeSelection_id,
   eDOMClassInfo_TreeContentView_id,
 #endif
 
 #ifdef MOZ_XUL
   eDOMClassInfo_XULTemplateBuilder_id,
   eDOMClassInfo_XULTreeBuilder_id,
 #endif
 
+  eDOMClassInfo_CSSMozDocumentRule_id,
+  eDOMClassInfo_CSSSupportsRule_id,
+
+  // @font-face in CSS
+  eDOMClassInfo_CSSFontFaceRule_id,
+
   eDOMClassInfo_ContentFrameMessageManager_id,
   eDOMClassInfo_ContentProcessMessageManager_id,
   eDOMClassInfo_ChromeMessageBroadcaster_id,
   eDOMClassInfo_ChromeMessageSender_id,
 
+  eDOMClassInfo_CSSKeyframeRule_id,
+  eDOMClassInfo_CSSKeyframesRule_id,
+
+  // @counter-style in CSS
+  eDOMClassInfo_CSSCounterStyleRule_id,
+
+  eDOMClassInfo_CSSPageRule_id,
+
+  eDOMClassInfo_CSSFontFeatureValuesRule_id,
+
   eDOMClassInfo_XULControlElement_id,
   eDOMClassInfo_XULLabeledControlElement_id,
   eDOMClassInfo_XULButtonElement_id,
   eDOMClassInfo_XULCheckboxElement_id,
   eDOMClassInfo_XULPopupElement_id,
 
   // This one better be the last one in this list
   eDOMClassInfoIDCount
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -5175,45 +5175,47 @@ nsDocument::StyleRuleChanged(StyleSheet*
                              css::Rule* aStyleRule)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleChanged, (aSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
                                "StyleRuleChanged",
                                mRule,
-                               aStyleRule);
+                               aStyleRule ? aStyleRule->GetDOMRule() : nullptr);
   }
 }
 
 void
 nsDocument::StyleRuleAdded(StyleSheet* aSheet,
                            css::Rule* aStyleRule)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleAdded, (aSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
                                "StyleRuleAdded",
                                mRule,
-                               aStyleRule);
+                               aStyleRule ? aStyleRule->GetDOMRule()
+                                          : nullptr);
   }
 }
 
 void
 nsDocument::StyleRuleRemoved(StyleSheet* aSheet,
                              css::Rule* aStyleRule)
 {
   NS_DOCUMENT_NOTIFY_OBSERVERS(StyleRuleRemoved, (aSheet));
 
   if (StyleSheetChangeEventsEnabled()) {
     DO_STYLESHEET_NOTIFICATION(StyleRuleChangeEvent,
                                "StyleRuleRemoved",
                                mRule,
-                               aStyleRule);
+                               aStyleRule ? aStyleRule->GetDOMRule()
+                                          : nullptr);
   }
 }
 
 #undef DO_STYLESHEET_NOTIFICATION
 
 already_AddRefed<AnonymousContent>
 nsIDocument::InsertAnonymousContent(Element& aElement, ErrorResult& aRv)
 {
--- a/dom/base/nsWrapperCache.h
+++ b/dom/base/nsWrapperCache.h
@@ -267,19 +267,16 @@ protected:
     if (mWrapper) {
       // Set the pointer to a value that will cause a crash if it is
       // dereferenced.
       mWrapper = reinterpret_cast<JSObject*>(1);
     }
   }
 
 private:
-  // Friend declarations for things that need to be able to call
-  // SetIsNotDOMBinding().  The goal is to get rid of all of these, and
-  // SetIsNotDOMBinding() too.
   friend class mozilla::dom::TabChildGlobal;
   friend class mozilla::dom::ProcessGlobal;
   friend class SandboxPrivate;
   friend class nsInProcessTabChildGlobal;
   friend class nsWindowRoot;
   void SetIsNotDOMBinding()
   {
     MOZ_ASSERT(!mWrapper && !(GetWrapperFlags() & ~WRAPPER_IS_NOT_DOM_BINDING),
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -191,106 +191,33 @@ DOMInterfaces = {
 'CSS': {
     'concrete': False,
 },
 
 'CSS2Properties': {
     'nativeType': 'nsDOMCSSDeclaration'
 },
 
-'CSSConditionRule': {
-    'concrete': False,
-    'nativeType': 'mozilla::css::ConditionRule',
-    'headerFile': 'mozilla/css/GroupRule.h',
-},
-
-'CSSCounterStyleRule': {
-    'nativeType': 'nsCSSCounterStyleRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
-'CSSFontFaceRule': {
-    'nativeType': 'nsCSSFontFaceRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
-'CSSFontFeatureValuesRule': {
-    'nativeType': 'nsCSSFontFeatureValuesRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
-'CSSGroupingRule': {
-    'concrete': False,
-    'nativeType': 'mozilla::css::GroupRule',
-},
-
-'CSSImportRule': {
-    'nativeType': 'mozilla::css::ImportRule',
-},
-
-'CSSKeyframeRule': {
-    'nativeType': 'nsCSSKeyframeRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
-'CSSKeyframesRule': {
-    'nativeType': 'nsCSSKeyframesRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
 'CSSLexer': {
     'wrapperCache': False
 },
 
-'CSSMediaRule': {
-    'nativeType': 'mozilla::css::MediaRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
-'CSSMozDocumentRule': {
-    'nativeType': 'mozilla::css::DocumentRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
-'CSSNamespaceRule': {
-    'nativeType': 'mozilla::css::NameSpaceRule',
-},
-
-'CSSPageRule': {
-    'nativeType': 'nsCSSPageRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
 'CSSPrimitiveValue': {
     'nativeType': 'nsROCSSPrimitiveValue',
 },
 
-'CSSRule': {
-    'concrete': False,
-    'nativeType': 'mozilla::css::Rule'
-},
-
 'CSSStyleDeclaration': {
     'nativeType': 'nsICSSDeclaration'
 },
 
-'CSSStyleRule': {
-    'nativeType': 'mozilla::BindingStyleRule',
-},
-
 'CSSStyleSheet': {
     'nativeType': 'mozilla::StyleSheet',
     'binaryNames': { 'ownerRule': 'DOMOwnerRule' },
 },
 
-'CSSSupportsRule': {
-    'nativeType': 'mozilla::CSSSupportsRule',
-    'headerFile': 'nsCSSRules.h',
-},
-
 'CSSValue': {
     'concrete': False
 },
 
 'CSSValueList': {
     'nativeType': 'nsDOMCSSValueList'
 },
 
@@ -1728,16 +1655,17 @@ def addExternalIface(iface, nativeType=N
         domInterface['nativeType'] = nativeType
     if not headerFile is None:
         domInterface['headerFile'] = headerFile
     domInterface['notflattened'] = notflattened
     DOMInterfaces[iface] = domInterface
 
 addExternalIface('ApplicationCache', nativeType='nsIDOMOfflineResourceList')
 addExternalIface('Counter')
+addExternalIface('CSSRule')
 addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
 addExternalIface('MozControllers', nativeType='nsIControllers')
 addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
 addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True)
--- a/dom/interfaces/css/nsIDOMCSSCounterStyleRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSCounterStyleRule.idl
@@ -1,18 +1,18 @@
 /* -*- Mode: IDL; tab-width: 2; 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 "nsISupports.idl"
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(9b5e48ce-d84c-4e31-aff5-34e9f4141313)]
-interface nsIDOMCSSCounterStyleRule : nsISupports
+interface nsIDOMCSSCounterStyleRule : nsIDOMCSSRule
 {
   attribute DOMString name;
   attribute DOMString system;
   attribute DOMString symbols;
   attribute DOMString additiveSymbols;
   attribute DOMString negative;
   attribute DOMString prefix;
   attribute DOMString suffix;
--- a/dom/interfaces/css/nsIDOMCSSFontFaceRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSFontFaceRule.idl
@@ -1,14 +1,12 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMCSSStyleDeclaration;
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(db971017-fe0c-4529-972c-8217f2fee217)]
-interface nsIDOMCSSFontFaceRule : nsISupports
+interface nsIDOMCSSFontFaceRule : nsIDOMCSSRule
 {
   readonly attribute nsIDOMCSSStyleDeclaration  style;
 };
--- a/dom/interfaces/css/nsIDOMCSSFontFeatureValuesRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSFontFeatureValuesRule.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(a343d27f-1da6-4fc3-9355-d4ca434f958e)]
-interface nsIDOMCSSFontFeatureValuesRule : nsISupports
+interface nsIDOMCSSFontFeatureValuesRule : nsIDOMCSSRule
 {
   attribute DOMString fontFamily;
                       // raises(DOMException) on setting
 
   attribute DOMString valueText;
                       // raises(DOMException) on setting
 };
--- a/dom/interfaces/css/nsIDOMCSSGroupingRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSGroupingRule.idl
@@ -1,22 +1,20 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMCSSRuleList;
+#include "nsIDOMCSSRule.idl"
 
 /**
  * Interface for at-rules that have child rules in the CSS OM.
  */
 [scriptable, uuid(a0e3324a-f911-4baf-9591-5322c76cbb0d)]
-interface nsIDOMCSSGroupingRule : nsISupports
+interface nsIDOMCSSGroupingRule : nsIDOMCSSRule
 {
   readonly attribute nsIDOMCSSRuleList cssRules;
 
   unsigned long      insertRule(in DOMString rule,
                                 in unsigned long index)
                                         raises(DOMException);
   void               deleteRule(in unsigned long index)
                                         raises(DOMException);
--- a/dom/interfaces/css/nsIDOMCSSImportRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSImportRule.idl
@@ -1,17 +1,14 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMMediaList;
-interface nsIDOMCSSStyleSheet;
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(d3b2b914-01ef-4663-beda-a6475a26f491)]
-interface nsIDOMCSSImportRule : nsISupports
+interface nsIDOMCSSImportRule : nsIDOMCSSRule
 {
   readonly attribute DOMString           href;
   readonly attribute nsIDOMMediaList     media;
   readonly attribute nsIDOMCSSStyleSheet styleSheet;
 };
--- a/dom/interfaces/css/nsIDOMCSSKeyframeRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSKeyframeRule.idl
@@ -1,15 +1,13 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMCSSStyleDeclaration;
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(a281a8b4-eaa2-49a8-8b97-acc2814a57c9)]
-interface nsIDOMCSSKeyframeRule : nsISupports
+interface nsIDOMCSSKeyframeRule : nsIDOMCSSRule
 {
            attribute DOMString                 keyText;
   readonly attribute nsIDOMCSSStyleDeclaration style;
 };
--- a/dom/interfaces/css/nsIDOMCSSKeyframesRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSKeyframesRule.idl
@@ -1,20 +1,17 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMCSSRuleList;
-interface nsIDOMCSSKeyframeRule;
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(400f4b70-ad0a-4047-aba4-ee8019f6b907)]
-interface nsIDOMCSSKeyframesRule : nsISupports
+interface nsIDOMCSSKeyframesRule : nsIDOMCSSRule
 {
            attribute DOMString         name;
   readonly attribute nsIDOMCSSRuleList cssRules;
 
   void                     appendRule(in DOMString rule);
   void                     deleteRule(in DOMString key);
   nsIDOMCSSKeyframeRule    findRule(in DOMString key);
 };
--- a/dom/interfaces/css/nsIDOMCSSMediaRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSMediaRule.idl
@@ -1,17 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsIDOMCSSConditionRule.idl"
 
-interface nsIDOMMediaList;
-
 /**
  * Interface for @media rules in the CSS OM.
  */
 [scriptable, uuid(6cf9c5b2-fa0f-43c0-aa50-ef85b4756e3a)]
 interface nsIDOMCSSMediaRule : nsIDOMCSSConditionRule
 {
   readonly attribute nsIDOMMediaList   media;
 };
--- a/dom/interfaces/css/nsIDOMCSSPageRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSPageRule.idl
@@ -1,17 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMCSSStyleDeclaration;
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(c119072b-7d2f-4aeb-a90d-e2d6b606c32a)]
-interface nsIDOMCSSPageRule : nsISupports
+interface nsIDOMCSSPageRule : nsIDOMCSSRule
 {
            //attribute DOMString        selectorText;
                                         // raises(DOMException) on setting
 
   readonly attribute nsIDOMCSSStyleDeclaration  style;
 };
--- a/dom/interfaces/css/nsIDOMCSSStyleRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSStyleRule.idl
@@ -1,17 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMCSSStyleDeclaration;
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(b5e9af48-a7c2-4f88-aae3-58307af4b5a5)]
-interface nsIDOMCSSStyleRule : nsISupports
+interface nsIDOMCSSStyleRule : nsIDOMCSSRule
 {
            attribute DOMString        selectorText;
                                         // raises(DOMException) on setting
 
   readonly attribute nsIDOMCSSStyleDeclaration  style;
 };
--- a/dom/interfaces/css/nsIDOMCSSUnknownRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSUnknownRule.idl
@@ -1,11 +1,11 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsISupports.idl"
+#include "nsIDOMCSSRule.idl"
 
 [scriptable, uuid(98f4c27b-fb35-4355-8fd9-546c4697d71a)]
-interface nsIDOMCSSUnknownRule : nsISupports
+interface nsIDOMCSSUnknownRule : nsIDOMCSSRule
 {
 };
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -244,17 +244,17 @@ var interfaceNamesInGlobalScope =
     "CSSKeyframeRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CSSKeyframesRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CSSMediaRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CSSMozDocumentRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    "CSSNamespaceRule",
+    "CSSNameSpaceRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CSSPageRule",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CSSPrimitiveValue",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "CSSPseudoElement", release: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CSSRule",
deleted file mode 100644
--- a/dom/webidl/CSSConditionRule.webidl
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-conditional/#the-cssconditionrule-interface
- */
-
-// https://drafts.csswg.org/css-conditional/#the-cssconditionrule-interface
-interface CSSConditionRule : CSSGroupingRule {
-  [SetterThrows]
-  attribute DOMString conditionText;
-};
deleted file mode 100644
--- a/dom/webidl/CSSCounterStyleRule.webidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-counter-styles-3/#the-csscounterstylerule-interface
- */
-
-// https://drafts.csswg.org/css-counter-styles-3/#the-csscounterstylerule-interface
-interface CSSCounterStyleRule : CSSRule {
-  attribute DOMString name;
-  attribute DOMString system;
-  attribute DOMString symbols;
-  attribute DOMString additiveSymbols;
-  attribute DOMString negative;
-  attribute DOMString prefix;
-  attribute DOMString suffix;
-  attribute DOMString range;
-  attribute DOMString pad;
-  attribute DOMString speakAs;
-  attribute DOMString fallback;
-};
deleted file mode 100644
--- a/dom/webidl/CSSFontFaceRule.webidl
+++ /dev/null
@@ -1,15 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-fonts/#om-fontface
- */
-
-// https://drafts.csswg.org/css-fonts/#om-fontface
-// But we implement a very old draft, apparently....
-// See bug 1058408 for implementing the current spec.
-interface CSSFontFaceRule : CSSRule {
-  [SameObject] readonly attribute CSSStyleDeclaration style;
-};
deleted file mode 100644
--- a/dom/webidl/CSSFontFeatureValuesRule.webidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-fonts/#om-fontfeaturevalues
- */
-
-// https://drafts.csswg.org/css-fonts/#om-fontfeaturevalues
-// but we don't implement anything remotely resembling the spec.
-interface CSSFontFeatureValuesRule : CSSRule {
-  [SetterThrows]
-  attribute DOMString fontFamily;
-
-  // Not yet implemented
-  //  readonly attribute CSSFontFeatureValuesMap annotation;
-  //  readonly attribute CSSFontFeatureValuesMap ornaments;
-  //  readonly attribute CSSFontFeatureValuesMap stylistic;
-  //  readonly attribute CSSFontFeatureValuesMap swash;
-  //  readonly attribute CSSFontFeatureValuesMap characterVariant;
-  //  readonly attribute CSSFontFeatureValuesMap styleset;
-};
-
-partial interface CSSFontFeatureValuesRule {
-  // Gecko addition?
-  [SetterThrows]
-  attribute DOMString valueText;
-};
deleted file mode 100644
--- a/dom/webidl/CSSGroupingRule.webidl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#cssgroupingrule
- */
-
-// https://drafts.csswg.org/cssom/#cssgroupingrule
-interface CSSGroupingRule : CSSRule {
-  [SameObject] readonly attribute CSSRuleList cssRules;
-  [Throws]
-  unsigned long insertRule(DOMString rule, unsigned long index);
-  [Throws]
-  void deleteRule(unsigned long index);
-};
deleted file mode 100644
--- a/dom/webidl/CSSImportRule.webidl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#cssimportrule
- */
-
-// https://drafts.csswg.org/cssom/#cssimportrule
-interface CSSImportRule : CSSRule {
-  readonly attribute DOMString href;
-  [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
-  // Per spec, the .styleSheet is never null, but in our implementation it can
-  // be.  See <https://bugzilla.mozilla.org/show_bug.cgi?id=1326509>.
-  [SameObject] readonly attribute CSSStyleSheet? styleSheet;
-};
deleted file mode 100644
--- a/dom/webidl/CSSKeyframeRule.webidl
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-animations/#interface-csskeyframerule
- */
-
-// https://drafts.csswg.org/css-animations/#interface-csskeyframerule
-interface CSSKeyframeRule : CSSRule {
-           attribute DOMString           keyText;
-  readonly attribute CSSStyleDeclaration style;
-};
deleted file mode 100644
--- a/dom/webidl/CSSKeyframesRule.webidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-animations/#interface-csskeyframesrule
- */
-
-// https://drafts.csswg.org/css-animations/#interface-csskeyframesrule
-interface CSSKeyframesRule : CSSRule {
-           attribute DOMString   name;
-  readonly attribute CSSRuleList cssRules;
-
-  void            appendRule(DOMString rule);
-  void            deleteRule(DOMString select);
-  CSSKeyframeRule? findRule(DOMString select);
-};
deleted file mode 100644
--- a/dom/webidl/CSSMediaRule.webidl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#the-cssmediarule-interface
- * https://drafts.csswg.org/css-conditional/#the-cssmediarule-interface
- */
-
-// https://drafts.csswg.org/cssom/#the-cssmediarule-interface and
-// https://drafts.csswg.org/css-conditional/#the-cssmediarule-interface
-// except they disagree with each other.  We're taking the inheritance from
-// css-conditional and the PutForwards behavior from cssom.
-interface CSSMediaRule : CSSConditionRule {
-  [SameObject, PutForwards=mediaText] readonly attribute MediaList media;
-};
deleted file mode 100644
--- a/dom/webidl/CSSMozDocumentRule.webidl
+++ /dev/null
@@ -1,10 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-// This is a non-standard interface for @-moz-document rules
-interface CSSMozDocumentRule : CSSConditionRule {
-  // XXX Add access to the URL list.
-};
deleted file mode 100644
--- a/dom/webidl/CSSNamespaceRule.webidl
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#cssnamespacerule
- */
-
-// https://drafts.csswg.org/cssom/#cssnamespacerule
-interface CSSNamespaceRule : CSSRule {
-  // Not implemented yet.  <See
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=1326514>.
-  //  readonly attribute DOMString namespaceURI;
-  //  readonly attribute DOMString prefix;
-};
deleted file mode 100644
--- a/dom/webidl/CSSPageRule.webidl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#the-csspagerule-interface
- */
-
-// https://drafts.csswg.org/cssom/#the-csspagerule-interface
-// Per spec, this should inherit from CSSGroupingRule, but we don't
-// implement this yet.
-interface CSSPageRule : CSSRule {
-  // selectorText not implemented yet
-  //         attribute DOMString selectorText;
-  [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
-};
deleted file mode 100644
--- a/dom/webidl/CSSRule.webidl
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#the-cssrule-interface
- * https://drafts.csswg.org/css-animations/#interface-cssrule
- * https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface
- * https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface
- * https://drafts.csswg.org/css-fonts-3/#om-fontfeaturevalues
- */
-
-// https://drafts.csswg.org/cssom/#the-cssrule-interface
-interface CSSRule {
-
-  const unsigned short STYLE_RULE = 1;
-  const unsigned short CHARSET_RULE = 2; // historical
-  const unsigned short IMPORT_RULE = 3;
-  const unsigned short MEDIA_RULE = 4;
-  const unsigned short FONT_FACE_RULE = 5;
-  const unsigned short PAGE_RULE = 6;
-  // FIXME: We don't support MARGIN_RULE yet.
-  // XXXbz Should we expose the constant anyway?
-  // const unsigned short MARGIN_RULE = 9;
-  const unsigned short NAMESPACE_RULE = 10;
-  readonly attribute unsigned short type;
-  attribute DOMString cssText;
-  readonly attribute CSSRule? parentRule;
-  readonly attribute CSSStyleSheet? parentStyleSheet;
-};
-
-// https://drafts.csswg.org/css-animations/#interface-cssrule
-partial interface CSSRule {
-    const unsigned short KEYFRAMES_RULE = 7;
-    const unsigned short KEYFRAME_RULE = 8;
-};
-
-// https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface
-partial interface CSSRule {
-    const unsigned short COUNTER_STYLE_RULE = 11;
-};
-
-// https://drafts.csswg.org/css-conditional-3/#extentions-to-cssrule-interface
-partial interface CSSRule {
-    const unsigned short SUPPORTS_RULE = 12;
-};
-
-// https://drafts.csswg.org/css-fonts-3/#om-fontfeaturevalues
-partial interface CSSRule {
-  const unsigned short FONT_FEATURE_VALUES_RULE = 14;
-};
--- a/dom/webidl/CSSStyleDeclaration.webidl
+++ b/dom/webidl/CSSStyleDeclaration.webidl
@@ -2,16 +2,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * http://dev.w3.org/csswg/cssom/
  */
 
+interface CSSRule;
+
 interface CSSStyleDeclaration {
   [SetterThrows]
   attribute DOMString cssText;
 
   readonly attribute unsigned long length;
   getter DOMString item(unsigned long index);
 
   [Throws]
deleted file mode 100644
--- a/dom/webidl/CSSStyleRule.webidl
+++ /dev/null
@@ -1,14 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/cssom/#the-cssstylerule-interface
- */
-
-// https://drafts.csswg.org/cssom/#the-cssstylerule-interface
-interface CSSStyleRule : CSSRule {
-  attribute DOMString selectorText;
-  [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style;
-};
--- a/dom/webidl/CSSStyleSheet.webidl
+++ b/dom/webidl/CSSStyleSheet.webidl
@@ -2,16 +2,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * http://dev.w3.org/csswg/cssom/
  */
 
+interface CSSRule;
+
 enum CSSStyleSheetParsingMode {
   "author",
   "user",
   "agent"
 };
 
 interface CSSStyleSheet : StyleSheet {
   [Pure]
deleted file mode 100644
--- a/dom/webidl/CSSSupportsRule.webidl
+++ /dev/null
@@ -1,12 +0,0 @@
-/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * The origin of this IDL file is
- * https://drafts.csswg.org/css-conditional/#the-csssupportsrule-interface
- */
-
-// https://drafts.csswg.org/css-conditional/#the-csssupportsrule-interface
-interface CSSSupportsRule : CSSConditionRule {
-};
--- a/dom/webidl/LegacyQueryInterface.webidl
+++ b/dom/webidl/LegacyQueryInterface.webidl
@@ -19,20 +19,18 @@ interface LegacyQueryInterface {
 };
 
 Attr implements LegacyQueryInterface;
 BarProp implements LegacyQueryInterface;
 BoxObject implements LegacyQueryInterface;
 CaretPosition implements LegacyQueryInterface;
 Comment implements LegacyQueryInterface;
 Crypto implements LegacyQueryInterface;
-CSSMozDocumentRule implements LegacyQueryInterface;
 CSSPrimitiveValue implements LegacyQueryInterface;
 CSSStyleDeclaration implements LegacyQueryInterface;
-CSSStyleRule implements LegacyQueryInterface;
 CSSValueList implements LegacyQueryInterface;
 DOMImplementation implements LegacyQueryInterface;
 DOMParser implements LegacyQueryInterface;
 DOMStringMap implements LegacyQueryInterface;
 DOMTokenList implements LegacyQueryInterface;
 Document implements LegacyQueryInterface;
 DocumentFragment implements LegacyQueryInterface;
 DocumentType implements LegacyQueryInterface;
--- a/dom/webidl/StyleRuleChangeEvent.webidl
+++ b/dom/webidl/StyleRuleChangeEvent.webidl
@@ -1,13 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  */
+interface CSSRule;
+
 [ChromeOnly, Constructor(DOMString type, optional StyleRuleChangeEventInit eventInitDict)]
 interface StyleRuleChangeEvent : Event
 {
   readonly attribute CSSStyleSheet? stylesheet;
   readonly attribute CSSRule? rule;
 };
 
 dictionary StyleRuleChangeEventInit : EventInit
--- a/dom/webidl/StyleSheet.webidl
+++ b/dom/webidl/StyleSheet.webidl
@@ -2,16 +2,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/.
  *
  * The origin of this IDL file is
  * http://dev.w3.org/csswg/cssom/
  */
 
+interface CSSRule;
+
 interface StyleSheet {
   [Constant]
   readonly attribute DOMString type;
   [Constant]
   readonly attribute DOMString? href;
   // Spec says "Node", but it can go null when the node gets a new
   // sheet.  That's also why it's not [Constant]
   [Pure]
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -84,37 +84,22 @@ WEBIDL_FILES = [
     'ConvolverNode.webidl',
     'Coordinates.webidl',
     'CreateOfferRequest.webidl',
     'Crypto.webidl',
     'CSPDictionaries.webidl',
     'CSPReport.webidl',
     'CSS.webidl',
     'CSSAnimation.webidl',
-    'CSSConditionRule.webidl',
-    'CSSCounterStyleRule.webidl',
-    'CSSFontFaceRule.webidl',
-    'CSSFontFeatureValuesRule.webidl',
-    'CSSGroupingRule.webidl',
-    'CSSImportRule.webidl',
-    'CSSKeyframeRule.webidl',
-    'CSSKeyframesRule.webidl',
     'CSSLexer.webidl',
-    'CSSMediaRule.webidl',
-    'CSSMozDocumentRule.webidl',
-    'CSSNamespaceRule.webidl',
-    'CSSPageRule.webidl',
     'CSSPrimitiveValue.webidl',
     'CSSPseudoElement.webidl',
-    'CSSRule.webidl',
     'CSSRuleList.webidl',
     'CSSStyleDeclaration.webidl',
-    'CSSStyleRule.webidl',
     'CSSStyleSheet.webidl',
-    'CSSSupportsRule.webidl',
     'CSSTransition.webidl',
     'CSSValue.webidl',
     'CSSValueList.webidl',
     'CustomElementRegistry.webidl',
     'DataContainerEvent.webidl',
     'DataTransfer.webidl',
     'DataTransferItem.webidl',
     'DataTransferItemList.webidl',
--- a/js/xpconnect/tests/chrome/test_weakmaps.xul
+++ b/js/xpconnect/tests/chrome/test_weakmaps.xul
@@ -209,18 +209,38 @@ https://bugzilla.mozilla.org/show_bug.cg
   let make_live_map = function () {
     let live = get_live_dom();
     wn_live_map.set(live, {});
     ok(wn_live_map.has(get_live_dom()), "Live map should have live DOM node before GC.");
   }
 
   make_live_map();
 
-  // We're out of ideas for unpreservable natives, now that just about
-  // everything is on webidl, so just don't test those.
+  let unpreservable_native_key = function () {
+    // We only allow natives that support wrapper preservation to be used as weak
+    // map keys.  We should be able to try to add unpreservable natives as keys without
+    // crashing (bug 711616), but we should throw an error (bug 761620).
+
+    let dummy_test_map = new WeakMap;
+
+    let rule_fail = false;
+    let got_rule = false;
+    try {
+      var rule = document.styleSheets[0].cssRules[0];
+      got_rule = true;
+      dummy_test_map.set(rule, 1);
+    } catch (e) {
+      rule_fail = true;
+    }
+    ok(got_rule, "Got the CSS rule");
+    ok(rule_fail, "Using a CSS rule as a weak map key should produce an exception because it can't be wrapper preserved.");
+
+  }
+
+  unpreservable_native_key();
 
   /* set up for running precise GC/CC then checking the results */
 
   SimpleTest.waitForExplicitFinish();
 
   Cu.schedulePreciseGC(function () {
     SpecialPowers.DOMWindowUtils.cycleCollect();
     SpecialPowers.DOMWindowUtils.garbageCollect();
--- a/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html
+++ b/js/xpconnect/tests/mochitest/file_crosscompartment_weakmap.html
@@ -1,8 +1,9 @@
 <!DOCTYPE HTML>
 <html>
 <head>
+  <link rel="stylesheet" href="data:text/css,div {}">
   <title>Test Cross-Compartment DOM WeakMaps</title>
 </head>
 <body>
 </body>
 </html>
--- a/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html
+++ b/js/xpconnect/tests/mochitest/test_crosscompartment_weakmap.html
@@ -10,16 +10,24 @@
 <script type="application/javascript">
 
 var my_map = new WeakMap();
 
 function setup() {
   var item = window.frames[0].document.querySelector("body");
 
   my_map.set(item, "success_string");
+
+  var rule_fail = false;
+  try {
+    my_map.set(window.frames[0].document.styleSheets[0].cssRules[0], 1);
+  } catch (e) {
+    rule_fail = true;
+  }
+  ok(rule_fail, "Using rule as a weak map key across compartments should produce an exception because it can't be wrapper preserved.");
 }
 
 function runTest() {
   setup();
   SpecialPowers.forceGC();
   SpecialPowers.forceCC();
   SpecialPowers.forceGC();
   SpecialPowers.forceCC();
--- a/layout/inspector/inCSSValueSearch.cpp
+++ b/layout/inspector/inCSSValueSearch.cpp
@@ -13,17 +13,16 @@
 #include "nsIDOMStyleSheetList.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsIDOMCSSRuleList.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsIDOMCSSImportRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIDOMCSSSupportsRule.h"
-#include "nsIDOMCSSRule.h"
 #include "nsIURI.h"
 #include "nsIDocument.h"
 #include "nsNetUtil.h"
 
 using namespace mozilla;
 
 ///////////////////////////////////////////////////////////////////////////////
 inCSSValueSearch::inCSSValueSearch()
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -248,19 +248,23 @@ inDOMUtils::GetCSSStyleRules(nsIDOMEleme
     ruleNodes.AppendElement(ruleNode);
     ruleNode = ruleNode->GetParent();
   }
 
   nsCOMPtr<nsIMutableArray> rules = nsArray::Create();
   for (nsRuleNode* ruleNode : Reversed(ruleNodes)) {
     RefPtr<Declaration> decl = do_QueryObject(ruleNode->GetRule());
     if (decl) {
-      css::Rule* owningRule = decl->GetOwningRule();
-      if (owningRule) {
-        rules->AppendElement(owningRule, /*weak =*/ false);
+      RefPtr<mozilla::css::StyleRule> styleRule =
+        do_QueryObject(decl->GetOwningRule());
+      if (styleRule) {
+        nsCOMPtr<nsIDOMCSSRule> domRule = styleRule->GetDOMRule();
+        if (domRule) {
+          rules->AppendElement(domRule, /*weak =*/ false);
+        }
       }
     }
   }
 
   rules.forget(_retval);
 
   return NS_OK;
 }
deleted file mode 100644
--- a/layout/style/BindingStyleRule.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "mozilla/BindingStyleRule.h"
-#include "mozilla/dom/CSSStyleRuleBinding.h"
-
-namespace mozilla {
-
-/* virtual */ JSObject*
-BindingStyleRule::WrapObject(JSContext* aCx,
-			     JS::Handle<JSObject*> aGivenProto)
-{
-  return dom::CSSStyleRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/layout/style/BindingStyleRule.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_BindingStyleRule_h__
-#define mozilla_BindingStyleRule_h__
-
-#include "nscore.h"
-#include "nsStringGlue.h"
-#include "mozilla/css/Rule.h"
-
-/**
- * Shared superclass for mozilla::css::StyleRule and mozilla::ServoStyleRule,
- * for use from bindings code.
- */
-
-class nsICSSDeclaration;
-
-namespace mozilla {
-
-class BindingStyleRule : public css::Rule
-{
-protected:
-  BindingStyleRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : css::Rule(aLineNumber, aColumnNumber)
-  {
-  }
-  BindingStyleRule(const BindingStyleRule& aCopy)
-    : css::Rule(aCopy)
-  {
-  }
-  virtual ~BindingStyleRule() {}
-
-public:
-  // This is pure virtual because we have no members, and are an abstract class
-  // to start with.  The fact that we have to have this declaration at all is
-  // kinda dumb.  :(
-  virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
-    const override MOZ_MUST_OVERRIDE = 0;
-
-  // WebIDL API
-  // For GetSelectorText/SetSelectorText, we purposefully use a signature that
-  // matches the nsIDOMCSSStyleRule one for now, so subclasses can just
-  // implement both at once.  The actual implementations must never return
-  // anything other than NS_OK;
-  NS_IMETHOD GetSelectorText(nsAString& aSelectorText) = 0;
-  NS_IMETHOD SetSelectorText(const nsAString& aSelectorText) = 0;
-  virtual nsICSSDeclaration* Style() = 0;
-
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-};
-
-} // namespace mozilla
-
-#endif // mozilla_BindingStyleRule_h__
--- a/layout/style/CSSRuleList.h
+++ b/layout/style/CSSRuleList.h
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_CSSRuleList_h
 #define mozilla_dom_CSSRuleList_h
 
 #include "mozilla/StyleSheetInlines.h"
-#include "mozilla/css/Rule.h"
 #include "nsIDOMCSSRule.h"
 #include "nsIDOMCSSRuleList.h"
 #include "nsWrapperCache.h"
 
 namespace mozilla {
 namespace dom {
 
 // IID for the CSSRuleList interface
@@ -41,23 +40,23 @@ public:
   NS_IMETHOD
   Item(uint32_t aIndex, nsIDOMCSSRule** aReturn) override final
   {
     NS_IF_ADDREF(*aReturn = Item(aIndex));
     return NS_OK;
   }
 
   // WebIDL API
-  css::Rule* Item(uint32_t aIndex)
+  nsIDOMCSSRule* Item(uint32_t aIndex)
   {
     bool unused;
     return IndexedGetter(aIndex, unused);
   }
 
-  virtual css::Rule* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
+  virtual nsIDOMCSSRule* IndexedGetter(uint32_t aIndex, bool& aFound) = 0;
   virtual uint32_t Length() = 0;
 
 protected:
   virtual ~CSSRuleList() {}
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(CSSRuleList, NS_ICSSRULELIST_IID)
 
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -56,17 +56,17 @@ using namespace mozilla::dom;
 //
 class CSSRuleListImpl final : public CSSRuleList
 {
 public:
   explicit CSSRuleListImpl(CSSStyleSheet *aStyleSheet);
 
   virtual CSSStyleSheet* GetParentObject() override;
 
-  virtual css::Rule*
+  virtual nsIDOMCSSRule*
   IndexedGetter(uint32_t aIndex, bool& aFound) override;
   virtual uint32_t
   Length() override;
 
   void DropReference() { mStyleSheet = nullptr; }
 
 protected:
   virtual ~CSSRuleListImpl();
@@ -96,28 +96,28 @@ CSSRuleListImpl::Length()
 {
   if (!mStyleSheet) {
     return 0;
   }
 
   return AssertedCast<uint32_t>(mStyleSheet->StyleRuleCount());
 }
 
-css::Rule*
+nsIDOMCSSRule*    
 CSSRuleListImpl::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   aFound = false;
 
   if (mStyleSheet) {
     // ensure rules have correct parent
     mStyleSheet->EnsureUniqueInner();
     css::Rule* rule = mStyleSheet->GetStyleRuleAt(aIndex);
     if (rule) {
       aFound = true;
-      return rule;
+      return rule->GetDOMRule();
     }
   }
 
   // Per spec: "Return Value ... null if ... not a valid index."
   return nullptr;
 }
 
 namespace mozilla {
@@ -503,17 +503,17 @@ CSSStyleSheet::TraverseInner(nsCycleColl
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "child sheet");
     cb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIDOMCSSStyleSheet*, childSheetSlot->get()));
     childSheetSlot = &(*childSheetSlot)->mNext;
   }
 
   const nsCOMArray<css::Rule>& rules = mInner->mOrderedRules;
   for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mOrderedRules[i]");
-    cb.NoteXPCOMChild(rules[i]);
+    cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule());
   }
 }
 
 // QueryInterface implementation for CSSStyleSheet
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CSSStyleSheet)
   NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, StyleSheet)
   if (aIID.Equals(NS_GET_IID(CSSStyleSheet)))
@@ -870,20 +870,20 @@ CSSStyleSheet::RegisterNamespaceRule(css
     nsresult rv = mInner->CreateNamespaceMap();
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   AddNamespaceRuleToMap(aRule, mInner->mNameSpaceMap);
   return NS_OK;
 }
 
-css::Rule*
+nsIDOMCSSRule*
 CSSStyleSheet::GetDOMOwnerRule() const
 {
-  return mOwnerRule;
+  return mOwnerRule ? mOwnerRule->GetDOMRule() : nullptr;
 }
 
 CSSRuleList*
 CSSStyleSheet::GetCssRulesInternal(ErrorResult& aRv)
 {
   if (!mRuleCollection) {
     mRuleCollection = new CSSRuleListImpl(this);
   }
@@ -1036,16 +1036,21 @@ CSSStyleSheet::DeleteRuleInternal(uint32
 
   NS_ASSERTION(uint32_t(mInner->mOrderedRules.Count()) <= INT32_MAX,
                "Too many style rules!");
 
   // Hold a strong ref to the rule so it doesn't die when we RemoveObjectAt
   RefPtr<css::Rule> rule = mInner->mOrderedRules.ObjectAt(aIndex);
   if (rule) {
     mInner->mOrderedRules.RemoveObjectAt(aIndex);
+    if (mDocument && mDocument->StyleSheetChangeEventsEnabled()) {
+      // Force creation of the DOM rule, so that it can be put on the
+      // StyleRuleRemoved event object.
+      rule->GetDOMRule();
+    }
     rule->SetStyleSheet(nullptr);
     DidDirty();
 
     if (mDocument) {
       mDocument->StyleRuleRemoved(this, rule);
     }
   }
 }
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -189,17 +189,17 @@ public:
   {
     mScopeElement = aScopeElement;
   }
 
   // WebIDL CSSStyleSheet API
   // Can't be inline because we can't include ImportRule here.  And can't be
   // called GetOwnerRule because that would be ambiguous with the ImportRule
   // version.
-  css::Rule* GetDOMOwnerRule() const final;
+  nsIDOMCSSRule* GetDOMOwnerRule() const final;
 
   void WillDirty();
   void DidDirty();
 
 private:
   CSSStyleSheet(const CSSStyleSheet& aCopy,
                 CSSStyleSheet* aParentToUse,
                 css::ImportRule* aOwnerRuleToUse,
--- a/layout/style/GroupRule.h
+++ b/layout/style/GroupRule.h
@@ -7,50 +7,47 @@
  * internal interface representing CSS style rules that contain other
  * rules, such as @media rules
  */
 
 #ifndef mozilla_css_GroupRule_h__
 #define mozilla_css_GroupRule_h__
 
 #include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
 #include "mozilla/IncrementalClearCOMRuleArray.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/css/Rule.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsPresContext;
 class nsMediaQueryResultCacheKey;
 
 namespace mozilla {
 
 class StyleSheet;
 
-namespace dom {
-class CSSRuleList;
-} // namespace dom
-
 namespace css {
 
 class GroupRuleRuleList;
 
 // inherits from Rule so it can be shared between
 // MediaRule and DocumentRule
 class GroupRule : public Rule
 {
 protected:
   GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber);
   GroupRule(const GroupRule& aCopy);
   virtual ~GroupRule();
 public:
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(GroupRule, Rule)
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS(GroupRule)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
+  // implement part of Rule
+  DECL_STYLE_RULE_INHERIT_NO_DOMRULE
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual void SetStyleSheet(StyleSheet* aSheet) override;
 
 public:
   void AppendStyleRule(Rule* aRule);
 
@@ -78,51 +75,27 @@ public:
   static bool
   CloneRuleInto(Rule* aRule, void* aArray)
   {
     RefPtr<Rule> clone = aRule->Clone();
     static_cast<IncrementalClearCOMRuleArray*>(aArray)->AppendObject(clone);
     return true;
   }
 
-  // WebIDL API
-  dom::CSSRuleList* CssRules();
-  uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
-                      ErrorResult& aRv);
-  void DeleteRule(uint32_t aIndex, ErrorResult& aRv);
-
 protected:
   // to help implement nsIDOMCSSRule
-  void AppendRulesToCssText(nsAString& aCssText) const;
+  void AppendRulesToCssText(nsAString& aCssText);
 
   // to implement common methods on nsIDOMCSSMediaRule and
   // nsIDOMCSSMozDocumentRule
   nsresult GetCssRules(nsIDOMCSSRuleList* *aRuleList);
   nsresult InsertRule(const nsAString & aRule, uint32_t aIndex,
                       uint32_t* _retval);
   nsresult DeleteRule(uint32_t aIndex);
 
   IncrementalClearCOMRuleArray mRules;
   RefPtr<GroupRuleRuleList> mRuleCollection; // lazily constructed
 };
 
-// Implementation of WebIDL CSSConditionRule.
-class ConditionRule : public GroupRule
-{
-protected:
-  ConditionRule(uint32_t aLineNumber, uint32_t aColumnNumber);
-  ConditionRule(const ConditionRule& aCopy);
-  virtual ~ConditionRule();
-
-public:
-
-  // GetConditionText signature matches nsIDOMCSSConditionRule, so subclasses
-  // can implement this easily.  The implementations should never return
-  // anything other than NS_OK.
-  NS_IMETHOD GetConditionText(nsAString& aConditionText) = 0;
-  virtual void SetConditionText(const nsAString& aConditionText,
-                                ErrorResult& aRv) = 0;
-};
-
 } // namespace css
 } // namespace mozilla
 
 #endif /* mozilla_css_GroupRule_h__ */
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -15,61 +15,54 @@
 #include "nsIDOMCSSImportRule.h"
 
 class nsMediaList;
 class nsString;
 
 namespace mozilla {
 
 class CSSStyleSheet;
-class StyleSheet;
 
 namespace css {
 
 class ImportRule final : public Rule,
                          public nsIDOMCSSImportRule
 {
 public:
   ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
              uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   ImportRule(const ImportRule& aCopy);
   ~ImportRule();
 public:
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ImportRule, Rule)
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(ImportRule, mozilla::css::Rule)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+  DECL_STYLE_RULE_INHERIT
 
   using Rule::GetStyleSheet; // unhide since nsIDOMCSSImportRule has its own GetStyleSheet
 
   // Rule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<Rule> Clone() const override;
 
   void SetSheet(CSSStyleSheet*);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSImportRule interface
   NS_DECL_NSIDOMCSSIMPORTRULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // The XPCOM GetHref is fine, since it never fails.
-  nsMediaList* Media() const { return mMedia; }
-  StyleSheet* GetStyleSheet() const;
-
 private:
   nsString  mURLSpec;
   RefPtr<nsMediaList> mMedia;
   RefPtr<CSSStyleSheet> mChildSheet;
 };
 
 } // namespace css
 } // namespace mozilla
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -19,50 +19,48 @@ class nsIAtom;
 // IID for the NameSpaceRule class {f0b0dbe1-5031-4a21-b06a-dc141ef2af98}
 #define NS_CSS_NAMESPACE_RULE_IMPL_CID     \
 {0xf0b0dbe1, 0x5031, 0x4a21, {0xb0, 0x6a, 0xdc, 0x14, 0x1e, 0xf2, 0xaf, 0x98}}
 
 
 namespace mozilla {
 namespace css {
 
-class NameSpaceRule final : public Rule
+class NameSpaceRule final : public Rule,
+                            public nsIDOMCSSRule
 {
 public:
   NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
                 uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   NameSpaceRule(const NameSpaceRule& aCopy);
   ~NameSpaceRule();
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_NAMESPACE_RULE_IMPL_CID)
 
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_ISUPPORTS
 
+  // Rule methods
+  DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<Rule> Clone() const override;
 
   nsIAtom* GetPrefix() const { return mPrefix; }
 
   void GetURLSpec(nsString& aURLSpec) const { aURLSpec = mURLSpec; }
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
     override MOZ_MUST_OVERRIDE;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
 
 private:
   nsCOMPtr<nsIAtom> mPrefix;
   nsString          mURLSpec;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(NameSpaceRule, NS_CSS_NAMESPACE_RULE_IMPL_CID)
 
--- a/layout/style/Rule.h
+++ b/layout/style/Rule.h
@@ -7,30 +7,35 @@
 
 #ifndef mozilla_css_Rule_h___
 #define mozilla_css_Rule_h___
 
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/MemoryReporting.h"
 #include "nsISupports.h"
 #include "nsIDOMCSSRule.h"
-#include "nsWrapperCache.h"
 
 class nsIDocument;
 struct nsRuleData;
 template<class T> struct already_AddRefed;
 class nsHTMLCSSStyleSheet;
 
 namespace mozilla {
 namespace css {
 class GroupRule;
 
-class Rule : public nsIDOMCSSRule
-           , public nsWrapperCache
-{
+#define DECL_STYLE_RULE_INHERIT_NO_DOMRULE  \
+ /* nothing */
+
+#define DECL_STYLE_RULE_INHERIT                            \
+  DECL_STYLE_RULE_INHERIT_NO_DOMRULE                       \
+  virtual nsIDOMCSSRule* GetDOMRule() override;        \
+  virtual nsIDOMCSSRule* GetExistingDOMRule() override;
+
+class Rule : public nsISupports {
 protected:
   Rule(uint32_t aLineNumber, uint32_t aColumnNumber)
     : mSheet(nullptr),
       mParentRule(nullptr),
       mLineNumber(aLineNumber),
       mColumnNumber(aColumnNumber)
   {
   }
@@ -42,22 +47,16 @@ protected:
       mColumnNumber(aCopy.mColumnNumber)
   {
   }
 
   virtual ~Rule() {}
 
 public:
 
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Rule)
-
-  // nsIDOMCSSRule interface
-  NS_DECL_NSIDOMCSSRULE
-
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const = 0;
 #endif
 
   // The constants in this list must maintain the following invariants:
   //   If a rule of type N must appear before a rule of type M in stylesheets
   //   then N < M
   // Note that CSSStyleSheet::RebuildChildList assumes that no other kinds of
@@ -102,30 +101,33 @@ public:
   uint32_t GetLineNumber() const { return mLineNumber; }
   uint32_t GetColumnNumber() const { return mColumnNumber; }
 
   /**
    * Clones |this|. Never returns nullptr.
    */
   virtual already_AddRefed<Rule> Clone() const = 0;
 
+  // Note that this returns null for inline style rules since they aren't
+  // supposed to have a DOM rule representation (and our code wouldn't work).
+  virtual nsIDOMCSSRule* GetDOMRule() = 0;
+
+  // Like GetDOMRule(), but won't create one if we don't have one yet
+  virtual nsIDOMCSSRule* GetExistingDOMRule() = 0;
+
+  // to implement methods on nsIDOMCSSRule
+  nsresult GetParentRule(nsIDOMCSSRule** aParentRule);
+  nsresult GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet);
+  Rule* GetCSSRule();
+
   // This is pure virtual because all of Rule's data members are non-owning and
   // thus measured elsewhere.
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const MOZ_MUST_OVERRIDE = 0;
 
-  // WebIDL interface, aka helpers for nsIDOMCSSRule implementation.
-  virtual uint16_t Type() const = 0;
-  virtual void GetCssTextImpl(nsAString& aCssText) const = 0;
-  // XPCOM GetCssText is OK, since it never throws.
-  // XPCOM SetCssText is OK, since it never throws.
-  Rule* GetParentRule() const;
-  StyleSheet* GetParentStyleSheet() const { return GetStyleSheet(); }
-  nsIDocument* GetParentObject() const { return GetDocument(); }
-
 protected:
   // This is sometimes null (e.g., for style attributes).
   StyleSheet* mSheet;
   // When the parent GroupRule is destroyed, it will call SetParentRule(nullptr)
   // on this object. (Through SetParentRuleReference);
   GroupRule* MOZ_NON_OWNING_REF mParentRule;
 
   // Keep the same type so that MSVC packs them.
--- a/layout/style/ServoCSSRuleList.cpp
+++ b/layout/style/ServoCSSRuleList.cpp
@@ -42,17 +42,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Se
       rule = 0;
     }
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(dom::CSSRuleList)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoCSSRuleList,
                                                   dom::CSSRuleList)
   tmp->EnumerateInstantiatedRules([&](css::Rule* aRule) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
-    cb.NoteXPCOMChild(aRule);
+    cb.NoteXPCOMChild(aRule->GetExistingDOMRule());
   });
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 css::Rule*
 ServoCSSRuleList::GetRule(uint32_t aIndex)
 {
   uintptr_t rule = mRules[aIndex];
   if (rule <= kMaxRuleType) {
@@ -74,25 +74,28 @@ ServoCSSRuleList::GetRule(uint32_t aInde
     }
     ruleObj->SetStyleSheet(mStyleSheet);
     rule = CastToUint(ruleObj.forget().take());
     mRules[aIndex] = rule;
   }
   return CastToPtr(rule);
 }
 
-css::Rule*
+nsIDOMCSSRule*
 ServoCSSRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   if (aIndex >= mRules.Length()) {
     aFound = false;
     return nullptr;
   }
   aFound = true;
-  return GetRule(aIndex);
+  if (css::Rule* rule = GetRule(aIndex)) {
+    return rule->GetDOMRule();
+  }
+  return nullptr;
 }
 
 template<typename Func>
 void
 ServoCSSRuleList::EnumerateInstantiatedRules(Func aCallback)
 {
   for (uintptr_t rule : mRules) {
     if (rule > kMaxRuleType) {
--- a/layout/style/ServoCSSRuleList.h
+++ b/layout/style/ServoCSSRuleList.h
@@ -25,17 +25,17 @@ public:
   ServoCSSRuleList(ServoStyleSheet* aStyleSheet,
                    already_AddRefed<ServoCssRules> aRawRules);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServoCSSRuleList, dom::CSSRuleList)
 
   ServoStyleSheet* GetParentObject() final { return mStyleSheet; }
 
-  css::Rule* IndexedGetter(uint32_t aIndex, bool& aFound) final;
+  nsIDOMCSSRule* IndexedGetter(uint32_t aIndex, bool& aFound) final;
   uint32_t Length() final { return mRules.Length(); }
 
   void DropReference();
 
   css::Rule* GetRule(uint32_t aIndex);
   nsresult InsertRule(const nsAString& aRule, uint32_t aIndex);
   nsresult DeleteRule(uint32_t aIndex);
 
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -6,18 +6,18 @@
 
 /* representation of CSSStyleRule for stylo */
 
 #include "mozilla/ServoStyleRule.h"
 
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/ServoDeclarationBlock.h"
-#include "mozilla/dom/CSSStyleRuleBinding.h"
 
+#include "nsDOMClassInfoID.h"
 #include "mozAutoDocUpdate.h"
 
 namespace mozilla {
 
 // -- ServoStyleRuleDeclaration ---------------------------------------
 
 ServoStyleRuleDeclaration::ServoStyleRuleDeclaration(
   already_AddRefed<RawServoDeclarationBlock> aDecls)
@@ -95,47 +95,50 @@ ServoStyleRuleDeclaration::GetCSSParsing
   CSSParsingEnvironment& aCSSParseEnv)
 {
   GetCSSParsingEnvironmentForRule(Rule(), aCSSParseEnv);
 }
 
 // -- ServoStyleRule --------------------------------------------------
 
 ServoStyleRule::ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule)
-  : BindingStyleRule(0, 0)
+  : css::Rule(0, 0)
   , mRawRule(aRawRule)
   , mDecls(Servo_StyleRule_GetStyle(mRawRule).Consume())
 {
 }
 
 // QueryInterface implementation for ServoStyleRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServoStyleRule)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServoStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
-NS_INTERFACE_MAP_END_INHERITING(css::Rule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSStyleRule)
+NS_INTERFACE_MAP_END
 
-NS_IMPL_ADDREF_INHERITED(ServoStyleRule, css::Rule)
-NS_IMPL_RELEASE_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ServoStyleRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ServoStyleRule)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(ServoStyleRule)
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ServoStyleRule)
   // Trace the wrapper for our declaration.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecls.TraceWrapper(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ServoStyleRule)
   // Unlink the wrapper for our declaraton.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecls.ReleaseWrapper(static_cast<nsISupports*>(p));
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServoStyleRule, css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ServoStyleRule)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 already_AddRefed<css::Rule>
 ServoStyleRule::Clone() const
 {
   // Rule::Clone is only used when CSSStyleSheetInner is cloned in
   // preparation of being mutated. However, ServoStyleSheet never clones
   // anything, so this method should never be called.
@@ -160,32 +163,53 @@ ServoStyleRule::List(FILE* out, int32_t 
   }
   Servo_StyleRule_Debug(mRawRule, &str);
   fprintf_stderr(out, "%s\n", str.get());
 }
 #endif
 
 /* CSSRule implementation */
 
-uint16_t
-ServoStyleRule::Type() const
+NS_IMETHODIMP
+ServoStyleRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::STYLE_RULE;
+  *aType = nsIDOMCSSRule::STYLE_RULE;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ServoStyleRule::GetCssText(nsAString& aCssText)
+{
+  Servo_StyleRule_GetCssText(mRawRule, &aCssText);
+  return NS_OK;
 }
 
-void
-ServoStyleRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+ServoStyleRule::SetCssText(const nsAString& aCssText)
 {
-  Servo_StyleRule_GetCssText(mRawRule, &aCssText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+ServoStyleRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return css::Rule::GetParentStyleSheet(aSheet);
 }
 
-nsICSSDeclaration*
-ServoStyleRule::Style()
+NS_IMETHODIMP
+ServoStyleRule::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
-  return &mDecls;
+  *aParentRule = nullptr;
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+css::Rule*
+ServoStyleRule::GetCSSRule()
+{
+  return this;
 }
 
 /* CSSStyleRule implementation */
 
 NS_IMETHODIMP
 ServoStyleRule::GetSelectorText(nsAString& aSelectorText)
 {
   Servo_StyleRule_GetSelectorText(mRawRule, &aSelectorText);
--- a/layout/style/ServoStyleRule.h
+++ b/layout/style/ServoStyleRule.h
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* representation of CSSStyleRule for stylo */
 
 #ifndef mozilla_ServoStyleRule_h
 #define mozilla_ServoStyleRule_h
 
-#include "mozilla/BindingStyleRule.h"
+#include "mozilla/css/Rule.h"
 #include "mozilla/ServoBindingTypes.h"
 
 #include "nsIDOMCSSStyleRule.h"
 #include "nsDOMCSSDeclaration.h"
 
 namespace mozilla {
 
 class ServoDeclarationBlock;
@@ -42,38 +42,35 @@ private:
     already_AddRefed<RawServoDeclarationBlock> aDecls);
   ~ServoStyleRuleDeclaration();
 
   inline ServoStyleRule* Rule();
 
   RefPtr<ServoDeclarationBlock> mDecls;
 };
 
-class ServoStyleRule final : public BindingStyleRule
+class ServoStyleRule final : public css::Rule
                            , public nsIDOMCSSStyleRule
 {
 public:
   explicit ServoStyleRule(already_AddRefed<RawServoStyleRule> aRawRule);
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ServoStyleRule,
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(ServoStyleRule,
                                                          css::Rule)
+  NS_DECL_NSIDOMCSSRULE
   NS_DECL_NSIDOMCSSSTYLERULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  virtual nsICSSDeclaration* Style() override;
-
   RawServoStyleRule* Raw() const { return mRawRule; }
 
   // Methods of mozilla::css::Rule
   int32_t GetType() const final { return css::Rule::STYLE_RULE; }
-  using Rule::GetType;
   already_AddRefed<Rule> Clone() const final;
+  nsIDOMCSSRule* GetDOMRule() final { return this; }
+  nsIDOMCSSRule* GetExistingDOMRule() final { return this; }
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const final;
 #ifdef DEBUG
   void List(FILE* out = stdout, int32_t aIndent = 0) const final;
 #endif
 
 private:
   ~ServoStyleRule() {}
 
--- a/layout/style/ServoStyleSheet.cpp
+++ b/layout/style/ServoStyleSheet.cpp
@@ -140,20 +140,19 @@ ServoStyleSheet::SizeOfIncludingThis(Mal
 #ifdef DEBUG
 void
 ServoStyleSheet::List(FILE* aOut, int32_t aIndex) const
 {
   MOZ_CRASH("stylo: not implemented");
 }
 #endif
 
-css::Rule*
+nsIDOMCSSRule*
 ServoStyleSheet::GetDOMOwnerRule() const
 {
-  NS_ERROR("stylo: Don't know how to get DOM owner rule for ServoStyleSheet");
   return nullptr;
 }
 
 CSSRuleList*
 ServoStyleSheet::GetCssRulesInternal(ErrorResult& aRv)
 {
   if (!mRuleList) {
     RefPtr<ServoCssRules> rawRules = Servo_StyleSheet_GetRules(mSheet).Consume();
--- a/layout/style/ServoStyleSheet.h
+++ b/layout/style/ServoStyleSheet.h
@@ -15,17 +15,16 @@
 #include "nsStringFwd.h"
 
 namespace mozilla {
 
 class ServoCSSRuleList;
 
 namespace css {
 class Loader;
-class Rule;
 }
 
 /**
  * CSS style sheet object that is a wrapper for a Servo Stylesheet.
  */
 class ServoStyleSheet : public StyleSheet
 {
 public:
@@ -69,17 +68,17 @@ public:
     MOZ_ASSERT(!mSheet);
     mSheet = aSheet;
   }
 
   // WebIDL CSSStyleSheet API
   // Can't be inline because we can't include ImportRule here.  And can't be
   // called GetOwnerRule because that would be ambiguous with the ImportRule
   // version.
-  css::Rule* GetDOMOwnerRule() const final;
+  nsIDOMCSSRule* GetDOMOwnerRule() const final;
 
   void WillDirty() {}
   void DidDirty() {}
 
 protected:
   virtual ~ServoStyleSheet();
 
   // Internal methods which do not have security check and completeness check.
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -11,27 +11,28 @@
 
 #include "mozilla/css/StyleRule.h"
 
 #include "mozilla/DeclarationBlockInlines.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/css/GroupRule.h"
 #include "mozilla/css/Declaration.h"
-#include "mozilla/dom/CSSStyleRuleBinding.h"
 #include "nsIDocument.h"
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "nsStyleUtil.h"
+#include "nsICSSStyleRuleDOMWrapper.h"
 #include "nsDOMCSSDeclaration.h"
 #include "nsNameSpaceManager.h"
 #include "nsXMLNameSpaceMap.h"
 #include "nsCSSPseudoClasses.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsTArray.h"
+#include "nsDOMClassInfoID.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "mozAutoDocUpdate.h"
 
 class nsIDOMCSSStyleDeclaration;
 class nsIDOMCSSStyleSheet;
 
 using namespace mozilla;
@@ -1041,96 +1042,166 @@ nsCSSSelectorList::SizeOfIncludingThis(m
     n += s->mSelectors ? s->mSelectors->SizeOfIncludingThis(aMallocSizeOf) : 0;
     s = s->mNext;
   }
   return n;
 }
 
 // --------------------------------------------------------
 
+namespace mozilla {
+namespace css {
+class DOMCSSStyleRule;
+} // namespace css
+} // namespace mozilla
+
 class DOMCSSDeclarationImpl : public nsDOMCSSDeclaration
 {
 protected:
-  // Needs to be protected so we can use NS_IMPL_ADDREF_USING_AGGREGATOR.
   virtual ~DOMCSSDeclarationImpl(void);
 
-  // But we need to allow UniquePtr to delete us.
-  friend class mozilla::DefaultDelete<DOMCSSDeclarationImpl>;
-
 public:
   explicit DOMCSSDeclarationImpl(css::StyleRule *aRule);
 
   NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) override;
+  void DropReference(void);
   virtual DeclarationBlock* GetCSSDeclaration(Operation aOperation) override;
   virtual nsresult SetCSSDeclaration(DeclarationBlock* aDecl) override;
   virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) override;
   virtual nsIDocument* DocToUpdate() override;
 
-  // Override |AddRef| and |Release| for being owned by StyleRule.  Also, we
-  // need to forward QI for cycle collection things to StyleRule.
+  // Override |AddRef| and |Release| for being a member of
+  // |DOMCSSStyleRule|.  Also, we need to forward QI for cycle
+  // collection things to DOMCSSStyleRule.
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual nsINode *GetParentObject() override
   {
     return mRule ? mRule->GetDocument() : nullptr;
   }
 
+  friend class css::DOMCSSStyleRule;
+
 protected:
-  // This reference is not reference-counted. The rule object owns us and we go
-  // away when it does.
+  // This reference is not reference-counted. The rule object tells us
+  // when it's about to go away.
   css::StyleRule *mRule;
+
+  inline css::DOMCSSStyleRule* DomRule();
+
+private:
+  // NOT TO BE IMPLEMENTED
+  // This object cannot be allocated on its own.  It must be a member of
+  // DOMCSSStyleRule.
+  void* operator new(size_t size) CPP_THROW_NEW;
 };
 
+namespace mozilla {
+namespace css {
+
+class DOMCSSStyleRule : public nsICSSStyleRuleDOMWrapper
+{
+public:
+  explicit DOMCSSStyleRule(StyleRule *aRule);
+
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMCSSStyleRule)
+  NS_DECL_NSIDOMCSSRULE
+  NS_DECL_NSIDOMCSSSTYLERULE
+
+  // nsICSSStyleRuleDOMWrapper
+  NS_IMETHOD GetCSSStyleRule(StyleRule **aResult) override;
+
+  DOMCSSDeclarationImpl* DOMDeclaration() { return &mDOMDeclaration; }
+
+  friend class ::DOMCSSDeclarationImpl;
+
+protected:
+  virtual ~DOMCSSStyleRule();
+
+  DOMCSSDeclarationImpl mDOMDeclaration;
+
+  StyleRule* Rule() {
+    return mDOMDeclaration.mRule;
+  }
+};
+
+} // namespace css
+} // namespace mozilla
+
 DOMCSSDeclarationImpl::DOMCSSDeclarationImpl(css::StyleRule *aRule)
   : mRule(aRule)
 {
 }
 
 DOMCSSDeclarationImpl::~DOMCSSDeclarationImpl(void)
 {
+  NS_ASSERTION(!mRule, "DropReference not called.");
 }
 
-NS_IMPL_ADDREF_USING_AGGREGATOR(DOMCSSDeclarationImpl, mRule)
-NS_IMPL_RELEASE_USING_AGGREGATOR(DOMCSSDeclarationImpl, mRule)
+inline css::DOMCSSStyleRule* DOMCSSDeclarationImpl::DomRule()
+{
+  return reinterpret_cast<css::DOMCSSStyleRule*>
+                         (reinterpret_cast<char*>(this) -
+           offsetof(css::DOMCSSStyleRule, mDOMDeclaration));
+}
+
+NS_IMPL_ADDREF_USING_AGGREGATOR(DOMCSSDeclarationImpl, DomRule())
+NS_IMPL_RELEASE_USING_AGGREGATOR(DOMCSSDeclarationImpl, DomRule())
 
 NS_INTERFACE_MAP_BEGIN(DOMCSSDeclarationImpl)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  // We forward the cycle collection interfaces to mRule, which is
-  // never null.
+  // We forward the cycle collection interfaces to DomRule(), which is
+  // never null (in fact, we're part of that object!)
   if (aIID.Equals(NS_GET_IID(nsCycleCollectionISupports)) ||
       aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
-    return mRule->QueryInterface(aIID, aInstancePtr);
+    return DomRule()->QueryInterface(aIID, aInstancePtr);
   }
   else
 NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
 
+void
+DOMCSSDeclarationImpl::DropReference(void)
+{
+  mRule = nullptr;
+}
+
 DeclarationBlock*
 DOMCSSDeclarationImpl::GetCSSDeclaration(Operation aOperation)
 {
-  if (aOperation != eOperation_Read) {
-    RefPtr<CSSStyleSheet> sheet = mRule->GetStyleSheet();
-    if (sheet) {
-      sheet->WillDirty();
+  if (mRule) {
+    if (aOperation != eOperation_Read) {
+      RefPtr<CSSStyleSheet> sheet = mRule->GetStyleSheet();
+      if (sheet) {
+        sheet->WillDirty();
+      }
     }
+    return mRule->GetDeclaration();
+  } else {
+    return nullptr;
   }
-  return mRule->GetDeclaration();
 }
 
 void
 DOMCSSDeclarationImpl::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
 {
   GetCSSParsingEnvironmentForRule(mRule, aCSSParseEnv);
 }
 
 NS_IMETHODIMP
 DOMCSSDeclarationImpl::GetParentRule(nsIDOMCSSRule **aParent)
 {
   NS_ENSURE_ARG_POINTER(aParent);
 
-  NS_IF_ADDREF(*aParent = mRule);
+  if (!mRule) {
+    *aParent = nullptr;
+    return NS_OK;
+  }
+
+  NS_IF_ADDREF(*aParent = mRule->GetDOMRule());
   return NS_OK;
 }
 
 nsresult
 DOMCSSDeclarationImpl::SetCSSDeclaration(DeclarationBlock* aDecl)
 {
   NS_PRECONDITION(mRule,
          "can only be called when |GetCSSDeclaration| returned a declaration");
@@ -1156,139 +1227,239 @@ DOMCSSDeclarationImpl::SetCSSDeclaration
 }
 
 nsIDocument*
 DOMCSSDeclarationImpl::DocToUpdate()
 {
   return nullptr;
 }
 
+namespace mozilla {
+namespace css {
+
+DOMCSSStyleRule::DOMCSSStyleRule(StyleRule* aRule)
+  : mDOMDeclaration(aRule)
+{
+}
+
+DOMCSSStyleRule::~DOMCSSStyleRule()
+{
+}
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMCSSStyleRule)
+  NS_INTERFACE_MAP_ENTRY(nsICSSStyleRuleDOMWrapper)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSStyleRule)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMCSSStyleRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMCSSStyleRule)
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(DOMCSSStyleRule)
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMCSSStyleRule)
+  // Trace the wrapper for our declaration.  This just expands out
+  // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
+  // directly because the wrapper is on the declaration, not on us.
+  tmp->DOMDeclaration()->TraceWrapper(aCallbacks, aClosure);
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMCSSStyleRule)
+  // Unlink the wrapper for our declaraton.  This just expands out
+  // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
+  // directly because the wrapper is on the declaration, not on us.
+  tmp->DOMDeclaration()->ReleaseWrapper(static_cast<nsISupports*>(p));
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMCSSStyleRule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetType(uint16_t* aType)
+{
+  *aType = nsIDOMCSSRule::STYLE_RULE;
+  
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetCssText(nsAString& aCssText)
+{
+  if (!Rule()) {
+    aCssText.Truncate();
+  } else {
+    Rule()->GetCssText(aCssText);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::SetCssText(const nsAString& aCssText)
+{
+  if (Rule()) {
+    Rule()->SetCssText(aCssText);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  if (!Rule()) {
+    *aSheet = nullptr;
+    return NS_OK;
+  }
+  return Rule()->GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  if (!Rule()) {
+    *aParentRule = nullptr;
+    return NS_OK;
+  }
+  return Rule()->GetParentRule(aParentRule);
+}
+
+css::Rule*
+DOMCSSStyleRule::GetCSSRule()
+{
+  return Rule();
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetSelectorText(nsAString& aSelectorText)
+{
+  if (!Rule()) {
+    aSelectorText.Truncate();
+  } else {
+    Rule()->GetSelectorText(aSelectorText);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::SetSelectorText(const nsAString& aSelectorText)
+{
+  if (Rule()) {
+    Rule()->SetSelectorText(aSelectorText);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
+{
+  *aStyle = &mDOMDeclaration;
+  NS_ADDREF(*aStyle);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DOMCSSStyleRule::GetCSSStyleRule(StyleRule **aResult)
+{
+  *aResult = Rule();
+  NS_IF_ADDREF(*aResult);
+  return NS_OK;
+}
+
+} // namespace css
+} // namespace mozilla
+
 // -- StyleRule ------------------------------------
 
 namespace mozilla {
 namespace css {
 
-uint16_t
-StyleRule::Type() const
-{
-  return nsIDOMCSSRule::STYLE_RULE;
-}
-
-NS_IMETHODIMP
-StyleRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
-{
-  NS_ADDREF(*aStyle = Style());
-  return NS_OK;
-}
-
-nsICSSDeclaration*
-StyleRule::Style()
-{
-  if (!mDOMDeclaration) {
-    mDOMDeclaration.reset(new DOMCSSDeclarationImpl(this));
-  }
-  return mDOMDeclaration.get();
-}
-
-NS_IMETHODIMP
-StyleRule::GetCSSStyleRule(StyleRule **aResult)
-{
-  *aResult = this;
-  NS_ADDREF(*aResult);
-  return NS_OK;
-}
-
 StyleRule::StyleRule(nsCSSSelectorList* aSelector,
                      Declaration* aDeclaration,
                      uint32_t aLineNumber,
                      uint32_t aColumnNumber)
-  : BindingStyleRule(aLineNumber, aColumnNumber),
+  : Rule(aLineNumber, aColumnNumber),
     mSelector(aSelector),
     mDeclaration(aDeclaration)
 {
   NS_PRECONDITION(aDeclaration, "must have a declaration");
 
   mDeclaration->SetOwningRule(this);
 }
 
 // for |Clone|
 StyleRule::StyleRule(const StyleRule& aCopy)
-  : BindingStyleRule(aCopy),
+  : Rule(aCopy),
     mSelector(aCopy.mSelector ? aCopy.mSelector->Clone() : nullptr),
     mDeclaration(new Declaration(*aCopy.mDeclaration))
 {
   mDeclaration->SetOwningRule(this);
   // rest is constructed lazily on existing data
 }
 
 StyleRule::~StyleRule()
 {
   delete mSelector;
-  DropReferences();
-}
+  if (mDOMRule) {
+    mDOMRule->DOMDeclaration()->DropReference();
+  }
 
-void
-StyleRule::DropReferences()
-{
   if (mDeclaration) {
     mDeclaration->SetOwningRule(nullptr);
-    mDeclaration = nullptr;
   }
 }
 
 // QueryInterface implementation for StyleRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(StyleRule)
+NS_INTERFACE_MAP_BEGIN(StyleRule)
   if (aIID.Equals(NS_GET_IID(mozilla::css::StyleRule))) {
     *aInstancePtr = this;
     NS_ADDREF_THIS();
     return NS_OK;
   }
   else
-  NS_INTERFACE_MAP_ENTRY(nsICSSStyleRuleDOMWrapper)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleRule)
-NS_INTERFACE_MAP_END_INHERITING(Rule)
-
-NS_IMPL_ADDREF_INHERITED(StyleRule, Rule)
-NS_IMPL_RELEASE_INHERITED(StyleRule, Rule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+NS_INTERFACE_MAP_END
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(StyleRule)
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(StyleRule, Rule)
-  // Trace the wrapper for our declaration.  This just expands out
-  // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
-  // directly because the wrapper is on the declaration, not on us.
-  if (tmp->mDOMDeclaration) {
-    tmp->mDOMDeclaration->TraceWrapper(aCallbacks, aClosure);
-  }
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(StyleRule, Rule)
-  // Unlink the wrapper for our declaraton.  This just expands out
-  // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
-  // directly because the wrapper is on the declaration, not on us.
-  if (tmp->mDOMDeclaration) {
-    tmp->mDOMDeclaration->ReleaseWrapper(static_cast<nsISupports*>(p));
-  }
-  tmp->DropReferences();
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(StyleRule, Rule)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeclaration)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_ADDREF(StyleRule)
+NS_IMPL_RELEASE(StyleRule)
 
 /* virtual */ int32_t
 StyleRule::GetType() const
 {
   return Rule::STYLE_RULE;
 }
 
 /* virtual */ already_AddRefed<Rule>
 StyleRule::Clone() const
 {
   RefPtr<Rule> clone = new StyleRule(*this);
   return clone.forget();
 }
 
+/* virtual */ nsIDOMCSSRule*
+StyleRule::GetDOMRule()
+{
+  if (!mDOMRule) {
+    if (!GetStyleSheet()) {
+      // Inline style rules aren't supposed to have a DOM rule object, only
+      // a declaration.  But if we do have one already, from a style sheet
+      // rule that used to be in a document, we still want to return it.
+      return nullptr;
+    }
+    mDOMRule = new DOMCSSStyleRule(this);
+  }
+  return mDOMRule;
+}
+
+/* virtual */ nsIDOMCSSRule*
+StyleRule::GetExistingDOMRule()
+{
+  return mDOMRule;
+}
+
 void
 StyleRule::SetDeclaration(Declaration* aDecl)
 {
   if (aDecl == mDeclaration) {
     return;
   }
   mDeclaration->SetOwningRule(nullptr);
   mDeclaration = aDecl;
@@ -1334,17 +1505,17 @@ StyleRule::List(FILE* out, int32_t aInde
     str.AppendLiteral("{ null declaration }");
   }
   str.Append('\n');
   fprintf_stderr(out, "%s", str.get());
 }
 #endif
 
 void
-StyleRule::GetCssTextImpl(nsAString& aCssText) const
+StyleRule::GetCssText(nsAString& aCssText)
 {
   if (mSelector) {
     mSelector->ToString(aCssText, GetStyleSheet());
     aCssText.Append(char16_t(' '));
   }
   aCssText.Append(char16_t('{'));
   aCssText.Append(char16_t(' '));
   if (mDeclaration)
@@ -1352,43 +1523,48 @@ StyleRule::GetCssTextImpl(nsAString& aCs
     nsAutoString   tempString;
     mDeclaration->ToString( tempString );
     aCssText.Append( tempString );
   }
   aCssText.Append(char16_t(' '));
   aCssText.Append(char16_t('}'));
 }
 
-NS_IMETHODIMP
+void
+StyleRule::SetCssText(const nsAString& aCssText)
+{
+  // XXX TBI - need to re-parse rule & declaration
+}
+
+void
 StyleRule::GetSelectorText(nsAString& aSelectorText)
 {
   if (mSelector)
     mSelector->ToString(aSelectorText, GetStyleSheet());
   else
     aSelectorText.Truncate();
-  return NS_OK;
 }
 
-NS_IMETHODIMP
+void
 StyleRule::SetSelectorText(const nsAString& aSelectorText)
 {
   // XXX TBI - get a parser and re-parse the selectors,
   // XXX then need to re-compute the cascade
   // XXX and dirty sheet
-  return NS_OK;
 }
 
 /* virtual */ size_t
 StyleRule::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
   n += mSelector ? mSelector->SizeOfIncludingThis(aMallocSizeOf) : 0;
   n += mDeclaration ? mDeclaration->SizeOfIncludingThis(aMallocSizeOf) : 0;
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mDOMRule;
 
   return n;
 }
 
+
 } // namespace css
 } // namespace mozilla
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -8,24 +8,22 @@
  * selectors
  */
 
 #ifndef mozilla_css_StyleRule_h__
 #define mozilla_css_StyleRule_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/UniquePtr.h"
-#include "mozilla/BindingStyleRule.h"
+#include "mozilla/css/Rule.h"
 
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsCSSPseudoElements.h"
 #include "nsIStyleRule.h"
-#include "nsICSSStyleRuleDOMWrapper.h"
 
 class nsIAtom;
 struct nsCSSSelectorList;
 
 namespace mozilla {
 enum class CSSPseudoClassType : uint8_t;
 class CSSStyleSheet;
 } // namespace mozilla
@@ -299,85 +297,76 @@ private:
   nsCSSSelectorList& operator=(const nsCSSSelectorList& aCopy) = delete;
 };
 
 // 464bab7a-2fce-4f30-ab44-b7a5f3aae57d
 #define NS_CSS_STYLE_RULE_IMPL_CID \
 { 0x464bab7a, 0x2fce, 0x4f30, \
   { 0xab, 0x44, 0xb7, 0xa5, 0xf3, 0xaa, 0xe5, 0x7d } }
 
-class DOMCSSDeclarationImpl;
-
 namespace mozilla {
 namespace css {
 
 class Declaration;
+class DOMCSSStyleRule;
 
-class StyleRule final : public BindingStyleRule
-                      , public nsICSSStyleRuleDOMWrapper
+class StyleRule final : public Rule
 {
  public:
   StyleRule(nsCSSSelectorList* aSelector,
             Declaration *aDeclaration,
             uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   StyleRule(const StyleRule& aCopy);
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_RULE_IMPL_CID)
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(StyleRule, Rule)
-  NS_DECL_NSIDOMCSSSTYLERULE
-
-  // nsICSSStyleRuleDOMWrapper
-  NS_IMETHOD GetCSSStyleRule(StyleRule **aResult) override;
-
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  virtual nsICSSDeclaration* Style() override;
+  NS_DECL_ISUPPORTS
 
   // null for style attribute
   nsCSSSelectorList* Selector() { return mSelector; }
 
   Declaration* GetDeclaration() const { return mDeclaration; }
 
   void SetDeclaration(Declaration* aDecl);
 
+  // hooks for DOM rule
+  void GetCssText(nsAString& aCssText);
+  void SetCssText(const nsAString& aCssText);
+  void GetSelectorText(nsAString& aSelectorText);
+  void SetSelectorText(const nsAString& aSelectorText);
+
   virtual int32_t GetType() const override;
-  using Rule::GetType;
 
   CSSStyleSheet* GetStyleSheet() const
   {
     StyleSheet* sheet = Rule::GetStyleSheet();
     return sheet ? sheet->AsGecko() : nullptr;
   }
 
   virtual already_AddRefed<Rule> Clone() const override;
 
+  virtual nsIDOMCSSRule* GetDOMRule() override;
+
+  virtual nsIDOMCSSRule* GetExistingDOMRule() override;
+
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
 private:
   ~StyleRule();
 
-  // Drop our references to mDeclaration and mRule, and let them know we're
-  // doing that.
-  void DropReferences();
-
 private:
   nsCSSSelectorList*      mSelector; // null for style attribute
   RefPtr<Declaration>     mDeclaration;
-
-  // We own it, and it aggregates its refcount with us.
-  UniquePtr<DOMCSSDeclarationImpl> mDOMDeclaration;
+  RefPtr<DOMCSSStyleRule> mDOMRule;
 
 private:
   StyleRule& operator=(const StyleRule& aCopy) = delete;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(StyleRule, NS_CSS_STYLE_RULE_IMPL_CID)
 
 } // namespace css
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -28,20 +28,16 @@ class CSSStyleSheet;
 class ServoStyleSheet;
 struct StyleSheetInfo;
 
 namespace dom {
 class CSSRuleList;
 class SRIMetadata;
 } // namespace dom
 
-namespace css {
-class Rule;
-}
-
 /**
  * Superclass for data common to CSSStyleSheet and ServoStyleSheet.
  */
 class StyleSheet : public nsIDOMCSSStyleSheet
                  , public nsWrapperCache
 {
 protected:
   StyleSheet(StyleBackendType aType, css::SheetParsingMode aParsingMode);
@@ -147,17 +143,17 @@ public:
   // GetOwnerNode is defined above.
   inline StyleSheet* GetParentStyleSheet() const;
   // The XPCOM GetTitle is fine for WebIDL.
   nsMediaList* Media();
   bool Disabled() const { return mDisabled; }
   // The XPCOM SetDisabled is fine for WebIDL.
 
   // WebIDL CSSStyleSheet API
-  virtual css::Rule* GetDOMOwnerRule() const = 0;
+  virtual nsIDOMCSSRule* GetDOMOwnerRule() const = 0;
   dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal,
                                 ErrorResult& aRv);
   uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
                       nsIPrincipal& aSubjectPrincipal,
                       ErrorResult& aRv);
   void DeleteRule(uint32_t aIndex,
                   nsIPrincipal& aSubjectPrincipal,
                   ErrorResult& aRv);
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -76,17 +76,16 @@ EXPORTS += [
     'nsStyleStructFwd.h',
     'nsStyleStructInlines.h',
     'nsStyleTransformMatrix.h',
     'nsStyleUtil.h',
 ]
 
 EXPORTS.mozilla += [
     'AnimationCollection.h',
-    'BindingStyleRule.h',
     'CSSEnabledState.h',
     'CSSStyleSheet.h',
     'CSSVariableDeclarations.h',
     'CSSVariableResolver.h',
     'CSSVariableValues.h',
     'DeclarationBlock.h',
     'DeclarationBlockInlines.h',
     'DocumentStyleRootIterator.h',
@@ -142,17 +141,16 @@ EXPORTS.mozilla.css += [
     'Rule.h',
     'SheetParsingMode.h',
     'StyleRule.h',
 ]
 
 UNIFIED_SOURCES += [
     'AnimationCollection.cpp',
     'AnimationCommon.cpp',
-    'BindingStyleRule.cpp',
     'CounterStyleManager.cpp',
     'CSS.cpp',
     'CSSLexer.cpp',
     'CSSRuleList.cpp',
     'CSSStyleSheet.cpp',
     'CSSVariableDeclarations.cpp',
     'CSSVariableResolver.cpp',
     'CSSVariableValues.cpp',
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -28,122 +28,85 @@
 
 #include "nsContentUtils.h"
 #include "nsError.h"
 #include "nsStyleUtil.h"
 #include "mozilla/DeclarationBlockInlines.h"
 #include "nsCSSParser.h"
 #include "nsDOMClassInfoID.h"
 #include "mozilla/dom/CSSStyleDeclarationBinding.h"
-#include "mozilla/dom/CSSNamespaceRuleBinding.h"
-#include "mozilla/dom/CSSImportRuleBinding.h"
-#include "mozilla/dom/CSSMediaRuleBinding.h"
-#include "mozilla/dom/CSSSupportsRuleBinding.h"
-#include "mozilla/dom/CSSMozDocumentRuleBinding.h"
-#include "mozilla/dom/CSSPageRuleBinding.h"
-#include "mozilla/dom/CSSFontFaceRuleBinding.h"
-#include "mozilla/dom/CSSFontFeatureValuesRuleBinding.h"
-#include "mozilla/dom/CSSKeyframeRuleBinding.h"
-#include "mozilla/dom/CSSKeyframesRuleBinding.h"
-#include "mozilla/dom/CSSCounterStyleRuleBinding.h"
 #include "StyleRule.h"
 #include "nsFont.h"
 #include "nsIURI.h"
 #include "mozAutoDocUpdate.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+#define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \
+  /* virtual */ nsIDOMCSSRule* class_::GetDOMRule()               \
+  { return this; }                                                \
+  /* virtual */ nsIDOMCSSRule* class_::GetExistingDOMRule()       \
+  { return this; }
+
+#define IMPL_STYLE_RULE_INHERIT(class_, super_) \
+IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_)
+
 // base class for all rule types in a CSS style sheet
 
 namespace mozilla {
 namespace css {
 
-NS_IMPL_CYCLE_COLLECTING_ADDREF(Rule)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(Rule)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Rule)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(Rule)
-
 /* virtual */ void
 Rule::SetStyleSheet(StyleSheet* aSheet)
 {
   // We don't reference count this up reference. The style sheet
   // will tell us when it's going away or when we're detached from
   // it.
   mSheet = aSheet;
 }
 
-NS_IMETHODIMP
+nsresult
 Rule::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
-  NS_IF_ADDREF(*aParentRule = mParentRule);
+  if (mParentRule) {
+    NS_IF_ADDREF(*aParentRule = mParentRule->GetDOMRule());
+  } else {
+    *aParentRule = nullptr;
+  }
   return NS_OK;
 }
 
-NS_IMETHODIMP
+nsresult
 Rule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
 {
   NS_ENSURE_ARG_POINTER(aSheet);
 
   NS_IF_ADDREF(*aSheet = GetStyleSheet());
   return NS_OK;
 }
 
-/* virtual */ css::Rule*
+css::Rule*
 Rule::GetCSSRule()
 {
   return this;
 }
 
-NS_IMETHODIMP
-Rule::GetType(uint16_t* aType)
-{
-  *aType = Type();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Rule::SetCssText(const nsAString& aCssText)
-{
-  // We used to throw for some rule types, but not all.  Specifically, we did
-  // not throw for StyleRule.  Let's just always not throw.
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-Rule::GetCssText(nsAString& aCssText)
-{
-  GetCssTextImpl(aCssText);
-  return NS_OK;
-}
-
-Rule*
-Rule::GetParentRule() const
-{
-  return mParentRule;
-}
-
 // -------------------------------
 // Style Rule List for group rules
 //
 
 class GroupRuleRuleList final : public dom::CSSRuleList
 {
 public:
   explicit GroupRuleRuleList(GroupRule *aGroupRule);
 
   virtual CSSStyleSheet* GetParentObject() override;
 
-  virtual Rule*
+  virtual nsIDOMCSSRule*
   IndexedGetter(uint32_t aIndex, bool& aFound) override;
   virtual uint32_t
   Length() override;
 
   void DropReference() { mGroupRule = nullptr; }
 
 private:
   ~GroupRuleRuleList();
@@ -178,43 +141,42 @@ GroupRuleRuleList::Length()
 {
   if (!mGroupRule) {
     return 0;
   }
 
   return AssertedCast<uint32_t>(mGroupRule->StyleRuleCount());
 }
 
-Rule*
+nsIDOMCSSRule*
 GroupRuleRuleList::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   aFound = false;
 
   if (mGroupRule) {
     RefPtr<Rule> rule = mGroupRule->GetStyleRuleAt(aIndex);
     if (rule) {
       aFound = true;
-      return rule;
+      return rule->GetDOMRule();
     }
   }
 
   return nullptr;
 }
 
 // -------------------------------------------
 // ImportRule
 //
 
 ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
                        uint32_t aLineNumber, uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber)
   , mURLSpec(aURLSpec)
   , mMedia(aMedia)
 {
-  MOZ_ASSERT(aMedia);
   // XXXbz This is really silly.... the mMedia here will be replaced
   // with itself if we manage to load a sheet.  Which should really
   // never fail nowadays, in sane cases.
 }
 
 ImportRule::ImportRule(const ImportRule& aCopy)
   : Rule(aCopy),
     mURLSpec(aCopy.mURLSpec)
@@ -232,25 +194,30 @@ ImportRule::ImportRule(const ImportRule&
 
 ImportRule::~ImportRule()
 {
   if (mChildSheet) {
     mChildSheet->SetOwnerRule(nullptr);
   }
 }
 
-NS_IMPL_ADDREF_INHERITED(ImportRule, Rule)
-NS_IMPL_RELEASE_INHERITED(ImportRule, Rule)
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(ImportRule, Rule, mMedia, mChildSheet)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(ImportRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(ImportRule)
+
+NS_IMPL_CYCLE_COLLECTION(ImportRule, mMedia, mChildSheet)
 
 // QueryInterface implementation for ImportRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ImportRule)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImportRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSImportRule)
-NS_INTERFACE_MAP_END_INHERITING(Rule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSImportRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT(ImportRule, Rule)
 
 #ifdef DEBUG
 /* virtual */ void
 ImportRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   // Indent
   for (int32_t indent = aIndent; --indent >= 0; ) {
@@ -290,58 +257,79 @@ ImportRule::SetSheet(CSSStyleSheet* aShe
   // set the new sheet
   mChildSheet = aSheet;
   aSheet->SetOwnerRule(this);
 
   // set our medialist to be the same as the sheet's medialist
   mMedia = mChildSheet->Media();
 }
 
-uint16_t
-ImportRule::Type() const
+NS_IMETHODIMP
+ImportRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::IMPORT_RULE;
+  NS_ENSURE_ARG_POINTER(aType);
+  *aType = nsIDOMCSSRule::IMPORT_RULE;
+  return NS_OK;
 }
 
-void
-ImportRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+ImportRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@import url(");
   nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
   aCssText.Append(')');
   if (mMedia) {
     nsAutoString mediaText;
     mMedia->GetText(mediaText);
     if (!mediaText.IsEmpty()) {
       aCssText.Append(' ');
       aCssText.Append(mediaText);
     }
   }
   aCssText.Append(';');
+  return NS_OK;
 }
 
-StyleSheet*
-ImportRule::GetStyleSheet() const
+NS_IMETHODIMP
+ImportRule::SetCssText(const nsAString& aCssText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+ImportRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
 {
-  return mChildSheet;
+  return Rule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+ImportRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+ImportRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 NS_IMETHODIMP
 ImportRule::GetHref(nsAString & aHref)
 {
   aHref = mURLSpec;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ImportRule::GetMedia(nsIDOMMediaList * *aMedia)
 {
   NS_ENSURE_ARG_POINTER(aMedia);
 
-  NS_ADDREF(*aMedia = mMedia);
+  NS_IF_ADDREF(*aMedia = mMedia);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ImportRule::GetStyleSheet(nsIDOMCSSStyleSheet * *aStyleSheet)
 {
   NS_ENSURE_ARG_POINTER(aStyleSheet);
 
@@ -358,23 +346,16 @@ ImportRule::SizeOfIncludingThis(MallocSi
   // worthwhile:
   // - mURLSpec
   //
   // The following members are not measured:
   // - mMedia, because it is measured via CSSStyleSheet::mMedia
   // - mChildSheet, because it is measured via CSSStyleSheetInner::mSheets
 }
 
-/* virtual */ JSObject*
-ImportRule::WrapObject(JSContext* aCx,
-                       JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSImportRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
   : Rule(aLineNumber, aColumnNumber)
 {
 }
 
 static bool
 SetParentRuleReference(Rule* aRule, void* aParentRule)
 {
@@ -394,32 +375,32 @@ GroupRule::~GroupRule()
 {
   MOZ_ASSERT(!mSheet, "SetStyleSheet should have been called");
   mRules.EnumerateForwards(SetParentRuleReference, nullptr);
   if (mRuleCollection) {
     mRuleCollection->DropReference();
   }
 }
 
-NS_IMPL_ADDREF_INHERITED(GroupRule, Rule)
-NS_IMPL_RELEASE_INHERITED(GroupRule, Rule)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(GroupRule)
-NS_INTERFACE_MAP_END_INHERITING(Rule)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(GroupRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(GroupRule)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(GroupRule)
+NS_INTERFACE_MAP_END
 
 static bool
 SetStyleSheetReference(Rule* aRule, void* aSheet)
 {
   aRule->SetStyleSheet(reinterpret_cast<StyleSheet*>(aSheet));
   return true;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(GroupRule)
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GroupRule, Rule)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(GroupRule)
   tmp->mRules.EnumerateForwards(SetParentRuleReference, nullptr);
   // If tmp does not have a stylesheet, neither do its descendants.  In that
   // case, don't try to null out their stylesheet, to avoid O(N^2) behavior in
   // depth of group rule nesting.  But if tmp _does_ have a stylesheet (which
   // can happen if it gets unlinked earlier than its owning stylesheet), then we
   // need to null out the stylesheet pointer on descendants now, before we clear
   // tmp->mRules.
   if (tmp->GetStyleSheet()) {
@@ -427,21 +408,21 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   }
   tmp->mRules.Clear();
   if (tmp->mRuleCollection) {
     tmp->mRuleCollection->DropReference();
     tmp->mRuleCollection = nullptr;
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GroupRule, Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(GroupRule)
   const nsCOMArray<Rule>& rules = tmp->mRules;
   for (int32_t i = 0, count = rules.Count(); i < count; ++i) {
     NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRules[i]");
-    cb.NoteXPCOMChild(rules[i]);
+    cb.NoteXPCOMChild(rules[i]->GetExistingDOMRule());
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleCollection)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 /* virtual */ void
 GroupRule::SetStyleSheet(StyleSheet* aSheet)
 {
   // Don't set the sheet on the kids if it's already the same as the sheet we
@@ -513,182 +494,130 @@ GroupRule::InsertStyleRuleAt(uint32_t aI
   aRule->SetParentRule(this);
   if (! mRules.InsertObjectAt(aRule, aIndex)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 void
-GroupRule::AppendRulesToCssText(nsAString& aCssText) const
+GroupRule::AppendRulesToCssText(nsAString& aCssText)
 {
   aCssText.AppendLiteral(" {\n");
 
   // get all the rules
   for (int32_t index = 0, count = mRules.Count(); index < count; ++index) {
     Rule* rule = mRules.ObjectAt(index);
-    nsAutoString cssText;
-    rule->GetCssText(cssText);
-    aCssText.AppendLiteral("  ");
-    aCssText.Append(cssText);
-    aCssText.Append('\n');
+    nsIDOMCSSRule* domRule = rule->GetDOMRule();
+    if (domRule) {
+      nsAutoString cssText;
+      domRule->GetCssText(cssText);
+      aCssText.AppendLiteral("  ");
+      aCssText.Append(cssText);
+      aCssText.Append('\n');
+    }
   }
 
   aCssText.Append('}');
 }
 
 // nsIDOMCSSMediaRule or nsIDOMCSSMozDocumentRule methods
 nsresult
 GroupRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
-  NS_ADDREF(*aRuleList = CssRules());
-  return NS_OK;
-}
-
-CSSRuleList*
-GroupRule::CssRules()
-{
   if (!mRuleCollection) {
     mRuleCollection = new css::GroupRuleRuleList(this);
   }
 
-  return mRuleCollection;
+  NS_ADDREF(*aRuleList = mRuleCollection);
+  return NS_OK;
 }
 
 nsresult
 GroupRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
 {
-  ErrorResult rv;
-  *_retval = InsertRule(aRule, aIndex, rv);
-  return rv.StealNSResult();
-}
-
-uint32_t
-GroupRule::InsertRule(const nsAString& aRule, uint32_t aIndex, ErrorResult& aRv)
-{
   StyleSheet* sheet = GetStyleSheet();
-  if (NS_WARN_IF(!sheet)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return 0;
-  }
-
-  if (aIndex > uint32_t(mRules.Count())) {
-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return 0;
-  }
+  NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
+  
+  if (aIndex > uint32_t(mRules.Count()))
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
   NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX,
                "Too many style rules!");
 
-  uint32_t retval;
-  nsresult rv =
-    sheet->AsGecko()->InsertRuleIntoGroup(aRule, this, aIndex, &retval);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-    return 0;
-  }
-  return retval;
+  return sheet->AsGecko()->InsertRuleIntoGroup(aRule, this, aIndex, _retval);
 }
 
 nsresult
 GroupRule::DeleteRule(uint32_t aIndex)
 {
-  ErrorResult rv;
-  DeleteRule(aIndex, rv);
-  return rv.StealNSResult();
-}
-
-void
-GroupRule::DeleteRule(uint32_t aIndex, ErrorResult& aRv)
-{
   StyleSheet* sheet = GetStyleSheet();
-  if (NS_WARN_IF(!sheet)) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-
-  if (aIndex >= uint32_t(mRules.Count())) {
-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return;
-  }
+  NS_ENSURE_TRUE(sheet, NS_ERROR_FAILURE);
+
+  if (aIndex >= uint32_t(mRules.Count()))
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
 
   NS_ASSERTION(uint32_t(mRules.Count()) <= INT32_MAX,
                "Too many style rules!");
 
-  nsresult rv = sheet->AsGecko()->DeleteRuleFromGroup(this, aIndex);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
+  return sheet->AsGecko()->DeleteRuleFromGroup(this, aIndex);
 }
 
 /* virtual */ size_t
 GroupRule::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = mRules.ShallowSizeOfExcludingThis(aMallocSizeOf);
   for (size_t i = 0; i < mRules.Length(); i++) {
     n += mRules[i]->SizeOfIncludingThis(aMallocSizeOf);
   }
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mRuleCollection
   return n;
 }
 
-ConditionRule::ConditionRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-  : GroupRule(aLineNumber, aColumnNumber)
-{
-}
-
-ConditionRule::ConditionRule(const ConditionRule& aCopy)
-  : GroupRule(aCopy)
-{
-}
-
-ConditionRule::~ConditionRule()
-{
-}
 
 // -------------------------------------------
 // nsICSSMediaRule
 //
 MediaRule::MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-  : ConditionRule(aLineNumber, aColumnNumber)
+  : GroupRule(aLineNumber, aColumnNumber)
 {
 }
 
 MediaRule::MediaRule(const MediaRule& aCopy)
-  : ConditionRule(aCopy)
+  : GroupRule(aCopy)
 {
   if (aCopy.mMedia) {
     mMedia = aCopy.mMedia->Clone();
     // XXXldb This doesn't really make sense.
     mMedia->SetStyleSheet(aCopy.GetStyleSheet());
   }
 }
 
 MediaRule::~MediaRule()
 {
   if (mMedia) {
     mMedia->SetStyleSheet(nullptr);
   }
 }
 
-NS_IMPL_ADDREF_INHERITED(MediaRule, ConditionRule)
-NS_IMPL_RELEASE_INHERITED(MediaRule, ConditionRule)
+NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule)
+NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule)
 
 // QueryInterface implementation for MediaRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaRule)
+NS_INTERFACE_MAP_BEGIN(MediaRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
-NS_INTERFACE_MAP_END_INHERITING(ConditionRule)
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(MediaRule, ConditionRule,
-                                   mMedia)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule)
+NS_INTERFACE_MAP_END_INHERITING(GroupRule)
 
 /* virtual */ void
 MediaRule::SetStyleSheet(StyleSheet* aSheet)
 {
   if (mMedia) {
     // Set to null so it knows it's leaving one sheet and joining another.
     mMedia->SetStyleSheet(nullptr);
     if (aSheet) {
@@ -743,36 +672,55 @@ nsresult
 MediaRule::SetMedia(nsMediaList* aMedia)
 {
   mMedia = aMedia;
   if (aMedia)
     mMedia->SetStyleSheet(GetStyleSheet());
   return NS_OK;
 }
 
-uint16_t
-MediaRule::Type() const
+// nsIDOMCSSRule methods
+NS_IMETHODIMP
+MediaRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::MEDIA_RULE;
+  *aType = nsIDOMCSSRule::MEDIA_RULE;
+  return NS_OK;
 }
 
-nsMediaList*
-MediaRule::Media() const
-{
-  // In practice, if we end up being parsed at all, we have non-null mMedia.  So
-  // it's OK to claim we don't return null here.
-  return mMedia;
-}
-
-void
-MediaRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+MediaRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@media ");
   AppendConditionText(aCssText);
   GroupRule::AppendRulesToCssText(aCssText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MediaRule::SetCssText(const nsAString& aCssText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MediaRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return GroupRule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return GroupRule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+MediaRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 // nsIDOMCSSGroupingRule methods
 NS_IMETHODIMP
 MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
   return GroupRule::GetCssRules(aRuleList);
 }
@@ -796,41 +744,27 @@ MediaRule::GetConditionText(nsAString& a
   aConditionText.Truncate(0);
   AppendConditionText(aConditionText);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MediaRule::SetConditionText(const nsAString& aConditionText)
 {
-  ErrorResult rv;
-  SetConditionText(aConditionText, rv);
-  return rv.StealNSResult();
-}
-
-void
-MediaRule::SetConditionText(const nsAString& aConditionText,
-                            ErrorResult& aRv)
-{
   if (!mMedia) {
     RefPtr<nsMediaList> media = new nsMediaList();
     media->SetStyleSheet(GetStyleSheet());
     nsresult rv = media->SetMediaText(aConditionText);
     if (NS_SUCCEEDED(rv)) {
       mMedia = media;
-    } else {
-      aRv.Throw(rv);
     }
-    return;
+    return rv;
   }
 
-  nsresult rv = mMedia->SetMediaText(aConditionText);
-  if (NS_FAILED(rv)) {
-    aRv.Throw(rv);
-  }
+  return mMedia->SetMediaText(aConditionText);
 }
 
 // nsIDOMCSSMediaRule methods
 NS_IMETHODIMP
 MediaRule::GetMedia(nsIDOMMediaList* *aMedia)
 {
   NS_ENSURE_ARG_POINTER(aMedia);
   NS_IF_ADDREF(*aMedia = mMedia);
@@ -856,57 +790,53 @@ MediaRule::SizeOfIncludingThis(MallocSiz
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mMedia
 
   return n;
 }
 
-/* virtual */ JSObject*
-MediaRule::WrapObject(JSContext* aCx,
-                      JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSMediaRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 void
-MediaRule::AppendConditionText(nsAString& aOutput) const
+MediaRule::AppendConditionText(nsAString& aOutput)
 {
   if (mMedia) {
     nsAutoString mediaText;
     mMedia->GetText(mediaText);
     aOutput.Append(mediaText);
   }
 }
 
 DocumentRule::DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-  : ConditionRule(aLineNumber, aColumnNumber)
+  : GroupRule(aLineNumber, aColumnNumber)
 {
 }
 
 DocumentRule::DocumentRule(const DocumentRule& aCopy)
-  : ConditionRule(aCopy)
+  : GroupRule(aCopy)
   , mURLs(new URL(*aCopy.mURLs))
 {
 }
 
 DocumentRule::~DocumentRule()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(DocumentRule, ConditionRule)
-NS_IMPL_RELEASE_INHERITED(DocumentRule, ConditionRule)
+NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule)
+NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule)
 
 // QueryInterface implementation for DocumentRule
 NS_INTERFACE_MAP_BEGIN(DocumentRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
-NS_INTERFACE_MAP_END_INHERITING(ConditionRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule)
+NS_INTERFACE_MAP_END_INHERITING(GroupRule)
 
 #ifdef DEBUG
 /* virtual */ void
 DocumentRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString indentStr;
   for (int32_t indent = aIndent; --indent >= 0; ) {
     indentStr.AppendLiteral("  ");
@@ -951,29 +881,56 @@ DocumentRule::GetType() const
 
 /* virtual */ already_AddRefed<Rule>
 DocumentRule::Clone() const
 {
   RefPtr<Rule> clone = new DocumentRule(*this);
   return clone.forget();
 }
 
-uint16_t
-DocumentRule::Type() const
+// nsIDOMCSSRule methods
+NS_IMETHODIMP
+DocumentRule::GetType(uint16_t* aType)
 {
   // XXX What should really happen here?
-  return nsIDOMCSSRule::UNKNOWN_RULE;
+  *aType = nsIDOMCSSRule::UNKNOWN_RULE;
+  return NS_OK;
 }
 
-void
-DocumentRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+DocumentRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@-moz-document ");
   AppendConditionText(aCssText);
   GroupRule::AppendRulesToCssText(aCssText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentRule::SetCssText(const nsAString& aCssText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+DocumentRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return GroupRule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return GroupRule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+DocumentRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 // nsIDOMCSSGroupingRule methods
 NS_IMETHODIMP
 DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
   return GroupRule::GetCssRules(aRuleList);
 }
@@ -1000,23 +957,16 @@ DocumentRule::GetConditionText(nsAString
 }
 
 NS_IMETHODIMP
 DocumentRule::SetConditionText(const nsAString& aConditionText)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-void
-DocumentRule::SetConditionText(const nsAString& aConditionText,
-                               ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
 // GroupRule interface
 /* virtual */ bool
 DocumentRule::UseForPresentation(nsPresContext* aPresContext,
                                  nsMediaQueryResultCacheKey& aKey)
 {
   return UseForPresentation(aPresContext);
 }
 
@@ -1082,25 +1032,18 @@ DocumentRule::SizeOfIncludingThis(Malloc
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mURLs
 
   return n;
 }
 
-/* virtual */ JSObject*
-DocumentRule::WrapObject(JSContext* aCx,
-                         JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSMozDocumentRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 void
-DocumentRule::AppendConditionText(nsAString& aCssText) const
+DocumentRule::AppendConditionText(nsAString& aCssText)
 {
   for (URL *url = mURLs; url; url = url->next) {
     switch (url->func) {
       case eURL:
         aCssText.AppendLiteral("url(");
         break;
       case eURLPrefix:
         aCssText.AppendLiteral("url-prefix(");
@@ -1137,28 +1080,33 @@ NameSpaceRule::NameSpaceRule(const NameS
     mURLSpec(aCopy.mURLSpec)
 {
 }
 
 NameSpaceRule::~NameSpaceRule()
 {
 }
 
-NS_IMPL_ADDREF_INHERITED(NameSpaceRule, Rule)
-NS_IMPL_RELEASE_INHERITED(NameSpaceRule, Rule)
+NS_IMPL_ADDREF(NameSpaceRule)
+NS_IMPL_RELEASE(NameSpaceRule)
 
 // QueryInterface implementation for NameSpaceRule
 NS_INTERFACE_MAP_BEGIN(NameSpaceRule)
   if (aIID.Equals(NS_GET_IID(css::NameSpaceRule))) {
     *aInstancePtr = this;
     NS_ADDREF_THIS();
     return NS_OK;
   }
   else
-NS_INTERFACE_MAP_END_INHERITING(Rule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSNameSpaceRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT(NameSpaceRule, Rule)
 
 #ifdef DEBUG
 /* virtual */ void
 NameSpaceRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t indent = aIndent; --indent >= 0; ) {
     str.AppendLiteral("  ");
@@ -1189,51 +1137,71 @@ NameSpaceRule::GetType() const
 
 /* virtual */ already_AddRefed<Rule>
 NameSpaceRule::Clone() const
 {
   RefPtr<Rule> clone = new NameSpaceRule(*this);
   return clone.forget();
 }
 
-uint16_t
-NameSpaceRule::Type() const
+NS_IMETHODIMP
+NameSpaceRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::NAMESPACE_RULE;
+  *aType = nsIDOMCSSRule::NAMESPACE_RULE;
+  return NS_OK;
 }
 
-void
-NameSpaceRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+NameSpaceRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@namespace ");
   if (mPrefix) {
     aCssText.Append(nsDependentAtomString(mPrefix) + NS_LITERAL_STRING(" "));
   }
   aCssText.AppendLiteral("url(");
   nsStyleUtil::AppendEscapedCSSString(mURLSpec, aCssText);
   aCssText.AppendLiteral(");");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+NameSpaceRule::SetCssText(const nsAString& aCssText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+NameSpaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return Rule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+NameSpaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+NameSpaceRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 /* virtual */ size_t
 NameSpaceRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mPrefix
   // - mURLSpec
 }
 
-/* virtual */ JSObject*
-NameSpaceRule::WrapObject(JSContext* aCx,
-                          JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSNamespaceRuleBinding::Wrap(aCx, this, aGivenProto);
-}
 
 } // namespace css
 } // namespace mozilla
 
 // -------------------------------------------
 // nsCSSFontFaceStyleDecl and related routines
 //
 
@@ -1356,23 +1324,16 @@ nsCSSFontFaceStyleDecl::GetPropertyValue
                 "out-of-range value got to the switch");
   return NS_ERROR_INVALID_ARG;
 }
 
 
 NS_IMETHODIMP
 nsCSSFontFaceStyleDecl::GetCssText(nsAString & aCssText)
 {
-  GetCssTextImpl(aCssText);
-  return NS_OK;
-}
-
-void
-nsCSSFontFaceStyleDecl::GetCssTextImpl(nsAString& aCssText) const
-{
   nsAutoString descStr;
 
   aCssText.Truncate();
   for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
        id < eCSSFontDesc_COUNT;
        id = nsCSSFontDesc(id + 1)) {
     if (mDescriptors.Get(id).GetUnit() != eCSSUnit_Null &&
         NS_SUCCEEDED(GetPropertyValue(id, descStr))) {
@@ -1380,16 +1341,17 @@ nsCSSFontFaceStyleDecl::GetCssTextImpl(n
                    "GetCssText: non-null unit, empty property value");
       aCssText.AppendLiteral("  ");
       aCssText.AppendASCII(nsCSSProps::GetStringValue(id).get());
       aCssText.AppendLiteral(": ");
       aCssText.Append(descStr);
       aCssText.AppendLiteral(";\n");
     }
   }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCSSFontFaceStyleDecl::SetCssText(const nsAString & aCssText)
 {
   return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
 }
 
@@ -1496,17 +1458,17 @@ nsCSSFontFaceStyleDecl::IndexedGetter(ui
     }
   }
   aFound = false;
 }
 
 NS_IMETHODIMP
 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
-  NS_IF_ADDREF(*aParentRule = ContainingRule());
+  NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCSSFontFaceStyleDecl::GetPropertyValue(const nsCSSPropertyID aPropID,
                                          nsAString& aValue)
 {
   return
@@ -1540,45 +1502,47 @@ nsCSSFontFaceStyleDecl::WrapObject(JSCon
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSFontFaceRule::Clone() const
 {
   RefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
   return clone.forget();
 }
 
-NS_IMPL_ADDREF_INHERITED(nsCSSFontFaceRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSFontFaceRule, mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSFontFaceRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSFontFaceRule)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSFontFaceRule)
 
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsCSSFontFaceRule,
-                                               mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsCSSFontFaceRule)
   // Trace the wrapper for our declaration.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecl.TraceWrapper(aCallbacks, aClosure);
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsCSSFontFaceRule,
-                                                mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSFontFaceRule)
   // Unlink the wrapper for our declaraton.  This just expands out
   // NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER which we can't use
   // directly because the wrapper is on the declaration, not on us.
   tmp->mDecl.ReleaseWrapper(static_cast<nsISupports*>(p));
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsCSSFontFaceRule,
-                                                  mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSFontFaceRule)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 // QueryInterface implementation for nsCSSFontFaceRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsCSSFontFaceRule)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSFontFaceRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFaceRule)
-NS_INTERFACE_MAP_END_INHERITING(Rule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFaceRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT(nsCSSFontFaceRule, Rule)
 
 #ifdef DEBUG
 void
 nsCSSFontFaceRule::List(FILE* out, int32_t aIndent) const
 {
   nsCString baseInd, descInd;
   for (int32_t indent = aIndent; --indent >= 0; ) {
     baseInd.AppendLiteral("  ");
@@ -1606,37 +1570,57 @@ nsCSSFontFaceRule::List(FILE* out, int32
 #endif
 
 /* virtual */ int32_t
 nsCSSFontFaceRule::GetType() const
 {
   return Rule::FONT_FACE_RULE;
 }
 
-uint16_t
-nsCSSFontFaceRule::Type() const
+NS_IMETHODIMP
+nsCSSFontFaceRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::FONT_FACE_RULE;
+  *aType = nsIDOMCSSRule::FONT_FACE_RULE;
+  return NS_OK;
 }
 
-void
-nsCSSFontFaceRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+nsCSSFontFaceRule::GetCssText(nsAString& aCssText)
 {
   nsAutoString propText;
-  mDecl.GetCssTextImpl(propText);
+  mDecl.GetCssText(propText);
 
   aCssText.AssignLiteral("@font-face {\n");
   aCssText.Append(propText);
   aCssText.Append('}');
+  return NS_OK;
 }
 
-nsICSSDeclaration*
-nsCSSFontFaceRule::Style()
+NS_IMETHODIMP
+nsCSSFontFaceRule::SetCssText(const nsAString& aCssText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED; // bug 443978
+}
+
+NS_IMETHODIMP
+nsCSSFontFaceRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
 {
-  return &mDecl;
+  return Rule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+nsCSSFontFaceRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+nsCSSFontFaceRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 NS_IMETHODIMP
 nsCSSFontFaceRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
 {
   NS_IF_ADDREF(*aStyle = &mDecl);
   return NS_OK;
 }
@@ -1669,41 +1653,40 @@ nsCSSFontFaceRule::SizeOfIncludingThis(M
 {
   return aMallocSizeOf(this);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mDecl
 }
 
-/* virtual */ JSObject*
-nsCSSFontFaceRule::WrapObject(JSContext* aCx,
-                              JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSFontFaceRuleBinding::Wrap(aCx, this, aGivenProto);
-}
 
 // -----------------------------------
 // nsCSSFontFeatureValuesRule
 //
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSFontFeatureValuesRule::Clone() const
 {
   RefPtr<css::Rule> clone = new nsCSSFontFeatureValuesRule(*this);
   return clone.forget();
 }
 
-NS_IMPL_ADDREF_INHERITED(nsCSSFontFeatureValuesRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSFontFeatureValuesRule, mozilla::css::Rule)
+NS_IMPL_ADDREF(nsCSSFontFeatureValuesRule)
+NS_IMPL_RELEASE(nsCSSFontFeatureValuesRule)
 
 // QueryInterface implementation for nsCSSFontFeatureValuesRule
 NS_INTERFACE_MAP_BEGIN(nsCSSFontFeatureValuesRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSFontFeatureValuesRule)
-NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSFontFeatureValuesRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT(nsCSSFontFeatureValuesRule, Rule)
 
 static void
 FeatureValuesToString(
   const nsTArray<gfxFontFeatureValueSet::FeatureValues>& aFeatureValues,
   nsAString& aOutStr)
 {
   uint32_t i, n;
 
@@ -1783,40 +1766,53 @@ nsCSSFontFeatureValuesRule::List(FILE* o
 #endif
 
 /* virtual */ int32_t
 nsCSSFontFeatureValuesRule::GetType() const
 {
   return Rule::FONT_FEATURE_VALUES_RULE;
 }
 
-uint16_t
-nsCSSFontFeatureValuesRule::Type() const
+NS_IMETHODIMP
+nsCSSFontFeatureValuesRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE;
+  *aType = nsIDOMCSSRule::FONT_FEATURE_VALUES_RULE;
+  return NS_OK;
 }
 
-void
-nsCSSFontFeatureValuesRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+nsCSSFontFeatureValuesRule::GetCssText(nsAString& aCssText)
 {
   FontFeatureValuesRuleToString(mFamilyList, mFeatureValues, aCssText);
+  return NS_OK;
 }
 
-void
-nsCSSFontFeatureValuesRule::SetFontFamily(const nsAString& aFamily,
-                                          ErrorResult& aRv)
+NS_IMETHODIMP
+nsCSSFontFeatureValuesRule::SetCssText(const nsAString& aCssText)
+{
+  // FIXME: implement???
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCSSFontFeatureValuesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
 {
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+  return Rule::GetParentStyleSheet(aSheet);
 }
 
-void
-nsCSSFontFeatureValuesRule::SetValueText(const nsAString& aFamily,
-                                         ErrorResult& aRv)
+NS_IMETHODIMP
+nsCSSFontFeatureValuesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+nsCSSFontFeatureValuesRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 NS_IMETHODIMP
 nsCSSFontFeatureValuesRule::GetFontFamily(nsAString& aFamilyListStr)
 {
   nsStyleUtil::AppendEscapedCSSFontFamilyList(mFamilyList, aFamilyListStr);
   return NS_OK;
 }
@@ -1897,23 +1893,16 @@ nsCSSFontFeatureValuesRule::AddValueList
 
 size_t
 nsCSSFontFeatureValuesRule::SizeOfIncludingThis(
   MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
-/* virtual */ JSObject*
-nsCSSFontFeatureValuesRule::WrapObject(JSContext* aCx,
-                                       JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSFontFeatureValuesRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 // -------------------------------------------
 // nsCSSKeyframeStyleDeclaration
 //
 
 nsCSSKeyframeStyleDeclaration::nsCSSKeyframeStyleDeclaration(nsCSSKeyframeRule *aRule)
   : mRule(aRule)
 {
 }
@@ -2000,37 +1989,40 @@ nsCSSKeyframeRule::~nsCSSKeyframeRule()
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSKeyframeRule::Clone() const
 {
   RefPtr<css::Rule> clone = new nsCSSKeyframeRule(*this);
   return clone.forget();
 }
 
-NS_IMPL_ADDREF_INHERITED(nsCSSKeyframeRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSKeyframeRule, mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSKeyframeRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSKeyframeRule)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSKeyframeRule)
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsCSSKeyframeRule,
-                                                mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSKeyframeRule)
   if (tmp->mDOMDeclaration) {
     tmp->mDOMDeclaration->DropReference();
     tmp->mDOMDeclaration = nullptr;
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsCSSKeyframeRule,
-                                                  mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSKeyframeRule)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 // QueryInterface implementation for nsCSSKeyframeRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsCSSKeyframeRule)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSKeyframeRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSKeyframeRule)
-NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSKeyframeRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSKeyframeRule, Rule)
 
 #ifdef DEBUG
 void
 nsCSSKeyframeRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t index = aIndent; --index >= 0; ) {
     str.AppendLiteral("  ");
@@ -2048,31 +2040,58 @@ nsCSSKeyframeRule::List(FILE* out, int32
 #endif
 
 /* virtual */ int32_t
 nsCSSKeyframeRule::GetType() const
 {
   return Rule::KEYFRAME_RULE;
 }
 
-uint16_t
-nsCSSKeyframeRule::Type() const
+NS_IMETHODIMP
+nsCSSKeyframeRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::KEYFRAME_RULE;
+  *aType = nsIDOMCSSRule::KEYFRAME_RULE;
+  return NS_OK;
 }
 
-void
-nsCSSKeyframeRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+nsCSSKeyframeRule::GetCssText(nsAString& aCssText)
 {
   DoGetKeyText(aCssText);
   aCssText.AppendLiteral(" { ");
   nsAutoString tmp;
   mDeclaration->ToString(tmp);
   aCssText.Append(tmp);
   aCssText.AppendLiteral(" }");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSKeyframeRule::SetCssText(const nsAString& aCssText)
+{
+  // FIXME: implement???
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCSSKeyframeRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return Rule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+nsCSSKeyframeRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+nsCSSKeyframeRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 NS_IMETHODIMP
 nsCSSKeyframeRule::GetKeyText(nsAString& aKeyText)
 {
   DoGetKeyText(aKeyText);
   return NS_OK;
 }
@@ -2118,27 +2137,21 @@ nsCSSKeyframeRule::SetKeyText(const nsAS
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCSSKeyframeRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
 {
-  NS_ADDREF(*aStyle = Style());
-  return NS_OK;
-}
-
-nsICSSDeclaration*
-nsCSSKeyframeRule::Style()
-{
   if (!mDOMDeclaration) {
     mDOMDeclaration = new nsCSSKeyframeStyleDeclaration(this);
   }
-  return mDOMDeclaration;
+  NS_ADDREF(*aStyle = mDOMDeclaration);
+  return NS_OK;
 }
 
 void
 nsCSSKeyframeRule::ChangeDeclaration(css::Declaration* aDeclaration)
 {
   // Our caller already did a BeginUpdate/EndUpdate, but with
   // UPDATE_CONTENT, and we need UPDATE_STYLE to trigger work in
   // PresShell::EndUpdate.
@@ -2166,22 +2179,16 @@ nsCSSKeyframeRule::SizeOfIncludingThis(M
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mKeys
   // - mDeclaration
   // - mDOMDeclaration
 }
 
-/* virtual */ JSObject*
-nsCSSKeyframeRule::WrapObject(JSContext* aCx,
-                              JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSKeyframeRuleBinding::Wrap(aCx, this, aGivenProto);
-}
 
 // -------------------------------------------
 // nsCSSKeyframesRule
 //
 
 nsCSSKeyframesRule::nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy)
   // copy everything except our reference count.  GroupRule's copy
   // constructor also doesn't copy the lazily-constructed
@@ -2202,17 +2209,20 @@ nsCSSKeyframesRule::Clone() const
   return clone.forget();
 }
 
 NS_IMPL_ADDREF_INHERITED(nsCSSKeyframesRule, css::GroupRule)
 NS_IMPL_RELEASE_INHERITED(nsCSSKeyframesRule, css::GroupRule)
 
 // QueryInterface implementation for nsCSSKeyframesRule
 NS_INTERFACE_MAP_BEGIN(nsCSSKeyframesRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSKeyframesRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSKeyframesRule)
 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
 
 #ifdef DEBUG
 void
 nsCSSKeyframesRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString indentStr;
   for (int32_t indent = aIndent; --indent >= 0; ) {
@@ -2229,35 +2239,62 @@ nsCSSKeyframesRule::List(FILE* out, int3
 #endif
 
 /* virtual */ int32_t
 nsCSSKeyframesRule::GetType() const
 {
   return Rule::KEYFRAMES_RULE;
 }
 
-uint16_t
-nsCSSKeyframesRule::Type() const
+NS_IMETHODIMP
+nsCSSKeyframesRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::KEYFRAMES_RULE;
+  *aType = nsIDOMCSSRule::KEYFRAMES_RULE;
+  return NS_OK;
 }
 
-void
-nsCSSKeyframesRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+nsCSSKeyframesRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@keyframes ");
   aCssText.Append(mName);
   aCssText.AppendLiteral(" {\n");
   nsAutoString tmp;
   for (uint32_t i = 0, i_end = mRules.Count(); i != i_end; ++i) {
     static_cast<nsCSSKeyframeRule*>(mRules[i])->GetCssText(tmp);
     aCssText.Append(tmp);
     aCssText.Append('\n');
   }
   aCssText.Append('}');
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSKeyframesRule::SetCssText(const nsAString& aCssText)
+{
+  // FIXME: implement???
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCSSKeyframesRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return GroupRule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+nsCSSKeyframesRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return GroupRule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+nsCSSKeyframesRule::GetCSSRule()
+{
+  return GroupRule::GetCSSRule();
 }
 
 NS_IMETHODIMP
 nsCSSKeyframesRule::GetName(nsAString& aName)
 {
   aName = mName;
   return NS_OK;
 }
@@ -2363,28 +2400,23 @@ nsCSSKeyframesRule::DeleteRule(const nsA
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCSSKeyframesRule::FindRule(const nsAString& aKey,
                              nsIDOMCSSKeyframeRule** aResult)
 {
-  NS_IF_ADDREF(*aResult = FindRule(aKey));
-  return NS_OK;
-}
-
-nsCSSKeyframeRule*
-nsCSSKeyframesRule::FindRule(const nsAString& aKey)
-{
   uint32_t index = FindRuleIndexForKey(aKey);
   if (index == RULE_NOT_FOUND) {
-    return nullptr;
+    *aResult = nullptr;
+  } else {
+    NS_ADDREF(*aResult = static_cast<nsCSSKeyframeRule*>(mRules[index]));
   }
-  return static_cast<nsCSSKeyframeRule*>(mRules[index]);
+  return NS_OK;
 }
 
 // GroupRule interface
 /* virtual */ bool
 nsCSSKeyframesRule::UseForPresentation(nsPresContext* aPresContext,
                                        nsMediaQueryResultCacheKey& aKey)
 {
   MOZ_ASSERT(false, "should not be called");
@@ -2399,23 +2431,16 @@ nsCSSKeyframesRule::SizeOfIncludingThis(
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mName
 
   return n;
 }
 
-/* virtual */ JSObject*
-nsCSSKeyframesRule::WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSKeyframesRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 // -------------------------------------------
 // nsCSSPageStyleDeclaration
 //
 
 nsCSSPageStyleDeclaration::nsCSSPageStyleDeclaration(nsCSSPageRule* aRule)
   : mRule(aRule)
 {
 }
@@ -2501,37 +2526,40 @@ nsCSSPageRule::~nsCSSPageRule()
 
 /* virtual */ already_AddRefed<css::Rule>
 nsCSSPageRule::Clone() const
 {
   RefPtr<css::Rule> clone = new nsCSSPageRule(*this);
   return clone.forget();
 }
 
-NS_IMPL_ADDREF_INHERITED(nsCSSPageRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSPageRule, mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCSSPageRule)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCSSPageRule)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsCSSPageRule)
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsCSSPageRule,
-                                                mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCSSPageRule)
   if (tmp->mDOMDeclaration) {
     tmp->mDOMDeclaration->DropReference();
     tmp->mDOMDeclaration = nullptr;
   }
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsCSSPageRule,
-                                                  mozilla::css::Rule)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCSSPageRule)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMDeclaration)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 // QueryInterface implementation for nsCSSPageRule
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsCSSPageRule)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCSSPageRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPageRule)
-NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSPageRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(nsCSSPageRule, Rule)
 
 #ifdef DEBUG
 void
 nsCSSPageRule::List(FILE* out, int32_t aIndent) const
 {
   nsAutoCString str;
   for (int32_t indent = aIndent; --indent >= 0; ) {
     str.AppendLiteral("  ");
@@ -2547,46 +2575,67 @@ nsCSSPageRule::List(FILE* out, int32_t a
 #endif
 
 /* virtual */ int32_t
 nsCSSPageRule::GetType() const
 {
   return Rule::PAGE_RULE;
 }
 
-uint16_t
-nsCSSPageRule::Type() const
+NS_IMETHODIMP
+nsCSSPageRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::PAGE_RULE;
+  *aType = nsIDOMCSSRule::PAGE_RULE;
+  return NS_OK;
 }
 
-void
-nsCSSPageRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+nsCSSPageRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AppendLiteral("@page { ");
   nsAutoString tmp;
   mDeclaration->ToString(tmp);
   aCssText.Append(tmp);
   aCssText.AppendLiteral(" }");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSPageRule::SetCssText(const nsAString& aCssText)
+{
+  // FIXME: implement???
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCSSPageRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return Rule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+nsCSSPageRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+nsCSSPageRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 NS_IMETHODIMP
 nsCSSPageRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
 {
-  NS_ADDREF(*aStyle = Style());
-  return NS_OK;
-}
-
-nsICSSDeclaration*
-nsCSSPageRule::Style()
-{
   if (!mDOMDeclaration) {
     mDOMDeclaration = new nsCSSPageStyleDeclaration(this);
   }
-  return mDOMDeclaration;
+  NS_ADDREF(*aStyle = mDOMDeclaration);
+  return NS_OK;
 }
 
 void
 nsCSSPageRule::ChangeDeclaration(css::Declaration* aDeclaration)
 {
   if (aDeclaration != mDeclaration) {
     mDeclaration->SetOwningRule(nullptr);
     mDeclaration = aDeclaration;
@@ -2599,40 +2648,33 @@ nsCSSPageRule::ChangeDeclaration(css::De
 }
 
 /* virtual */ size_t
 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
-/* virtual */ JSObject*
-nsCSSPageRule::WrapObject(JSContext* aCx,
-                          JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSPageRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 namespace mozilla {
 
 CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
                                  const nsString& aCondition,
                                  uint32_t aLineNumber, uint32_t aColumnNumber)
-  : css::ConditionRule(aLineNumber, aColumnNumber)
+  : css::GroupRule(aLineNumber, aColumnNumber)
   , mUseGroup(aConditionMet)
   , mCondition(aCondition)
 {
 }
 
 CSSSupportsRule::~CSSSupportsRule()
 {
 }
 
 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
-  : css::ConditionRule(aCopy),
+  : css::GroupRule(aCopy),
     mUseGroup(aCopy.mUseGroup),
     mCondition(aCopy.mCondition)
 {
 }
 
 #ifdef DEBUG
 /* virtual */ void
 CSSSupportsRule::List(FILE* out, int32_t aIndent) const
@@ -2666,38 +2708,68 @@ CSSSupportsRule::Clone() const
 
 /* virtual */ bool
 CSSSupportsRule::UseForPresentation(nsPresContext* aPresContext,
                                    nsMediaQueryResultCacheKey& aKey)
 {
   return mUseGroup;
 }
 
-NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::ConditionRule)
-NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::ConditionRule)
+NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::GroupRule)
+NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::GroupRule)
 
 // QueryInterface implementation for CSSSupportsRule
 NS_INTERFACE_MAP_BEGIN(CSSSupportsRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule)
-NS_INTERFACE_MAP_END_INHERITING(ConditionRule)
-
-uint16_t
-CSSSupportsRule::Type() const
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSSupportsRule)
+NS_INTERFACE_MAP_END_INHERITING(GroupRule)
+
+// nsIDOMCSSRule methods
+NS_IMETHODIMP
+CSSSupportsRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::SUPPORTS_RULE;
+  *aType = nsIDOMCSSRule::SUPPORTS_RULE;
+  return NS_OK;
 }
 
-void
-CSSSupportsRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+CSSSupportsRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@supports ");
   aCssText.Append(mCondition);
   css::GroupRule::AppendRulesToCssText(aCssText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+CSSSupportsRule::SetCssText(const nsAString& aCssText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+CSSSupportsRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return css::GroupRule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+CSSSupportsRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return css::GroupRule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+CSSSupportsRule::GetCSSRule()
+{
+  return css::GroupRule::GetCSSRule();
 }
 
 // nsIDOMCSSGroupingRule methods
 NS_IMETHODIMP
 CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
   return css::GroupRule::GetCssRules(aRuleList);
 }
@@ -2723,39 +2795,25 @@ CSSSupportsRule::GetConditionText(nsAStr
 }
 
 NS_IMETHODIMP
 CSSSupportsRule::SetConditionText(const nsAString& aConditionText)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-void
-CSSSupportsRule::SetConditionText(const nsAString& aConditionText,
-                                  ErrorResult& aRv)
-{
-  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
-}
-
 /* virtual */ size_t
 CSSSupportsRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
   n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
   n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
   return n;
 }
 
-/* virtual */ JSObject*
-CSSSupportsRule::WrapObject(JSContext* aCx,
-                            JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSSupportsRuleBinding::Wrap(aCx, this, aGivenProto);
-}
-
 } // namespace mozilla
 
 // -------------------------------------------
 // nsCSSCounterStyleRule
 //
 
 nsCSSCounterStyleRule::nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy)
   : Rule(aCopy)
@@ -2780,23 +2838,28 @@ nsCSSCounterStyleRule::Clone() const
 
 nsCSSCounterStyleRule::Getter const
 nsCSSCounterStyleRule::kGetters[] = {
 #define CSS_COUNTER_DESC(name_, method_) &nsCSSCounterStyleRule::Get##method_,
 #include "nsCSSCounterDescList.h"
 #undef CSS_COUNTER_DESC
 };
 
-NS_IMPL_ADDREF_INHERITED(nsCSSCounterStyleRule, mozilla::css::Rule)
-NS_IMPL_RELEASE_INHERITED(nsCSSCounterStyleRule, mozilla::css::Rule)
+NS_IMPL_ADDREF(nsCSSCounterStyleRule)
+NS_IMPL_RELEASE(nsCSSCounterStyleRule)
 
 // QueryInterface implementation for nsCSSCounterStyleRule
 NS_INTERFACE_MAP_BEGIN(nsCSSCounterStyleRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSCounterStyleRule)
-NS_INTERFACE_MAP_END_INHERITING(mozilla::css::Rule)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozilla::css::Rule)
+  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSCounterStyleRule)
+NS_INTERFACE_MAP_END
+
+IMPL_STYLE_RULE_INHERIT(nsCSSCounterStyleRule, css::Rule)
 
 #ifdef DEBUG
 void
 nsCSSCounterStyleRule::List(FILE* out, int32_t aIndent) const
 {
   nsCString baseInd, descInd;
   for (int32_t indent = aIndent; --indent >= 0; ) {
     baseInd.AppendLiteral("  ");
@@ -2813,45 +2876,70 @@ nsCSSCounterStyleRule::List(FILE* out, i
 #endif
 
 /* virtual */ int32_t
 nsCSSCounterStyleRule::GetType() const
 {
   return Rule::COUNTER_STYLE_RULE;
 }
 
-uint16_t
-nsCSSCounterStyleRule::Type() const
+// nsIDOMCSSRule methods
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetType(uint16_t* aType)
 {
-  return nsIDOMCSSRule::COUNTER_STYLE_RULE;
+  *aType = nsIDOMCSSRule::COUNTER_STYLE_RULE;
+  return NS_OK;
 }
 
-void
-nsCSSCounterStyleRule::GetCssTextImpl(nsAString& aCssText) const
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral(u"@counter-style ");
   nsStyleUtil::AppendEscapedCSSIdent(mName, aCssText);
   aCssText.AppendLiteral(u" {\n");
   for (nsCSSCounterDesc id = nsCSSCounterDesc(0);
        id < eCSSCounterDesc_COUNT;
        id = nsCSSCounterDesc(id + 1)) {
     if (mValues[id].GetUnit() != eCSSUnit_Null) {
       nsAutoString tmp;
-      // This is annoying.  We want to be a const method, but kGetters stores
-      // XPCOM method pointers, which aren't const methods.  The thing is,
-      // none of those mutate "this".  So it's OK to cast away const here.
-      (const_cast<nsCSSCounterStyleRule*>(this)->*kGetters[id])(tmp);
+      (this->*kGetters[id])(tmp);
       aCssText.AppendLiteral(u"  ");
       AppendASCIItoUTF16(nsCSSProps::GetStringValue(id), aCssText);
       aCssText.AppendLiteral(u": ");
       aCssText.Append(tmp);
       aCssText.AppendLiteral(u";\n");
     }
   }
   aCssText.AppendLiteral(u"}");
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::SetCssText(const nsAString& aCssText)
+{
+  // FIXME: implement???
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetParentStyleSheet(nsIDOMCSSStyleSheet** aSheet)
+{
+  return Rule::GetParentStyleSheet(aSheet);
+}
+
+NS_IMETHODIMP
+nsCSSCounterStyleRule::GetParentRule(nsIDOMCSSRule** aParentRule)
+{
+  return Rule::GetParentRule(aParentRule);
+}
+
+css::Rule*
+nsCSSCounterStyleRule::GetCSSRule()
+{
+  return Rule::GetCSSRule();
 }
 
 // nsIDOMCSSCounterStyleRule methods
 NS_IMETHODIMP
 nsCSSCounterStyleRule::GetName(nsAString& aName)
 {
   aName.Truncate();
   nsStyleUtil::AppendEscapedCSSIdent(mName, aName);
@@ -3176,15 +3264,8 @@ CSS_COUNTER_DESC_SETTER(Fallback)
 CSS_COUNTER_DESC_SETTER(SpeakAs)
 #undef CSS_COUNTER_DESC_SETTER
 
 /* virtual */ size_t
 nsCSSCounterStyleRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
-
-/* virtual */ JSObject*
-nsCSSCounterStyleRule::WrapObject(JSContext* aCx,
-                                  JS::Handle<JSObject*> aGivenProto)
-{
-  return CSSCounterStyleRuleBinding::Wrap(aCx, this, aGivenProto);
-}
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -38,98 +38,106 @@
 class nsMediaList;
 
 namespace mozilla {
 
 class ErrorResult;
 
 namespace css {
 
-class MediaRule final : public ConditionRule,
+class MediaRule final : public GroupRule,
                         public nsIDOMCSSMediaRule
 {
 public:
   MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   MediaRule(const MediaRule& aCopy);
   ~MediaRule();
 public:
 
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaRule, ConditionRule)
   NS_DECL_ISUPPORTS_INHERITED
 
   // Rule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual void SetStyleSheet(mozilla::StyleSheet* aSheet) override; //override GroupRule
   mozilla::CSSStyleSheet* GetStyleSheet() const
   {
     mozilla::StyleSheet* sheet = GroupRule::GetStyleSheet();
     return sheet ? sheet->AsGecko() : nullptr;
   }
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<Rule> Clone() const override;
+  virtual nsIDOMCSSRule* GetDOMRule() override
+  {
+    return this;
+  }
+  virtual nsIDOMCSSRule* GetExistingDOMRule() override
+  {
+    return this;
+  }
+
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSGroupingRule interface
   NS_DECL_NSIDOMCSSGROUPINGRULE
 
   // nsIDOMCSSConditionRule interface
   NS_DECL_NSIDOMCSSCONDITIONRULE
 
   // nsIDOMCSSMediaRule interface
   NS_DECL_NSIDOMCSSMEDIARULE
 
   // rest of GroupRule
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                     nsMediaQueryResultCacheKey& aKey) override;
 
   // @media rule methods
   nsresult SetMedia(nsMediaList* aMedia);
-
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // Our XPCOM GetConditionText is OK
-  virtual void SetConditionText(const nsAString& aConditionText,
-                                ErrorResult& aRv) override;
-  nsMediaList* Media() const;
   
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const override MOZ_MUST_OVERRIDE;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 protected:
-  void AppendConditionText(nsAString& aOutput) const;
+  void AppendConditionText(nsAString& aOutput);
 
   RefPtr<nsMediaList> mMedia;
 };
 
-class DocumentRule final : public ConditionRule,
+class DocumentRule final : public GroupRule,
                            public nsIDOMCSSMozDocumentRule
 {
 public:
   DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   DocumentRule(const DocumentRule& aCopy);
   ~DocumentRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Rule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<Rule> Clone() const override;
+  virtual nsIDOMCSSRule* GetDOMRule() override
+  {
+    return this;
+  }
+  virtual nsIDOMCSSRule* GetExistingDOMRule() override
+  {
+    return this;
+  }
+
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSGroupingRule interface
   NS_DECL_NSIDOMCSSGROUPINGRULE
 
   // nsIDOMCSSConditionRule interface
   NS_DECL_NSIDOMCSSCONDITIONRULE
 
   // nsIDOMCSSMozDocumentRule interface
@@ -160,31 +168,21 @@ public:
       , next(aOther.next ? new URL(*aOther.next) : nullptr)
     {
     }
     ~URL();
   };
 
   void SetURLs(URL *aURLs) { mURLs = aURLs; }
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // Our XPCOM GetConditionText is OK
-  virtual void SetConditionText(const nsAString& aConditionText,
-                                ErrorResult& aRv) override;
-
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
     const override MOZ_MUST_OVERRIDE;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 protected:
-  void AppendConditionText(nsAString& aOutput) const;
+  void AppendConditionText(nsAString& aOutput);
 
   nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
 };
 
 } // namespace css
 
 struct CSSFontFaceDescriptors
 {
@@ -227,68 +225,57 @@ protected:
 
   friend class nsCSSFontFaceRule;
 
   inline nsCSSFontFaceRule* ContainingRule();
   inline const nsCSSFontFaceRule* ContainingRule() const;
 
   mozilla::CSSFontFaceDescriptors mDescriptors;
 
-  // The actual implementation of GetCssText, so we can make it const.
-  void GetCssTextImpl(nsAString& aCssText) const;
-
 private:
   // NOT TO BE IMPLEMENTED
   // This object cannot be allocated on its own, only as part of
   // nsCSSFontFaceRule.
   void* operator new(size_t size) CPP_THROW_NEW;
 };
 
 class nsCSSFontFaceRule final : public mozilla::css::Rule,
                                 public nsIDOMCSSFontFaceRule
 {
 public:
   nsCSSFontFaceRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::css::Rule(aLineNumber, aColumnNumber)
-  {
-  }
+    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
 
   nsCSSFontFaceRule(const nsCSSFontFaceRule& aCopy)
     // copy everything except our reference count
-    : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl)
-  {
-  }
+    : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsCSSFontFaceRule,
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSFontFaceRule,
                                                          mozilla::css::Rule)
 
+  // Rule methods
+  DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
+
   // nsIDOMCSSFontFaceRule interface
   NS_DECL_NSIDOMCSSFONTFACERULE
 
   void SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue);
   void GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue);
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  nsICSSDeclaration* Style();
-
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
   void GetDescriptors(mozilla::CSSFontFaceDescriptors& aDescriptors) const
     { aDescriptors = mDecl.mDescriptors; }
 
 protected:
   ~nsCSSFontFaceRule() {}
 
   friend class nsCSSFontFaceStyleDecl;
   nsCSSFontFaceStyleDecl mDecl;
@@ -315,64 +302,53 @@ nsCSSFontFaceStyleDecl::ContainingRule()
     (reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
 }
 
 class nsCSSFontFeatureValuesRule final : public mozilla::css::Rule,
                                          public nsIDOMCSSFontFeatureValuesRule
 {
 public:
   nsCSSFontFeatureValuesRule(uint32_t aLineNumber, uint32_t aColumnNumber)
-    : mozilla::css::Rule(aLineNumber, aColumnNumber)
-  {
-  }
+    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
 
   nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy),
       mFamilyList(aCopy.mFamilyList),
-      mFeatureValues(aCopy.mFeatureValues)
-  {
-  }
+      mFeatureValues(aCopy.mFeatureValues) {}
 
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_ISUPPORTS
 
+  // Rule methods
+  DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
+
   // nsIDOMCSSFontFaceRule interface
   NS_DECL_NSIDOMCSSFONTFEATUREVALUESRULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // The XPCOM GetFontFamily is fine
-  void SetFontFamily(const nsAString& aFamily, mozilla::ErrorResult& aRv);
-  // The XPCOM GetValueText is fine
-  void SetValueText(const nsAString& aFamily, mozilla::ErrorResult& aRv);
-
   const mozilla::FontFamilyList& GetFamilyList() { return mFamilyList; }
   void SetFamilyList(const mozilla::FontFamilyList& aFamilyList);
 
   void AddValueList(int32_t aVariantAlternate,
                     nsTArray<gfxFontFeatureValueSet::ValueList>& aValueList);
 
   const nsTArray<gfxFontFeatureValueSet::FeatureValues>& GetFeatureValues()
   {
     return mFeatureValues;
   }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 protected:
   ~nsCSSFontFeatureValuesRule() {}
 
   mozilla::FontFamilyList mFamilyList;
   nsTArray<gfxFontFeatureValueSet::FeatureValues> mFeatureValues;
 };
 
 class nsCSSKeyframeRule;
@@ -416,46 +392,40 @@ public:
     , mDeclaration(mozilla::Move(aDeclaration))
   {
     mDeclaration->SetOwningRule(this);
   }
 private:
   nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
   ~nsCSSKeyframeRule();
 public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsCSSKeyframeRule, mozilla::css::Rule)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSKeyframeRule, mozilla::css::Rule)
 
+  // Rule methods
+  DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
+
   // nsIDOMCSSKeyframeRule interface
   NS_DECL_NSIDOMCSSKEYFRAMERULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // The XPCOM GetKeyText is fine.
-  // The XPCOM SetKeyText is fine.
-  nsICSSDeclaration* Style();
-
   const nsTArray<float>& GetKeys() const     { return mKeys; }
   mozilla::css::Declaration* Declaration()   { return mDeclaration; }
 
   void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
   void DoGetKeyText(nsAString &aKeyText) const;
 
 private:
   nsTArray<float>                            mKeys;
   RefPtr<mozilla::css::Declaration>          mDeclaration;
   // lazily created when needed:
   RefPtr<nsCSSKeyframeStyleDeclaration>    mDOMDeclaration;
 };
@@ -476,43 +446,40 @@ private:
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // Rule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
+  virtual nsIDOMCSSRule* GetDOMRule() override
+  {
+    return this;
+  }
+  virtual nsIDOMCSSRule* GetExistingDOMRule() override
+  {
+    return this;
+  }
+
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
 
   // nsIDOMCSSKeyframesRule interface
   NS_DECL_NSIDOMCSSKEYFRAMESRULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // The XPCOM GetName is OK
-  // The XPCOM SetName is OK
-  using mozilla::css::GroupRule::CssRules;
-  // The XPCOM appendRule is OK, since it never throws
-  // The XPCOM deleteRule is OK, since it never throws
-  nsCSSKeyframeRule* FindRule(const nsAString& aKey);
-
   // rest of GroupRule
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                     nsMediaQueryResultCacheKey& aKey) override;
 
   const nsString& GetName() { return mName; }
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 private:
   uint32_t FindRuleIndexForKey(const nsAString& aKey);
 
   nsString                                   mName;
 };
 
 class nsCSSPageRule;
 
@@ -552,92 +519,87 @@ public:
     , mDeclaration(aDeclaration)
   {
     mDeclaration->SetOwningRule(this);
   }
 private:
   nsCSSPageRule(const nsCSSPageRule& aCopy);
   ~nsCSSPageRule();
 public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsCSSPageRule, mozilla::css::Rule)
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSPageRule, nsIDOMCSSPageRule)
 
+  // Rule methods
+  DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
+
   // nsIDOMCSSPageRule interface
   NS_DECL_NSIDOMCSSPAGERULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  nsICSSDeclaration* Style();
-
   mozilla::css::Declaration* Declaration()   { return mDeclaration; }
 
   void ChangeDeclaration(mozilla::css::Declaration* aDeclaration);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
-
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 private:
   RefPtr<mozilla::css::Declaration>     mDeclaration;
   // lazily created when needed:
   RefPtr<nsCSSPageStyleDeclaration>     mDOMDeclaration;
 };
 
 namespace mozilla {
 
-class CSSSupportsRule final : public css::ConditionRule,
-                              public nsIDOMCSSSupportsRule
+class CSSSupportsRule : public css::GroupRule,
+                        public nsIDOMCSSSupportsRule
 {
 public:
   CSSSupportsRule(bool aConditionMet, const nsString& aCondition,
                   uint32_t aLineNumber, uint32_t aColumnNumber);
   CSSSupportsRule(const CSSSupportsRule& aCopy);
 
   // Rule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                   nsMediaQueryResultCacheKey& aKey) override;
+  virtual nsIDOMCSSRule* GetDOMRule() override
+  {
+    return this;
+  }
+  virtual nsIDOMCSSRule* GetExistingDOMRule() override
+  {
+    return this;
+  }
 
   NS_DECL_ISUPPORTS_INHERITED
 
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
+
   // nsIDOMCSSGroupingRule interface
   NS_DECL_NSIDOMCSSGROUPINGRULE
 
   // nsIDOMCSSConditionRule interface
   NS_DECL_NSIDOMCSSCONDITIONRULE
 
   // nsIDOMCSSSupportsRule interface
   NS_DECL_NSIDOMCSSSUPPORTSRULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // Our XPCOM GetConditionText is OK
-  virtual void SetConditionText(const nsAString& aConditionText,
-                                ErrorResult& aRv) override;
-
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 protected:
   virtual ~CSSSupportsRule();
 
   bool mUseGroup;
   nsString mCondition;
 };
 
 } // namespace mozilla
@@ -654,54 +616,32 @@ public:
   {
   }
 
 private:
   nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy);
   ~nsCSSCounterStyleRule();
 
 public:
-  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_ISUPPORTS
 
+  // Rule methods
+  DECL_STYLE_RULE_INHERIT
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override;
 #endif
   virtual int32_t GetType() const override;
-  using Rule::GetType;
   virtual already_AddRefed<mozilla::css::Rule> Clone() const override;
 
+  // nsIDOMCSSRule interface
+  NS_DECL_NSIDOMCSSRULE
+
   // nsIDOMCSSCounterStyleRule
   NS_DECL_NSIDOMCSSCOUNTERSTYLERULE
 
-  // WebIDL interface
-  uint16_t Type() const override;
-  void GetCssTextImpl(nsAString& aCssText) const override;
-  // The XPCOM GetName is OK
-  // The XPCOM SetName is OK
-  // The XPCOM GetSystem is OK
-  // The XPCOM SetSystem is OK
-  // The XPCOM GetSymbols is OK
-  // The XPCOM SetSymbols is OK
-  // The XPCOM GetAdditiveSymbols is OK
-  // The XPCOM SetAdditiveSymbols is OK
-  // The XPCOM GetNegative is OK
-  // The XPCOM SetNegative is OK
-  // The XPCOM GetPrefix is OK
-  // The XPCOM SetPrefix is OK
-  // The XPCOM GetSuffix is OK
-  // The XPCOM SetSuffix is OK
-  // The XPCOM GetRange is OK
-  // The XPCOM SetRange is OK
-  // The XPCOM GetPad is OK
-  // The XPCOM SetPad is OK
-  // The XPCOM GetSpeakAs is OK
-  // The XPCOM SetSpeakAs is OK
-  // The XPCOM GetFallback is OK
-  // The XPCOM SetFallback is OK
-
   // This function is only used to check whether a non-empty value, which has
   // been accepted by parser, is valid for the given system and descriptor.
   static bool CheckDescValue(int32_t aSystem,
                              nsCSSCounterDesc aDescID,
                              const nsCSSValue& aValue);
 
   const nsString& GetName() const { return mName; }
 
@@ -716,19 +656,16 @@ public:
                "descriptor ID out of range");
     return mValues[aDescID];
   }
 
   void SetDesc(nsCSSCounterDesc aDescID, const nsCSSValue& aValue);
 
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
 
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aGivenProto) override;
-
 private:
   typedef NS_STDCALL_FUNCPROTO(nsresult, Getter, nsCSSCounterStyleRule,
                                GetSymbols, (nsAString&));
   static const Getter kGetters[];
 
   nsresult GetDescriptor(nsCSSCounterDesc aDescID, nsAString& aValue);
   nsresult SetDescriptor(nsCSSCounterDesc aDescID, const nsAString& aValue);
 
--- a/layout/style/nsICSSStyleRuleDOMWrapper.h
+++ b/layout/style/nsICSSStyleRuleDOMWrapper.h
@@ -13,21 +13,16 @@
 
 #include "nsIDOMCSSStyleRule.h"
 
 // IID for the nsICSSStyleRuleDOMWrapper interface
 // {cee1bbb6-0a32-4cf3-8d42-ba3938e9ecaa}
 #define NS_ICSS_STYLE_RULE_DOM_WRAPPER_IID \
 {0xcee1bbb6, 0x0a32, 0x4cf3, {0x8d, 0x42, 0xba, 0x39, 0x38, 0xe9, 0xec, 0xaa}}
 
-namespace mozilla {
-namespace css {
-class StyleRule;
-} // namespace css
-} // namespace mozilla
 
 class nsICSSStyleRuleDOMWrapper : public nsIDOMCSSStyleRule {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSS_STYLE_RULE_DOM_WRAPPER_IID)
 
   NS_IMETHOD GetCSSStyleRule(mozilla::css::StyleRule** aResult) = 0;
 };