Bug 1315601 part 3 - Add base class MediaList and move part of nsMediaList to it. r=heycam draft
authorXidorn Quan <me@upsuper.org>
Wed, 09 Nov 2016 17:28:24 +1100
changeset 497326 40a9171307b6a30288169e27caa43595349d2df7
parent 497325 e7cbb83a6e205e6359e5a81ade6996a3b6a1cdd4
child 497327 cfa00f45b4ff00857956cad9094a68a22149a692
push id48868
push userxquan@mozilla.com
push dateMon, 13 Mar 2017 06:44:26 +0000
reviewersheycam
bugs1315601
milestone55.0a1
Bug 1315601 part 3 - Add base class MediaList and move part of nsMediaList to it. r=heycam MozReview-Commit-ID: A2uJpbGgO55
dom/bindings/Bindings.conf
layout/style/CSSStyleSheet.cpp
layout/style/ImportRule.h
layout/style/MediaList.cpp
layout/style/MediaList.h
layout/style/StyleSheet.cpp
layout/style/StyleSheet.h
layout/style/moz.build
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsMediaList.cpp
layout/style/nsMediaList.h
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -610,20 +610,16 @@ DOMInterfaces = {
     'wrapperCache': False,
 },
 
 'LocalMediaStream': {
     'headerFile': 'DOMMediaStream.h',
     'nativeType': 'mozilla::DOMLocalMediaStream'
 },
 
-'MediaList': {
-    'nativeType': 'nsMediaList',
-},
-
 'MediaKeys' : {
     'implicitJSContext': [ 'createSession']
 },
 
 'MediaStream': {
     'headerFile': 'DOMMediaStream.h',
     'nativeType': 'mozilla::DOMMediaStream'
 },
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -508,17 +508,18 @@ CSSStyleSheet::DropStyleSet(nsStyleSet* 
   NS_ASSERTION(found, "didn't find style set");
 }
 
 bool
 CSSStyleSheet::UseForPresentation(nsPresContext* aPresContext,
                                   nsMediaQueryResultCacheKey& aKey) const
 {
   if (mMedia) {
-    return mMedia->Matches(aPresContext, &aKey);
+    auto media = static_cast<nsMediaList*>(mMedia.get());
+    return media->Matches(aPresContext, &aKey);
   }
   return true;
 }
 
 
 bool
 CSSStyleSheet::HasRules() const
 {
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -17,16 +17,20 @@
 class nsMediaList;
 class nsString;
 
 namespace mozilla {
 
 class CSSStyleSheet;
 class StyleSheet;
 
+namespace dom {
+class MediaList;
+}
+
 namespace css {
 
 class ImportRule final : public Rule,
                          public nsIDOMCSSImportRule
 {
 public:
   ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
              uint32_t aLineNumber, uint32_t aColumnNumber);
@@ -58,17 +62,17 @@ public:
 
   // 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; }
+  dom::MediaList* Media() const;
   StyleSheet* GetStyleSheet() const;
 
 private:
   nsString  mURLSpec;
   RefPtr<nsMediaList> mMedia;
   RefPtr<CSSStyleSheet> mChildSheet;
 };
 
new file mode 100644
--- /dev/null
+++ b/layout/style/MediaList.cpp
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* base class for representation of media lists */
+
+#include "mozilla/dom/MediaList.h"
+
+#include "mozAutoDocUpdate.h"
+#include "mozilla/dom/MediaListBinding.h"
+#include "mozilla/StyleSheetInlines.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaList)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList)
+  NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaList)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaList)
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(MediaList)
+
+JSObject*
+MediaList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return MediaListBinding::Wrap(aCx, this, aGivenProto);
+}
+
+void
+MediaList::SetStyleSheet(StyleSheet* aSheet)
+{
+  MOZ_ASSERT(aSheet == mStyleSheet || !aSheet || !mStyleSheet,
+             "Multiple style sheets competing for one media list");
+  mStyleSheet = aSheet;
+}
+
+template<typename Func>
+nsresult
+MediaList::DoMediaChange(Func aCallback)
+{
+  nsCOMPtr<nsIDocument> doc;
+  if (mStyleSheet) {
+    doc = mStyleSheet->GetAssociatedDocument();
+  }
+  mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
+  if (mStyleSheet) {
+    mStyleSheet->WillDirty();
+  }
+
+  nsresult rv = aCallback();
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  if (mStyleSheet) {
+    mStyleSheet->DidDirty();
+  }
+  /* XXXldb Pass something meaningful? */
+  if (doc) {
+    doc->StyleRuleChanged(mStyleSheet, nullptr);
+  }
+  return rv;
+}
+
+NS_IMETHODIMP
+MediaList::GetMediaText(nsAString& aMediaText)
+{
+  GetText(aMediaText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MediaList::SetMediaText(const nsAString& aMediaText)
+{
+  return DoMediaChange([&]() {
+    SetText(aMediaText);
+    return NS_OK;
+  });
+}
+
+NS_IMETHODIMP
+MediaList::GetLength(uint32_t* aLength)
+{
+  NS_ENSURE_ARG_POINTER(aLength);
+
+  *aLength = Length();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MediaList::Item(uint32_t aIndex, nsAString& aReturn)
+{
+  bool dummy;
+  IndexedGetter(aIndex, dummy, aReturn);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MediaList::DeleteMedium(const nsAString& aOldMedium)
+{
+  return DoMediaChange([&]() { return Delete(aOldMedium); });
+}
+
+NS_IMETHODIMP
+MediaList::AppendMedium(const nsAString& aNewMedium)
+{
+  return DoMediaChange([&]() { return Append(aNewMedium); });
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/layout/style/MediaList.h
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* base class for representation of media lists */
+
+#ifndef mozilla_dom_MediaList_h
+#define mozilla_dom_MediaList_h
+
+#include "mozilla/ErrorResult.h"
+#include "mozilla/ServoUtils.h"
+
+#include "nsIDOMMediaList.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+class StyleSheet;
+
+namespace dom {
+
+// XXX This class doesn't use the branch dispatch approach that we use
+//     elsewhere for stylo, but instead just relies on virtual call.
+//     That's because this class should not be critical to performance,
+//     and using branch dispatch would make it much more complicated.
+//     Performance critical path should hold a subclass of this class
+//     directly. We may want to determine in the future whether the
+//     above is correct.
+
+class MediaList : public nsIDOMMediaList
+                , public nsWrapperCache
+{
+public:
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaList)
+
+  virtual already_AddRefed<MediaList> Clone() = 0;
+
+  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
+  nsISupports* GetParentObject() const { return nullptr; }
+
+  virtual void GetText(nsAString& aMediaText) = 0;
+  virtual void SetText(const nsAString& aMediaText) = 0;
+
+  void SetStyleSheet(StyleSheet* aSheet);
+
+  NS_DECL_NSIDOMMEDIALIST
+
+  // WebIDL
+  // XPCOM GetMediaText and SetMediaText are fine.
+  virtual uint32_t Length() = 0;
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound,
+                             nsAString& aReturn) = 0;
+  // XPCOM Item is fine.
+  void DeleteMedium(const nsAString& aMedium, ErrorResult& aRv)
+  {
+    aRv = DeleteMedium(aMedium);
+  }
+  void AppendMedium(const nsAString& aMedium, ErrorResult& aRv)
+  {
+    aRv = AppendMedium(aMedium);
+  }
+
+protected:
+  virtual nsresult Delete(const nsAString& aOldMedium) = 0;
+  virtual nsresult Append(const nsAString& aNewMedium) = 0;
+
+  virtual ~MediaList() {}
+
+  // not refcounted; sheet will let us know when it goes away
+  // mStyleSheet is the sheet that needs to be dirtied when this
+  // medialist changes
+  StyleSheet* mStyleSheet = nullptr;
+
+private:
+  template<typename Func>
+  inline nsresult DoMediaChange(Func aCallback);
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MediaList_h
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/StyleSheet.h"
 
 #include "mozilla/dom/CSSRuleList.h"
+#include "mozilla/dom/MediaList.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/ServoStyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 #include "mozilla/CSSStyleSheet.h"
 
 #include "mozAutoDocUpdate.h"
 #include "nsMediaList.h"
 #include "nsNullPrincipal.h"
@@ -603,31 +604,31 @@ StyleSheet::List(FILE* out, int32_t aInd
        child;
        child = child->mNext) {
     child->List(out, aIndent + 1);
   }
 }
 #endif
 
 void
-StyleSheet::SetMedia(nsMediaList* aMedia)
+StyleSheet::SetMedia(dom::MediaList* aMedia)
 {
   mMedia = aMedia;
 }
 
 void
 StyleSheet::DropMedia()
 {
   if (mMedia) {
     mMedia->SetStyleSheet(nullptr);
     mMedia = nullptr;
   }
 }
 
-nsMediaList*
+dom::MediaList*
 StyleSheet::Media()
 {
   if (!mMedia) {
     mMedia = new nsMediaList();
     mMedia->SetStyleSheet(this);
   }
 
   return mMedia;
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -15,28 +15,28 @@
 #include "mozilla/ServoUtils.h"
 
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsWrapperCache.h"
 
 class nsIDocument;
 class nsINode;
 class nsIPrincipal;
-class nsMediaList;
 class nsCSSRuleProcessor;
 
 namespace mozilla {
 
 class CSSStyleSheet;
 class ServoStyleSheet;
 struct StyleSheetInfo;
 struct CSSStyleSheetInner;
 
 namespace dom {
 class CSSRuleList;
+class MediaList;
 class SRIMetadata;
 } // namespace dom
 
 namespace css {
 class ImportRule;
 class Rule;
 }
 
@@ -145,17 +145,17 @@ public:
   /**
    * SetPrincipal should be called on all sheets before parsing into them.
    * This can only be called once with a non-null principal.  Calling this with
    * a null pointer is allowed and is treated as a no-op.
    */
   inline void SetPrincipal(nsIPrincipal* aPrincipal);
 
   void SetTitle(const nsAString& aTitle) { mTitle = aTitle; }
-  void SetMedia(nsMediaList* aMedia);
+  void SetMedia(dom::MediaList* aMedia);
 
   // Get this style sheet's CORS mode
   inline CORSMode GetCORSMode() const;
   // Get this style sheet's Referrer Policy
   inline net::ReferrerPolicy GetReferrerPolicy() const;
   // Get this style sheet's integrity metadata
   inline void GetIntegrity(dom::SRIMetadata& aResult) const;
 
@@ -165,17 +165,17 @@ public:
 #endif
 
   // WebIDL StyleSheet API
   // The XPCOM GetType is fine for WebIDL.
   // The XPCOM GetHref is fine for WebIDL
   // GetOwnerNode is defined above.
   inline StyleSheet* GetParentStyleSheet() const;
   // The XPCOM GetTitle is fine for WebIDL.
-  nsMediaList* Media();
+  dom::MediaList* Media();
   bool Disabled() const { return mDisabled; }
   // The XPCOM SetDisabled is fine for WebIDL.
 
   // WebIDL CSSStyleSheet API
   virtual css::Rule* GetDOMOwnerRule() const = 0;
   dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal,
                                 ErrorResult& aRv);
   uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
@@ -257,17 +257,17 @@ protected:
   virtual void TraverseInner(nsCycleCollectionTraversalCallback &);
 
   StyleSheet*           mParent;    // weak ref
 
   nsString              mTitle;
   nsIDocument*          mDocument; // weak ref; parents maintain this for their children
   nsINode*              mOwningNode; // weak ref
 
-  RefPtr<nsMediaList> mMedia;
+  RefPtr<dom::MediaList> mMedia;
 
   RefPtr<StyleSheet> mNext;
 
   // mParsingMode controls access to nonstandard style constructs that
   // are not safe for use on the public Web but necessary in UA sheets
   // and/or useful in user sheets.
   css::SheetParsingMode mParsingMode;
 
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -125,16 +125,17 @@ EXPORTS.mozilla += [
 EXPORTS.mozilla.dom += [
     'CSS.h',
     'CSSLexer.h',
     'CSSRuleList.h',
     'CSSValue.h',
     'FontFace.h',
     'FontFaceSet.h',
     'FontFaceSetIterator.h',
+    'MediaList.h',
     'MediaQueryList.h',
 ]
 
 EXPORTS.mozilla.css += [
     'Declaration.h',
     'ErrorReporter.h',
     'GroupRule.h',
     'ImageLoader.h',
@@ -162,16 +163,17 @@ UNIFIED_SOURCES += [
     'ErrorReporter.cpp',
     'FontFace.cpp',
     'FontFaceSet.cpp',
     'FontFaceSetIterator.cpp',
     'ImageLoader.cpp',
     'IncrementalClearCOMRuleArray.cpp',
     'LayerAnimationInfo.cpp',
     'Loader.cpp',
+    'MediaList.cpp',
     'MediaQueryList.cpp',
     'nsAnimationManager.cpp',
     'nsComputedDOMStyle.cpp',
     'nsCSSAnonBoxes.cpp',
     'nsCSSDataBlock.cpp',
     'nsCSSKeywords.cpp',
     'nsCSSParser.cpp',
     'nsCSSProps.cpp',
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -343,17 +343,17 @@ ImportRule::SetSheet(CSSStyleSheet* aShe
 {
   NS_PRECONDITION(aSheet, "null arg");
 
   // set the new sheet
   mChildSheet = aSheet;
   aSheet->SetOwnerRule(this);
 
   // set our medialist to be the same as the sheet's medialist
-  mMedia = mChildSheet->Media();
+  mMedia = static_cast<nsMediaList*>(mChildSheet->Media());
 }
 
 uint16_t
 ImportRule::Type() const
 {
   return nsIDOMCSSRule::IMPORT_RULE;
 }
 
@@ -369,16 +369,22 @@ ImportRule::GetCssTextImpl(nsAString& aC
     if (!mediaText.IsEmpty()) {
       aCssText.Append(' ');
       aCssText.Append(mediaText);
     }
   }
   aCssText.Append(';');
 }
 
+MediaList*
+ImportRule::Media() const
+{
+  return mMedia;
+}
+
 StyleSheet*
 ImportRule::GetStyleSheet() const
 {
   return mChildSheet;
 }
 
 NS_IMETHODIMP
 ImportRule::GetHref(nsAString & aHref)
@@ -719,17 +725,17 @@ MediaRule::MediaRule(uint32_t aLineNumbe
   : ConditionRule(aLineNumber, aColumnNumber)
 {
 }
 
 MediaRule::MediaRule(const MediaRule& aCopy)
   : ConditionRule(aCopy)
 {
   if (aCopy.mMedia) {
-    mMedia = aCopy.mMedia->Clone();
+    mMedia = aCopy.mMedia->Clone().downcast<nsMediaList>();
     // XXXldb This doesn't really make sense.
     mMedia->SetStyleSheet(aCopy.GetStyleSheet());
   }
 }
 
 MediaRule::~MediaRule()
 {
   if (mMedia) {
@@ -814,17 +820,17 @@ MediaRule::SetMedia(nsMediaList* aMedia)
 }
 
 uint16_t
 MediaRule::Type() const
 {
   return nsIDOMCSSRule::MEDIA_RULE;
 }
 
-nsMediaList*
+MediaList*
 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
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -36,16 +36,20 @@
 #include "nsTArray.h"
 
 class nsMediaList;
 
 namespace mozilla {
 
 class ErrorResult;
 
+namespace dom {
+class MediaList;
+}
+
 namespace css {
 
 class MediaRule final : public ConditionRule,
                         public nsIDOMCSSMediaRule
 {
 public:
   MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
@@ -87,17 +91,17 @@ public:
   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;
+  dom::MediaList* 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:
--- a/layout/style/nsMediaList.cpp
+++ b/layout/style/nsMediaList.cpp
@@ -5,19 +5,16 @@
 
 /*
  * representation of media lists used when linking to style sheets or by
  * @media rules
  */
 
 #include "nsMediaList.h"
 
-#include "mozAutoDocUpdate.h"
-#include "mozilla/dom/MediaListBinding.h"
-#include "mozilla/StyleSheet.h"
 #include "nsCSSParser.h"
 #include "nsCSSRules.h"
 #include "nsMediaFeatures.h"
 #include "nsRuleNode.h"
 
 using namespace mozilla;
 
 template <class Numeric>
@@ -489,42 +486,24 @@ nsMediaQuery::Matches(nsPresContext* aPr
     if (aKey) {
       aKey->AddExpression(&expr, match);
     }
   }
 
   return match == !mNegated;
 }
 
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsMediaList)
-  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
-  NS_INTERFACE_MAP_ENTRY(nsIDOMMediaList)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsMediaList)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsMediaList)
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsMediaList)
-
 nsMediaList::nsMediaList()
-  : mStyleSheet(nullptr)
 {
 }
 
 nsMediaList::~nsMediaList()
 {
 }
 
-/* virtual */ JSObject*
-nsMediaList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
-  return dom::MediaListBinding::Wrap(aCx, this, aGivenProto);
-}
-
 void
 nsMediaList::GetText(nsAString& aMediaText)
 {
   aMediaText.Truncate();
 
   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     nsMediaQuery* query = mArray[i];
 
@@ -552,122 +531,41 @@ nsMediaList::Matches(nsPresContext* aPre
   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     if (mArray[i]->Matches(aPresContext, aKey)) {
       return true;
     }
   }
   return mArray.IsEmpty();
 }
 
-void
-nsMediaList::SetStyleSheet(StyleSheet* aSheet)
-{
-  NS_ASSERTION(aSheet == mStyleSheet || !aSheet || !mStyleSheet,
-               "multiple style sheets competing for one media list");
-  mStyleSheet = aSheet;
-}
-
-already_AddRefed<nsMediaList>
+already_AddRefed<MediaList>
 nsMediaList::Clone()
 {
   RefPtr<nsMediaList> result = new nsMediaList();
   result->mArray.AppendElements(mArray.Length());
   for (uint32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     result->mArray[i] = mArray[i]->Clone();
     MOZ_ASSERT(result->mArray[i]);
   }
   return result.forget();
 }
 
-template<typename Func>
-nsresult
-nsMediaList::DoMediaChange(Func aCallback)
-{
-  nsCOMPtr<nsIDocument> doc;
-  if (mStyleSheet) {
-    doc = mStyleSheet->GetAssociatedDocument();
-  }
-  mozAutoDocUpdate updateBatch(doc, UPDATE_STYLE, true);
-  if (mStyleSheet) {
-    mStyleSheet->WillDirty();
-  }
-
-  nsresult rv = aCallback();
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  if (mStyleSheet) {
-    mStyleSheet->DidDirty();
-  }
-  /* XXXldb Pass something meaningful? */
-  if (doc) {
-    doc->StyleRuleChanged(mStyleSheet, nullptr);
-  }
-  return rv;
-}
-
-NS_IMETHODIMP
-nsMediaList::GetMediaText(nsAString& aMediaText)
-{
-  GetText(aMediaText);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsMediaList::SetMediaText(const nsAString& aMediaText)
-{
-  return DoMediaChange([&]() {
-    SetText(aMediaText);
-    return NS_OK;
-  });
-}
-
-NS_IMETHODIMP
-nsMediaList::GetLength(uint32_t* aLength)
-{
-  NS_ENSURE_ARG_POINTER(aLength);
-
-  *aLength = Length();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsMediaList::Item(uint32_t aIndex, nsAString& aReturn)
-{
-  bool dummy;
-  IndexedGetter(aIndex, dummy, aReturn);
-  return NS_OK;
-}
-
 void
 nsMediaList::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aReturn)
 {
   if (aIndex < Length()) {
     aFound = true;
     aReturn.Truncate();
     mArray[aIndex]->AppendToString(aReturn);
   } else {
     aFound = false;
     SetDOMStringToNull(aReturn);
   }
 }
 
-NS_IMETHODIMP
-nsMediaList::DeleteMedium(const nsAString& aOldMedium)
-{
-  return DoMediaChange([&]() { return Delete(aOldMedium); });
-}
-
-NS_IMETHODIMP
-nsMediaList::AppendMedium(const nsAString& aNewMedium)
-{
-  return DoMediaChange([&]() { return Append(aNewMedium); });
-}
-
 nsresult
 nsMediaList::Delete(const nsAString& aOldMedium)
 {
   if (aOldMedium.IsEmpty())
     return NS_ERROR_DOM_NOT_FOUND_ERR;
 
   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
     nsMediaQuery* query = mArray[i];
--- a/layout/style/nsMediaList.h
+++ b/layout/style/nsMediaList.h
@@ -8,30 +8,27 @@
  * representation of media lists used when linking to style sheets or by
  * @media rules
  */
 
 #ifndef nsMediaList_h_
 #define nsMediaList_h_
 
 #include "nsAutoPtr.h"
-#include "nsIDOMMediaList.h"
 #include "nsTArray.h"
 #include "nsIAtom.h"
 #include "nsCSSValue.h"
-#include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/MediaList.h"
 
 class nsPresContext;
 class nsAString;
 struct nsMediaFeature;
 
 namespace mozilla {
-class StyleSheet;
 namespace css {
 class DocumentRule;
 } // namespace css
 } // namespace mozilla
 
 struct nsMediaExpression {
   enum Range { eMin, eMax, eEqual };
 
@@ -245,77 +242,45 @@ private:
   bool mNegated;
   bool mHasOnly; // only needed for serialization
   bool mTypeOmitted; // only needed for serialization
   bool mHadUnknownExpression;
   nsCOMPtr<nsIAtom> mMediaType;
   nsTArray<nsMediaExpression> mExpressions;
 };
 
-class nsMediaList final : public nsIDOMMediaList
-                        , public nsWrapperCache
+class nsMediaList final : public mozilla::dom::MediaList
 {
 public:
-  typedef mozilla::ErrorResult ErrorResult;
-
   nsMediaList();
 
-  virtual JSObject*
-  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-  nsISupports* GetParentObject() const
-  {
-    return nullptr;
-  }
-
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsMediaList)
-
-  NS_DECL_NSIDOMMEDIALIST
-
-  void GetText(nsAString& aMediaText);
-  void SetText(const nsAString& aMediaText);
+  void GetText(nsAString& aMediaText) final;
+  void SetText(const nsAString& aMediaText) final;
 
   // Does this query apply to the presentation?
   // If |aKey| is non-null, add cache information to it.
   bool Matches(nsPresContext* aPresContext,
                  nsMediaQueryResultCacheKey* aKey);
 
-  void SetStyleSheet(mozilla::StyleSheet* aSheet);
   void AppendQuery(nsAutoPtr<nsMediaQuery>& aQuery) {
     // Takes ownership of aQuery
     mArray.AppendElement(aQuery.forget());
   }
 
-  already_AddRefed<nsMediaList> Clone();
+  already_AddRefed<mozilla::dom::MediaList> Clone() final;
 
   nsMediaQuery* MediumAt(int32_t aIndex) { return mArray[aIndex]; }
   void Clear() { mArray.Clear(); }
 
   // WebIDL
-  // XPCOM GetMediaText and SetMediaText are fine.
-  uint32_t Length() { return mArray.Length(); }
-  void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aReturn);
-  // XPCOM Item is fine.
-  void DeleteMedium(const nsAString& aMedium, ErrorResult& aRv)
-  {
-    aRv = DeleteMedium(aMedium);
-  }
-  void AppendMedium(const nsAString& aMedium, ErrorResult& aRv)
-  {
-    aRv = AppendMedium(aMedium);
-  }
+  uint32_t Length() final { return mArray.Length(); }
+  void IndexedGetter(uint32_t aIndex, bool& aFound,
+                     nsAString& aReturn) final;
 
 protected:
   ~nsMediaList();
 
-  template<typename Func>
-  nsresult DoMediaChange(Func aCallback);
-
-  nsresult Delete(const nsAString & aOldMedium);
-  nsresult Append(const nsAString & aOldMedium);
+  nsresult Delete(const nsAString & aOldMedium) final;
+  nsresult Append(const nsAString & aOldMedium) final;
 
   InfallibleTArray<nsAutoPtr<nsMediaQuery> > mArray;
-  // not refcounted; sheet will let us know when it goes away
-  // mStyleSheet is the sheet that needs to be dirtied when this medialist
-  // changes
-  mozilla::StyleSheet* mStyleSheet;
 };
 #endif /* !defined(nsMediaList_h_) */