| 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))
|
|
|