commit 983359260a4012b3117326d771ab2bda2a60f319
parent 58abf99335c3d64233863fc70ac42ae59b499ff7
Author: Anders Hartvoll Ruud <andruud@chromium.org>
Date: Wed, 15 Oct 2025 08:22:21 +0000
Bug 1993507 [wpt PR 55320] - Ignore context.is_sub_selector when disallowing :visited, a=testonly
Automatic update from web-platform-tests
Ignore context.is_sub_selector when disallowing :visited
We currently have a bug where, given a link inside a visited link,
a selector like ':visited > a#inner' can match, but a selector like
':visited > #inner' (i.e. a single rightmost simple selector) can not.
This bug comes from a test on 'context.is_sub_selector', which is a flag
that is set when we're matching non-rightmost simple selectors within
a compound. I still [1] don't understand why this test is here,
and given Issue 449573618, it seems that it's just wrong.
Note that the 'context.in_nested_complex_selector' part was added
in CL:2476214 to "disable" the 'context.is_sub_selector' test
within :is()/:where(), presumably because it caused some trouble
there as well.
The reason this is being looked at at all, is that WebKit accidentally
included this in Interop 2025 [2], and it's easier to just fix it
than to exclude the test.
This is a web-facing change: ':visited > a#inner' will not match
anymore in a link-within-link scenario (see test case). This aligns
with how Safari and Firefox already works.
Note: :visited in general isn't strictly specified, but the WPT
takes this into account (see comment in the test).
Fixed: 449573618
[1] See one of the unresolved comments in CL:2476214 (five years ago).
[2] https://github.com/web-platform-tests/wpt/commit/80703b2603cb65f763a11f61b1abe092d11b2388
Change-Id: I0a01ee5e85068945946545044ce70ba00b4d32dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7021753
Commit-Queue: Anders Hartvoll Ruud <andruud@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1527380}
--
wpt-commits: 94d3f9ddb8a78cb89360a93f6e5d16f97b7ef4b9
wpt-pr: 55320
Diffstat:
2 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/testing/web-platform/tests/css/selectors/visited-in-visited-compound-ref.html b/testing/web-platform/tests/css/selectors/visited-in-visited-compound-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Behavior of :visited with a compound subject selector (ref)</title>
+<style>
+ :visited > #inner { color: red; }
+</style>
+<a href="" id=outer>Visited1</a>
+<script>
+ window.onload = () => {
+ // Use script, since the parser can't produce this.
+ let inner = document.createElement('a');
+ inner.setAttribute('href', '');
+ inner.setAttribute('id', 'inner');
+ inner.textContent = 'Visited2';
+ outer.append(inner);
+ }
+</script>
diff --git a/testing/web-platform/tests/css/selectors/visited-in-visited-compound.html b/testing/web-platform/tests/css/selectors/visited-in-visited-compound.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Behavior of :visited with a compound subject selector</title>
+<!--
+ Note: this test is intentionally not specific about the exact expected
+ result, since the exact behavior is not specified well at the moment.
+ As long as a#inner and #inner (see -ref.html) behaves the same way
+ for the same DOM, we consider that a pass.
+-->
+<link rel="help" href="https://drafts.csswg.org/selectors/#visited-pseudo">
+<link rel="match" href="visited-in-visited-compound-ref.html">
+<style>
+ :visited > a#inner { color: red; }
+</style>
+<a href="" id=outer>Visited1</a>
+<script>
+ window.onload = () => {
+ // Use script, since the parser can't produce this.
+ let inner = document.createElement('a');
+ inner.setAttribute('href', '');
+ inner.setAttribute('id', 'inner');
+ inner.textContent = 'Visited2';
+ outer.append(inner);
+ }
+</script>