mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-23 21:15:14 +00:00
LibWeb: Clamp scroll offset into valid range after relayout
If the layout has been recalculated and the sizes of scrollable overflow rectangles could have changed, we need to ensure that scroll offsets remain within the valid range.
This commit is contained in:
parent
155070cfd8
commit
309259aeb6
Notes:
sideshowbarker
2024-07-17 18:08:55 +09:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/SerenityOS/serenity/commit/309259aeb6 Pull-request: https://github.com/SerenityOS/serenity/pull/23302
3 changed files with 45 additions and 0 deletions
2
Tests/LibWeb/Text/expected/resize-scrollable-box.txt
Normal file
2
Tests/LibWeb/Text/expected/resize-scrollable-box.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
Item 1Item 2Item 3Item 4Item 5Item 6Item 7Item 8Item 9Item 10Item 11Item 12 scrollLeft (before resize): 1130
|
||||
scrollLeft (after resize): 830
|
36
Tests/LibWeb/Text/input/resize-scrollable-box.html
Normal file
36
Tests/LibWeb/Text/input/resize-scrollable-box.html
Normal file
|
@ -0,0 +1,36 @@
|
|||
<style>
|
||||
.scrollable-div {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
border: 10px magenta solid;
|
||||
}
|
||||
|
||||
span {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: inline-block;
|
||||
border: 10px solid #000;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div class="scrollable-div">
|
||||
<span>Item 1</span><span>Item 2</span><span>Item 3</span><span>Item 4</span
|
||||
><span>Item 5</span><span>Item 6</span><span>Item 7</span><span>Item 8</span
|
||||
><span>Item 9</span><span>Item 10</span><span>Item 11</span><span>Item 12</span>
|
||||
</div>
|
||||
</body>
|
||||
<script src="./include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const scrollableDiv = document.querySelector('.scrollable-div');
|
||||
scrollableDiv.scrollLeft = scrollableDiv.scrollWidth;
|
||||
println("scrollLeft (before resize): " + scrollableDiv.scrollLeft);
|
||||
document.body.style.width = '600px';
|
||||
println("scrollLeft (after resize): " + scrollableDiv.scrollLeft);
|
||||
});
|
||||
</script>
|
|
@ -352,6 +352,13 @@ void LayoutState::commit(Box& root)
|
|||
continue;
|
||||
auto const& box = static_cast<Layout::Box const&>(used_values.node());
|
||||
measure_scrollable_overflow(box);
|
||||
|
||||
// The scroll offset can become invalid if the scrollable overflow rectangle has changed after layout.
|
||||
// For example, if the scroll container has been scrolled to the very end and is then resized to become larger
|
||||
// (scrollable overflow rect become smaller), the scroll offset would be out of bounds.
|
||||
auto& paintable_box = const_cast<Painting::PaintableBox&>(*box.paintable_box());
|
||||
if (!paintable_box.scroll_offset().is_zero())
|
||||
paintable_box.set_scroll_offset(paintable_box.scroll_offset());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue