Skip to content

script: Fire scroll event on visual viewport scroll#42771

Merged
mrobinson merged 2 commits into
servo:mainfrom
stevennovaryo:visual-viewport-scroll
Mar 19, 2026
Merged

script: Fire scroll event on visual viewport scroll#42771
mrobinson merged 2 commits into
servo:mainfrom
stevennovaryo:visual-viewport-scroll

Conversation

@stevennovaryo

Copy link
Copy Markdown
Member

On visual viewport scroll, fire the scroll event to the VisualViewport instances. Incidentaly, fix a bug where the pinch zoom update should be propagated to the script.

Testing: New unit test and manual WPT.

Comment thread components/script/dom/document.rs Outdated
Comment on lines +1795 to +1798
/// Whenever a visual viewport gets scrolled (whether in response to user interaction or by an
/// API), the user agent must run these steps:
/// <https://drafts.csswg.org/cssom-view/#scrolling-events>
// TODO: the scroll event handling should be updated and this function should follow as well

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Whenever a visual viewport gets scrolled (whether in response to user interaction or by an
/// API), the user agent must run these steps:
/// <https://drafts.csswg.org/cssom-view/#scrolling-events>
// TODO: the scroll event handling should be updated and this function should follow as well
/// From <https://drafts.csswg.org/cssom-view/#scrolling-events>:
/// > Whenever a visual viewport gets scrolled (whether in response to user interaction or by an
/// > API), the user agent must run these steps:
// TODO: the scroll event handling should be updated and this function should follow as well

What do you mean by the last TODO? I'm not sure I completely follow it. Updated in what way?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is to note that the Document::pending_scroll_event_targets is changed and thus the algorithm need some modification too. Should have move the TODO to the Document::pending_scroll_event_targets instead. It is not necessary to change it now since scrollend is not implemented i guess.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But changed in what way? And what modifications?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But changed in what way? And what modifications?

Initially, the document have two pending list of event targets.

From: https://www.w3.org/TR/cssom-view-1/#scrolling-events, which is not updated yet.

Each Document has an associated list of pending scroll event targets, initially empty.
Each Document has an associated list of pending scrollend event targets, initially empty.

But now it is merged, I remember it is because essentially all browser are doing the same.

From: https://drafts.csswg.org/cssom-view/#scrolling-events

Each Document has an associated list of pending scroll events, which stores pairs of (EventTarget, DOMString), initially empty.

Should have added that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just updated the comments. Please check whether it is clear. Thanks! @mrobinson

// > If target is a Document, fire an event named scroll that bubbles at target.
target.fire_bubbling_event(Atom::from("scroll"), can_gc);
} else if target.downcast::<Element>().is_some() {
} else {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What sort of non-Elements is it important to send scroll events to?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially the scroll only applies to Element and Document since the VisualViewport is not implemented, but now, since it is implemented we should fire to the VisualViewport as well.

It is to bring the algorithm closer to the spec as well, since the spec doesn't limit what kind of target we are firing on to.

@stevennovaryo stevennovaryo force-pushed the visual-viewport-scroll branch 2 times, most recently from 99ca390 to 0cca5a9 Compare February 23, 2026 09:01
@stevennovaryo stevennovaryo marked this pull request as ready for review February 23, 2026 09:18
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Feb 23, 2026
@stevennovaryo stevennovaryo force-pushed the visual-viewport-scroll branch 2 times, most recently from 254e83f to c9f3256 Compare February 24, 2026 02:31
@webbeef

webbeef commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

@stevennovaryo is that something we could use to implement #42150 ?

@stevennovaryo

Copy link
Copy Markdown
Member Author

@stevennovaryo is that something we could use to implement #42150 ?

It is more about JS scroll event, instead of embedder. Looking at #42150, we might be able to push it from constellation maybe with some cleanup, because scroll updates is is not unified. Sending one by depending on JS event sounds very inefficient.

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
@stevennovaryo stevennovaryo force-pushed the visual-viewport-scroll branch from 43e5401 to d6c3caa Compare March 12, 2026 09:40
@stevennovaryo

Copy link
Copy Markdown
Member Author

Rebased, can we have another look for the PR? @mrobinson Thanks!

@mrobinson mrobinson left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good with some tiny nits:

/// > Whenever a visual viewport gets scrolled (whether in response to user interaction or by an
/// > API), the user agent must run these steps:
pub(crate) fn handle_visual_viewport_scroll_event(&self, visual_viewport: &VisualViewport) {
// Step 3.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include the text of steps 1 and 2 here with a TODO comment. There are other examples of this, in this file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! It is definitely better to be comprehensive, I have added the steps 1 and 2, they are basically the variable that's been passed into the function.

Comment thread components/servo/tests/webview.rs Outdated
Comment on lines 849 to 856
let eval_visual_viewport = |attr: &str| match evaluate_javascript(
&servo_test,
webview.clone(),
format!("window.visualViewport.{}", attr),
) {
Ok(JSValue::Number(num)) => Some(num),
_ => None,
};

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let eval_visual_viewport = |attr: &str| match evaluate_javascript(
&servo_test,
webview.clone(),
format!("window.visualViewport.{}", attr),
) {
Ok(JSValue::Number(num)) => Some(num),
_ => None,
};
let eval_visual_viewport = |attribute: &str| match evaluate_javascript(
&servo_test,
webview.clone(),
format!("window.visualViewport.{}", attribute)
)
Ok(JSValue::Number(number)) => Some(number),
_ => None,
};

Comment thread components/script/dom/document.rs Outdated
Comment on lines +588 to +590
// TODO(31665): Instead of having separate list for `scroll` and `scrollend` event, the updated spec
// make it store both the event target and the event type. Need to update this along with
// the implementation of `scrollend`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a tiny nit, but we typically don't indent TODO comments like this. Please format them like this:

Suggested change
// TODO(31665): Instead of having separate list for `scroll` and `scrollend` event, the updated spec
// make it store both the event target and the event type. Need to update this along with
// the implementation of `scrollend`.
// TODO(#31665): Instead of having separate list for `scroll` and `scrollend` event, the updated spec
// make it store both the event target and the event type. Need to update this along with the
// implementation of `scrollend`.

@servo-highfive servo-highfive removed the S-awaiting-review There is new code that needs to be reviewed. label Mar 12, 2026
Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
@servo-highfive servo-highfive added the S-awaiting-review There is new code that needs to be reviewed. label Mar 12, 2026
@mrobinson mrobinson added this pull request to the merge queue Mar 19, 2026
@servo-highfive servo-highfive added the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Mar 19, 2026
Merged via the queue into servo:main with commit c4cdcb7 Mar 19, 2026
33 checks passed
@servo-highfive servo-highfive removed the S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. label Mar 19, 2026
Gae24 pushed a commit to Gae24/servo that referenced this pull request Mar 26, 2026
On visual viewport scroll, fire the scroll event to the `VisualViewport`
instances. Incidentaly, fix a bug where the pinch zoom update should be
propagated to the script.

Testing: New unit test and manual WPT.

---------

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-awaiting-review There is new code that needs to be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants