Index: Source/core/css/RuleFeature.cpp |
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp |
index a30022f1d0006737cbe311a7432ad9c3eba843c3..b5dc017d657c25ba94f3434040e6d60f3b7bc5ed 100644 |
--- a/Source/core/css/RuleFeature.cpp |
+++ b/Source/core/css/RuleFeature.cpp |
@@ -47,7 +47,7 @@ static bool isSkippableComponentForInvalidation(const CSSSelector& selector) |
|| selector.isAttributeSelector()) |
return true; |
if (selector.m_match == CSSSelector::PseudoElement) { |
- switch (selector.m_pseudoType) { |
+ switch (selector.pseudoType()) { |
case CSSSelector::PseudoBefore: |
case CSSSelector::PseudoAfter: |
case CSSSelector::PseudoBackdrop: |
@@ -112,6 +112,16 @@ RuleFeatureSet::InvalidationSetMode RuleFeatureSet::supportsClassDescendantInval |
if (component->m_match == CSSSelector::Class || component->isAttributeSelector()) { |
if (!foundDescendantRelation) |
foundIdent = true; |
+ } else if (component->pseudoType() == CSSSelector::PseudoHost) { |
+ if (const CSSSelectorList* selectorList = component->selectorList()) { |
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) { |
+ InvalidationSetMode hostMode = supportsClassDescendantInvalidation(*selector); |
+ if (hostMode == UseSubtreeStyleChange) |
+ return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeStyleChange; |
+ if (hostMode == AddFeatures) |
+ foundIdent = true; |
+ } |
+ } |
} else if (!isSkippableComponentForInvalidation(*component)) { |
return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeStyleChange; |
} |
@@ -168,19 +178,38 @@ RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const |
AtomicString tagName; |
Vector<AtomicString> attributes; |
+ const CSSSelector* current = extractInvalidationSetFeatures(selector, classes, id, tagName, attributes); |
+ if (current) |
+ current = current->tagHistory(); |
+ |
+ if (current) |
+ addFeaturesToInvalidationSets(*current, classes, id, tagName, attributes); |
+ return AddFeatures; |
+} |
+ |
+const CSSSelector* RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Vector<AtomicString>& classes, AtomicString& id, AtomicString& tagName, Vector<AtomicString>& attributes) |
+{ |
const CSSSelector* lastSelector = &selector; |
for (; lastSelector; lastSelector = lastSelector->tagHistory()) { |
extractClassIdTagOrAttribute(*lastSelector, classes, id, tagName, attributes); |
// Initialize the entry in the invalidation set map, if supported. |
invalidationSetForSelector(*lastSelector); |
+ if (lastSelector->pseudoType() == CSSSelector::PseudoHost) { |
+ if (const CSSSelectorList* selectorList = lastSelector->selectorList()) { |
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) |
+ extractInvalidationSetFeatures(*selector, classes, id, tagName, attributes); |
+ } |
+ } |
if (lastSelector->relation() != CSSSelector::SubSelector) |
break; |
} |
+ return lastSelector; |
+} |
- if (!lastSelector) |
- return AddFeatures; |
- for (const CSSSelector* current = lastSelector->tagHistory(); current; current = current->tagHistory()) { |
+void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, const Vector<AtomicString>& classes, AtomicString id, AtomicString tagName, const Vector<AtomicString>& attributes) |
+{ |
+ for (const CSSSelector* current = &selector; current; current = current->tagHistory()) { |
if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current)) { |
if (!id.isEmpty()) |
invalidationSet->addId(id); |
@@ -190,9 +219,13 @@ RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const |
invalidationSet->addClass(*it); |
for (Vector<AtomicString>::const_iterator it = attributes.begin(); it != attributes.end(); ++it) |
invalidationSet->addAttribute(*it); |
+ } else if (current->pseudoType() == CSSSelector::PseudoHost) { |
+ if (const CSSSelectorList* selectorList = current->selectorList()) { |
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) |
+ addFeaturesToInvalidationSets(*selector, classes, id, tagName, attributes); |
+ } |
} |
} |
- return AddFeatures; |
} |
void RuleFeatureSet::addContentAttr(const AtomicString& attributeName) |