Synchronize WebdriverScriptEvent with pending input events

Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
Co-authored-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
Euclid Ye 2025-04-30 10:59:02 +08:00
parent 539ca27284
commit 569c5c7ce0

View file

@ -335,6 +335,14 @@ pub struct ScriptThread {
/// The screen coordinates where the primary mouse button was pressed. /// The screen coordinates where the primary mouse button was pressed.
#[no_trace] #[no_trace]
relative_mouse_down_point: Cell<Point2D<f32, DevicePixel>>, relative_mouse_down_point: Cell<Point2D<f32, DevicePixel>>,
#[no_trace]
pending_webdriver_script_events: DomRefCell<HashMap<PipelineId, Vec<WebdriverScriptEvent>>>,
}
struct WebdriverScriptEvent {
pub msg: WebDriverScriptCommand,
pub can_gc: CanGc,
} }
struct BHMExitSignal { struct BHMExitSignal {
@ -954,6 +962,7 @@ impl ScriptThread {
inherited_secure_context: state.inherited_secure_context, inherited_secure_context: state.inherited_secure_context,
layout_factory, layout_factory,
relative_mouse_down_point: Cell::new(Point2D::zero()), relative_mouse_down_point: Cell::new(Point2D::zero()),
pending_webdriver_script_events: Default::default(),
} }
} }
@ -1060,6 +1069,30 @@ impl ScriptThread {
} }
} }
fn process_pending_webdriver_script_events(&self, pipeline_id: PipelineId) {
if let Some(events) = self
.pending_webdriver_script_events
.borrow_mut()
.remove(&pipeline_id)
{
for WebdriverScriptEvent { msg, can_gc } in events {
match msg {
WebDriverScriptCommand::ExecuteScript(script, reply) => {
let window = self.documents.borrow().find_window(pipeline_id);
webdriver_handlers::handle_execute_script(window, script, reply, can_gc);
},
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => {
let window = self.documents.borrow().find_window(pipeline_id);
webdriver_handlers::handle_execute_async_script(
window, script, reply, can_gc,
);
},
_ => (),
}
}
}
}
/// Process compositor events as part of a "update the rendering task". /// Process compositor events as part of a "update the rendering task".
fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) { fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) {
let Some(document) = self.documents.borrow().find_document(pipeline_id) else { let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
@ -1272,6 +1305,9 @@ impl ScriptThread {
#[cfg(feature = "webgpu")] #[cfg(feature = "webgpu")]
document.update_rendering_of_webgpu_canvases(); document.update_rendering_of_webgpu_canvases();
// after entering realm, process pending webdriver script event
self.process_pending_webdriver_script_events(*pipeline_id);
// > Step 22: For each doc of docs, update the rendering or user interface of // > Step 22: For each doc of docs, update the rendering or user interface of
// > doc and its node navigable to reflect the current state. // > doc and its node navigable to reflect the current state.
let window = document.window(); let window = document.window();
@ -1283,6 +1319,10 @@ impl ScriptThread {
// https://drafts.csswg.org/css-position-4/#process-top-layer-removals. // https://drafts.csswg.org/css-position-4/#process-top-layer-removals.
} }
// TODO: remaining documents requested are non-existent
// For each left in self.pending_webdriver_script_events
// reply.send(Err(WebDriverJSError::BrowsingContextNotFound)).unwrap();
// Perform a microtask checkpoint as the specifications says that *update the rendering* // Perform a microtask checkpoint as the specifications says that *update the rendering*
// should be run in a task and a microtask checkpoint is always done when running tasks. // should be run in a task and a microtask checkpoint is always done when running tasks.
self.perform_a_microtask_checkpoint(can_gc); self.perform_a_microtask_checkpoint(can_gc);
@ -2088,15 +2128,14 @@ impl ScriptThread {
// `self.documents`, which would conflict with the immutable borrow of it that // `self.documents`, which would conflict with the immutable borrow of it that
// occurs for the rest of the messages // occurs for the rest of the messages
match msg { match msg {
WebDriverScriptCommand::ExecuteScript(script, reply) => { WebDriverScriptCommand::ExecuteScript(..) |
let window = self.documents.borrow().find_window(pipeline_id); WebDriverScriptCommand::ExecuteAsyncScript(..) => {
return webdriver_handlers::handle_execute_script(window, script, reply, can_gc); self.pending_webdriver_script_events
}, .borrow_mut()
WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => { .entry(pipeline_id)
let window = self.documents.borrow().find_window(pipeline_id); .or_default()
return webdriver_handlers::handle_execute_async_script( .push(WebdriverScriptEvent { msg, can_gc });
window, script, reply, can_gc, return;
);
}, },
_ => (), _ => (),
} }