From 569c5c7ce0ca22a27706bb72f315c44b12a188a5 Mon Sep 17 00:00:00 2001 From: Euclid Ye Date: Wed, 30 Apr 2025 10:59:02 +0800 Subject: [PATCH] Synchronize `WebdriverScriptEvent` with pending input events Signed-off-by: Euclid Ye Co-authored-by: batu_hoang --- components/script/script_thread.rs | 57 +++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 7241c115a2a..092552928a0 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -335,6 +335,14 @@ pub struct ScriptThread { /// The screen coordinates where the primary mouse button was pressed. #[no_trace] relative_mouse_down_point: Cell>, + + #[no_trace] + pending_webdriver_script_events: DomRefCell>>, +} + +struct WebdriverScriptEvent { + pub msg: WebDriverScriptCommand, + pub can_gc: CanGc, } struct BHMExitSignal { @@ -954,6 +962,7 @@ impl ScriptThread { inherited_secure_context: state.inherited_secure_context, layout_factory, 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". fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) { let Some(document) = self.documents.borrow().find_document(pipeline_id) else { @@ -1272,6 +1305,9 @@ impl ScriptThread { #[cfg(feature = "webgpu")] 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 // > doc and its node navigable to reflect the current state. let window = document.window(); @@ -1283,6 +1319,10 @@ impl ScriptThread { // 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* // should be run in a task and a microtask checkpoint is always done when running tasks. 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 // occurs for the rest of the messages match msg { - WebDriverScriptCommand::ExecuteScript(script, reply) => { - let window = self.documents.borrow().find_window(pipeline_id); - return webdriver_handlers::handle_execute_script(window, script, reply, can_gc); - }, - WebDriverScriptCommand::ExecuteAsyncScript(script, reply) => { - let window = self.documents.borrow().find_window(pipeline_id); - return webdriver_handlers::handle_execute_async_script( - window, script, reply, can_gc, - ); + WebDriverScriptCommand::ExecuteScript(..) | + WebDriverScriptCommand::ExecuteAsyncScript(..) => { + self.pending_webdriver_script_events + .borrow_mut() + .entry(pipeline_id) + .or_default() + .push(WebdriverScriptEvent { msg, can_gc }); + return; }, _ => (), }