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.
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.
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.
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.
23 #include "StyleRule.h"
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"
44 struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase {
45 unsigned bitfields : 5;
48 COMPILE_ASSERT(sizeof(StyleRuleBase) == sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
50 RefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
52 return createCSSOMWrapper(parentSheet, nullptr);
55 RefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
57 return createCSSOMWrapper(nullptr, parentRule);
60 void StyleRuleBase::destroy()
64 delete downcast<StyleRule>(this);
67 delete downcast<StyleRulePage>(this);
70 delete downcast<StyleRuleFontFace>(this);
73 delete downcast<StyleRuleMedia>(this);
76 delete downcast<StyleRuleSupports>(this);
78 #if ENABLE(CSS_REGIONS)
80 delete downcast<StyleRuleRegion>(this);
84 delete downcast<StyleRuleImport>(this);
87 delete downcast<StyleRuleKeyframes>(this);
89 #if ENABLE(CSS_DEVICE_ADAPTATION)
91 delete downcast<StyleRuleViewport>(this);
95 delete downcast<StyleRuleNamespace>(this);
98 delete downcast<StyleRuleKeyframe>(this);
101 delete downcast<StyleRuleCharset>(this);
104 #if !ENABLE(CSS_REGIONS)
107 ASSERT_NOT_REACHED();
110 ASSERT_NOT_REACHED();
113 Ref<StyleRuleBase> StyleRuleBase::copy() const
117 return downcast<StyleRule>(*this).copy();
119 return downcast<StyleRulePage>(*this).copy();
121 return downcast<StyleRuleFontFace>(*this).copy();
123 return downcast<StyleRuleMedia>(*this).copy();
125 return downcast<StyleRuleSupports>(*this).copy();
126 #if ENABLE(CSS_REGIONS)
128 return downcast<StyleRuleRegion>(*this).copy();
131 return downcast<StyleRuleKeyframes>(*this).copy();
132 #if ENABLE(CSS_DEVICE_ADAPTATION)
134 return downcast<StyleRuleViewport>(*this).copy();
138 // FIXME: Copy import and namespace rules.
143 #if !ENABLE(CSS_REGIONS)
151 RefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
153 RefPtr<CSSRule> rule;
154 StyleRuleBase& self = const_cast<StyleRuleBase&>(*this);
157 rule = CSSStyleRule::create(downcast<StyleRule>(self), parentSheet);
160 rule = CSSPageRule::create(downcast<StyleRulePage>(self), parentSheet);
163 rule = CSSFontFaceRule::create(downcast<StyleRuleFontFace>(self), parentSheet);
166 rule = CSSMediaRule::create(downcast<StyleRuleMedia>(self), parentSheet);
169 rule = CSSSupportsRule::create(downcast<StyleRuleSupports>(self), parentSheet);
171 #if ENABLE(CSS_REGIONS)
173 rule = WebKitCSSRegionRule::create(downcast<StyleRuleRegion>(self), parentSheet);
177 rule = CSSImportRule::create(downcast<StyleRuleImport>(self), parentSheet);
180 rule = CSSKeyframesRule::create(downcast<StyleRuleKeyframes>(self), parentSheet);
182 #if ENABLE(CSS_DEVICE_ADAPTATION)
184 rule = WebKitCSSViewportRule::create(downcast<StyleRuleViewport>(self), parentSheet);
188 rule = CSSNamespaceRule::create(downcast<StyleRuleNamespace>(self), parentSheet);
193 #if !ENABLE(CSS_REGIONS)
196 ASSERT_NOT_REACHED();
200 rule->setParentRule(parentRule);
204 unsigned StyleRule::averageSizeInBytes()
206 return sizeof(StyleRule) + sizeof(CSSSelector) + StyleProperties::averageSizeInBytes();
209 StyleRule::StyleRule(Ref<StylePropertiesBase>&& properties)
210 : StyleRuleBase(Style)
211 , m_properties(WTFMove(properties))
215 StyleRule::StyleRule(const StyleRule& o)
217 , m_properties(o.properties().mutableCopy())
218 , m_selectorList(o.m_selectorList)
222 StyleRule::~StyleRule()
226 const StyleProperties& StyleRule::properties() const
228 if (m_properties->type() == DeferredPropertiesType)
229 m_properties = downcast<DeferredStyleProperties>(m_properties.get()).parseDeferredProperties();
230 return downcast<StyleProperties>(m_properties.get());
233 MutableStyleProperties& StyleRule::mutableProperties()
235 if (!is<MutableStyleProperties>(m_properties.get()))
236 m_properties = properties().mutableCopy();
237 return downcast<MutableStyleProperties>(m_properties.get());
240 Ref<StyleRule> StyleRule::create(const Vector<const CSSSelector*>& selectors, Ref<StyleProperties>&& properties)
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);
252 Vector<RefPtr<StyleRule>> StyleRule::splitIntoMultipleRulesWithMaximumSelectorComponentCount(unsigned maxCount) const
254 ASSERT(selectorList().componentCount() > maxCount);
256 Vector<RefPtr<StyleRule>> rules;
257 Vector<const CSSSelector*> componentsSinceLastSplit;
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);
264 if (componentsInThisSelector.size() + componentsSinceLastSplit.size() > maxCount && !componentsSinceLastSplit.isEmpty()) {
265 rules.append(create(componentsSinceLastSplit, const_cast<StyleProperties&>(properties())));
266 componentsSinceLastSplit.clear();
269 componentsSinceLastSplit.appendVector(componentsInThisSelector);
272 if (!componentsSinceLastSplit.isEmpty())
273 rules.append(create(componentsSinceLastSplit, const_cast<StyleProperties&>(properties())));
278 StyleRulePage::StyleRulePage(Ref<StyleProperties>&& properties)
279 : StyleRuleBase(Page)
280 , m_properties(WTFMove(properties))
284 StyleRulePage::StyleRulePage(const StyleRulePage& o)
286 , m_properties(o.m_properties->mutableCopy())
287 , m_selectorList(o.m_selectorList)
291 StyleRulePage::~StyleRulePage()
295 MutableStyleProperties& StyleRulePage::mutableProperties()
297 if (!is<MutableStyleProperties>(m_properties.get()))
298 m_properties = m_properties->mutableCopy();
299 return downcast<MutableStyleProperties>(m_properties.get());
302 StyleRuleFontFace::StyleRuleFontFace(Ref<StyleProperties>&& properties)
303 : StyleRuleBase(FontFace)
304 , m_properties(WTFMove(properties))
308 StyleRuleFontFace::StyleRuleFontFace(const StyleRuleFontFace& o)
310 , m_properties(o.m_properties->mutableCopy())
314 StyleRuleFontFace::~StyleRuleFontFace()
318 MutableStyleProperties& StyleRuleFontFace::mutableProperties()
320 if (!is<MutableStyleProperties>(m_properties.get()))
321 m_properties = m_properties->mutableCopy();
322 return downcast<MutableStyleProperties>(m_properties.get());
325 DeferredStyleGroupRuleList::DeferredStyleGroupRuleList(const CSSParserTokenRange& range, CSSDeferredParser& parser)
328 size_t length = range.end() - range.begin();
329 m_tokens.reserveCapacity(length);
330 m_tokens.append(range.begin(), length);
333 void DeferredStyleGroupRuleList::parseDeferredRules(Vector<RefPtr<StyleRuleBase>>& childRules)
335 m_parser->parseRuleList(m_tokens, childRules);
338 void DeferredStyleGroupRuleList::parseDeferredKeyframes(StyleRuleKeyframes& keyframesRule)
340 m_parser->parseKeyframeList(m_tokens, keyframesRule);
343 StyleRuleGroup::StyleRuleGroup(Type type, Vector<RefPtr<StyleRuleBase>>& adoptRule)
344 : StyleRuleBase(type)
346 m_childRules.swap(adoptRule);
349 StyleRuleGroup::StyleRuleGroup(Type type, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredRules)
350 : StyleRuleBase(type)
351 , m_deferredRules(WTFMove(deferredRules))
355 StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& o)
358 m_childRules.reserveInitialCapacity(o.childRules().size());
359 for (auto& childRule : o.childRules())
360 m_childRules.uncheckedAppend(childRule->copy());
363 const Vector<RefPtr<StyleRuleBase>>& StyleRuleGroup::childRules() const
365 parseDeferredRulesIfNeeded();
369 void StyleRuleGroup::wrapperInsertRule(unsigned index, Ref<StyleRuleBase>&& rule)
371 parseDeferredRulesIfNeeded();
372 m_childRules.insert(index, WTFMove(rule));
375 void StyleRuleGroup::wrapperRemoveRule(unsigned index)
377 parseDeferredRulesIfNeeded();
378 m_childRules.remove(index);
381 void StyleRuleGroup::parseDeferredRulesIfNeeded() const
383 if (!m_deferredRules)
386 m_deferredRules->parseDeferredRules(m_childRules);
387 m_deferredRules = nullptr;
390 StyleRuleMedia::StyleRuleMedia(Ref<MediaQuerySet>&& media, Vector<RefPtr<StyleRuleBase>>& adoptRules)
391 : StyleRuleGroup(Media, adoptRules)
392 , m_mediaQueries(WTFMove(media))
396 StyleRuleMedia::StyleRuleMedia(Ref<MediaQuerySet>&& media, std::unique_ptr<DeferredStyleGroupRuleList>&& deferredRules)
397 : StyleRuleGroup(Media, WTFMove(deferredRules))
398 , m_mediaQueries(WTFMove(media))
402 StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o)
405 if (o.m_mediaQueries)
406 m_mediaQueries = o.m_mediaQueries->copy();
410 StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>& adoptRules)
411 : StyleRuleGroup(Supports, adoptRules)
412 , m_conditionText(conditionText)
413 , m_conditionIsSupported(conditionIsSupported)
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)
424 StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& o)
426 , m_conditionText(o.m_conditionText)
427 , m_conditionIsSupported(o.m_conditionIsSupported)
431 StyleRuleRegion::StyleRuleRegion(Vector<std::unique_ptr<CSSParserSelector>>* selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
432 : StyleRuleGroup(Region, adoptRules)
434 m_selectorList.adoptSelectorVector(*selectors);
437 StyleRuleRegion::StyleRuleRegion(CSSSelectorList& selectors, Vector<RefPtr<StyleRuleBase>>& adoptRules)
438 : StyleRuleGroup(Region, adoptRules)
439 , m_selectorList(WTFMove(selectors))
443 StyleRuleRegion::StyleRuleRegion(const StyleRuleRegion& o)
445 , m_selectorList(o.m_selectorList)
450 #if ENABLE(CSS_DEVICE_ADAPTATION)
451 StyleRuleViewport::StyleRuleViewport(Ref<StyleProperties>&& properties)
452 : StyleRuleBase(Viewport, 0)
453 , m_properties(WTFMove(properties))
457 StyleRuleViewport::StyleRuleViewport(const StyleRuleViewport& o)
459 , m_properties(o.m_properties->mutableCopy())
463 StyleRuleViewport::~StyleRuleViewport()
467 MutableStyleProperties& StyleRuleViewport::mutableProperties()
469 if (!m_properties->isMutable())
470 m_properties = m_properties->mutableCopy();
471 return static_cast<MutableStyleProperties&>(m_properties.get());
473 #endif // ENABLE(CSS_DEVICE_ADAPTATION)
475 StyleRuleCharset::StyleRuleCharset()
476 : StyleRuleBase(Charset)
480 StyleRuleCharset::StyleRuleCharset(const StyleRuleCharset& o)
485 StyleRuleCharset::~StyleRuleCharset()
489 StyleRuleNamespace::StyleRuleNamespace(AtomicString prefix, AtomicString uri)
490 : StyleRuleBase(Namespace)
496 StyleRuleNamespace::StyleRuleNamespace(const StyleRuleNamespace& o)
498 , m_prefix(o.m_prefix)
503 StyleRuleNamespace::~StyleRuleNamespace()
507 } // namespace WebCore