Diff
Modified: trunk/Source/WebCore/ChangeLog (286597 => 286598)
--- trunk/Source/WebCore/ChangeLog 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/ChangeLog 2021-12-07 17:49:42 UTC (rev 286598)
@@ -1,3 +1,63 @@
+2021-12-07 Antti Koivisto <[email protected]>
+
+ Use more specific keys for pseudo-class invalidation
+ https://bugs.webkit.org/show_bug.cgi?id=233883
+
+ Reviewed by Simon Fraser.
+
+ Currently pseudo-class invalidation is keyed with pseudo-class type only. If we have rule like
+
+ .foo:hover { ... }
+
+ we end up considering this rule for every element whenever :hover state changes, whether the element has class 'foo' or not.
+
+ We can improve this by keying pseudo-class invalidation more narrowly with type/class, type/id or type/tag pairs.
+
+ * css/CSSSelector.cpp:
+ (WebCore::CSSSelector::CSSSelector):
+ (WebCore::CSSSelector::firstInCompound const):
+
+ Add a function to find the start of a compound selector.
+
+ * css/CSSSelector.h:
+ (WebCore::CSSSelector::tagHistory const):
+ (WebCore::CSSSelector::isFirstInTagHistory const):
+ (WebCore::CSSSelector::setNotFirstInTagHistory):
+
+ Add isFirstInTagHistory bit, similar to the isLastInTagHistory bit, to enable firstInCompound.
+
+ (WebCore::CSSSelector::CSSSelector):
+ * css/CSSSelectorList.cpp:
+ (WebCore::CSSSelectorList::CSSSelectorList):
+
+ Set the bit.
+
+ * style/PseudoClassChangeInvalidation.cpp:
+ (WebCore::Style::makePseudoClassInvalidationKeys):
+
+ Collect the id, tag and classes from the element and make keys out of them.
+
+ (WebCore::Style::PseudoClassChangeInvalidation::computeInvalidation):
+ (WebCore::Style::PseudoClassChangeInvalidation::collectRuleSets):
+
+ Use the keys to look up for matching invalidation rulesets.
+
+ * style/PseudoClassChangeInvalidation.h:
+ * style/RuleFeature.cpp:
+ (WebCore::Style::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):
+ (WebCore::Style::makePseudoClassInvalidationKey):
+
+ Make a key out of a selector.
+ Search the compound for id, classes or tag.
+
+ (WebCore::Style::RuleFeatureSet::collectFeatures):
+ (WebCore::Style::RuleFeatureSet::add):
+ (WebCore::Style::RuleFeatureSet::clear):
+ * style/RuleFeature.h:
+ * style/StyleScopeRuleSets.cpp:
+ (WebCore::Style::ScopeRuleSets::pseudoClassInvalidationRuleSets const):
+ * style/StyleScopeRuleSets.h:
+
2021-12-07 Kimmo Kinnunen <[email protected]>
Cocoa WebGL should support UI side compositing
Modified: trunk/Source/WebCore/css/CSSSelector.cpp (286597 => 286598)
--- trunk/Source/WebCore/css/CSSSelector.cpp 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/css/CSSSelector.cpp 2021-12-07 17:49:42 UTC (rev 286598)
@@ -56,6 +56,7 @@
, m_match(Tag)
, m_pseudoType(0)
, m_isLastInSelectorList(false)
+ , m_isFirstInTagHistory(true)
, m_isLastInTagHistory(true)
, m_hasRareData(false)
, m_hasNameWithCase(false)
@@ -288,6 +289,18 @@
return type;
}
+const CSSSelector* CSSSelector::firstInCompound() const
+{
+ auto* selector = this;
+ while (!selector->isFirstInTagHistory()) {
+ auto* previousSelector = selector - 1;
+ if (previousSelector->relation() != Subselector)
+ break;
+ selector = previousSelector;
+ }
+ return selector;
+}
+
bool CSSSelector::operator==(const CSSSelector& other) const
{
const CSSSelector* sel1 = this;
Modified: trunk/Source/WebCore/css/CSSSelector.h (286597 => 286598)
--- trunk/Source/WebCore/css/CSSSelector.h 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/css/CSSSelector.h 2021-12-07 17:49:42 UTC (rev 286598)
@@ -253,7 +253,8 @@
// Selectors are kept in an array by CSSSelectorList. The next component of the selector is
// the next item in the array.
- const CSSSelector* tagHistory() const { return m_isLastInTagHistory ? 0 : const_cast<CSSSelector*>(this + 1); }
+ const CSSSelector* tagHistory() const { return m_isLastInTagHistory ? nullptr : this + 1; }
+ const CSSSelector* firstInCompound() const;
const QualifiedName& tagQName() const;
const AtomString& tagLowercaseLocalName() const;
@@ -339,7 +340,9 @@
bool isLastInSelectorList() const { return m_isLastInSelectorList; }
void setLastInSelectorList() { m_isLastInSelectorList = true; }
+ bool isFirstInTagHistory() const { return m_isFirstInTagHistory; }
bool isLastInTagHistory() const { return m_isLastInTagHistory; }
+ void setNotFirstInTagHistory() { m_isFirstInTagHistory = false; }
void setNotLastInTagHistory() { m_isLastInTagHistory = false; }
bool isForPage() const { return m_isForPage; }
@@ -350,6 +353,7 @@
mutable unsigned m_match : 4; // enum Match.
mutable unsigned m_pseudoType : 8; // PseudoType.
unsigned m_isLastInSelectorList : 1;
+ unsigned m_isFirstInTagHistory : 1;
unsigned m_isLastInTagHistory : 1;
unsigned m_hasRareData : 1;
unsigned m_hasNameWithCase : 1;
@@ -468,6 +472,21 @@
return pseudoClassIsRelativeToSiblings(type) || type == CSSSelector::PseudoClassRoot;
}
+inline bool isLogicalCombinationPseudoClass(CSSSelector::PseudoClassType pseudoClassType)
+{
+ switch (pseudoClassType) {
+ case CSSSelector::PseudoClassIs:
+ case CSSSelector::PseudoClassWhere:
+ case CSSSelector::PseudoClassNot:
+ case CSSSelector::PseudoClassAny:
+ case CSSSelector::PseudoClassMatches:
+ case CSSSelector::PseudoClassHas:
+ return true;
+ default:
+ return false;
+ }
+}
+
inline bool CSSSelector::isSiblingSelector() const
{
return relation() == DirectAdjacent
@@ -511,6 +530,7 @@
, m_match(Unknown)
, m_pseudoType(0)
, m_isLastInSelectorList(false)
+ , m_isFirstInTagHistory(true)
, m_isLastInTagHistory(true)
, m_hasRareData(false)
, m_hasNameWithCase(false)
@@ -528,6 +548,7 @@
, m_match(o.m_match)
, m_pseudoType(o.m_pseudoType)
, m_isLastInSelectorList(o.m_isLastInSelectorList)
+ , m_isFirstInTagHistory(o.m_isFirstInTagHistory)
, m_isLastInTagHistory(o.m_isLastInTagHistory)
, m_hasRareData(o.m_hasRareData)
, m_hasNameWithCase(o.m_hasNameWithCase)
Modified: trunk/Source/WebCore/css/CSSSelectorList.cpp (286597 => 286598)
--- trunk/Source/WebCore/css/CSSSelectorList.cpp 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/css/CSSSelectorList.cpp 2021-12-07 17:49:42 UTC (rev 286598)
@@ -55,7 +55,8 @@
m_selectorArray = makeUniqueArray<CSSSelector>(flattenedSize);
size_t arrayIndex = 0;
for (size_t i = 0; i < selectorVector.size(); ++i) {
- CSSParserSelector* current = selectorVector[i].get();
+ CSSParserSelector* first = selectorVector[i].get();
+ CSSParserSelector* current = first;
while (current) {
{
// Move item from the parser selector vector into m_selectorArray without invoking destructor (Ugh.)
@@ -65,6 +66,8 @@
// Free the underlying memory without invoking the destructor.
operator delete (currentSelector);
}
+ if (current != first)
+ m_selectorArray[arrayIndex].setNotFirstInTagHistory();
current = current->tagHistory();
ASSERT(!m_selectorArray[arrayIndex].isLastInSelectorList());
if (current)
Modified: trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp (286597 => 286598)
--- trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/css/parser/CSSSelectorParser.cpp 2021-12-07 17:49:42 UTC (rev 286598)
@@ -320,21 +320,6 @@
}
}
-static bool isLogicalCombinationPseudoClass(CSSSelector::PseudoClassType pseudo)
-{
- switch (pseudo) {
- case CSSSelector::PseudoClassIs:
- case CSSSelector::PseudoClassWhere:
- case CSSSelector::PseudoClassNot:
- case CSSSelector::PseudoClassAny:
- case CSSSelector::PseudoClassMatches:
- case CSSSelector::PseudoClassHas:
- return true;
- default:
- return false;
- }
-}
-
static bool isPseudoClassValidAfterPseudoElement(CSSSelector::PseudoClassType pseudoClass, CSSSelector::PseudoElementType compoundPseudoElement)
{
// Validity of these is determined by their content.
Modified: trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp (286597 => 286598)
--- trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp 2021-12-07 17:49:42 UTC (rev 286598)
@@ -32,6 +32,25 @@
namespace WebCore {
namespace Style {
+static Vector<PseudoClassInvalidationKey, 4> makePseudoClassInvalidationKeys(CSSSelector::PseudoClassType pseudoClass, const Element& element)
+{
+ Vector<PseudoClassInvalidationKey, 4> keys;
+
+ if (!element.idForStyleResolution().isEmpty())
+ keys.append(makePseudoClassInvalidationKey(pseudoClass, InvalidationKeyType::Id, element.idForStyleResolution()));
+
+ if (element.hasClass()) {
+ auto classCount = element.classNames().size();
+ for (size_t i = 0; i < classCount; ++i)
+ keys.append(makePseudoClassInvalidationKey(pseudoClass, InvalidationKeyType::Class, element.classNames()[i]));
+ }
+
+ keys.append(makePseudoClassInvalidationKey(pseudoClass, InvalidationKeyType::Tag, element.localName().convertToASCIILowercase()));
+ keys.append(makePseudoClassInvalidationKey(pseudoClass, InvalidationKeyType::Universal));
+
+ return keys;
+};
+
void PseudoClassChangeInvalidation::computeInvalidation(CSSSelector::PseudoClassType pseudoClass, InvalidationScope invalidationScope)
{
bool shouldInvalidateCurrent = false;
@@ -38,7 +57,7 @@
bool mayAffectStyleInShadowTree = false;
traverseRuleFeatures(m_element, [&] (const RuleFeatureSet& features, bool mayAffectShadowTree) {
- if (mayAffectShadowTree && features.pseudoClassRules.contains(pseudoClass))
+ if (mayAffectShadowTree && features.pseudoClassTypes.contains(pseudoClass))
mayAffectStyleInShadowTree = true;
if (m_element.shadowRoot() && features.pseudoClassesAffectingHost.contains(pseudoClass))
shouldInvalidateCurrent = true;
@@ -52,26 +71,36 @@
if (shouldInvalidateCurrent)
m_element.invalidateStyle();
+ for (auto& key : makePseudoClassInvalidationKeys(pseudoClass, m_element))
+ collectRuleSets(key, invalidationScope);
+}
+
+void PseudoClassChangeInvalidation::collectRuleSets(const PseudoClassInvalidationKey& key, InvalidationScope invalidationScope)
+{
auto& ruleSets = m_element.styleResolver().ruleSets();
- if (auto* invalidationRuleSets = ruleSets.pseudoClassInvalidationRuleSets(pseudoClass)) {
- for (auto& invalidationRuleSet : *invalidationRuleSets) {
- // For focus/hover we flip the whole ancestor chain. We only need to do deep invalidation traversal in the change root.
- auto shouldInvalidate = [&] {
- switch (invalidationScope) {
- case InvalidationScope::All:
- return true;
- case InvalidationScope::SelfChildrenAndSiblings:
- return invalidationRuleSet.matchElement != MatchElement::Ancestor;
- case InvalidationScope::Descendants:
- return invalidationRuleSet.matchElement == MatchElement::Ancestor;
- }
- ASSERT_NOT_REACHED();
+ auto* invalidationRuleSets = ruleSets.pseudoClassInvalidationRuleSets(key);
+ if (!invalidationRuleSets)
+ return;
+
+ for (auto& invalidationRuleSet : *invalidationRuleSets) {
+ // For focus/hover we flip the whole ancestor chain. We only need to do deep invalidation traversal in the change root.
+ auto shouldInvalidate = [&] {
+ bool invalidatesAllDescendants = invalidationRuleSet.matchElement == MatchElement::Ancestor && isUniversalInvalidation(key);
+ switch (invalidationScope) {
+ case InvalidationScope::All:
return true;
- }();
- if (!shouldInvalidate)
- continue;
- Invalidator::addToMatchElementRuleSets(m_matchElementRuleSets, invalidationRuleSet);
- }
+ case InvalidationScope::SelfChildrenAndSiblings:
+ return !invalidatesAllDescendants;
+ case InvalidationScope::Descendants:
+ return invalidatesAllDescendants;
+ }
+ ASSERT_NOT_REACHED();
+ return true;
+ }();
+ if (!shouldInvalidate)
+ continue;
+
+ Invalidator::addToMatchElementRuleSets(m_matchElementRuleSets, invalidationRuleSet);
}
}
Modified: trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h (286597 => 286598)
--- trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h 2021-12-07 17:49:42 UTC (rev 286598)
@@ -40,6 +40,7 @@
private:
void computeInvalidation(CSSSelector::PseudoClassType, Style::InvalidationScope);
+ void collectRuleSets(const PseudoClassInvalidationKey&, InvalidationScope);
void invalidateStyleWithRuleSets();
const bool m_isEnabled;
Modified: trunk/Source/WebCore/style/RuleFeature.cpp (286597 => 286598)
--- trunk/Source/WebCore/style/RuleFeature.cpp 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/style/RuleFeature.cpp 2021-12-07 17:49:42 UTC (rev 286598)
@@ -226,8 +226,10 @@
default:
break;
}
- } else if (selector->match() == CSSSelector::PseudoClass)
- selectorFeatures.pseudoClasses.append(std::make_pair(selector->pseudoClassType(), matchElement));
+ } else if (selector->match() == CSSSelector::PseudoClass) {
+ if (!isLogicalCombinationPseudoClass(selector->pseudoClassType()))
+ selectorFeatures.pseudoClasses.append(std::make_pair(selector, matchElement));
+ }
if (!selectorFeatures.hasSiblingSelector && selector->isSiblingSelector())
selectorFeatures.hasSiblingSelector = true;
@@ -247,6 +249,46 @@
} while (selector);
}
+PseudoClassInvalidationKey makePseudoClassInvalidationKey(CSSSelector::PseudoClassType pseudoClass, InvalidationKeyType keyType, const AtomString& keyString)
+{
+ ASSERT(keyType != InvalidationKeyType::Universal || keyString == starAtom());
+ return {
+ pseudoClass,
+ static_cast<uint8_t>(keyType),
+ keyString
+ };
+};
+
+static PseudoClassInvalidationKey makePseudoClassInvalidationKey(const CSSSelector& selector)
+{
+ ASSERT(selector.match() == CSSSelector::PseudoClass);
+
+ auto pseudoClassType = selector.pseudoClassType();
+
+ AtomString className;
+ AtomString tagName;
+ for (auto* simpleSelector = selector.firstInCompound(); simpleSelector; simpleSelector = simpleSelector->tagHistory()) {
+ if (simpleSelector->match() == CSSSelector::Id)
+ return makePseudoClassInvalidationKey(pseudoClassType, InvalidationKeyType::Id, simpleSelector->value());
+
+ if (simpleSelector->match() == CSSSelector::Class && className.isNull())
+ className = simpleSelector->value();
+
+ if (simpleSelector->match() == CSSSelector::Tag)
+ tagName = simpleSelector->tagLowercaseLocalName();
+
+ if (simpleSelector->relation() != CSSSelector::Subselector)
+ break;
+ }
+ if (!className.isEmpty())
+ return makePseudoClassInvalidationKey(pseudoClassType, InvalidationKeyType::Class, className);
+
+ if (!tagName.isEmpty() && tagName != starAtom())
+ return makePseudoClassInvalidationKey(pseudoClassType, InvalidationKeyType::Tag, tagName);
+
+ return makePseudoClassInvalidationKey(selector.pseudoClassType(), InvalidationKeyType::Universal);
+};
+
void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
{
SelectorFeatures selectorFeatures;
@@ -287,7 +329,19 @@
setUsesMatchElement(matchElement);
}
- addToMap(pseudoClassRules, selectorFeatures.pseudoClasses, &pseudoClassesAffectingHost);
+ for (auto& selectorAndMatch : selectorFeatures.pseudoClasses) {
+ auto* selector = selectorAndMatch.first;
+ auto matchElement = selectorAndMatch.second;
+ pseudoClassRules.ensure(makePseudoClassInvalidationKey(*selector), [] {
+ return makeUnique<Vector<RuleFeature>>();
+ }).iterator->value->append({ ruleData, matchElement });
+
+ if (matchElement == MatchElement::Host)
+ pseudoClassesAffectingHost.add(selector->pseudoClassType());
+ pseudoClassTypes.add(selector->pseudoClassType());
+
+ setUsesMatchElement(matchElement);
+ }
}
void RuleFeatureSet::add(const RuleFeatureSet& other)
@@ -319,6 +373,7 @@
addMap(pseudoClassRules, other.pseudoClassRules);
pseudoClassesAffectingHost.add(other.pseudoClassesAffectingHost.begin(), other.pseudoClassesAffectingHost.end());
+ pseudoClassTypes.add(other.pseudoClassTypes.begin(), other.pseudoClassTypes.end());
for (size_t i = 0; i < usedMatchElements.size(); ++i)
usedMatchElements[i] = usedMatchElements[i] || other.usedMatchElements[i];
@@ -351,6 +406,7 @@
attributesAffectingHost.clear();
pseudoClassRules.clear();
pseudoClassesAffectingHost.clear();
+ pseudoClassTypes.clear();
usesFirstLineRules = false;
usesFirstLetterRules = false;
}
Modified: trunk/Source/WebCore/style/RuleFeature.h (286597 => 286598)
--- trunk/Source/WebCore/style/RuleFeature.h 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/style/RuleFeature.h 2021-12-07 17:49:42 UTC (rev 286598)
@@ -74,6 +74,8 @@
const CSSSelector* invalidationSelector { nullptr };
};
+using PseudoClassInvalidationKey = std::tuple<unsigned, uint8_t, AtomString>;
+
using RuleFeatureVector = Vector<RuleFeature>;
struct RuleFeatureSet {
@@ -98,10 +100,11 @@
HashMap<AtomString, std::unique_ptr<RuleFeatureVector>> idRules;
HashMap<AtomString, std::unique_ptr<RuleFeatureVector>> classRules;
HashMap<AtomString, std::unique_ptr<Vector<RuleFeatureWithInvalidationSelector>>> attributeRules;
- HashMap<CSSSelector::PseudoClassType, std::unique_ptr<RuleFeatureVector>, IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> pseudoClassRules;
+ HashMap<PseudoClassInvalidationKey, std::unique_ptr<RuleFeatureVector>> pseudoClassRules;
HashSet<AtomString> classesAffectingHost;
HashSet<AtomString> attributesAffectingHost;
HashSet<CSSSelector::PseudoClassType, IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> pseudoClassesAffectingHost;
+ HashSet<CSSSelector::PseudoClassType, IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> pseudoClassTypes;
std::array<bool, matchElementCount> usedMatchElements { };
@@ -116,7 +119,7 @@
Vector<std::pair<AtomString, MatchElement>, 32> ids;
Vector<std::pair<AtomString, MatchElement>, 32> classes;
Vector<std::pair<const CSSSelector*, MatchElement>, 32> attributes;
- Vector<std::pair<CSSSelector::PseudoClassType, MatchElement>, 32> pseudoClasses;
+ Vector<std::pair<const CSSSelector*, MatchElement>, 32> pseudoClasses;
};
void recursivelyCollectFeaturesFromSelector(SelectorFeatures&, const CSSSelector&, MatchElement = MatchElement::Subject);
};
@@ -124,5 +127,13 @@
bool isHasPseudoClassMatchElement(MatchElement);
MatchElement computeHasPseudoClassMatchElement(const CSSSelector&);
+enum class InvalidationKeyType : uint8_t { Universal = 1, Class, Id, Tag };
+PseudoClassInvalidationKey makePseudoClassInvalidationKey(CSSSelector::PseudoClassType, InvalidationKeyType, const AtomString& = starAtom());
+
+inline bool isUniversalInvalidation(const PseudoClassInvalidationKey& key)
+{
+ return static_cast<InvalidationKeyType>(std::get<1>(key)) == InvalidationKeyType::Universal;
+}
+
} // namespace Style
} // namespace WebCore
Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.cpp (286597 => 286598)
--- trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2021-12-07 17:49:42 UTC (rev 286598)
@@ -295,9 +295,9 @@
return ensureInvalidationRuleSets(attributeName, m_attributeInvalidationRuleSets, m_features.attributeRules);
}
-const Vector<InvalidationRuleSet>* ScopeRuleSets::pseudoClassInvalidationRuleSets(CSSSelector::PseudoClassType pseudoClass) const
+const Vector<InvalidationRuleSet>* ScopeRuleSets::pseudoClassInvalidationRuleSets(const PseudoClassInvalidationKey& pseudoClassKey) const
{
- return ensureInvalidationRuleSets(pseudoClass, m_pseudoClassInvalidationRuleSets, m_features.pseudoClassRules);
+ return ensureInvalidationRuleSets(pseudoClassKey, m_pseudoClassInvalidationRuleSets, m_features.pseudoClassRules);
}
bool ScopeRuleSets::hasComplexSelectorsForStyleAttribute() const
Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.h (286597 => 286598)
--- trunk/Source/WebCore/style/StyleScopeRuleSets.h 2021-12-07 16:56:04 UTC (rev 286597)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.h 2021-12-07 17:49:42 UTC (rev 286598)
@@ -67,7 +67,7 @@
const Vector<InvalidationRuleSet>* idInvalidationRuleSets(const AtomString&) const;
const Vector<InvalidationRuleSet>* classInvalidationRuleSets(const AtomString&) const;
const Vector<InvalidationRuleSet>* attributeInvalidationRuleSets(const AtomString&) const;
- const Vector<InvalidationRuleSet>* pseudoClassInvalidationRuleSets(CSSSelector::PseudoClassType) const;
+ const Vector<InvalidationRuleSet>* pseudoClassInvalidationRuleSets(const PseudoClassInvalidationKey&) const;
const Vector<InvalidationRuleSet>* invalidationRuleSetsForChildChange(const Element&);
@@ -106,7 +106,7 @@
mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_idInvalidationRuleSets;
mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_classInvalidationRuleSets;
mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_attributeInvalidationRuleSets;
- mutable HashMap<CSSSelector::PseudoClassType, std::unique_ptr<Vector<InvalidationRuleSet>>, IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> m_pseudoClassInvalidationRuleSets;
+ mutable HashMap<PseudoClassInvalidationKey, std::unique_ptr<Vector<InvalidationRuleSet>>> m_pseudoClassInvalidationRuleSets;
mutable std::optional<bool> m_cachedHasComplexSelectorsForStyleAttribute;