REGRESSION(r125294): A style rule with more than 8192 selectors can cause style corru...
[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 #ifndef StyleRule_h
23 #define StyleRule_h
24
25 #include "CSSSelectorList.h"
26 #include "MediaList.h"
27 #include <wtf/RefPtr.h>
28
29 namespace WebCore {
30
31 class CSSRule;
32 class CSSStyleRule;
33 class CSSStyleSheet;
34 class MutableStylePropertySet;
35 class StylePropertySet;
36
37 class StyleRuleBase : public WTF::RefCountedBase {
38     WTF_MAKE_FAST_ALLOCATED;
39 public:
40     enum Type {
41         Unknown, // Not used.
42         Style,
43         Charset, // Not used. These are internally strings owned by the style sheet.
44         Import,
45         Media,
46         FontFace,
47         Page,
48         Keyframes,
49         Keyframe, // Not used. These are internally non-rule StyleKeyframe objects.
50 #if ENABLE(CSS3_CONDITIONAL_RULES)
51         Supports = 12,
52 #endif
53 #if ENABLE(CSS_DEVICE_ADAPTATION)
54         Viewport = 15,
55 #endif
56         Region = 16,
57 #if ENABLE(CSS_SHADERS)
58         Filter = 17,
59 #endif
60 #if ENABLE(SHADOW_DOM)
61         HostInternal = 18, // Spec says Host = 1001, but we can use only 5 bit for type().
62 #endif
63     };
64
65     Type type() const { return static_cast<Type>(m_type); }
66     
67     bool isCharsetRule() const { return type() == Charset; }
68     bool isFontFaceRule() const { return type() == FontFace; }
69     bool isKeyframesRule() const { return type() == Keyframes; }
70     bool isMediaRule() const { return type() == Media; }
71     bool isPageRule() const { return type() == Page; }
72     bool isStyleRule() const { return type() == Style; }
73     bool isRegionRule() const { return type() == Region; }
74 #if ENABLE(CSS3_CONDITIONAL_RULES)
75     bool isSupportsRule() const { return type() == Supports; }
76 #endif
77 #if ENABLE(CSS_DEVICE_ADAPTATION)
78     bool isViewportRule() const { return type() == Viewport; }
79 #endif
80     bool isImportRule() const { return type() == Import; }
81 #if ENABLE(SHADOW_DOM)
82     bool isHostRule() const { return type() == HostInternal; }
83 #endif
84 #if ENABLE(CSS_SHADERS)
85     bool isFilterRule() const { return type() == Filter; }
86 #endif
87
88     PassRefPtr<StyleRuleBase> copy() const;
89
90     int sourceLine() const { return m_sourceLine; }
91
92     void deref()
93     {
94         if (derefBase())
95             destroy();
96     }
97
98     // FIXME: There shouldn't be any need for the null parent version.
99     PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const;
100     PassRefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
101
102 protected:
103     StyleRuleBase(Type type, signed sourceLine = 0) : m_type(type), m_sourceLine(sourceLine) { }
104     StyleRuleBase(const StyleRuleBase& o) : WTF::RefCountedBase(), m_type(o.m_type), m_sourceLine(o.m_sourceLine) { }
105
106     ~StyleRuleBase() { }
107
108 private:
109     void destroy();
110     
111     PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
112
113     unsigned m_type : 5;
114     signed m_sourceLine : 27;
115 };
116
117 class StyleRule : public StyleRuleBase {
118     WTF_MAKE_FAST_ALLOCATED;
119 public:
120     static PassRefPtr<StyleRule> create(int sourceLine) { return adoptRef(new StyleRule(sourceLine)); }
121     
122     ~StyleRule();
123
124     const CSSSelectorList& selectorList() const { return m_selectorList; }
125     const StylePropertySet* properties() const { return m_properties.get(); }
126     MutableStylePropertySet* mutableProperties();
127     
128     void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
129     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); }
130     void parserAdoptSelectorArray(CSSSelector* selectors) { m_selectorList.adoptSelectorArray(selectors); }
131     void setProperties(PassRefPtr<StylePropertySet>);
132
133     PassRefPtr<StyleRule> copy() const { return adoptRef(new StyleRule(*this)); }
134
135     Vector<RefPtr<StyleRule> > splitIntoMultipleRulesWithMaximumSelectorCount(unsigned maxSelectorCount) const;
136
137     static unsigned averageSizeInBytes();
138
139 private:
140     StyleRule(int sourceLine);
141     StyleRule(const StyleRule&);
142
143     static PassRefPtr<StyleRule> create(int sourceLine, const Vector<const CSSSelector*>&, PassRefPtr<StylePropertySet>);
144
145     RefPtr<StylePropertySet> m_properties;
146     CSSSelectorList m_selectorList;
147 };
148
149 inline const StyleRule* toStyleRule(const StyleRuleBase* rule)
150 {
151     ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isStyleRule());
152     return static_cast<const StyleRule*>(rule);
153 }
154
155 class StyleRuleFontFace : public StyleRuleBase {
156 public:
157     static PassRefPtr<StyleRuleFontFace> create() { return adoptRef(new StyleRuleFontFace); }
158     
159     ~StyleRuleFontFace();
160
161     const StylePropertySet* properties() const { return m_properties.get(); }
162     MutableStylePropertySet* mutableProperties();
163
164     void setProperties(PassRefPtr<StylePropertySet>);
165
166     PassRefPtr<StyleRuleFontFace> copy() const { return adoptRef(new StyleRuleFontFace(*this)); }
167
168
169 private:
170     StyleRuleFontFace();
171     StyleRuleFontFace(const StyleRuleFontFace&);
172
173     RefPtr<StylePropertySet> m_properties;
174 };
175
176 class StyleRulePage : public StyleRuleBase {
177 public:
178     static PassRefPtr<StyleRulePage> create() { return adoptRef(new StyleRulePage); }
179
180     ~StyleRulePage();
181
182     const CSSSelector* selector() const { return m_selectorList.first(); }    
183     const StylePropertySet* properties() const { return m_properties.get(); }
184     MutableStylePropertySet* mutableProperties();
185
186     void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
187     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); }
188     void setProperties(PassRefPtr<StylePropertySet>);
189
190     PassRefPtr<StyleRulePage> copy() const { return adoptRef(new StyleRulePage(*this)); }
191
192 private:
193     StyleRulePage();
194     StyleRulePage(const StyleRulePage&);
195     
196     RefPtr<StylePropertySet> m_properties;
197     CSSSelectorList m_selectorList;
198 };
199
200 class StyleRuleGroup : public StyleRuleBase {
201 public:
202     const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
203     
204     void wrapperInsertRule(unsigned, PassRefPtr<StyleRuleBase>);
205     void wrapperRemoveRule(unsigned);
206     
207 protected:
208     StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase> >& adoptRule);
209     StyleRuleGroup(const StyleRuleGroup&);
210     
211 private:
212     Vector<RefPtr<StyleRuleBase> > m_childRules;
213 };
214
215 class StyleRuleMedia : public StyleRuleGroup {
216 public:
217     static PassRefPtr<StyleRuleMedia> create(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules)
218     {
219         return adoptRef(new StyleRuleMedia(media, adoptRules));
220     }
221
222     MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
223
224     PassRefPtr<StyleRuleMedia> copy() const { return adoptRef(new StyleRuleMedia(*this)); }
225
226 private:
227     StyleRuleMedia(PassRefPtr<MediaQuerySet>, Vector<RefPtr<StyleRuleBase> >& adoptRules);
228     StyleRuleMedia(const StyleRuleMedia&);
229
230     RefPtr<MediaQuerySet> m_mediaQueries;
231 };
232
233 #if ENABLE(CSS3_CONDITIONAL_RULES)
234 class StyleRuleSupports : public StyleRuleGroup {
235 public:
236     static PassRefPtr<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules)
237     {
238         return adoptRef(new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
239     }
240
241     String conditionText() const { return m_conditionText; }
242     bool conditionIsSupported() const { return m_conditionIsSupported; }
243     PassRefPtr<StyleRuleSupports> copy() const { return adoptRef(new StyleRuleSupports(*this)); }
244
245 private:
246     StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules);
247     StyleRuleSupports(const StyleRuleSupports&);
248
249     String m_conditionText;
250     bool m_conditionIsSupported;
251 };
252 #endif
253
254 class StyleRuleRegion : public StyleRuleGroup {
255 public:
256     static PassRefPtr<StyleRuleRegion> create(Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<StyleRuleBase> >& adoptRules)
257     {
258         return adoptRef(new StyleRuleRegion(selectors, adoptRules));
259     }
260
261     const CSSSelectorList& selectorList() const { return m_selectorList; }
262
263     PassRefPtr<StyleRuleRegion> copy() const { return adoptRef(new StyleRuleRegion(*this)); }
264
265 private:
266     StyleRuleRegion(Vector<OwnPtr<CSSParserSelector> >*, Vector<RefPtr<StyleRuleBase> >& adoptRules);
267     StyleRuleRegion(const StyleRuleRegion&);
268     
269     CSSSelectorList m_selectorList;
270 };
271
272 #if ENABLE(SHADOW_DOM)
273 class StyleRuleHost : public StyleRuleGroup {
274 public:
275     static PassRefPtr<StyleRuleHost> create(Vector<RefPtr<StyleRuleBase> >& adoptRules)
276     {
277         return adoptRef(new StyleRuleHost(adoptRules));
278     }
279
280     PassRefPtr<StyleRuleHost> copy() const { return adoptRef(new StyleRuleHost(*this)); }
281
282 private:
283     StyleRuleHost(Vector<RefPtr<StyleRuleBase> >& adoptRules) : StyleRuleGroup(HostInternal, adoptRules) { }
284     StyleRuleHost(const StyleRuleHost& o) : StyleRuleGroup(o) { }
285 };
286 #endif
287
288 #if ENABLE(CSS_DEVICE_ADAPTATION)
289 class StyleRuleViewport : public StyleRuleBase {
290 public:
291     static PassRefPtr<StyleRuleViewport> create() { return adoptRef(new StyleRuleViewport); }
292
293     ~StyleRuleViewport();
294
295     const StylePropertySet* properties() const { return m_properties.get(); }
296     MutableStylePropertySet* mutableProperties();
297
298     void setProperties(PassRefPtr<StylePropertySet>);
299
300     PassRefPtr<StyleRuleViewport> copy() const { return adoptRef(new StyleRuleViewport(*this)); }
301
302 private:
303     StyleRuleViewport();
304     StyleRuleViewport(const StyleRuleViewport&);
305
306     RefPtr<StylePropertySet> m_properties;
307 };
308 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
309
310 inline const StyleRuleMedia* toStyleRuleMedia(const StyleRuleGroup* rule)
311 {
312     ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isMediaRule());
313     return static_cast<const StyleRuleMedia*>(rule);
314 }
315
316 #if ENABLE(CSS3_CONDITIONAL_RULES)
317 inline const StyleRuleSupports* toStyleRuleSupports(const StyleRuleGroup* rule)
318 {
319     ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isSupportsRule());
320     return static_cast<const StyleRuleSupports*>(rule);
321 }
322 #endif
323
324 inline const StyleRuleRegion* toStyleRuleRegion(const StyleRuleGroup* rule)
325 {
326     ASSERT_WITH_SECURITY_IMPLICATION(!rule || rule->isRegionRule());
327     return static_cast<const StyleRuleRegion*>(rule);
328 }
329
330 #if ENABLE(CSS_SHADERS)
331 class StyleRuleFilter : public StyleRuleBase {
332 public:
333     static PassRefPtr<StyleRuleFilter> create(const String& filterName) { return adoptRef(new StyleRuleFilter(filterName)); }
334
335     ~StyleRuleFilter();
336
337     const String& filterName() const { return m_filterName; }
338
339     const StylePropertySet* properties() const { return m_properties.get(); }
340     MutableStylePropertySet* mutableProperties();
341
342     void setProperties(PassRefPtr<StylePropertySet>);
343
344     PassRefPtr<StyleRuleFilter> copy() const { return adoptRef(new StyleRuleFilter(*this)); }
345
346 private:
347     StyleRuleFilter(const String&);
348     StyleRuleFilter(const StyleRuleFilter&);
349
350     String m_filterName;
351     RefPtr<StylePropertySet> m_properties;
352 };
353 #endif // ENABLE(CSS_SHADERS)
354
355 } // namespace WebCore
356
357 #endif // StyleRule_h