LCOV - code coverage report
Current view: top level - dom/base - nsStyleLinkElement.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 80 299 26.8 %
Date: 2017-07-14 16:53:18 Functions: 8 24 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /*
       8             :  * A base class which implements nsIStyleSheetLinkingElement and can
       9             :  * be subclassed by various content nodes that want to load
      10             :  * stylesheets (<style>, <link>, processing instructions, etc).
      11             :  */
      12             : 
      13             : #include "nsStyleLinkElement.h"
      14             : 
      15             : #include "mozilla/StyleSheet.h"
      16             : #include "mozilla/StyleSheetInlines.h"
      17             : #include "mozilla/css/Loader.h"
      18             : #include "mozilla/dom/Element.h"
      19             : #include "mozilla/dom/FragmentOrElement.h"
      20             : #include "mozilla/dom/HTMLLinkElement.h"
      21             : #include "mozilla/dom/ShadowRoot.h"
      22             : #include "mozilla/dom/SRILogHelper.h"
      23             : #include "mozilla/Preferences.h"
      24             : #include "nsIContent.h"
      25             : #include "nsIDocument.h"
      26             : #include "nsIDOMComment.h"
      27             : #include "nsIDOMNode.h"
      28             : #include "nsIDOMStyleSheet.h"
      29             : #include "nsUnicharUtils.h"
      30             : #include "nsCRT.h"
      31             : #include "nsXPCOMCIDInternal.h"
      32             : #include "nsUnicharInputStream.h"
      33             : #include "nsContentUtils.h"
      34             : #include "nsStyleUtil.h"
      35             : #include "nsQueryObject.h"
      36             : #include "nsIContentPolicyBase.h"
      37             : #include "nsMimeTypes.h"
      38             : #include "imgLoader.h"
      39             : #include "MediaContainerType.h"
      40             : #include "DecoderDoctorDiagnostics.h"
      41             : #include "DecoderTraits.h"
      42             : #include "MediaList.h"
      43             : #include "nsAttrValueInlines.h"
      44             : 
      45             : using namespace mozilla;
      46             : using namespace mozilla::dom;
      47             : 
      48          11 : nsStyleLinkElement::nsStyleLinkElement()
      49             :   : mDontLoadStyle(false)
      50             :   , mUpdatesEnabled(true)
      51          11 :   , mLineNumber(1)
      52             : {
      53          11 : }
      54             : 
      55           0 : nsStyleLinkElement::~nsStyleLinkElement()
      56             : {
      57           0 :   nsStyleLinkElement::SetStyleSheet(nullptr);
      58           0 : }
      59             : 
      60             : void
      61           0 : nsStyleLinkElement::Unlink()
      62             : {
      63           0 :   nsStyleLinkElement::SetStyleSheet(nullptr);
      64           0 : }
      65             : 
      66             : void
      67           0 : nsStyleLinkElement::Traverse(nsCycleCollectionTraversalCallback &cb)
      68             : {
      69           0 :   nsStyleLinkElement* tmp = this;
      70           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheet);
      71           0 : }
      72             : 
      73             : NS_IMETHODIMP
      74          11 : nsStyleLinkElement::SetStyleSheet(StyleSheet* aStyleSheet)
      75             : {
      76          11 :   if (mStyleSheet) {
      77           0 :     mStyleSheet->SetOwningNode(nullptr);
      78             :   }
      79             : 
      80          11 :   mStyleSheet = aStyleSheet;
      81          11 :   if (mStyleSheet) {
      82          22 :     nsCOMPtr<nsINode> node = do_QueryObject(this);
      83          11 :     if (node) {
      84          11 :       mStyleSheet->SetOwningNode(node);
      85             :     }
      86             :   }
      87             : 
      88          11 :   return NS_OK;
      89             : }
      90             : 
      91             : NS_IMETHODIMP_(StyleSheet*)
      92           0 : nsStyleLinkElement::GetStyleSheet()
      93             : {
      94           0 :   return mStyleSheet;
      95             : }
      96             : 
      97             : NS_IMETHODIMP
      98          11 : nsStyleLinkElement::InitStyleLinkElement(bool aDontLoadStyle)
      99             : {
     100          11 :   mDontLoadStyle = aDontLoadStyle;
     101             : 
     102          11 :   return NS_OK;
     103             : }
     104             : 
     105             : NS_IMETHODIMP
     106          22 : nsStyleLinkElement::SetEnableUpdates(bool aEnableUpdates)
     107             : {
     108          22 :   mUpdatesEnabled = aEnableUpdates;
     109             : 
     110          22 :   return NS_OK;
     111             : }
     112             : 
     113             : NS_IMETHODIMP
     114           0 : nsStyleLinkElement::GetCharset(nsAString& aCharset)
     115             : {
     116             :   // descendants have to implement this themselves
     117           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     118             : }
     119             : 
     120             : /* virtual */ void
     121           0 : nsStyleLinkElement::OverrideBaseURI(nsIURI* aNewBaseURI)
     122             : {
     123           0 :   NS_NOTREACHED("Base URI can't be overriden in this implementation "
     124             :                 "of nsIStyleSheetLinkingElement.");
     125           0 : }
     126             : 
     127             : /* virtual */ void
     128           5 : nsStyleLinkElement::SetLineNumber(uint32_t aLineNumber)
     129             : {
     130           5 :   mLineNumber = aLineNumber;
     131           5 : }
     132             : 
     133             : /* virtual */ uint32_t
     134           0 : nsStyleLinkElement::GetLineNumber()
     135             : {
     136           0 :   return mLineNumber;
     137             : }
     138             : 
     139           0 : static uint32_t ToLinkMask(const nsAString& aLink)
     140             : {
     141             :   // Keep this in sync with sRelValues in HTMLLinkElement.cpp
     142           0 :   if (aLink.EqualsLiteral("prefetch"))
     143           0 :     return nsStyleLinkElement::ePREFETCH;
     144           0 :   else if (aLink.EqualsLiteral("dns-prefetch"))
     145           0 :     return nsStyleLinkElement::eDNS_PREFETCH;
     146           0 :   else if (aLink.EqualsLiteral("stylesheet"))
     147           0 :     return nsStyleLinkElement::eSTYLESHEET;
     148           0 :   else if (aLink.EqualsLiteral("next"))
     149           0 :     return nsStyleLinkElement::eNEXT;
     150           0 :   else if (aLink.EqualsLiteral("alternate"))
     151           0 :     return nsStyleLinkElement::eALTERNATE;
     152           0 :   else if (aLink.EqualsLiteral("preconnect"))
     153           0 :     return nsStyleLinkElement::ePRECONNECT;
     154           0 :   else if (aLink.EqualsLiteral("preload"))
     155           0 :     return nsStyleLinkElement::ePRELOAD;
     156           0 :   else if (aLink.EqualsLiteral("prerender"))
     157           0 :     return nsStyleLinkElement::ePRERENDER;
     158             :   else
     159           0 :     return 0;
     160             : }
     161             : 
     162           0 : uint32_t nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
     163             : {
     164           0 :   uint32_t linkMask = 0;
     165           0 :   nsAString::const_iterator start, done;
     166           0 :   aTypes.BeginReading(start);
     167           0 :   aTypes.EndReading(done);
     168           0 :   if (start == done)
     169           0 :     return linkMask;
     170             : 
     171           0 :   nsAString::const_iterator current(start);
     172           0 :   bool inString = !nsContentUtils::IsHTMLWhitespace(*current);
     173           0 :   nsAutoString subString;
     174             : 
     175           0 :   while (current != done) {
     176           0 :     if (nsContentUtils::IsHTMLWhitespace(*current)) {
     177           0 :       if (inString) {
     178           0 :         nsContentUtils::ASCIIToLower(Substring(start, current), subString);
     179           0 :         linkMask |= ToLinkMask(subString);
     180           0 :         inString = false;
     181             :       }
     182             :     }
     183             :     else {
     184           0 :       if (!inString) {
     185           0 :         start = current;
     186           0 :         inString = true;
     187             :       }
     188             :     }
     189           0 :     ++current;
     190             :   }
     191           0 :   if (inString) {
     192           0 :     nsContentUtils::ASCIIToLower(Substring(start, current), subString);
     193           0 :     linkMask |= ToLinkMask(subString);
     194             :   }
     195           0 :   return linkMask;
     196             : }
     197             : 
     198             : // We will use official mime-types from:
     199             : // https://www.iana.org/assignments/media-types/media-types.xhtml#font
     200             : // We do not support old deprecated mime-types for preload feature.
     201             : // (We currectly do not support font/collection)
     202             : static uint32_t StyleLinkElementFontMimeTypesNum = 5;
     203             : static const char* StyleLinkElementFontMimeTypes[] = {
     204             :   "font/otf",
     205             :   "font/sfnt",
     206             :   "font/ttf",
     207             :   "font/woff",
     208             :   "font/woff2"
     209             : };
     210             : 
     211             : bool
     212           0 : IsFontMimeType(const nsAString& aType)
     213             : {
     214           0 :   if (aType.IsEmpty()) {
     215           0 :     return true;
     216             :   }
     217           0 :   for (uint32_t i = 0; i < StyleLinkElementFontMimeTypesNum; i++) {
     218           0 :     if (aType.EqualsASCII(StyleLinkElementFontMimeTypes[i])) {
     219           0 :       return true;
     220             :     }
     221             :   }
     222           0 :   return false;
     223             : }
     224             : 
     225             : bool
     226           0 : nsStyleLinkElement::CheckPreloadAttrs(const nsAttrValue& aAs,
     227             :                                       const nsAString& aType,
     228             :                                       const nsAString& aMedia,
     229             :                                       nsIDocument* aDocument)
     230             : {
     231           0 :   nsContentPolicyType policyType = Link::AsValueToContentPolicy(aAs);
     232           0 :   if (policyType == nsIContentPolicy::TYPE_INVALID) {
     233           0 :     return false;
     234             :   }
     235             : 
     236             :   // Check if media attribute is valid.
     237           0 :   if (!aMedia.IsEmpty()) {
     238           0 :     RefPtr<MediaList> mediaList = MediaList::Create(aDocument->GetStyleBackendType(),
     239           0 :                                                     aMedia);
     240           0 :     nsIPresShell* shell = aDocument->GetShell();
     241           0 :     if (!shell) {
     242           0 :       return false;
     243             :     }
     244             : 
     245           0 :     nsPresContext* presContext = shell->GetPresContext();
     246           0 :     if (!presContext) {
     247           0 :       return false;
     248             :     }
     249           0 :     if (!mediaList->Matches(presContext)) {
     250           0 :       return false;
     251             :     }
     252             :   }
     253             : 
     254           0 :   if (aType.IsEmpty()) {
     255           0 :     return true;
     256             :   }
     257             : 
     258           0 :   nsString type = nsString(aType);
     259           0 :   ToLowerCase(type);
     260             : 
     261           0 :   if (policyType == nsIContentPolicy::TYPE_OTHER) {
     262           0 :     return true;
     263             : 
     264           0 :   } else if (policyType == nsIContentPolicy::TYPE_MEDIA) {
     265           0 :     if (aAs.GetEnumValue() == DESTINATION_TRACK) {
     266           0 :       if (type.EqualsASCII("text/vtt")) {
     267           0 :         return true;
     268             :       } else {
     269           0 :         return false;
     270             :       }
     271             :     }
     272           0 :     Maybe<MediaContainerType> mimeType = MakeMediaContainerType(aType);
     273           0 :     if (!mimeType) {
     274           0 :       return false;
     275             :     }
     276           0 :     DecoderDoctorDiagnostics diagnostics;
     277           0 :     CanPlayStatus status = DecoderTraits::CanHandleContainerType(*mimeType,
     278           0 :                                                                  &diagnostics);
     279             :     // Preload if this return CANPLAY_YES and CANPLAY_MAYBE.
     280           0 :     if (status == CANPLAY_NO) {
     281           0 :       return false;
     282             :     } else {
     283           0 :       return true;
     284             :     }
     285             : 
     286           0 :   } else if (policyType == nsIContentPolicy::TYPE_FONT) {
     287           0 :     if (IsFontMimeType(type)) {
     288           0 :       return true;
     289             :     } else {
     290           0 :       return false;
     291             :     }
     292             : 
     293           0 :   } else if (policyType == nsIContentPolicy::TYPE_IMAGE) {
     294           0 :     if (imgLoader::SupportImageWithMimeType(NS_ConvertUTF16toUTF8(type).get(),
     295             :                                             AcceptedMimeTypes::IMAGES_AND_DOCUMENTS)) {
     296           0 :       return true;
     297             :     } else {
     298           0 :       return false;
     299             :     }
     300             : 
     301           0 :   } else if (policyType == nsIContentPolicy::TYPE_SCRIPT) {
     302           0 :     if (nsContentUtils::IsJavascriptMIMEType(type)) {
     303           0 :       return true;
     304             :     } else {
     305           0 :       return false;
     306             :     }
     307             : 
     308           0 :   } else if (policyType == nsIContentPolicy::TYPE_STYLESHEET) {
     309           0 :     if (type.EqualsASCII("text/css")) {
     310           0 :       return true;
     311             :     } else {
     312           0 :       return false;
     313             :     }
     314             :   }
     315           0 :   return false;
     316             : }
     317             : 
     318             : NS_IMETHODIMP
     319          11 : nsStyleLinkElement::UpdateStyleSheet(nsICSSLoaderObserver* aObserver,
     320             :                                      bool* aWillNotify,
     321             :                                      bool* aIsAlternate,
     322             :                                      bool aForceReload)
     323             : {
     324          11 :   if (aForceReload) {
     325             :     // We remove this stylesheet from the cache to load a new version.
     326           0 :     nsCOMPtr<nsIContent> thisContent;
     327           0 :     CallQueryInterface(this, getter_AddRefs(thisContent));
     328           0 :     nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
     329           0 :       thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
     330           0 :     if (doc && doc->CSSLoader()->GetEnabled() &&
     331           0 :         mStyleSheet && !mStyleSheet->IsInline()) {
     332           0 :       doc->CSSLoader()->ObsoleteSheet(mStyleSheet->GetOriginalURI());
     333             :     }
     334             :   }
     335          11 :   return DoUpdateStyleSheet(nullptr, nullptr, aObserver, aWillNotify,
     336          11 :                             aIsAlternate, aForceReload);
     337             : }
     338             : 
     339             : nsresult
     340          11 : nsStyleLinkElement::UpdateStyleSheetInternal(nsIDocument *aOldDocument,
     341             :                                              ShadowRoot *aOldShadowRoot,
     342             :                                              bool aForceUpdate)
     343             : {
     344             :   bool notify, alternate;
     345          11 :   return DoUpdateStyleSheet(aOldDocument, aOldShadowRoot, nullptr, &notify,
     346          11 :                             &alternate, aForceUpdate);
     347             : }
     348             : 
     349             : static bool
     350           0 : IsScopedStyleElement(nsIContent* aContent)
     351             : {
     352             :   // This is quicker than, say, QIing aContent to nsStyleLinkElement
     353             :   // and then calling its virtual GetStyleSheetInfo method to find out
     354             :   // if it is scoped.
     355           0 :   return (aContent->IsHTMLElement(nsGkAtoms::style) ||
     356           0 :           aContent->IsSVGElement(nsGkAtoms::style)) &&
     357           0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scoped) &&
     358           0 :          aContent->OwnerDoc()->IsScopedStyleEnabled();
     359             : }
     360             : 
     361             : static bool
     362           0 : HasScopedStyleSheetChild(nsIContent* aContent)
     363             : {
     364           0 :   for (nsIContent* n = aContent->GetFirstChild(); n; n = n->GetNextSibling()) {
     365           0 :     if (IsScopedStyleElement(n)) {
     366           0 :       return true;
     367             :     }
     368             :   }
     369           0 :   return false;
     370             : }
     371             : 
     372             : // Called when aElement has had a <style scoped> child removed.
     373             : static void
     374           0 : UpdateIsElementInStyleScopeFlagOnSubtree(Element* aElement)
     375             : {
     376           0 :   NS_ASSERTION(aElement->IsElementInStyleScope(),
     377             :                "only call UpdateIsElementInStyleScopeFlagOnSubtree on a "
     378             :                "subtree that has IsElementInStyleScope boolean flag set");
     379             : 
     380           0 :   if (HasScopedStyleSheetChild(aElement)) {
     381           0 :     return;
     382             :   }
     383             : 
     384           0 :   aElement->ClearIsElementInStyleScope();
     385             : 
     386           0 :   nsIContent* n = aElement->GetNextNode(aElement);
     387           0 :   while (n) {
     388           0 :     if (HasScopedStyleSheetChild(n)) {
     389           0 :       n = n->GetNextNonChildNode(aElement);
     390             :     } else {
     391           0 :       if (n->IsElement()) {
     392           0 :         n->ClearIsElementInStyleScope();
     393             :       }
     394           0 :       n = n->GetNextNode(aElement);
     395             :     }
     396             :   }
     397             : }
     398             : 
     399             : nsresult
     400          22 : nsStyleLinkElement::DoUpdateStyleSheet(nsIDocument* aOldDocument,
     401             :                                        ShadowRoot* aOldShadowRoot,
     402             :                                        nsICSSLoaderObserver* aObserver,
     403             :                                        bool* aWillNotify,
     404             :                                        bool* aIsAlternate,
     405             :                                        bool aForceUpdate)
     406             : {
     407          22 :   *aWillNotify = false;
     408             : 
     409          44 :   nsCOMPtr<nsIContent> thisContent;
     410          22 :   CallQueryInterface(this, getter_AddRefs(thisContent));
     411             : 
     412             :   // All instances of nsStyleLinkElement should implement nsIContent.
     413          22 :   NS_ENSURE_TRUE(thisContent, NS_ERROR_FAILURE);
     414             : 
     415          22 :   if (thisContent->IsInAnonymousSubtree() &&
     416           0 :       thisContent->IsAnonymousContentInSVGUseSubtree()) {
     417             :     // Stylesheets in <use>-cloned subtrees are disabled until we figure out
     418             :     // how they should behave.
     419           0 :     return NS_OK;
     420             :   }
     421             : 
     422             :   // Check for a ShadowRoot because link elements are inert in a
     423             :   // ShadowRoot.
     424          22 :   ShadowRoot* containingShadow = thisContent->GetContainingShadow();
     425          22 :   if (thisContent->IsHTMLElement(nsGkAtoms::link) &&
     426           0 :       (aOldShadowRoot || containingShadow)) {
     427           0 :     return NS_OK;
     428             :   }
     429             : 
     430             :   // XXXheycam ServoStyleSheets do not support <style scoped>.
     431          22 :   Element* oldScopeElement = nullptr;
     432          22 :   if (mStyleSheet) {
     433           0 :     if (mStyleSheet->IsServo()) {
     434           0 :       NS_WARNING("stylo: ServoStyleSheets don't support <style scoped>");
     435             :     } else {
     436           0 :       oldScopeElement = mStyleSheet->AsGecko()->GetScopeElement();
     437             :     }
     438             :   }
     439             : 
     440          22 :   if (mStyleSheet && (aOldDocument || aOldShadowRoot)) {
     441           0 :     MOZ_ASSERT(!(aOldDocument && aOldShadowRoot),
     442             :                "ShadowRoot content is never in document, thus "
     443             :                "there should not be a old document and old "
     444             :                "ShadowRoot simultaneously.");
     445             : 
     446             :     // We're removing the link element from the document or shadow tree,
     447             :     // unload the stylesheet.  We want to do this even if updates are
     448             :     // disabled, since otherwise a sheet with a stale linking element pointer
     449             :     // will be hanging around -- not good!
     450           0 :     if (aOldShadowRoot) {
     451           0 :       aOldShadowRoot->RemoveSheet(mStyleSheet);
     452             :     } else {
     453           0 :       aOldDocument->BeginUpdate(UPDATE_STYLE);
     454           0 :       aOldDocument->RemoveStyleSheet(mStyleSheet);
     455           0 :       aOldDocument->EndUpdate(UPDATE_STYLE);
     456             :     }
     457             : 
     458           0 :     nsStyleLinkElement::SetStyleSheet(nullptr);
     459           0 :     if (oldScopeElement) {
     460           0 :       UpdateIsElementInStyleScopeFlagOnSubtree(oldScopeElement);
     461             :     }
     462             :   }
     463             : 
     464             :   // When static documents are created, stylesheets are cloned manually.
     465          33 :   if (mDontLoadStyle || !mUpdatesEnabled ||
     466          11 :       thisContent->OwnerDoc()->IsStaticDocument()) {
     467          11 :     return NS_OK;
     468             :   }
     469             : 
     470          11 :   nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
     471          22 :     thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
     472          11 :   if (!doc || !doc->CSSLoader()->GetEnabled()) {
     473           0 :     return NS_OK;
     474             :   }
     475             : 
     476             :   bool isInline;
     477          22 :   nsCOMPtr<nsIURI> uri = GetStyleSheetURL(&isInline);
     478             : 
     479          11 :   if (!aForceUpdate && mStyleSheet && !isInline && uri) {
     480           0 :     nsIURI* oldURI = mStyleSheet->GetSheetURI();
     481           0 :     if (oldURI) {
     482             :       bool equal;
     483           0 :       nsresult rv = oldURI->Equals(uri, &equal);
     484           0 :       if (NS_SUCCEEDED(rv) && equal) {
     485           0 :         return NS_OK; // We already loaded this stylesheet
     486             :       }
     487             :     }
     488             :   }
     489             : 
     490          11 :   if (mStyleSheet) {
     491           0 :     if (thisContent->IsInShadowTree()) {
     492           0 :       ShadowRoot* containingShadow = thisContent->GetContainingShadow();
     493           0 :       containingShadow->RemoveSheet(mStyleSheet);
     494             :     } else {
     495           0 :       doc->BeginUpdate(UPDATE_STYLE);
     496           0 :       doc->RemoveStyleSheet(mStyleSheet);
     497           0 :       doc->EndUpdate(UPDATE_STYLE);
     498             :     }
     499             : 
     500           0 :     nsStyleLinkElement::SetStyleSheet(nullptr);
     501             :   }
     502             : 
     503          11 :   if (!uri && !isInline) {
     504           0 :     return NS_OK; // If href is empty and this is not inline style then just bail
     505             :   }
     506             : 
     507          22 :   nsAutoString title, type, media;
     508             :   bool isScoped;
     509             :   bool isAlternate;
     510             : 
     511          11 :   GetStyleSheetInfo(title, type, media, &isScoped, &isAlternate);
     512             : 
     513          11 :   if (!type.LowerCaseEqualsLiteral("text/css")) {
     514           0 :     return NS_OK;
     515             :   }
     516             : 
     517          11 :   Element* scopeElement = isScoped ? thisContent->GetParentElement() : nullptr;
     518          11 :   if (scopeElement) {
     519           0 :     NS_ASSERTION(isInline, "non-inline style must not have scope element");
     520           0 :     scopeElement->SetIsElementInStyleScopeFlagOnSubtree(true);
     521             :   }
     522             : 
     523          11 :   bool doneLoading = false;
     524          11 :   nsresult rv = NS_OK;
     525          11 :   if (isInline) {
     526          10 :     nsAutoString text;
     527           5 :     if (!nsContentUtils::GetNodeTextContent(thisContent, false, text, fallible)) {
     528           0 :       return NS_ERROR_OUT_OF_MEMORY;
     529             :     }
     530             : 
     531           5 :     MOZ_ASSERT(thisContent->NodeInfo()->NameAtom() != nsGkAtoms::link,
     532             :                "<link> is not 'inline', and needs different CSP checks");
     533          10 :     if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent,
     534           5 :                                            thisContent->NodePrincipal(),
     535             :                                            doc->GetDocumentURI(),
     536             :                                            mLineNumber, text, &rv))
     537           0 :       return rv;
     538             : 
     539             :     // Parse the style sheet.
     540           5 :     rv = doc->CSSLoader()->
     541           5 :       LoadInlineStyle(thisContent, text, mLineNumber, title, media,
     542             :                       scopeElement, aObserver, &doneLoading, &isAlternate);
     543             :   }
     544             :   else {
     545          12 :     nsAutoString integrity;
     546           6 :     thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::integrity, integrity);
     547           6 :     if (!integrity.IsEmpty()) {
     548           0 :       MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug,
     549             :               ("nsStyleLinkElement::DoUpdateStyleSheet, integrity=%s",
     550             :                NS_ConvertUTF16toUTF8(integrity).get()));
     551             :     }
     552             : 
     553             :     // if referrer attributes are enabled in preferences, load the link's referrer
     554             :     // attribute. If the link does not provide a referrer attribute, ignore this
     555             :     // and use the document's referrer policy
     556             : 
     557           6 :     net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
     558           6 :     if (referrerPolicy == net::RP_Unset) {
     559           6 :       referrerPolicy = doc->GetReferrerPolicy();
     560             :     }
     561             : 
     562             :     // XXXbz clone the URI here to work around content policies modifying URIs.
     563          12 :     nsCOMPtr<nsIURI> clonedURI;
     564           6 :     uri->Clone(getter_AddRefs(clonedURI));
     565           6 :     NS_ENSURE_TRUE(clonedURI, NS_ERROR_OUT_OF_MEMORY);
     566           6 :     rv = doc->CSSLoader()->
     567           6 :       LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
     568           6 :                     GetCORSMode(), referrerPolicy, integrity,
     569             :                     aObserver, &isAlternate);
     570           6 :     if (NS_FAILED(rv)) {
     571             :       // Don't propagate LoadStyleLink() errors further than this, since some
     572             :       // consumers (e.g. nsXMLContentSink) will completely abort on innocuous
     573             :       // things like a stylesheet load being blocked by the security system.
     574           0 :       doneLoading = true;
     575           0 :       isAlternate = false;
     576           0 :       rv = NS_OK;
     577             :     }
     578             :   }
     579             : 
     580          11 :   NS_ENSURE_SUCCESS(rv, rv);
     581             : 
     582          11 :   *aWillNotify = !doneLoading;
     583          11 :   *aIsAlternate = isAlternate;
     584             : 
     585          11 :   return NS_OK;
     586             : }
     587             : 
     588             : void
     589           0 : nsStyleLinkElement::UpdateStyleSheetScopedness(bool aIsNowScoped)
     590             : {
     591           0 :   if (!mStyleSheet) {
     592           0 :     return;
     593             :   }
     594             : 
     595           0 :   if (mStyleSheet->IsServo()) {
     596             :     // XXXheycam ServoStyleSheets don't support <style scoped>.
     597           0 :     NS_ERROR("stylo: ServoStyleSheets don't support <style scoped>");
     598           0 :     return;
     599             :   }
     600             : 
     601           0 :   CSSStyleSheet* sheet = mStyleSheet->AsGecko();
     602             : 
     603           0 :   nsCOMPtr<nsIContent> thisContent;
     604           0 :   CallQueryInterface(this, getter_AddRefs(thisContent));
     605             : 
     606           0 :   Element* oldScopeElement = sheet->GetScopeElement();
     607           0 :   Element* newScopeElement = aIsNowScoped ?
     608           0 :                                thisContent->GetParentElement() :
     609           0 :                                nullptr;
     610             : 
     611           0 :   if (oldScopeElement == newScopeElement) {
     612           0 :     return;
     613             :   }
     614             : 
     615           0 :   nsIDocument* document = thisContent->GetOwnerDocument();
     616             : 
     617           0 :   if (thisContent->IsInShadowTree()) {
     618           0 :     ShadowRoot* containingShadow = thisContent->GetContainingShadow();
     619           0 :     containingShadow->RemoveSheet(mStyleSheet);
     620             : 
     621           0 :     sheet->SetScopeElement(newScopeElement);
     622             : 
     623           0 :     containingShadow->InsertSheet(mStyleSheet, thisContent);
     624             :   } else {
     625           0 :     document->BeginUpdate(UPDATE_STYLE);
     626           0 :     document->RemoveStyleSheet(mStyleSheet);
     627             : 
     628           0 :     sheet->SetScopeElement(newScopeElement);
     629             : 
     630           0 :     document->AddStyleSheet(mStyleSheet);
     631           0 :     document->EndUpdate(UPDATE_STYLE);
     632             :   }
     633             : 
     634           0 :   if (oldScopeElement) {
     635           0 :     UpdateIsElementInStyleScopeFlagOnSubtree(oldScopeElement);
     636             :   }
     637           0 :   if (newScopeElement) {
     638           0 :     newScopeElement->SetIsElementInStyleScopeFlagOnSubtree(true);
     639             :   }
     640             : }

Generated by: LCOV version 1.13