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
109 lines
4.0 KiB
HTML
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>
|