| 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 2e2e24592a26c973f333022ba4435ee515d03738..b53fe7b64cf47a8a0b49a62fb63442aa0a0fc9f7 100644
|
| --- a/third_party/WebKit/Source/core/css/RuleFeature.cpp
|
| +++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
|
| @@ -506,9 +506,13 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector,
|
| // We set siblingFeatures to &localFeatures if we find a rightmost sibling combinator.
|
| InvalidationSetFeatures localFeatures;
|
|
|
| + bool universalCompound = true;
|
| +
|
| for (const CSSSelector* current = selector; current; current = current->tagHistory()) {
|
| InvalidationType type = siblingFeatures ? InvalidateSiblings : InvalidateDescendants;
|
| if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current, type)) {
|
| + if (current->match() != CSSSelector::PseudoClass)
|
| + universalCompound = false;
|
| if (siblingFeatures) {
|
| SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvalidationSet(invalidationSet);
|
| siblingInvalidationSet->updateMaxDirectAdjacentSelectors(siblingFeatures->maxDirectAdjacentSelectors);
|
| @@ -536,6 +540,10 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector,
|
| if (current->relation() == CSSSelector::SubSelector)
|
| continue;
|
|
|
| + if (universalCompound && siblingFeatures)
|
| + addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendantFeatures);
|
| + universalCompound = true;
|
| +
|
| if (current->relationIsAffectedByPseudoContent() || current->relation() == CSSSelector::ShadowSlot) {
|
| descendantFeatures.insertionPointCrossing = true;
|
| descendantFeatures.contentPseudoCrossing = true;
|
| @@ -565,6 +573,9 @@ void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector* selector,
|
| localFeatures.forceSubtree = result.second == ForceSubtree;
|
| siblingFeatures = &localFeatures;
|
| }
|
| +
|
| + if (universalCompound && siblingFeatures)
|
| + addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures, descendantFeatures);
|
| }
|
|
|
| RuleFeatureSet::SelectorPreMatch RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
|
| @@ -682,6 +693,8 @@ void RuleFeatureSet::add(const RuleFeatureSet& other)
|
| ensureInvalidationSet(m_idInvalidationSets, entry.key, entry.value->type()).combine(*entry.value);
|
| for (const auto& entry : other.m_pseudoInvalidationSets)
|
| ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector::PseudoType>(entry.key), entry.value->type()).combine(*entry.value);
|
| + if (other.m_universalSiblingInvalidationSet)
|
| + ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblingInvalidationSet);
|
|
|
| m_metadata.add(other.m_metadata);
|
|
|
| @@ -721,6 +734,21 @@ void RuleFeatureSet::collectInvalidationSetsForClass(InvalidationLists& invalida
|
| }
|
| }
|
|
|
| +void RuleFeatureSet::collectSiblingInvalidationSetForClass(InvalidationLists& invalidationLists, Element& element, const AtomicString& className) const
|
| +{
|
| + InvalidationSetMap::const_iterator it = m_classInvalidationSets.find(className);
|
| + if (it == m_classInvalidationSets.end())
|
| + return;
|
| +
|
| + InvalidationSet* invalidationSet = it->value.get();
|
| + if (invalidationSet->type() == InvalidateDescendants)
|
| + return;
|
| +
|
| + SiblingInvalidationSet* siblingSet = toSiblingInvalidationSet(invalidationSet);
|
| + TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblingSet, classChange, className);
|
| + invalidationLists.siblings.append(siblingSet);
|
| +}
|
| +
|
| void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidationLists, Element& element, const AtomicString& id) const
|
| {
|
| InvalidationSetMap::const_iterator it = m_idInvalidationSets.find(id);
|
| @@ -742,6 +770,21 @@ void RuleFeatureSet::collectInvalidationSetsForId(InvalidationLists& invalidatio
|
| }
|
| }
|
|
|
| +void RuleFeatureSet::collectSiblingInvalidationSetForId(InvalidationLists& invalidationLists, Element& element, const AtomicString& id) const
|
| +{
|
| + InvalidationSetMap::const_iterator it = m_idInvalidationSets.find(id);
|
| + if (it == m_idInvalidationSets.end())
|
| + return;
|
| +
|
| + InvalidationSet* invalidationSet = it->value.get();
|
| + if (invalidationSet->type() == InvalidateDescendants)
|
| + return;
|
| +
|
| + SiblingInvalidationSet* siblingSet = toSiblingInvalidationSet(invalidationSet);
|
| + TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblingSet, idChange, id);
|
| + invalidationLists.siblings.append(siblingSet);
|
| +}
|
| +
|
| void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& invalidationLists, Element& element, const QualifiedName& attributeName) const
|
| {
|
| InvalidationSetMap::const_iterator it = m_attributeInvalidationSets.find(attributeName.localName());
|
| @@ -763,6 +806,21 @@ void RuleFeatureSet::collectInvalidationSetsForAttribute(InvalidationLists& inva
|
| }
|
| }
|
|
|
| +void RuleFeatureSet::collectSiblingInvalidationSetForAttribute(InvalidationLists& invalidationLists, Element& element, const QualifiedName& attributeName) const
|
| +{
|
| + InvalidationSetMap::const_iterator it = m_attributeInvalidationSets.find(attributeName.localName());
|
| + if (it == m_attributeInvalidationSets.end())
|
| + return;
|
| +
|
| + InvalidationSet* invalidationSet = it->value.get();
|
| + if (invalidationSet->type() == InvalidateDescendants)
|
| + return;
|
| +
|
| + SiblingInvalidationSet* siblingSet = toSiblingInvalidationSet(invalidationSet);
|
| + TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblingSet, attributeChange, attributeName);
|
| + invalidationLists.siblings.append(siblingSet);
|
| +}
|
| +
|
| void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& invalidationLists, Element& element, CSSSelector::PseudoType pseudo) const
|
| {
|
| PseudoTypeInvalidationSetMap::const_iterator it = m_pseudoInvalidationSets.find(pseudo);
|
| @@ -784,6 +842,31 @@ void RuleFeatureSet::collectInvalidationSetsForPseudoClass(InvalidationLists& in
|
| }
|
| }
|
|
|
| +void RuleFeatureSet::collectUniversalSiblingInvalidationSet(InvalidationLists& invalidationLists) const
|
| +{
|
| + if (m_universalSiblingInvalidationSet)
|
| + invalidationLists.siblings.append(m_universalSiblingInvalidationSet);
|
| +}
|
| +
|
| +SiblingInvalidationSet& RuleFeatureSet::ensureUniversalSiblingInvalidationSet()
|
| +{
|
| + if (!m_universalSiblingInvalidationSet)
|
| + m_universalSiblingInvalidationSet = SiblingInvalidationSet::create(nullptr);
|
| + return *m_universalSiblingInvalidationSet;
|
| +}
|
| +
|
| +void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const InvalidationSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatures)
|
| +{
|
| + SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet();
|
| + addFeaturesToInvalidationSet(universalSet, siblingFeatures);
|
| + universalSet.updateMaxDirectAdjacentSelectors(siblingFeatures.maxDirectAdjacentSelectors);
|
| +
|
| + if (&siblingFeatures == &descendantFeatures)
|
| + universalSet.setInvalidatesSelf();
|
| + else
|
| + addFeaturesToInvalidationSet(universalSet.ensureSiblingDescendants(), descendantFeatures);
|
| +}
|
| +
|
| DEFINE_TRACE(RuleFeatureSet)
|
| {
|
| visitor->trace(siblingRules);
|
|
|