Modified: trunk/LayoutTests/imported/w3c/ChangeLog (294097 => 294098)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2022-05-12 08:44:29 UTC (rev 294097)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2022-05-12 12:40:27 UTC (rev 294098)
@@ -1,5 +1,17 @@
2022-05-12 Tim Nguyen <n...@apple.com>
+ [:has() pseudo-class] Support invalidation for :target pseudo-class
+ https://bugs.webkit.org/show_bug.cgi?id=240329
+
+ Reviewed by Antti Koivisto.
+
+ Extend current test to cover more cases, and mark it as passing.
+
+ * web-platform-tests/css/selectors/invalidation/target-pseudo-in-has-expected.txt:
+ * web-platform-tests/css/selectors/invalidation/target-pseudo-in-has.html:
+
+2022-05-12 Tim Nguyen <n...@apple.com>
+
Re-import css/selectors WPT from revision 4653e9128742e2c2609e76f04f4084cdc10ffead
https://bugs.webkit.org/show_bug.cgi?id=240332
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has-expected.txt (294097 => 294098)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has-expected.txt 2022-05-12 08:44:29 UTC (rev 294097)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has-expected.txt 2022-05-12 12:40:27 UTC (rev 294098)
@@ -1,5 +1,7 @@
-parent color must be yellow green when containing :target
-link to #fragment link to #
+link to #fragment link to #fragment2 link to #fragment3 link to #
+1: Must be green when containing :target
+2: Must be green when containing :target
+3: Must be green when containing :target
-FAIL CSS Selectors Invalidation: target pseudo in :has() argument assert_equals: parent should be yellowgreen on fragment click expected "rgb(154, 205, 50)" but got "rgb(0, 128, 0)"
+PASS CSS Selectors Invalidation: :target pseudo-class in :has() argument
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has.html (294097 => 294098)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has.html 2022-05-12 08:44:29 UTC (rev 294097)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has.html 2022-05-12 12:40:27 UTC (rev 294098)
@@ -1,36 +1,93 @@
<!DOCTYPE html>
<meta charset="utf-8" />
-<title>CSS Selectors Invalidation: target pseudo in :has() argument</title>
+<title>CSS Selectors Invalidation: :target pseudo-class in :has() argument</title>
<link rel="help" href=""
<script src=""
<script src=""
<style>
- #parent1 { color: green; }
- #parent1:has(:target) { color: yellowgreen; }
+ #parent1 { color: grey; }
+ #parent1:has(:target) { color: green; }
+
+ #parent2 { color: blue; }
+ #parent2:has(:not(:target)) { color: grey; }
+ #parent2:has(:target) { color: green; }
+
+ #parent3 { color: green; }
+ #parent3:not(:has(:target)) { color: grey; }
</style>
+<a href="" to #fragment</a>
+<a href="" to #fragment2</a>
+<a href="" to #fragment3</a>
+<a href="" to #</a>
<div id="parent1">
- <div id="fragment">parent color must be yellow green when containing :target</div>
- <a href="" to #fragment</a>
- <a href="" to #</a>
+ 1:
+ <span id="fragment">Must be green when containing :target</span>
</div>
+<div id="parent2">
+ 2:
+ <span id="fragment2">Must be green when containing :target</span>
+</div>
+<div id="parent3">
+ 3:
+ <span id="fragment3">Must be green when containing :target</span>
+</div>
<script>
- test((t) => {
+ const GREEN = "rgb(0, 128, 0)";
+ const GREY = "rgb(128, 128, 128)";
+ const BLUE = "rgb(0, 0, 255)";
+
+ function fragmentLink(fragment) {
+ return document.querySelector(`a[href=""
+ }
+
+ promise_test(async () => {
const fragment = document.querySelector("#fragment");
- const toFragment = document.querySelector(`a[href=""
- const toTop = document.querySelector(`a[href=""
+ const fragment2 = document.querySelector("#fragment2");
+ const fragment3 = document.querySelector("#fragment3");
location.hash = "";
- assert_equals(getComputedStyle(parent1).color, "rgb(0, 128, 0)", "parent should be green");
+ assert_equals(getComputedStyle(parent1).color, GREY, "parent1 should be grey without :target");
+ assert_equals(getComputedStyle(parent2).color, GREY, "parent2 should be grey without :target");
+ assert_equals(getComputedStyle(parent3).color, GREY, "parent3 should be grey without :target");
- toFragment.click();
+ fragmentLink("fragment").click();
assert_true(fragment.matches(":target"));
- assert_equals(getComputedStyle(parent1).color, "rgb(154, 205, 50)", "parent should be yellowgreen on fragment click");
+ assert_equals(getComputedStyle(parent1).color, GREEN, "parent1 should be green on fragment click");
+ assert_equals(getComputedStyle(parent2).color, GREY, "parent2 should be grey without :target");
+ assert_equals(getComputedStyle(parent3).color, GREY, "parent3 should be grey without :target");
- toTop.click();
+ fragmentLink("fragment2").click();
+ assert_true(fragment2.matches(":target"));
+ assert_equals(getComputedStyle(parent1).color, GREY, "parent1 should be grey without :target");
+ assert_equals(getComputedStyle(parent2).color, GREEN, "parent2 should be green on fragment click");
+ assert_equals(getComputedStyle(parent3).color, GREY, "parent3 should be grey without :target");
+
+ fragment2.remove();
+ assert_equals(getComputedStyle(parent2).color, BLUE, "parent2 should be blue after removing only child");
+
+ parent2.append(fragment2);
+
+ // Wait for :target to be detected.
+ await new Promise(r => requestAnimationFrame(r));
+
+ assert_true(fragment2.matches(":target"));
+ assert_equals(getComputedStyle(parent2).color, GREEN, "parent2 should be green after re-appending :target child");
+
+ fragmentLink("fragment3").click();
+
+ assert_true(fragment3.matches(":target"));
+ assert_equals(getComputedStyle(parent1).color, GREY, "parent1 should be grey without :target");
+ assert_equals(getComputedStyle(parent2).color, GREY, "parent2 should be grey without :target");
+ assert_equals(getComputedStyle(parent3).color, GREEN, "parent3 should be green on fragment click");
+
+ fragmentLink("").click();
+
assert_equals(location.hash, "");
- assert_equals(getComputedStyle(parent1).color, "rgb(0, 128, 0)", "parent should be green without :target");
+ assert_equals(getComputedStyle(parent1).color, GREY, "parent1 should be grey without :target");
+ assert_equals(getComputedStyle(parent2).color, GREY, "parent2 should be grey without :target");
+ assert_equals(getComputedStyle(parent3).color, GREY, "parent3 should be grey without :target");
});
</script>
Modified: trunk/Source/WebCore/ChangeLog (294097 => 294098)
--- trunk/Source/WebCore/ChangeLog 2022-05-12 08:44:29 UTC (rev 294097)
+++ trunk/Source/WebCore/ChangeLog 2022-05-12 12:40:27 UTC (rev 294098)
@@ -1,3 +1,15 @@
+2022-05-12 Tim Nguyen <n...@apple.com>
+
+ [:has() pseudo-class] Support invalidation for :target pseudo-class
+ https://bugs.webkit.org/show_bug.cgi?id=240329
+
+ Reviewed by Antti Koivisto.
+
+ Test: imported/w3c/web-platform-tests/css/selectors/invalidation/target-pseudo-in-has.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::setCSSTarget):
+
2022-05-11 Diego Pino Garcia <dp...@igalia.com>
[WPE] Unreviewed, build fix after r293816
Modified: trunk/Source/WebCore/dom/Document.cpp (294097 => 294098)
--- trunk/Source/WebCore/dom/Document.cpp 2022-05-12 08:44:29 UTC (rev 294097)
+++ trunk/Source/WebCore/dom/Document.cpp 2022-05-12 12:40:27 UTC (rev 294098)
@@ -4870,13 +4870,19 @@
return node->parentOrShadowHostElement();
}
-void Document::setCSSTarget(Element* targetNode)
+void Document::setCSSTarget(Element* newTarget)
{
+ if (m_cssTarget == newTarget)
+ return;
+
+ std::optional<Style::PseudoClassChangeInvalidation> oldInvalidation;
if (m_cssTarget)
- m_cssTarget->invalidateStyleForSubtree();
- m_cssTarget = targetNode;
- if (targetNode)
- targetNode->invalidateStyleForSubtree();
+ emplace(oldInvalidation, *m_cssTarget, { { CSSSelector::PseudoClassTarget, false } });
+
+ std::optional<Style::PseudoClassChangeInvalidation> newInvalidation;
+ if (newTarget)
+ emplace(newInvalidation, *newTarget, { { CSSSelector::PseudoClassTarget, true } });
+ m_cssTarget = newTarget;
}
void Document::registerNodeListForInvalidation(LiveNodeList& list)