Files
sousa-gecko/testing/web-platform/tests/css/css-cascade/scope-visited-cssom.html
T
Steinar H. Gunderson 8cc6fa6964 Bug 1970357 [wpt PR 52952] - Return the actual :visited color from getComputedStyle()., a=testonly
Automatic update from web-platform-tests
Return the actual :visited color from getComputedStyle().

Now that we have partitioning of the history, the :visited status of a
link is no longer sensitive, and we can think about removing all the
code for tracking the color of two alternate realities.

This flag (off by default, since we cannot enable it before we are sure
that PartitionVisitedLinkDatabaseWithSelfLinks isn't going away -- also,
there are still some issues with it) prepares for such a reality;
it applies the :visited color onto the ComputedStyle as normal, which
means we get the same external behavior but in a form that we can easily
turn off.  When it's been on in stable for enough releases, we can start
removing the actual code for maintaining separate :visited colors.

Change-Id: I512437bc4145c463112109dd8c48370add15799a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6586806
Commit-Queue: Steinar H Gunderson <sesse@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Auto-Submit: Steinar H Gunderson <sesse@chromium.org>
Reviewed-by: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1469285}

--

wpt-commits: f362ddf4c48389e25390c2dddb415be9b34247d9
wpt-pr: 52952
2025-06-19 08:16:06 +00:00

315 lines
9.8 KiB
HTML

<!DOCTYPE html>
<title>@scope - :visited and CSSOM</title>
<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scoped-styles">
<link rel="help" href="https://drafts.csswg.org/selectors-4/#link">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<main id=main></main>
<style>
:where(:visited, :link), :where(div) {
background-color: white;
}
</style>
<!--
Both #visited and #unvisited should appear to be in an unvisited state
through getComputedStyle.
-->
<!-- :visited/:link in scoped selector -->
<template id=test_link>
<style>
@scope (main) {
:link { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_link.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(0, 128, 0)');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(0, 128, 0)');
}, ':link as scoped selector');
</script>
<template id=test_visited>
<style>
@scope (main) {
:visited { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_visited.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':visited as scoped selector');
</script>
<template id=test_not_link>
<style>
@scope (main) {
:not(:link) { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_not_link.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':not(:link) as scoped selector');
</script>
<template id=test_not_visited>
<style>
@scope (main) {
:not(:visited) { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_not_visited.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':not(:visited) as scoped selector');
</script>
<!-- :visited/:link in root -->
<template id=test_link_root>
<style>
@scope (main :link) {
div { background-color: green; }
}
</style>
<a id=visited href=""><div></div></a>
<a id=unvisited href="x"><div></div></a>
</template>
<script>
test((t) => {
main.append(test_link_root.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited.firstElementChild).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited.firstElementChild).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':link as scoping root');
</script>
<template id=test_visited_root>
<style>
@scope (main :visited) {
div { background-color: green; }
}
</style>
<a id=visited href=""><div></div></a>
<a id=unvisited href="x"><div></div></a>
</template>
<script>
test((t) => {
main.append(test_visited_root.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited.firstElementChild).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited.firstElementChild).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':visited as scoping root');
</script>
<template id=test_not_visited_root>
<style>
@scope (main :not(:visited)) {
div { background-color: green; }
}
</style>
<a id=visited href=""><div></div></a>
<a id=unvisited href="x"><div></div></a>
</template>
<script>
test((t) => {
main.append(test_not_visited_root.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited.firstElementChild).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited.firstElementChild).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':not(:visited) as scoping root');
</script>
<template id=test_not_link_root>
<style>
@scope (main :not(:link)) {
div { background-color: green; }
}
</style>
<a id=visited href=""><div></div></a>
<a id=unvisited href="x"><div></div></a>
</template>
<script>
test((t) => {
main.append(test_not_link_root.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited.firstElementChild).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited.firstElementChild).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':not(:link) as scoping root');
</script>
<!-- :visited/:link in scoping root, with inner :scope -->
<template id=test_link_root_scope>
<style>
@scope (main :link) {
:scope { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_link_root_scope.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':link as scoping root, :scope');
</script>
<template id=test_visited_root_scope>
<style>
@scope (main :visited) {
:scope { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_visited_root_scope.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':visited as scoping root, :scope');
</script>
<template id=test_not_visited_root_scope>
<style>
@scope (main :not(:visited)) {
:scope { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_not_visited_root_scope.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':not(:visited) as scoping root, :scope');
</script>
<template id=test_not_link_root_scope>
<style>
@scope (main :not(:link)) {
:scope { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_not_link_root_scope.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':not(:link) as scoping root, :scope');
</script>
<!-- :visited/:link in scoping limit -->
<template id=test_link_scoping_limit>
<style>
@scope (main) to (:link) {
* { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_link_scoping_limit.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':link as scoping limit');
</script>
<template id=test_visited_scoping_limit>
<style>
@scope (main) to (:visited) {
* { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_visited_scoping_limit.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':visited as scoping limit');
</script>
<template id=test_not_link_scoping_limit>
<style>
@scope (main) to (:not(:link)) {
* { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_not_link_scoping_limit.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(0, 128, 0)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(0, 128, 0)', 'unvisited');
}, ':not(:link) as scoping limit');
</script>
<template id=test_not_visited_scoping_limit>
<style>
@scope (main) to (:not(:visited)) {
* { background-color: green; }
}
</style>
<a id=visited href=""></a>
<a id=unvisited href="x"></a>
</template>
<script>
test((t) => {
main.append(test_not_visited_scoping_limit.content.cloneNode(true));
t.add_cleanup(() => main.replaceChildren());
assert_equals(getComputedStyle(visited).backgroundColor, 'rgb(255, 255, 255)', 'visited');
assert_equals(getComputedStyle(unvisited).backgroundColor, 'rgb(255, 255, 255)', 'unvisited');
}, ':not(:visited) as scoping limit');
</script>