webdriver: Evaluate script commands via the WebView API in servoshell (#37663)

Let `WebDriverCommandMsg::ScriptCommand` goes through embedder first.
Give `embedder` the ability to release `webdriver` from waiting for a
response of `ExecuteScript`.

Tests: https://github.com/longvatrong111/servo/actions/runs/16071375821
No regression compared to CI run on main branch.

Fixes: https://github.com/servo/servo/issues/37370

cc: @xiaochengh

---------

Signed-off-by: batu_hoang <longvatrong111@gmail.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
batu_hoang 2025-07-09 22:05:39 +08:00 committed by GitHub
parent 562d9e4a21
commit 4499fdeb2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 75 additions and 150 deletions

View file

@ -27,7 +27,7 @@ use servo::webrender_api::ScrollLocation;
use servo::webrender_api::units::DeviceIntSize;
use servo::{
EventLoopWaker, InputEvent, KeyboardEvent, MouseButtonEvent, MouseMoveEvent,
WebDriverCommandMsg, WheelDelta, WheelEvent, WheelMode,
WebDriverCommandMsg, WebDriverScriptCommand, WheelDelta, WheelEvent, WheelMode,
};
use url::Url;
use winit::application::ApplicationHandler;
@ -542,7 +542,16 @@ impl App {
webview.notify_scroll_event(scroll_location, point.to_i32());
}
},
WebDriverCommandMsg::ScriptCommand(..) |
WebDriverCommandMsg::ScriptCommand(
browsing_context_id,
webdriver_script_command,
) => {
self.handle_webdriver_script_commnd(&webdriver_script_command, running_state);
running_state.forward_webdriver_command(WebDriverCommandMsg::ScriptCommand(
browsing_context_id,
webdriver_script_command,
));
},
WebDriverCommandMsg::TakeScreenshot(..) => {
warn!(
"WebDriverCommand {:?} is still not moved from constellation to embedder",
@ -552,6 +561,24 @@ impl App {
};
}
}
fn handle_webdriver_script_commnd(
&self,
msg: &WebDriverScriptCommand,
running_state: &RunningAppState,
) {
match msg {
WebDriverScriptCommand::ExecuteScript(_webview_id, response_sender) => {
// Give embedder a chance to interrupt the script command.
// Webdriver only handles 1 script command at a time, so we can
// safely set a new interrupt sender and remove the previous one here.
running_state.set_script_command_interrupt_sender(Some(response_sender.clone()));
},
_ => {
running_state.set_script_command_interrupt_sender(None);
},
}
}
}
impl ApplicationHandler<AppEvent> for App {