Diff
Modified: trunk/LayoutTests/ChangeLog (258320 => 258321)
--- trunk/LayoutTests/ChangeLog 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/LayoutTests/ChangeLog 2020-03-12 13:30:10 UTC (rev 258321)
@@ -1,3 +1,24 @@
+2020-03-12 Antti Koivisto <an...@apple.com>
+
+ Accurate style invalidation for user action pseudo classes
+ https://bugs.webkit.org/show_bug.cgi?id=208859
+ <rdar://problem/55196888>
+
+ Reviewed by Zalan Bujtas.
+
+ * fast/selectors/style-invalidation-focus-change-descendants-expected.txt: Added.
+ * fast/selectors/style-invalidation-focus-change-descendants.html: Added.
+ * fast/selectors/style-invalidation-focus-change-siblings-expected.txt: Added.
+ * fast/selectors/style-invalidation-focus-change-siblings.html: Added.
+ * fast/selectors/style-invalidation-focus-within-change-descendants-expected.txt: Added.
+ * fast/selectors/style-invalidation-focus-within-change-descendants.html: Added.
+ * fast/selectors/style-invalidation-focus-within-change-siblings-expected.txt: Added.
+ * fast/selectors/style-invalidation-focus-within-change-siblings.html: Added.
+ * fast/selectors/style-invalidation-hover-change-descendants-expected.txt: Added.
+ * fast/selectors/style-invalidation-hover-change-descendants.html: Added.
+ * fast/selectors/style-invalidation-hover-change-siblings-expected.txt: Added.
+ * fast/selectors/style-invalidation-hover-change-siblings.html: Added.
+
2020-03-12 Diego Pino Garcia <dp...@igalia.com>
[WPE] Gardening, expected to fail but passed
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-descendants-expected.txt (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-descendants-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-descendants-expected.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,7 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-descendants.html (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-descendants.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-descendants.html 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,82 @@
+<html>
+<style>
+.container {
+ background-color: blue;
+ width: 200px;
+ height: 600px;
+ position: absolute;
+}
+.inert {
+ background-color: yellow;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.target {
+ background-color: red;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.container:focus .target {
+ background-color: green;
+}
+.child {
+ width: 50px;
+ height: 50px;
+}
+</style>
+<div class=container tabindex=1 id=focusTarget>
+ <div class=inert>
+ </div>
+ <div class=target>
+ </div>
+ <div class=inert>
+ </div>
+ <div class=target>
+ <div class="inert child">
+ </div>
+ </div>
+ <div class=inert>
+ <div class="target child">
+ </div>
+ </div>
+</div>
+<pre id=log></pre>
+
+<script>
+function testStyleChangeType(selector, expectedType)
+{
+ let pass = true;
+ const elements = document.querySelectorAll(selector);
+ for (var i = 0; i < elements.length; ++i) {
+ const type = window.internals.styleChangeType(elements[i]);
+ if (type != expectedType) {
+ log.textContent += `FAIL ${selector} styleChangeType was ${type} expected ${expectedType}\n`;
+ pass = false;
+ }
+ }
+ if (pass)
+ log.textContent += "PASS\n";
+}
+
+window._onload_ = function () {
+ if (!window.testRunner)
+ return;
+ testRunner.dumpAsText();
+
+ document.body.offsetLeft;
+ focusTarget.focus();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "InlineStyleChange"); // Style change due to to UA style sheet.
+ testStyleChangeType(".inert", "NoStyleChange");
+
+ document.body.offsetLeft;
+ focusTarget.blur();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "InlineStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+};
+</script>
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-siblings-expected.txt (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-siblings-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-siblings-expected.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,7 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-siblings.html (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-siblings.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-change-siblings.html 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,86 @@
+<html>
+<style>
+.container {
+ background-color: blue;
+ width: 200px;
+ height: 600px;
+ position: absolute;
+}
+.inert {
+ background-color: yellow;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.target {
+ background-color: red;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+:focus ~ .target {
+ background-color: green;
+}
+:focus ~ .inert > .target {
+ background-color: green;
+}
+.child {
+ width: 50px;
+ height: 50px;
+}
+</style>
+<div class=container>
+ <!--Style change due to to UA style sheet.-->
+ <div class=target tabindex=1 id=focusTarget>
+ </div>
+ <div class=target>
+ </div>
+ <div class=inert>
+ </div>
+ <div class=target>
+ <div class="inert child">
+ </div>
+ </div>
+ <div class=inert>
+ <div class="target child">
+ </div>
+ </div>
+</div>
+<pre id=log></pre>
+
+<script>
+function testStyleChangeType(selector, expectedType)
+{
+ let pass = true;
+ const elements = document.querySelectorAll(selector);
+ for (var i = 0; i < elements.length; ++i) {
+ const type = window.internals.styleChangeType(elements[i]);
+ if (type != expectedType) {
+ log.textContent += `FAIL ${selector} styleChangeType was ${type} expected ${expectedType}\n`;
+ pass = false;
+ }
+ }
+ if (pass)
+ log.textContent += "PASS\n";
+}
+
+window._onload_ = function () {
+ if (!window.testRunner)
+ return;
+ testRunner.dumpAsText();
+
+ document.body.offsetLeft;
+ focusTarget.focus();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+
+ document.body.offsetLeft;
+ focusTarget.blur();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+};
+</script>
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-descendants-expected.txt (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-descendants-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-descendants-expected.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,7 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-descendants.html (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-descendants.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-descendants.html 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,82 @@
+<html>
+<style>
+.container {
+ background-color: blue;
+ width: 200px;
+ height: 600px;
+ position: absolute;
+}
+.inert {
+ background-color: yellow;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.target {
+ background-color: red;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.container:focus-within .target {
+ background-color: green;
+}
+.child {
+ width: 50px;
+ height: 50px;
+}
+</style>
+<div class=container>
+ <div class=target tabindex=1 id=focusTarget>
+ </div>
+ <div class=target>
+ </div>
+ <div class=inert>
+ </div>
+ <div class=target>
+ <div class="inert child">
+ </div>
+ </div>
+ <div class=inert>
+ <div class="target child">
+ </div>
+ </div>
+</div>
+<pre id=log></pre>
+
+<script>
+function testStyleChangeType(selector, expectedType)
+{
+ let pass = true;
+ const elements = document.querySelectorAll(selector);
+ for (var i = 0; i < elements.length; ++i) {
+ const type = window.internals.styleChangeType(elements[i]);
+ if (type != expectedType) {
+ log.textContent += `FAIL ${selector} styleChangeType was ${type} expected ${expectedType}\n`;
+ pass = false;
+ }
+ }
+ if (pass)
+ log.textContent += "PASS\n";
+}
+
+window._onload_ = function () {
+ if (!window.testRunner)
+ return;
+ testRunner.dumpAsText();
+
+ document.body.offsetLeft;
+ focusTarget.focus();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+
+ document.body.offsetLeft;
+ focusTarget.blur();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+};
+</script>
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-siblings-expected.txt (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-siblings-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-siblings-expected.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,7 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Added: trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-siblings.html (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-siblings.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-focus-within-change-siblings.html 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,88 @@
+<html>
+<style>
+.container {
+ background-color: blue;
+ width: 200px;
+ height: 600px;
+ position: absolute;
+}
+.inert {
+ background-color: yellow;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.target {
+ background-color: red;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.inert:focus-within ~ .target {
+ background-color: green;
+}
+.inert:focus-within ~ .inert > .target {
+ background-color: green;
+}
+.child {
+ width: 50px;
+ height: 50px;
+}
+</style>
+<div class=container>
+ <div class=inert>
+ <!--Style change due to to UA style sheet.-->
+ <div class="target child" tabindex=1 id=focusTarget>
+ </div>
+ </div>
+ <div class=target>
+ </div>
+ <div class=inert>
+ </div>
+ <div class=target>
+ <div class="inert child">
+ </div>
+ </div>
+ <div class=inert>
+ <div class="target child">
+ </div>
+ </div>
+</div>
+<pre id=log></pre>
+
+<script>
+function testStyleChangeType(selector, expectedType)
+{
+ let pass = true;
+ const elements = document.querySelectorAll(selector);
+ for (var i = 0; i < elements.length; ++i) {
+ const type = window.internals.styleChangeType(elements[i]);
+ if (type != expectedType) {
+ log.textContent += `FAIL ${selector} styleChangeType was ${type} expected ${expectedType}\n`;
+ pass = false;
+ }
+ }
+ if (pass)
+ log.textContent += "PASS\n";
+}
+
+window._onload_ = function () {
+ if (!window.testRunner)
+ return;
+ testRunner.dumpAsText();
+
+ document.body.offsetLeft;
+ focusTarget.focus();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+
+ document.body.offsetLeft;
+ focusTarget.blur();
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+};
+</script>
Added: trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-descendants-expected.txt (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-descendants-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-descendants-expected.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,7 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Added: trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-descendants.html (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-descendants.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-descendants.html 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,82 @@
+<html>
+<style>
+.container {
+ background-color: blue;
+ width: 200px;
+ height: 600px;
+ position: absolute;
+}
+.inert {
+ background-color: yellow;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.target {
+ background-color: red;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.container:hover .target {
+ background-color: green;
+}
+.child {
+ width: 50px;
+ height: 50px;
+}
+</style>
+<div class=container>
+ <div class=inert>
+ </div>
+ <div class=target>
+ </div>
+ <div class=inert>
+ </div>
+ <div class=target>
+ <div class="inert child">
+ </div>
+ </div>
+ <div class=inert>
+ <div class="target child">
+ </div>
+ </div>
+</div>
+<pre id=log></pre>
+
+<script>
+function testStyleChangeType(selector, expectedType)
+{
+ let pass = true;
+ const elements = document.querySelectorAll(selector);
+ for (var i = 0; i < elements.length; ++i) {
+ const type = window.internals.styleChangeType(elements[i]);
+ if (type != expectedType) {
+ log.textContent += `FAIL ${selector} styleChangeType was ${type} expected ${expectedType}\n`;
+ pass = false;
+ }
+ }
+ if (pass)
+ log.textContent += "PASS\n";
+}
+
+window._onload_ = function () {
+ if (!window.testRunner)
+ return;
+ testRunner.dumpAsText();
+
+ document.body.offsetLeft;
+ eventSender.mouseMoveTo(50,50);
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+
+ document.body.offsetLeft;
+ eventSender.mouseMoveTo(300,50);
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+};
+</script>
Added: trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-siblings-expected.txt (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-siblings-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-siblings-expected.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,7 @@
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+
Added: trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-siblings.html (0 => 258321)
--- trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-siblings.html (rev 0)
+++ trunk/LayoutTests/fast/selectors/style-invalidation-hover-change-siblings.html 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,85 @@
+<html>
+<style>
+.container {
+ background-color: blue;
+ width: 200px;
+ height: 600px;
+ position: absolute;
+}
+.inert {
+ background-color: yellow;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.target {
+ background-color: red;
+ width: 100px;
+ height: 100px;
+ position: relative;
+}
+.inert:hover ~ .target {
+ background-color: green;
+}
+.inert:hover ~ .inert > .target {
+ background-color: green;
+}
+.child {
+ width: 50px;
+ height: 50px;
+}
+</style>
+<div class=container>
+ <div class=inert>
+ </div>
+ <div class=target>
+ </div>
+ <div class=inert>
+ </div>
+ <div class=target>
+ <div class="inert child">
+ </div>
+ </div>
+ <div class=inert>
+ <div class="target child">
+ </div>
+ </div>
+</div>
+<pre id=log></pre>
+
+<script>
+function testStyleChangeType(selector, expectedType)
+{
+ let pass = true;
+ const elements = document.querySelectorAll(selector);
+ for (var i = 0; i < elements.length; ++i) {
+ const type = window.internals.styleChangeType(elements[i]);
+ if (type != expectedType) {
+ log.textContent += `FAIL ${selector} styleChangeType was ${type} expected ${expectedType}\n`;
+ pass = false;
+ }
+ }
+ if (pass)
+ log.textContent += "PASS\n";
+}
+
+window._onload_ = function () {
+ if (!window.testRunner)
+ return;
+ testRunner.dumpAsText();
+
+ document.body.offsetLeft;
+ eventSender.mouseMoveTo(50,50);
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+
+ document.body.offsetLeft;
+ eventSender.mouseMoveTo(300,50);
+
+ testStyleChangeType(".target", "InlineStyleChange");
+ testStyleChangeType(".container", "NoStyleChange");
+ testStyleChangeType(".inert", "NoStyleChange");
+};
+</script>
Modified: trunk/LayoutTests/platform/ios/TestExpectations (258320 => 258321)
--- trunk/LayoutTests/platform/ios/TestExpectations 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2020-03-12 13:30:10 UTC (rev 258321)
@@ -693,6 +693,8 @@
fast/selectors/hover-strict.html [ Skip ]
fast/selectors/not-active-hover-quirks.html [ Skip ]
fast/selectors/not-active-hover-strict.html [ Skip ]
+fast/selectors/style-invalidation-hover-change-descendants.html [ Skip ]
+fast/selectors/style-invalidation-hover-change-siblings.html [ Skip ]
fast/shapes/shape-outside-floats/shape-outside-clip-path-selection.html [ Skip ]
fast/shadow-dom/mouseenter-mouseleave-across-shadow-boundary.html [ Skip ]
fast/shadow-dom/mouseenter-mouseleave-inside-shadow-tree.html [ Skip ]
Modified: trunk/LayoutTests/platform/win/TestExpectations (258320 => 258321)
--- trunk/LayoutTests/platform/win/TestExpectations 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/LayoutTests/platform/win/TestExpectations 2020-03-12 13:30:10 UTC (rev 258321)
@@ -2863,6 +2863,14 @@
fast/selectors/querySelector-window-inactive.html [ Failure ]
fast/selectors/read-only-read-write-input-basics.html [ Failure ]
+# Win port sometimes forces synchronous style recalc on focus/hover making these unreliable.
+fast/selectors/style-invalidation-focus-change-descendants.html [ Pass Failure ]
+fast/selectors/style-invalidation-focus-change-siblings.html [ Pass Failure ]
+fast/selectors/style-invalidation-focus-within-change-descendants.html [ Pass Failure ]
+fast/selectors/style-invalidation-focus-within-change-siblings.html [ Pass Failure ]
+fast/selectors/style-invalidation-hover-change-descendants.html [ Pass Failure ]
+fast/selectors/style-invalidation-hover-change-siblings.html [ Pass Failure ]
+
fast/shapes/shape-outside-floats/shape-outside-image-fit-002.html [ Pass ImageOnlyFailure ]
fast/table/border-collapsing/cached-change-tbody-border-width.html [ Pass Failure ]
Modified: trunk/Source/WebCore/ChangeLog (258320 => 258321)
--- trunk/Source/WebCore/ChangeLog 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/ChangeLog 2020-03-12 13:30:10 UTC (rev 258321)
@@ -1,3 +1,68 @@
+2020-03-12 Antti Koivisto <an...@apple.com>
+
+ Accurate style invalidation for user action pseudo classes
+ https://bugs.webkit.org/show_bug.cgi?id=208859
+ <rdar://problem/55196888>
+
+ Reviewed by Zalan Bujtas.
+
+ Currently :hover, :focus, :focus-within and :active lack fine grained invalidation using
+ rule sets like we do with class and attribute selectors.
+
+ This can be added easily following the same pattern.
+
+ Tests: fast/selectors/style-invalidation-hover-change-descendants.html
+ fast/selectors/style-invalidation-hover-change-siblings.html
+ fast/selectors/style-invalidation-focus-change-descendants.html
+ fast/selectors/style-invalidation-focus-change-siblings.html
+ fast/selectors/style-invalidation-focus-within-change-descendants.html
+ fast/selectors/style-invalidation-focus-within-change-siblings.html
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Element.cpp:
+ (WebCore::Element::setActive):
+ (WebCore::Element::setFocus):
+ (WebCore::Element::setHasFocusWithin):
+ (WebCore::Element::setHovered):
+
+ Use PseudoClassChangeInvalidation.
+
+ * dom/Element.h:
+ (WebCore::Element::setHasFocusWithin): Deleted.
+ * page/FrameViewLayoutContext.cpp:
+ (WebCore::RenderTreeNeedsLayoutChecker::~RenderTreeNeedsLayoutChecker):
+ * style/PseudoClassChangeInvalidation.cpp: Added.
+ (WebCore::Style::PseudoClassChangeInvalidation::computeInvalidation):
+
+ Compute invalidation rule set for a pseudo class change.
+
+ (WebCore::Style::PseudoClassChangeInvalidation::invalidateStyleWithRuleSets):
+ * style/PseudoClassChangeInvalidation.h: Added.
+ (WebCore::Style::PseudoClassChangeInvalidation::PseudoClassChangeInvalidation):
+ (WebCore::Style::PseudoClassChangeInvalidation::~PseudoClassChangeInvalidation):
+ * style/RuleFeature.cpp:
+ (WebCore::Style::RuleFeatureSet::recursivelyCollectFeaturesFromSelector):
+ (WebCore::Style::RuleFeatureSet::collectFeatures):
+
+ Collect pseudo class features, similar to classes/attributes.
+
+ (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::ensureInvalidationRuleSets):
+
+ Make more generic to allow enum key.
+
+ (WebCore::Style::ScopeRuleSets::pseudoClassInvalidationRuleSets const):
+
+ Create pseudo class invalidation ruleset.
+
+ * style/StyleScopeRuleSets.h:
+
2020-03-12 Said Abou-Hallawa <sabouhall...@apple.com>
[GPU Process] GraphicsContextStateChange must accumulate fill and stroke fields as single properties
Modified: trunk/Source/WebCore/Sources.txt (258320 => 258321)
--- trunk/Source/WebCore/Sources.txt 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/Sources.txt 2020-03-12 13:30:10 UTC (rev 258321)
@@ -2374,6 +2374,7 @@
style/MatchedDeclarationsCache.cpp
style/PageRuleCollector.cpp
style/PropertyCascade.cpp
+style/PseudoClassChangeInvalidation.cpp
style/RuleData.cpp
style/RuleFeature.cpp
style/RuleSet.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (258320 => 258321)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-03-12 13:30:10 UTC (rev 258321)
@@ -4890,6 +4890,7 @@
E451C6322394031A00993190 /* MarginTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE7AA2621C37B6300296DCD /* MarginTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
E451C6342394058F00993190 /* DisplayInlineContent.h in Headers */ = {isa = PBXBuildFile; fileRef = E451C6332394058E00993190 /* DisplayInlineContent.h */; settings = {ATTRIBUTES = (Private, ); }; };
E45322AC140CE267005A0F92 /* SelectorQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = E45322AA140CE267005A0F92 /* SelectorQuery.h */; };
+ E45A6C772417BA59006E4CD5 /* PseudoClassChangeInvalidation.h in Headers */ = {isa = PBXBuildFile; fileRef = E45A6C762417BA59006E4CD5 /* PseudoClassChangeInvalidation.h */; };
E45BA6AA2374926C004DFC07 /* MatchedDeclarationsCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E45BA6A82374926B004DFC07 /* MatchedDeclarationsCache.h */; };
E45BA6B6237622A3004DFC07 /* StyleAdjuster.h in Headers */ = {isa = PBXBuildFile; fileRef = E45BA6B52376229F004DFC07 /* StyleAdjuster.h */; };
E4605FEC2166480900E53046 /* PrewarmInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = E4605FEA2166480800E53046 /* PrewarmInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -15298,6 +15299,8 @@
E45390340EAFD637003695C8 /* ScrollViewIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollViewIOS.mm; sourceTree = "<group>"; };
E453903C0EAFD637003695C8 /* WidgetIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WidgetIOS.mm; sourceTree = "<group>"; };
E45390AD0EAFF4B5003695C8 /* SystemMemoryIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SystemMemoryIOS.cpp; sourceTree = "<group>"; };
+ E45A6C732417BA4C006E4CD5 /* PseudoClassChangeInvalidation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoClassChangeInvalidation.cpp; sourceTree = "<group>"; };
+ E45A6C762417BA59006E4CD5 /* PseudoClassChangeInvalidation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoClassChangeInvalidation.h; sourceTree = "<group>"; };
E45BA6A82374926B004DFC07 /* MatchedDeclarationsCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchedDeclarationsCache.h; sourceTree = "<group>"; };
E45BA6AB2374927B004DFC07 /* MatchedDeclarationsCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MatchedDeclarationsCache.cpp; sourceTree = "<group>"; };
E45BA6B22376227E004DFC07 /* StyleAdjuster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleAdjuster.cpp; sourceTree = "<group>"; };
@@ -27273,6 +27276,8 @@
FBDB61A016D6037E00BB3394 /* PageRuleCollector.h */,
E4ABABE52361A34200FA4345 /* PropertyCascade.cpp */,
E4ABABE22361A32900FA4345 /* PropertyCascade.h */,
+ E45A6C732417BA4C006E4CD5 /* PseudoClassChangeInvalidation.cpp */,
+ E45A6C762417BA59006E4CD5 /* PseudoClassChangeInvalidation.h */,
E4863CFA23842E8700972158 /* RuleData.cpp */,
E4863CFD23842E9E00972158 /* RuleData.h */,
A79BAD9D161E7F3F00C2E652 /* RuleFeature.cpp */,
@@ -31173,6 +31178,7 @@
B2FA3D570AB75A6F000E5AC4 /* JSSVGAnimationElement.h in Headers */,
B2FA3D590AB75A6F000E5AC4 /* JSSVGCircleElement.h in Headers */,
B2FA3D5B0AB75A6F000E5AC4 /* JSSVGClipPathElement.h in Headers */,
+ E45A6C772417BA59006E4CD5 /* PseudoClassChangeInvalidation.h in Headers */,
B2FA3D5F0AB75A6F000E5AC4 /* JSSVGComponentTransferFunctionElement.h in Headers */,
B2FA3D610AB75A6F000E5AC4 /* JSSVGCursorElement.h in Headers */,
B2FA3D630AB75A6F000E5AC4 /* JSSVGDefsElement.h in Headers */,
Modified: trunk/Source/WebCore/dom/Element.cpp (258320 => 258321)
--- trunk/Source/WebCore/dom/Element.cpp 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/dom/Element.cpp 2020-03-12 13:30:10 UTC (rev 258321)
@@ -86,6 +86,7 @@
#include "PointerCaptureController.h"
#include "PointerEvent.h"
#include "PointerLockController.h"
+#include "PseudoClassChangeInvalidation.h"
#include "RenderFragmentedFlow.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
@@ -632,17 +633,15 @@
{
if (flag == active())
return;
+ {
+ Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassActive);
+ document().userActionElements().setActive(*this, flag);
+ }
- document().userActionElements().setActive(*this, flag);
-
- auto* renderStyle = renderOrDisplayContentsStyle();
- bool reactsToPress = (renderStyle && renderStyle->affectedByActive()) || styleAffectedByActive();
- if (reactsToPress)
- invalidateStyleForSubtree();
-
if (!renderer())
return;
+ bool reactsToPress = false;
if (renderer()->style().hasAppearance() && renderer()->theme().stateChanged(*renderer(), ControlStates::PressedState))
reactsToPress = true;
@@ -681,10 +680,12 @@
{
if (flag == focused())
return;
+ {
+ Style::PseudoClassChangeInvalidation focusStyleInvalidation(*this, CSSSelector::PseudoClassFocus);
+ Style::PseudoClassChangeInvalidation directFocusStyleInvalidation(*this, CSSSelector::PseudoClassDirectFocus);
+ document().userActionElements().setFocused(*this, flag);
+ }
- document().userActionElements().setFocused(*this, flag);
- invalidateStyleForSubtree();
-
// Shadow host with a slot that contain focused element is not considered focused.
for (auto* root = containingShadowRoot(); root; root = root->host()->containingShadowRoot()) {
root->setContainsFocusedElement(flag);
@@ -691,34 +692,30 @@
root->host()->invalidateStyle();
}
- for (Element* element = this; element; element = element->parentElementInComposedTree())
+ for (auto* element = this; element; element = element->parentElementInComposedTree())
element->setHasFocusWithin(flag);
}
+void Element::setHasFocusWithin(bool flag)
+{
+ if (hasFocusWithin() == flag)
+ return;
+ {
+ Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassFocusWithin);
+ setFlag(flag, HasFocusWithin);
+ }
+}
+
void Element::setHovered(bool flag)
{
if (flag == hovered())
return;
-
- document().userActionElements().setHovered(*this, flag);
-
- auto* style = renderOrDisplayContentsStyle();
- if (style && (style->affectedByHover() || childrenAffectedByHover()))
- invalidateStyleForSubtree();
-
- if (!renderer()) {
- // When setting hover to false, the style needs to be recalc'd even when
- // there's no renderer (imagine setting display:none in the :hover class,
- // if a nil renderer would prevent this element from recalculating its
- // style, it would never go back to its normal style and remain
- // stuck in its hovered style).
- if (!flag && !style)
- invalidateStyleForSubtree();
-
- return;
+ {
+ Style::PseudoClassChangeInvalidation styleInvalidation(*this, CSSSelector::PseudoClassHover);
+ document().userActionElements().setHovered(*this, flag);
}
- if (style->hasAppearance())
+ if (auto* style = renderStyle(); style && style->hasAppearance())
renderer()->theme().stateChanged(*renderer(), ControlStates::HoverState);
}
Modified: trunk/Source/WebCore/dom/Element.h (258320 => 258321)
--- trunk/Source/WebCore/dom/Element.h 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/dom/Element.h 2020-03-12 13:30:10 UTC (rev 258321)
@@ -859,15 +859,6 @@
return element.isHTMLElement() && element.document().isHTMLDocument();
}
-inline void Element::setHasFocusWithin(bool flag)
-{
- if (hasFocusWithin() == flag)
- return;
- setFlag(flag, HasFocusWithin);
- if (styleAffectedByFocusWithin())
- invalidateStyleForSubtree();
-}
-
template<typename... QualifiedNames>
inline const AtomString& Element::getAttribute(const QualifiedName& name, const QualifiedNames&... names) const
{
Added: trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp (0 => 258321)
--- trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp (rev 0)
+++ trunk/Source/WebCore/style/PseudoClassChangeInvalidation.cpp 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PseudoClassChangeInvalidation.h"
+
+#include "ElementChildIterator.h"
+#include "StyleInvalidationFunctions.h"
+
+namespace WebCore {
+namespace Style {
+
+void PseudoClassChangeInvalidation::computeInvalidation(CSSSelector::PseudoClassType pseudoClass)
+{
+ bool shouldInvalidateCurrent = false;
+ bool mayAffectStyleInShadowTree = false;
+
+ traverseRuleFeatures(m_element, [&] (const RuleFeatureSet& features, bool mayAffectShadowTree) {
+ if (mayAffectShadowTree && features.pseudoClassRules.contains(pseudoClass))
+ mayAffectStyleInShadowTree = true;
+ if (m_element.shadowRoot() && features.pseudoClassesAffectingHost.contains(pseudoClass))
+ shouldInvalidateCurrent = true;
+ });
+
+ if (mayAffectStyleInShadowTree) {
+ // FIXME: We should do fine-grained invalidation for shadow tree.
+ m_element.invalidateStyleForSubtree();
+ }
+
+ if (shouldInvalidateCurrent)
+ m_element.invalidateStyle();
+
+ auto& ruleSets = m_element.styleResolver().ruleSets();
+ if (auto* invalidationRuleSets = ruleSets.pseudoClassInvalidationRuleSets(pseudoClass)) {
+ for (auto& invalidationRuleSet : *invalidationRuleSets)
+ Invalidator::addToMatchElementRuleSets(m_matchElementRuleSets, invalidationRuleSet);
+ }
+}
+
+void PseudoClassChangeInvalidation::invalidateStyleWithRuleSets()
+{
+ Invalidator::invalidateWithMatchElementRuleSets(m_element, m_matchElementRuleSets);
+}
+
+}
+}
Added: trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h (0 => 258321)
--- trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h (rev 0)
+++ trunk/Source/WebCore/style/PseudoClassChangeInvalidation.h 2020-03-12 13:30:10 UTC (rev 258321)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CSSSelector.h"
+#include "Element.h"
+#include "StyleInvalidator.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+namespace Style {
+
+class PseudoClassChangeInvalidation {
+public:
+ PseudoClassChangeInvalidation(Element&, CSSSelector::PseudoClassType);
+ ~PseudoClassChangeInvalidation();
+
+private:
+ void computeInvalidation(CSSSelector::PseudoClassType);
+ void invalidateStyleWithRuleSets();
+
+ const bool m_isEnabled;
+ Element& m_element;
+
+ Invalidator::MatchElementRuleSets m_matchElementRuleSets;
+};
+
+inline PseudoClassChangeInvalidation::PseudoClassChangeInvalidation(Element& element, CSSSelector::PseudoClassType pseudoClassType)
+ : m_isEnabled(element.needsStyleInvalidation())
+ , m_element(element)
+
+{
+ if (!m_isEnabled)
+ return;
+ computeInvalidation(pseudoClassType);
+ invalidateStyleWithRuleSets();
+}
+
+inline PseudoClassChangeInvalidation::~PseudoClassChangeInvalidation()
+{
+ if (!m_isEnabled)
+ return;
+ invalidateStyleWithRuleSets();
+}
+
+}
+}
Modified: trunk/Source/WebCore/style/RuleFeature.cpp (258320 => 258321)
--- trunk/Source/WebCore/style/RuleFeature.cpp 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/style/RuleFeature.cpp 2020-03-12 13:30:10 UTC (rev 258321)
@@ -153,7 +153,8 @@
default:
break;
}
- }
+ } else if (selector->match() == CSSSelector::PseudoClass)
+ selectorFeatures.pseudoClasses.append(std::make_pair(selector->pseudoClassType(), matchElement));
if (!selectorFeatures.hasSiblingSelector && selector->isSiblingSelector())
selectorFeatures.hasSiblingSelector = true;
@@ -199,6 +200,13 @@
if (matchElement == MatchElement::Host)
attributesAffectingHost.add(selector->attribute().localName().convertToASCIILowercase());
}
+ for (auto& keyAndMatch : selectorFeatures.pseudoClasses) {
+ pseudoClassRules.ensure(keyAndMatch.first, [] {
+ return makeUnique<Vector<RuleFeature>>();
+ }).iterator->value->append({ ruleData, keyAndMatch.second });
+ if (keyAndMatch.second == MatchElement::Host)
+ pseudoClassesAffectingHost.add(keyAndMatch.first);
+ }
}
void RuleFeatureSet::add(const RuleFeatureSet& other)
@@ -224,6 +232,13 @@
}
attributesAffectingHost.add(other.attributesAffectingHost.begin(), other.attributesAffectingHost.end());
+ for (auto& keyValuePair : other.pseudoClassRules) {
+ pseudoClassRules.ensure(keyValuePair.key, [] {
+ return makeUnique<Vector<RuleFeature>>();
+ }).iterator->value->appendVector(*keyValuePair.value);
+ }
+ pseudoClassesAffectingHost.add(other.pseudoClassesAffectingHost.begin(), other.pseudoClassesAffectingHost.end());
+
usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
usesFirstLetterRules = usesFirstLetterRules || other.usesFirstLetterRules;
}
@@ -248,6 +263,8 @@
classesAffectingHost.clear();
attributeRules.clear();
attributesAffectingHost.clear();
+ pseudoClassRules.clear();
+ pseudoClassesAffectingHost.clear();
usesFirstLineRules = false;
usesFirstLetterRules = false;
}
@@ -260,6 +277,8 @@
rules->shrinkToFit();
for (auto& rules : attributeRules.values())
rules->shrinkToFit();
+ for (auto& rules : pseudoClassRules.values())
+ rules->shrinkToFit();
}
} // namespace Style
Modified: trunk/Source/WebCore/style/RuleFeature.h (258320 => 258321)
--- trunk/Source/WebCore/style/RuleFeature.h 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/style/RuleFeature.h 2020-03-12 13:30:10 UTC (rev 258321)
@@ -75,8 +75,10 @@
HashMap<AtomString, std::unique_ptr<Vector<RuleFeature>>> classRules;
HashMap<AtomString, std::unique_ptr<Vector<RuleFeatureWithInvalidationSelector>>> attributeRules;
+ HashMap<CSSSelector::PseudoClassType, std::unique_ptr<Vector<RuleFeature>>, WTF::IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> pseudoClassRules;
HashSet<AtomString> classesAffectingHost;
HashSet<AtomString> attributesAffectingHost;
+ HashSet<CSSSelector::PseudoClassType, WTF::IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> pseudoClassesAffectingHost;
bool usesFirstLineRules { false };
bool usesFirstLetterRules { false };
@@ -90,6 +92,7 @@
Vector<std::pair<AtomString, MatchElement>, 32> classes;
Vector<std::pair<const CSSSelector*, MatchElement>, 32> attributes;
+ Vector<std::pair<CSSSelector::PseudoClassType, MatchElement>, 32> pseudoClasses;
};
void recursivelyCollectFeaturesFromSelector(SelectorFeatures&, const CSSSelector&, MatchElement = MatchElement::Subject);
};
Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.cpp (258320 => 258321)
--- trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.cpp 2020-03-12 13:30:10 UTC (rev 258321)
@@ -196,13 +196,15 @@
m_classInvalidationRuleSets.clear();
m_attributeInvalidationRuleSets.clear();
+ m_pseudoClassInvalidationRuleSets.clear();
+
m_cachedHasComplexSelectorsForStyleAttribute = WTF::nullopt;
m_features.shrinkToFit();
}
-template<typename RuleFeatureType>
-static Vector<InvalidationRuleSet>* ensureInvalidationRuleSets(const AtomString& key, HashMap<AtomString, std::unique_ptr<Vector<InvalidationRuleSet>>>& ruleSetMap, const HashMap<AtomString, std::unique_ptr<Vector<RuleFeatureType>>>& ruleFeatures)
+template<typename KeyType, typename RuleFeatureType, typename Hash, typename HashTraits>
+static Vector<InvalidationRuleSet>* ensureInvalidationRuleSets(const KeyType& key, HashMap<KeyType, std::unique_ptr<Vector<InvalidationRuleSet>>, Hash, HashTraits>& ruleSetMap, const HashMap<KeyType, std::unique_ptr<Vector<RuleFeatureType>>, Hash, HashTraits>& ruleFeatures)
{
return ruleSetMap.ensure(key, [&] () -> std::unique_ptr<Vector<InvalidationRuleSet>> {
auto* features = ruleFeatures.get(key);
@@ -241,6 +243,11 @@
return ensureInvalidationRuleSets(attributeName, m_attributeInvalidationRuleSets, m_features.attributeRules);
}
+const Vector<InvalidationRuleSet>* ScopeRuleSets::pseudoClassInvalidationRuleSets(CSSSelector::PseudoClassType pseudoClass) const
+{
+ return ensureInvalidationRuleSets(pseudoClass, m_pseudoClassInvalidationRuleSets, m_features.pseudoClassRules);
+}
+
bool ScopeRuleSets::hasComplexSelectorsForStyleAttribute() const
{
auto compute = [&] {
Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.h (258320 => 258321)
--- trunk/Source/WebCore/style/StyleScopeRuleSets.h 2020-03-12 10:39:05 UTC (rev 258320)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.h 2020-03-12 13:30:10 UTC (rev 258321)
@@ -65,6 +65,7 @@
const Vector<InvalidationRuleSet>* classInvalidationRuleSets(const AtomString& className) const;
const Vector<InvalidationRuleSet>* attributeInvalidationRuleSets(const AtomString& attributeName) const;
+ const Vector<InvalidationRuleSet>* pseudoClassInvalidationRuleSets(CSSSelector::PseudoClassType) const;
bool hasComplexSelectorsForStyleAttribute() const;
@@ -101,6 +102,7 @@
mutable RefPtr<RuleSet> m_uncommonAttributeRuleSet;
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>>, WTF::IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> m_pseudoClassInvalidationRuleSets;
mutable Optional<bool> m_cachedHasComplexSelectorsForStyleAttribute;