script: Notify PinchZoom resizes to ScriptThread's VisualViewport (#41754)

Continuing the implementation of `VisualViewport`, the resizing of
`PinchZoom` should be notified to `ScriptThread` to update the
`VisualViewport` interface and to fire the appropriate JS event. Top
level `Window`/`Pipeline` would have a `VisualViewport` interface that
mirrors the `PinchZoom` viewport, while nested `Window` would have a
default value that represent layout viewport of the relevant iframe. The
`VisualViewport` of an iframe is updated after each reflow that
calculate the rectangle of the iframe.

The updates of DOM's `VisualViewport` occurs immediately (instead of
waiting for the event loop like the viewport) but integrates with the
event loop for the JS events. This behavior would helps with the fact
that `VisualViewport` needs to be updated both when it is scrolled or
resized.

Testing: Existing WPTs and new unit test.
Part of: https://github.com/servo/servo/issues/41341

---------

Signed-off-by: Jo Steven Novaryo <steven.novaryo@gmail.com>
This commit is contained in:
Steven Novaryo
2026-01-28 17:33:55 +08:00
committed by GitHub
parent 67c0ce7e75
commit 45c39d7496
17 changed files with 293 additions and 24 deletions

View File

@@ -79,7 +79,7 @@ use net_traits::{
FetchMetadata, FetchResponseMsg, Metadata, NetworkError, ResourceFetchTiming, ResourceThreads,
ResourceTimingType,
};
use paint_api::{CrossProcessPaintApi, PipelineExitSource};
use paint_api::{CrossProcessPaintApi, PinchZoomInfos, PipelineExitSource};
use percent_encoding::percent_decode;
use profile_traits::mem::{ProcessReports, ReportsChan, perform_memory_report};
use profile_traits::time::ProfilerCategory;
@@ -1935,6 +1935,9 @@ impl ScriptThread {
EmbedderMsg::AccessibilityTreeUpdate(webview_id, tree_update),
);
},
ScriptThreadMessage::UpdatePinchZoomInfos(id, pinch_zoom_infos) => {
self.handle_update_pinch_zoom_infos(id, pinch_zoom_infos, CanGc::from_cx(cx));
},
}
}
@@ -4050,6 +4053,20 @@ impl ScriptThread {
.embedder_controls()
.handle_embedder_control_response(id, response, can_gc);
}
pub(crate) fn handle_update_pinch_zoom_infos(
&self,
pipeline_id: PipelineId,
pinch_zoom_infos: PinchZoomInfos,
can_gc: CanGc,
) {
let Some(window) = self.documents.borrow().find_window(pipeline_id) else {
warn!("Visual viewport update for closed pipeline {pipeline_id}.");
return;
};
window.maybe_update_visual_viewport(pinch_zoom_infos, can_gc);
}
}
impl Drop for ScriptThread {