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#pragma once
22
23#include "CSSParserContext.h"
24#include "CachePolicy.h"
25#include <wtf/Function.h>
26#include <wtf/HashMap.h>
27#include <wtf/RefCounted.h>
28#include <wtf/URL.h>
29#include <wtf/Vector.h>
30#include <wtf/WeakPtr.h>
31#include <wtf/text/AtomStringHash.h>
32
33namespace WebCore {
34
35class CSSStyleSheet;
36class CachedCSSStyleSheet;
37class CachedResource;
38class Document;
39class FrameLoader;
40class Node;
41class SecurityOrigin;
42class StyleRuleBase;
43class StyleRuleImport;
44class StyleRuleNamespace;
45
46class StyleSheetContents final : public RefCounted<StyleSheetContents>, public CanMakeWeakPtr<StyleSheetContents> {
47public:
48 static Ref<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(HTMLStandardMode))
49 {
50 return adoptRef(*new StyleSheetContents(0, String(), context));
51 }
52 static Ref<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
53 {
54 return adoptRef(*new StyleSheetContents(0, originalURL, context));
55 }
56 static Ref<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
57 {
58 return adoptRef(*new StyleSheetContents(ownerRule, originalURL, context));
59 }
60
61 WEBCORE_EXPORT ~StyleSheetContents();
62
63 const CSSParserContext& parserContext() const { return m_parserContext; }
64
65 const AtomString& defaultNamespace() { return m_defaultNamespace; }
66 const AtomString& namespaceURIFromPrefix(const AtomString& prefix);
67
68 void parseAuthorStyleSheet(const CachedCSSStyleSheet*, const SecurityOrigin*);
69 WEBCORE_EXPORT bool parseString(const String&);
70
71 bool isCacheable() const;
72
73 bool isLoading() const;
74 bool subresourcesAllowReuse(CachePolicy, FrameLoader&) const;
75 WEBCORE_EXPORT bool isLoadingSubresources() const;
76
77 void checkLoaded();
78 void startLoadingDynamicSheet();
79
80 StyleSheetContents* rootStyleSheet() const;
81 Node* singleOwnerNode() const;
82 Document* singleOwnerDocument() const;
83
84 const String& charset() const { return m_parserContext.charset; }
85
86 bool loadCompleted() const { return m_loadCompleted; }
87
88 URL completeURL(const String& url) const;
89 bool traverseRules(const WTF::Function<bool (const StyleRuleBase&)>& handler) const;
90 bool traverseSubresources(const WTF::Function<bool (const CachedResource&)>& handler) const;
91
92 void setIsUserStyleSheet(bool b) { m_isUserStyleSheet = b; }
93 bool isUserStyleSheet() const { return m_isUserStyleSheet; }
94 void setHasSyntacticallyValidCSSHeader(bool b) { m_hasSyntacticallyValidCSSHeader = b; }
95 bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; }
96
97 void parserAddNamespace(const AtomString& prefix, const AtomString& uri);
98 void parserAppendRule(Ref<StyleRuleBase>&&);
99 void parserSetEncodingFromCharsetRule(const String& encoding);
100 void parserSetUsesStyleBasedEditability() { m_usesStyleBasedEditability = true; }
101
102 void clearRules();
103
104 String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
105 // Rules other than @charset and @import.
106 const Vector<RefPtr<StyleRuleBase>>& childRules() const { return m_childRules; }
107 const Vector<RefPtr<StyleRuleImport>>& importRules() const { return m_importRules; }
108 const Vector<RefPtr<StyleRuleNamespace>>& namespaceRules() const { return m_namespaceRules; }
109
110 void notifyLoadedSheet(const CachedCSSStyleSheet*);
111
112 StyleSheetContents* parentStyleSheet() const;
113 StyleRuleImport* ownerRule() const { return m_ownerRule; }
114 void clearOwnerRule() { m_ownerRule = 0; }
115
116 // Note that href is the URL that started the redirect chain that led to
117 // this style sheet. This property probably isn't useful for much except
118 // the JavaScript binding (which needs to use this value for security).
119 String originalURL() const { return m_originalURL; }
120 const URL& baseURL() const { return m_parserContext.baseURL; }
121
122 unsigned ruleCount() const;
123 StyleRuleBase* ruleAt(unsigned index) const;
124
125 bool usesStyleBasedEditability() const { return m_usesStyleBasedEditability; }
126
127 unsigned estimatedSizeInBytes() const;
128
129 bool wrapperInsertRule(Ref<StyleRuleBase>&&, unsigned index);
130 void wrapperDeleteRule(unsigned index);
131
132 Ref<StyleSheetContents> copy() const { return adoptRef(*new StyleSheetContents(*this)); }
133
134 void registerClient(CSSStyleSheet*);
135 void unregisterClient(CSSStyleSheet*);
136 bool hasOneClient() { return m_clients.size() == 1; }
137
138 bool isMutable() const { return m_isMutable; }
139 void setMutable() { m_isMutable = true; }
140
141 bool isInMemoryCache() const { return m_inMemoryCacheCount; }
142 void addedToMemoryCache();
143 void removedFromMemoryCache();
144
145 void shrinkToFit();
146
147 void setAsOpaque() { m_parserContext.isContentOpaque = true; }
148 bool isContentOpaque() const { return m_parserContext.isContentOpaque; }
149
150private:
151 WEBCORE_EXPORT StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext&);
152 StyleSheetContents(const StyleSheetContents&);
153
154 void clearCharsetRule();
155
156 StyleRuleImport* m_ownerRule;
157
158 String m_originalURL;
159
160 String m_encodingFromCharsetRule;
161 Vector<RefPtr<StyleRuleImport>> m_importRules;
162 Vector<RefPtr<StyleRuleNamespace>> m_namespaceRules;
163 Vector<RefPtr<StyleRuleBase>> m_childRules;
164 typedef HashMap<AtomString, AtomString> PrefixNamespaceURIMap;
165 PrefixNamespaceURIMap m_namespaces;
166 AtomString m_defaultNamespace;
167
168 bool m_isUserStyleSheet;
169 bool m_loadCompleted { false };
170 bool m_hasSyntacticallyValidCSSHeader { true };
171 bool m_didLoadErrorOccur { false };
172 bool m_usesStyleBasedEditability { false };
173 bool m_isMutable { false };
174 unsigned m_inMemoryCacheCount { 0 };
175
176 CSSParserContext m_parserContext;
177
178 Vector<CSSStyleSheet*> m_clients;
179};
180
181} // namespace WebCore
182