Bug 1325878: Create less hardcoded nsMediaList instances. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 10 Apr 2017 10:25:33 +0800
changeset 561038 2a834789d009463d3835e368dca5a2240d7e10be
parent 561037 6a90efbc300bd9d3ab669e6647ffbbc9dae6107d
child 561039 6759d82023fbcb86e5cbe70ca2e0d43c06ad5a72
push id53604
push userbmo:emilio+bugs@crisal.io
push dateWed, 12 Apr 2017 05:05:04 +0000
reviewersxidorn
bugs1325878
milestone55.0a1
Bug 1325878: Create less hardcoded nsMediaList instances. r?xidorn MozReview-Commit-ID: K6T3MM1ZrFb
dom/html/HTMLSourceElement.cpp
dom/html/HTMLSourceElement.h
layout/style/CSSStyleSheet.cpp
layout/style/MediaList.cpp
layout/style/MediaList.h
layout/style/MediaQueryList.cpp
layout/style/ServoBindingList.h
layout/style/ServoMediaList.cpp
layout/style/ServoMediaList.h
layout/style/ServoStyleSet.h
layout/style/nsCSSRules.cpp
layout/style/nsMediaList.cpp
layout/style/nsMediaList.h
servo/ports/geckolib/glue.rs
--- a/dom/html/HTMLSourceElement.cpp
+++ b/dom/html/HTMLSourceElement.cpp
@@ -4,21 +4,21 @@
  * 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/dom/HTMLSourceElement.h"
 #include "mozilla/dom/HTMLSourceElementBinding.h"
 
 #include "mozilla/dom/HTMLImageElement.h"
 #include "mozilla/dom/ResponsiveImageSelector.h"
+#include "mozilla/dom/MediaList.h"
 #include "mozilla/dom/MediaSource.h"
 
 #include "nsGkAtoms.h"
 
-#include "nsMediaList.h"
 #include "nsCSSParser.h"
 #include "nsHostObjectProtocolHandler.h"
 
 #include "mozilla/Preferences.h"
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(Source)
 
 namespace mozilla {
@@ -52,17 +52,17 @@ NS_IMPL_STRING_ATTR(HTMLSourceElement, S
 NS_IMPL_STRING_ATTR(HTMLSourceElement, Media, media)
 
 bool
 HTMLSourceElement::MatchesCurrentMedia()
 {
   if (mMediaList) {
     nsIPresShell* presShell = OwnerDoc()->GetShell();
     nsPresContext* pctx = presShell ? presShell->GetPresContext() : nullptr;
-    return pctx && mMediaList->Matches(pctx, nullptr);
+    return pctx && mMediaList->Matches(*pctx);
   }
 
   // No media specified
   return true;
 }
 
 /* static */ bool
 HTMLSourceElement::WouldMatchMediaForDocument(const nsAString& aMedia,
@@ -70,35 +70,31 @@ HTMLSourceElement::WouldMatchMediaForDoc
 {
   if (aMedia.IsEmpty()) {
     return true;
   }
 
   nsIPresShell* presShell = aDocument->GetShell();
   nsPresContext* pctx = presShell ? presShell->GetPresContext() : nullptr;
 
-  nsCSSParser cssParser;
-  RefPtr<nsMediaList> mediaList = new nsMediaList();
-  cssParser.ParseMediaList(aMedia, nullptr, 0, mediaList);
-
-  return pctx && mediaList->Matches(pctx, nullptr);
+  RefPtr<MediaList> mediaList = MediaList::Create(*aDocument, aMedia);
+  return pctx && mediaList->Matches(*pctx, nullptr);
 }
 
 void
 HTMLSourceElement::UpdateMediaList(const nsAttrValue* aValue)
 {
   mMediaList = nullptr;
   nsString mediaStr;
   if (!aValue || (mediaStr = aValue->GetStringValue()).IsEmpty()) {
     return;
   }
 
   nsCSSParser cssParser;
-  mMediaList = new nsMediaList();
-  cssParser.ParseMediaList(mediaStr, nullptr, 0, mMediaList);
+  mMediaList = MediaList::Create(*OwnerDoc(), mediaStr);
 }
 
 nsresult
 HTMLSourceElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify)
 {
   // If we are associated with a <picture> with a valid <img>, notify it of
   // responsive parameter changes
--- a/dom/html/HTMLSourceElement.h
+++ b/dom/html/HTMLSourceElement.h
@@ -7,22 +7,23 @@
 #ifndef mozilla_dom_HTMLSourceElement_h
 #define mozilla_dom_HTMLSourceElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsIDOMHTMLSourceElement.h"
 #include "nsGenericHTMLElement.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 
-class nsMediaList;
 class nsAttrValue;
 
 namespace mozilla {
 namespace dom {
 
+class MediaList;
+
 class HTMLSourceElement final : public nsGenericHTMLElement,
                                 public nsIDOMHTMLSourceElement
 {
 public:
   explicit HTMLSourceElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
@@ -108,19 +109,19 @@ protected:
   virtual JSObject* WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 protected:
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue,
                                 bool aNotify) override;
 
 private:
-  RefPtr<nsMediaList> mMediaList;
+  RefPtr<MediaList> mMediaList;
   RefPtr<MediaSource> mSrcMediaSource;
 
-  // Generates a new nsMediaList using the given input
+  // Generates a new MediaList using the given input
   void UpdateMediaList(const nsAttrValue* aValue);
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLSourceElement_h
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -508,18 +508,19 @@ CSSStyleSheet::DropStyleSet(nsStyleSet* 
   NS_ASSERTION(found, "didn't find style set");
 }
 
 bool
 CSSStyleSheet::UseForPresentation(nsPresContext* aPresContext,
                                   nsMediaQueryResultCacheKey& aKey) const
 {
   if (mMedia) {
+    MOZ_ASSERT(aPresContext);
     auto media = static_cast<nsMediaList*>(mMedia.get());
-    return media->Matches(aPresContext, &aKey);
+    return media->Matches(*aPresContext, &aKey);
   }
   return true;
 }
 
 
 bool
 CSSStyleSheet::HasRules() const
 {
--- a/layout/style/MediaList.cpp
+++ b/layout/style/MediaList.cpp
@@ -67,20 +67,20 @@ MediaList::DoMediaChange(Func aCallback)
   /* XXXldb Pass something meaningful? */
   if (doc) {
     doc->StyleRuleChanged(mStyleSheet, nullptr);
   }
   return rv;
 }
 
 /* static */ already_AddRefed<MediaList>
-MediaList::Create(nsIDocument* aDocument, const nsAString& aMedia)
+MediaList::Create(const nsIDocument& aDocument,
+                  const nsAString& aMedia)
 {
-  MOZ_ASSERT(aDocument);
-  if (aDocument->IsStyledByServo()) {
+  if (aDocument.IsStyledByServo()) {
     RefPtr<ServoMediaList> mediaList = new ServoMediaList(aMedia);
     return mediaList.forget();
   }
 
   nsCSSParser parser;
   RefPtr<nsMediaList> mediaList = new nsMediaList();
   parser.ParseMediaList(aMedia, nullptr, 0, mediaList);
   return mediaList.forget();
--- a/layout/style/MediaList.h
+++ b/layout/style/MediaList.h
@@ -11,16 +11,18 @@
 
 #include "mozilla/ErrorResult.h"
 #include "mozilla/ServoUtils.h"
 
 #include "nsIDOMMediaList.h"
 #include "nsWrapperCache.h"
 
 class nsIDocument;
+class nsPresContext;
+class nsMediaQueryResultCacheKey;
 
 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.
@@ -35,26 +37,28 @@ class MediaList : public nsIDOMMediaList
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaList)
 
   /**
    * Creates a MediaList backed by the StyleBackendType of the document.
    */
-  static already_AddRefed<MediaList> Create(nsIDocument* aDocument,
+  static already_AddRefed<MediaList> Create(const nsIDocument& aDocument,
                                             const nsAString& aMedia);
 
   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;
+  virtual bool Matches(nsPresContext& aPresContext,
+                       nsMediaQueryResultCacheKey* = nullptr) const = 0;
 
   void SetStyleSheet(StyleSheet* aSheet);
 
   NS_DECL_NSIDOMMEDIALIST
 
   // WebIDL
   // XPCOM GetMediaText and SetMediaText are fine.
   virtual uint32_t Length() = 0;
--- a/layout/style/MediaQueryList.cpp
+++ b/layout/style/MediaQueryList.cpp
@@ -229,17 +229,17 @@ MediaQueryList::RecomputeMatches()
   }
 
   nsPresContext* presContext = shell->GetPresContext();
   if (!presContext) {
     // XXXbz What's the right behavior here?  Spec doesn't say.
     return;
   }
 
-  mMatches = mMediaList->Matches(presContext, nullptr);
+  mMatches = mMediaList->Matches(*presContext, nullptr);
   mMatchesValid = true;
 }
 
 nsISupports*
 MediaQueryList::GetParentObject() const
 {
   return mDocument;
 }
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -257,16 +257,19 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetFontFamily, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    const nsAString& value)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetTextDecorationColorOverride, void,
                    RawServoDeclarationBlockBorrowed declarations)
 
 // MediaList
 SERVO_BINDING_FUNC(Servo_MediaList_Create, RawServoMediaListStrong)
+SERVO_BINDING_FUNC(Servo_MediaList_Matches, bool,
+                   RawServoMediaListBorrowed list,
+                   RawServoStyleSetBorrowed set)
 SERVO_BINDING_FUNC(Servo_MediaList_GetText, void,
                    RawServoMediaListBorrowed list, nsAString* result)
 SERVO_BINDING_FUNC(Servo_MediaList_SetText, void,
                    RawServoMediaListBorrowed list, const nsACString* text)
 SERVO_BINDING_FUNC(Servo_MediaList_GetLength, uint32_t,
                    RawServoMediaListBorrowed list)
 SERVO_BINDING_FUNC(Servo_MediaList_GetMediumAt, bool,
                    RawServoMediaListBorrowed list, uint32_t index,
--- a/layout/style/ServoMediaList.cpp
+++ b/layout/style/ServoMediaList.cpp
@@ -4,16 +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 media lists for servo backend */
 
 #include "mozilla/ServoMediaList.h"
 
 #include "mozilla/ServoBindings.h"
+#include "mozilla/ServoStyleSet.h"
 
 namespace mozilla {
 
 already_AddRefed<dom::MediaList>
 ServoMediaList::Clone()
 {
   // Currently MediaList::Clone() is only called from CSSStyleSheet's
   // constructor, so we don't need to support it at the moment.
@@ -74,9 +75,17 @@ ServoMediaList::Delete(const nsAString& 
 {
   NS_ConvertUTF16toUTF8 oldMedium(aOldMedium);
   if (Servo_MediaList_DeleteMedium(mRawList, &oldMedium)) {
     return NS_OK;
   }
   return NS_ERROR_DOM_NOT_FOUND_ERR;
 }
 
+bool
+ServoMediaList::Matches(nsPresContext& aPresContext,
+                        nsMediaQueryResultCacheKey*) const
+{
+  const RawServoStyleSet& rawSet = aPresContext.StyleSet()->AsServo()->RawSet();
+  return Servo_MediaList_Matches(mRawList, &rawSet);
+}
+
 } // namespace mozilla
--- a/layout/style/ServoMediaList.h
+++ b/layout/style/ServoMediaList.h
@@ -26,16 +26,18 @@ public:
 
   void GetText(nsAString& aMediaText) final;
   void SetText(const nsAString& aMediaText) final;
 
   uint32_t Length() final;
   void IndexedGetter(uint32_t aIndex, bool& aFound,
                      nsAString& aReturn) final;
 
+  bool Matches(nsPresContext&, nsMediaQueryResultCacheKey*) const final;
+
 protected:
   nsresult Delete(const nsAString& aOldMedium) final;
   nsresult Append(const nsAString& aNewMedium) final;
 
   ~ServoMediaList() {}
 
 private:
   RefPtr<RawServoMediaList> mRawList;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -88,16 +88,17 @@ public:
   ServoStyleSet();
   ~ServoStyleSet();
 
   void Init(nsPresContext* aPresContext);
   void BeginShutdown();
   void Shutdown();
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
+  const RawServoStyleSet& RawSet() const { return *mRawSet; }
 
   bool GetAuthorStyleDisabled() const;
   nsresult SetAuthorStyleDisabled(bool aStyleDisabled);
 
   void BeginUpdate();
   nsresult EndUpdate();
 
   already_AddRefed<nsStyleContext>
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -489,20 +489,21 @@ MediaRule::SetConditionText(const nsAStr
   }
 
   return mMedia->SetMediaText(aConditionText);
 }
 
 // GroupRule interface
 /* virtual */ bool
 MediaRule::UseForPresentation(nsPresContext* aPresContext,
-                                   nsMediaQueryResultCacheKey& aKey)
+                              nsMediaQueryResultCacheKey& aKey)
 {
   if (mMedia) {
-    return mMedia->Matches(aPresContext, &aKey);
+    MOZ_ASSERT(aPresContext);
+    return mMedia->Matches(*aPresContext, &aKey);
   }
   return true;
 }
 
 /* virtual */ size_t
 MediaRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = aMallocSizeOf(this);
--- a/layout/style/nsMediaList.cpp
+++ b/layout/style/nsMediaList.cpp
@@ -520,21 +520,21 @@ nsMediaList::GetText(nsAString& aMediaTe
 void
 nsMediaList::SetText(const nsAString& aMediaText)
 {
   nsCSSParser parser;
   parser.ParseMediaList(aMediaText, nullptr, 0, this);
 }
 
 bool
-nsMediaList::Matches(nsPresContext* aPresContext,
-                     nsMediaQueryResultCacheKey* aKey)
+nsMediaList::Matches(nsPresContext& aPresContext,
+                     nsMediaQueryResultCacheKey* aKey) const
 {
   for (int32_t i = 0, i_end = mArray.Length(); i < i_end; ++i) {
-    if (mArray[i]->Matches(aPresContext, aKey)) {
+    if (mArray[i]->Matches(&aPresContext, aKey)) {
       return true;
     }
   }
   return mArray.IsEmpty();
 }
 
 already_AddRefed<dom::MediaList>
 nsMediaList::Clone()
--- a/layout/style/nsMediaList.h
+++ b/layout/style/nsMediaList.h
@@ -231,17 +231,17 @@ public:
 
   void AppendToString(nsAString& aString) const;
 
   nsMediaQuery* Clone() const;
 
   // Does this query apply to the presentation?
   // If |aKey| is non-null, add cache information to it.
   bool Matches(nsPresContext* aPresContext,
-                 nsMediaQueryResultCacheKey* aKey) const;
+               nsMediaQueryResultCacheKey* aKey) const;
 
 private:
   bool mNegated;
   bool mHasOnly; // only needed for serialization
   bool mTypeOmitted; // only needed for serialization
   bool mHadUnknownExpression;
   nsCOMPtr<nsIAtom> mMediaType;
   nsTArray<nsMediaExpression> mExpressions;
@@ -252,18 +252,18 @@ class nsMediaList final : public mozilla
 public:
   nsMediaList();
 
   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);
+  bool Matches(nsPresContext& aPresContext,
+               nsMediaQueryResultCacheKey* aKey) const final;
 
   void AppendQuery(nsAutoPtr<nsMediaQuery>& aQuery) {
     // Takes ownership of aQuery
     mArray.AppendElement(aQuery.forget());
   }
 
   already_AddRefed<mozilla::dom::MediaList> Clone() final;
 
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1155,17 +1155,26 @@ pub extern "C" fn Servo_DeclarationBlock
     remove_property(declarations, get_property_id_from_nscsspropertyid!(property, ()))
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_MediaList_Create() -> RawServoMediaListStrong {
 
     let global_style_data = &*GLOBAL_STYLE_DATA;
     Arc::new(global_style_data.shared_lock.wrap(MediaList::default())).into_strong()
+}
 
+#[no_mangle]
+pub extern "C" fn Servo_MediaList_Matches(list: RawServoMediaListBorrowed,
+                                          raw_data: RawServoStyleSetBorrowed)
+                                          -> bool {
+    let per_doc_data = PerDocumentStyleData::from_ffi(raw_data).borrow();
+    read_locked_arc(list, |list: &MediaList| {
+        list.evaluate(&per_doc_data.stylist.device)
+    })
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed, result: *mut nsAString) {
     read_locked_arc(list, |list: &MediaList| {
         list.to_css(unsafe { result.as_mut().unwrap() }).unwrap();
     })
 }