Index: Source/core/css/RuleFeature.cpp |
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp |
index 33b5ed35496d04b053c91f7e56daef4bafc9844e..a767562d88f6348c21cd985e3708b8be866a4949 100644 |
--- a/Source/core/css/RuleFeature.cpp |
+++ b/Source/core/css/RuleFeature.cpp |
@@ -109,8 +109,8 @@ RuleFeatureSet::InvalidationSetMode RuleFeatureSet::supportsClassDescendantInval |
bool foundIdent = false; |
for (const CSSSelector* component = &selector; component; component = component->tagHistory()) { |
- // FIXME: next up: Tag and Id. |
- if (component->m_match == CSSSelector::Class || component->isAttributeSelector() || component->isCustomPseudoElement()) { |
+ // FIXME: next up: Tag. |
+ if (component->m_match == CSSSelector::Class || component->m_match == CSSSelector::Id || component->isAttributeSelector() || component->isCustomPseudoElement()) { |
if (!foundDescendantRelation) |
foundIdent = true; |
} else if (component->pseudoType() == CSSSelector::PseudoHost || component->pseudoType() == CSSSelector::PseudoAny) { |
@@ -167,6 +167,8 @@ DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSS |
return &ensureClassInvalidationSet(selector.value()); |
if (selector.isAttributeSelector()) |
return &ensureAttributeInvalidationSet(selector.attribute().localName()); |
+ if (selector.m_match == CSSSelector::Id) |
+ return &ensureIdInvalidationSet(selector.value()); |
return 0; |
} |
@@ -266,6 +268,15 @@ DescendantInvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet(const |
addResult.storedValue->value = DescendantInvalidationSet::create(); |
return *addResult.storedValue->value; |
} |
+ |
+DescendantInvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicString& id) |
+{ |
+ InvalidationSetMap::AddResult addResult = m_idInvalidationSets.add(id, nullptr); |
+ if (addResult.isNewEntry) |
+ addResult.storedValue->value = DescendantInvalidationSet::create(); |
+ return *addResult.storedValue->value; |
+} |
+ |
void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector) |
{ |
collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange); |
@@ -276,9 +287,7 @@ void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, Ru |
unsigned maxDirectAdjacentSelectors = 0; |
for (const CSSSelector* current = &selector; current; current = current->tagHistory()) { |
- if (current->m_match == CSSSelector::Id) { |
- metadata.idsInRules.add(current->value()); |
- } else if (mode != AddFeatures && (current->m_match == CSSSelector::Class || current->isAttributeSelector())) { |
+ if (mode != AddFeatures && (current->m_match == CSSSelector::Class || current->m_match == CSSSelector::Id || current->isAttributeSelector())) { |
DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current); |
ASSERT(invalidationSet); |
if (mode == UseSubtreeStyleChange) |
@@ -318,15 +327,10 @@ void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other) |
{ |
usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules; |
maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxDirectAdjacentSelectors); |
- |
- HashSet<AtomicString>::const_iterator end = other.idsInRules.end(); |
- for (HashSet<AtomicString>::const_iterator it = other.idsInRules.begin(); it != end; ++it) |
- idsInRules.add(*it); |
} |
void RuleFeatureSet::FeatureMetadata::clear() |
{ |
- idsInRules.clear(); |
usesFirstLineRules = false; |
foundSiblingSelector = false; |
maxDirectAdjacentSelectors = 0; |
@@ -338,6 +342,8 @@ void RuleFeatureSet::add(const RuleFeatureSet& other) |
ensureClassInvalidationSet(it->key).combine(*it->value); |
for (InvalidationSetMap::const_iterator it = other.m_attributeInvalidationSets.begin(); it != other.m_attributeInvalidationSets.end(); ++it) |
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); |
m_metadata.add(other.m_metadata); |
@@ -352,6 +358,7 @@ void RuleFeatureSet::clear() |
m_metadata.clear(); |
m_classInvalidationSets.clear(); |
m_attributeInvalidationSets.clear(); |
+ m_idInvalidationSets.clear(); |
m_styleInvalidator.clearPendingInvalidations(); |
} |
@@ -402,6 +409,18 @@ void RuleFeatureSet::scheduleStyleInvalidationForAttributeChange(const Qualified |
m_styleInvalidator.scheduleInvalidation(invalidationSet, element); |
} |
+void RuleFeatureSet::scheduleStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, Element& element) |
+{ |
+ if (!oldId.isEmpty()) { |
+ if (RefPtr<DescendantInvalidationSet> invalidationSet = m_idInvalidationSets.get(oldId)) |
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element); |
+ } |
+ if (!newId.isEmpty()) { |
+ if (RefPtr<DescendantInvalidationSet> invalidationSet = m_idInvalidationSets.get(newId)) |
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element); |
+ } |
+} |
+ |
void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element& element) |
{ |
if (RefPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className)) |