dfcf19ef8d2c1487838a0397f7264c71db08cd10
[WebKit-https.git] / Source / WebCore / css / StyleRule.h
1 /*
2  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3  * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
4  * Copyright (C) 2002, 2006, 2008, 2012, 2013 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #pragma once
23
24 #include "CSSSelectorList.h"
25 #include "StyleProperties.h"
26 #include <wtf/RefPtr.h>
27 #include <wtf/TypeCasts.h>
28
29 namespace WebCore {
30
31 class CSSRule;
32 class CSSStyleRule;
33 class CSSStyleSheet;
34 class MediaQuerySet;
35 class MutableStyleProperties;
36 class StyleRuleKeyframe;
37 class StyleProperties;
38 class StyleRuleKeyframes;
39     
40 class StyleRuleBase : public WTF::RefCountedBase {
41     WTF_MAKE_FAST_ALLOCATED;
42 public:
43     enum Type {
44         Unknown, // Not used.
45         Style,
46         Charset, // Not used. These are internally strings owned by the style sheet.
47         Import,
48         Media,
49         FontFace,
50         Page,
51         Keyframes,
52         Keyframe, // Not used. These are internally non-rule StyleRuleKeyframe objects.
53         Namespace,
54         Supports = 12,
55 #if ENABLE(CSS_DEVICE_ADAPTATION)
56         Viewport = 15,
57 #endif
58     };
59
60     Type type() const { return static_cast<Type>(m_type); }
61     
62     bool isCharsetRule() const { return type() == Charset; }
63     bool isFontFaceRule() const { return type() == FontFace; }
64     bool isKeyframesRule() const { return type() == Keyframes; }
65     bool isKeyframeRule() const { return type() == Keyframe; }
66     bool isNamespaceRule() const { return type() == Namespace; }
67     bool isMediaRule() const { return type() == Media; }
68     bool isPageRule() const { return type() == Page; }
69     bool isStyleRule() const { return type() == Style; }
70     bool isSupportsRule() const { return type() == Supports; }
71 #if ENABLE(CSS_DEVICE_ADAPTATION)
72     bool isViewportRule() const { return type() == Viewport; }
73 #endif
74     bool isImportRule() const { return type() == Import; }
75
76     Ref<StyleRuleBase> copy() const;
77
78     void deref()
79     {
80         if (derefBase())
81             destroy();
82     }
83
84     // FIXME: There shouldn't be any need for the null parent version.
85     RefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = nullptr) const;
86     RefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
87
88 protected:
89     StyleRuleBase(Type type, bool hasDocumentSecurityOrigin = false)
90         : m_type(type)
91         , m_hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
92     {
93     }
94
95     StyleRuleBase(const StyleRuleBase& o)
96         : WTF::RefCountedBase()
97         , m_type(o.m_type)
98         , m_hasDocumentSecurityOrigin(o.m_hasDocumentSecurityOrigin)
99     {
100     }
101
102     ~StyleRuleBase() = default;
103
104     bool hasDocumentSecurityOrigin() const { return m_hasDocumentSecurityOrigin; }
105
106 private:
107     WEBCORE_EXPORT void destroy();
108     
109     RefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
110
111     unsigned m_type : 5;
112     // This is only needed to support getMatchedCSSRules.
113     unsigned m_hasDocumentSecurityOrigin : 1;
114 };
115
116 class StyleRule final : public StyleRuleBase {
117     WTF_MAKE_FAST_ALLOCATED;
118 public:
119     static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties, bool hasDocumentSecurityOrigin)
120     {
121         return adoptRef(*new StyleRule(WTFMove(properties), hasDocumentSecurityOrigin));
122     }
123     
124     ~StyleRule();
125
126     const CSSSelectorList& selectorList() const { return m_selectorList; }
127     
128     const StyleProperties& properties() const;
129     MutableStyleProperties& mutableProperties();
130     const StyleProperties* propertiesWithoutDeferredParsing() const;
131
132     using StyleRuleBase::hasDocumentSecurityOrigin;
133
134     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
135     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
136     void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); }
137
138     Ref<StyleRule> copy() const { return adoptRef(*new StyleRule(*this)); }
139
140     Vector<RefPtr<StyleRule>> splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned) const;
141
142     static unsigned averageSizeInBytes();
143
144 private:
145     StyleRule(Ref<StylePropertiesBase>&&, bool hasDocumentSecurityOrigin);
146     StyleRule(const StyleRule&);
147
148     static Ref<StyleRule> createForSplitting(const Vector<const CSSSelector*>&, Ref<StyleProperties>&&, bool hasDocumentSecurityOrigin);
149
150     mutable Ref<StylePropertiesBase> m_properties;
151     CSSSelectorList m_selectorList;
152 };
153
154 inline const StyleProperties* StyleRule::propertiesWithoutDeferredParsing() const
155 {
156     return m_properties->type() != DeferredPropertiesType ? &downcast<StyleProperties>(m_properties.get()) : nullptr;
157 }
158
159 class StyleRuleFontFace final : public StyleRuleBase {
160 public:
161     static Ref<StyleRuleFontFace> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRuleFontFace(WTFMove(properties))); }
162     
163     ~StyleRuleFontFace();
164
165     const StyleProperties& properties() const { return m_properties; }
166     MutableStyleProperties& mutableProperties();
167
168     Ref<StyleRuleFontFace> copy() const { return adoptRef(*new StyleRuleFontFace(*this)); }
169
170 private:
171     explicit StyleRuleFontFace(Ref<StyleProperties>&&);
172     StyleRuleFontFace(const StyleRuleFontFace&);
173
174     Ref<StyleProperties> m_properties;
175 };
176
177 class StyleRulePage final : public StyleRuleBase {
178 public:
179     static Ref<StyleRulePage> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRulePage(WTFMove(properties))); }
180
181     ~StyleRulePage();
182
183     const CSSSelector* selector() const { return m_selectorList.first(); }    
184     const StyleProperties& properties() const { return m_properties; }
185     MutableStyleProperties& mutableProperties();
186
187     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
188     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
189
190     Ref<StyleRulePage> copy() const { return adoptRef(*new StyleRulePage(*this)); }
191
192 private:
193     explicit StyleRulePage(Ref<StyleProperties>&&);
194     StyleRulePage(const StyleRulePage&);
195     
196     Ref<StyleProperties> m_properties;
197     CSSSelectorList m_selectorList;
198 };
199
200 class DeferredStyleGroupRuleList final {
201 public:
202     DeferredStyleGroupRuleList(const CSSParserTokenRange&, CSSDeferredParser&);
203     
204     void parseDeferredRules(Vector<RefPtr<StyleRuleBase>>&);
205     void parseDeferredKeyframes(StyleRuleKeyframes&);
206
207 private:
208     Vector<CSSParserToken> m_tokens;
209     Ref<CSSDeferredParser> m_parser;
210 };
211     
212 class StyleRuleGroup : public StyleRuleBase {
213 public:
214     const Vector<RefPtr<StyleRuleBase>>& childRules() const;
215     const Vector<RefPtr<StyleRuleBase>>* childRulesWithoutDeferredParsing() const;
216
217     void wrapperInsertRule(unsigned, Ref<StyleRuleBase>&&);
218     void wrapperRemoveRule(unsigned);
219     
220 protected:
221     StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase>>&);
222     StyleRuleGroup(Type, std::unique_ptr<DeferredStyleGroupRuleList>&&);
223     StyleRuleGroup(const StyleRuleGroup&);
224     
225 private:
226     void parseDeferredRulesIfNeeded() const;
227
228     mutable Vector<RefPtr<StyleRuleBase>> m_childRules;
229     mutable std::unique_ptr<DeferredStyleGroupRuleList> m_deferredRules;
230 };
231
232 inline const Vector<RefPtr<StyleRuleBase>>* StyleRuleGroup::childRulesWithoutDeferredParsing() const
233 {
234     return !m_deferredRules ? &m_childRules : nullptr;
235 }
236
237 class StyleRuleMedia final : public StyleRuleGroup {
238 public:
239     static Ref<StyleRuleMedia> create(Ref<MediaQuerySet>&& media, Vector<RefPtr<StyleRuleBase>>& adoptRules)
240     {
241         return adoptRef(*new StyleRuleMedia(WTFMove(media), adoptRules));
242     }
243
244     static Ref<StyleRuleMedia> create(Ref<MediaQuerySet>&& media, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredChildRules)
245     {
246         return adoptRef(*new StyleRuleMedia(WTFMove(media), WTFMove(deferredChildRules)));
247     }
248
249     MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
250
251     Ref<StyleRuleMedia> copy() const { return adoptRef(*new StyleRuleMedia(*this)); }
252
253 private:
254     StyleRuleMedia(Ref<MediaQuerySet>&&, Vector<RefPtr<StyleRuleBase>>& adoptRules);
255     StyleRuleMedia(Ref<MediaQuerySet>&&, std::unique_ptr<DeferredStyleGroupRuleList>&&);
256     StyleRuleMedia(const StyleRuleMedia&);
257
258     RefPtr<MediaQuerySet> m_mediaQueries;
259 };
260
261 class StyleRuleSupports final : public StyleRuleGroup {
262 public:
263     static Ref<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules)
264     {
265         return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
266     }
267     
268     static Ref<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredChildRules)
269     {
270         return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, WTFMove(deferredChildRules)));
271     }
272
273     String conditionText() const { return m_conditionText; }
274     bool conditionIsSupported() const { return m_conditionIsSupported; }
275     Ref<StyleRuleSupports> copy() const { return adoptRef(*new StyleRuleSupports(*this)); }
276
277 private:
278     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules);
279     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, std::unique_ptr<DeferredStyleGroupRuleList>&&);
280     
281     StyleRuleSupports(const StyleRuleSupports&);
282
283     String m_conditionText;
284     bool m_conditionIsSupported;
285 };
286
287 #if ENABLE(CSS_DEVICE_ADAPTATION)
288 class StyleRuleViewport final : public StyleRuleBase {
289 public:
290     static Ref<StyleRuleViewport> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRuleViewport(WTFMove(properties))); }
291
292     ~StyleRuleViewport();
293
294     const StyleProperties& properties() const { return m_properties.get(); }
295     MutableStyleProperties& mutableProperties();
296
297     Ref<StyleRuleViewport> copy() const { return adoptRef(*new StyleRuleViewport(*this)); }
298
299 private:
300     explicit StyleRuleViewport(Ref<StyleProperties>&&);
301     StyleRuleViewport(const StyleRuleViewport&);
302
303     Ref<StyleProperties> m_properties;
304 };
305 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
306
307 // This is only used by the CSS parser.
308 class StyleRuleCharset final : public StyleRuleBase {
309 public:
310     static Ref<StyleRuleCharset> create() { return adoptRef(*new StyleRuleCharset()); }
311     
312     ~StyleRuleCharset();
313     
314     Ref<StyleRuleCharset> copy() const { return adoptRef(*new StyleRuleCharset(*this)); }
315
316 private:
317     explicit StyleRuleCharset();
318     StyleRuleCharset(const StyleRuleCharset&);
319 };
320
321 class StyleRuleNamespace final : public StyleRuleBase {
322 public:
323     static Ref<StyleRuleNamespace> create(AtomicString prefix, AtomicString uri)
324     {
325         return adoptRef(*new StyleRuleNamespace(prefix, uri));
326     }
327     
328     ~StyleRuleNamespace();
329
330     Ref<StyleRuleNamespace> copy() const { return adoptRef(*new StyleRuleNamespace(*this)); }
331     
332     AtomicString prefix() const { return m_prefix; }
333     AtomicString uri() const { return m_uri; }
334
335 private:
336     StyleRuleNamespace(AtomicString prefix, AtomicString uri);
337     StyleRuleNamespace(const StyleRuleNamespace&);
338     
339     AtomicString m_prefix;
340     AtomicString m_uri;
341 };
342     
343 } // namespace WebCore
344
345 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRule)
346     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isStyleRule(); }
347 SPECIALIZE_TYPE_TRAITS_END()
348
349 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleFontFace)
350     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isFontFaceRule(); }
351 SPECIALIZE_TYPE_TRAITS_END()
352
353 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleMedia)
354     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isMediaRule(); }
355 SPECIALIZE_TYPE_TRAITS_END()
356
357 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRulePage)
358     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isPageRule(); }
359 SPECIALIZE_TYPE_TRAITS_END()
360
361 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleSupports)
362     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isSupportsRule(); }
363 SPECIALIZE_TYPE_TRAITS_END()
364
365 #if ENABLE(CSS_DEVICE_ADAPTATION)
366 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleViewport)
367     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isViewportRule(); }
368 SPECIALIZE_TYPE_TRAITS_END()
369 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
370
371 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleNamespace)
372     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isNamespaceRule(); }
373 SPECIALIZE_TYPE_TRAITS_END()
374
375 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleKeyframe)
376 static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isKeyframeRule(); }
377 SPECIALIZE_TYPE_TRAITS_END()
378
379 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleCharset)
380 static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isCharsetRule(); }
381 SPECIALIZE_TYPE_TRAITS_END()
382