<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[287973] trunk/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/287973">287973</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2022-01-12 23:31:50 -0800 (Wed, 12 Jan 2022)</dd>
</dl>
<h3>Log Message</h3>
<pre>[:has() pseudo-class] Collect invalidation selectors for child invalidation
https://bugs.webkit.org/show_bug.cgi?id=235103
Reviewed by Dean Jackson.
Collect selectors we can use to test if :has status actually changed before invalidating.
This patch doesn't yet use the the selector.
* style/ChildChangeInvalidation.cpp:
(WebCore::Style::ChildChangeInvalidation::invalidateForChangedElement):
Use the pseudo class invalidation keys for looking up :has selectors too
instead of having a custom mechanism for doing the same thing.
* style/PseudoClassChangeInvalidation.cpp:
(WebCore::Style::makePseudoClassInvalidationKeys):
* style/PseudoClassChangeInvalidation.h:
* style/RuleFeature.cpp:
(WebCore::Style::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):
Always return a selector for consistency.
(WebCore::Style::makePseudoClassInvalidationKey):
(WebCore::Style::RuleFeatureSet::collectFeatures):
(WebCore::Style::RuleFeatureSet::add):
(WebCore::Style::RuleFeatureSet::clear):
(WebCore::Style::RuleFeatureSet::shrinkToFit):
* style/RuleFeature.h:
* style/StyleScopeRuleSets.cpp:
(WebCore::Style::ScopeRuleSets::collectFeatures const):
(WebCore::Style::ScopeRuleSets::hasPseudoClassInvalidationRuleSets const):
(WebCore::Style::ScopeRuleSets::tagInvalidationRuleSets const): Deleted.
We don't need keep around tag rule sets anymore.
* style/StyleScopeRuleSets.h:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorestyleChildChangeInvalidationcpp">trunk/Source/WebCore/style/ChildChangeInvalidation.cpp</a></li>
<li><a href="#trunkSourceWebCorestylePseudoClassChangeInvalidationcpp">trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp</a></li>
<li><a href="#trunkSourceWebCorestylePseudoClassChangeInvalidationh">trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h</a></li>
<li><a href="#trunkSourceWebCorestyleRuleFeaturecpp">trunk/Source/WebCore/style/RuleFeature.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleRuleFeatureh">trunk/Source/WebCore/style/RuleFeature.h</a></li>
<li><a href="#trunkSourceWebCorestyleStyleScopeRuleSetscpp">trunk/Source/WebCore/style/StyleScopeRuleSets.cpp</a></li>
<li><a href="#trunkSourceWebCorestyleStyleScopeRuleSetsh">trunk/Source/WebCore/style/StyleScopeRuleSets.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/ChangeLog 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -1,3 +1,43 @@
</span><ins>+2022-01-12 Antti Koivisto <antti@apple.com>
+
+ [:has() pseudo-class] Collect invalidation selectors for child invalidation
+ https://bugs.webkit.org/show_bug.cgi?id=235103
+
+ Reviewed by Dean Jackson.
+
+ Collect selectors we can use to test if :has status actually changed before invalidating.
+
+ This patch doesn't yet use the the selector.
+
+ * style/ChildChangeInvalidation.cpp:
+ (WebCore::Style::ChildChangeInvalidation::invalidateForChangedElement):
+
+ Use the pseudo class invalidation keys for looking up :has selectors too
+ instead of having a custom mechanism for doing the same thing.
+
+ * style/PseudoClassChangeInvalidation.cpp:
+ (WebCore::Style::makePseudoClassInvalidationKeys):
+ * style/PseudoClassChangeInvalidation.h:
+ * style/RuleFeature.cpp:
+ (WebCore::Style::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):
+
+ Always return a selector for consistency.
+
+ (WebCore::Style::makePseudoClassInvalidationKey):
+ (WebCore::Style::RuleFeatureSet::collectFeatures):
+ (WebCore::Style::RuleFeatureSet::add):
+ (WebCore::Style::RuleFeatureSet::clear):
+ (WebCore::Style::RuleFeatureSet::shrinkToFit):
+ * style/RuleFeature.h:
+ * style/StyleScopeRuleSets.cpp:
+ (WebCore::Style::ScopeRuleSets::collectFeatures const):
+ (WebCore::Style::ScopeRuleSets::hasPseudoClassInvalidationRuleSets const):
+ (WebCore::Style::ScopeRuleSets::tagInvalidationRuleSets const): Deleted.
+
+ We don't need keep around tag rule sets anymore.
+
+ * style/StyleScopeRuleSets.h:
+
</ins><span class="cx"> 2022-01-12 John Wilander <wilander@apple.com>
</span><span class="cx">
</span><span class="cx"> PCM: Same-site triggering events should support ephemeral measurement
</span></span></pre></div>
<a id="trunkSourceWebCorestyleChildChangeInvalidationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/ChildChangeInvalidation.cpp (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/ChildChangeInvalidation.cpp 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/ChildChangeInvalidation.cpp 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx">
</span><span class="cx"> #include "ElementTraversal.h"
</span><span class="cx"> #include "NodeRenderStyle.h"
</span><ins>+#include "PseudoClassChangeInvalidation.h"
</ins><span class="cx"> #include "ShadowRoot.h"
</span><span class="cx"> #include "SlotAssignment.h"
</span><span class="cx"> #include "StyleResolver.h"
</span><span class="lines">@@ -44,42 +45,27 @@
</span><span class="cx">
</span><span class="cx"> bool isDescendant = changedElement.parentElement() != &parentElement();
</span><span class="cx">
</span><ins>+ auto canAffectAncestors = [&](MatchElement matchElement) {
+ if (!isDescendant)
+ return true;
+ return matchElement == MatchElement::HasDescendant
+ || matchElement == MatchElement::HasSiblingDescendant
+ || matchElement == MatchElement::HasNonSubject;
+ };
+
</ins><span class="cx"> auto addHasInvalidation = [&](const Vector<InvalidationRuleSet>* invalidationRuleSets) {
</span><span class="cx"> if (!invalidationRuleSets)
</span><span class="cx"> return;
</span><span class="cx"> for (auto& invalidationRuleSet : *invalidationRuleSets) {
</span><del>- if (!isHasPseudoClassMatchElement(invalidationRuleSet.matchElement))
</del><ins>+ if (!canAffectAncestors(invalidationRuleSet.matchElement))
</ins><span class="cx"> continue;
</span><del>- if (isDescendant) {
- // Elements deeper in the tree can't affect anything except when :has() selector uses descendant combinator.
- if (invalidationRuleSet.matchElement != MatchElement::HasDescendant && invalidationRuleSet.matchElement != MatchElement::HasNonSubject)
- continue;
- }
</del><span class="cx"> Invalidator::addToMatchElementRuleSets(matchElementRuleSets, invalidationRuleSet);
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span><del>- auto tagName = changedElement.localName().convertToASCIILowercase();
- addHasInvalidation(ruleSets.tagInvalidationRuleSets(tagName));
</del><ins>+ for (auto key : makePseudoClassInvalidationKeys(CSSSelector::PseudoClassHas, changedElement))
+ addHasInvalidation(ruleSets.hasPseudoClassInvalidationRuleSets(key));
</ins><span class="cx">
</span><del>- if (changedElement.hasID())
- addHasInvalidation(ruleSets.idInvalidationRuleSets(changedElement.idForStyleResolution()));
-
- if (changedElement.hasAttributes()) {
- for (auto& attribute : changedElement.attributesIterator()) {
- auto attributeName = attribute.localName().convertToASCIILowercase();
- addHasInvalidation(ruleSets.attributeInvalidationRuleSets(attributeName));
- }
- }
-
- if (changedElement.hasClass()) {
- auto count = changedElement.classNames().size();
- for (size_t i = 0; i < count; ++i) {
- auto& className = changedElement.classNames()[i];
- addHasInvalidation(ruleSets.classInvalidationRuleSets(className));
- }
- }
-
</del><span class="cx"> Invalidator::invalidateWithMatchElementRuleSets(changedElement, matchElementRuleSets);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorestylePseudoClassChangeInvalidationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -32,7 +32,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace Style {
</span><span class="cx">
</span><del>-static Vector<PseudoClassInvalidationKey, 4> makePseudoClassInvalidationKeys(CSSSelector::PseudoClassType pseudoClass, const Element& element)
</del><ins>+Vector<PseudoClassInvalidationKey, 4> makePseudoClassInvalidationKeys(CSSSelector::PseudoClassType pseudoClass, const Element& element)
</ins><span class="cx"> {
</span><span class="cx"> Vector<PseudoClassInvalidationKey, 4> keys;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCorestylePseudoClassChangeInvalidationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -53,6 +53,8 @@
</span><span class="cx"> Invalidator::MatchElementRuleSets m_afterChangeRuleSets;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+Vector<PseudoClassInvalidationKey, 4> makePseudoClassInvalidationKeys(CSSSelector::PseudoClassType, const Element&);
+
</ins><span class="cx"> inline void emplace(std::optional<PseudoClassChangeInvalidation>& invalidation, Element& element, std::initializer_list<std::pair<CSSSelector::PseudoClassType, bool>> pseudoClasses)
</span><span class="cx"> {
</span><span class="cx"> invalidation.emplace(element, pseudoClasses);
</span></span></pre></div>
<a id="trunkSourceWebCorestyleRuleFeaturecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/RuleFeature.cpp (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/RuleFeature.cpp 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/RuleFeature.cpp 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -216,13 +216,10 @@
</span><span class="cx"> if (matchElement == MatchElement::Parent || matchElement == MatchElement::Ancestor)
</span><span class="cx"> idsMatchingAncestorsInRules.add(selector->value());
</span><span class="cx"> else if (isHasPseudoClassMatchElement(matchElement))
</span><del>- selectorFeatures.ids.append({ selector->value(), matchElement, isNegation });
</del><ins>+ selectorFeatures.ids.append({ selector, matchElement, isNegation });
</ins><span class="cx"> } else if (selector->match() == CSSSelector::Class)
</span><del>- selectorFeatures.classes.append({ selector->value(), matchElement, isNegation });
- else if (selector->match() == CSSSelector::Tag) {
- if (isHasPseudoClassMatchElement(matchElement))
- selectorFeatures.tags.append({ selector->tagLowercaseLocalName(), matchElement, isNegation });
- } else if (selector->isAttributeSelector()) {
</del><ins>+ selectorFeatures.classes.append({ selector, matchElement, isNegation });
+ else if (selector->isAttributeSelector()) {
</ins><span class="cx"> auto& canonicalLocalName = selector->attributeCanonicalLocalName();
</span><span class="cx"> auto& localName = selector->attribute().localName();
</span><span class="cx"> attributeCanonicalLocalNamesInRules.add(canonicalLocalName);
</span><span class="lines">@@ -257,6 +254,9 @@
</span><span class="cx"> if (!selectorFeatures.hasSiblingSelector && selector->isSiblingSelector())
</span><span class="cx"> selectorFeatures.hasSiblingSelector = true;
</span><span class="cx"> recursivelyCollectFeaturesFromSelector(selectorFeatures, *subSelector, subSelectorMatchElement, subSelectorIsNegation);
</span><ins>+
+ if (selector->match() == CSSSelector::PseudoClass && selector->pseudoClassType() == CSSSelector::PseudoClassHas)
+ selectorFeatures.hasPseudoClasses.append({ subSelector, subSelectorMatchElement, isNegation });
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -276,12 +276,8 @@
</span><span class="cx"> };
</span><span class="cx"> };
</span><span class="cx">
</span><del>-static PseudoClassInvalidationKey makePseudoClassInvalidationKey(const CSSSelector& selector)
</del><ins>+static PseudoClassInvalidationKey makePseudoClassInvalidationKey(CSSSelector::PseudoClassType pseudoClassType, const CSSSelector& selector)
</ins><span class="cx"> {
</span><del>- ASSERT(selector.match() == CSSSelector::PseudoClass);
-
- auto pseudoClassType = selector.pseudoClassType();
-
</del><span class="cx"> AtomString className;
</span><span class="cx"> AtomString tagName;
</span><span class="cx"> for (auto* simpleSelector = selector.firstInCompound(); simpleSelector; simpleSelector = simpleSelector->tagHistory()) {
</span><span class="lines">@@ -303,7 +299,7 @@
</span><span class="cx"> if (!tagName.isEmpty() && tagName != starAtom())
</span><span class="cx"> return makePseudoClassInvalidationKey(pseudoClassType, InvalidationKeyType::Tag, tagName);
</span><span class="cx">
</span><del>- return makePseudoClassInvalidationKey(selector.pseudoClassType(), InvalidationKeyType::Universal);
</del><ins>+ return makePseudoClassInvalidationKey(pseudoClassType, InvalidationKeyType::Universal);
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> void RuleFeatureSet::collectFeatures(const RuleData& ruleData)
</span><span class="lines">@@ -317,7 +313,9 @@
</span><span class="cx">
</span><span class="cx"> auto addToMap = [&](auto& map, auto& entries, auto hostAffectingNames) {
</span><span class="cx"> for (auto& entry : entries) {
</span><del>- auto& [name, matchElement, isNegation] = entry;
</del><ins>+ auto& [selector, matchElement, isNegation] = entry;
+ auto& name = selector->value();
+
</ins><span class="cx"> map.ensure(name, [] {
</span><span class="cx"> return makeUnique<RuleFeatureVector>();
</span><span class="cx"> }).iterator->value->append({ ruleData, matchElement, isNegation });
</span><span class="lines">@@ -331,7 +329,6 @@
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span><del>- addToMap(tagRules, selectorFeatures.tags, nullptr);
</del><span class="cx"> addToMap(idRules, selectorFeatures.ids, nullptr);
</span><span class="cx"> addToMap(classRules, selectorFeatures.classes, &classesAffectingHost);
</span><span class="cx">
</span><span class="lines">@@ -347,7 +344,7 @@
</span><span class="cx">
</span><span class="cx"> for (auto& entry : selectorFeatures.pseudoClasses) {
</span><span class="cx"> auto [selector, matchElement, isNegation] = entry;
</span><del>- pseudoClassRules.ensure(makePseudoClassInvalidationKey(*selector), [] {
</del><ins>+ pseudoClassRules.ensure(makePseudoClassInvalidationKey(selector->pseudoClassType(), *selector), [] {
</ins><span class="cx"> return makeUnique<Vector<RuleFeature>>();
</span><span class="cx"> }).iterator->value->append({ ruleData, matchElement, isNegation });
</span><span class="cx">
</span><span class="lines">@@ -357,6 +354,16 @@
</span><span class="cx">
</span><span class="cx"> setUsesMatchElement(matchElement);
</span><span class="cx"> }
</span><ins>+
+ for (auto& entry : selectorFeatures.hasPseudoClasses) {
+ auto [selector, matchElement, isNegation] = entry;
+ // The selector argument points to a selector inside :has() selector list instead of :has() itself.
+ hasPseudoClassRules.ensure(makePseudoClassInvalidationKey(CSSSelector::PseudoClassHas, *selector), [] {
+ return makeUnique<Vector<RuleFeatureWithInvalidationSelector>>();
+ }).iterator->value->append({ ruleData, matchElement, isNegation, selector });
+
+ setUsesMatchElement(matchElement);
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void RuleFeatureSet::add(const RuleFeatureSet& other)
</span><span class="lines">@@ -377,7 +384,6 @@
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span><del>- addMap(tagRules, other.tagRules);
</del><span class="cx"> addMap(idRules, other.idRules);
</span><span class="cx">
</span><span class="cx"> addMap(classRules, other.classRules);
</span><span class="lines">@@ -390,6 +396,8 @@
</span><span class="cx"> pseudoClassesAffectingHost.add(other.pseudoClassesAffectingHost.begin(), other.pseudoClassesAffectingHost.end());
</span><span class="cx"> pseudoClassTypes.add(other.pseudoClassTypes.begin(), other.pseudoClassTypes.end());
</span><span class="cx">
</span><ins>+ addMap(hasPseudoClassRules, other.hasPseudoClassRules);
+
</ins><span class="cx"> for (size_t i = 0; i < usedMatchElements.size(); ++i)
</span><span class="cx"> usedMatchElements[i] = usedMatchElements[i] || other.usedMatchElements[i];
</span><span class="cx">
</span><span class="lines">@@ -413,9 +421,9 @@
</span><span class="cx"> contentAttributeNamesInRules.clear();
</span><span class="cx"> siblingRules.clear();
</span><span class="cx"> uncommonAttributeRules.clear();
</span><del>- tagRules.clear();
</del><span class="cx"> idRules.clear();
</span><span class="cx"> classRules.clear();
</span><ins>+ hasPseudoClassRules.clear();
</ins><span class="cx"> classesAffectingHost.clear();
</span><span class="cx"> attributeRules.clear();
</span><span class="cx"> attributesAffectingHost.clear();
</span><span class="lines">@@ -430,8 +438,6 @@
</span><span class="cx"> {
</span><span class="cx"> siblingRules.shrinkToFit();
</span><span class="cx"> uncommonAttributeRules.shrinkToFit();
</span><del>- for (auto& rules : tagRules.values())
- rules->shrinkToFit();
</del><span class="cx"> for (auto& rules : idRules.values())
</span><span class="cx"> rules->shrinkToFit();
</span><span class="cx"> for (auto& rules : classRules.values())
</span><span class="lines">@@ -440,6 +446,8 @@
</span><span class="cx"> rules->shrinkToFit();
</span><span class="cx"> for (auto& rules : pseudoClassRules.values())
</span><span class="cx"> rules->shrinkToFit();
</span><ins>+ for (auto& rules : hasPseudoClassRules.values())
+ rules->shrinkToFit();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace Style
</span></span></pre></div>
<a id="trunkSourceWebCorestyleRuleFeatureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/RuleFeature.h (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/RuleFeature.h 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/RuleFeature.h 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -105,11 +105,12 @@
</span><span class="cx"> Vector<RuleAndSelector> siblingRules;
</span><span class="cx"> Vector<RuleAndSelector> uncommonAttributeRules;
</span><span class="cx">
</span><del>- HashMap<AtomString, std::unique_ptr<RuleFeatureVector>> tagRules;
</del><span class="cx"> HashMap<AtomString, std::unique_ptr<RuleFeatureVector>> idRules;
</span><span class="cx"> HashMap<AtomString, std::unique_ptr<RuleFeatureVector>> classRules;
</span><span class="cx"> HashMap<AtomString, std::unique_ptr<Vector<RuleFeatureWithInvalidationSelector>>> attributeRules;
</span><span class="cx"> HashMap<PseudoClassInvalidationKey, std::unique_ptr<RuleFeatureVector>> pseudoClassRules;
</span><ins>+ HashMap<PseudoClassInvalidationKey, std::unique_ptr<Vector<RuleFeatureWithInvalidationSelector>>> hasPseudoClassRules;
+
</ins><span class="cx"> HashSet<AtomString> classesAffectingHost;
</span><span class="cx"> HashSet<AtomString> attributesAffectingHost;
</span><span class="cx"> HashSet<CSSSelector::PseudoClassType, IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> pseudoClassesAffectingHost;
</span><span class="lines">@@ -124,13 +125,15 @@
</span><span class="cx"> struct SelectorFeatures {
</span><span class="cx"> bool hasSiblingSelector { false };
</span><span class="cx">
</span><del>- Vector<std::tuple<AtomString, MatchElement, IsNegation>, 32> tags;
- Vector<std::tuple<AtomString, MatchElement, IsNegation>, 32> ids;
- Vector<std::tuple<AtomString, MatchElement, IsNegation>, 32> classes;
- Vector<std::tuple<const CSSSelector*, MatchElement, IsNegation>, 32> attributes;
- Vector<std::tuple<const CSSSelector*, MatchElement, IsNegation>, 32> pseudoClasses;
</del><ins>+ using InvalidationFeature = std::tuple<const CSSSelector*, MatchElement, IsNegation>;
+
+ Vector<InvalidationFeature> ids;
+ Vector<InvalidationFeature> classes;
+ Vector<InvalidationFeature> attributes;
+ Vector<InvalidationFeature> pseudoClasses;
+ Vector<InvalidationFeature> hasPseudoClasses;
</ins><span class="cx"> };
</span><del>- void recursivelyCollectFeaturesFromSelector(SelectorFeatures&, const CSSSelector&, MatchElement = MatchElement::Subject, IsNegation = IsNegation::No);
</del><ins>+ void recursivelyCollectFeaturesFromSelector(SelectorFeatures&, const CSSSelector&, MatchElement = MatchElement::Subject, IsNegation = IsNegation::No);
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> bool isHasPseudoClassMatchElement(MatchElement);
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleScopeRuleSetscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.cpp (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -221,11 +221,11 @@
</span><span class="cx"> m_siblingRuleSet = makeRuleSet(m_features.siblingRules);
</span><span class="cx"> m_uncommonAttributeRuleSet = makeRuleSet(m_features.uncommonAttributeRules);
</span><span class="cx">
</span><del>- m_tagInvalidationRuleSets.clear();
</del><span class="cx"> m_idInvalidationRuleSets.clear();
</span><span class="cx"> m_classInvalidationRuleSets.clear();
</span><span class="cx"> m_attributeInvalidationRuleSets.clear();
</span><span class="cx"> m_pseudoClassInvalidationRuleSets.clear();
</span><ins>+ m_hasPseudoClassInvalidationRuleSets.clear();
</ins><span class="cx">
</span><span class="cx"> m_cachedHasComplexSelectorsForStyleAttribute = std::nullopt;
</span><span class="cx">
</span><span class="lines">@@ -272,11 +272,6 @@
</span><span class="cx"> }).iterator->value.get();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-const Vector<InvalidationRuleSet>* ScopeRuleSets::tagInvalidationRuleSets(const AtomString& tagName) const
-{
- return ensureInvalidationRuleSets(tagName, m_tagInvalidationRuleSets, m_features.tagRules);
-}
-
</del><span class="cx"> const Vector<InvalidationRuleSet>* ScopeRuleSets::idInvalidationRuleSets(const AtomString& id) const
</span><span class="cx"> {
</span><span class="cx"> return ensureInvalidationRuleSets(id, m_idInvalidationRuleSets, m_features.idRules);
</span><span class="lines">@@ -297,6 +292,11 @@
</span><span class="cx"> return ensureInvalidationRuleSets(pseudoClassKey, m_pseudoClassInvalidationRuleSets, m_features.pseudoClassRules);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+const Vector<InvalidationRuleSet>* ScopeRuleSets::hasPseudoClassInvalidationRuleSets(const PseudoClassInvalidationKey& key) const
+{
+ return ensureInvalidationRuleSets(key, m_hasPseudoClassInvalidationRuleSets, m_features.hasPseudoClassRules);
+}
+
</ins><span class="cx"> bool ScopeRuleSets::hasComplexSelectorsForStyleAttribute() const
</span><span class="cx"> {
</span><span class="cx"> auto compute = [&] {
</span></span></pre></div>
<a id="trunkSourceWebCorestyleStyleScopeRuleSetsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.h (287972 => 287973)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/style/StyleScopeRuleSets.h 2022-01-13 07:10:04 UTC (rev 287972)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.h 2022-01-13 07:31:50 UTC (rev 287973)
</span><span class="lines">@@ -62,14 +62,12 @@
</span><span class="cx"> RuleSet* sibling() const { return m_siblingRuleSet.get(); }
</span><span class="cx"> RuleSet* uncommonAttribute() const { return m_uncommonAttributeRuleSet.get(); }
</span><span class="cx">
</span><del>- const Vector<InvalidationRuleSet>* tagInvalidationRuleSets(const AtomString&) const;
</del><span class="cx"> const Vector<InvalidationRuleSet>* idInvalidationRuleSets(const AtomString&) const;
</span><span class="cx"> const Vector<InvalidationRuleSet>* classInvalidationRuleSets(const AtomString&) const;
</span><span class="cx"> const Vector<InvalidationRuleSet>* attributeInvalidationRuleSets(const AtomString&) const;
</span><span class="cx"> const Vector<InvalidationRuleSet>* pseudoClassInvalidationRuleSets(const PseudoClassInvalidationKey&) const;
</span><ins>+ const Vector<InvalidationRuleSet>* hasPseudoClassInvalidationRuleSets(const PseudoClassInvalidationKey&) const;
</ins><span class="cx">
</span><del>- const Vector<InvalidationRuleSet>* invalidationRuleSetsForChildChange(const Element&);
-
</del><span class="cx"> bool hasComplexSelectorsForStyleAttribute() const;
</span><span class="cx">
</span><span class="cx"> void setUsesSharedUserStyle(bool b) { m_usesSharedUserStyle = b; }
</span><span class="lines">@@ -101,11 +99,11 @@
</span><span class="cx"> mutable RuleFeatureSet m_features;
</span><span class="cx"> mutable RefPtr<RuleSet> m_siblingRuleSet;
</span><span class="cx"> mutable RefPtr<RuleSet> m_uncommonAttributeRuleSet;
</span><del>- mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_tagInvalidationRuleSets;
</del><span class="cx"> mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_idInvalidationRuleSets;
</span><span class="cx"> mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_classInvalidationRuleSets;
</span><span class="cx"> mutable HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>> m_attributeInvalidationRuleSets;
</span><span class="cx"> mutable HashMap<PseudoClassInvalidationKey, std::unique_ptr<Vector<InvalidationRuleSet>>> m_pseudoClassInvalidationRuleSets;
</span><ins>+ mutable HashMap<PseudoClassInvalidationKey, std::unique_ptr<Vector<InvalidationRuleSet>>> m_hasPseudoClassInvalidationRuleSets;
</ins><span class="cx">
</span><span class="cx"> mutable std::optional<bool> m_cachedHasComplexSelectorsForStyleAttribute;
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>