script: Fire scroll event whenever JS scrolled (#38321)

Implement JS scroll event firing compliant to
https://drafts.csswg.org/cssom-view/#scrolling-events. Basically
whenever, the an element or the viewport is scrolled, we will fire a
scroll event. The changes push a scroll event whenever an API causes a
scroll position to change.

Testing: New WPT tests for basic APIs.
Part of: https://github.com/servo/servo/issues/31665

---------

Signed-off-by: Jo Steven Novaryo <jo.steven.novaryo@huawei.com>
This commit is contained in:
Jo Steven Novaryo 2025-08-01 15:30:22 +08:00 committed by GitHub
parent 372e5eae59
commit a063b5e78a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 407 additions and 74 deletions

View file

@ -344,7 +344,8 @@ pub enum ReflowGoal {
LayoutQuery(QueryMsg),
/// Tells layout about a single new scrolling offset from the script. The rest will
/// remain untouched and layout won't forward this back to script.
/// remain untouched. Layout will forward whether the element is scrolled through
/// [ReflowResult].
UpdateScrollNode(ExternalScrollId, LayoutVector2D),
}
@ -391,8 +392,28 @@ pub struct ReflowResult {
pub pending_rasterization_images: Vec<PendingRasterizationImage>,
/// The list of iframes in this layout and their sizes, used in order
/// to communicate them with the Constellation and also the `Window`
/// element of their content pages.
pub iframe_sizes: IFrameSizes,
/// element of their content pages. Returning None if incremental reflow
/// finished before reaching this stage of the layout. I.e., no update
/// required.
pub iframe_sizes: Option<IFrameSizes>,
/// Whether the reflow is for [ReflowGoal::UpdateScrollNode] and the target is scrolled.
/// Specifically, a node is scrolled whenever the scroll position of it changes.
pub update_scroll_reflow_target_scrolled: bool,
/// Do the reflow results in a new component within layout. Incremental layout could be
/// skipped if it is deemed unnecessary or the required component is not ready to be
/// processed.
pub processed_relayout: bool,
}
impl ReflowResult {
/// In incremental reflow, we could skip the layout calculation completely, if it is deemed
/// unecessary. In those cases, many of the [ReflowResult] would be irrelevant.
pub fn new_without_relayout(update_scroll_reflow_target_scrolled: bool) -> Self {
ReflowResult {
update_scroll_reflow_target_scrolled,
..Default::default()
}
}
}
/// Information needed for a script-initiated reflow that requires a restyle