blob: 44ac62ba5db3b87df3b0ab5a71b136d219a86d76 [file] [log] [blame]
morrita@google.com3b321b52012-10-05 06:15:20 +00001/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
4 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
benjamin@webkit.org44b54972014-07-12 05:08:33 +00005 * Copyright (C) 2005-2014 Apple Inc. All rights reserved.
morrita@google.com3b321b52012-10-05 06:15:20 +00006 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
8 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
9 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
10 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
11 * Copyright (C) 2012 Google Inc. All rights reserved.
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Library General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Library General Public License for more details.
22 *
23 * You should have received a copy of the GNU Library General Public License
24 * along with this library; see the file COPYING.LIB. If not, write to
25 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26 * Boston, MA 02110-1301, USA.
27 */
28
29#include "config.h"
30#include "RuleSet.h"
31
32#include "CSSFontSelector.h"
dino@apple.comd2a5e4c2014-11-15 23:02:43 +000033#include "CSSKeyframesRule.h"
morrita@google.com3b321b52012-10-05 06:15:20 +000034#include "CSSSelector.h"
35#include "CSSSelectorList.h"
36#include "HTMLNames.h"
37#include "MediaQueryEvaluator.h"
38#include "SecurityOrigin.h"
39#include "SelectorChecker.h"
dglazkov@chromium.org4e8caa32012-12-24 05:05:13 +000040#include "SelectorFilter.h"
morrita@google.com3b321b52012-10-05 06:15:20 +000041#include "StyleResolver.h"
42#include "StyleRule.h"
43#include "StyleRuleImport.h"
44#include "StyleSheetContents.h"
achristensen@apple.comef05c0f2016-05-18 23:09:09 +000045#include "ViewportStyleResolver.h"
morrita@google.com3b321b52012-10-05 06:15:20 +000046
commit-queue@webkit.org0bcebbe2013-01-23 05:50:15 +000047#if ENABLE(VIDEO_TRACK)
48#include "TextTrackCue.h"
49#endif
50
morrita@google.com3b321b52012-10-05 06:15:20 +000051namespace WebCore {
52
53using namespace HTMLNames;
54
55// -----------------------------------------------------------------
56
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +000057static inline MatchBasedOnRuleHash computeMatchBasedOnRuleHash(const CSSSelector& selector)
morrita@google.com3b321b52012-10-05 06:15:20 +000058{
benjamin@webkit.org44b54972014-07-12 05:08:33 +000059 if (selector.tagHistory())
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +000060 return MatchBasedOnRuleHash::None;
benjamin@webkit.org44b54972014-07-12 05:08:33 +000061
cdumez@apple.com58aa8692014-09-12 19:24:12 +000062 if (selector.match() == CSSSelector::Tag) {
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +000063 const QualifiedName& tagQualifiedName = selector.tagQName();
64 const AtomicString& selectorNamespace = tagQualifiedName.namespaceURI();
65 if (selectorNamespace == starAtom || selectorNamespace == xhtmlNamespaceURI) {
66 if (tagQualifiedName == anyQName())
67 return MatchBasedOnRuleHash::Universal;
68 return MatchBasedOnRuleHash::ClassC;
69 }
70 return MatchBasedOnRuleHash::None;
akling@apple.com48d56042013-01-22 00:45:14 +000071 }
benjamin@webkit.org44b54972014-07-12 05:08:33 +000072 if (SelectorChecker::isCommonPseudoClassSelector(&selector))
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +000073 return MatchBasedOnRuleHash::ClassB;
74 if (selector.match() == CSSSelector::Id)
75 return MatchBasedOnRuleHash::ClassA;
76 if (selector.match() == CSSSelector::Class)
77 return MatchBasedOnRuleHash::ClassB;
78 return MatchBasedOnRuleHash::None;
morrita@google.com3b321b52012-10-05 06:15:20 +000079}
80
benjamin@webkit.org6e590eb2014-07-13 21:51:16 +000081static bool selectorCanMatchPseudoElement(const CSSSelector& rootSelector)
82{
83 const CSSSelector* selector = &rootSelector;
84 do {
85 if (selector->matchesPseudoElement())
86 return true;
87
88 if (const CSSSelectorList* selectorList = selector->selectorList()) {
89 for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
90 if (selectorCanMatchPseudoElement(*subSelector))
91 return true;
92 }
93 }
94
95 selector = selector->tagHistory();
96 } while (selector);
97 return false;
98}
99
morrita@google.com3b321b52012-10-05 06:15:20 +0000100static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attribute)
101{
102 // These are explicitly tested for equality in canShareStyleWithElement.
103 return attribute == typeAttr || attribute == readonlyAttr;
104}
105
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000106static bool containsUncommonAttributeSelector(const CSSSelector& rootSelector, bool matchesRightmostElement)
morrita@google.com3b321b52012-10-05 06:15:20 +0000107{
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000108 const CSSSelector* selector = &rootSelector;
109 do {
110 if (selector->isAttributeSelector()) {
111 // FIXME: considering non-rightmost simple selectors is necessary because of the style sharing of cousins.
112 // It is a primitive solution which disable a lot of style sharing on pages that rely on attributes for styling.
113 // We should investigate better ways of doing this.
114 if (!isCommonAttributeSelectorAttribute(selector->attribute()) || !matchesRightmostElement)
115 return true;
morrita@google.com3b321b52012-10-05 06:15:20 +0000116 }
morrita@google.com3b321b52012-10-05 06:15:20 +0000117
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000118 if (const CSSSelectorList* selectorList = selector->selectorList()) {
119 for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
120 if (containsUncommonAttributeSelector(*subSelector, matchesRightmostElement))
121 return true;
122 }
123 }
124
125 if (selector->relation() != CSSSelector::SubSelector)
126 matchesRightmostElement = false;
127
128 selector = selector->tagHistory();
129 } while (selector);
morrita@google.com3b321b52012-10-05 06:15:20 +0000130 return false;
131}
132
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000133static inline bool containsUncommonAttributeSelector(const CSSSelector& rootSelector)
134{
135 return containsUncommonAttributeSelector(rootSelector, true);
136}
137
commit-queue@webkit.org085528c2013-01-18 18:22:46 +0000138static inline PropertyWhitelistType determinePropertyWhitelistType(const AddRuleFlags addRuleFlags, const CSSSelector* selector)
139{
140 if (addRuleFlags & RuleIsInRegionRule)
141 return PropertyWhitelistRegion;
142#if ENABLE(VIDEO_TRACK)
akling@apple.com48d56042013-01-22 00:45:14 +0000143 for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
cdumez@apple.com58aa8692014-09-12 19:24:12 +0000144 if (component->match() == CSSSelector::PseudoElement && (component->pseudoElementType() == CSSSelector::PseudoElementCue || component->value() == TextTrackCue::cueShadowPseudoId()))
akling@apple.com48d56042013-01-22 00:45:14 +0000145 return PropertyWhitelistCue;
146 }
commit-queue@webkit.org0bcebbe2013-01-23 05:50:15 +0000147#else
148 UNUSED_PARAM(selector);
commit-queue@webkit.org085528c2013-01-18 18:22:46 +0000149#endif
150 return PropertyWhitelistNone;
151}
152
tasak@google.com4a7bee52012-10-26 11:33:22 +0000153RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, AddRuleFlags addRuleFlags)
morrita@google.com3b321b52012-10-05 06:15:20 +0000154 : m_rule(rule)
155 , m_selectorIndex(selectorIndex)
benjamin@webkit.org6e590eb2014-07-13 21:51:16 +0000156 , m_hasDocumentSecurityOrigin(addRuleFlags & RuleHasDocumentSecurityOrigin)
morrita@google.com3b321b52012-10-05 06:15:20 +0000157 , m_position(position)
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +0000158 , m_matchBasedOnRuleHash(static_cast<unsigned>(computeMatchBasedOnRuleHash(*selector())))
benjamin@webkit.org6e590eb2014-07-13 21:51:16 +0000159 , m_canMatchPseudoElement(selectorCanMatchPseudoElement(*selector()))
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000160 , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(*selector()))
morrita@google.com3b321b52012-10-05 06:15:20 +0000161 , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
commit-queue@webkit.org085528c2013-01-18 18:22:46 +0000162 , m_propertyWhitelistType(determinePropertyWhitelistType(addRuleFlags, selector()))
achristensen@apple.com6cfd7e62014-07-09 17:49:59 +0000163#if ENABLE(CSS_SELECTOR_JIT) && CSS_SELECTOR_JIT_PROFILING
164 , m_compiledSelectorUseCount(0)
165#endif
morrita@google.com3b321b52012-10-05 06:15:20 +0000166{
167 ASSERT(m_position == position);
168 ASSERT(m_selectorIndex == selectorIndex);
dglazkov@chromium.org4e8caa32012-12-24 05:05:13 +0000169 SelectorFilter::collectIdentifierHashes(selector(), m_descendantSelectorIdentifierHashes, maximumIdentifierCount);
morrita@google.com3b321b52012-10-05 06:15:20 +0000170}
171
antti@apple.com03d89392016-02-10 20:47:04 +0000172RuleSet::RuleSet()
morrita@google.com3b321b52012-10-05 06:15:20 +0000173{
antti@apple.com03d89392016-02-10 20:47:04 +0000174}
benjamin@webkit.org8a05e822014-10-22 03:28:29 +0000175
antti@apple.com03d89392016-02-10 20:47:04 +0000176RuleSet::~RuleSet()
177{
morrita@google.com3b321b52012-10-05 06:15:20 +0000178}
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000179
morrita@google.com3b321b52012-10-05 06:15:20 +0000180void RuleSet::addToRuleSet(AtomicStringImpl* key, AtomRuleMap& map, const RuleData& ruleData)
181{
182 if (!key)
183 return;
akling@apple.comd6d61af22015-01-16 17:50:14 +0000184 auto& rules = map.add(key, nullptr).iterator->value;
morrita@google.com3b321b52012-10-05 06:15:20 +0000185 if (!rules)
cdumez@apple.comc7a0f032016-01-19 20:59:56 +0000186 rules = std::make_unique<RuleDataVector>();
morrita@google.com3b321b52012-10-05 06:15:20 +0000187 rules->append(ruleData);
188}
189
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000190static unsigned rulesCountForName(const RuleSet::AtomRuleMap& map, AtomicStringImpl* name)
morrita@google.com3b321b52012-10-05 06:15:20 +0000191{
akling@apple.comd6d61af22015-01-16 17:50:14 +0000192 if (const auto* rules = map.get(name))
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000193 return rules->size();
194 return 0;
akling@apple.com48d56042013-01-22 00:45:14 +0000195}
196
197void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addRuleFlags)
198{
199 RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags);
antti@apple.com03d89392016-02-10 20:47:04 +0000200 m_features.collectFeatures(ruleData);
akling@apple.com48d56042013-01-22 00:45:14 +0000201
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000202 unsigned classBucketSize = 0;
203 const CSSSelector* tagSelector = nullptr;
204 const CSSSelector* classSelector = nullptr;
205 const CSSSelector* linkSelector = nullptr;
206 const CSSSelector* focusSelector = nullptr;
207 const CSSSelector* selector = ruleData.selector();
208 do {
cdumez@apple.com58aa8692014-09-12 19:24:12 +0000209 if (selector->match() == CSSSelector::Id) {
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000210 addToRuleSet(selector->value().impl(), m_idRules, ruleData);
211 return;
212 }
213
214#if ENABLE(VIDEO_TRACK)
cdumez@apple.com58aa8692014-09-12 19:24:12 +0000215 if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementCue) {
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000216 m_cuePseudoRules.append(ruleData);
217 return;
218 }
219#endif
220
221 if (selector->isCustomPseudoElement()) {
antti@apple.comab38f882016-01-08 09:06:10 +0000222 // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
223 ruleData.disableSelectorFiltering();
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000224 addToRuleSet(selector->value().impl(), m_shadowPseudoElementRules, ruleData);
225 return;
226 }
227
cdumez@apple.com58aa8692014-09-12 19:24:12 +0000228 if (selector->match() == CSSSelector::Class) {
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000229 AtomicStringImpl* className = selector->value().impl();
230 if (!classSelector) {
231 classSelector = selector;
232 classBucketSize = rulesCountForName(m_classRules, className);
233 } else if (classBucketSize) {
234 unsigned newClassBucketSize = rulesCountForName(m_classRules, className);
235 if (newClassBucketSize < classBucketSize) {
236 classSelector = selector;
237 classBucketSize = newClassBucketSize;
238 }
239 }
240 }
241
cdumez@apple.com58aa8692014-09-12 19:24:12 +0000242 if (selector->match() == CSSSelector::Tag && selector->tagQName().localName() != starAtom)
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000243 tagSelector = selector;
244
245 if (SelectorChecker::isCommonPseudoClassSelector(selector)) {
246 switch (selector->pseudoClassType()) {
247 case CSSSelector::PseudoClassLink:
248 case CSSSelector::PseudoClassVisited:
249 case CSSSelector::PseudoClassAnyLink:
benjamin@webkit.org061761a2014-10-29 04:21:21 +0000250 case CSSSelector::PseudoClassAnyLinkDeprecated:
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000251 linkSelector = selector;
252 break;
253 case CSSSelector::PseudoClassFocus:
254 focusSelector = selector;
255 break;
256 default:
257 ASSERT_NOT_REACHED();
258 }
259 }
260
antti@apple.com6d9e2412015-10-07 19:59:32 +0000261#if ENABLE(SHADOW_DOM)
262 if (selector->match() == CSSSelector::PseudoClass && selector->pseudoClassType() == CSSSelector::PseudoClassHost) {
263 m_hostPseudoClassRules.append(ruleData);
264 return;
265 }
antti@apple.com8c4fa4e2016-02-26 14:57:01 +0000266 if (selector->match() == CSSSelector::PseudoElement && selector->pseudoElementType() == CSSSelector::PseudoElementSlotted) {
267 // ::slotted pseudo elements work accross shadow boundary making filtering difficult.
268 ruleData.disableSelectorFiltering();
269 m_slottedPseudoElementRules.append(ruleData);
270 return;
271 }
antti@apple.com6d9e2412015-10-07 19:59:32 +0000272#endif
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000273 if (selector->relation() != CSSSelector::SubSelector)
274 break;
275 selector = selector->tagHistory();
276 } while (selector);
277
278 if (classSelector) {
279 addToRuleSet(classSelector->value().impl(), m_classRules, ruleData);
280 return;
akling@apple.com48d56042013-01-22 00:45:14 +0000281 }
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000282
283 if (linkSelector) {
284 m_linkPseudoClassRules.append(ruleData);
285 return;
286 }
287
288 if (focusSelector) {
289 m_focusPseudoClassRules.append(ruleData);
290 return;
291 }
292
293 if (tagSelector) {
benjamin@webkit.orgd58a1a72015-01-26 20:40:18 +0000294 addToRuleSet(tagSelector->tagQName().localName().impl(), m_tagLocalNameRules, ruleData);
295 addToRuleSet(tagSelector->tagLowercaseLocalName().impl(), m_tagLowercaseLocalNameRules, ruleData);
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000296 return;
297 }
298
299 // If we didn't find a specialized map to stick it in, file under universal rules.
300 m_universalRules.append(ruleData);
morrita@google.com3b321b52012-10-05 06:15:20 +0000301}
302
303void RuleSet::addPageRule(StyleRulePage* rule)
304{
305 m_pageRules.append(rule);
306}
307
308void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin)
309{
zandobersek@gmail.comfca12762014-02-04 15:57:23 +0000310 auto regionRuleSet = std::make_unique<RuleSet>();
morrita@google.com3b321b52012-10-05 06:15:20 +0000311 // The region rule set should take into account the position inside the parent rule set.
312 // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from
313 // the stylesheet that contains the region block.
314 regionRuleSet->m_ruleCount = m_ruleCount;
315
316 // Collect the region rules into a rule set
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000317 // FIXME: Should this add other types of rules? (i.e. use addChildRules() directly?)
andersca@apple.comc3523f82013-10-18 23:41:24 +0000318 const Vector<RefPtr<StyleRuleBase>>& childRules = regionRule->childRules();
tasak@google.com4a7bee52012-10-26 11:33:22 +0000319 AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
benjamin@webkit.org6e590eb2014-07-13 21:51:16 +0000320 addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleIsInRegionRule);
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000321 for (auto& childRule : childRules) {
322 if (is<StyleRule>(*childRule))
323 regionRuleSet->addStyleRule(downcast<StyleRule>(childRule.get()), addRuleFlags);
morrita@google.com3b321b52012-10-05 06:15:20 +0000324 }
325 // Update the "global" rule count so that proper order is maintained
326 m_ruleCount = regionRuleSet->m_ruleCount;
327
aestes@apple.com13aae082016-01-02 08:03:08 +0000328 m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), WTFMove(regionRuleSet)));
morrita@google.com3b321b52012-10-05 06:15:20 +0000329}
330
dbates@webkit.org264add72015-07-07 00:42:50 +0000331void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, bool hasDocumentSecurityOrigin, bool isInitiatingElementInUserAgentShadowTree, AddRuleFlags addRuleFlags)
morrita@google.com3b321b52012-10-05 06:15:20 +0000332{
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000333 for (auto& rule : rules) {
334 if (is<StyleRule>(*rule))
335 addStyleRule(downcast<StyleRule>(rule.get()), addRuleFlags);
336 else if (is<StyleRulePage>(*rule))
337 addPageRule(downcast<StyleRulePage>(rule.get()));
338 else if (is<StyleRuleMedia>(*rule)) {
339 auto& mediaRule = downcast<StyleRuleMedia>(*rule);
darin@apple.com9eaaf9f2016-05-27 00:05:24 +0000340 if ((!mediaRule.mediaQueries() || medium.evaluate(*mediaRule.mediaQueries(), resolver)))
dbates@webkit.org264add72015-07-07 00:42:50 +0000341 addChildRules(mediaRule.childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags);
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000342 } else if (is<StyleRuleFontFace>(*rule) && resolver) {
morrita@google.com3b321b52012-10-05 06:15:20 +0000343 // Add this font face to our set.
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000344 resolver->document().fontSelector().addFontFaceRule(downcast<StyleRuleFontFace>(*rule.get()), isInitiatingElementInUserAgentShadowTree);
morrita@google.com3b321b52012-10-05 06:15:20 +0000345 resolver->invalidateMatchedPropertiesCache();
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000346 } else if (is<StyleRuleKeyframes>(*rule) && resolver)
cdumez@apple.comdf0d6f52016-05-23 17:40:36 +0000347 resolver->addKeyframeStyle(downcast<StyleRuleKeyframes>(*rule));
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000348 else if (is<StyleRuleSupports>(*rule) && downcast<StyleRuleSupports>(*rule).conditionIsSupported())
dbates@webkit.org264add72015-07-07 00:42:50 +0000349 addChildRules(downcast<StyleRuleSupports>(*rule).childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags);
morrita@google.com3b321b52012-10-05 06:15:20 +0000350#if ENABLE(CSS_REGIONS)
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000351 else if (is<StyleRuleRegion>(*rule) && resolver) {
352 addRegionRule(downcast<StyleRuleRegion>(rule.get()), hasDocumentSecurityOrigin);
morrita@google.com3b321b52012-10-05 06:15:20 +0000353 }
354#endif
commit-queue@webkit.orgdaa81a42012-11-19 16:37:01 +0000355#if ENABLE(CSS_DEVICE_ADAPTATION)
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000356 else if (is<StyleRuleViewport>(*rule) && resolver) {
357 resolver->viewportStyleResolver()->addViewportRule(downcast<StyleRuleViewport>(rule.get()));
commit-queue@webkit.orgdaa81a42012-11-19 16:37:01 +0000358 }
359#endif
morrita@google.com3b321b52012-10-05 06:15:20 +0000360 }
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000361}
362
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000363void RuleSet::addRulesFromSheet(StyleSheetContents& sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver)
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000364{
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000365 for (auto& rule : sheet.importRules()) {
darin@apple.com9eaaf9f2016-05-27 00:05:24 +0000366 if (rule->styleSheet() && (!rule->mediaQueries() || medium.evaluate(*rule->mediaQueries(), resolver)))
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000367 addRulesFromSheet(*rule->styleSheet(), medium, resolver);
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000368 }
369
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000370 bool hasDocumentSecurityOrigin = resolver && resolver->document().securityOrigin()->canRequest(sheet.baseURL());
benjamin@webkit.org6e590eb2014-07-13 21:51:16 +0000371 AddRuleFlags addRuleFlags = static_cast<AddRuleFlags>((hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : 0));
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000372
dbates@webkit.org264add72015-07-07 00:42:50 +0000373 // FIXME: Skip Content Security Policy check when stylesheet is in a user agent shadow tree.
374 // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
375 bool isInitiatingElementInUserAgentShadowTree = false;
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000376 addChildRules(sheet.childRules(), medium, resolver, hasDocumentSecurityOrigin, isInitiatingElementInUserAgentShadowTree, addRuleFlags);
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000377
morrita@google.com3b321b52012-10-05 06:15:20 +0000378 if (m_autoShrinkToFitEnabled)
379 shrinkToFit();
380}
381
tasak@google.com4a7bee52012-10-26 11:33:22 +0000382void RuleSet::addStyleRule(StyleRule* rule, AddRuleFlags addRuleFlags)
morrita@google.com3b321b52012-10-05 06:15:20 +0000383{
384 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = rule->selectorList().indexOfNextSelectorAfter(selectorIndex))
tasak@google.com4a7bee52012-10-26 11:33:22 +0000385 addRule(rule, selectorIndex, addRuleFlags);
morrita@google.com3b321b52012-10-05 06:15:20 +0000386}
387
antti@apple.com0ffd7132015-09-30 15:39:15 +0000388bool RuleSet::hasShadowPseudoElementRules() const
389{
390 if (!m_shadowPseudoElementRules.isEmpty())
391 return true;
392#if ENABLE(VIDEO_TRACK)
393 if (!m_cuePseudoRules.isEmpty())
394 return true;
395#endif
396 return false;
397}
398
399void RuleSet::copyShadowPseudoElementRulesFrom(const RuleSet& other)
400{
401 for (auto& keyValuePair : other.m_shadowPseudoElementRules)
cdumez@apple.comc7a0f032016-01-19 20:59:56 +0000402 m_shadowPseudoElementRules.add(keyValuePair.key, std::make_unique<RuleDataVector>(*keyValuePair.value));
antti@apple.com0ffd7132015-09-30 15:39:15 +0000403
404#if ENABLE(VIDEO_TRACK)
405 // FIXME: We probably shouldn't treat WebVTT as author stylable user agent shadow tree.
406 for (auto& cue : other.m_cuePseudoRules)
407 m_cuePseudoRules.append(cue);
408#endif
409}
410
morrita@google.com3b321b52012-10-05 06:15:20 +0000411static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
412{
akling@apple.comd6d61af22015-01-16 17:50:14 +0000413 for (auto& vector : map.values())
414 vector->shrinkToFit();
morrita@google.com3b321b52012-10-05 06:15:20 +0000415}
416
417void RuleSet::shrinkToFit()
418{
419 shrinkMapVectorsToFit(m_idRules);
420 shrinkMapVectorsToFit(m_classRules);
benjamin@webkit.orgd58a1a72015-01-26 20:40:18 +0000421 shrinkMapVectorsToFit(m_tagLocalNameRules);
422 shrinkMapVectorsToFit(m_tagLowercaseLocalNameRules);
morrita@google.com3b321b52012-10-05 06:15:20 +0000423 shrinkMapVectorsToFit(m_shadowPseudoElementRules);
424 m_linkPseudoClassRules.shrinkToFit();
commit-queue@webkit.org7db073d2012-12-18 00:01:39 +0000425#if ENABLE(VIDEO_TRACK)
426 m_cuePseudoRules.shrinkToFit();
427#endif
antti@apple.com8c4fa4e2016-02-26 14:57:01 +0000428#if ENABLE(SHADOW_DOM)
429 m_hostPseudoClassRules.shrinkToFit();
430 m_slottedPseudoElementRules.shrinkToFit();
431#endif
morrita@google.com3b321b52012-10-05 06:15:20 +0000432 m_focusPseudoClassRules.shrinkToFit();
433 m_universalRules.shrinkToFit();
434 m_pageRules.shrinkToFit();
akling@apple.comd6d61af22015-01-16 17:50:14 +0000435 m_features.shrinkToFit();
436 m_regionSelectorsAndRuleSets.shrinkToFit();
morrita@google.com3b321b52012-10-05 06:15:20 +0000437}
438
439} // namespace WebCore