Implement scroll event (#36687)

Reimplementation of https://github.com/servo/servo/pull/35105.

test: `tests/wpt/tests/pointerevents/{pointerevent_hit_test_scroll,
pointerevent_hit_test_scroll_visible_decendant}.html` (after
https://github.com/servo/servo/pull/37461)

Signed-off-by: PotatoCP <kenzieradityatirtarahardja.18@gmail.com>
Co-authored-by: PotatoCP <kenzieradityatirtarahardja.18@gmail.com>
Co-authored-by: Asun0204 <asun0204@163.com>
This commit is contained in:
Kenzie Raditya Tirtarahardja 2025-06-18 14:05:45 +08:00 committed by GitHub
parent 152467bc67
commit 96ef92b9ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 88 additions and 20 deletions

View file

@ -31,7 +31,8 @@ use dom_struct::dom_struct;
use embedder_traits::{
AllowOrDeny, AnimationState, CompositorHitTestResult, ContextMenuResult, EditingActionEvent,
EmbedderMsg, FocusSequenceNumber, ImeEvent, InputEvent, LoadStatus, MouseButton,
MouseButtonAction, MouseButtonEvent, TouchEvent, TouchEventType, TouchId, WheelEvent,
MouseButtonAction, MouseButtonEvent, ScrollEvent, TouchEvent, TouchEventType, TouchId,
UntrustedNodeAddress, WheelEvent,
};
use encoding_rs::{Encoding, UTF_8};
use euclid::default::{Point2D, Rect, Size2D};
@ -54,7 +55,7 @@ use profile_traits::ipc as profile_ipc;
use profile_traits::time::TimerMetadataFrameType;
use regex::bytes::Regex;
use script_bindings::interfaces::DocumentHelpers;
use script_layout_interface::{PendingRestyle, TrustedNodeAddress};
use script_layout_interface::{PendingRestyle, TrustedNodeAddress, node_id_from_scroll_id};
use script_traits::{ConstellationInputEvent, DocumentActivity, ProgressiveWebMetricType};
use servo_arc::Arc;
use servo_config::pref;
@ -2327,6 +2328,40 @@ impl Document {
}
}
#[allow(unsafe_code)]
pub(crate) fn handle_scroll_event(&self, event: ScrollEvent, can_gc: CanGc) {
// <https://drafts.csswg.org/cssom-view/#scrolling-events>
// If target is a Document, fire an event named scroll that bubbles at target.
if event.external_id.is_root() {
let Some(document) = self
.node
.inclusive_ancestors(ShadowIncluding::No)
.filter_map(DomRoot::downcast::<Document>)
.next()
else {
return;
};
DomRoot::upcast::<EventTarget>(document)
.fire_bubbling_event(Atom::from("scroll"), can_gc);
} else {
// Otherwise, fire an event named scroll at target.
let Some(node_id) = node_id_from_scroll_id(event.external_id.0 as usize) else {
return;
};
let node = unsafe {
node::from_untrusted_node_address(UntrustedNodeAddress::from_id(node_id))
};
let Some(element) = node
.inclusive_ancestors(ShadowIncluding::No)
.filter_map(DomRoot::downcast::<Element>)
.next()
else {
return;
};
DomRoot::upcast::<EventTarget>(element).fire_event(Atom::from("scroll"), can_gc);
}
}
/// The entry point for all key processing for web content
pub(crate) fn dispatch_key_event(
&self,