60d1dbb42b68da2d35ccee38b38e21405003a7ad
[WebKit-https.git] / Source / WebCore / css / StyleRule.cpp
1 /*
2  * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3  * (C) 2002-2003 Dirk Mueller (mueller@kde.org)
4  * Copyright (C) 2002, 2005, 2006, 2008, 2012 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 #include "config.h"
23 #include "StyleRule.h"
24
25 #include "CSSDeferredParser.h"
26 #include "CSSFontFaceRule.h"
27 #include "CSSImportRule.h"
28 #include "CSSKeyframeRule.h"
29 #include "CSSKeyframesRule.h"
30 #include "CSSMediaRule.h"
31 #include "CSSNamespaceRule.h"
32 #include "CSSPageRule.h"
33 #include "CSSStyleRule.h"
34 #include "CSSSupportsRule.h"
35 #include "CSSUnknownRule.h"
36 #include "MediaList.h"
37 #include "StyleProperties.h"
38 #include "StyleRuleImport.h"
39 #include "WebKitCSSRegionRule.h"
40 #include "WebKitCSSViewportRule.h"
41
42 namespace WebCore {
43
44 struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase {
45     unsigned bitfields : 5;
46 };
47
48 COMPILE_ASSERT(sizeof(StyleRuleBase) == sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
49
50 RefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
51 {
52     return createCSSOMWrapper(parentSheet, nullptr);
53 }
54
55 RefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
56
57     return createCSSOMWrapper(nullptr, parentRule);
58 }
59
60 void StyleRuleBase::destroy()
61 {
62     switch (type()) {
63     case Style:
64         delete downcast<StyleRule>(this);
65         return;
66     case Page:
67         delete downcast<StyleRulePage>(this);
68         return;
69     case FontFace:
70         delete downcast<StyleRuleFontFace>(this);
71         return;
72     case Media:
73         delete downcast<StyleRuleMedia>(this);
74         return;
75     case Supports:
76         delete downcast<StyleRuleSupports>(this);
77         return;
78 #if ENABLE(CSS_REGIONS)
79     case Region:
80         delete downcast<StyleRuleRegion>(this);
81         return;
82 #endif
83     case Import:
84         delete downcast<StyleRuleImport>(this);
85         return;
86     case Keyframes:
87         delete downcast<StyleRuleKeyframes>(this);
88         return;
89 #if ENABLE(CSS_DEVICE_ADAPTATION)
90     case Viewport:
91         delete downcast<StyleRuleViewport>(this);
92         return;
93 #endif
94     case Namespace:
95         delete downcast<StyleRuleNamespace>(this);
96         return;
97     case Keyframe:
98         delete downcast<StyleRuleKeyframe>(this);
99         return;
100     case Charset:
101         delete downcast<StyleRuleCharset>(this);
102         return;
103     case Unknown:
104 #if !ENABLE(CSS_REGIONS)
105     case Region:
106 #endif
107         ASSERT_NOT_REACHED();
108         return;
109     }
110     ASSERT_NOT_REACHED();
111 }
112
113 Ref<StyleRuleBase> StyleRuleBase::copy() const
114 {
115     switch (type()) {
116     case Style:
117         return downcast<StyleRule>(*this).copy();
118     case Page:
119         return downcast<StyleRulePage>(*this).copy();
120     case FontFace:
121         return downcast<StyleRuleFontFace>(*this).copy();
122     case Media:
123         return downcast<StyleRuleMedia>(*this).copy();
124     case Supports:
125         return downcast<StyleRuleSupports>(*this).copy();
126 #if ENABLE(CSS_REGIONS)
127     case Region:
128         return downcast<StyleRuleRegion>(*this).copy();
129 #endif
130     case Keyframes:
131         return downcast<StyleRuleKeyframes>(*this).copy();
132 #if ENABLE(CSS_DEVICE_ADAPTATION)
133     case Viewport:
134         return downcast<StyleRuleViewport>(*this).copy();
135 #endif
136     case Import:
137     case Namespace:
138         // FIXME: Copy import and namespace rules.
139         break;
140     case Unknown:
141     case Charset:
142     case Keyframe:
143 #if !ENABLE(CSS_REGIONS)
144     case Region:
145 #endif
146         break;
147     }
148     CRASH();
149 }
150
151 RefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
152 {
153     RefPtr<CSSRule> rule;
154     StyleRuleBase& self = const_cast<StyleRuleBase&>(*this);
155     switch (type()) {
156     case Style:
157         rule = CSSStyleRule::create(downcast<StyleRule>(self), parentSheet);
158         break;
159     case Page:
160         rule = CSSPageRule::create(downcast<StyleRulePage>(self), parentSheet);
161         break;
162     case FontFace:
163         rule = CSSFontFaceRule::create(downcast<StyleRuleFontFace>(self), parentSheet);
164         break;
165     case Media:
166         rule = CSSMediaRule::create(downcast<StyleRuleMedia>(self), parentSheet);
167         break;
168     case Supports:
169         rule = CSSSupportsRule::create(downcast<StyleRuleSupports>(self), parentSheet);
170         break;
171 #if ENABLE(CSS_REGIONS)
172     case Region:
173         rule = WebKitCSSRegionRule::create(downcast<StyleRuleRegion>(self), parentSheet);
174         break;
175 #endif
176     case Import:
177         rule = CSSImportRule::create(downcast<StyleRuleImport>(self), parentSheet);
178         break;
179     case Keyframes:
180         rule = CSSKeyframesRule::create(downcast<StyleRuleKeyframes>(self), parentSheet);
181         break;
182 #if ENABLE(CSS_DEVICE_ADAPTATION)
183     case Viewport:
184         rule = WebKitCSSViewportRule::create(downcast<StyleRuleViewport>(self), parentSheet);
185         break;
186 #endif
187     case Namespace:
188         rule = CSSNamespaceRule::create(downcast<StyleRuleNamespace>(self), parentSheet);
189         break;
190     case Unknown:
191     case Charset:
192     case Keyframe:
193 #if !ENABLE(CSS_REGIONS)
194     case Region:
195 #endif
196         ASSERT_NOT_REACHED();
197         return nullptr;
198     }
199     if (parentRule)
200         rule->setParentRule(parentRule);
201     return rule;
202 }
203
204 unsigned StyleRule::averageSizeInBytes()
205 {
206     return sizeof(StyleRule) + sizeof(CSSSelector) + StyleProperties::averageSizeInBytes();
207 }
208
209 StyleRule::StyleRule(Ref<StylePropertiesBase>&& properties)
210     : StyleRuleBase(Style)
211     , m_properties(WTFMove(properties))
212 {
213 }
214
215 StyleRule::StyleRule(const StyleRule& o)
216     : StyleRuleBase(o)
217     , m_properties(o.properties().mutableCopy())
218     , m_selectorList(o.m_selectorList)
219 {
220 }
221
222 StyleRule::~StyleRule()
223 {
224 }
225
226 const StyleProperties& StyleRule::properties() const
227 {
228     if (m_properties->type() == DeferredPropertiesType)
229         m_properties = downcast<DeferredStyleProperties>(m_properties.get()).parseDeferredProperties();
230     return downcast<StyleProperties>(m_properties.get());
231 }
232
233 MutableStyleProperties& StyleRule::mutableProperties()
234 {
235     if (!is<MutableStyleProperties>(m_properties.get()))
236         m_properties = properties().mutableCopy();
237     return downcast<MutableStyleProperties>(m_properties.get());
238 }
239
240 Ref<StyleRule> StyleRule::create(const Vector<const CSSSelector*>& selectors, Ref<StyleProperties>&& properties)
241 {
242     ASSERT_WITH_SECURITY_IMPLICATION(!selectors.isEmpty());
243     CSSSelector* selectorListArray = reinterpret_cast<CSSSelector*>(fastMalloc(sizeof(CSSSelector) * selectors.size()));
244     for (unsigned i = 0; i < selectors.size(); ++i)
245         new (NotNull, &selectorListArray[i]) CSSSelector(*selectors.at(i));
246     selectorListArray[selectors.size() - 1].setLastInSelectorList();
247     auto rule = StyleRule::create(WTFMove(properties));
248     rule.get().parserAdoptSelectorArray(selectorListArray);
249     return rule;
250 }
251
252 Vector<RefPtr<StyleRule>> StyleRule::splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned maxCount) const
253 {
254     ASSERT(selectorList().componentCount() > maxCount);
255
256     Vector<RefPtr<StyleRule>> rules;
257     Vector<const CSSSelector*> componentsSinceLastSplit;
258
259     for (const CSSSelector* selector = selectorList().first(); selector; selector = CSSSelectorList::next(selector)) {
260         Vector<const CSSSelector*, 8> componentsInThisSelector;
261         for (const CSSSelector* component = selector; component; component = component->tagHistory())
262             componentsInThisSelector.append(component);
263
264         if (componentsInThisSelector.size() + componentsSinceLastSplit.size() > maxCount && !componentsSinceLastSplit.isEmpty()) {
265             rules.append(create(componentsSinceLastSplit, const_cast<StyleProperties&>(properties())));
266             componentsSinceLastSplit.clear();
267         }
268
269         componentsSinceLastSplit.appendVector(componentsInThisSelector);
270     }
271
272     if (!componentsSinceLastSplit.isEmpty())
273         rules.append(create(componentsSinceLastSplit, const_cast<StyleProperties&>(properties())));
274
275     return rules;
276 }
277
278 StyleRulePage::StyleRulePage(Ref<StyleProperties>&& properties)
279     : StyleRuleBase(Page)
280     , m_properties(WTFMove(properties))
281 {
282 }
283
284 StyleRulePage::StyleRulePage(const StyleRulePage& o)
285     : StyleRuleBase(o)
286     , m_properties(o.m_properties->mutableCopy())
287     , m_selectorList(o.m_selectorList)
288 {
289 }
290
291 StyleRulePage::~StyleRulePage()
292 {
293 }
294
295 MutableStyleProperties& StyleRulePage::mutableProperties()
296 {
297     if (!is<MutableStyleProperties>(m_properties.get()))
298         m_properties = m_properties->mutableCopy();
299     return downcast<MutableStyleProperties>(m_properties.get());
300 }
301
302 StyleRuleFontFace::StyleRuleFontFace(Ref<StyleProperties>&& properties)
303     : StyleRuleBase(FontFace)
304     , m_properties(WTFMove(properties))
305 {
306 }
307
308 StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& o)
309     : StyleRuleBase(o)
310     , m_properties(o.m_properties->mutableCopy())
311 {
312 }
313
314 StyleRuleFontFace::~StyleRuleFontFace()
315 {
316 }
317
318 MutableStyleProperties& StyleRuleFontFace::mutableProperties()
319 {
320     if (!is<MutableStyleProperties>(m_properties.get()))
321         m_properties = m_properties->mutableCopy();
322     return downcast<MutableStyleProperties>(m_properties.get());
323 }
324
325 DeferredStyleGroupRuleList::DeferredStyleGroupRuleList(const CSSParserTokenRange& range, CSSDeferredParser& parser)
326     : m_parser(parser)
327 {
328     size_t length = range.end() - range.begin();
329     m_tokens.reserveCapacity(length);
330     m_tokens.append(range.begin(), length);
331 }
332
333 void DeferredStyleGroupRuleList::parseDeferredRules(Vector<RefPtr<StyleRuleBase>>& childRules)
334 {
335     m_parser->parseRuleList(m_tokens, childRules);
336 }
337
338 void DeferredStyleGroupRuleList::parseDeferredKeyframes(StyleRuleKeyframes& keyframesRule)
339 {
340     m_parser->parseKeyframeList(m_tokens, keyframesRule);
341 }
342     
343 StyleRuleGroup::StyleRuleGroup(Type type, Vector<RefPtr<StyleRuleBase>>& adoptRule)
344     : StyleRuleBase(type)
345 {
346     m_childRules.swap(adoptRule);
347 }
348
349 StyleRuleGroup::StyleRuleGroup(Type type, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredRules)
350     : StyleRuleBase(type)
351     , m_deferredRules(WTFMove(deferredRules))
352 {
353 }
354
355 StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& o)
356     : StyleRuleBase(o)
357 {
358     m_childRules.reserveInitialCapacity(o.childRules().size());
359     for (auto& childRule : o.childRules())
360         m_childRules.uncheckedAppend(childRule->copy());
361 }
362
363 const Vector<RefPtr<StyleRuleBase>>& StyleRuleGroup::childRules() const
364 {
365     parseDeferredRulesIfNeeded();
366     return m_childRules;
367 }
368
369 void StyleRuleGroup::wrapperInsertRule(unsigned index, Ref<StyleRuleBase>&& rule)
370 {
371     parseDeferredRulesIfNeeded();
372     m_childRules.insert(index, WTFMove(rule));
373 }
374     
375 void StyleRuleGroup::wrapperRemoveRule(unsigned index)
376 {
377     parseDeferredRulesIfNeeded();
378     m_childRules.remove(index);
379 }
380
381 void StyleRuleGroup::parseDeferredRulesIfNeeded() const
382 {
383     if (!m_deferredRules)
384         return;
385     
386     m_deferredRules->parseDeferredRules(m_childRules);
387     m_deferredRules = nullptr;
388 }
389     
390 StyleRuleMedia::StyleRuleMedia(Ref<MediaQuerySet>&& media, Vector<RefPtr<StyleRuleBase>>& adoptRules)
391     : StyleRuleGroup(Media, adoptRules)
392     , m_mediaQueries(WTFMove(media))
393 {
394 }
395
396 StyleRuleMedia::StyleRuleMedia(Ref<MediaQuerySet>&& media, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredRules)
397     : StyleRuleGroup(Media, WTFMove(deferredRules))
398     , m_mediaQueries(WTFMove(media))
399 {
400 }
401
402 StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o)
403     : StyleRuleGroup(o)
404 {
405     if (o.m_mediaQueries)
406         m_mediaQueries = o.m_mediaQueries->copy();
407 }
408
409
410 StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules)
411     : StyleRuleGroup(Supports, adoptRules)
412     , m_conditionText(conditionText)
413     , m_conditionIsSupported(conditionIsSupported)
414 {
415 }
416
417 StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported,  std::unique_ptr<DeferredStyleGroupRuleList>&& deferredRules)
418     : StyleRuleGroup(Supports, WTFMove(deferredRules))
419     , m_conditionText(conditionText)
420     , m_conditionIsSupported(conditionIsSupported)
421 {
422 }
423
424 StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& o)
425     : StyleRuleGroup(o)
426     , m_conditionText(o.m_conditionText)
427     , m_conditionIsSupported(o.m_conditionIsSupported)
428 {
429 }
430
431 StyleRuleRegion::StyleRuleRegion(Vector<std::unique_ptr<CSSParserSelector>>* selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
432     : StyleRuleGroup(Region, adoptRules)
433 {
434     m_selectorList.adoptSelectorVector(*selectors);
435 }
436
437 StyleRuleRegion::StyleRuleRegion(CSSSelectorList& selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
438     : StyleRuleGroup(Region, adoptRules)
439     , m_selectorList(WTFMove(selectors))
440 {
441 }
442
443 StyleRuleRegion::StyleRuleRegion(const StyleRuleRegion& o)
444     : StyleRuleGroup(o)
445     , m_selectorList(o.m_selectorList)
446 {
447 }
448
449
450 #if ENABLE(CSS_DEVICE_ADAPTATION)
451 StyleRuleViewport::StyleRuleViewport(Ref<StyleProperties>&& properties)
452     : StyleRuleBase(Viewport, 0)
453     , m_properties(WTFMove(properties))
454 {
455 }
456
457 StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& o)
458     : StyleRuleBase(o)
459     , m_properties(o.m_properties->mutableCopy())
460 {
461 }
462
463 StyleRuleViewport::~StyleRuleViewport()
464 {
465 }
466
467 MutableStyleProperties& StyleRuleViewport::mutableProperties()
468 {
469     if (!m_properties->isMutable())
470         m_properties = m_properties->mutableCopy();
471     return static_cast<MutableStyleProperties&>(m_properties.get());
472 }
473 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
474
475 StyleRuleCharset::StyleRuleCharset()
476     : StyleRuleBase(Charset)
477 {
478 }
479
480 StyleRuleCharset::StyleRuleCharset(const StyleRuleCharset& o)
481     : StyleRuleBase(o)
482 {
483 }
484
485 StyleRuleCharset::~StyleRuleCharset()
486 {
487 }
488
489 StyleRuleNamespace::StyleRuleNamespace(AtomicString prefix, AtomicString uri)
490     : StyleRuleBase(Namespace)
491     , m_prefix(prefix)
492     , m_uri(uri)
493 {
494 }
495
496 StyleRuleNamespace::StyleRuleNamespace(const StyleRuleNamespace& o)
497     : StyleRuleBase(o)
498     , m_prefix(o.m_prefix)
499     , m_uri(o.m_uri)
500 {
501 }
502
503 StyleRuleNamespace::~StyleRuleNamespace()
504 {
505 }
506
507 } // namespace WebCore