commit efccffff3bce0decd79bd8ee5e125d7a085934de
parent 0cab465a411451f2aec502b8efebbff1ea4294ba
Author: Daniil Sakhapov <sakhapov@chromium.org>
Date: Fri, 28 Nov 2025 14:53:51 +0000
Bug 2002973 [wpt PR 56335] - Revert "Implement border-shape hit testing", a=testonly
Automatic update from web-platform-tests
Revert "Implement border-shape hit testing"
This reverts commit 709cf5c977c287723630f2b4e8a521e0c2067f3e.
Reason for revert: perf regressions, null ptr deref
Original change's description:
> Implement border-shape hit testing
>
> So far it's specified not to affect layout, but we want it to be
> hit-testable. Existing hit-testing code normally does a simple border
> box check first before going into any clipping details inside, but,
> since the border-shape can be painted outside the border box, we need
> to check its border-shape bounding box for hit-testing.
>
> To do so, and also not to lose the border when the shape is painted
> outside the viewport, this CL computes scrollable (layout) overflow
> and uses that box for hit-testing purposes. That box is propagated up,
> meaning all the ancestors will now account for scrollable overflow
> of a descendant element with border-shape.
>
> The hit test of PaintLayer will be done in the follow-up and tracked
> in crbug.com/456675133
>
> Bug: 370041145
> Change-Id: I9f548620db37732c198243940325216c85e8f34e
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6862996
> Reviewed-by: Philip Rogers <pdr@chromium.org>
> Commit-Queue: Daniil Sakhapov <sakhapov@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1550496}
Bug: 370041145
Change-Id: Ie22c2cacb595e01119e32cc07f6ab0acf385117e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7208865
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Daniil Sakhapov <sakhapov@chromium.org>
Reviewed-by: Steinar H Gunderson <sesse@chromium.org>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1551401}
--
wpt-commits: 1d894d7ad32a0363baf3b3f740e51a2f6e3c888d
wpt-pr: 56335
Diffstat:
5 files changed, 0 insertions(+), 317 deletions(-)
diff --git a/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test-overflow-clip-margin.html b/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test-overflow-clip-margin.html
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Borders Test: hit testing border-shape circle with overflow clip parent</title>
-<link rel="help" href="https://drafts.csswg.org/css-borders-4/#border-shape">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<style>
- #outer {
- width: 100px;
- height: 100px;
- overflow: clip;
- overflow-clip-margin: 50px;
- }
- #target {
- width: 100px;
- height: 100px;
- border-shape: circle(45px at 50% 50%);
- border: 10px solid purple;
- background: green;
- }
-</style>
-<div id="outer">
- <div id="target"></div>
-</div>
-<script>
- function getCenter(el) {
- const rect = el.getBoundingClientRect();
- return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
- }
-
- function polarToXY(center, radius, angleRad) {
- return {
- x: Math.round(center.x + radius * Math.cos(angleRad)),
- y: Math.round(center.y + radius * Math.sin(angleRad))
- };
- }
-
- promise_test(async t => {
- const target = document.getElementById('target');
- const center = getCenter(target);
- const strokeWidthHalf = 5; // 10px border-width
- const circleRadius = 45 + strokeWidthHalf;
-
- // Check a point on the edge of the circle (should hit due to overflow-clip-margin).
- const { x, y } = polarToXY(center, circleRadius - 2, 0); // angle 0deg, right edge of the circle, -2px just to make it inside the border-shape contour.
- let hit = false;
- let hitBody = false;
- target.addEventListener('pointerdown', () => { hit = true; }, { once: true });
- document.body.addEventListener('pointerdown', () => { hitBody = true; }, { once: true });
- await new test_driver.Actions().pointerMove(x, y).pointerDown().pointerUp().send();
- assert_true(hit, 'Point outside the clipped part should hit the border-shape due to overflow-clip-margin');
- });
-</script>
diff --git a/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test-overflow-clip.html b/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test-overflow-clip.html
@@ -1,56 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Borders Test: hit testing border-shape circle with overflow clip parent</title>
-<link rel="help" href="https://drafts.csswg.org/css-borders-4/#border-shape">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<style>
- #outer {
- width: 100px;
- height: 100px;
- overflow: clip;
- }
- #target {
- width: 100px;
- height: 100px;
- border-shape: circle(50% at 50% 50%);
- stroke: purple;
- stroke-width: 10px;
- background: green;
- }
-</style>
-<div id="outer">
- <div id="target"></div>
-</div>
-<script>
- function getCenter(el) {
- const rect = el.getBoundingClientRect();
- return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
- }
-
- function polarToXY(center, radius, angleRad) {
- return {
- x: Math.round(center.x + radius * Math.cos(angleRad)),
- y: Math.round(center.y + radius * Math.sin(angleRad))
- };
- }
-
- promise_test(async t => {
- const target = document.getElementById('target');
- const center = getCenter(target);
- const strokeWidthHalf = 5; // 10px stroke-width
- const circleRadius = 50 + strokeWidthHalf; // 100px box, circle(50%) => 50px radius
-
- // Check a point on the edge of the circle (shouldn't hit as clipped).
- const { x, y } = polarToXY(center, circleRadius - 2, 0); // angle 0deg, right edge of the circle, -2px just to make it inside the border-shape contour.
- let hit = false;
- let hitBody = false;
- target.addEventListener('pointerdown', () => { hit = true; }, { once: true });
- document.body.addEventListener('pointerdown', () => { hitBody = true; }, { once: true });
- await new test_driver.Actions().pointerMove(x, y).pointerDown().pointerUp().send();
- assert_false(hit, 'Point outside the clipped part should not hit the border-shape');
- assert_true(hitBody, 'Point outside the clipped part should hit body');
- });
-</script>
diff --git a/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test-siblings.html b/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test-siblings.html
@@ -1,101 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Borders Test: hit testing border-shape circle depth order with siblings</title>
-<link rel="help" href="https://drafts.csswg.org/css-borders-4/#border-shape">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<style>
- .container {
- position: relative;
- width: 200px;
- height: 100px;
- }
-
- .sibling {
- position: absolute;
- width: 100px;
- height: 100px;
- top: 0;
- left: 0;
- background: blue;
- opacity: 0.5;
- }
-
- #target {
- position: absolute;
- left: 50px;
- width: 80px;
- height: 80px;
- border-shape: circle(45px at 50% 50%);
- border: 10px solid purple;
- background: green;
- }
-
- .sibling2 {
- position: absolute;
- left: 100px;
- width: 100px;
- height: 100px;
- background: red;
- opacity: 0.5;
- }
-</style>
-<div class="container">
- <div class="sibling" id="before"></div>
- <div id="target"></div>
- <div class="sibling2" id="after"></div>
-</div>
-<script>
- function getRect(el) {
- return el.getBoundingClientRect();
- }
- function getCenter(el) {
- const r = getRect(el);
- return { x: r.left + r.width / 2, y: r.top + r.height / 2 };
- }
- function polarToXY(center, radius, angleRad) {
- return {
- x: Math.round(center.x + radius * Math.cos(angleRad)),
- y: Math.round(center.y + radius * Math.sin(angleRad))
- };
- }
-
- let hit = null;
- function handler(e) { hit = e.currentTarget.id; }
-
- const before = document.getElementById('before');
- const target = document.getElementById('target');
- const after = document.getElementById('after');
- const center = getCenter(target);
- const strokeWidthHalf = 5; // 10px stroke-width
- const radius = 45 + strokeWidthHalf;
-
- promise_test(async t => {
- // Checking hit on upper left part of the circle border (should be before).
- hit = null;
- before.addEventListener('pointerdown', handler, { once: true });
- const { x, y } = polarToXY(center, radius + 1, (3 * Math.PI) / 4); // angle 135deg, top-left edge of the circle
- await new test_driver.Actions().pointerMove(x, y).pointerDown().pointerUp().send();
- assert_equals(hit, 'before', 'Before sibling hit while not overlapping');
- });
-
- promise_test(async t => {
- // Checking hit on left part of the circle border (should be target).
- hit = null;
- target.addEventListener('pointerdown', handler, { once: true });
- const { x, y } = polarToXY(center, radius, Math.PI); // angle 180deg, left edge of the circle
- await new test_driver.Actions().pointerMove(x, y).pointerDown().pointerUp().send();
- assert_equals(hit, 'target', 'Target has higher z-index than before sibling while overlapping');
- });
-
- promise_test(async t => {
- // Checking hit on right part of the circle (should be after).
- hit = null;
- after.addEventListener('pointerdown', handler, { once: true });
- const { x, y } = polarToXY(center, radius, 0); // angle 0deg, right edge of the circle
- await new test_driver.Actions().pointerMove(x, y).pointerDown().pointerUp().send();
- assert_equals(hit, 'after', 'Target has lower z-index than after sibling while overlapping');
- });
-</script>
diff --git a/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test.html b/testing/web-platform/tests/css/css-borders/tentative/border-shape-circle-hit-test.html
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Borders Test: hit testing border-shape circle</title>
-<link rel="help" href="https://drafts.csswg.org/css-borders-4/#border-shape">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<style>
- #target {
- width: 100px;
- height: 100px;
- border-shape: circle(45px at 50% 50%);
- border: 10px solid purple;
- background: green;
- }
-</style>
-<div id="target"></div>
-<script>
- function getCenter(el) {
- const rect = el.getBoundingClientRect();
- return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
- }
-
- function polarToXY(center, radius, angleRad) {
- return {
- x: Math.round(center.x + radius * Math.cos(angleRad)),
- y: Math.round(center.y + radius * Math.sin(angleRad))
- };
- }
-
- promise_test(async t => {
- const target = document.getElementById('target');
- const center = getCenter(target);
- const strokeWidthHalf = 5; // 10px border-width
- const circleRadius = 45 + strokeWidthHalf;
-
- // Check points from center to the edge of the circle (should hit).
- for (let r = 0; r < circleRadius; r += 5) {
- let angle = Math.random() * 2 * Math.PI;
- const { x, y } = polarToXY(center, r, angle);
- let hit = false;
- target.addEventListener('pointerdown', () => { hit = true; }, { once: true });
- await new test_driver.Actions().pointerMove(x, y).pointerDown().pointerUp().send();
- assert_true(hit, `Point at radius ${r} should hit the element`);
- }
-
- // Check a point just outside the circle (should not hit).
- const { x: outX, y: outY } = polarToXY(center, circleRadius + 1, Math.PI / 4);
- let hit = false;
- target.addEventListener('pointerdown', () => { hit = true; }, { once: true });
- await new test_driver.Actions().pointerMove(outX, outY).pointerDown().pointerUp().send();
- assert_false(hit, 'Point outside the border-shape should not hit the element');
- });
-</script>
diff --git a/testing/web-platform/tests/css/css-borders/tentative/border-shape/border-shape-hit-test-overflow.html b/testing/web-platform/tests/css/css-borders/tentative/border-shape/border-shape-hit-test-overflow.html
@@ -1,50 +0,0 @@
-<!DOCTYPE html>
-<title>CSS Borders Test: hit testing border-shape with overflow</title>
-<link rel="help" href="https://drafts.csswg.org/css-borders-4/#border-shape">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<style>
- #bs-target {
- width: 200px;
- height: 200px;
- border-shape: circle(50% at 50% 50%);
- border: 20px solid purple;
- background: green;
- }
-
- #bs-target:hover {
- border-color: orange;
- }
-
- #overflower {
- width: 400px;
- height: 25px;
- background: lightblue;
- text-align: end;
- }
-</style>
-
-border-shape:<br>
-<div id="bs-target">
- <div id="overflower">hover here</div>
-</div>
-<script>
- promise_test(async t => {
- let eventTarget;
- const target = document.getElementById('bs-target');
- const overflower = document.getElementById('overflower');
- const x = 350, y = 60;
- const rect = target.getBoundingClientRect();
- assert_false(
- x >= rect.left && x <= rect.right &&
- y >= rect.top && y <= rect.bottom,
- 'Point should be outside the border-shape element');
-
- target.addEventListener('mouseover', (e) => { eventTarget = e.target; }, { once: true });
- await new test_driver.Actions().pointerMove(x, y).send();
- assert_equals(eventTarget, overflower, 'Event target should be the overflowing element');
- });
-</script>