tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 5e0e11d1cf9bed58c00af5f636dd9ceb18c8ea5e
parent 563cf05a5f349835f7c95487efa07c74a44504ba
Author: Steve Kobes <skobes@chromium.org>
Date:   Wed, 26 Nov 2025 08:54:29 +0000

Bug 2001679 [wpt PR 56189] - Paint transition pseudos on top of everything else in the scope., a=testonly

Automatic update from web-platform-tests
Paint transition pseudos on top of everything else in the scope.

Since crrev.com/1546589, the ::view-transition pseudo's PaintLayer is a
child of the scope's PaintLayer.

This patch implements custom paint order logic to ensure that the
pseudo tree behaves like an overlay, regardless of any higher z-index
that may be set on the scope's non-participating descendants.

Also test the crash repro from https://crbug.com/445406431#comment3
(self-participating scope with high z-index child also participating).

Bug: 421927605, 445406431
Change-Id: Ifac38969abbb82ea9a4ca67e6b03fffe99d52044
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7178180
Commit-Queue: Steve Kobes <skobes@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1549132}

--

wpt-commits: 7733484b3e7c79cc8fc6288500d5c30ea52ffa36
wpt-pr: 56189

Diffstat:
Atesting/web-platform/tests/css/css-view-transitions/scoped/crashtests/zindex-part.html | 30++++++++++++++++++++++++++++++
Atesting/web-platform/tests/css/css-view-transitions/scoped/paint-order-ref.html | 32++++++++++++++++++++++++++++++++
Atesting/web-platform/tests/css/css-view-transitions/scoped/paint-order.html | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/testing/web-platform/tests/css/css-view-transitions/scoped/crashtests/zindex-part.html b/testing/web-platform/tests/css/css-view-transitions/scoped/crashtests/zindex-part.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html class="test-wait"> +<head> +<style> + +#scope { + position: relative; width: 100px; height: 100px; + background: #ddd; contain: strict; +} +#part { + position: absolute; top: 10px; left: 10px; + width: 80px; height: 80px; background: #8cf; + z-index: 1; view-transition-name: foo; +} + +</style> +</head> +<body> +<div id=scope><div id=part></div></div> +<script> + +onload = async () => { + t = scope.startViewTransition(() => {}); + await t.finished; + document.documentElement.classList.remove('test-wait'); +}; + +</script> +</body> +</html> diff --git a/testing/web-platform/tests/css/css-view-transitions/scoped/paint-order-ref.html b/testing/web-platform/tests/css/css-view-transitions/scoped/paint-order-ref.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<style> + #scope { + position: relative; width: 200px; height: 100px; + background: white; contain: strict; + } + #nonpart1 { + position: absolute; top: 40px; left: 20px; + width: 50px; height: 50px; background: #a4f; + } + #nonpart2 { + position: absolute; top: 20px; left: 30px; + width: 50px; height: 50px; background: #f88; + } + #vt { + position: relative; width: 200px; height: 100px; + top: -100px; background: rgba(0, 0, 0, 0.1); + will-change: transform; + } + #part { + position: absolute; top: 30px; left: 50px; + width: 50px; height: 50px; background: #8cf; + } + +</style> +<div id=scope> + <div id=nonpart1></div> + <div id=nonpart2></div> +</div> +<div id=vt> + <div id=part></div> +</div> diff --git a/testing/web-platform/tests/css/css-view-transitions/scoped/paint-order.html b/testing/web-platform/tests/css/css-view-transitions/scoped/paint-order.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<head> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="paint-order-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="/web-animations/testcommon.js"></script> +<style> + +#scope { + position: relative; width: 200px; height: 100px; + background: white; contain: strict; + view-transition-name: none; +} +#part { + position: absolute; top: 10px; left: 10px; + width: 50px; height: 50px; background: #8cf; + z-index: 1; view-transition-name: foo; +} +#higher-nonpart { + position: absolute; top: 20px; left: 30px; + z-index: 2; width: 50px; height: 50px; background: #f88; +} +#lower-nonpart { + position: absolute; top: 40px; left: 20px; + z-index: -1; width: 50px; height: 50px; background: #a4f; +} +::view-transition { background: rgba(0, 0, 0, 0.1); } +::view-transition-group(*) { animation-play-state: paused; } +::view-transition-new(*) { + animation: unset; opacity: 1; + transform: translateX(40px) translateY(20px); +} +::view-transition-old(*) { animation: unset; opacity: 0; } + +</style> +</head> +<body> +<div id=scope> + <div id=part></div> + <div id=higher-nonpart></div> + <div id=lower-nonpart></div> +</div> +<script> + +const scope = document.querySelector("#scope"); +failIfNot(scope.startViewTransition, "Missing element.startViewTransition"); + +async function runTest() { + await waitForCompositorReady(); + scope.startViewTransition(() => requestAnimationFrame(takeScreenshot)); +} +onload = () => runTest(); + +</script> +</body> +</html>