LibWeb: Fire "scroll" events on DOM elements

Before this change "scroll" events were only fired on document but now
it happens for all elements with scrollable overflow.
This commit is contained in:
Aliaksandr Kalenik 2024-04-22 18:16:14 +02:00 committed by Alexander Kalenik
parent 771054bff7
commit dd73cccf8f
Notes: sideshowbarker 2024-07-17 01:13:25 +09:00
3 changed files with 50 additions and 0 deletions

View file

@ -0,0 +1 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. scroll event fired y=100

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<style>
#scrollable-div {
width: 300px;
height: 200px;
overflow: auto;
border: 1px solid black;
padding: 10px;
font-size: 50px;
}
</style>
<script src="include.js"></script>
<div id="scrollable-div">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed
cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis
ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum
lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
inceptos himenaeos.
</div>
<script>
asyncTest(done => {
const scrollable = document.getElementById("scrollable-div");
scrollable.addEventListener("scroll", event => {
println(`scroll event fired y=${scrollable.scrollTop}`);
done();
});
scrollable.scrollTop = 100;
});
</script>

View file

@ -91,6 +91,26 @@ void PaintableBox::set_scroll_offset(CSSPixelPoint offset)
return;
}
// https://drafts.csswg.org/cssom-view-1/#scrolling-events
// Whenever an element gets scrolled (whether in response to user interaction or by an API),
// the user agent must run these steps:
// 1. Let doc be the elements node document.
auto& document = layout_box().document();
// FIXME: 2. If the element is a snap container, run the steps to update snapchanging targets for the element with
// the elements eventual snap target in the block axis as newBlockTarget and the elements eventual snap
// target in the inline axis as newInlineTarget.
JS::NonnullGCPtr<DOM::EventTarget> const event_target = *dom_node();
// 3. If the element is already in docs pending scroll event targets, abort these steps.
if (document.pending_scroll_event_targets().contains_slow(event_target))
return;
// 4. Append the element to docs pending scroll event targets.
document.pending_scroll_event_targets().append(*layout_box().dom_node());
set_needs_display();
}