Index: Source/core/css/RuleFeature.cpp |
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp |
index bdc04544ce4e4a588c187dbca89a74e2ef7ea4b5..e14be9602943935eece6e7014cb0976d0e3b3163 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()) { |
+ // FIXME: next up: Tag. |
+ if (component->m_match == CSSSelector::Class || component->m_match == CSSSelector::Id || component->isAttributeSelector()) { |
if (!foundDescendantRelation) |
foundIdent = true; |
} else if (component->pseudoType() == CSSSelector::PseudoHost || component->pseudoType() == CSSSelector::PseudoAny) { |
@@ -165,6 +165,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; |
} |
@@ -262,6 +264,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); |
@@ -272,9 +283,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) |
@@ -314,15 +323,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; |
@@ -334,6 +338,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); |
@@ -348,6 +354,7 @@ void RuleFeatureSet::clear() |
m_metadata.clear(); |
m_classInvalidationSets.clear(); |
m_attributeInvalidationSets.clear(); |
+ m_idInvalidationSets.clear(); |
m_styleInvalidator.clearPendingInvalidations(); |
} |
@@ -398,6 +405,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)) |