1/*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#ifndef StyleSheetContents_h
22#define StyleSheetContents_h
23
24#include "core/css/RuleSet.h"
25#include "platform/heap/Handle.h"
26#include "platform/weborigin/KURL.h"
27#include "wtf/HashMap.h"
28#include "wtf/ListHashSet.h"
29#include "wtf/RefCounted.h"
30#include "wtf/Vector.h"
31#include "wtf/text/AtomicStringHash.h"
32#include "wtf/text/StringHash.h"
33#include "wtf/text/TextPosition.h"
34
35
36namespace blink {
37
38class CSSStyleSheet;
39class CSSStyleSheetResource;
40class Document;
41class Node;
42class SecurityOrigin;
43class StyleRuleBase;
44class StyleRuleFontFace;
45class StyleRuleImport;
46
47class StyleSheetContents : public RefCountedWillBeGarbageCollectedFinalized<StyleSheetContents> {
48public:
49    static PassRefPtrWillBeRawPtr<StyleSheetContents> create(const CSSParserContext& context)
50    {
51        return adoptRefWillBeNoop(new StyleSheetContents(0, String(), context));
52    }
53    static PassRefPtrWillBeRawPtr<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
54    {
55        return adoptRefWillBeNoop(new StyleSheetContents(0, originalURL, context));
56    }
57    static PassRefPtrWillBeRawPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
58    {
59        return adoptRefWillBeNoop(new StyleSheetContents(ownerRule, originalURL, context));
60    }
61
62    ~StyleSheetContents();
63
64    const CSSParserContext& parserContext() const { return m_parserContext; }
65
66    const AtomicString& determineNamespace(const AtomicString& prefix);
67
68    void parseAuthorStyleSheet(const CSSStyleSheetResource*, const SecurityOrigin*);
69    bool parseString(const String&);
70    bool parseStringAtPosition(const String&, const TextPosition&, bool);
71
72    bool isCacheable() const;
73
74    bool isLoading() const;
75
76    void checkLoaded();
77    void startLoadingDynamicSheet();
78
79    StyleSheetContents* rootStyleSheet() const;
80    bool hasSingleOwnerNode() const;
81    Node* singleOwnerNode() const;
82    Document* singleOwnerDocument() const;
83
84    const String& charset() const { return m_parserContext.charset(); }
85
86    bool loadCompleted() const;
87    bool hasFailedOrCanceledSubresources() const;
88
89    KURL completeURL(const String& url) const;
90
91    void setHasSyntacticallyValidCSSHeader(bool isValidCss);
92    bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; }
93
94    void setHasFontFaceRule(bool b) { m_hasFontFaceRule = b; }
95    bool hasFontFaceRule() const { return m_hasFontFaceRule; }
96    void findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules);
97
98    void parserAddNamespace(const AtomicString& prefix, const AtomicString& uri);
99    void parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase>);
100    void parserSetEncodingFromCharsetRule(const String& encoding);
101    void parserSetUsesRemUnits(bool b) { m_usesRemUnits = b; }
102
103    void clearRules();
104
105    bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
106    String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
107    // Rules other than @charset and @import.
108    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& childRules() const { return m_childRules; }
109    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules() const { return m_importRules; }
110
111    void notifyLoadedSheet(const CSSStyleSheetResource*);
112
113    StyleSheetContents* parentStyleSheet() const;
114    StyleRuleImport* ownerRule() const { return m_ownerRule; }
115    void clearOwnerRule() { m_ownerRule = nullptr; }
116
117    // Note that href is the URL that started the redirect chain that led to
118    // this style sheet. This property probably isn't useful for much except
119    // the JavaScript binding (which needs to use this value for security).
120    String originalURL() const { return m_originalURL; }
121    const KURL& baseURL() const { return m_parserContext.baseURL(); }
122
123    unsigned ruleCount() const;
124    StyleRuleBase* ruleAt(unsigned index) const;
125
126    bool usesRemUnits() const { return m_usesRemUnits; }
127
128    unsigned estimatedSizeInBytes() const;
129
130    bool wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase>, unsigned index);
131    void wrapperDeleteRule(unsigned index);
132
133    PassRefPtrWillBeRawPtr<StyleSheetContents> copy() const
134    {
135        return adoptRefWillBeNoop(new StyleSheetContents(*this));
136    }
137
138    void registerClient(CSSStyleSheet*);
139    void unregisterClient(CSSStyleSheet*);
140    size_t clientSize() const { return m_loadingClients.size() + m_completedClients.size(); }
141    bool hasOneClient() { return clientSize() == 1; }
142    void clientLoadCompleted(CSSStyleSheet*);
143    void clientLoadStarted(CSSStyleSheet*);
144
145    bool isMutable() const { return m_isMutable; }
146    void setMutable() { m_isMutable = true; }
147
148    void removeSheetFromCache(Document*);
149
150    bool isInMemoryCache() const { return m_isInMemoryCache; }
151    void addedToMemoryCache();
152    void removedFromMemoryCache();
153
154    void setHasMediaQueries();
155    bool hasMediaQueries() const { return m_hasMediaQueries; }
156
157    bool didLoadErrorOccur() const { return m_didLoadErrorOccur; }
158
159    void shrinkToFit();
160    RuleSet& ruleSet() { ASSERT(m_ruleSet); return *m_ruleSet.get(); }
161    RuleSet& ensureRuleSet(const MediaQueryEvaluator&, AddRuleFlags);
162    void clearRuleSet();
163
164    void trace(Visitor*);
165
166private:
167    StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext&);
168    StyleSheetContents(const StyleSheetContents&);
169    void notifyRemoveFontFaceRule(const StyleRuleFontFace*);
170
171    Document* clientSingleOwnerDocument() const;
172    void clearCharsetRule();
173
174    RawPtrWillBeMember<StyleRuleImport> m_ownerRule;
175
176    String m_originalURL;
177
178    String m_encodingFromCharsetRule;
179    WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> > m_importRules;
180    WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_childRules;
181    typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
182    PrefixNamespaceURIMap m_namespaces;
183
184    bool m_hasSyntacticallyValidCSSHeader : 1;
185    bool m_didLoadErrorOccur : 1;
186    bool m_usesRemUnits : 1;
187    bool m_isMutable : 1;
188    bool m_isInMemoryCache : 1;
189    bool m_hasFontFaceRule : 1;
190    bool m_hasMediaQueries : 1;
191    bool m_hasSingleOwnerDocument : 1;
192
193    CSSParserContext m_parserContext;
194
195    WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_loadingClients;
196    WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_completedClients;
197    typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator ClientsIterator;
198
199    OwnPtrWillBeMember<RuleSet> m_ruleSet;
200};
201
202} // namespace
203
204#endif
205