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 740a207cdb3e824647b458898ea0a7494e5a4c30..db3fd116fa1e19202c3cdefad28f9685e5177b1f 100644 |
--- a/third_party/WebKit/Source/core/css/RuleFeature.cpp |
+++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp |
@@ -332,6 +332,8 @@ void RuleFeatureSet::updateFeaturesFromCombinator( |
descendantFeatures.insertionPointCrossing = true; |
if (lastInCompound.relationIsAffectedByPseudoContent()) |
descendantFeatures.contentPseudoCrossing = true; |
+ if (lastInCompound.relationIsAffectedByPseudoContent() || lastInCompound.isShadowSelector()) |
+ descendantFeatures.hasInvalidationSetFeaturesInScope = false; |
} |
void RuleFeatureSet::extractInvalidationSetFeaturesFromSimpleSelector(const CSSSelector& selector, InvalidationSetFeatures& features) |
@@ -441,7 +443,9 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
InvalidationSetFeatures features; |
const CSSSelector* nextCompound = extractInvalidationSetFeaturesFromCompound(ruleData.selector(), features, Subject); |
- if (!features.hasFeatures()) |
+ if (features.forceSubtree) |
+ features.hasInvalidationSetFeaturesInScope = false; |
+ else if (!features.hasFeatures()) |
features.forceSubtree = true; |
if (nextCompound) |
@@ -451,6 +455,9 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
if (features.hasBeforeOrAfter) |
updateInvalidationSetsForContentAttribute(ruleData); |
+ |
+ if (!features.hasInvalidationSetFeaturesInScope) |
+ m_metadata.needsFullRecalcForRuleSetInvalidation = true; |
} |
void RuleFeatureSet::updateInvalidationSetsForContentAttribute(const RuleData& ruleData) |
@@ -570,12 +577,14 @@ RuleFeatureSet::extractInvalidationSetFeaturesFromCompound(const CSSSelector& co |
else |
m_nthInvalidationSet->setWholeSubtreeInvalid(); |
} |
+ features.hasInvalidationSetFeaturesInScope = features.hasFeatures(); |
InvalidationSetFeatures* siblingFeatures = nullptr; |
updateFeaturesFromCombinator(*simpleSelector, nullptr, features, siblingFeatures, features); |
} |
return simpleSelector->tagHistory(); |
} |
+ features.hasInvalidationSetFeaturesInScope = features.hasFeatures(); |
return nullptr; |
} |
@@ -621,8 +630,20 @@ void RuleFeatureSet::addFeaturesToInvalidationSetsForSelectorList(const CSSSelec |
DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType())); |
- for (const CSSSelector* subSelector = simpleSelector.selectorList()->first(); subSelector; subSelector = CSSSelectorList::next(*subSelector)) |
+ bool hadInvalidationSetFeaturesInScope = descendantFeatures.hasInvalidationSetFeaturesInScope; |
+ bool selectorListContainsUniversal = simpleSelector.getPseudoType() == CSSSelector::PseudoNot |
+ || simpleSelector.getPseudoType() == CSSSelector::PseudoHostContext; |
+ |
+ for (const CSSSelector* subSelector = simpleSelector.selectorList()->first(); subSelector; subSelector = CSSSelectorList::next(*subSelector)) { |
+ descendantFeatures.hasInvalidationSetFeaturesInScope = false; |
+ |
addFeaturesToInvalidationSetsForCompoundSelector(*subSelector, siblingFeatures, descendantFeatures); |
+ |
+ if (!descendantFeatures.hasInvalidationSetFeaturesInScope) |
+ selectorListContainsUniversal = true; |
+ } |
+ |
+ descendantFeatures.hasInvalidationSetFeaturesInScope = hadInvalidationSetFeaturesInScope || !selectorListContainsUniversal; |
} |
void RuleFeatureSet::addFeaturesToInvalidationSetsForSimpleSelector(const CSSSelector& simpleSelector, InvalidationSetFeatures* siblingFeatures, InvalidationSetFeatures& descendantFeatures) |
@@ -657,15 +678,17 @@ const CSSSelector* RuleFeatureSet::addFeaturesToInvalidationSetsForCompoundSelec |
const CSSSelector* simpleSelector = &compound; |
for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) { |
addFeaturesToInvalidationSetsForSimpleSelector(*simpleSelector, siblingFeatures, descendantFeatures); |
- if (siblingFeatures) |
- compoundHasIdClassOrAttribute |= simpleSelector->isIdClassOrAttributeSelector(); |
+ if (simpleSelector->isIdClassOrAttributeSelector()) |
+ compoundHasIdClassOrAttribute = true; |
if (simpleSelector->relation() != CSSSelector::SubSelector) |
break; |
if (!simpleSelector->tagHistory()) |
break; |
} |
- if (siblingFeatures && !compoundHasIdClassOrAttribute) |
+ if (compoundHasIdClassOrAttribute) |
+ descendantFeatures.hasInvalidationSetFeaturesInScope = true; |
+ else if (siblingFeatures) |
addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendantFeatures); |
return simpleSelector; |
@@ -780,8 +803,8 @@ RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromSelector(con |
void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) |
{ |
- usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; |
- usesWindowInactiveSelector = usesWindowInactiveSelector || other.usesWindowInactiveSelector; |
+ usesFirstLineRules |= other.usesFirstLineRules; |
+ usesWindowInactiveSelector |= other.usesWindowInactiveSelector; |
maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxDirectAdjacentSelectors); |
} |
@@ -791,6 +814,7 @@ void RuleFeatureSet::FeatureMetadata::clear() |
usesWindowInactiveSelector = false; |
foundSiblingSelector = false; |
foundInsertionPointCrossing = false; |
+ needsFullRecalcForRuleSetInvalidation = false; |
maxDirectAdjacentSelectors = 0; |
} |