Automatic update from web-platform-tests Enforce scroll axis constraints in single-axis containers The SingleAxisScrollContainers feature allows containers to be configured to scroll along only one axis via CSS overflow properties. Previously, scroll APIs like scrollTo and scrollIntoView did not respect these constraints and would incorrectly apply offsets to both axes. This change updates PaintLayerScrollableArea to accurately reflect single-axis scrollability. The scrollable delta for the maximum scroll offset is now set to zero for non-scrollable axes. Adds tests to ensure scrollIntoView and style changes to single-axis scroll container work as expected. Fixed: 496515802 Change-Id: I7cfa72d64feceb0daf060dc77754acf1a0799ee0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7702333 Auto-Submit: Free Debreuil <freedebreuil@google.com> Reviewed-by: Robert Flack <flackr@chromium.org> Commit-Queue: Free Debreuil <freedebreuil@google.com> Cr-Commit-Position: refs/heads/main@{#1614582} -- wpt-commits: 2ae012c5ca1d0c85a886e0ff797d44193f78f8b0 wpt-pr: 58878
162 lines
5.3 KiB
HTML
162 lines
5.3 KiB
HTML
<!doctype html>
|
|
<meta charset="utf-8">
|
|
<title>Single-axis scroll containers with programmatic scroll APIs</title>
|
|
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollto">
|
|
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollby">
|
|
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth">
|
|
<link rel="help" href="https://drafts.csswg.org/cssom-view/#dom-element-scrollheight">
|
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5572">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<style>
|
|
.scroller {
|
|
width: 100px;
|
|
height: 100px;
|
|
scrollbar-width: none;
|
|
}
|
|
.clip-x {
|
|
overflow-x: clip;
|
|
overflow-y: scroll;
|
|
}
|
|
.clip-y {
|
|
overflow-x: scroll;
|
|
overflow-y: clip;
|
|
}
|
|
.rtl {
|
|
direction: rtl;
|
|
}
|
|
.content {
|
|
width: 300px;
|
|
height: 300px;
|
|
}
|
|
</style>
|
|
|
|
<!-- LTR scroller with clipped X -->
|
|
<div class="scroller clip-x">
|
|
<div class="content"></div>
|
|
</div>
|
|
|
|
<!-- RTL scroller with clipped X -->
|
|
<div class="scroller clip-x rtl">
|
|
<div class="content"></div>
|
|
</div>
|
|
|
|
<!-- LTR scroller with clipped Y -->
|
|
<div class="scroller clip-y">
|
|
<div class="content"></div>
|
|
</div>
|
|
|
|
<!-- RTL scroller with clipped Y -->
|
|
<div class="scroller clip-y rtl">
|
|
<div class="content"></div>
|
|
</div>
|
|
|
|
<script>
|
|
function assertOverflowDimensions(scroller, label) {
|
|
assert_equals(scroller.scrollWidth, 300,
|
|
`${label}: scrollWidth retains overflowing content size`);
|
|
assert_equals(scroller.scrollHeight, 300,
|
|
`${label}: scrollHeight retains overflowing content size`);
|
|
}
|
|
|
|
test(() => {
|
|
const scroller = document.querySelector('.scroller.clip-x');
|
|
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'LTR clipped X: scrollLeft is set to default value of 0');
|
|
|
|
scroller.scrollTo(40, 50);
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'LTR clipped X: scrollTo ignores the clipped X-axis');
|
|
assert_equals(scroller.scrollTop, 50,
|
|
'LTR clipped X: scrollTo updates the unclipped Y-axis');
|
|
|
|
scroller.scrollBy(20, 20);
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'LTR clipped X: scrollBy ignores the clipped X-axis');
|
|
assert_equals(scroller.scrollTop, 70,
|
|
'LTR clipped X: scrollBy incrementally updates the unclipped Y-axis (50 + 20 = 70)');
|
|
|
|
scroller.scrollLeft = 70;
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'LTR clipped X: setting scrollLeft ignores the clipped X-axis');
|
|
assert_equals(scroller.scrollTop, 70,
|
|
'LTR clipped X: setting scrollLeft leaves the unclipped Y-axis unchanged');
|
|
|
|
assertOverflowDimensions(scroller, 'LTR clipped X');
|
|
}, 'LTR clipped X');
|
|
|
|
test(() => {
|
|
const scroller = document.querySelector('.scroller.clip-x.rtl');
|
|
|
|
scroller.scrollTo(-40, 50);
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'RTL clipped X: scrollTo ignores the clipped X-axis (negative in RTL)');
|
|
assert_equals(scroller.scrollTop, 50,
|
|
'RTL clipped X: scrollTo updates the unclipped Y-axis');
|
|
|
|
scroller.scrollBy(-20, 20);
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'RTL clipped X: scrollBy ignores the clipped X-axis');
|
|
assert_equals(scroller.scrollTop, 70,
|
|
'RTL clipped X: scrollBy incrementally updates the unclipped Y-axis (50 + 20 = 70)');
|
|
|
|
scroller.scrollLeft = -70;
|
|
assert_equals(scroller.scrollLeft, 0,
|
|
'RTL clipped X: setting scrollLeft ignores the clipped X-axis');
|
|
assert_equals(scroller.scrollTop, 70,
|
|
'RTL clipped X: setting scrollLeft leaves the unclipped Y-axis unchanged');
|
|
|
|
assertOverflowDimensions(scroller, 'RTL clipped X');
|
|
}, 'RTL clipped X');
|
|
|
|
test(() => {
|
|
const scroller = document.querySelector('.scroller.clip-y');
|
|
|
|
scroller.scrollTo(40, 50);
|
|
assert_equals(scroller.scrollLeft, 40,
|
|
'LTR clipped Y: scrollTo updates the unclipped X-axis');
|
|
assert_equals(scroller.scrollTop, 0,
|
|
'LTR clipped Y: scrollTo ignores the clipped Y-axis');
|
|
|
|
scroller.scrollBy(20, 20);
|
|
assert_equals(scroller.scrollLeft, 60,
|
|
'LTR clipped Y: scrollBy incrementally updates the unclipped X-axis (40 + 20 = 60)');
|
|
assert_equals(scroller.scrollTop, 0,
|
|
'LTR clipped Y: scrollBy ignores the clipped Y-axis');
|
|
|
|
scroller.scrollTop = 70;
|
|
assert_equals(scroller.scrollLeft, 60,
|
|
'LTR clipped Y: setting scrollTop leaves the unclipped X-axis unchanged');
|
|
assert_equals(scroller.scrollTop, 0,
|
|
'LTR clipped Y: setting scrollTop ignores the clipped Y-axis');
|
|
|
|
assertOverflowDimensions(scroller, 'LTR clipped Y');
|
|
}, 'LTR clipped Y');
|
|
|
|
test(() => {
|
|
const scroller = document.querySelector('.scroller.clip-y.rtl');
|
|
|
|
scroller.scrollTo(-40, 50);
|
|
assert_equals(scroller.scrollLeft, -40,
|
|
'RTL clipped Y: scrollTo updates the unclipped X-axis (negative in RTL)');
|
|
assert_equals(scroller.scrollTop, 0,
|
|
'RTL clipped Y: scrollTo ignores the clipped Y-axis');
|
|
|
|
scroller.scrollBy(-20, 20);
|
|
assert_equals(scroller.scrollLeft, -60,
|
|
'RTL clipped Y: scrollBy incrementally updates the unclipped X-axis (-40 + -20 = -60)');
|
|
assert_equals(scroller.scrollTop, 0,
|
|
'RTL clipped Y: scrollBy ignores the clipped Y-axis');
|
|
|
|
scroller.scrollTop = 70;
|
|
assert_equals(scroller.scrollLeft, -60,
|
|
'RTL clipped Y: setting scrollTop leaves the unclipped X-axis unchanged');
|
|
assert_equals(scroller.scrollTop, 0,
|
|
'RTL clipped Y: setting scrollTop ignores the clipped Y-axis');
|
|
|
|
assertOverflowDimensions(scroller, 'RTL clipped Y');
|
|
}, 'RTL clipped Y');
|
|
</script>
|