c572872e6205aafb8e3cc81796b1e699cfbadf5a
[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 StyleKeyframe;
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 StyleKeyframe objects.
53         Namespace,
54         Supports = 12,
55 #if ENABLE(CSS_DEVICE_ADAPTATION)
56         Viewport = 15,
57 #endif
58         Region = 16,
59     };
60
61     Type type() const { return static_cast<Type>(m_type); }
62     
63     bool isCharsetRule() const { return type() == Charset; }
64     bool isFontFaceRule() const { return type() == FontFace; }
65     bool isKeyframesRule() const { return type() == Keyframes; }
66     bool isKeyframeRule() const { return type() == Keyframe; }
67     bool isNamespaceRule() const { return type() == Namespace; }
68     bool isMediaRule() const { return type() == Media; }
69     bool isPageRule() const { return type() == Page; }
70     bool isStyleRule() const { return type() == Style; }
71     bool isRegionRule() const { return type() == Region; }
72     bool isSupportsRule() const { return type() == Supports; }
73 #if ENABLE(CSS_DEVICE_ADAPTATION)
74     bool isViewportRule() const { return type() == Viewport; }
75 #endif
76     bool isImportRule() const { return type() == Import; }
77
78     Ref<StyleRuleBase> copy() const;
79
80     void deref()
81     {
82         if (derefBase())
83             destroy();
84     }
85
86     // FIXME: There shouldn't be any need for the null parent version.
87     RefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = nullptr) const;
88     RefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
89
90 protected:
91     StyleRuleBase(Type type)
92         : m_type(type)
93         { }
94
95     StyleRuleBase(const StyleRuleBase& o)
96         : WTF::RefCountedBase()
97         , m_type(o.m_type)
98         { }
99
100     ~StyleRuleBase() { }
101
102 private:
103     WEBCORE_EXPORT void destroy();
104     
105     RefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
106
107     unsigned m_type : 5;
108 };
109
110 class StyleRule final : public StyleRuleBase {
111     WTF_MAKE_FAST_ALLOCATED;
112 public:
113     static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties)
114     {
115         return adoptRef(*new StyleRule(WTFMove(properties)));
116     }
117     
118     ~StyleRule();
119
120     const CSSSelectorList& selectorList() const { return m_selectorList; }
121     
122     const StyleProperties& properties() const;
123     MutableStyleProperties& mutableProperties();
124     const StyleProperties* propertiesWithoutDeferredParsing() const;
125
126     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
127     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
128     void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); }
129
130     Ref<StyleRule> copy() const { return adoptRef(*new StyleRule(*this)); }
131
132     Vector<RefPtr<StyleRule>> splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned) const;
133
134     static unsigned averageSizeInBytes();
135
136 private:
137     StyleRule(Ref<StylePropertiesBase>&&);
138     StyleRule(const StyleRule&);
139
140     static Ref<StyleRule> create(const Vector<const CSSSelector*>&, Ref<StyleProperties>&&);
141
142     mutable Ref<StylePropertiesBase> m_properties;
143     CSSSelectorList m_selectorList;
144 };
145
146 inline const StyleProperties* StyleRule::propertiesWithoutDeferredParsing() const
147 {
148     return m_properties->type() != DeferredPropertiesType ? &downcast<StyleProperties>(m_properties.get()) : nullptr;
149 }
150
151 class StyleRuleFontFace final : public StyleRuleBase {
152 public:
153     static Ref<StyleRuleFontFace> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRuleFontFace(WTFMove(properties))); }
154     
155     ~StyleRuleFontFace();
156
157     const StyleProperties& properties() const { return m_properties; }
158     MutableStyleProperties& mutableProperties();
159
160     Ref<StyleRuleFontFace> copy() const { return adoptRef(*new StyleRuleFontFace(*this)); }
161
162 private:
163     explicit StyleRuleFontFace(Ref<StyleProperties>&&);
164     StyleRuleFontFace(const StyleRuleFontFace&);
165
166     Ref<StyleProperties> m_properties;
167 };
168
169 class StyleRulePage final : public StyleRuleBase {
170 public:
171     static Ref<StyleRulePage> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRulePage(WTFMove(properties))); }
172
173     ~StyleRulePage();
174
175     const CSSSelector* selector() const { return m_selectorList.first(); }    
176     const StyleProperties& properties() const { return m_properties; }
177     MutableStyleProperties& mutableProperties();
178
179     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
180     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
181
182     Ref<StyleRulePage> copy() const { return adoptRef(*new StyleRulePage(*this)); }
183
184 private:
185     explicit StyleRulePage(Ref<StyleProperties>&&);
186     StyleRulePage(const StyleRulePage&);
187     
188     Ref<StyleProperties> m_properties;
189     CSSSelectorList m_selectorList;
190 };
191
192 class DeferredStyleGroupRuleList final {
193 public:
194     DeferredStyleGroupRuleList(const CSSParserTokenRange&, CSSDeferredParser&);
195     
196     void parseDeferredRules(Vector<RefPtr<StyleRuleBase>>&);
197     void parseDeferredKeyframes(StyleRuleKeyframes&);
198
199 private:
200     Vector<CSSParserToken> m_tokens;
201     Ref<CSSDeferredParser> m_parser;
202 };
203     
204 class StyleRuleGroup : public StyleRuleBase {
205 public:
206     const Vector<RefPtr<StyleRuleBase>>& childRules() const;
207     const Vector<RefPtr<StyleRuleBase>>* childRulesWithoutDeferredParsing() const;
208
209     void wrapperInsertRule(unsigned, Ref<StyleRuleBase>&&);
210     void wrapperRemoveRule(unsigned);
211     
212 protected:
213     StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase>>&);
214     StyleRuleGroup(Type, std::unique_ptr<DeferredStyleGroupRuleList>&&);
215     StyleRuleGroup(const StyleRuleGroup&);
216     
217 private:
218     void parseDeferredRulesIfNeeded() const;
219
220     mutable Vector<RefPtr<StyleRuleBase>> m_childRules;
221     mutable std::unique_ptr<DeferredStyleGroupRuleList> m_deferredRules;
222 };
223
224 inline const Vector<RefPtr<StyleRuleBase>>* StyleRuleGroup::childRulesWithoutDeferredParsing() const
225 {
226     return !m_deferredRules ? &m_childRules : nullptr;
227 }
228
229 class StyleRuleMedia final : public StyleRuleGroup {
230 public:
231     static Ref<StyleRuleMedia> create(Ref<MediaQuerySet>&& media, Vector<RefPtr<StyleRuleBase>>& adoptRules)
232     {
233         return adoptRef(*new StyleRuleMedia(WTFMove(media), adoptRules));
234     }
235
236     static Ref<StyleRuleMedia> create(Ref<MediaQuerySet>&& media, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredChildRules)
237     {
238         return adoptRef(*new StyleRuleMedia(WTFMove(media), WTFMove(deferredChildRules)));
239     }
240
241     MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
242
243     Ref<StyleRuleMedia> copy() const { return adoptRef(*new StyleRuleMedia(*this)); }
244
245 private:
246     StyleRuleMedia(Ref<MediaQuerySet>&&, Vector<RefPtr<StyleRuleBase>>& adoptRules);
247     StyleRuleMedia(Ref<MediaQuerySet>&&, std::unique_ptr<DeferredStyleGroupRuleList>&&);
248     StyleRuleMedia(const StyleRuleMedia&);
249
250     RefPtr<MediaQuerySet> m_mediaQueries;
251 };
252
253 class StyleRuleSupports final : public StyleRuleGroup {
254 public:
255     static Ref<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules)
256     {
257         return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
258     }
259     
260     static Ref<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredChildRules)
261     {
262         return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, WTFMove(deferredChildRules)));
263     }
264
265     String conditionText() const { return m_conditionText; }
266     bool conditionIsSupported() const { return m_conditionIsSupported; }
267     Ref<StyleRuleSupports> copy() const { return adoptRef(*new StyleRuleSupports(*this)); }
268
269 private:
270     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules);
271     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, std::unique_ptr<DeferredStyleGroupRuleList>&&);
272     
273     StyleRuleSupports(const StyleRuleSupports&);
274
275     String m_conditionText;
276     bool m_conditionIsSupported;
277 };
278
279 class StyleRuleRegion final : public StyleRuleGroup {
280 public:
281     static Ref<StyleRuleRegion> create(Vector<std::unique_ptr<CSSParserSelector>>* selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
282     {
283         return adoptRef(*new StyleRuleRegion(selectors, adoptRules));
284     }
285     
286     static Ref<StyleRuleRegion> create(CSSSelectorList& selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
287     {
288         return adoptRef(*new StyleRuleRegion(selectors, adoptRules));
289     }
290     
291     const CSSSelectorList& selectorList() const { return m_selectorList; }
292
293     Ref<StyleRuleRegion> copy() const { return adoptRef(*new StyleRuleRegion(*this)); }
294
295 private:
296     StyleRuleRegion(Vector<std::unique_ptr<CSSParserSelector>>*, Vector<RefPtr<StyleRuleBase>>& adoptRules);
297     StyleRuleRegion(CSSSelectorList&, Vector<RefPtr<StyleRuleBase>>&);
298     
299     StyleRuleRegion(const StyleRuleRegion&);
300     
301     CSSSelectorList m_selectorList;
302 };
303
304 #if ENABLE(CSS_DEVICE_ADAPTATION)
305 class StyleRuleViewport final : public StyleRuleBase {
306 public:
307     static Ref<StyleRuleViewport> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRuleViewport(WTFMove(properties))); }
308
309     ~StyleRuleViewport();
310
311     const StyleProperties& properties() const { return m_properties.get(); }
312     MutableStyleProperties& mutableProperties();
313
314     Ref<StyleRuleViewport> copy() const { return adoptRef(*new StyleRuleViewport(*this)); }
315
316 private:
317     explicit StyleRuleViewport(Ref<StyleProperties>&&);
318     StyleRuleViewport(const StyleRuleViewport&);
319
320     Ref<StyleProperties> m_properties;
321 };
322 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
323
324 // This is only used by the CSS parser.
325 class StyleRuleCharset final : public StyleRuleBase {
326 public:
327     static Ref<StyleRuleCharset> create() { return adoptRef(*new StyleRuleCharset()); }
328     
329     ~StyleRuleCharset();
330     
331     Ref<StyleRuleCharset> copy() const { return adoptRef(*new StyleRuleCharset(*this)); }
332
333 private:
334     explicit StyleRuleCharset();
335     StyleRuleCharset(const StyleRuleCharset&);
336 };
337
338 class StyleRuleNamespace final : public StyleRuleBase {
339 public:
340     static Ref<StyleRuleNamespace> create(AtomicString prefix, AtomicString uri)
341     {
342         return adoptRef(*new StyleRuleNamespace(prefix, uri));
343     }
344     
345     ~StyleRuleNamespace();
346
347     Ref<StyleRuleNamespace> copy() const { return adoptRef(*new StyleRuleNamespace(*this)); }
348     
349     AtomicString prefix() const { return m_prefix; }
350     AtomicString uri() const { return m_uri; }
351
352 private:
353     StyleRuleNamespace(AtomicString prefix, AtomicString uri);
354     StyleRuleNamespace(const StyleRuleNamespace&);
355     
356     AtomicString m_prefix;
357     AtomicString m_uri;
358 };
359     
360 } // namespace WebCore
361
362 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRule)
363     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isStyleRule(); }
364 SPECIALIZE_TYPE_TRAITS_END()
365
366 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleFontFace)
367     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isFontFaceRule(); }
368 SPECIALIZE_TYPE_TRAITS_END()
369
370 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleMedia)
371     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isMediaRule(); }
372 SPECIALIZE_TYPE_TRAITS_END()
373
374 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRulePage)
375     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isPageRule(); }
376 SPECIALIZE_TYPE_TRAITS_END()
377
378 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleSupports)
379     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isSupportsRule(); }
380 SPECIALIZE_TYPE_TRAITS_END()
381
382 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleRegion)
383     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isRegionRule(); }
384 SPECIALIZE_TYPE_TRAITS_END()
385
386 #if ENABLE(CSS_DEVICE_ADAPTATION)
387 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleViewport)
388     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isViewportRule(); }
389 SPECIALIZE_TYPE_TRAITS_END()
390 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
391
392 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleNamespace)
393     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isNamespaceRule(); }
394 SPECIALIZE_TYPE_TRAITS_END()
395
396 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleKeyframe)
397 static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isKeyframeRule(); }
398 SPECIALIZE_TYPE_TRAITS_END()
399
400 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleCharset)
401 static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isCharsetRule(); }
402 SPECIALIZE_TYPE_TRAITS_END()
403