Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / core / html / HTMLLinkElement.cpp
blobc3d871ca039cd564f23123bcbd1da419450b5499
1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
6 * Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
7 * Copyright (C) 2011 Google Inc. All rights reserved.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
25 #include "config.h"
26 #include "core/html/HTMLLinkElement.h"
28 #include "bindings/core/v8/ScriptEventListener.h"
29 #include "bindings/core/v8/V8DOMActivityLogger.h"
30 #include "core/HTMLNames.h"
31 #include "core/css/MediaList.h"
32 #include "core/css/MediaQueryEvaluator.h"
33 #include "core/css/StyleSheetContents.h"
34 #include "core/css/resolver/StyleResolver.h"
35 #include "core/dom/Attribute.h"
36 #include "core/dom/Document.h"
37 #include "core/dom/StyleEngine.h"
38 #include "core/events/Event.h"
39 #include "core/events/EventSender.h"
40 #include "core/fetch/CSSStyleSheetResource.h"
41 #include "core/fetch/FetchRequest.h"
42 #include "core/fetch/ResourceFetcher.h"
43 #include "core/frame/FrameView.h"
44 #include "core/frame/LocalFrame.h"
45 #include "core/frame/SubresourceIntegrity.h"
46 #include "core/frame/UseCounter.h"
47 #include "core/frame/csp/ContentSecurityPolicy.h"
48 #include "core/html/LinkManifest.h"
49 #include "core/html/imports/LinkImport.h"
50 #include "core/inspector/ConsoleMessage.h"
51 #include "core/loader/FrameLoader.h"
52 #include "core/loader/FrameLoaderClient.h"
53 #include "core/loader/NetworkHintsInterface.h"
54 #include "core/style/StyleInheritedData.h"
55 #include "platform/RuntimeEnabledFeatures.h"
56 #include "wtf/StdLibExtras.h"
58 namespace blink {
60 using namespace HTMLNames;
62 template <typename CharacterType>
63 static void parseSizes(const CharacterType* value, unsigned length, Vector<IntSize>& iconSizes)
65 enum State {
66 ParseStart,
67 ParseWidth,
68 ParseHeight
70 int width = 0;
71 unsigned start = 0;
72 unsigned i = 0;
73 State state = ParseStart;
74 bool invalid = false;
75 for (; i < length; ++i) {
76 if (state == ParseWidth) {
77 if (value[i] == 'x' || value[i] == 'X') {
78 if (i == start) {
79 invalid = true;
80 break;
82 width = charactersToInt(value + start, i - start);
83 start = i + 1;
84 state = ParseHeight;
85 } else if (value[i] < '0' || value[i] > '9') {
86 invalid = true;
87 break;
89 } else if (state == ParseHeight) {
90 if (value[i] == ' ') {
91 if (i == start) {
92 invalid = true;
93 break;
95 int height = charactersToInt(value + start, i - start);
96 iconSizes.append(IntSize(width, height));
97 start = i + 1;
98 state = ParseStart;
99 } else if (value[i] < '0' || value[i] > '9') {
100 invalid = true;
101 break;
103 } else if (state == ParseStart) {
104 if (value[i] >= '0' && value[i] <= '9') {
105 start = i;
106 state = ParseWidth;
107 } else if (value[i] != ' ') {
108 invalid = true;
109 break;
113 if (invalid || state == ParseWidth || (state == ParseHeight && start == i)) {
114 iconSizes.clear();
115 return;
117 if (state == ParseHeight && i > start) {
118 int height = charactersToInt(value + start, i - start);
119 iconSizes.append(IntSize(width, height));
123 static LinkEventSender& linkLoadEventSender()
125 DEFINE_STATIC_LOCAL(LinkEventSender, sharedLoadEventSender, (EventTypeNames::load));
126 return sharedLoadEventSender;
129 void HTMLLinkElement::parseSizesAttribute(const AtomicString& value, Vector<IntSize>& iconSizes)
131 ASSERT(iconSizes.isEmpty());
132 if (value.isEmpty())
133 return;
134 if (value.is8Bit())
135 parseSizes(value.characters8(), value.length(), iconSizes);
136 else
137 parseSizes(value.characters16(), value.length(), iconSizes);
140 inline HTMLLinkElement::HTMLLinkElement(Document& document, bool createdByParser)
141 : HTMLElement(linkTag, document)
142 , m_linkLoader(this)
143 , m_sizes(DOMSettableTokenList::create())
144 , m_createdByParser(createdByParser)
145 , m_isInShadowTree(false)
149 PassRefPtrWillBeRawPtr<HTMLLinkElement> HTMLLinkElement::create(Document& document, bool createdByParser)
151 return adoptRefWillBeNoop(new HTMLLinkElement(document, createdByParser));
154 HTMLLinkElement::~HTMLLinkElement()
156 #if !ENABLE(OILPAN)
157 m_link.clear();
159 if (inDocument())
160 document().styleEngine().removeStyleSheetCandidateNode(this);
161 #endif
163 linkLoadEventSender().cancelEvent(this);
166 void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
168 if (name == relAttr) {
169 m_relAttribute = LinkRelAttribute(value);
170 process();
171 } else if (name == hrefAttr) {
172 process();
173 } else if (name == typeAttr) {
174 m_type = value;
175 process();
176 } else if (name == asAttr) {
177 m_as = value;
178 process();
179 } else if (name == sizesAttr) {
180 m_sizes->setValue(value);
181 parseSizesAttribute(value, m_iconSizes);
182 process();
183 } else if (name == mediaAttr) {
184 m_media = value.lower();
185 process();
186 } else if (name == disabledAttr) {
187 UseCounter::count(document(), UseCounter::HTMLLinkElementDisabled);
188 if (LinkStyle* link = linkStyle())
189 link->setDisabledState(!value.isNull());
190 } else {
191 if (name == titleAttr) {
192 if (LinkStyle* link = linkStyle())
193 link->setSheetTitle(value);
196 HTMLElement::parseAttribute(name, value);
200 bool HTMLLinkElement::shouldLoadLink()
202 return inDocument();
205 bool HTMLLinkElement::loadLink(const String& type, const String& as, const KURL& url)
207 return m_linkLoader.loadLink(m_relAttribute, fastGetAttribute(HTMLNames::crossoriginAttr), type, as, url, document(), NetworkHintsInterfaceImpl());
210 LinkResource* HTMLLinkElement::linkResourceToProcess()
212 bool visible = inDocument() && !m_isInShadowTree;
213 if (!visible) {
214 ASSERT(!linkStyle() || !linkStyle()->hasSheet());
215 return nullptr;
218 if (!m_link) {
219 if (m_relAttribute.isImport()) {
220 m_link = LinkImport::create(this);
221 } else if (m_relAttribute.isManifest()) {
222 m_link = LinkManifest::create(this);
223 } else {
224 OwnPtrWillBeRawPtr<LinkStyle> link = LinkStyle::create(this);
225 if (fastHasAttribute(disabledAttr)) {
226 UseCounter::count(document(), UseCounter::HTMLLinkElementDisabled);
227 link->setDisabledState(true);
229 m_link = link.release();
233 return m_link.get();
236 LinkStyle* HTMLLinkElement::linkStyle() const
238 if (!m_link || m_link->type() != LinkResource::Style)
239 return nullptr;
240 return static_cast<LinkStyle*>(m_link.get());
243 LinkImport* HTMLLinkElement::linkImport() const
245 if (!m_link || m_link->type() != LinkResource::Import)
246 return nullptr;
247 return static_cast<LinkImport*>(m_link.get());
250 Document* HTMLLinkElement::import() const
252 if (LinkImport* link = linkImport())
253 return link->importedDocument();
254 return nullptr;
257 void HTMLLinkElement::process()
259 if (LinkResource* link = linkResourceToProcess())
260 link->process();
263 Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode* insertionPoint)
265 if (insertionPoint->inDocument()) {
266 V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld();
267 if (activityLogger) {
268 Vector<String> argv;
269 argv.append("link");
270 argv.append(fastGetAttribute(relAttr));
271 argv.append(fastGetAttribute(hrefAttr));
272 activityLogger->logEvent("blinkAddElement", argv.size(), argv.data());
275 HTMLElement::insertedInto(insertionPoint);
276 if (!insertionPoint->inDocument())
277 return InsertionDone;
279 m_isInShadowTree = isInShadowTree();
280 if (m_isInShadowTree) {
281 String message = "HTML element <link> is ignored in shadow tree.";
282 document().addConsoleMessage(ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message));
283 return InsertionDone;
286 document().styleEngine().addStyleSheetCandidateNode(this, m_createdByParser);
288 process();
290 if (m_link)
291 m_link->ownerInserted();
293 return InsertionDone;
296 void HTMLLinkElement::removedFrom(ContainerNode* insertionPoint)
298 HTMLElement::removedFrom(insertionPoint);
299 if (!insertionPoint->inDocument())
300 return;
302 m_linkLoader.released();
304 if (m_isInShadowTree) {
305 ASSERT(!linkStyle() || !linkStyle()->hasSheet());
306 return;
308 document().styleEngine().removeStyleSheetCandidateNode(this);
310 RefPtrWillBeRawPtr<StyleSheet> removedSheet = sheet();
312 if (m_link)
313 m_link->ownerRemoved();
315 document().removedStyleSheet(removedSheet.get());
318 void HTMLLinkElement::finishParsingChildren()
320 m_createdByParser = false;
321 HTMLElement::finishParsingChildren();
324 bool HTMLLinkElement::styleSheetIsLoading() const
326 return linkStyle() && linkStyle()->styleSheetIsLoading();
329 void HTMLLinkElement::linkLoaded()
331 dispatchEvent(Event::create(EventTypeNames::load));
334 void HTMLLinkElement::linkLoadingErrored()
336 dispatchEvent(Event::create(EventTypeNames::error));
339 void HTMLLinkElement::didStartLinkPrerender()
341 dispatchEvent(Event::create(EventTypeNames::webkitprerenderstart));
344 void HTMLLinkElement::didStopLinkPrerender()
346 dispatchEvent(Event::create(EventTypeNames::webkitprerenderstop));
349 void HTMLLinkElement::didSendLoadForLinkPrerender()
351 dispatchEvent(Event::create(EventTypeNames::webkitprerenderload));
354 void HTMLLinkElement::didSendDOMContentLoadedForLinkPrerender()
356 dispatchEvent(Event::create(EventTypeNames::webkitprerenderdomcontentloaded));
359 bool HTMLLinkElement::sheetLoaded()
361 ASSERT(linkStyle());
362 return linkStyle()->sheetLoaded();
365 void HTMLLinkElement::notifyLoadedSheetAndAllCriticalSubresources(LoadedSheetErrorStatus errorStatus)
367 ASSERT(linkStyle());
368 linkStyle()->notifyLoadedSheetAndAllCriticalSubresources(errorStatus);
371 void HTMLLinkElement::dispatchPendingLoadEvents()
373 linkLoadEventSender().dispatchPendingEvents();
376 void HTMLLinkElement::dispatchPendingEvent(LinkEventSender* eventSender)
378 ASSERT_UNUSED(eventSender, eventSender == &linkLoadEventSender());
379 ASSERT(m_link);
380 if (m_link->hasLoaded())
381 linkLoaded();
382 else
383 linkLoadingErrored();
386 void HTMLLinkElement::scheduleEvent()
388 linkLoadEventSender().dispatchEventSoon(this);
391 void HTMLLinkElement::startLoadingDynamicSheet()
393 ASSERT(linkStyle());
394 linkStyle()->startLoadingDynamicSheet();
397 bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const
399 return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
402 bool HTMLLinkElement::hasLegalLinkAttribute(const QualifiedName& name) const
404 return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
407 const QualifiedName& HTMLLinkElement::subResourceAttributeName() const
409 // If the link element is not css, ignore it.
410 if (equalIgnoringCase(getAttribute(typeAttr), "text/css")) {
411 // FIXME: Add support for extracting links of sub-resources which
412 // are inside style-sheet such as @import, @font-face, url(), etc.
413 return hrefAttr;
415 return HTMLElement::subResourceAttributeName();
418 KURL HTMLLinkElement::href() const
420 return document().completeURL(getAttribute(hrefAttr));
423 const AtomicString& HTMLLinkElement::rel() const
425 return getAttribute(relAttr);
428 const AtomicString& HTMLLinkElement::type() const
430 return getAttribute(typeAttr);
433 bool HTMLLinkElement::async() const
435 return fastHasAttribute(HTMLNames::asyncAttr);
438 IconType HTMLLinkElement::iconType() const
440 return m_relAttribute.iconType();
443 const Vector<IntSize>& HTMLLinkElement::iconSizes() const
445 return m_iconSizes;
448 DOMSettableTokenList* HTMLLinkElement::sizes() const
450 return m_sizes.get();
453 DEFINE_TRACE(HTMLLinkElement)
455 visitor->trace(m_link);
456 visitor->trace(m_sizes);
457 visitor->trace(m_linkLoader);
458 HTMLElement::trace(visitor);
461 void HTMLLinkElement::attributeWillChange(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
463 if (name == hrefAttr && inDocument()) {
464 V8DOMActivityLogger* activityLogger = V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld();
465 if (activityLogger) {
466 Vector<String> argv;
467 argv.append("link");
468 argv.append(hrefAttr.toString());
469 argv.append(oldValue);
470 argv.append(newValue);
471 activityLogger->logEvent("blinkSetAttribute", argv.size(), argv.data());
474 HTMLElement::attributeWillChange(name, oldValue, newValue);
477 PassOwnPtrWillBeRawPtr<LinkStyle> LinkStyle::create(HTMLLinkElement* owner)
479 return adoptPtrWillBeNoop(new LinkStyle(owner));
482 LinkStyle::LinkStyle(HTMLLinkElement* owner)
483 : LinkResource(owner)
484 , m_disabledState(Unset)
485 , m_pendingSheetType(None)
486 , m_loading(false)
487 , m_firedLoad(false)
488 , m_loadedSheet(false)
489 , m_fetchFollowingCORS(false)
493 LinkStyle::~LinkStyle()
495 #if !ENABLE(OILPAN)
496 if (m_sheet)
497 m_sheet->clearOwnerNode();
498 #endif
501 Document& LinkStyle::document()
503 return m_owner->document();
506 void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* cachedStyleSheet)
508 if (!m_owner->inDocument()) {
509 ASSERT(!m_sheet);
510 return;
513 // See the comment in ScriptLoader.cpp about why this check is necessary
514 // here. https://crbug.com/500701.
515 if (!cachedStyleSheet->errorOccurred() && !SubresourceIntegrity::CheckSubresourceIntegrity(*m_owner, cachedStyleSheet->sheetText(), KURL(baseURL, href), *cachedStyleSheet)) {
516 m_loading = false;
517 removePendingSheet();
518 notifyLoadedSheetAndAllCriticalSubresources(Node::ErrorOccurredLoadingSubresource);
519 return;
521 // While the stylesheet is asynchronously loading, the owner can be moved under
522 // shadow tree. In that case, cancel any processing on the loaded content.
523 if (m_owner->isInShadowTree()) {
524 m_loading = false;
525 removePendingSheet();
526 if (m_sheet)
527 clearSheet();
528 return;
530 // Completing the sheet load may cause scripts to execute.
531 RefPtrWillBeRawPtr<Node> protector(m_owner.get());
533 CSSParserContext parserContext(m_owner->document(), 0, baseURL, charset);
535 if (RefPtrWillBeRawPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
536 ASSERT(restoredSheet->isCacheable());
537 ASSERT(!restoredSheet->isLoading());
539 if (m_sheet)
540 clearSheet();
541 m_sheet = CSSStyleSheet::create(restoredSheet, m_owner);
542 m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media()));
543 m_sheet->setTitle(m_owner->title());
544 setCrossOriginStylesheetStatus(m_sheet.get());
546 m_loading = false;
547 restoredSheet->checkLoaded();
548 return;
551 RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
553 if (m_sheet)
554 clearSheet();
556 m_sheet = CSSStyleSheet::create(styleSheet, m_owner);
557 m_sheet->setMediaQueries(MediaQuerySet::create(m_owner->media()));
558 m_sheet->setTitle(m_owner->title());
559 setCrossOriginStylesheetStatus(m_sheet.get());
561 styleSheet->parseAuthorStyleSheet(cachedStyleSheet, m_owner->document().securityOrigin());
563 m_loading = false;
564 styleSheet->notifyLoadedSheet(cachedStyleSheet);
565 styleSheet->checkLoaded();
567 if (styleSheet->isCacheable())
568 const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->saveParsedStyleSheet(styleSheet);
571 bool LinkStyle::sheetLoaded()
573 if (!styleSheetIsLoading()) {
574 removePendingSheet();
575 return true;
577 return false;
580 void LinkStyle::notifyLoadedSheetAndAllCriticalSubresources(Node::LoadedSheetErrorStatus errorStatus)
582 if (m_firedLoad)
583 return;
584 m_loadedSheet = (errorStatus == Node::NoErrorLoadingSubresource);
585 if (m_owner)
586 m_owner->scheduleEvent();
587 m_firedLoad = true;
590 void LinkStyle::startLoadingDynamicSheet()
592 ASSERT(m_pendingSheetType < Blocking);
593 addPendingSheet(Blocking);
596 void LinkStyle::clearSheet()
598 ASSERT(m_sheet);
599 ASSERT(m_sheet->ownerNode() == m_owner);
600 m_sheet->clearOwnerNode();
601 m_sheet = nullptr;
604 bool LinkStyle::styleSheetIsLoading() const
606 if (m_loading)
607 return true;
608 if (!m_sheet)
609 return false;
610 return m_sheet->contents()->isLoading();
613 void LinkStyle::addPendingSheet(PendingSheetType type)
615 if (type <= m_pendingSheetType)
616 return;
617 m_pendingSheetType = type;
619 if (m_pendingSheetType == NonBlocking)
620 return;
621 m_owner->document().styleEngine().addPendingSheet();
624 void LinkStyle::removePendingSheet()
626 PendingSheetType type = m_pendingSheetType;
627 m_pendingSheetType = None;
629 if (type == None)
630 return;
631 if (type == NonBlocking) {
632 // Tell StyleEngine to re-compute styleSheets of this m_owner's treescope.
633 m_owner->document().styleEngine().modifiedStyleSheetCandidateNode(m_owner);
634 // Document::removePendingSheet() triggers the style selector recalc for blocking sheets.
635 // FIXME: We don't have enough knowledge at this point to know if we're adding or removing a sheet
636 // so we can't call addedStyleSheet() or removedStyleSheet().
637 m_owner->document().styleResolverChanged();
638 return;
641 m_owner->document().styleEngine().removePendingSheet(m_owner);
644 void LinkStyle::setDisabledState(bool disabled)
646 LinkStyle::DisabledState oldDisabledState = m_disabledState;
647 m_disabledState = disabled ? Disabled : EnabledViaScript;
648 if (oldDisabledState != m_disabledState) {
649 // If we change the disabled state while the sheet is still loading, then we have to
650 // perform three checks:
651 if (styleSheetIsLoading()) {
652 // Check #1: The sheet becomes disabled while loading.
653 if (m_disabledState == Disabled)
654 removePendingSheet();
656 // Check #2: An alternate sheet becomes enabled while it is still loading.
657 if (m_owner->relAttribute().isAlternate() && m_disabledState == EnabledViaScript)
658 addPendingSheet(Blocking);
660 // Check #3: A main sheet becomes enabled while it was still loading and
661 // after it was disabled via script. It takes really terrible code to make this
662 // happen (a double toggle for no reason essentially). This happens on
663 // virtualplastic.net, which manages to do about 12 enable/disables on only 3
664 // sheets. :)
665 if (!m_owner->relAttribute().isAlternate() && m_disabledState == EnabledViaScript && oldDisabledState == Disabled)
666 addPendingSheet(Blocking);
668 // If the sheet is already loading just bail.
669 return;
672 if (m_sheet)
673 m_sheet->setDisabled(disabled);
675 // Load the sheet, since it's never been loaded before.
676 if (!m_sheet && m_disabledState == EnabledViaScript) {
677 if (m_owner->shouldProcessStyle())
678 process();
679 } else {
680 // FIXME: We don't have enough knowledge here to know if we should call addedStyleSheet() or removedStyleSheet().
681 m_owner->document().styleResolverChanged();
686 void LinkStyle::setCrossOriginStylesheetStatus(CSSStyleSheet* sheet)
688 if (m_fetchFollowingCORS && resource() && !resource()->errorOccurred()) {
689 // Record the security origin the CORS access check succeeded at, if cross origin.
690 // Only origins that are script accessible to it may access the stylesheet's rules.
691 sheet->setAllowRuleAccessFromOrigin(m_owner->document().securityOrigin());
693 m_fetchFollowingCORS = false;
696 void LinkStyle::process()
698 ASSERT(m_owner->shouldProcessStyle());
699 String type = m_owner->typeValue().lower();
700 String as = m_owner->asValue().lower();
701 LinkRequestBuilder builder(m_owner);
703 if (m_owner->relAttribute().iconType() != InvalidIcon && builder.url().isValid() && !builder.url().isEmpty()) {
704 if (!m_owner->shouldLoadLink())
705 return;
706 if (!document().securityOrigin()->canDisplay(builder.url()))
707 return;
708 if (!document().contentSecurityPolicy()->allowImageFromSource(builder.url()))
709 return;
710 if (document().frame() && document().frame()->loader().client())
711 document().frame()->loader().client()->dispatchDidChangeIcons(m_owner->relAttribute().iconType());
714 if (!m_owner->loadLink(type, as, builder.url()))
715 return;
717 if (m_disabledState != Disabled && m_owner->relAttribute().isStyleSheet() && shouldLoadResource() && builder.url().isValid()) {
719 if (resource()) {
720 removePendingSheet();
721 clearResource();
724 if (!m_owner->shouldLoadLink())
725 return;
727 m_loading = true;
729 bool mediaQueryMatches = true;
730 LocalFrame* frame = loadingFrame();
731 if (!m_owner->media().isEmpty() && frame && frame->document()) {
732 RefPtr<ComputedStyle> documentStyle = StyleResolver::styleForDocument(*frame->document());
733 RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
734 MediaQueryEvaluator evaluator(frame);
735 mediaQueryMatches = evaluator.eval(media.get());
738 // Don't hold up layout tree construction and script execution on stylesheets
739 // that are not needed for the layout at the moment.
740 bool blocking = mediaQueryMatches && !m_owner->isAlternate();
741 addPendingSheet(blocking ? Blocking : NonBlocking);
743 // Load stylesheets that are not needed for the layout immediately with low priority.
744 FetchRequest request = builder.build(blocking);
745 AtomicString crossOriginMode = m_owner->fastGetAttribute(HTMLNames::crossoriginAttr);
746 if (!crossOriginMode.isNull()) {
747 request.setCrossOriginAccessControl(document().securityOrigin(), crossOriginMode);
748 setFetchFollowingCORS();
750 setResource(CSSStyleSheetResource::fetch(request, document().fetcher()));
752 if (!resource()) {
753 // The request may have been denied if (for example) the stylesheet is local and the document is remote, or if there was a Content Security Policy Failure.
754 m_loading = false;
755 removePendingSheet();
756 notifyLoadedSheetAndAllCriticalSubresources(Node::ErrorOccurredLoadingSubresource);
758 } else if (m_sheet) {
759 // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
760 RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
761 clearSheet();
762 document().removedStyleSheet(removedSheet.get());
766 void LinkStyle::setSheetTitle(const String& title)
768 if (m_sheet)
769 m_sheet->setTitle(title);
772 void LinkStyle::ownerRemoved()
774 if (m_sheet)
775 clearSheet();
777 if (styleSheetIsLoading())
778 removePendingSheet();
781 DEFINE_TRACE(LinkStyle)
783 visitor->trace(m_sheet);
784 LinkResource::trace(visitor);
787 } // namespace blink