LibWeb: Try to dispatch wheel event on hit-testing target first

...before falling back to containing block. Fixes a bug when we can't
scroll innermost scrollable element, because wheel event dispatching
immediately falls back to containing block.
This commit is contained in:
Aliaksandr Kalenik 2025-10-03 17:51:22 +02:00 committed by Jelle Raaijmakers
parent b1a7782c59
commit c5da92f664
3 changed files with 72 additions and 1 deletions

View File

@ -408,7 +408,7 @@ EventResult EventHandler::handle_mousewheel(CSSPixelPoint viewport_position, CSS
paintable = result->paintable;
if (paintable) {
auto* containing_block = paintable->containing_block();
Painting::Paintable* containing_block = paintable;
while (containing_block) {
auto handled_scroll_event = containing_block->handle_mousewheel({}, viewport_position, buttons, modifiers, wheel_delta_x, wheel_delta_y);
if (handled_scroll_event)

View File

@ -0,0 +1 @@
inner.scrollTop: 100, inner.scrollLeft: 0

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<script src="include.js"></script>
<style>
body {
margin: 0;
}
#outer {
transform-origin: top left;
transform: scale(2);
width: 200px;
height: 200px;
}
#inner {
width: 100px;
height: 100px;
border: 1px solid black;
overflow: scroll;
}
.box {
width: 50px;
height: 50px;
background: darkorange;
box-sizing: border-box;
border: 10px solid darkorchid;
}
#top-level {
width: 300px;
height: 300px;
overflow: scroll;
outline: 2px solid blue;
}
#something-big {
height: 1000px;
background-color: blue;
}
</style>
<div id="top-level">
<div id="outer">
<div id="inner">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
<div class="box">11</div>
<div class="box">12</div>
</div>
</div>
<div id="something-big"></div>
</div>
<script>
asyncTest(async done => {
inner.onscroll = () => {
println(`inner.scrollTop: ${inner.scrollTop}, inner.scrollLeft: ${inner.scrollLeft}`);
done();
};
internals.wheel(200, 100, 0, 100);
});
</script>