Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(651)

Unified Diff: third_party/WebKit/Source/core/css/RuleFeature.cpp

Issue 2683373003: RuleSet invalidations on single feature only, including tags. (Closed)
Patch Set: Trace type ruleset invalidation Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 31227852af3a4d175212a7e44d971750f30ffc63..20c25d92c6d56877a8b710bfaa97481e1ec7b2a5 100644
--- a/third_party/WebKit/Source/core/css/RuleFeature.cpp
+++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -347,18 +347,28 @@ void RuleFeatureSet::extractInvalidationSetFeaturesFromSimpleSelector(
if (selector.match() == CSSSelector::Tag &&
selector.tagQName().localName() != starAtom) {
features.tagNames.push_back(selector.tagQName().localName());
+ features.setRuleSetInvalidationFeature(
+ selector.tagQName().localName(),
+ InvalidationSetFeatures::RuleSetFeatureType::Tag);
return;
}
if (selector.match() == CSSSelector::Id) {
features.ids.push_back(selector.value());
+ features.setRuleSetInvalidationFeature(
+ selector.value(), InvalidationSetFeatures::RuleSetFeatureType::Id);
return;
}
if (selector.match() == CSSSelector::Class) {
features.classes.push_back(selector.value());
+ features.setRuleSetInvalidationFeature(
+ selector.value(), InvalidationSetFeatures::RuleSetFeatureType::Class);
return;
}
if (selector.isAttributeSelector()) {
features.attributes.push_back(selector.attribute().localName());
+ features.setRuleSetInvalidationFeature(
+ selector.attribute().localName(),
+ InvalidationSetFeatures::RuleSetFeatureType::Attribute);
return;
}
switch (selector.getPseudoType()) {
@@ -456,7 +466,7 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) {
Subject);
if (features.forceSubtree)
- features.hasFeaturesForRuleSetInvalidation = false;
+ features.clearRuleSetInvalidationFeature();
else if (!features.hasFeatures())
features.forceSubtree = true;
if (features.hasNthPseudo)
@@ -467,8 +477,7 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) {
const CSSSelector* nextCompound =
lastInCompound ? lastInCompound->tagHistory() : &ruleData.selector();
if (!nextCompound) {
- if (!features.hasFeaturesForRuleSetInvalidation)
- m_metadata.needsFullRecalcForRuleSetInvalidation = true;
+ processRuleSetInvalidationFeature(features);
return;
}
if (lastInCompound)
@@ -476,9 +485,45 @@ void RuleFeatureSet::updateInvalidationSets(const RuleData& ruleData) {
siblingFeatures, features);
addFeaturesToInvalidationSets(*nextCompound, siblingFeatures, features);
+ processRuleSetInvalidationFeature(features);
+}
+
+void RuleFeatureSet::processRuleSetInvalidationFeature(
+ const InvalidationSetFeatures& features) {
+ InvalidationSetMap* map = nullptr;
+ switch (features.ruleSetInvalidationFeatureType) {
+ case InvalidationSetFeatures::RuleSetFeatureType::None:
+ m_metadata.needsFullRecalcForRuleSetInvalidation = true;
+ return;
+ case InvalidationSetFeatures::RuleSetFeatureType::Tag: {
+ DescendantInvalidationSet& typeSet = ensureTypeRuleInvalidationSet();
+ typeSet.addTagName(features.ruleSetInvalidationFeature);
+ return;
+ }
+ case InvalidationSetFeatures::RuleSetFeatureType::Attribute:
+ map = &m_attributeInvalidationSets;
+ break;
+ case InvalidationSetFeatures::RuleSetFeatureType::Class:
+ map = &m_classInvalidationSets;
+ break;
+ case InvalidationSetFeatures::RuleSetFeatureType::Id:
+ map = &m_idInvalidationSets;
+ break;
+ }
- if (!features.hasFeaturesForRuleSetInvalidation)
- m_metadata.needsFullRecalcForRuleSetInvalidation = true;
+ DCHECK(map);
+ InvalidationSetMap::const_iterator it =
+ map->find(features.ruleSetInvalidationFeature);
+ if (it == map->end())
+ return;
+
+ DescendantInvalidationSet* descendants;
+ SiblingInvalidationSet* siblings;
+ extractInvalidationSets(it->value.get(), descendants, siblings);
+ if (descendants)
+ descendants->setAppliesToRuleSetInvalidations();
+ if (siblings)
+ siblings->setAppliesToRuleSetInvalidations();
}
void RuleFeatureSet::updateInvalidationSetsForContentAttribute(
@@ -550,7 +595,9 @@ RuleFeatureSet::extractInvalidationSetFeaturesFromSelectorList(
else
allSubSelectorsHaveFeatures = false;
}
- // Don't add any features if one of the sub-selectors of does not contain
+ if (!selectorList->hasOneSelector())
+ anyFeatures.clearRuleSetInvalidationFeature();
+ // Don't add any features if one of the sub-selectors does not contain
// any invalidation set features. E.g. :-webkit-any(*, span).
if (allSubSelectorsHaveFeatures)
features.add(anyFeatures);
@@ -607,8 +654,6 @@ const CSSSelector* RuleFeatureSet::extractInvalidationSetFeaturesFromCompound(
if (!simpleSelector->tagHistory() ||
simpleSelector->relation() != CSSSelector::SubSelector) {
- features.hasFeaturesForRuleSetInvalidation =
- features.hasTagIdClassOrAttribute();
return simpleSelector;
}
}
@@ -660,25 +705,24 @@ void RuleFeatureSet::addFeaturesToInvalidationSetsForSelectorList(
DCHECK(supportsInvalidationWithSelectorList(simpleSelector.getPseudoType()));
- bool hadFeaturesForRuleSetInvalidation =
- descendantFeatures.hasFeaturesForRuleSetInvalidation;
- bool selectorListContainsUniversal =
- simpleSelector.getPseudoType() == CSSSelector::PseudoNot ||
- simpleSelector.getPseudoType() == CSSSelector::PseudoHostContext;
+ AtomicString prevRuleSetFeature =
+ descendantFeatures.ruleSetInvalidationFeature;
+ InvalidationSetFeatures::RuleSetFeatureType prevRuleSetFeatureType =
+ descendantFeatures.ruleSetInvalidationFeatureType;
for (const CSSSelector* subSelector = simpleSelector.selectorList()->first();
subSelector; subSelector = CSSSelectorList::next(*subSelector)) {
- descendantFeatures.hasFeaturesForRuleSetInvalidation = false;
-
addFeaturesToInvalidationSetsForCompoundSelector(
*subSelector, siblingFeatures, descendantFeatures);
-
- if (!descendantFeatures.hasFeaturesForRuleSetInvalidation)
- selectorListContainsUniversal = true;
}
- descendantFeatures.hasFeaturesForRuleSetInvalidation =
- hadFeaturesForRuleSetInvalidation || !selectorListContainsUniversal;
+ if (simpleSelector.getPseudoType() == CSSSelector::PseudoNot ||
+ simpleSelector.getPseudoType() == CSSSelector::PseudoHostContext ||
+ !simpleSelector.selectorList()->hasOneSelector()) {
+ descendantFeatures.clearRuleSetInvalidationFeature();
+ descendantFeatures.setRuleSetInvalidationFeature(prevRuleSetFeature,
+ prevRuleSetFeatureType);
+ }
}
void RuleFeatureSet::addFeaturesToInvalidationSetsForSimpleSelector(
@@ -726,17 +770,17 @@ RuleFeatureSet::addFeaturesToInvalidationSetsForCompoundSelector(
for (; simpleSelector; simpleSelector = simpleSelector->tagHistory()) {
addFeaturesToInvalidationSetsForSimpleSelector(
*simpleSelector, siblingFeatures, descendantFeatures);
- if (simpleSelector->isIdClassOrAttributeSelector())
+ if (simpleSelector->isIdClassOrAttributeSelector()) {
+ descendantFeatures.setRuleSetFeatureFromSimpleSelector(*simpleSelector);
compoundHasIdClassOrAttribute = true;
+ }
if (simpleSelector->relation() != CSSSelector::SubSelector)
break;
if (!simpleSelector->tagHistory())
break;
}
- if (compoundHasIdClassOrAttribute)
- descendantFeatures.hasFeaturesForRuleSetInvalidation = true;
- else if (siblingFeatures)
+ if (!compoundHasIdClassOrAttribute && siblingFeatures)
addFeaturesToUniversalSiblingInvalidationSet(*siblingFeatures,
descendantFeatures);
@@ -933,7 +977,8 @@ void RuleFeatureSet::clear() {
void RuleFeatureSet::collectInvalidationSetsForClass(
InvalidationLists& invalidationLists,
Element& element,
- const AtomicString& className) const {
+ const AtomicString& className,
+ InvalidationSetFilter filter) const {
InvalidationSetMap::const_iterator it =
m_classInvalidationSets.find(className);
if (it == m_classInvalidationSets.end())
@@ -943,13 +988,15 @@ void RuleFeatureSet::collectInvalidationSetsForClass(
SiblingInvalidationSet* siblings;
extractInvalidationSets(it->value.get(), descendants, siblings);
- if (descendants) {
+ if (descendants && (filter == InvalidationSetFilter::None ||
+ descendants->appliesToRuleSetInvalidations())) {
TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, classChange,
className);
invalidationLists.descendants.push_back(descendants);
}
- if (siblings) {
+ if (siblings && (filter == InvalidationSetFilter::None ||
+ siblings->appliesToRuleSetInvalidations())) {
TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, classChange,
className);
invalidationLists.siblings.push_back(siblings);
@@ -983,7 +1030,8 @@ void RuleFeatureSet::collectSiblingInvalidationSetForClass(
void RuleFeatureSet::collectInvalidationSetsForId(
InvalidationLists& invalidationLists,
Element& element,
- const AtomicString& id) const {
+ const AtomicString& id,
+ InvalidationSetFilter filter) const {
InvalidationSetMap::const_iterator it = m_idInvalidationSets.find(id);
if (it == m_idInvalidationSets.end())
return;
@@ -992,12 +1040,14 @@ void RuleFeatureSet::collectInvalidationSetsForId(
SiblingInvalidationSet* siblings;
extractInvalidationSets(it->value.get(), descendants, siblings);
- if (descendants) {
+ if (descendants && (filter == InvalidationSetFilter::None ||
+ descendants->appliesToRuleSetInvalidations())) {
TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, idChange, id);
invalidationLists.descendants.push_back(descendants);
}
- if (siblings) {
+ if (siblings && (filter == InvalidationSetFilter::None ||
+ siblings->appliesToRuleSetInvalidations())) {
TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, idChange, id);
invalidationLists.siblings.push_back(siblings);
}
@@ -1028,7 +1078,8 @@ void RuleFeatureSet::collectSiblingInvalidationSetForId(
void RuleFeatureSet::collectInvalidationSetsForAttribute(
InvalidationLists& invalidationLists,
Element& element,
- const QualifiedName& attributeName) const {
+ const QualifiedName& attributeName,
+ InvalidationSetFilter filter) const {
InvalidationSetMap::const_iterator it =
m_attributeInvalidationSets.find(attributeName.localName());
if (it == m_attributeInvalidationSets.end())
@@ -1038,13 +1089,15 @@ void RuleFeatureSet::collectInvalidationSetsForAttribute(
SiblingInvalidationSet* siblings;
extractInvalidationSets(it->value.get(), descendants, siblings);
- if (descendants) {
+ if (descendants && (filter == InvalidationSetFilter::None ||
+ descendants->appliesToRuleSetInvalidations())) {
TRACE_SCHEDULE_STYLE_INVALIDATION(element, *descendants, attributeChange,
attributeName);
invalidationLists.descendants.push_back(descendants);
}
- if (siblings) {
+ if (siblings && (filter == InvalidationSetFilter::None ||
+ siblings->appliesToRuleSetInvalidations())) {
TRACE_SCHEDULE_STYLE_INVALIDATION(element, *siblings, attributeChange,
attributeName);
invalidationLists.siblings.push_back(siblings);
@@ -1128,6 +1181,24 @@ DescendantInvalidationSet& RuleFeatureSet::ensureNthInvalidationSet() {
return *m_nthInvalidationSet;
}
+void RuleFeatureSet::collectTypeRuleInvalidationSet(
+ InvalidationLists& invalidationLists,
+ ContainerNode& rootNode) const {
+ if (m_typeRuleInvalidationSet) {
+ invalidationLists.descendants.push_back(m_typeRuleInvalidationSet);
+ TRACE_SCHEDULE_STYLE_INVALIDATION(rootNode, *m_typeRuleInvalidationSet,
+ typeInvalidation);
+ }
+}
+
+DescendantInvalidationSet& RuleFeatureSet::ensureTypeRuleInvalidationSet() {
+ if (!m_typeRuleInvalidationSet) {
+ m_typeRuleInvalidationSet = DescendantInvalidationSet::create();
+ m_typeRuleInvalidationSet->setAppliesToRuleSetInvalidations();
+ }
+ return *m_typeRuleInvalidationSet;
+}
+
void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(
const InvalidationSetFeatures& siblingFeatures,
const InvalidationSetFeatures& descendantFeatures) {
@@ -1167,6 +1238,8 @@ void RuleFeatureSet::InvalidationSetFeatures::add(
contentPseudoCrossing |= other.contentPseudoCrossing;
invalidatesSlotted |= other.invalidatesSlotted;
hasNthPseudo |= other.hasNthPseudo;
+ setRuleSetInvalidationFeature(other.ruleSetInvalidationFeature,
+ other.ruleSetInvalidationFeatureType);
}
bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const {
@@ -1174,9 +1247,19 @@ bool RuleFeatureSet::InvalidationSetFeatures::hasFeatures() const {
!tagNames.isEmpty() || customPseudoElement;
}
-bool RuleFeatureSet::InvalidationSetFeatures::hasTagIdClassOrAttribute() const {
- return !classes.isEmpty() || !attributes.isEmpty() || !ids.isEmpty() ||
- !tagNames.isEmpty();
+void RuleFeatureSet::InvalidationSetFeatures::
+ setRuleSetFeatureFromSimpleSelector(const CSSSelector& selector) {
+ if (selector.match() == CSSSelector::Id) {
+ setRuleSetInvalidationFeature(selector.value(), RuleSetFeatureType::Id);
+ return;
+ }
+ if (selector.match() == CSSSelector::Class) {
+ setRuleSetInvalidationFeature(selector.value(), RuleSetFeatureType::Class);
+ return;
+ }
+ DCHECK(selector.isAttributeSelector());
+ setRuleSetInvalidationFeature(selector.attribute().localName(),
+ RuleSetFeatureType::Attribute);
}
} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/css/RuleFeature.h ('k') | third_party/WebKit/Source/core/css/RuleFeatureSetTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698