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 fa5268046a1d7de88956888acfa1d51b42902d4e..0af9acc79aa6c38f73366e35d08752cd7bfb1222 100644 |
--- a/third_party/WebKit/Source/core/css/RuleFeature.cpp |
+++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp |
@@ -351,6 +351,14 @@ InvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& s |
case CSSSelector::PseudoUnresolved: |
case CSSSelector::PseudoDefined: |
return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); |
+ case CSSSelector::PseudoFirstOfType: |
+ case CSSSelector::PseudoLastOfType: |
+ case CSSSelector::PseudoOnlyOfType: |
+ case CSSSelector::PseudoNthChild: |
+ case CSSSelector::PseudoNthOfType: |
+ case CSSSelector::PseudoNthLastChild: |
+ case CSSSelector::PseudoNthLastOfType: |
+ return &ensureNthInvalidationSet(); |
default: |
break; |
} |
@@ -371,9 +379,12 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) |
InvalidationSetFeatures features; |
auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject); |
+ features.forceSubtree = result.second == ForceSubtree; |
if (result.first) { |
- features.forceSubtree = result.second == ForceSubtree; |
addFeaturesToInvalidationSets(result.first, features.adjacent ? &features : nullptr, features); |
+ } else if (features.hasNthPseudo) { |
+ DCHECK(m_nthInvalidationSet); |
+ addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); |
} |
// If any ::before and ::after rules specify 'content: attr(...)', we |
@@ -416,8 +427,12 @@ RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva |
foundFeatures |= extractInvalidationSetFeature(*current, features); |
// Initialize the entry in the invalidation set map, if supported. |
if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current, InvalidateDescendants)) { |
- if (position == Subject) |
- invalidationSet->setInvalidatesSelf(); |
+ if (position == Subject) { |
+ if (invalidationSet == m_nthInvalidationSet) |
+ features.hasNthPseudo = true; |
+ else |
+ invalidationSet->setInvalidatesSelf(); |
+ } |
} else { |
if (requiresSubtreeInvalidation(*current)) { |
// Fall back to use subtree invalidations, even for features in the |
@@ -452,6 +467,13 @@ RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva |
if (current->relation() == CSSSelector::SubSelector) |
continue; |
+ if (features.hasNthPseudo && position == Subject) { |
+ DCHECK(m_nthInvalidationSet); |
+ addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); |
+ if (!foundFeatures) |
+ m_nthInvalidationSet->setWholeSubtreeInvalid(); |
esprehn
2016/08/11 10:32:55
If we're going to mark it for the whole subtree wh
rune
2016/08/12 11:03:14
Will fix.
|
+ } |
+ |
features.treeBoundaryCrossing = current->isShadowSelector(); |
if (current->relationIsAffectedByPseudoContent()) { |
features.contentPseudoCrossing = true; |
@@ -462,7 +484,7 @@ RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, Inva |
features.maxDirectAdjacentSelectors = 1; |
return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); |
} |
- return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
+ return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); |
} |
// Add features extracted from the rightmost compound selector to descendant invalidation |
@@ -516,7 +538,7 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector, |
if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current, type)) { |
if (current->match() != CSSSelector::PseudoClass) |
universalCompound = false; |
- if (siblingFeatures) { |
+ if (siblingFeatures && invalidationSet != m_nthInvalidationSet) { |
SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvalidationSet(invalidationSet); |
siblingInvalidationSet->updateMaxDirectAdjacentSelectors(siblingFeatures->maxDirectAdjacentSelectors); |
@@ -698,6 +720,8 @@ void RuleFeatureSet::add(const RuleFeatureSet& other) |
ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector::PseudoType>(entry.key), entry.value->type()).combine(*entry.value); |
if (other.m_universalSiblingInvalidationSet) |
ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblingInvalidationSet); |
+ if (other.m_nthInvalidationSet) |
+ ensureNthInvalidationSet().combine(*other.m_nthInvalidationSet); |
m_metadata.add(other.m_metadata); |
@@ -867,6 +891,19 @@ SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet() |
return *m_universalSiblingInvalidationSet; |
} |
+void RuleFeatureSet::collectNthInvalidationSet(InvalidationLists& invalidationLists) const |
+{ |
+ if (m_nthInvalidationSet) |
+ invalidationLists.descendants.append(m_nthInvalidationSet); |
+} |
+ |
+DescendantInvalidationSet& RuleFeatureSet::ensureNthInvalidationSet() |
+{ |
+ if (!m_nthInvalidationSet) |
+ m_nthInvalidationSet = DescendantInvalidationSet::create(); |
+ return *m_nthInvalidationSet; |
+} |
+ |
void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const InvalidationSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatures) |
{ |
SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet(); |