Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / css / RuleFeature.cpp
blobf89de00af3ef780abe8d90b3ac724873fc0d88cc
1 /*
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)
5 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
6 * 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.
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.
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.
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.
29 #include "config.h"
30 #include "core/css/RuleFeature.h"
32 #include "core/HTMLNames.h"
33 #include "core/css/CSSFunctionValue.h"
34 #include "core/css/CSSSelector.h"
35 #include "core/css/CSSSelectorList.h"
36 #include "core/css/CSSValueList.h"
37 #include "core/css/RuleSet.h"
38 #include "core/css/StylePropertySet.h"
39 #include "core/css/StyleRule.h"
40 #include "core/css/invalidation/InvalidationSet.h"
41 #include "core/dom/Element.h"
42 #include "core/dom/Node.h"
43 #include "core/inspector/InspectorTraceEvents.h"
44 #include "wtf/BitVector.h"
46 namespace blink {
48 #if ENABLE(ASSERT)
50 static bool supportsInvalidation(CSSSelector::Match match)
52 switch (match) {
53 case CSSSelector::Tag:
54 case CSSSelector::Id:
55 case CSSSelector::Class:
56 case CSSSelector::AttributeExact:
57 case CSSSelector::AttributeSet:
58 case CSSSelector::AttributeHyphen:
59 case CSSSelector::AttributeList:
60 case CSSSelector::AttributeContain:
61 case CSSSelector::AttributeBegin:
62 case CSSSelector::AttributeEnd:
63 return true;
64 case CSSSelector::Unknown:
65 case CSSSelector::PagePseudoClass:
66 // These should not appear in StyleRule selectors.
67 ASSERT_NOT_REACHED();
68 return false;
69 default:
70 // New match type added. Figure out if it needs a subtree invalidation or not.
71 ASSERT_NOT_REACHED();
72 return false;
76 static bool supportsInvalidation(CSSSelector::PseudoType type)
78 switch (type) {
79 case CSSSelector::PseudoEmpty:
80 case CSSSelector::PseudoFirstChild:
81 case CSSSelector::PseudoFirstOfType:
82 case CSSSelector::PseudoLastChild:
83 case CSSSelector::PseudoLastOfType:
84 case CSSSelector::PseudoOnlyChild:
85 case CSSSelector::PseudoOnlyOfType:
86 case CSSSelector::PseudoNthChild:
87 case CSSSelector::PseudoNthOfType:
88 case CSSSelector::PseudoNthLastChild:
89 case CSSSelector::PseudoNthLastOfType:
90 case CSSSelector::PseudoLink:
91 case CSSSelector::PseudoVisited:
92 case CSSSelector::PseudoAny:
93 case CSSSelector::PseudoAnyLink:
94 case CSSSelector::PseudoAutofill:
95 case CSSSelector::PseudoHover:
96 case CSSSelector::PseudoDrag:
97 case CSSSelector::PseudoFocus:
98 case CSSSelector::PseudoActive:
99 case CSSSelector::PseudoChecked:
100 case CSSSelector::PseudoEnabled:
101 case CSSSelector::PseudoFullPageMedia:
102 case CSSSelector::PseudoDefault:
103 case CSSSelector::PseudoDisabled:
104 case CSSSelector::PseudoOptional:
105 case CSSSelector::PseudoPlaceholderShown:
106 case CSSSelector::PseudoRequired:
107 case CSSSelector::PseudoReadOnly:
108 case CSSSelector::PseudoReadWrite:
109 case CSSSelector::PseudoValid:
110 case CSSSelector::PseudoInvalid:
111 case CSSSelector::PseudoIndeterminate:
112 case CSSSelector::PseudoTarget:
113 case CSSSelector::PseudoBefore:
114 case CSSSelector::PseudoAfter:
115 case CSSSelector::PseudoBackdrop:
116 case CSSSelector::PseudoLang:
117 case CSSSelector::PseudoNot:
118 case CSSSelector::PseudoResizer:
119 case CSSSelector::PseudoRoot:
120 case CSSSelector::PseudoScope:
121 case CSSSelector::PseudoScrollbar:
122 case CSSSelector::PseudoScrollbarButton:
123 case CSSSelector::PseudoScrollbarCorner:
124 case CSSSelector::PseudoScrollbarThumb:
125 case CSSSelector::PseudoScrollbarTrack:
126 case CSSSelector::PseudoScrollbarTrackPiece:
127 case CSSSelector::PseudoWindowInactive:
128 case CSSSelector::PseudoSelection:
129 case CSSSelector::PseudoCornerPresent:
130 case CSSSelector::PseudoDecrement:
131 case CSSSelector::PseudoIncrement:
132 case CSSSelector::PseudoHorizontal:
133 case CSSSelector::PseudoVertical:
134 case CSSSelector::PseudoStart:
135 case CSSSelector::PseudoEnd:
136 case CSSSelector::PseudoDoubleButton:
137 case CSSSelector::PseudoSingleButton:
138 case CSSSelector::PseudoNoButton:
139 case CSSSelector::PseudoFullScreen:
140 case CSSSelector::PseudoFullScreenAncestor:
141 case CSSSelector::PseudoInRange:
142 case CSSSelector::PseudoOutOfRange:
143 case CSSSelector::PseudoWebKitCustomElement:
144 case CSSSelector::PseudoCue:
145 case CSSSelector::PseudoFutureCue:
146 case CSSSelector::PseudoPastCue:
147 case CSSSelector::PseudoUnresolved:
148 case CSSSelector::PseudoContent:
149 case CSSSelector::PseudoHost:
150 case CSSSelector::PseudoShadow:
151 case CSSSelector::PseudoSpatialNavigationFocus:
152 case CSSSelector::PseudoListBox:
153 return true;
154 case CSSSelector::PseudoUnknown:
155 case CSSSelector::PseudoLeftPage:
156 case CSSSelector::PseudoRightPage:
157 case CSSSelector::PseudoFirstPage:
158 // These should not appear in StyleRule selectors.
159 ASSERT_NOT_REACHED();
160 return false;
161 default:
162 // New pseudo type added. Figure out if it needs a subtree invalidation or not.
163 ASSERT_NOT_REACHED();
164 return false;
168 static bool supportsInvalidationWithSelectorList(CSSSelector::PseudoType pseudo)
170 return pseudo == CSSSelector::PseudoAny
171 || pseudo == CSSSelector::PseudoCue
172 || pseudo == CSSSelector::PseudoHost
173 || pseudo == CSSSelector::PseudoHostContext
174 || pseudo == CSSSelector::PseudoNot;
177 #endif // ENABLE(ASSERT)
179 static bool requiresSubtreeInvalidation(const CSSSelector& selector)
181 if (selector.match() != CSSSelector::PseudoElement && selector.match() != CSSSelector::PseudoClass) {
182 ASSERT(supportsInvalidation(selector.match()));
183 return false;
186 switch (selector.pseudoType()) {
187 case CSSSelector::PseudoFirstLine:
188 case CSSSelector::PseudoFirstLetter:
189 // FIXME: Most pseudo classes/elements above can be supported and moved
190 // to assertSupportedPseudo(). Move on a case-by-case basis. If they
191 // require subtree invalidation, document why.
192 case CSSSelector::PseudoHostContext:
193 // :host-context matches a shadow host, yet the simple selectors inside
194 // :host-context matches an ancestor of the shadow host.
195 return true;
196 default:
197 ASSERT(supportsInvalidation(selector.pseudoType()));
198 return false;
202 RuleFeature::RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
203 : rule(rule)
204 , selectorIndex(selectorIndex)
205 , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
209 DEFINE_TRACE(RuleFeature)
211 visitor->trace(rule);
214 bool RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, InvalidationSetFeatures& features)
216 if (selector.match() == CSSSelector::Tag && selector.tagQName().localName() != starAtom)
217 features.tagName = selector.tagQName().localName();
218 else if (selector.match() == CSSSelector::Id)
219 features.id = selector.value();
220 else if (selector.match() == CSSSelector::Class)
221 features.classes.append(selector.value());
222 else if (selector.isAttributeSelector())
223 features.attributes.append(selector.attribute().localName());
224 else if (selector.pseudoType() == CSSSelector::PseudoWebKitCustomElement)
225 features.customPseudoElement = true;
226 else if (selector.pseudoType() == CSSSelector::PseudoBefore || selector.pseudoType() == CSSSelector::PseudoAfter)
227 features.hasBeforeOrAfter = true;
228 else
229 return false;
230 return true;
233 RuleFeatureSet::RuleFeatureSet()
237 RuleFeatureSet::~RuleFeatureSet()
241 InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& selector)
243 if (selector.match() == CSSSelector::Class)
244 return &ensureClassInvalidationSet(selector.value());
245 if (selector.isAttributeSelector())
246 return &ensureAttributeInvalidationSet(selector.attribute().localName());
247 if (selector.match() == CSSSelector::Id)
248 return &ensureIdInvalidationSet(selector.value());
249 if (selector.match() == CSSSelector::PseudoClass) {
250 switch (selector.pseudoType()) {
251 case CSSSelector::PseudoEmpty:
252 case CSSSelector::PseudoLink:
253 case CSSSelector::PseudoVisited:
254 case CSSSelector::PseudoAnyLink:
255 case CSSSelector::PseudoAutofill:
256 case CSSSelector::PseudoHover:
257 case CSSSelector::PseudoFocus:
258 case CSSSelector::PseudoActive:
259 case CSSSelector::PseudoChecked:
260 case CSSSelector::PseudoEnabled:
261 case CSSSelector::PseudoDisabled:
262 case CSSSelector::PseudoOptional:
263 case CSSSelector::PseudoPlaceholderShown:
264 case CSSSelector::PseudoRequired:
265 case CSSSelector::PseudoValid:
266 case CSSSelector::PseudoInvalid:
267 case CSSSelector::PseudoIndeterminate:
268 case CSSSelector::PseudoTarget:
269 return &ensurePseudoInvalidationSet(selector.pseudoType());
270 default:
271 break;
274 return nullptr;
277 // Given a rule, update the descendant invalidation sets for the features found
278 // in its selector. The first step is to extract the features from the rightmost
279 // compound selector (extractInvalidationSetFeatures). Secondly, add those features
280 // to the invalidation sets for the features found in the other compound selectors
281 // (addFeaturesToInvalidationSets). If we find a feature in the right-most compound
282 // selector that requires a subtree recalc, we addFeaturesToInvalidationSets for the
283 // rightmost compound selector as well.
285 void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData)
287 InvalidationSetFeatures features;
288 auto result = extractInvalidationSetFeatures(ruleData.selector(), features, false);
289 if (result.first) {
290 features.forceSubtree = result.second == ForceSubtree;
291 addFeaturesToInvalidationSets(*result.first, features);
294 // If any ::before and ::after rules specify 'content: attr(...)', we
295 // need to create invalidation sets for those attributes.
296 if (features.hasBeforeOrAfter)
297 updateInvalidationSetsForContentAttribute(ruleData);
300 void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& ruleData)
302 const StylePropertySet& propertySet = ruleData.rule()->properties();
304 int propertyIndex = propertySet.findPropertyIndex(CSSPropertyContent);
306 if (propertyIndex == -1)
307 return;
309 StylePropertySet::PropertyReference contentProperty = propertySet.propertyAt(propertyIndex);
310 CSSValue* contentValue = contentProperty.value();
312 if (!contentValue->isValueList())
313 return;
315 for (auto& item : toCSSValueList(*contentValue)) {
316 if (!item->isFunctionValue())
317 continue;
318 CSSFunctionValue* functionValue = toCSSFunctionValue(item.get());
319 if (functionValue->functionType() != CSSValueAttr)
320 continue;
321 ensureAttributeInvalidationSet(AtomicString(toCSSPrimitiveValue(functionValue->item(0))->getStringValue())).setInvalidatesSelf();
325 std::pair<const CSSSelector*, RuleFeatureSet::UseFeaturesType>
326 RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, InvalidationSetFeatures& features, bool negated)
328 bool foundFeatures = false;
329 for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
330 if (!negated)
331 foundFeatures |= extractInvalidationSetFeature(*current, features);
332 // Initialize the entry in the invalidation set map, if supported.
333 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current)) {
334 invalidationSet->setInvalidatesSelf();
335 } else {
336 if (requiresSubtreeInvalidation(*current)) {
337 // Fall back to use subtree invalidations, even for features in the
338 // rightmost compound selector. Returning the start &selector here
339 // will make addFeaturesToInvalidationSets start marking invalidation
340 // sets for subtree recalc for features in the rightmost compound
341 // selector.
342 return std::make_pair(&selector, ForceSubtree);
344 if (const CSSSelectorList* selectorList = current->selectorList()) {
345 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType()));
346 const CSSSelector* subSelector = selectorList->first();
347 bool allSubSelectorsHaveFeatures = !!subSelector;
348 for (; subSelector; subSelector = CSSSelectorList::next(*subSelector)) {
349 auto result = extractInvalidationSetFeatures(*subSelector, features, current->pseudoType() == CSSSelector::PseudoNot);
350 if (result.first) {
351 // A non-null selector return means the sub-selector contained a
352 // selector which requiresSubtreeInvalidation(). Return the rightmost
353 // selector to mark for subtree recalcs like above.
354 return std::make_pair(&selector, ForceSubtree);
356 allSubSelectorsHaveFeatures &= result.second == UseFeatures;
358 foundFeatures |= allSubSelectorsHaveFeatures;
362 if (current->relation() == CSSSelector::SubSelector)
363 continue;
365 features.treeBoundaryCrossing = current->isShadowSelector();
366 features.adjacent = current->isAdjacentSelector();
367 return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree);
369 return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree);
372 // Add features extracted from the rightmost compound selector to descendant invalidation
373 // sets for features found in other compound selectors.
375 // Style invalidation is currently supported for descendants only, not for sibling subtrees.
376 // We use wholeSubtree invalidation for features found left of adjacent combinators as
377 // SubtreeStyleChange will force sibling subtree recalc in
378 // ContainerNode::checkForChildrenAdjacentRuleChanges.
380 // As we encounter a descendant type of combinator, the features only need to be checked
381 // against descendants in the same subtree only. features.adjacent is set to false, and
382 // we start adding features instead of calling setWholeSubtreeInvalid.
384 void RuleFeatureSet::addFeaturesToInvalidationSet(InvalidationSet& invalidationSet, const InvalidationSetFeatures& features)
386 if (features.treeBoundaryCrossing)
387 invalidationSet.setTreeBoundaryCrossing();
388 if (features.insertionPointCrossing)
389 invalidationSet.setInsertionPointCrossing();
390 if (features.useSubtreeInvalidation()) {
391 invalidationSet.setWholeSubtreeInvalid();
392 return;
394 if (!features.id.isEmpty())
395 invalidationSet.addId(features.id);
396 if (!features.tagName.isEmpty())
397 invalidationSet.addTagName(features.tagName);
398 for (const auto& className : features.classes)
399 invalidationSet.addClass(className);
400 for (const auto& attribute : features.attributes)
401 invalidationSet.addAttribute(attribute);
402 if (features.customPseudoElement)
403 invalidationSet.setCustomPseudoInvalid();
406 void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, InvalidationSetFeatures& features)
408 for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
409 if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current)) {
410 addFeaturesToInvalidationSet(*invalidationSet, features);
411 } else {
412 if (current->isTreeBoundaryCrossing())
413 features.treeBoundaryCrossing = true;
414 if (current->isInsertionPointCrossing())
415 features.insertionPointCrossing = true;
416 if (const CSSSelectorList* selectorList = current->selectorList()) {
417 ASSERT(supportsInvalidationWithSelectorList(current->pseudoType()));
418 for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(*subSelector))
419 addFeaturesToInvalidationSets(*subSelector, features);
423 if (current->relation() == CSSSelector::SubSelector)
424 continue;
426 if (current->isShadowSelector())
427 features.treeBoundaryCrossing = true;
429 features.adjacent = current->isAdjacentSelector();
433 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
435 updateInvalidationSets(ruleData);
437 FeatureMetadata metadata;
438 collectFeaturesFromSelector(ruleData.selector(), metadata);
439 m_metadata.add(metadata);
441 if (metadata.foundSiblingSelector)
442 siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
443 if (ruleData.containsUncommonAttributeSelector())
444 uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
447 InvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const AtomicString& className)
449 InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(className, nullptr);
450 if (addResult.isNewEntry)
451 addResult.storedValue->value = InvalidationSet::create();
452 return *addResult.storedValue->value;
455 InvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet(const AtomicString& attributeName)
457 InvalidationSetMap::AddResult addResult = m_attributeInvalidationSets.add(attributeName, nullptr);
458 if (addResult.isNewEntry)
459 addResult.storedValue->value = InvalidationSet::create();
460 return *addResult.storedValue->value;
463 InvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicString& id)
465 InvalidationSetMap::AddResult addResult = m_idInvalidationSets.add(id, nullptr);
466 if (addResult.isNewEntry)
467 addResult.storedValue->value = InvalidationSet::create();
468 return *addResult.storedValue->value;
471 InvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelector::PseudoType pseudoType)
473 PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets.add(pseudoType, nullptr);
474 if (addResult.isNewEntry)
475 addResult.storedValue->value = InvalidationSet::create();
476 return *addResult.storedValue->value;
479 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, RuleFeatureSet::FeatureMetadata& metadata)
481 unsigned maxDirectAdjacentSelectors = 0;
483 for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
484 if (current->pseudoType() == CSSSelector::PseudoFirstLine)
485 metadata.usesFirstLineRules = true;
486 if (current->pseudoType() == CSSSelector::PseudoWindowInactive)
487 metadata.usesWindowInactiveSelector = true;
488 if (current->relation() == CSSSelector::DirectAdjacent) {
489 maxDirectAdjacentSelectors++;
490 } else if (maxDirectAdjacentSelectors
491 && ((current->relation() != CSSSelector::SubSelector) || current->isLastInTagHistory())) {
492 if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors)
493 metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors;
494 maxDirectAdjacentSelectors = 0;
496 if (current->isSiblingSelector())
497 metadata.foundSiblingSelector = true;
499 const CSSSelectorList* selectorList = current->selectorList();
500 if (!selectorList)
501 continue;
503 for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(*subSelector))
504 collectFeaturesFromSelector(*subSelector, metadata);
507 ASSERT(!maxDirectAdjacentSelectors);
510 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other)
512 usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
513 usesWindowInactiveSelector = usesWindowInactiveSelector || other.usesWindowInactiveSelector;
514 maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxDirectAdjacentSelectors);
517 void RuleFeatureSet::FeatureMetadata::clear()
519 usesFirstLineRules = false;
520 usesWindowInactiveSelector = false;
521 foundSiblingSelector = false;
522 maxDirectAdjacentSelectors = 0;
525 void RuleFeatureSet::add(const RuleFeatureSet& other)
527 for (const auto& invalidationSet : other.m_classInvalidationSets)
528 ensureClassInvalidationSet(invalidationSet.key).combine(*invalidationSet.value);
529 for (const auto& invalidationSet : other.m_attributeInvalidationSets)
530 ensureAttributeInvalidationSet(invalidationSet.key).combine(*invalidationSet.value);
531 for (const auto& invalidationSet : other.m_idInvalidationSets)
532 ensureIdInvalidationSet(invalidationSet.key).combine(*invalidationSet.value);
533 for (const auto& invalidationSet : other.m_pseudoInvalidationSets)
534 ensurePseudoInvalidationSet(static_cast<CSSSelector::PseudoType>(invalidationSet.key)).combine(*invalidationSet.value);
536 m_metadata.add(other.m_metadata);
538 siblingRules.appendVector(other.siblingRules);
539 uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
542 void RuleFeatureSet::clear()
544 siblingRules.clear();
545 uncommonAttributeRules.clear();
546 m_metadata.clear();
547 m_classInvalidationSets.clear();
548 m_attributeInvalidationSets.clear();
549 m_idInvalidationSets.clear();
552 void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationSetVector& invalidationSets, Element& element, const AtomicString& className) const
554 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_classInvalidationSets.get(className)) {
555 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, classChange, className);
556 invalidationSets.append(invalidationSet);
560 void RuleFeatureSet::collectInvalidationSetsForId(InvalidationSetVector& invalidationSets, Element& element, const AtomicString& id) const
562 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_idInvalidationSets.get(id)) {
563 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, idChange, id);
564 invalidationSets.append(invalidationSet);
568 void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationSetVector& invalidationSets, Element& element, const QualifiedName& attributeName) const
570 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_attributeInvalidationSets.get(attributeName.localName())) {
571 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, attributeChange, attributeName);
572 invalidationSets.append(invalidationSet);
576 void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationSetVector& invalidationSets, Element& element, CSSSelector::PseudoType pseudo) const
578 if (RefPtrWillBeRawPtr<InvalidationSet> invalidationSet = m_pseudoInvalidationSets.get(pseudo)) {
579 TRACE_SCHEDULE_STYLE_INVALIDATION(element, *invalidationSet, pseudoChange, pseudo);
580 invalidationSets.append(invalidationSet);
584 DEFINE_TRACE(RuleFeatureSet)
586 #if ENABLE(OILPAN)
587 visitor->trace(siblingRules);
588 visitor->trace(uncommonAttributeRules);
589 visitor->trace(m_classInvalidationSets);
590 visitor->trace(m_attributeInvalidationSets);
591 visitor->trace(m_idInvalidationSets);
592 visitor->trace(m_pseudoInvalidationSets);
593 #endif
596 } // namespace blink