Bug 1410074: Make the caller type from MatchMedia arrive to the CSS code. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 19 Oct 2017 16:06:50 +0200
changeset 685281 d3bf386e0edeedcf99a1c45a703507845be28225
parent 685280 ebec641c7bf720b19977c31e822968c50734d3f2
child 685282 42a68096e8003bef8abb958c5b3898f25a239a02
push id85891
push userbmo:emilio@crisal.io
push dateTue, 24 Oct 2017 10:29:04 +0000
reviewersxidorn
bugs1410074
milestone58.0a1
Bug 1410074: Make the caller type from MatchMedia arrive to the CSS code. r?xidorn MozReview-Commit-ID: LUiobfHSUq1
dom/base/nsDocument.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsIDocument.h
dom/webidl/Window.webidl
layout/style/MediaList.cpp
layout/style/MediaList.h
layout/style/MediaQueryList.cpp
layout/style/MediaQueryList.h
layout/style/ServoMediaList.cpp
layout/style/ServoMediaList.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSParser.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -7454,19 +7454,21 @@ nsDocument::ClearBoxObjectFor(nsIContent
       nsPIBoxObject* boxObject = entry.Data();
       boxObject->Clear();
       entry.Remove();
     }
   }
 }
 
 already_AddRefed<MediaQueryList>
-nsIDocument::MatchMedia(const nsAString& aMediaQueryList)
-{
-  RefPtr<MediaQueryList> result = new MediaQueryList(this, aMediaQueryList);
+nsIDocument::MatchMedia(const nsAString& aMediaQueryList,
+                        CallerType aCallerType)
+{
+  RefPtr<MediaQueryList> result =
+    new MediaQueryList(this, aMediaQueryList, aCallerType);
 
   mDOMMediaQueryLists.insertBack(result);
 
   return result.forget();
 }
 
 void
 nsDocument::FlushSkinBindings()
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6333,36 +6333,38 @@ nsGlobalWindow::CancelAnimationFrame(int
   if (!mDoc) {
     return;
   }
 
   mDoc->CancelFrameRequestCallback(aHandle);
 }
 
 already_AddRefed<MediaQueryList>
-nsGlobalWindow::MatchMediaOuter(const nsAString& aMediaQueryList)
+nsGlobalWindow::MatchMediaOuter(const nsAString& aMediaQueryList,
+                                CallerType aCallerType)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
 
   if (!mDoc) {
     return nullptr;
   }
 
-  return mDoc->MatchMedia(aMediaQueryList);
+  return mDoc->MatchMedia(aMediaQueryList, aCallerType);
 }
 
 already_AddRefed<MediaQueryList>
 nsGlobalWindow::MatchMedia(const nsAString& aMediaQueryList,
+                           CallerType aCallerType,
                            ErrorResult& aError)
 {
   // FIXME: This whole forward-to-outer and then get a pres
   // shell/context off the docshell dance is sort of silly; it'd make
   // more sense to forward to the inner, but it's what everyone else
   // (GetSelection, GetScrollXY, etc.) does around here.
-  FORWARD_TO_OUTER_OR_THROW(MatchMediaOuter, (aMediaQueryList), aError, nullptr);
+  FORWARD_TO_OUTER_OR_THROW(MatchMediaOuter, (aMediaQueryList, aCallerType), aError, nullptr);
 }
 
 void
 nsGlobalWindow::SetScreenXOuter(int32_t aScreenX,
                                 CallerType aCallerType,
                                 ErrorResult& aError)
 {
   MOZ_RELEASE_ASSERT(IsOuterWindow());
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1036,19 +1036,23 @@ public:
   GetLocalStorage(mozilla::ErrorResult& aError);
   mozilla::dom::Selection* GetSelectionOuter();
   mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
   already_AddRefed<nsISelection> GetSelection() override;
   mozilla::dom::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
   already_AddRefed<nsICSSDeclaration>
     GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
                      mozilla::ErrorResult& aError) override;
-  already_AddRefed<mozilla::dom::MediaQueryList> MatchMediaOuter(const nsAString& aQuery);
-  already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia(const nsAString& aQuery,
-                                                            mozilla::ErrorResult& aError);
+  already_AddRefed<mozilla::dom::MediaQueryList> MatchMediaOuter(
+    const nsAString& aQuery,
+    mozilla::dom::CallerType aCallerType);
+  already_AddRefed<mozilla::dom::MediaQueryList> MatchMedia(
+    const nsAString& aQuery,
+    mozilla::dom::CallerType aCallerType,
+    mozilla::ErrorResult& aError);
   nsScreen* GetScreen(mozilla::ErrorResult& aError);
   nsIDOMScreen* GetScreen() override;
   void MoveToOuter(int32_t aXPos, int32_t aYPos,
                    mozilla::dom::CallerType aCallerType,
                    mozilla::ErrorResult& aError);
   void MoveTo(int32_t aXPos, int32_t aYPos,
               mozilla::dom::CallerType aCallerType,
               mozilla::ErrorResult& aError);
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2073,17 +2073,18 @@ public:
     GetBoxObjectFor(mozilla::dom::Element* aElement,
                     mozilla::ErrorResult& aRv) = 0;
 
   /**
    * Support for window.matchMedia()
    */
 
   already_AddRefed<mozilla::dom::MediaQueryList>
-    MatchMedia(const nsAString& aMediaQueryList);
+    MatchMedia(const nsAString& aMediaQueryList,
+               mozilla::dom::CallerType aCallerType);
 
   mozilla::LinkedList<mozilla::dom::MediaQueryList>& MediaQueryLists() {
     return mDOMMediaQueryLists;
   }
 
   /**
    * Get the compatibility mode for this document
    */
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -136,18 +136,18 @@ dictionary ScrollOptions {
 };
 
 dictionary ScrollToOptions : ScrollOptions {
   unrestricted double left;
   unrestricted double top;
 };
 
 partial interface Window {
-  //[Throws,NewObject] MediaQueryList matchMedia(DOMString query);
-  [Throws,NewObject] MediaQueryList? matchMedia(DOMString query);
+  //[Throws, NewObject, NeedsCallerType] MediaQueryList matchMedia(DOMString query);
+  [Throws, NewObject, NeedsCallerType] MediaQueryList? matchMedia(DOMString query);
   // Per spec, screen is SameObject, but we don't actually guarantee that given
   // nsGlobalWindow::Cleanup.  :(
   //[SameObject, Replaceable, Throws] readonly attribute Screen screen;
   [Replaceable, Throws] readonly attribute Screen screen;
 
   // browsing context
   //[Throws] void moveTo(double x, double y);
   //[Throws] void moveBy(double x, double y);
--- a/layout/style/MediaList.cpp
+++ b/layout/style/MediaList.cpp
@@ -67,26 +67,29 @@ MediaList::DoMediaChange(Func aCallback)
   /* XXXldb Pass something meaningful? */
   if (doc) {
     doc->StyleRuleChanged(mStyleSheet, nullptr);
   }
   return rv;
 }
 
 /* static */ already_AddRefed<MediaList>
-MediaList::Create(StyleBackendType aBackendType, const nsAString& aMedia)
+MediaList::Create(
+    StyleBackendType aBackendType,
+    const nsAString& aMedia,
+    CallerType aCallerType)
 {
   if (aBackendType == StyleBackendType::Servo) {
-    RefPtr<ServoMediaList> mediaList = new ServoMediaList(aMedia);
+    RefPtr<ServoMediaList> mediaList = new ServoMediaList(aMedia, aCallerType);
     return mediaList.forget();
   }
 
   nsCSSParser parser;
   RefPtr<nsMediaList> mediaList = new nsMediaList();
-  parser.ParseMediaList(aMedia, nullptr, 0, mediaList);
+  parser.ParseMediaList(aMedia, nullptr, 0, mediaList, aCallerType);
   return mediaList.forget();
 }
 
 NS_IMETHODIMP
 MediaList::GetMediaText(nsAString& aMediaText)
 {
   GetText(aMediaText);
   return NS_OK;
--- a/layout/style/MediaList.h
+++ b/layout/style/MediaList.h
@@ -39,17 +39,19 @@ class MediaList : public nsIDOMMediaList
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaList)
 
   /**
    * Creates a MediaList backed by the given StyleBackendType.
    */
   static already_AddRefed<MediaList> Create(StyleBackendType,
-                                            const nsAString& aMedia);
+                                            const nsAString& aMedia,
+                                            CallerType aCallerType =
+                                              CallerType::NonSystem);
 
   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;
--- a/layout/style/MediaQueryList.cpp
+++ b/layout/style/MediaQueryList.cpp
@@ -16,22 +16,25 @@
 #include "nsIDocument.h"
 
 #define ONCHANGE_STRING NS_LITERAL_STRING("change")
 
 namespace mozilla {
 namespace dom {
 
 MediaQueryList::MediaQueryList(nsIDocument* aDocument,
-                               const nsAString& aMediaQueryList)
+                               const nsAString& aMediaQueryList,
+                               CallerType aCallerType)
   : mDocument(aDocument)
   , mMatchesValid(false)
 {
   mMediaList =
-    MediaList::Create(aDocument->GetStyleBackendType(), aMediaQueryList);
+    MediaList::Create(aDocument->GetStyleBackendType(),
+                      aMediaQueryList,
+                      aCallerType);
 
   KeepAliveIfHasListenersFor(ONCHANGE_STRING);
 }
 
 MediaQueryList::~MediaQueryList()
 {}
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQueryList)
--- a/layout/style/MediaQueryList.h
+++ b/layout/style/MediaQueryList.h
@@ -27,18 +27,19 @@ namespace dom {
 class MediaList;
 
 class MediaQueryList final : public DOMEventTargetHelper,
                              public mozilla::LinkedListElement<MediaQueryList>
 {
 public:
   // The caller who constructs is responsible for calling Evaluate
   // before calling any other methods.
-  MediaQueryList(nsIDocument *aDocument,
-                 const nsAString &aMediaQueryList);
+  MediaQueryList(nsIDocument* aDocument,
+                 const nsAString& aMediaQueryList,
+                 mozilla::dom::CallerType aCallerType);
 private:
   ~MediaQueryList();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaQueryList, DOMEventTargetHelper)
 
   nsISupports* GetParentObject() const;
--- a/layout/style/ServoMediaList.cpp
+++ b/layout/style/ServoMediaList.cpp
@@ -21,31 +21,39 @@ ServoMediaList::Clone()
   return clone.forget();
 }
 
 ServoMediaList::ServoMediaList()
   : mRawList(Servo_MediaList_Create().Consume())
 {
 }
 
-ServoMediaList::ServoMediaList(const nsAString& aMedia)
+ServoMediaList::ServoMediaList(const nsAString& aMedia,
+                               dom::CallerType aCallerType)
   : ServoMediaList()
 {
-  SetText(aMedia);
+  SetTextInternal(aMedia, aCallerType);
 }
 
 void
 ServoMediaList::GetText(nsAString& aMediaText)
 {
   Servo_MediaList_GetText(mRawList, &aMediaText);
 }
 
 void
 ServoMediaList::SetText(const nsAString& aMediaText)
 {
+  SetTextInternal(aMediaText, dom::CallerType::NonSystem);
+}
+
+void
+ServoMediaList::SetTextInternal(const nsAString& aMediaText,
+                                dom::CallerType aCallerType)
+{
   NS_ConvertUTF16toUTF8 mediaText(aMediaText);
   Servo_MediaList_SetText(mRawList, &mediaText);
 }
 
 uint32_t
 ServoMediaList::Length()
 {
   return Servo_MediaList_GetLength(mRawList);
--- a/layout/style/ServoMediaList.h
+++ b/layout/style/ServoMediaList.h
@@ -14,17 +14,17 @@
 
 namespace mozilla {
 
 class ServoMediaList final : public dom::MediaList
 {
 public:
   explicit ServoMediaList(already_AddRefed<RawServoMediaList> aRawList)
     : mRawList(aRawList) {}
-  explicit ServoMediaList(const nsAString& aMedia);
+  ServoMediaList(const nsAString& aMedia, dom::CallerType);
   ServoMediaList();
 
   already_AddRefed<dom::MediaList> Clone() final;
 
   void GetText(nsAString& aMediaText) final;
   void SetText(const nsAString& aMediaText) final;
 
   uint32_t Length() final;
@@ -37,16 +37,17 @@ public:
   bool IsServo() const final { return true; }
 #endif
 
   RawServoMediaList& RawList() { return *mRawList; }
 
 protected:
   nsresult Delete(const nsAString& aOldMedium) final;
   nsresult Append(const nsAString& aNewMedium) final;
+  void SetTextInternal(const nsAString& aMediaText, dom::CallerType);
 
   ~ServoMediaList() {}
 
 private:
   RefPtr<RawServoMediaList> mRawList;
 };
 
 } // namespace mozilla
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -194,17 +194,18 @@ public:
 
   bool ParseTransformProperty(const nsAString& aPropValue,
                               bool aDisallowRelativeValues,
                               nsCSSValue& aResult);
 
   void ParseMediaList(const nsAString& aBuffer,
                       nsIURI* aURL, // for error reporting
                       uint32_t aLineNumber, // for error reporting
-                      nsMediaList* aMediaList);
+                      nsMediaList* aMediaList,
+                      mozilla::dom::CallerType aCallerType);
 
   bool ParseSourceSizeList(const nsAString& aBuffer,
                            nsIURI* aURI, // for error reporting
                            uint32_t aLineNumber, // for error reporting
                            InfallibleTArray< nsAutoPtr<nsMediaQuery> >& aQueries,
                            InfallibleTArray<nsCSSValue>& aValues);
 
   void ParseVariable(const nsAString& aVariableName,
@@ -490,17 +491,18 @@ protected:
   private:
     CSSParserImpl* const mParser;
   };
 
   // the caller must hold on to aString until parsing is done
   void InitScanner(nsCSSScanner& aScanner,
                    css::ErrorReporter& aReporter,
                    nsIURI* aSheetURI, nsIURI* aBaseURI,
-                   nsIPrincipal* aSheetPrincipal);
+                   nsIPrincipal* aSheetPrincipal,
+                   dom::CallerType aCallerType = dom::CallerType::NonSystem);
   void ReleaseScanner(void);
 
   /**
    * Saves the current input state, which includes any currently pushed
    * back token, and the current position of the scanner.
    */
   void SaveInputState(CSSParserInputState& aState);
 
@@ -1322,16 +1324,19 @@ protected:
     eCSSSection_Import,
     eCSSSection_NameSpace,
     eCSSSection_General
   };
   nsCSSSection  mSection;
 
   nsXMLNameSpaceMap *mNameSpaceMap;  // weak, mSheet owns it
 
+  // Whether the caller of the DOM API that invoked us is chrome or not.
+  dom::CallerType mDomCallerType = dom::CallerType::NonSystem;
+
   // After an UngetToken is done this flag is true. The next call to
   // GetToken clears the flag.
   bool mHavePushBack : 1;
 
   // True if we are in quirks mode; false in standards or almost standards mode
   bool          mNavQuirkMode : 1;
 
   // True when the hashless color quirk applies.
@@ -1542,39 +1547,42 @@ CSSParserImpl::Reset()
   SetQuirkMode(false);
   SetChildLoader(nullptr);
 }
 
 void
 CSSParserImpl::InitScanner(nsCSSScanner& aScanner,
                            css::ErrorReporter& aReporter,
                            nsIURI* aSheetURI, nsIURI* aBaseURI,
-                           nsIPrincipal* aSheetPrincipal)
+                           nsIPrincipal* aSheetPrincipal,
+                           dom::CallerType aCallerType)
 {
   NS_PRECONDITION(!mParsingCompoundProperty, "Bad initial state");
   NS_PRECONDITION(!mScanner, "already have scanner");
 
   mScanner = &aScanner;
   mReporter = &aReporter;
   mScanner->SetErrorReporter(mReporter);
 
   mBaseURI = aBaseURI;
   mSheetURI = aSheetURI;
   mSheetPrincipal = aSheetPrincipal;
   mHavePushBack = false;
+  mDomCallerType = aCallerType;
 }
 
 void
 CSSParserImpl::ReleaseScanner()
 {
   mScanner = nullptr;
   mReporter = nullptr;
   mBaseURI = nullptr;
   mSheetURI = nullptr;
   mSheetPrincipal = nullptr;
+  mDomCallerType = dom::CallerType::NonSystem;
 }
 
 nsresult
 CSSParserImpl::ParseSheet(const nsAString& aInput,
                           nsIURI*          aSheetURI,
                           nsIURI*          aBaseURI,
                           nsIPrincipal*    aSheetPrincipal,
                           uint32_t         aLineNumber,
@@ -1991,27 +1999,28 @@ CSSParserImpl::ParseVariable(const nsASt
 
   ReleaseScanner();
 }
 
 void
 CSSParserImpl::ParseMediaList(const nsAString& aBuffer,
                               nsIURI* aURI, // for error reporting
                               uint32_t aLineNumber, // for error reporting
-                              nsMediaList* aMediaList)
+                              nsMediaList* aMediaList,
+                              dom::CallerType aCallerType)
 {
   // XXX Are there cases where the caller wants to keep what it already
   // has in case of parser error?  If GatherMedia ever changes to return
   // a value other than true, we probably should avoid modifying aMediaList.
   aMediaList->Clear();
 
   // fake base URI since media lists don't have URIs in them
   nsCSSScanner scanner(aBuffer, aLineNumber);
   css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
-  InitScanner(scanner, reporter, aURI, aURI, nullptr);
+  InitScanner(scanner, reporter, aURI, aURI, nullptr, aCallerType);
 
   DebugOnly<bool> parsedOK = GatherMedia(aMediaList, false);
   NS_ASSERTION(parsedOK, "GatherMedia returned false; we probably want to avoid "
                          "trashing aMediaList");
 
   CLEAR_ERROR();
   ReleaseScanner();
 }
@@ -18004,20 +18013,21 @@ nsCSSParser::ParseVariable(const nsAStri
     ParseVariable(aVariableName, aPropValue, aSheetURI, aBaseURI,
                   aSheetPrincipal, aDeclaration, aChanged, aIsImportant);
 }
 
 void
 nsCSSParser::ParseMediaList(const nsAString& aBuffer,
                             nsIURI*            aURI,
                             uint32_t           aLineNumber,
-                            nsMediaList*       aMediaList)
+                            nsMediaList*       aMediaList,
+                            dom::CallerType aCallerType)
 {
   static_cast<CSSParserImpl*>(mImpl)->
-    ParseMediaList(aBuffer, aURI, aLineNumber, aMediaList);
+    ParseMediaList(aBuffer, aURI, aLineNumber, aMediaList, aCallerType);
 }
 
 bool
 nsCSSParser::ParseSourceSizeList(const nsAString& aBuffer,
                                  nsIURI* aURI,
                                  uint32_t aLineNumber,
                                  InfallibleTArray< nsAutoPtr<nsMediaQuery> >& aQueries,
                                  InfallibleTArray<nsCSSValue>& aValues)
--- a/layout/style/nsCSSParser.h
+++ b/layout/style/nsCSSParser.h
@@ -159,17 +159,19 @@ public:
   /**
    * Parse aBuffer into a media list |aMediaList|, which must be non-null,
    * replacing its current contents. |aURL| and |aLineNumber| are used for error
    * reporting.
    */
   void ParseMediaList(const nsAString& aBuffer,
                       nsIURI*            aURL,
                       uint32_t           aLineNumber,
-                      nsMediaList*       aMediaList);
+                      nsMediaList*       aMediaList,
+                      mozilla::dom::CallerType aCallerType =
+                        mozilla::dom::CallerType::NonSystem);
 
   /*
    * Parse aBuffer into a list of media queries and their associated values,
    * according to grammar:
    *    <source-size-list> = <source-size>#?
    *    <source-size> = <media-condition>? <length>
    *
    * Note that this grammar is top-level: The function expects to consume the