Files
sousa-gecko/testing/web-platform/tests/css/css-overflow/hit-test-stacking-context-parent-border-radius.html
T
Peng Zhou 987a77d0eb Bug 2040096 [wpt PR 59911] - PaintLayer: fix border radius hit test with perspective transform, a=testonly
Automatic update from web-platform-tests
PaintLayer: fix border radius hit test with perspective transform

`HitTestClippedOutByBorderRadius` mapped an axis-aligned rect,
which lost perspective details. Map the hit-test quad with `
SourceToDestinationProjection` after applying the transform
container's paint offset, and include the transform container
when checking ancestor `border-radius` clips.

Bug: 40811639, 456164629, 452333498
Change-Id: I3436446ece4299f9ba5ac7ee3458e2e2e46a015e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7106639
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Peng Zhou <pengzhou@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1631502}

--

wpt-commits: c7f4ae7080ae6a45ad3a10c53d61b7beee44e153
wpt-pr: 59911
2026-05-19 08:26:43 +00:00

109 lines
4.0 KiB
HTML

<!DOCTYPE html>
<title>Hit Test with Stacking Context</title>
<link rel="author" title="Peng Zhou" href="mailto:zhoupeng.1996@bytedance.com">
<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-radius">
<link rel="help" href="https://issues.chromium.org/issues/40811639">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#parent {
width: 100px;
height: 100px;
overflow: hidden;
border-radius: 50%;
}
#child {
width: 100px;
height: 100px;
background-color: green;
}
</style>
<div id="wrapper">
<div id="parent">
<div id="child"></div>
</div>
</div>
<script>
function elementFromPointOutsideParentBorderRadius() {
const rect = document.getElementById('parent').getBoundingClientRect();
return document.elementFromPoint(rect.left + 27, rect.bottom - 5);
}
function elementFromPointInsideParentBorderRadius() {
const rect = document.getElementById('parent').getBoundingClientRect();
return document.elementFromPoint(rect.left + 32, rect.bottom - 10);
}
function runTest(fn, description) {
wrapper.style = '';
test(fn, description);
// reset style
wrapper.style = 'perspective: 1px;';
test(fn, `${description} with perspective`);
wrapper.style = '';
}
runTest(() => {
assert_equals(elementFromPointOutsideParentBorderRadius(), wrapper);
assert_equals(elementFromPointInsideParentBorderRadius(), child);
}, 'Hit testing respects border-radius clipping on elements without creating stacking contexts');
runTest(() => {
child.style = 'will-change: transform';
assert_equals(elementFromPointOutsideParentBorderRadius(), wrapper);
assert_equals(elementFromPointInsideParentBorderRadius(), child);
child.style = '';
}, 'Hit testing respects border-radius clipping on elements with will-change transform');
runTest(() => {
child.style = 'opacity: 0.2';
assert_equals(elementFromPointOutsideParentBorderRadius(), wrapper);
assert_equals(elementFromPointInsideParentBorderRadius(), child);
child.style = '';
}, 'Hit testing respects border-radius clipping on elements with opacity < 1');
runTest(() => {
child.style = 'height: 1000px; transform: translate(0, -500px);';
assert_equals(elementFromPointOutsideParentBorderRadius(), wrapper);
assert_equals(elementFromPointInsideParentBorderRadius(), child);
child.style = '';
}, 'Hit testing respects border-radius clipping on elements with a transform property');
runTest(() => {
child.style = 'position: relative; top: 30px;';
assert_equals(elementFromPointOutsideParentBorderRadius(), wrapper);
assert_equals(elementFromPointInsideParentBorderRadius(), child);
child.style = '';
}, 'Hit testing respects border-radius clipping on elements with a PaintOffset from the container');
runTest(() => {
child.style = 'position: relative; top: 30px; overflow: scroll;';
assert_equals(elementFromPointOutsideParentBorderRadius(), wrapper);
assert_equals(elementFromPointInsideParentBorderRadius(), child);
child.style = '';
}, 'Hit testing respects border-radius clipping on elements with a PaintOffsetTranslation from the container');
test(() => {
child.style = 'position: relative; top: 30px; overflow: scroll;';
document.body.style.margin = '50px';
const container = document.createElement('div');
container.style.width = '50px';
container.style.height = '50px';
container.style.overflow = 'scroll';
container.appendChild(document.getElementById('parent'));
wrapper.appendChild(container);
container.scrollTop = container.scrollHeight;
container.scrollLeft = 0;
const offset = container.getBoundingClientRect().left;
const curY = offset + 10;
assert_equals(document.elementFromPoint(offset, curY), container);
assert_equals(document.elementFromPoint(offset + 10, curY), child);
wrapper.style = 'perspective: 1px;';
assert_equals(document.elementFromPoint(offset, curY), container);
assert_equals(document.elementFromPoint(offset + 10, curY), child);
wrapper.style = '';
child.style = '';
}, 'Hit testing respects border-radius clipping on elements with a different coordinate space');
</script>