1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2003-2017 Apple Inc. All rights reserved.
5 * Copyright (C) 2011 Google Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#pragma once
25
26#include "CSSStyleSheet.h"
27#include "CachedStyleSheetClient.h"
28#include "CachedResourceHandle.h"
29#include "DOMTokenList.h"
30#include "HTMLElement.h"
31#include "LinkLoader.h"
32#include "LinkLoaderClient.h"
33#include "LinkRelAttribute.h"
34
35namespace WebCore {
36
37class DOMTokenList;
38class HTMLLinkElement;
39struct MediaQueryParserContext;
40
41template<typename T> class EventSender;
42typedef EventSender<HTMLLinkElement> LinkEventSender;
43
44class HTMLLinkElement final : public HTMLElement, public CachedStyleSheetClient, public LinkLoaderClient {
45 WTF_MAKE_ISO_ALLOCATED(HTMLLinkElement);
46public:
47 static Ref<HTMLLinkElement> create(const QualifiedName&, Document&, bool createdByParser);
48 virtual ~HTMLLinkElement();
49
50 URL href() const;
51 const AtomString& rel() const;
52
53 String target() const final;
54
55 const AtomString& type() const;
56
57 Optional<LinkIconType> iconType() const;
58
59 CSSStyleSheet* sheet() const { return m_sheet.get(); }
60
61 bool styleSheetIsLoading() const;
62
63 bool isDisabled() const { return m_disabledState == Disabled; }
64 bool isEnabledViaScript() const { return m_disabledState == EnabledViaScript; }
65 DOMTokenList& sizes();
66
67 WEBCORE_EXPORT void setCrossOrigin(const AtomString&);
68 WEBCORE_EXPORT String crossOrigin() const;
69 WEBCORE_EXPORT void setAs(const AtomString&);
70 WEBCORE_EXPORT String as() const;
71
72 void dispatchPendingEvent(LinkEventSender*);
73 static void dispatchPendingLoadEvents();
74
75 WEBCORE_EXPORT DOMTokenList& relList();
76
77#if ENABLE(APPLICATION_MANIFEST)
78 bool isApplicationManifest() const { return m_relAttribute.isApplicationManifest; }
79#endif
80
81private:
82 void parseAttribute(const QualifiedName&, const AtomString&) final;
83
84 bool shouldLoadLink() final;
85 void process();
86 static void processCallback(Node*);
87 void clearSheet();
88
89 InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode&) final;
90 void didFinishInsertingNode() final;
91 void removedFromAncestor(RemovalType, ContainerNode&) final;
92
93 void initializeStyleSheet(Ref<StyleSheetContents>&&, const CachedCSSStyleSheet&, MediaQueryParserContext);
94
95 // from CachedResourceClient
96 void setCSSStyleSheet(const String& href, const URL& baseURL, const String& charset, const CachedCSSStyleSheet*) final;
97 bool sheetLoaded() final;
98 void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) final;
99 void startLoadingDynamicSheet() final;
100
101 void linkLoaded() final;
102 void linkLoadingErrored() final;
103
104 bool isAlternate() const { return m_disabledState == Unset && m_relAttribute.isAlternate; }
105
106 void setDisabledState(bool);
107
108 bool isURLAttribute(const Attribute&) const final;
109
110 void defaultEventHandler(Event&) final;
111 void handleClick(Event&);
112
113 HTMLLinkElement(const QualifiedName&, Document&, bool createdByParser);
114
115 void addSubresourceAttributeURLs(ListHashSet<URL>&) const final;
116
117 void finishParsingChildren() final;
118
119 enum PendingSheetType { Unknown, ActiveSheet, InactiveSheet };
120 void addPendingSheet(PendingSheetType);
121
122 void removePendingSheet();
123
124 LinkLoader m_linkLoader;
125 Style::Scope* m_styleScope { nullptr };
126 CachedResourceHandle<CachedCSSStyleSheet> m_cachedSheet;
127 RefPtr<CSSStyleSheet> m_sheet;
128 enum DisabledState {
129 Unset,
130 EnabledViaScript,
131 Disabled
132 };
133
134 String m_type;
135 String m_media;
136 std::unique_ptr<DOMTokenList> m_sizes;
137 DisabledState m_disabledState;
138 LinkRelAttribute m_relAttribute;
139 bool m_loading;
140 bool m_createdByParser;
141 bool m_firedLoad;
142 bool m_loadedResource;
143 bool m_isHandlingBeforeLoad { false };
144
145 PendingSheetType m_pendingSheetType;
146 String m_integrityMetadataForPendingSheetRequest;
147
148 std::unique_ptr<DOMTokenList> m_relList;
149};
150
151}
152