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

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

Issue 220943002: Use invalidation sets for :hover, :active, and :focus. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added layout tests Created 6 years, 8 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: Source/core/css/RuleFeature.cpp
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp
index bca0970bc71b558ff69f5ec20adfc8c7c418899f..90bd6b4357903083cc30dbcdd73ca0c8cd6568ae 100644
--- a/Source/core/css/RuleFeature.cpp
+++ b/Source/core/css/RuleFeature.cpp
@@ -166,7 +166,7 @@ RuleFeatureSet::RuleFeatureSet()
{
}
-DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& selector)
+DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& selector, bool seenCombinator)
{
if (selector.m_match == CSSSelector::Class)
return &ensureClassInvalidationSet(selector.value());
@@ -174,6 +174,11 @@ DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSS
return &ensureAttributeInvalidationSet(selector.attribute().localName());
if (selector.m_match == CSSSelector::Id)
return &ensureIdInvalidationSet(selector.value());
+ if (seenCombinator && selector.m_match == CSSSelector::PseudoClass) {
+ CSSSelector::PseudoType pseudo = selector.pseudoType();
+ if (pseudo == CSSSelector::PseudoHover || pseudo == CSSSelector::PseudoActive || pseudo == CSSSelector::PseudoFocus)
+ return &ensurePseudoInvalidationSet(pseudo);
+ }
return 0;
}
@@ -200,7 +205,7 @@ const CSSSelector* RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelec
for (; lastSelector; lastSelector = lastSelector->tagHistory()) {
extractInvalidationSetFeature(*lastSelector, features);
// Initialize the entry in the invalidation set map, if supported.
- invalidationSetForSelector(*lastSelector);
+ invalidationSetForSelector(*lastSelector, false);
if (lastSelector->pseudoType() == CSSSelector::PseudoHost || lastSelector->pseudoType() == CSSSelector::PseudoAny) {
if (const CSSSelectorList* selectorList = lastSelector->selectorList()) {
for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
@@ -217,7 +222,7 @@ const CSSSelector* RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelec
void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, const InvalidationSetFeatures& features, bool wholeSubtree)
{
for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
- if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current)) {
+ if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current, true)) {
if (wholeSubtree) {
invalidationSet->setWholeSubtreeInvalid();
} else {
@@ -272,7 +277,7 @@ void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
if (m_targetedStyleRecalcEnabled)
mode = updateInvalidationSets(ruleData.selector());
- collectFeaturesFromSelector(ruleData.selector(), metadata, mode);
+ collectFeaturesFromSelector(ruleData.selector(), metadata, mode, false);
m_metadata.add(metadata);
if (metadata.foundSiblingSelector)
@@ -305,21 +310,29 @@ DescendantInvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicS
return *addResult.storedValue->value;
}
+DescendantInvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelector::PseudoType pseudoType)
+{
+ PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets.add(pseudoType, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = DescendantInvalidationSet::create();
+ return *addResult.storedValue->value;
+}
+
void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector)
{
- collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange);
+ collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange, false);
}
-void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
+void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode, bool seenCombinator)
{
unsigned maxDirectAdjacentSelectors = 0;
for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
- if (mode != AddFeatures && (current->m_match == CSSSelector::Class || current->m_match == CSSSelector::Id || current->isAttributeSelector())) {
- DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current);
- ASSERT(invalidationSet);
- if (mode == UseSubtreeStyleChange)
- invalidationSet->setWholeSubtreeInvalid();
+ if (mode != AddFeatures) {
+ if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current, seenCombinator)) {
+ if (mode == UseSubtreeStyleChange)
+ invalidationSet->setWholeSubtreeInvalid();
+ }
}
if (current->pseudoType() == CSSSelector::PseudoFirstLine)
metadata.usesFirstLineRules = true;
@@ -333,22 +346,24 @@ void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru
if (current->isSiblingSelector())
metadata.foundSiblingSelector = true;
- collectFeaturesFromSelectorList(current->selectorList(), metadata, mode);
+ collectFeaturesFromSelectorList(current->selectorList(), metadata, mode, seenCombinator);
- if (mode == UseLocalStyleChange && current->relation() != CSSSelector::SubSelector)
+ if (mode == UseLocalStyleChange && current->relation() != CSSSelector::SubSelector) {
+ seenCombinator = true;
mode = UseSubtreeStyleChange;
+ }
}
ASSERT(!maxDirectAdjacentSelectors);
}
-void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* selectorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
+void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* selectorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode, bool seenCombinator)
{
if (!selectorList)
return;
for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
- collectFeaturesFromSelector(*selector, metadata, mode);
+ collectFeaturesFromSelector(*selector, metadata, mode, seenCombinator);
}
void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other)
@@ -372,6 +387,8 @@ void RuleFeatureSet::add(const RuleFeatureSet& other)
ensureAttributeInvalidationSet(it->key).combine(*it->value);
for (InvalidationSetMap::const_iterator it = other.m_idInvalidationSets.begin(); it != other.m_idInvalidationSets.end(); ++it)
ensureIdInvalidationSet(it->key).combine(*it->value);
+ for (PseudoTypeInvalidationSetMap::const_iterator it = other.m_pseudoInvalidationSets.begin(); it != other.m_pseudoInvalidationSets.end(); ++it)
+ ensurePseudoInvalidationSet(static_cast<CSSSelector::PseudoType>(it->key)).combine(*it->value);
esprehn 2014/04/11 20:23:01 Why do you need the cast?
rune 2014/04/11 22:34:36 It's because of the use of IntHash: typedef Has
m_metadata.add(other.m_metadata);
@@ -452,6 +469,12 @@ void RuleFeatureSet::scheduleStyleInvalidationForIdChange(const AtomicString& ol
}
}
+void RuleFeatureSet::scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoType pseudo, Element& element)
+{
+ if (RefPtr<DescendantInvalidationSet> invalidationSet = m_pseudoInvalidationSets.get(pseudo))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
+}
+
void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element& element)
{
if (RefPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className))

Powered by Google App Engine
This is Rietveld 408576698