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