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 460794 e8b32aaa2eec84c15f44cfd677142a0047481152
parent 460750 7a82c1099a05d9dfa32a3d04ab79db22b29a31ba
child 460795 9aaaf2c863db85a520103530f597543817f016c3
child 460805 83b1e97f352a360bd39442635ca0a963cc415ce0
push id41495
push usercatlee@mozilla.com
push dateFri, 13 Jan 2017 20:48:44 +0000
bugs851892
milestone53.0a1
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;
 };