1 /* 2 * Copyright (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 1999 Antti Koivisto (koivisto (at) kde.org) 4 * Copyright (C) 2003, 2008, 2010 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 #ifndef HTMLLinkElement_h 25 #define HTMLLinkElement_h 26 27 #include "core/css/CSSStyleSheet.h" 28 #include "core/dom/DOMSettableTokenList.h" 29 #include "core/dom/IconURL.h" 30 #include "core/fetch/ResourceOwner.h" 31 #include "core/fetch/StyleSheetResource.h" 32 #include "core/fetch/StyleSheetResourceClient.h" 33 #include "core/html/HTMLElement.h" 34 #include "core/html/LinkRelAttribute.h" 35 #include "core/html/LinkResource.h" 36 #include "core/loader/LinkLoader.h" 37 #include "core/loader/LinkLoaderClient.h" 38 39 namespace WebCore { 40 41 class DocumentFragment; 42 class HTMLLinkElement; 43 class KURL; 44 class LinkImport; 45 46 template<typename T> class EventSender; 47 typedef EventSender<HTMLLinkElement> LinkEventSender; 48 49 // 50 // LinkStyle handles dynaically change-able link resources, which is 51 // typically @rel="stylesheet". 52 // 53 // It could be @rel="shortcut icon" or soething else though. Each of 54 // types might better be handled by a separate class, but dynamically 55 // changing @rel makes it harder to move such a design so we are 56 // sticking current way so far. 57 // 58 class LinkStyle FINAL : public LinkResource, ResourceOwner<StyleSheetResource> { 59 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 60 public: 61 static PassOwnPtrWillBeRawPtr<LinkStyle> create(HTMLLinkElement* owner); 62 63 explicit LinkStyle(HTMLLinkElement* owner); 64 virtual ~LinkStyle(); 65 66 virtual Type type() const OVERRIDE { return Style; } 67 virtual void process() OVERRIDE; 68 virtual void ownerRemoved() OVERRIDE; 69 virtual bool hasLoaded() const OVERRIDE { return m_loadedSheet; } 70 virtual void trace(Visitor*) OVERRIDE; 71 72 void startLoadingDynamicSheet(); 73 void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred); 74 bool sheetLoaded(); 75 76 void setDisabledState(bool); 77 void setSheetTitle(const String&); 78 79 bool styleSheetIsLoading() const; 80 bool hasSheet() const { return m_sheet; } 81 bool isDisabled() const { return m_disabledState == Disabled; } 82 bool isEnabledViaScript() const { return m_disabledState == EnabledViaScript; } 83 bool isUnset() const { return m_disabledState == Unset; } 84 85 CSSStyleSheet* sheet() const { return m_sheet.get(); } 86 87 private: 88 // From StyleSheetResourceClient 89 virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*) OVERRIDE; 90 91 enum DisabledState { 92 Unset, 93 EnabledViaScript, 94 Disabled 95 }; 96 97 enum PendingSheetType { 98 None, 99 NonBlocking, 100 Blocking 101 }; 102 103 void clearSheet(); 104 void addPendingSheet(PendingSheetType); 105 void removePendingSheet(); 106 Document& document(); 107 108 RefPtrWillBeMember<CSSStyleSheet> m_sheet; 109 DisabledState m_disabledState; 110 PendingSheetType m_pendingSheetType; 111 bool m_loading; 112 bool m_firedLoad; 113 bool m_loadedSheet; 114 }; 115 116 117 class HTMLLinkElement FINAL : public HTMLElement, public LinkLoaderClient { 118 public: 119 static PassRefPtrWillBeRawPtr<HTMLLinkElement> create(Document&, bool createdByParser); 120 virtual ~HTMLLinkElement(); 121 122 KURL href() const; 123 const AtomicString& rel() const; 124 String media() const { return m_media; } 125 String typeValue() const { return m_type; } 126 const LinkRelAttribute& relAttribute() const { return m_relAttribute; } 127 128 const AtomicString& type() const; 129 130 IconType iconType() const; 131 132 // the icon sizes as parsed from the HTML attribute 133 const Vector<IntSize>& iconSizes() const; 134 135 bool async() const; 136 137 CSSStyleSheet* sheet() const { return linkStyle() ? linkStyle()->sheet() : 0; } 138 Document* import() const; 139 140 bool styleSheetIsLoading() const; 141 142 bool isImport() const { return linkImport(); } 143 bool isDisabled() const { return linkStyle() && linkStyle()->isDisabled(); } 144 bool isEnabledViaScript() const { return linkStyle() && linkStyle()->isEnabledViaScript(); } 145 void enableIfExitTransitionStyle(); 146 147 DOMSettableTokenList* sizes() const; 148 149 void dispatchPendingEvent(LinkEventSender*); 150 void scheduleEvent(); 151 void dispatchEventImmediately(); 152 static void dispatchPendingLoadEvents(); 153 154 // From LinkLoaderClient 155 virtual bool shouldLoadLink() OVERRIDE; 156 157 // For LinkStyle 158 bool loadLink(const String& type, const KURL&); 159 bool isAlternate() const { return linkStyle()->isUnset() && m_relAttribute.isAlternate(); } 160 bool shouldProcessStyle() { return linkResourceToProcess() && linkStyle(); } 161 bool isCreatedByParser() const { return m_createdByParser; } 162 163 // Parse the icon size attribute into |iconSizes|, make this method public 164 // visible for testing purpose. 165 static void parseSizesAttribute(const AtomicString& value, Vector<IntSize>& iconSizes); 166 167 virtual void trace(Visitor*) OVERRIDE; 168 169 private: 170 virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE; 171 172 LinkStyle* linkStyle() const; 173 LinkImport* linkImport() const; 174 LinkResource* linkResourceToProcess(); 175 176 void process(); 177 static void processCallback(Node*); 178 179 // From Node and subclassses 180 virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE; 181 virtual void removedFrom(ContainerNode*) OVERRIDE; 182 virtual bool isURLAttribute(const Attribute&) const OVERRIDE; 183 virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE; 184 virtual const QualifiedName& subResourceAttributeName() const OVERRIDE; 185 virtual bool sheetLoaded() OVERRIDE; 186 virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) OVERRIDE; 187 virtual void startLoadingDynamicSheet() OVERRIDE; 188 virtual void finishParsingChildren() OVERRIDE; 189 190 // From LinkLoaderClient 191 virtual void linkLoaded() OVERRIDE; 192 virtual void linkLoadingErrored() OVERRIDE; 193 virtual void didStartLinkPrerender() OVERRIDE; 194 virtual void didStopLinkPrerender() OVERRIDE; 195 virtual void didSendLoadForLinkPrerender() OVERRIDE; 196 virtual void didSendDOMContentLoadedForLinkPrerender() OVERRIDE; 197 198 private: 199 HTMLLinkElement(Document&, bool createdByParser); 200 201 OwnPtrWillBeMember<LinkResource> m_link; 202 LinkLoader m_linkLoader; 203 204 String m_type; 205 String m_media; 206 RefPtrWillBeMember<DOMSettableTokenList> m_sizes; 207 Vector<IntSize> m_iconSizes; 208 LinkRelAttribute m_relAttribute; 209 210 bool m_createdByParser; 211 bool m_isInShadowTree; 212 }; 213 214 } //namespace 215 216 #endif 217