Index: Source/core/css/RuleFeature.cpp |
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp |
index 0009922b77b2e9249db2f5d88519047305447a20..ff2101d9332d2eaf422a3ae2c975b87aaa88e1ce 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,14 @@ DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSS |
return &ensureAttributeInvalidationSet(selector.attribute().localName()); |
if (selector.m_match == CSSSelector::Id) |
return &ensureIdInvalidationSet(selector.value()); |
+ if (seenCombinator) { |
+ if (selector.pseudoType() == CSSSelector::PseudoHover) |
+ return &ensureHoverInvalidationSet(); |
esprehn
2014/04/04 22:48:27
Lets use a HashMap<CSSSelector::PseudoType, Descen
rune
2014/04/08 16:28:25
Done.
|
+ if (selector.pseudoType() == CSSSelector::PseudoActive) |
+ return &ensureActiveInvalidationSet(); |
+ if (selector.pseudoType() == CSSSelector::PseudoFocus) |
+ return &ensureFocusInvalidationSet(); |
+ } |
return 0; |
} |
@@ -200,7 +208,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 +225,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 +280,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 +313,42 @@ DescendantInvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicS |
return *addResult.storedValue->value; |
} |
+DescendantInvalidationSet& RuleFeatureSet::ensureHoverInvalidationSet() |
+{ |
+ if (!m_hoverInvalidationSet) |
+ m_hoverInvalidationSet = DescendantInvalidationSet::create(); |
+ return *m_hoverInvalidationSet; |
+} |
+ |
+DescendantInvalidationSet& RuleFeatureSet::ensureActiveInvalidationSet() |
+{ |
+ if (!m_activeInvalidationSet) |
+ m_activeInvalidationSet = DescendantInvalidationSet::create(); |
+ return *m_activeInvalidationSet; |
+} |
+ |
+DescendantInvalidationSet& RuleFeatureSet::ensureFocusInvalidationSet() |
+{ |
+ if (!m_focusInvalidationSet) |
+ m_focusInvalidationSet = DescendantInvalidationSet::create(); |
+ return *m_focusInvalidationSet; |
+} |
+ |
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 +362,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) |
@@ -373,6 +404,13 @@ void RuleFeatureSet::add(const RuleFeatureSet& other) |
for (InvalidationSetMap::const_iterator it = other.m_idInvalidationSets.begin(); it != other.m_idInvalidationSets.end(); ++it) |
ensureIdInvalidationSet(it->key).combine(*it->value); |
+ if (other.m_hoverInvalidationSet) |
+ ensureHoverInvalidationSet().combine(*other.m_hoverInvalidationSet); |
+ if (other.m_activeInvalidationSet) |
+ ensureActiveInvalidationSet().combine(*other.m_activeInvalidationSet); |
+ if (other.m_focusInvalidationSet) |
+ ensureFocusInvalidationSet().combine(*other.m_focusInvalidationSet); |
+ |
m_metadata.add(other.m_metadata); |
siblingRules.appendVector(other.siblingRules); |
@@ -449,6 +487,24 @@ void RuleFeatureSet::scheduleStyleInvalidationForIdChange(const AtomicString& ol |
} |
} |
+void RuleFeatureSet::scheduleStyleInvalidationForHoverChange(Element& element) |
+{ |
+ if (m_hoverInvalidationSet) |
+ m_styleInvalidator.scheduleInvalidation(m_hoverInvalidationSet, element); |
+} |
+ |
+void RuleFeatureSet::scheduleStyleInvalidationForActiveChange(Element& element) |
+{ |
+ if (m_activeInvalidationSet) |
+ m_styleInvalidator.scheduleInvalidation(m_activeInvalidationSet, element); |
+} |
+ |
+void RuleFeatureSet::scheduleStyleInvalidationForFocusChange(Element& element) |
+{ |
+ if (m_focusInvalidationSet) |
+ m_styleInvalidator.scheduleInvalidation(m_focusInvalidationSet, element); |
+} |
+ |
void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element& element) |
{ |
if (RefPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className)) |