Use "= default" to denote default constructor or destructor
[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)
90         : m_type(type)
91         { }
92
93     StyleRuleBase(const StyleRuleBase& o)
94         : WTF::RefCountedBase()
95         , m_type(o.m_type)
96         { }
97
98     ~StyleRuleBase() = default;
99
100 private:
101     WEBCORE_EXPORT void destroy();
102     
103     RefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
104
105     unsigned m_type : 5;
106 };
107
108 class StyleRule final : public StyleRuleBase {
109     WTF_MAKE_FAST_ALLOCATED;
110 public:
111     static Ref<StyleRule> create(Ref<StylePropertiesBase>&& properties)
112     {
113         return adoptRef(*new StyleRule(WTFMove(properties)));
114     }
115     
116     ~StyleRule();
117
118     const CSSSelectorList& selectorList() const { return m_selectorList; }
119     
120     const StyleProperties& properties() const;
121     MutableStyleProperties& mutableProperties();
122     const StyleProperties* propertiesWithoutDeferredParsing() const;
123
124     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
125     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
126     void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); }
127
128     Ref<StyleRule> copy() const { return adoptRef(*new StyleRule(*this)); }
129
130     Vector<RefPtr<StyleRule>> splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned) const;
131
132     static unsigned averageSizeInBytes();
133
134 private:
135     StyleRule(Ref<StylePropertiesBase>&&);
136     StyleRule(const StyleRule&);
137
138     static Ref<StyleRule> create(const Vector<const CSSSelector*>&, Ref<StyleProperties>&&);
139
140     mutable Ref<StylePropertiesBase> m_properties;
141     CSSSelectorList m_selectorList;
142 };
143
144 inline const StyleProperties* StyleRule::propertiesWithoutDeferredParsing() const
145 {
146     return m_properties->type() != DeferredPropertiesType ? &downcast<StyleProperties>(m_properties.get()) : nullptr;
147 }
148
149 class StyleRuleFontFace final : public StyleRuleBase {
150 public:
151     static Ref<StyleRuleFontFace> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRuleFontFace(WTFMove(properties))); }
152     
153     ~StyleRuleFontFace();
154
155     const StyleProperties& properties() const { return m_properties; }
156     MutableStyleProperties& mutableProperties();
157
158     Ref<StyleRuleFontFace> copy() const { return adoptRef(*new StyleRuleFontFace(*this)); }
159
160 private:
161     explicit StyleRuleFontFace(Ref<StyleProperties>&&);
162     StyleRuleFontFace(const StyleRuleFontFace&);
163
164     Ref<StyleProperties> m_properties;
165 };
166
167 class StyleRulePage final : public StyleRuleBase {
168 public:
169     static Ref<StyleRulePage> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRulePage(WTFMove(properties))); }
170
171     ~StyleRulePage();
172
173     const CSSSelector* selector() const { return m_selectorList.first(); }    
174     const StyleProperties& properties() const { return m_properties; }
175     MutableStyleProperties& mutableProperties();
176
177     void parserAdoptSelectorVector(Vector<std::unique_ptr<CSSParserSelector>>& selectors) { m_selectorList.adoptSelectorVector(selectors); }
178     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList = WTFMove(selectors); }
179
180     Ref<StyleRulePage> copy() const { return adoptRef(*new StyleRulePage(*this)); }
181
182 private:
183     explicit StyleRulePage(Ref<StyleProperties>&&);
184     StyleRulePage(const StyleRulePage&);
185     
186     Ref<StyleProperties> m_properties;
187     CSSSelectorList m_selectorList;
188 };
189
190 class DeferredStyleGroupRuleList final {
191 public:
192     DeferredStyleGroupRuleList(const CSSParserTokenRange&, CSSDeferredParser&);
193     
194     void parseDeferredRules(Vector<RefPtr<StyleRuleBase>>&);
195     void parseDeferredKeyframes(StyleRuleKeyframes&);
196
197 private:
198     Vector<CSSParserToken> m_tokens;
199     Ref<CSSDeferredParser> m_parser;
200 };
201     
202 class StyleRuleGroup : public StyleRuleBase {
203 public:
204     const Vector<RefPtr<StyleRuleBase>>& childRules() const;
205     const Vector<RefPtr<StyleRuleBase>>* childRulesWithoutDeferredParsing() const;
206
207     void wrapperInsertRule(unsigned, Ref<StyleRuleBase>&&);
208     void wrapperRemoveRule(unsigned);
209     
210 protected:
211     StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase>>&);
212     StyleRuleGroup(Type, std::unique_ptr<DeferredStyleGroupRuleList>&&);
213     StyleRuleGroup(const StyleRuleGroup&);
214     
215 private:
216     void parseDeferredRulesIfNeeded() const;
217
218     mutable Vector<RefPtr<StyleRuleBase>> m_childRules;
219     mutable std::unique_ptr<DeferredStyleGroupRuleList> m_deferredRules;
220 };
221
222 inline const Vector<RefPtr<StyleRuleBase>>* StyleRuleGroup::childRulesWithoutDeferredParsing() const
223 {
224     return !m_deferredRules ? &m_childRules : nullptr;
225 }
226
227 class StyleRuleMedia final : public StyleRuleGroup {
228 public:
229     static Ref<StyleRuleMedia> create(Ref<MediaQuerySet>&& media, Vector<RefPtr<StyleRuleBase>>& adoptRules)
230     {
231         return adoptRef(*new StyleRuleMedia(WTFMove(media), adoptRules));
232     }
233
234     static Ref<StyleRuleMedia> create(Ref<MediaQuerySet>&& media, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredChildRules)
235     {
236         return adoptRef(*new StyleRuleMedia(WTFMove(media), WTFMove(deferredChildRules)));
237     }
238
239     MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
240
241     Ref<StyleRuleMedia> copy() const { return adoptRef(*new StyleRuleMedia(*this)); }
242
243 private:
244     StyleRuleMedia(Ref<MediaQuerySet>&&, Vector<RefPtr<StyleRuleBase>>& adoptRules);
245     StyleRuleMedia(Ref<MediaQuerySet>&&, std::unique_ptr<DeferredStyleGroupRuleList>&&);
246     StyleRuleMedia(const StyleRuleMedia&);
247
248     RefPtr<MediaQuerySet> m_mediaQueries;
249 };
250
251 class StyleRuleSupports final : public StyleRuleGroup {
252 public:
253     static Ref<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules)
254     {
255         return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
256     }
257     
258     static Ref<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredChildRules)
259     {
260         return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, WTFMove(deferredChildRules)));
261     }
262
263     String conditionText() const { return m_conditionText; }
264     bool conditionIsSupported() const { return m_conditionIsSupported; }
265     Ref<StyleRuleSupports> copy() const { return adoptRef(*new StyleRuleSupports(*this)); }
266
267 private:
268     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules);
269     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, std::unique_ptr<DeferredStyleGroupRuleList>&&);
270     
271     StyleRuleSupports(const StyleRuleSupports&);
272
273     String m_conditionText;
274     bool m_conditionIsSupported;
275 };
276
277 #if ENABLE(CSS_DEVICE_ADAPTATION)
278 class StyleRuleViewport final : public StyleRuleBase {
279 public:
280     static Ref<StyleRuleViewport> create(Ref<StyleProperties>&& properties) { return adoptRef(*new StyleRuleViewport(WTFMove(properties))); }
281
282     ~StyleRuleViewport();
283
284     const StyleProperties& properties() const { return m_properties.get(); }
285     MutableStyleProperties& mutableProperties();
286
287     Ref<StyleRuleViewport> copy() const { return adoptRef(*new StyleRuleViewport(*this)); }
288
289 private:
290     explicit StyleRuleViewport(Ref<StyleProperties>&&);
291     StyleRuleViewport(const StyleRuleViewport&);
292
293     Ref<StyleProperties> m_properties;
294 };
295 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
296
297 // This is only used by the CSS parser.
298 class StyleRuleCharset final : public StyleRuleBase {
299 public:
300     static Ref<StyleRuleCharset> create() { return adoptRef(*new StyleRuleCharset()); }
301     
302     ~StyleRuleCharset();
303     
304     Ref<StyleRuleCharset> copy() const { return adoptRef(*new StyleRuleCharset(*this)); }
305
306 private:
307     explicit StyleRuleCharset();
308     StyleRuleCharset(const StyleRuleCharset&);
309 };
310
311 class StyleRuleNamespace final : public StyleRuleBase {
312 public:
313     static Ref<StyleRuleNamespace> create(AtomicString prefix, AtomicString uri)
314     {
315         return adoptRef(*new StyleRuleNamespace(prefix, uri));
316     }
317     
318     ~StyleRuleNamespace();
319
320     Ref<StyleRuleNamespace> copy() const { return adoptRef(*new StyleRuleNamespace(*this)); }
321     
322     AtomicString prefix() const { return m_prefix; }
323     AtomicString uri() const { return m_uri; }
324
325 private:
326     StyleRuleNamespace(AtomicString prefix, AtomicString uri);
327     StyleRuleNamespace(const StyleRuleNamespace&);
328     
329     AtomicString m_prefix;
330     AtomicString m_uri;
331 };
332     
333 } // namespace WebCore
334
335 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRule)
336     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isStyleRule(); }
337 SPECIALIZE_TYPE_TRAITS_END()
338
339 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleFontFace)
340     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isFontFaceRule(); }
341 SPECIALIZE_TYPE_TRAITS_END()
342
343 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleMedia)
344     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isMediaRule(); }
345 SPECIALIZE_TYPE_TRAITS_END()
346
347 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRulePage)
348     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isPageRule(); }
349 SPECIALIZE_TYPE_TRAITS_END()
350
351 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleSupports)
352     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isSupportsRule(); }
353 SPECIALIZE_TYPE_TRAITS_END()
354
355 #if ENABLE(CSS_DEVICE_ADAPTATION)
356 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleViewport)
357     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isViewportRule(); }
358 SPECIALIZE_TYPE_TRAITS_END()
359 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
360
361 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleNamespace)
362     static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isNamespaceRule(); }
363 SPECIALIZE_TYPE_TRAITS_END()
364
365 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleKeyframe)
366 static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isKeyframeRule(); }
367 SPECIALIZE_TYPE_TRAITS_END()
368
369 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::StyleRuleCharset)
370 static bool isType(const WebCore::StyleRuleBase& rule) { return rule.isCharsetRule(); }
371 SPECIALIZE_TYPE_TRAITS_END()
372