Chromium Code Reviews| 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)) |