Bug 1459498: Use StyleSheetInfo more. r=heycam
authorEmilio Cobos Álvarez <emilio@crisal.io>
Sun, 06 May 2018 16:10:09 +0200
changeset 417186 00978d0f6e27b5a334ec5cdd2ab992b088683001
parent 417185 c8f3d4b8b6d931824bbf2f346a2efb750e700e19
child 417187 9f3986a987fac207fd17c2d56e75ffec30b73bbb
push id103016
push userecoal95@gmail.com
push dateTue, 08 May 2018 08:10:17 +0000
treeherdermozilla-inbound@fb3186662dda [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1459498
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1459498: Use StyleSheetInfo more. r=heycam Not as much as I'd like, because we have all the internal loads and child sheets, but... MozReview-Commit-ID: 7402w8vxCel
dom/base/nsContentSink.cpp
dom/base/nsIStyleSheetLinkingElement.h
dom/base/nsStyleLinkElement.cpp
dom/base/nsStyleLinkElement.h
layout/style/Loader.cpp
layout/style/Loader.h
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -51,16 +51,17 @@
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "nsParserConstants.h"
 #include "nsSandboxFlags.h"
 #include "Link.h"
 #include "HTMLLinkElement.h"
 
 using namespace mozilla;
+using namespace mozilla::css;
 using namespace mozilla::dom;
 
 LazyLogModule gContentSinkLogModuleInfo("nscontentsink");
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsContentSink)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsContentSink)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsContentSink)
@@ -778,28 +779,32 @@ nsContentSink::ProcessStyleLinkFromHeade
   nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nullptr,
                           mDocument->GetDocBaseURI());
 
   if (NS_FAILED(rv)) {
     // The URI is bad, move along, don't propagate the error (for now)
     return NS_OK;
   }
 
-  mozilla::net::ReferrerPolicy referrerPolicy =
-    mozilla::net::AttributeReferrerPolicyFromString(aReferrerPolicy);
-  if (referrerPolicy == net::RP_Unset) {
-    referrerPolicy = mDocument->GetReferrerPolicy();
-  }
-  // If this is a fragment parser, we don't want to observe.
-  // We don't support CORS for processing instructions
+
+  Loader::StyleSheetInfo info {
+    *mDocument,
+    nullptr,
+    url.forget(),
+    nullptr,
+    net::AttributeReferrerPolicyFromString(aReferrerPolicy),
+    CORS_NONE,
+    aTitle,
+    aMedia,
+    aAlternate ? Loader::HasAlternateRel::Yes : Loader::HasAlternateRel::No,
+    Loader::IsInline::No,
+  };
+
   auto loadResultOrErr =
-    mCSSLoader->LoadStyleLink(nullptr, url, nullptr, aTitle, aMedia, aAlternate,
-                              CORS_NONE, referrerPolicy,
-                              /* integrity = */ EmptyString(),
-                              mRunsToCompletion ? nullptr : this);
+    mCSSLoader->LoadStyleLink(info, mRunsToCompletion ? nullptr : this);
   if (loadResultOrErr.isErr()) {
     return loadResultOrErr.unwrapErr();
   }
 
   if (loadResultOrErr.unwrap().ShouldBlock() && !mRunsToCompletion) {
     ++mPendingSheetCount;
     mScriptLoader->AddParserBlockingScriptExecutionBlocker();
   }
--- a/dom/base/nsIStyleSheetLinkingElement.h
+++ b/dom/base/nsIStyleSheetLinkingElement.h
@@ -6,41 +6,55 @@
 #ifndef nsIStyleSheetLinkingElement_h__
 #define nsIStyleSheetLinkingElement_h__
 
 
 #include "nsISupports.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/Result.h"
 
+class nsIContent;
 class nsICSSLoaderObserver;
+class nsIPrincipal;
 class nsIURI;
 
 #define NS_ISTYLESHEETLINKINGELEMENT_IID          \
 { 0xa8b79f3b, 0x9d18, 0x4f9c, \
   { 0xb1, 0xaa, 0x8c, 0x9b, 0x1b, 0xaa, 0xac, 0xad } }
 
 class nsIStyleSheetLinkingElement : public nsISupports {
 public:
   enum class ForceUpdate
   {
     Yes,
     No,
   };
 
+  enum class Completed
+  {
+    Yes,
+    No,
+  };
+
+  enum class HasAlternateRel
+  {
+    Yes,
+    No
+  };
+
   enum class IsAlternate
   {
     Yes,
     No,
   };
 
-  enum class Completed
+  enum class IsInline
   {
     Yes,
-    No,
+    No
   };
 
   enum class MediaMatched
   {
     Yes,
     No,
   };
 
@@ -74,16 +88,47 @@ public:
       if (!mWillNotify) {
         return false;
       }
 
       return !mIsAlternate && mMediaMatched;
     }
   };
 
+  struct MOZ_STACK_CLASS StyleSheetInfo
+  {
+    nsIContent* mContent;
+    // FIXME(emilio): do these really need to be strong refs?
+    nsCOMPtr<nsIURI> mURI;
+    nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+    mozilla::net::ReferrerPolicy mReferrerPolicy;
+    mozilla::CORSMode mCORSMode;
+    nsAutoString mTitle;
+    nsAutoString mMedia;
+    nsAutoString mIntegrity;
+
+    bool mIsAlternate : 1;
+    bool mHasAlternateRel : 1;
+    bool mIsInline : 1;
+
+    StyleSheetInfo(const nsIDocument&,
+                   nsIContent*,
+                   already_AddRefed<nsIURI> aURI,
+                   already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
+                   mozilla::net::ReferrerPolicy aReferrerPolicy,
+                   mozilla::CORSMode aCORSMode,
+                   const nsAString& aTitle,
+                   const nsAString& aMedia,
+                   HasAlternateRel aHasAlternateRel,
+                   IsInline aIsInline);
+
+    ~StyleSheetInfo();
+  };
+
+
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
 
   /**
    * Used to make the association between a style sheet and
    * the element that linked it to the document.
    *
    * @param aStyleSheet the style sheet associated with this
    *                    element.
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -32,27 +32,28 @@
 #include "nsStyleUtil.h"
 #include "nsQueryObject.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsStyleLinkElement::StyleSheetInfo::StyleSheetInfo(
   const nsIDocument& aDocument,
-  const nsIContent* aContent,
+  nsIContent* aContent,
   already_AddRefed<nsIURI> aURI,
   already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
   mozilla::net::ReferrerPolicy aReferrerPolicy,
   mozilla::CORSMode aCORSMode,
   const nsAString& aTitle,
   const nsAString& aMedia,
   HasAlternateRel aHasAlternateRel,
   IsInline aIsInline
 )
-  : mURI(aURI)
+  : mContent(aContent)
+  , mURI(aURI)
   , mTriggeringPrincipal(aTriggeringPrincipal)
   , mReferrerPolicy(aReferrerPolicy)
   , mCORSMode(aCORSMode)
   , mTitle(aTitle)
   , mMedia(aMedia)
   , mHasAlternateRel(aHasAlternateRel == HasAlternateRel::Yes)
   , mIsInline(aIsInline == IsInline::Yes)
 {
@@ -355,47 +356,29 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
                                            mLineNumber, text, &rv)) {
       if (NS_FAILED(rv)) {
         return Err(rv);
       }
       return Update { };
     }
 
     // Parse the style sheet.
-    return doc->CSSLoader()->
-      LoadInlineStyle(thisContent,
-                      text,
-                      info->mTriggeringPrincipal,
-                      mLineNumber,
-                      info->mTitle,
-                      info->mMedia,
-                      info->mReferrerPolicy,
-                      aObserver);
+    return doc->CSSLoader()->LoadInlineStyle(*info, text, mLineNumber, aObserver);
   }
   nsAutoString integrity;
   if (thisContent->IsElement()) {
     thisContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::integrity,
                                       integrity);
   }
   if (!integrity.IsEmpty()) {
     MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug,
             ("nsStyleLinkElement::DoUpdateStyleSheet, integrity=%s",
              NS_ConvertUTF16toUTF8(integrity).get()));
   }
-  auto resultOrError =
-    doc->CSSLoader()->LoadStyleLink(thisContent,
-                                    info->mURI,
-                                    info->mTriggeringPrincipal,
-                                    info->mTitle,
-                                    info->mMedia,
-                                    info->mHasAlternateRel,
-                                    info->mCORSMode,
-                                    info->mReferrerPolicy,
-                                    info->mIntegrity,
-                                    aObserver);
+  auto resultOrError = doc->CSSLoader()->LoadStyleLink(*info, aObserver);
   if (resultOrError.isErr()) {
     // Don't propagate LoadStyleLink() errors further than this, since some
     // consumers (e.g. nsXMLContentSink) will completely abort on innocuous
     // things like a stylesheet load being blocked by the security system.
     return Update { };
   }
   return resultOrError;
 }
--- a/dom/base/nsStyleLinkElement.h
+++ b/dom/base/nsStyleLinkElement.h
@@ -29,59 +29,16 @@ namespace mozilla {
 class CSSStyleSheet;
 namespace dom {
 class ShadowRoot;
 } // namespace dom
 } // namespace mozilla
 
 class nsStyleLinkElement : public nsIStyleSheetLinkingElement
 {
-protected:
-  enum class IsInline
-  {
-    Yes,
-    No
-  };
-
-  enum class HasAlternateRel
-  {
-    Yes,
-    No
-  };
-
-  struct MOZ_STACK_CLASS StyleSheetInfo
-  {
-    const nsIContent* mContent;
-    // FIXME(emilio): do these really need to be strong refs?
-    nsCOMPtr<nsIURI> mURI;
-    nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
-    mozilla::net::ReferrerPolicy mReferrerPolicy;
-    mozilla::CORSMode mCORSMode;
-    nsAutoString mTitle;
-    nsAutoString mMedia;
-    nsAutoString mIntegrity;
-
-    bool mIsAlternate : 1;
-    bool mHasAlternateRel : 1;
-    bool mIsInline : 1;
-
-    StyleSheetInfo(const nsIDocument&,
-                   const nsIContent*,
-                   already_AddRefed<nsIURI> aURI,
-                   already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
-                   mozilla::net::ReferrerPolicy aReferrerPolicy,
-                   mozilla::CORSMode aCORSMode,
-                   const nsAString& aTitle,
-                   const nsAString& aMedia,
-                   HasAlternateRel aHasAlternateRel,
-                   IsInline aIsInline);
-
-    ~StyleSheetInfo();
-  };
-
 public:
   nsStyleLinkElement();
   virtual ~nsStyleLinkElement();
 
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override = 0;
 
   mozilla::StyleSheet* GetSheet() const { return mStyleSheet; }
 
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -1880,87 +1880,91 @@ Loader::MarkLoadTreeFailed(SheetLoadData
       MarkLoadTreeFailed(aLoadData->mParentData);
     }
 
     aLoadData = aLoadData->mNext;
   } while (aLoadData);
 }
 
 Result<Loader::LoadSheetResult, nsresult>
-Loader::LoadInlineStyle(nsIContent* aElement,
+Loader::LoadInlineStyle(const StyleSheetInfo& aInfo,
                         const nsAString& aBuffer,
-                        nsIPrincipal* aTriggeringPrincipal,
                         uint32_t aLineNumber,
-                        const nsAString& aTitle,
-                        const nsAString& aMedia,
-                        ReferrerPolicy aReferrerPolicy,
                         nsICSSLoaderObserver* aObserver)
 {
   LOG(("css::Loader::LoadInlineStyle"));
 
   if (!mEnabled) {
     LOG_WARN(("  Not enabled"));
     return Err(NS_ERROR_NOT_AVAILABLE);
   }
 
   if (!mDocument) {
     return Err(NS_ERROR_NOT_INITIALIZED);
   }
 
-  nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(do_QueryInterface(aElement));
+  nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(
+      do_QueryInterface(aInfo.mContent));
   NS_ASSERTION(owningElement, "Element is not a style linking element!");
 
   // Since we're not planning to load a URI, no need to hand a principal to the
-  // load data or to CreateSheet().  Also, OK to use CORS_NONE for the CORS
-  // mode.
+  // load data or to CreateSheet().
 
   StyleSheetState state;
   RefPtr<StyleSheet> sheet;
   IsAlternate isAlternate;
-  nsresult rv = CreateSheet(nullptr, aElement, nullptr, eAuthorSheetFeatures,
-                            CORS_NONE, aReferrerPolicy,
-                            EmptyString(), // no inline integrity checks
-                            false, false, aTitle, state, &isAlternate,
+  nsresult rv = CreateSheet(aInfo,
+                            nullptr,
+                            eAuthorSheetFeatures,
+                            false,
+                            state,
+                            &isAlternate,
                             &sheet);
   if (NS_FAILED(rv)) {
     return Err(rv);
   }
   NS_ASSERTION(state == eSheetNeedsParser,
                "Inline sheets should not be cached");
 
   LOG(("  Sheet is alternate: %d", static_cast<int>(isAlternate)));
 
-  auto matched = PrepareSheet(sheet, aTitle, aMedia, nullptr, isAlternate);
+  auto matched =
+    PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate);
 
-  if (aElement->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
-    ShadowRoot* containingShadow = aElement->GetContainingShadow();
+  if (aInfo.mContent->HasFlag(NODE_IS_IN_SHADOW_TREE)) {
+    ShadowRoot* containingShadow = aInfo.mContent->GetContainingShadow();
     MOZ_ASSERT(containingShadow);
-    containingShadow->InsertSheet(sheet, aElement);
+    containingShadow->InsertSheet(sheet, aInfo.mContent);
   } else {
-    rv = InsertSheetInDoc(sheet, aElement, mDocument);
+    rv = InsertSheetInDoc(sheet, aInfo.mContent, mDocument);
     if (NS_FAILED(rv)) {
       return Err(rv);
     }
   }
 
-  nsIPrincipal* principal = aElement->NodePrincipal();
-  if (aTriggeringPrincipal) {
+  nsIPrincipal* principal = aInfo.mContent->NodePrincipal();
+  if (aInfo.mTriggeringPrincipal) {
     // The triggering principal may be an expanded principal, which is safe to
     // use for URL security checks, but not as the loader principal for a
     // stylesheet. So treat this as principal inheritance, and downgrade if
     // necessary.
-    principal = BasePrincipal::Cast(aTriggeringPrincipal)->PrincipalToInherit();
+    principal =
+      BasePrincipal::Cast(aInfo.mTriggeringPrincipal)->PrincipalToInherit();
   }
 
-  SheetLoadData* data = new SheetLoadData(this, aTitle, nullptr, sheet,
+  SheetLoadData* data = new SheetLoadData(this,
+                                          aInfo.mTitle,
+                                          nullptr,
+                                          sheet,
                                           owningElement,
                                           isAlternate == IsAlternate::Yes,
                                           matched == MediaMatched::Yes,
-                                          aObserver, nullptr,
-                                          static_cast<nsINode*>(aElement));
+                                          aObserver,
+                                          nullptr,
+                                          aInfo.mContent);
 
   // We never actually load this, so just set its principal directly
   sheet->SetPrincipal(principal);
 
   NS_ADDREF(data);
   data->mLineNumber = aLineNumber;
   bool completed = true;
   // Parse completion releases the load data.
@@ -1972,130 +1976,132 @@ Loader::LoadInlineStyle(nsIContent* aEle
   // If completed is true, |data| may well be deleted by now.
   if (!completed) {
     data->mMustNotify = true;
   }
   return LoadSheetResult { completed ? Completed::Yes : Completed::No, isAlternate, matched };
 }
 
 Result<Loader::LoadSheetResult, nsresult>
-Loader::LoadStyleLink(nsIContent* aElement,
-                      nsIURI* aURL,
-                      nsIPrincipal* aTriggeringPrincipal,
-                      const nsAString& aTitle,
-                      const nsAString& aMedia,
-                      bool aHasAlternateRel,
-                      CORSMode aCORSMode,
-                      ReferrerPolicy aReferrerPolicy,
-                      const nsAString& aIntegrity,
+Loader::LoadStyleLink(const StyleSheetInfo& aInfo,
                       nsICSSLoaderObserver* aObserver)
 {
-  MOZ_ASSERT(aURL, "Must have URL to load");
+  MOZ_ASSERT(aInfo.mURI, "Must have URL to load");
   LOG(("css::Loader::LoadStyleLink"));
-  LOG_URI("  Link uri: '%s'", aURL);
-  LOG(("  Link title: '%s'", NS_ConvertUTF16toUTF8(aTitle).get()));
-  LOG(("  Link media: '%s'", NS_ConvertUTF16toUTF8(aMedia).get()));
-  LOG(("  Link alternate rel: %d", aHasAlternateRel));
+  LOG_URI("  Link uri: '%s'", aInfo.mURI);
+  LOG(("  Link title: '%s'", NS_ConvertUTF16toUTF8(aInfo.mTitle).get()));
+  LOG(("  Link media: '%s'", NS_ConvertUTF16toUTF8(aInfo.mMedia).get()));
+  LOG(("  Link alternate rel: %d", aInfo.mHasAlternateRel));
 
   if (!mEnabled) {
     LOG_WARN(("  Not enabled"));
     return Err(NS_ERROR_NOT_AVAILABLE);
   }
 
   if (!mDocument) {
     return Err(NS_ERROR_NOT_INITIALIZED);
   }
 
-  nsIPrincipal* loadingPrincipal = aElement ? aElement->NodePrincipal()
-                                            : mDocument->NodePrincipal();
+  nsIPrincipal* loadingPrincipal = aInfo.mContent
+    ? aInfo.mContent->NodePrincipal()
+    : mDocument->NodePrincipal();
 
-  nsIPrincipal* principal = aTriggeringPrincipal ? aTriggeringPrincipal
-                                                 : loadingPrincipal;
+  nsIPrincipal* principal = aInfo.mTriggeringPrincipal
+    ? aInfo.mTriggeringPrincipal.get()
+    : loadingPrincipal;
 
-  nsISupports* context = aElement;
+  nsINode* context = aInfo.mContent;
   if (!context) {
     context = mDocument;
   }
 
-  nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aURL, context, false);
+  nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aInfo.mURI, context, false);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     // Don't fire the error event if our document is loaded as data.  We're
     // supposed to not even try to do loads in that case... Unfortunately, we
     // implement that via nsDataDocumentContentPolicy, which doesn't have a good
     // way to communicate back to us that _it_ is the thing that blocked the
     // load.
-    if (aElement && !mDocument->IsLoadedAsData()) {
+    if (aInfo.mContent && !mDocument->IsLoadedAsData()) {
       // Fire an async error event on it.
       RefPtr<AsyncEventDispatcher> loadBlockingAsyncDispatcher =
-        new LoadBlockingAsyncEventDispatcher(aElement,
+        new LoadBlockingAsyncEventDispatcher(aInfo.mContent,
                                              NS_LITERAL_STRING("error"),
                                              false, false);
       loadBlockingAsyncDispatcher->PostDOMEvent();
     }
     return Err(rv);
   }
 
   StyleSheetState state;
   RefPtr<StyleSheet> sheet;
   IsAlternate isAlternate;
-  rv = CreateSheet(aURL, aElement, principal, eAuthorSheetFeatures,
-                   aCORSMode, aReferrerPolicy, aIntegrity, false,
-                   aHasAlternateRel, aTitle, state, &isAlternate,
+  rv = CreateSheet(aInfo,
+                   principal,
+                   eAuthorSheetFeatures,
+                   false,
+                   state,
+                   &isAlternate,
                    &sheet);
   if (NS_FAILED(rv)) {
     return Err(rv);
   }
 
   LOG(("  Sheet is alternate: %d", static_cast<int>(isAlternate)));
 
-  auto matched = PrepareSheet(sheet, aTitle, aMedia, nullptr, isAlternate);
+  auto matched =
+    PrepareSheet(sheet, aInfo.mTitle, aInfo.mMedia, nullptr, isAlternate);
 
   // FIXME(emilio, bug 1410578): Shadow DOM should be handled here too.
-  rv = InsertSheetInDoc(sheet, aElement, mDocument);
+  rv = InsertSheetInDoc(sheet, aInfo.mContent, mDocument);
   if (NS_FAILED(rv)) {
     return Err(rv);
   }
 
-  nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(do_QueryInterface(aElement));
+  nsCOMPtr<nsIStyleSheetLinkingElement> owningElement(
+    do_QueryInterface(aInfo.mContent));
 
   if (state == eSheetComplete) {
     LOG(("  Sheet already complete: 0x%p", sheet.get()));
     if (aObserver || !mObservers.IsEmpty() || owningElement) {
-      rv = PostLoadEvent(aURL,
+      rv = PostLoadEvent(aInfo.mURI,
                          sheet,
                          aObserver,
                          isAlternate,
                          matched,
                          owningElement);
       if (NS_FAILED(rv)) {
         return Err(rv);
       }
     }
 
     // The load hasn't been completed yet, will be done in PostLoadEvent.
     return LoadSheetResult { Completed::No, isAlternate, matched };
   }
 
-  // Now we need to actually load it
-  nsCOMPtr<nsINode> requestingNode = do_QueryInterface(context);
-  SheetLoadData* data = new SheetLoadData(this, aTitle, aURL, sheet,
+  // Now we need to actually load it.
+  SheetLoadData* data = new SheetLoadData(this,
+                                          aInfo.mTitle,
+                                          aInfo.mURI,
+                                          sheet,
                                           owningElement,
                                           isAlternate == IsAlternate::Yes,
                                           matched == MediaMatched::Yes,
-                                          aObserver, principal, requestingNode);
+                                          aObserver,
+                                          principal,
+                                          context);
   NS_ADDREF(data);
 
   auto result = LoadSheetResult { Completed::No, isAlternate, matched };
 
   MOZ_ASSERT(result.ShouldBlock() == !data->ShouldDefer(),
              "These should better match!");
 
   // If we have to parse and it's a non-blocking non-inline sheet, defer it.
-  if (aURL &&
-      state == eSheetNeedsParser &&
+  if (state == eSheetNeedsParser &&
       mSheets->mLoadingDatas.Count() != 0 &&
       !result.ShouldBlock()) {
     LOG(("  Deferring sheet load"));
     URIPrincipalReferrerPolicyAndCORSModeHashKey key(data->mURI,
                                                      data->mLoaderPrincipal,
                                                      data->mSheet->GetCORSMode(),
                                                      data->mSheet->GetReferrerPolicy());
     mSheets->mPendingDatas.Put(&key, data);
@@ -2171,17 +2177,17 @@ Loader::LoadChildSheet(StyleSheet* aPare
   if (aParentSheet->GetAssociatedDocument()) {
     StyleSheet* topSheet = aParentSheet;
     while (StyleSheet* parent = topSheet->GetParentSheet()) {
       topSheet = parent;
     }
     owningNode = topSheet->GetOwnerNode();
   }
 
-  nsISupports* context = nullptr;
+  nsINode* context = nullptr;
   nsIPrincipal* loadingPrincipal = nullptr;
   if (owningNode) {
     context = owningNode;
     loadingPrincipal = owningNode->NodePrincipal();
   } else if (mDocument) {
     context = mDocument;
     loadingPrincipal = mDocument->NodePrincipal();
   }
@@ -2243,19 +2249,18 @@ Loader::LoadChildSheet(StyleSheet* aPare
   if (state == eSheetComplete) {
     LOG(("  Sheet already complete"));
     // We're completely done.  No need to notify, even, since the
     // @import rule addition/modification will trigger the right style
     // changes automatically.
     return NS_OK;
   }
 
-  nsCOMPtr<nsINode> requestingNode = do_QueryInterface(context);
   SheetLoadData* data = new SheetLoadData(this, aURL, sheet, aParentData,
-                                          observer, principal, requestingNode);
+                                          observer, principal, context);
 
   NS_ADDREF(data);
   bool syncLoad = data->mSyncLoad;
 
   // Load completion will release the data
   rv = LoadSheet(data, state, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -186,20 +186,23 @@ enum StyleSheetState {
   eSheetLoading,
   eSheetComplete
 };
 
 class Loader final {
   typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
 
 public:
+  typedef nsIStyleSheetLinkingElement::Completed Completed;
+  typedef nsIStyleSheetLinkingElement::HasAlternateRel HasAlternateRel;
   typedef nsIStyleSheetLinkingElement::IsAlternate IsAlternate;
+  typedef nsIStyleSheetLinkingElement::IsInline IsInline;
   typedef nsIStyleSheetLinkingElement::MediaMatched MediaMatched;
-  typedef nsIStyleSheetLinkingElement::Completed Completed;
   typedef nsIStyleSheetLinkingElement::Update LoadSheetResult;
+  typedef nsIStyleSheetLinkingElement::StyleSheetInfo StyleSheetInfo;
 
   Loader();
   // aDocGroup is used for dispatching SheetLoadData in PostLoadEvent(). It
   // can be null if you want to use this constructor, and there's no
   // document when the Loader is constructed.
   explicit Loader(mozilla::dom::DocGroup*);
   explicit Loader(nsIDocument*);
 
@@ -225,72 +228,37 @@ public:
 
   /**
    * Load an inline style sheet.  If a successful result is returned and
    * result.WillNotify() is true, then aObserver is guaranteed to be notified
    * asynchronously once the sheet is marked complete.  If an error is
    * returned, or if result.WillNotify() is false, aObserver will not be
    * notified.  In addition to parsing the sheet, this method will insert it
    * into the stylesheet list of this CSSLoader's document.
-   *
-   * @param aElement the element linking to the stylesheet.  This must not be
-   *                 null and must implement nsIStyleSheetLinkingElement.
-   * @param aBuffer the stylesheet data
-   * @param aTriggeringPrincipal The principal of the scripted caller that
-   *                             initiated the load, if available. Otherwise
-   *                             null.
-   * @param aLineNumber the line number at which the stylesheet data started.
-   * @param aTitle the title of the sheet.
-   * @param aMedia the media string for the sheet.
-   * @param aReferrerPolicy the referrer policy for loading the sheet.
    * @param aObserver the observer to notify when the load completes.
    *        May be null.
    */
   Result<LoadSheetResult, nsresult>
-    LoadInlineStyle(nsIContent* aElement,
+    LoadInlineStyle(const StyleSheetInfo&,
                     const nsAString& aBuffer,
-                    nsIPrincipal* aTriggeringPrincipal,
                     uint32_t aLineNumber,
-                    const nsAString& aTitle,
-                    const nsAString& aMedia,
-                    ReferrerPolicy aReferrerPolicy,
                     nsICSSLoaderObserver* aObserver);
 
   /**
    * Load a linked (document) stylesheet.  If a successful result is returned,
    * aObserver is guaranteed to be notified asynchronously once the sheet is
    * loaded and marked complete, i.e., result.WillNotify() will always return
    * true.  If an error is returned, aObserver will not be notified.  In
    * addition to loading the sheet, this method will insert it into the
    * stylesheet list of this CSSLoader's document.
-   *
-   * @param aElement the element linking to the the stylesheet.  May be null.
-   * @param aURL the URL of the sheet.
-   * @param aTriggeringPrincipal the triggering principal for the load. May be
-   *        null, in which case the NodePrincipal() of the element (or
-   *        document if aElement is null) should be used.
-   * @param aTitle the title of the sheet.
-   * @param aMedia the media string for the sheet.
-   * @param aHasAlternateRel whether the rel for this link included
-   *        "alternate".
-   * @param aCORSMode the CORS mode for this load.
    * @param aObserver the observer to notify when the load completes.
    *                  May be null.
    */
   Result<LoadSheetResult, nsresult>
-    LoadStyleLink(nsIContent* aElement,
-                  nsIURI* aURL,
-                  nsIPrincipal* aTriggeringPrincipal,
-                  const nsAString& aTitle,
-                  const nsAString& aMedia,
-                  bool aHasAlternateRel,
-                  CORSMode aCORSMode,
-                  ReferrerPolicy aReferrerPolicy,
-                  const nsAString& aIntegrity,
-                  nsICSSLoaderObserver* aObserver);
+    LoadStyleLink(const StyleSheetInfo&, nsICSSLoaderObserver* aObserver);
 
   /**
    * Load a child (@import-ed) style sheet.  In addition to loading the sheet,
    * this method will insert it into the child sheet list of aParentSheet.  If
    * there is no sheet currently being parsed and the child sheet is not
    * complete when this method returns, then when the child sheet becomes
    * complete aParentSheet will be QIed to nsICSSLoaderObserver and
    * asynchronously notified, just like for LoadStyleLink.  Note that if the
@@ -490,16 +458,39 @@ private:
   already_AddRefed<nsISerialEventTarget> DispatchTarget();
 
   nsresult CheckContentPolicy(nsIPrincipal* aLoadingPrincipal,
                               nsIPrincipal* aTriggeringPrincipal,
                               nsIURI* aTargetURI,
                               nsISupports* aContext,
                               bool aIsPreload);
 
+  nsresult CreateSheet(const StyleSheetInfo& aInfo,
+                       nsIPrincipal* aLoaderPrincipal,
+                       css::SheetParsingMode aParsingMode,
+                       bool aSyncLoad,
+                       StyleSheetState& aSheetState,
+                       IsAlternate* aIsAlternate,
+                       RefPtr<StyleSheet>* aSheet)
+  {
+    return CreateSheet(aInfo.mURI,
+                       aInfo.mContent,
+                       aLoaderPrincipal,
+                       aParsingMode,
+                       aInfo.mCORSMode,
+                       aInfo.mReferrerPolicy,
+                       aInfo.mIntegrity,
+                       aSyncLoad,
+                       aInfo.mHasAlternateRel,
+                       aInfo.mTitle,
+                       aSheetState,
+                       aIsAlternate,
+                       aSheet);
+  }
+
   // For inline style, the aURI param is null, but the aLinkingContent
   // must be non-null then.  The loader principal must never be null
   // if aURI is not null.
   // *aIsAlternate is set based on aTitle and aHasAlternateRel.
   nsresult CreateSheet(nsIURI* aURI,
                        nsIContent* aLinkingContent,
                        nsIPrincipal* aLoaderPrincipal,
                        css::SheetParsingMode aParsingMode,