script: Chain up keyboard scrolling to parent <iframe>s (#39469)

When an `<iframe>` cannot scroll because the size of the frame is
greater than or
equal to the size of page contents, chain up the keyboard scroll
operation to the parent frame.

Testing: A new Servo-only WPT tests is added, though needs to be
manually
run with `--product servodriver`.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
Martin Robinson 2025-09-25 13:16:41 +02:00 committed by GitHub
parent 75e32ba5a4
commit ffdb7d3663
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 406 additions and 132 deletions

View file

@ -26,6 +26,7 @@ fonts_traits = { workspace = true }
http = { workspace = true }
hyper_serde = { workspace = true }
ipc-channel = { workspace = true }
keyboard-types = { workspace = true }
log = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }

View file

@ -480,6 +480,27 @@ pub struct IFrameSizeMsg {
pub type_: WindowSizeType,
}
/// An enum that describe a type of keyboard scroll.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum KeyboardScroll {
/// Scroll the container one line up.
Up,
/// Scroll the container one line down.
Down,
/// Scroll the container one "line" left.
Left,
/// Scroll the container one "line" right.
Right,
/// Scroll the container one page up.
PageUp,
/// Scroll the container one page down.
PageDown,
/// Scroll the container to the vertical start.
Home,
/// Scroll the container to the vertical end.
End,
}
/// Messages from the script to the constellation.
#[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum ScriptToConstellationMessage {
@ -665,6 +686,8 @@ pub enum ScriptToConstellationMessage {
),
/// Notify the completion of a webdriver command.
WebDriverInputComplete(WebDriverMessageId),
/// Forward a keyboard scroll operation from an `<iframe>` to a parent pipeline.
ForwardKeyboardScroll(PipelineId, KeyboardScroll),
}
impl fmt::Debug for ScriptToConstellationMessage {

View file

@ -306,9 +306,11 @@ pub trait Layout {
fn query_client_rect(&self, node: TrustedNodeAddress) -> Rect<i32>;
fn query_element_inner_outer_text(&self, node: TrustedNodeAddress) -> String;
fn query_offset_parent(&self, node: TrustedNodeAddress) -> OffsetParentResponse;
/// Query the scroll container for the given node. If node is `None`, the scroll container for
/// the viewport is returned.
fn query_scroll_container(
&self,
node: TrustedNodeAddress,
node: Option<TrustedNodeAddress>,
flags: ScrollContainerQueryFlags,
) -> Option<ScrollContainerResponse>;
fn query_resolved_style(
@ -377,7 +379,7 @@ bitflags! {
}
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, MallocSizeOf)]
pub struct AxesOverflow {
pub x: Overflow,
pub y: Overflow,
@ -401,9 +403,18 @@ impl From<&ComputedValues> for AxesOverflow {
}
}
impl AxesOverflow {
pub fn to_scrollable(&self) -> Self {
Self {
x: self.x.to_scrollable(),
y: self.y.to_scrollable(),
}
}
}
#[derive(Clone)]
pub enum ScrollContainerResponse {
Viewport,
Viewport(AxesOverflow),
Element(UntrustedNodeAddress, AxesOverflow),
}

View file

@ -21,8 +21,8 @@ use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline;
use compositing_traits::CrossProcessCompositorApi;
use constellation_traits::{
LoadData, NavigationHistoryBehavior, ScriptToConstellationChan, StructuredSerializedData,
WindowSizeType,
KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationChan,
StructuredSerializedData, WindowSizeType,
};
use crossbeam_channel::{RecvTimeoutError, Sender};
use devtools_traits::ScriptToDevtoolsControlMsg;
@ -265,6 +265,8 @@ pub enum ScriptThreadMessage {
/// asynchronous image uploads for the given `Pipeline`. These are mainly used
/// by canvas to perform uploads while the display list is being built.
NoLongerWaitingOnAsychronousImageUpdates(PipelineId),
/// Forward a keyboard scroll operation from an `<iframe>` to a parent pipeline.
ForwardKeyboardScroll(PipelineId, KeyboardScroll),
}
impl fmt::Debug for ScriptThreadMessage {