blob: dcd0e0de1b3d115f85d94f4a1aef08998e65f6d1 [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();
darin@apple.com0ce67df2019-06-17 01:48:13 +000064 const AtomString& selectorNamespace = tagQualifiedName.namespaceURI();
utatane.tea@gmail.comc4579a02017-07-07 04:42:04 +000065 if (selectorNamespace == starAtom() || selectorNamespace == xhtmlNamespaceURI) {
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +000066 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
hyatt@apple.com32585f12016-10-19 15:07:19 +0000125 if (selector->relation() != CSSSelector::Subselector)
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000126 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
antti@apple.com52d83832017-09-20 12:58:45 +0000138static inline PropertyWhitelistType determinePropertyWhitelistType(const CSSSelector* selector)
commit-queue@webkit.org085528c2013-01-18 18:22:46 +0000139{
akling@apple.com48d56042013-01-22 00:45:14 +0000140 for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
dbates@webkit.orgc50097a2017-08-03 16:16:50 +0000141#if ENABLE(VIDEO_TRACK)
cdumez@apple.com58aa8692014-09-12 19:24:12 +0000142 if (component->match() == CSSSelector::PseudoElement && (component->pseudoElementType() == CSSSelector::PseudoElementCue || component->value() == TextTrackCue::cueShadowPseudoId()))
akling@apple.com48d56042013-01-22 00:45:14 +0000143 return PropertyWhitelistCue;
commit-queue@webkit.org085528c2013-01-18 18:22:46 +0000144#endif
dbates@webkit.orgc50097a2017-08-03 16:16:50 +0000145 if (component->match() == CSSSelector::PseudoElement && component->pseudoElementType() == CSSSelector::PseudoElementMarker)
146 return PropertyWhitelistMarker;
antti@apple.com617731f2019-05-23 00:43:09 +0000147
148 if (const auto* selectorList = selector->selectorList()) {
149 for (const auto* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
150 auto whitelistType = determinePropertyWhitelistType(subSelector);
151 if (whitelistType != PropertyWhitelistNone)
152 return whitelistType;
153 }
154 }
dbates@webkit.orgc50097a2017-08-03 16:16:50 +0000155 }
commit-queue@webkit.org085528c2013-01-18 18:22:46 +0000156 return PropertyWhitelistNone;
157}
158
antti@apple.com25390a22018-02-09 09:11:05 +0000159RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned position)
morrita@google.com3b321b52012-10-05 06:15:20 +0000160 : m_rule(rule)
161 , m_selectorIndex(selectorIndex)
antti@apple.com25390a22018-02-09 09:11:05 +0000162 , m_selectorListIndex(selectorListIndex)
morrita@google.com3b321b52012-10-05 06:15:20 +0000163 , m_position(position)
benjamin@webkit.orgb2b7d542014-11-08 02:05:36 +0000164 , m_matchBasedOnRuleHash(static_cast<unsigned>(computeMatchBasedOnRuleHash(*selector())))
benjamin@webkit.org6e590eb2014-07-13 21:51:16 +0000165 , m_canMatchPseudoElement(selectorCanMatchPseudoElement(*selector()))
benjamin@webkit.org5d0143f2014-12-05 20:58:08 +0000166 , m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(*selector()))
morrita@google.com3b321b52012-10-05 06:15:20 +0000167 , m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
antti@apple.com52d83832017-09-20 12:58:45 +0000168 , m_propertyWhitelistType(determinePropertyWhitelistType(selector()))
antti@apple.come6f718e2017-12-06 22:24:06 +0000169 , m_descendantSelectorIdentifierHashes(SelectorFilter::collectHashes(*selector()))
morrita@google.com3b321b52012-10-05 06:15:20 +0000170{
171 ASSERT(m_position == position);
172 ASSERT(m_selectorIndex == selectorIndex);
morrita@google.com3b321b52012-10-05 06:15:20 +0000173}
174
dbates@webkit.orgf21f3ae2017-10-19 23:48:45 +0000175RuleSet::RuleSet() = default;
benjamin@webkit.org8a05e822014-10-22 03:28:29 +0000176
dbates@webkit.orgf21f3ae2017-10-19 23:48:45 +0000177RuleSet::~RuleSet() = default;
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000178
darin@apple.com0ce67df2019-06-17 01:48:13 +0000179void RuleSet::addToRuleSet(const AtomString& key, AtomRuleMap& map, const RuleData& ruleData)
morrita@google.com3b321b52012-10-05 06:15:20 +0000180{
antti@apple.com420029c2017-03-22 17:19:28 +0000181 if (key.isNull())
morrita@google.com3b321b52012-10-05 06:15:20 +0000182 return;
akling@apple.comd6d61af22015-01-16 17:50:14 +0000183 auto& rules = map.add(key, nullptr).iterator->value;
morrita@google.com3b321b52012-10-05 06:15:20 +0000184 if (!rules)
ysuzuki@apple.com1d8e24d2019-08-19 06:59:40 +0000185 rules = makeUnique<RuleDataVector>();
morrita@google.com3b321b52012-10-05 06:15:20 +0000186 rules->append(ruleData);
187}
188
darin@apple.com0ce67df2019-06-17 01:48:13 +0000189static unsigned rulesCountForName(const RuleSet::AtomRuleMap& map, const AtomString& name)
morrita@google.com3b321b52012-10-05 06:15:20 +0000190{
akling@apple.comd6d61af22015-01-16 17:50:14 +0000191 if (const auto* rules = map.get(name))
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000192 return rules->size();
193 return 0;
akling@apple.com48d56042013-01-22 00:45:14 +0000194}
195
antti@apple.com6cdaf372017-05-12 12:31:49 +0000196static bool isHostSelectorMatchingInShadowTree(const CSSSelector& startSelector)
197{
198 auto* leftmostSelector = &startSelector;
199 bool hasDescendantOrChildRelation = false;
200 while (auto* previous = leftmostSelector->tagHistory()) {
201 hasDescendantOrChildRelation = leftmostSelector->hasDescendantOrChildRelation();
202 leftmostSelector = previous;
203 }
204 if (!hasDescendantOrChildRelation)
205 return false;
206
207 return leftmostSelector->match() == CSSSelector::PseudoClass && leftmostSelector->pseudoClassType() == CSSSelector::PseudoClassHost;
208}
209
antti@apple.com25390a22018-02-09 09:11:05 +0000210void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, unsigned selectorListIndex)
akling@apple.com48d56042013-01-22 00:45:14 +0000211{
antti@apple.com25390a22018-02-09 09:11:05 +0000212 RuleData ruleData(rule, selectorIndex, selectorListIndex, m_ruleCount++);
antti@apple.com03d89392016-02-10 20:47:04 +0000213 m_features.collectFeatures(ruleData);
akling@apple.com48d56042013-01-22 00:45:14 +0000214
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000215 unsigned classBucketSize = 0;
antti@apple.com857868c2016-11-04 18:32:45 +0000216 const CSSSelector* idSelector = nullptr;
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000217 const CSSSelector* tagSelector = nullptr;
218 const CSSSelector* classSelector = nullptr;
219 const CSSSelector* linkSelector = nullptr;
220 const CSSSelector* focusSelector = nullptr;
antti@apple.coma86f3282016-12-08 14:05:27 +0000221 const CSSSelector* hostPseudoClassSelector = nullptr;
antti@apple.com857868c2016-11-04 18:32:45 +0000222 const CSSSelector* customPseudoElementSelector = nullptr;
223 const CSSSelector* slottedPseudoElementSelector = nullptr;
antti@apple.com89a09912019-10-02 21:15:52 +0000224 const CSSSelector* partPseudoElementSelector = nullptr;
ossy@webkit.org20904492016-11-14 15:39:27 +0000225#if ENABLE(VIDEO_TRACK)
antti@apple.com857868c2016-11-04 18:32:45 +0000226 const CSSSelector* cuePseudoElementSelector = nullptr;
ossy@webkit.org20904492016-11-14 15:39:27 +0000227#endif
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000228 const CSSSelector* selector = ruleData.selector();
229 do {
antti@apple.com857868c2016-11-04 18:32:45 +0000230 switch (selector->match()) {
231 case CSSSelector::Id:
232 idSelector = selector;
233 break;
234 case CSSSelector::Class: {
antti@apple.com420029c2017-03-22 17:19:28 +0000235 auto& className = selector->value();
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000236 if (!classSelector) {
237 classSelector = selector;
238 classBucketSize = rulesCountForName(m_classRules, className);
239 } else if (classBucketSize) {
240 unsigned newClassBucketSize = rulesCountForName(m_classRules, className);
241 if (newClassBucketSize < classBucketSize) {
242 classSelector = selector;
243 classBucketSize = newClassBucketSize;
244 }
245 }
antti@apple.com857868c2016-11-04 18:32:45 +0000246 break;
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000247 }
antti@apple.com857868c2016-11-04 18:32:45 +0000248 case CSSSelector::Tag:
utatane.tea@gmail.comc4579a02017-07-07 04:42:04 +0000249 if (selector->tagQName().localName() != starAtom())
antti@apple.com857868c2016-11-04 18:32:45 +0000250 tagSelector = selector;
251 break;
252 case CSSSelector::PseudoElement:
253 switch (selector->pseudoElementType()) {
antti@apple.com857868c2016-11-04 18:32:45 +0000254 case CSSSelector::PseudoElementWebKitCustom:
255 case CSSSelector::PseudoElementWebKitCustomLegacyPrefixed:
256 customPseudoElementSelector = selector;
257 break;
258 case CSSSelector::PseudoElementSlotted:
259 slottedPseudoElementSelector = selector;
260 break;
antti@apple.com89a09912019-10-02 21:15:52 +0000261 case CSSSelector::PseudoElementPart:
262 partPseudoElementSelector = selector;
263 break;
antti@apple.com857868c2016-11-04 18:32:45 +0000264#if ENABLE(VIDEO_TRACK)
265 case CSSSelector::PseudoElementCue:
266 cuePseudoElementSelector = selector;
267 break;
268#endif
269 default:
270 break;
271 }
272 break;
273 case CSSSelector::PseudoClass:
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000274 switch (selector->pseudoClassType()) {
275 case CSSSelector::PseudoClassLink:
276 case CSSSelector::PseudoClassVisited:
277 case CSSSelector::PseudoClassAnyLink:
benjamin@webkit.org061761a2014-10-29 04:21:21 +0000278 case CSSSelector::PseudoClassAnyLinkDeprecated:
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000279 linkSelector = selector;
280 break;
281 case CSSSelector::PseudoClassFocus:
282 focusSelector = selector;
283 break;
antti@apple.com857868c2016-11-04 18:32:45 +0000284 case CSSSelector::PseudoClassHost:
antti@apple.coma86f3282016-12-08 14:05:27 +0000285 hostPseudoClassSelector = selector;
286 break;
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000287 default:
antti@apple.com857868c2016-11-04 18:32:45 +0000288 break;
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000289 }
antti@apple.com857868c2016-11-04 18:32:45 +0000290 break;
291 case CSSSelector::Unknown:
292 case CSSSelector::Exact:
293 case CSSSelector::Set:
294 case CSSSelector::List:
295 case CSSSelector::Hyphen:
296 case CSSSelector::Contain:
297 case CSSSelector::Begin:
298 case CSSSelector::End:
299 case CSSSelector::PagePseudoClass:
300 break;
antti@apple.com8c4fa4e2016-02-26 14:57:01 +0000301 }
hyatt@apple.com32585f12016-10-19 15:07:19 +0000302 if (selector->relation() != CSSSelector::Subselector)
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000303 break;
304 selector = selector->tagHistory();
305 } while (selector);
306
ossy@webkit.org20904492016-11-14 15:39:27 +0000307#if ENABLE(VIDEO_TRACK)
antti@apple.com857868c2016-11-04 18:32:45 +0000308 if (cuePseudoElementSelector) {
309 m_cuePseudoRules.append(ruleData);
310 return;
311 }
ossy@webkit.org20904492016-11-14 15:39:27 +0000312#endif
antti@apple.com857868c2016-11-04 18:32:45 +0000313
314 if (slottedPseudoElementSelector) {
315 // ::slotted pseudo elements work accross shadow boundary making filtering difficult.
316 ruleData.disableSelectorFiltering();
317 m_slottedPseudoElementRules.append(ruleData);
318 return;
319 }
320
antti@apple.com89a09912019-10-02 21:15:52 +0000321 if (partPseudoElementSelector) {
322 // Filtering doesn't work accross shadow boundaries.
323 ruleData.disableSelectorFiltering();
324 m_partPseudoElementRules.append(ruleData);
325 return;
326 }
327
antti@apple.com857868c2016-11-04 18:32:45 +0000328 if (customPseudoElementSelector) {
329 // FIXME: Custom pseudo elements are handled by the shadow tree's selector filter. It doesn't know about the main DOM.
330 ruleData.disableSelectorFiltering();
antti@apple.com420029c2017-03-22 17:19:28 +0000331 addToRuleSet(customPseudoElementSelector->value(), m_shadowPseudoElementRules, ruleData);
antti@apple.com857868c2016-11-04 18:32:45 +0000332 return;
333 }
334
antti@apple.com6cdaf372017-05-12 12:31:49 +0000335 if (!m_hasHostPseudoClassRulesMatchingInShadowTree)
336 m_hasHostPseudoClassRulesMatchingInShadowTree = isHostSelectorMatchingInShadowTree(*ruleData.selector());
337
antti@apple.coma86f3282016-12-08 14:05:27 +0000338 if (hostPseudoClassSelector) {
339 m_hostPseudoClassRules.append(ruleData);
340 return;
341 }
342
antti@apple.com857868c2016-11-04 18:32:45 +0000343 if (idSelector) {
antti@apple.com420029c2017-03-22 17:19:28 +0000344 addToRuleSet(idSelector->value(), m_idRules, ruleData);
antti@apple.com857868c2016-11-04 18:32:45 +0000345 return;
346 }
347
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000348 if (classSelector) {
antti@apple.com420029c2017-03-22 17:19:28 +0000349 addToRuleSet(classSelector->value(), m_classRules, ruleData);
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000350 return;
akling@apple.com48d56042013-01-22 00:45:14 +0000351 }
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000352
353 if (linkSelector) {
354 m_linkPseudoClassRules.append(ruleData);
355 return;
356 }
357
358 if (focusSelector) {
359 m_focusPseudoClassRules.append(ruleData);
360 return;
361 }
362
363 if (tagSelector) {
antti@apple.com420029c2017-03-22 17:19:28 +0000364 addToRuleSet(tagSelector->tagQName().localName(), m_tagLocalNameRules, ruleData);
365 addToRuleSet(tagSelector->tagLowercaseLocalName(), m_tagLowercaseLocalNameRules, ruleData);
benjamin@webkit.org44b54972014-07-12 05:08:33 +0000366 return;
367 }
368
369 // If we didn't find a specialized map to stick it in, file under universal rules.
370 m_universalRules.append(ruleData);
morrita@google.com3b321b52012-10-05 06:15:20 +0000371}
372
373void RuleSet::addPageRule(StyleRulePage* rule)
374{
375 m_pageRules.append(rule);
376}
377
antti@apple.comc430d672017-12-07 23:58:39 +0000378void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules, const MediaQueryEvaluator& medium, StyleResolver* resolver, bool isInitiatingElementInUserAgentShadowTree)
morrita@google.com3b321b52012-10-05 06:15:20 +0000379{
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000380 for (auto& rule : rules) {
381 if (is<StyleRule>(*rule))
antti@apple.comc430d672017-12-07 23:58:39 +0000382 addStyleRule(downcast<StyleRule>(rule.get()));
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000383 else if (is<StyleRulePage>(*rule))
384 addPageRule(downcast<StyleRulePage>(rule.get()));
385 else if (is<StyleRuleMedia>(*rule)) {
386 auto& mediaRule = downcast<StyleRuleMedia>(*rule);
darin@apple.com9eaaf9f2016-05-27 00:05:24 +0000387 if ((!mediaRule.mediaQueries() || medium.evaluate(*mediaRule.mediaQueries(), resolver)))
antti@apple.comc430d672017-12-07 23:58:39 +0000388 addChildRules(mediaRule.childRules(), medium, resolver, isInitiatingElementInUserAgentShadowTree);
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000389 } else if (is<StyleRuleFontFace>(*rule) && resolver) {
morrita@google.com3b321b52012-10-05 06:15:20 +0000390 // Add this font face to our set.
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000391 resolver->document().fontSelector().addFontFaceRule(downcast<StyleRuleFontFace>(*rule.get()), isInitiatingElementInUserAgentShadowTree);
morrita@google.com3b321b52012-10-05 06:15:20 +0000392 resolver->invalidateMatchedPropertiesCache();
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000393 } else if (is<StyleRuleKeyframes>(*rule) && resolver)
cdumez@apple.comdf0d6f52016-05-23 17:40:36 +0000394 resolver->addKeyframeStyle(downcast<StyleRuleKeyframes>(*rule));
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000395 else if (is<StyleRuleSupports>(*rule) && downcast<StyleRuleSupports>(*rule).conditionIsSupported())
antti@apple.comc430d672017-12-07 23:58:39 +0000396 addChildRules(downcast<StyleRuleSupports>(*rule).childRules(), medium, resolver, isInitiatingElementInUserAgentShadowTree);
commit-queue@webkit.orgdaa81a42012-11-19 16:37:01 +0000397#if ENABLE(CSS_DEVICE_ADAPTATION)
cdumez@apple.com7687ecf2014-12-12 20:28:17 +0000398 else if (is<StyleRuleViewport>(*rule) && resolver) {
399 resolver->viewportStyleResolver()->addViewportRule(downcast<StyleRuleViewport>(rule.get()));
commit-queue@webkit.orgdaa81a42012-11-19 16:37:01 +0000400 }
401#endif
morrita@google.com3b321b52012-10-05 06:15:20 +0000402 }
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000403}
404
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000405void RuleSet::addRulesFromSheet(StyleSheetContents& sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver)
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000406{
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000407 for (auto& rule : sheet.importRules()) {
darin@apple.com9eaaf9f2016-05-27 00:05:24 +0000408 if (rule->styleSheet() && (!rule->mediaQueries() || medium.evaluate(*rule->mediaQueries(), resolver)))
mmaxfield@apple.com03357532015-11-02 00:52:46 +0000409 addRulesFromSheet(*rule->styleSheet(), medium, resolver);
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000410 }
411
dbates@webkit.org264add72015-07-07 00:42:50 +0000412 // FIXME: Skip Content Security Policy check when stylesheet is in a user agent shadow tree.
413 // See <https://bugs.webkit.org/show_bug.cgi?id=146663>.
414 bool isInitiatingElementInUserAgentShadowTree = false;
antti@apple.comc430d672017-12-07 23:58:39 +0000415 addChildRules(sheet.childRules(), medium, resolver, isInitiatingElementInUserAgentShadowTree);
commit-queue@webkit.org104b5ab2013-01-14 09:49:56 +0000416
morrita@google.com3b321b52012-10-05 06:15:20 +0000417 if (m_autoShrinkToFitEnabled)
418 shrinkToFit();
419}
420
antti@apple.comc430d672017-12-07 23:58:39 +0000421void RuleSet::addStyleRule(StyleRule* rule)
morrita@google.com3b321b52012-10-05 06:15:20 +0000422{
antti@apple.com25390a22018-02-09 09:11:05 +0000423 unsigned selectorListIndex = 0;
morrita@google.com3b321b52012-10-05 06:15:20 +0000424 for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = rule->selectorList().indexOfNextSelectorAfter(selectorIndex))
antti@apple.com25390a22018-02-09 09:11:05 +0000425 addRule(rule, selectorIndex, selectorListIndex++);
morrita@google.com3b321b52012-10-05 06:15:20 +0000426}
427
antti@apple.com0ffd7132015-09-30 15:39:15 +0000428bool RuleSet::hasShadowPseudoElementRules() const
429{
430 if (!m_shadowPseudoElementRules.isEmpty())
431 return true;
432#if ENABLE(VIDEO_TRACK)
433 if (!m_cuePseudoRules.isEmpty())
434 return true;
435#endif
436 return false;
437}
438
morrita@google.com3b321b52012-10-05 06:15:20 +0000439static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
440{
akling@apple.comd6d61af22015-01-16 17:50:14 +0000441 for (auto& vector : map.values())
442 vector->shrinkToFit();
morrita@google.com3b321b52012-10-05 06:15:20 +0000443}
444
445void RuleSet::shrinkToFit()
446{
447 shrinkMapVectorsToFit(m_idRules);
448 shrinkMapVectorsToFit(m_classRules);
benjamin@webkit.orgd58a1a72015-01-26 20:40:18 +0000449 shrinkMapVectorsToFit(m_tagLocalNameRules);
450 shrinkMapVectorsToFit(m_tagLowercaseLocalNameRules);
morrita@google.com3b321b52012-10-05 06:15:20 +0000451 shrinkMapVectorsToFit(m_shadowPseudoElementRules);
452 m_linkPseudoClassRules.shrinkToFit();
commit-queue@webkit.org7db073d2012-12-18 00:01:39 +0000453#if ENABLE(VIDEO_TRACK)
454 m_cuePseudoRules.shrinkToFit();
455#endif
antti@apple.com8c4fa4e2016-02-26 14:57:01 +0000456 m_hostPseudoClassRules.shrinkToFit();
457 m_slottedPseudoElementRules.shrinkToFit();
morrita@google.com3b321b52012-10-05 06:15:20 +0000458 m_focusPseudoClassRules.shrinkToFit();
459 m_universalRules.shrinkToFit();
460 m_pageRules.shrinkToFit();
akling@apple.comd6d61af22015-01-16 17:50:14 +0000461 m_features.shrinkToFit();
morrita@google.com3b321b52012-10-05 06:15:20 +0000462}
463
464} // namespace WebCore