Index: third_party/WebKit/Source/core/css/RuleFeature.cpp |
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.cpp b/third_party/WebKit/Source/core/css/RuleFeature.cpp |
index 6284b30302380f93d0f84389385077434595150f..9a283776f44db5652a33a2942c3ea39da484df29 100644 |
--- a/third_party/WebKit/Source/core/css/RuleFeature.cpp |
+++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp |
@@ -368,11 +368,17 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
InvalidationSetFeatures features; |
auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject); |
- if (result.first) { |
- features.forceSubtree = result.second == ForceSubtree; |
- addFeaturesToInvalidationSets(result.first, features.adjacent ? &features : nullptr, features); |
+ if (result.second == ForceSubtree) { |
+ features.forceSubtree = true; |
+ features.containsIdClassAttributeOrTypeInScope = false; |
} |
+ if (result.first) |
+ addFeaturesToInvalidationSets(result.first, features.adjacent ? &features : nullptr, features); |
+ |
+ if (!features.containsIdClassAttributeOrTypeInScope) |
+ m_metadata.needsFullRecalcForRuleSetInvalidation = true; |
+ |
// If any ::before and ::after rules specify 'content: attr(...)', we |
// need to create invalidation sets for those attributes. |
if (features.hasBeforeOrAfter) |
@@ -449,17 +455,24 @@ RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva |
if (current->relation() == CSSSelector::SubSelector) |
continue; |
- features.treeBoundaryCrossing = current->isShadowSelector(); |
+ features.containsIdClassAttributeOrTypeInScope |= foundFeatures; |
+ if (current->isShadowSelector()) { |
+ features.treeBoundaryCrossing = true; |
+ features.containsIdClassAttributeOrTypeInScope = false; |
+ } |
if (current->relationIsAffectedByPseudoContent()) { |
features.contentPseudoCrossing = true; |
features.insertionPointCrossing = true; |
+ features.containsIdClassAttributeOrTypeInScope = false; |
} |
+ |
features.adjacent = current->isAdjacentSelector(); |
if (current->relation() == CSSSelector::DirectAdjacent) |
features.maxDirectAdjacentSelectors = 1; |
return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); |
} |
- return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
+ features.containsIdClassAttributeOrTypeInScope |= foundFeatures; |
+ return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
} |
// Add features extracted from the rightmost compound selector to descendant invalidation |
@@ -509,6 +522,8 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, |
for (const CSSSelector* current = selector; current; current = current->tagHistory()) { |
InvalidationType type = siblingFeatures ? InvalidateSiblings : InvalidateDescendants; |
if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current, type)) { |
+ if (current->match() == CSSSelector::Id || current->match() == CSSSelector::Class || current->match() >= CSSSelector::FirstAttributeSelectorMatch) |
+ descendantFeatures.containsIdClassAttributeOrTypeInScope = true; |
if (siblingFeatures) { |
SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvalidationSet(invalidationSet); |
siblingInvalidationSet->updateMaxDirectAdjacentSelectors(siblingFeatures->maxDirectAdjacentSelectors); |
@@ -528,8 +543,13 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, |
descendantFeatures.insertionPointCrossing = true; |
if (const CSSSelectorList* selectorList = current->selectorList()) { |
ASSERT(supportsInvalidationWithSelectorList(current->getPseudoType())); |
+ bool didContain = descendantFeatures.containsIdClassAttributeOrTypeInScope; |
for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(*subSelector)) |
addFeaturesToInvalidationSets(subSelector, siblingFeatures, descendantFeatures); |
+ if (current->getPseudoType() == CSSSelector::PseudoNot || current->getPseudoType() == CSSSelector::PseudoHostContext) |
+ descendantFeatures.containsIdClassAttributeOrTypeInScope = didContain; |
+ else |
+ descendantFeatures.containsIdClassAttributeOrTypeInScope |= didContain; |
} |
} |
@@ -539,9 +559,12 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, |
if (current->relationIsAffectedByPseudoContent() || current->relation() == CSSSelector::ShadowSlot) { |
descendantFeatures.insertionPointCrossing = true; |
descendantFeatures.contentPseudoCrossing = true; |
+ descendantFeatures.containsIdClassAttributeOrTypeInScope = false; |
} |
- if (current->isShadowSelector()) |
+ if (current->isShadowSelector()) { |
descendantFeatures.treeBoundaryCrossing = true; |
+ descendantFeatures.containsIdClassAttributeOrTypeInScope = false; |
+ } |
if (!current->isAdjacentSelector()) { |
lastCompoundSelectorInAdjacentChain = current->tagHistory(); |
siblingFeatures = nullptr; |
@@ -669,6 +692,7 @@ void RuleFeatureSet::FeatureMetadata::clear() |
usesWindowInactiveSelector = false; |
foundSiblingSelector = false; |
foundInsertionPointCrossing = false; |
+ needsFullRecalcForRuleSetInvalidation = false; |
maxDirectAdjacentSelectors = 0; |
} |
@@ -687,6 +711,8 @@ void RuleFeatureSet::add(const RuleFeatureSet& other) |
siblingRules.appendVector(other.siblingRules); |
uncommonAttributeRules.appendVector(other.uncommonAttributeRules); |
+ viewportDependentMediaQueryResults.appendVector(other.viewportDependentMediaQueryResults); |
+ deviceDependentMediaQueryResults.appendVector(other.deviceDependentMediaQueryResults); |
} |
void RuleFeatureSet::clear() |
@@ -788,6 +814,8 @@ DEFINE_TRACE(RuleFeatureSet) |
{ |
visitor->trace(siblingRules); |
visitor->trace(uncommonAttributeRules); |
+ visitor->trace(viewportDependentMediaQueryResults); |
+ visitor->trace(deviceDependentMediaQueryResults); |
} |
} // namespace blink |