From d3bd244ed4d1284c8a4787cc26554f7b501a2b34 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 21 Nov 2024 16:34:27 +0800 Subject: [PATCH 01/11] Allow setting init script through cli --- src/config.rs | 10 +++++++++ src/verso.rs | 3 +++ src/webview.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++---- src/window.rs | 9 ++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index cfdcb05d..e9686e39 100644 --- a/src/config.rs +++ b/src/config.rs @@ -41,6 +41,8 @@ pub struct CliArgs { pub resource_dir: Option, /// Override the user agent pub user_agent: Option, + /// Script to run on document started to load + pub init_script: Option, /// Initial window's zoom level pub zoom_level: Option, } @@ -101,6 +103,12 @@ fn parse_cli_args() -> Result { "Override the user agent", "'VersoView/1.0'", ); + opts.optopt( + "", + "init-script", + "Script to run on document started to load", + "console.log('hello world')", + ); opts.optopt( "w", @@ -173,6 +181,7 @@ fn parse_cli_args() -> Result { }; let user_agent = matches.opt_str("user-agent"); + let init_script = matches.opt_str("init-script"); let mut window_attributes = winit::window::Window::default_attributes(); @@ -237,6 +246,7 @@ fn parse_cli_args() -> Result { devtools_port, profiler_settings, user_agent, + init_script, zoom_level, }) } diff --git a/src/verso.rs b/src/verso.rs index 75e5cb95..803b6cd9 100644 --- a/src/verso.rs +++ b/src/verso.rs @@ -114,6 +114,7 @@ impl Verso { .clone() .unwrap_or_else(|| default_user_agent_string().to_string()) .into(); + let init_script = config.args.init_script.clone(); let zoom_level = config.args.zoom_level; config.init(); @@ -391,6 +392,8 @@ impl Verso { window.create_webview(&constellation_sender, initial_url.into()); } + window.set_init_script(init_script); + let mut windows = HashMap::new(); windows.insert(window.id(), (window, webrender_document)); diff --git a/src/webview.rs b/src/webview.rs index 68513a09..54bd8937 100644 --- a/src/webview.rs +++ b/src/webview.rs @@ -5,7 +5,9 @@ use crossbeam_channel::Sender; use embedder_traits::{CompositorEventVariant, EmbedderMsg, PromptDefinition}; use ipc_channel::ipc; use script_traits::{ - webdriver_msg::{WebDriverJSResult, WebDriverScriptCommand}, + webdriver_msg::{ + WebDriverJSError, WebDriverJSResult, WebDriverJSValue, WebDriverScriptCommand, + }, TraversalDirection, WebDriverCommandMsg, }; use servo_url::ServoUrl; @@ -27,7 +29,7 @@ pub struct WebView { } impl WebView { - /// Create a web view from Winit window. + /// Create a web view. pub fn new(webview_id: WebViewId, rect: DeviceIntRect) -> Self { Self { webview_id, rect } } @@ -68,8 +70,7 @@ impl Window { ) { log::trace!("Verso WebView {webview_id:?} is handling Embedder message: {message:?}",); match message { - EmbedderMsg::LoadStart - | EmbedderMsg::HeadParsed + EmbedderMsg::HeadParsed | EmbedderMsg::WebViewOpened(_) | EmbedderMsg::WebViewClosed(_) => { // Most WebView messages are ignored because it's done by compositor. @@ -82,6 +83,11 @@ impl Window { w ); } + EmbedderMsg::LoadStart => { + if let Some(init_script) = &self.init_script { + execute_script_async(&sender, &webview_id, init_script); + } + } EmbedderMsg::LoadComplete => { self.window.request_redraw(); send_to_constellation(sender, ConstellationMsg::FocusWebView(webview_id)); @@ -326,3 +332,47 @@ impl Window { false } } + +/// Blocking execute a script on this webview +pub fn execute_script( + constellation_sender: &Sender, + webview: &WebViewId, + js: impl ToString, +) -> Result { + let (result_sender, result_receiver) = ipc::channel::().unwrap(); + send_to_constellation( + constellation_sender, + ConstellationMsg::WebDriverCommand(script_traits::WebDriverCommandMsg::ScriptCommand( + webview.0, + WebDriverScriptCommand::ExecuteScript(js.to_string(), result_sender), + )), + ); + result_receiver.recv().unwrap() +} + +/// Execute a script asynchronous on this webview +pub fn execute_script_async( + constellation_sender: &Sender, + webview: &WebViewId, + js: impl ToString, +) { + execute_script_async_with_callback(constellation_sender, webview, js, |_| {}) +} + +/// Execute a script asynchronous on this webview with a callback processing the result +pub fn execute_script_async_with_callback( + constellation_sender: &Sender, + webview: &WebViewId, + js: impl ToString, + callback: impl FnOnce(Result) + Send + 'static, +) { + let (result_sender, result_receiver) = ipc::channel::().unwrap(); + send_to_constellation( + constellation_sender, + ConstellationMsg::WebDriverCommand(script_traits::WebDriverCommandMsg::ScriptCommand( + webview.0, + WebDriverScriptCommand::ExecuteAsyncScript(js.to_string(), result_sender), + )), + ); + std::thread::spawn(move || callback(result_receiver.recv().unwrap())); +} diff --git a/src/window.rs b/src/window.rs index 35eeb74b..60032255 100644 --- a/src/window.rs +++ b/src/window.rs @@ -52,6 +52,8 @@ pub struct Window { pub(crate) panel: Option, /// The WebView of this window. pub(crate) webview: Option, + /// Script to run on document started to load + pub(crate) init_script: Option, /// The mouse physical position in the web view. mouse_position: Cell>>, /// Modifiers state of the keyboard. @@ -118,6 +120,7 @@ impl Window { surface, panel: None, webview: None, + init_script: None, mouse_position: Default::default(), modifiers_state: Cell::new(ModifiersState::default()), history: vec![], @@ -162,6 +165,7 @@ impl Window { surface, panel: None, webview: None, + init_script: None, mouse_position: Default::default(), modifiers_state: Cell::new(ModifiersState::default()), history: vec![], @@ -232,6 +236,11 @@ impl Window { log::debug!("Verso Window {:?} adds webview {}", self.id(), webview_id); } + /// Set the init script that runs on document started to load. + pub fn set_init_script(&mut self, init_script: Option) { + self.init_script = init_script; + } + /// Handle Winit window event and return a boolean to indicate if the compositor should repaint immediately. pub fn handle_winit_window_event( &mut self, From 15d0643b5796ff2c80e8dbac353f8fe770c2d881 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 21 Nov 2024 19:21:53 +0800 Subject: [PATCH 02/11] Add userscripts directory as well --- src/config.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/config.rs b/src/config.rs index e9686e39..ac784362 100644 --- a/src/config.rs +++ b/src/config.rs @@ -43,6 +43,8 @@ pub struct CliArgs { pub user_agent: Option, /// Script to run on document started to load pub init_script: Option, + /// The directory to load userscripts from + pub userscripts_directory: Option, /// Initial window's zoom level pub zoom_level: Option, } @@ -109,6 +111,12 @@ fn parse_cli_args() -> Result { "Script to run on document started to load", "console.log('hello world')", ); + opts.optopt( + "", + "userscripts-directory", + "The directory to load userscripts from", + "resources/user-agent-js/", + ); opts.optopt( "w", @@ -182,6 +190,7 @@ fn parse_cli_args() -> Result { let user_agent = matches.opt_str("user-agent"); let init_script = matches.opt_str("init-script"); + let userscripts_directory = matches.opt_str("userscripts-directory"); let mut window_attributes = winit::window::Window::default_attributes(); @@ -247,6 +256,7 @@ fn parse_cli_args() -> Result { profiler_settings, user_agent, init_script, + userscripts_directory, zoom_level, }) } @@ -267,6 +277,10 @@ impl Config { opts.time_profiler_trace_path = profiler_settings.trace_path.clone(); } + if let Some(ref userscripts_directory) = args.userscripts_directory { + opts.userscripts = Some(userscripts_directory.clone()); + } + let resource_dir = args.resource_dir.clone().unwrap_or(resources_dir_path()); Self { From 767cd643a7f8542824f5f16c80e60e2e397fd1e7 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 23 Jan 2025 11:08:42 +0800 Subject: [PATCH 03/11] Use WebDriverJSResult --- src/webview/webview.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/webview/webview.rs b/src/webview/webview.rs index fd1e5c71..ec72f03f 100644 --- a/src/webview/webview.rs +++ b/src/webview/webview.rs @@ -605,13 +605,12 @@ impl Window { } } - /// Blocking execute a script on this webview pub fn execute_script( constellation_sender: &Sender, webview: &WebViewId, js: impl ToString, -) -> Result { +) -> WebDriverJSResult { let (result_sender, result_receiver) = ipc::channel::().unwrap(); send_to_constellation( constellation_sender, @@ -637,7 +636,7 @@ pub fn execute_script_async_with_callback( constellation_sender: &Sender, webview: &WebViewId, js: impl ToString, - callback: impl FnOnce(Result) + Send + 'static, + callback: impl FnOnce(WebDriverJSResult) + Send + 'static, ) { let (result_sender, result_receiver) = ipc::channel::().unwrap(); send_to_constellation( From d5ef9c30d7c5ae3d48e346065f9632b81dbab4d5 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 23 Jan 2025 11:11:46 +0800 Subject: [PATCH 04/11] Migrate to use `execute_script` --- src/webview/webview.rs | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/webview/webview.rs b/src/webview/webview.rs index ec72f03f..52f3b9db 100644 --- a/src/webview/webview.rs +++ b/src/webview/webview.rs @@ -1,5 +1,5 @@ use arboard::Clipboard; -use base::id::{BrowsingContextId, WebViewId}; +use base::id::WebViewId; use compositing_traits::ConstellationMsg; use crossbeam_channel::Sender; use embedder_traits::{ @@ -9,7 +9,7 @@ use embedder_traits::{ use ipc_channel::ipc; use script_traits::{ webdriver_msg::{WebDriverJSResult, WebDriverScriptCommand}, - TraversalDirection, WebDriverCommandMsg, + TraversalDirection, }; use servo_url::ServoUrl; use url::Url; @@ -113,16 +113,7 @@ impl Window { serde_json::to_string(&webview_id).unwrap(), title.as_str() ); - - let (tx, rx) = ipc::channel::().unwrap(); - send_to_constellation( - sender, - ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand( - BrowsingContextId::from(panel.webview.webview_id), - WebDriverScriptCommand::ExecuteScript(script, tx), - )), - ); - let _ = rx.recv(); + let _ = execute_script(sender, &panel.webview.webview_id, script); } } EmbedderMsg::AllowNavigationRequest(id, _url) => { @@ -166,18 +157,11 @@ impl Window { .set_history(webview_id, list.clone(), index); let url = list.get(index).unwrap(); if let Some(panel) = self.panel.as_ref() { - let (tx, rx) = ipc::channel::().unwrap(); - send_to_constellation( + let _ = execute_script( sender, - ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand( - BrowsingContextId::from(panel.webview.webview_id), - WebDriverScriptCommand::ExecuteScript( - format!("window.navbar.setNavbarUrl('{}')", url.as_str()), - tx, - ), - )), + &panel.webview.webview_id, + format!("window.navbar.setNavbarUrl('{}')", url.as_str()), ); - let _ = rx.recv(); } } EmbedderMsg::EventDelivered(event) => { From a08d36e54637b789c234f2f39093a5523b891a04 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 23 Jan 2025 14:40:13 +0800 Subject: [PATCH 05/11] Migrate the rest of to use `execute_script` --- src/webview/mod.rs | 2 +- src/window.rs | 40 ++++++++++++++++------------------------ 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/webview/mod.rs b/src/webview/mod.rs index 6e7bf8c5..725c866a 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -1,6 +1,6 @@ mod webview; /// WebView -pub use webview::{Panel, WebView}; +pub use webview::{Panel, WebView, execute_script}; /// Context Menu pub mod context_menu; /// Prompt Dialog diff --git a/src/window.rs b/src/window.rs index fc5d595a..ab6bc26f 100644 --- a/src/window.rs +++ b/src/window.rs @@ -12,16 +12,12 @@ use glutin::{ surface::{Surface, WindowSurface}, }; use glutin_winit::DisplayBuilder; -use ipc_channel::ipc; use keyboard_types::{Code, KeyState, KeyboardEvent, Modifiers}; #[cfg(any(target_os = "macos", target_os = "windows"))] use muda::{Menu as MudaMenu, MenuEvent, MenuEventReceiver, MenuItem}; #[cfg(any(target_os = "macos", target_os = "windows"))] use raw_window_handle::HasWindowHandle; -use script_traits::{ - webdriver_msg::{WebDriverJSResult, WebDriverJSValue, WebDriverScriptCommand}, - TraversalDirection, WebDriverCommandMsg, -}; +use script_traits::{webdriver_msg::WebDriverJSValue, TraversalDirection}; use script_traits::{TouchEventType, WheelDelta, WheelMode}; use servo_url::ServoUrl; use webrender_api::{ @@ -46,6 +42,7 @@ use crate::{ verso::send_to_constellation, webview::{ context_menu::{ContextMenu, Menu}, + execute_script, prompt::PromptSender, Panel, WebView, }, @@ -242,20 +239,17 @@ impl Window { let mut webview = WebView::new(webview_id, rect); webview.set_size(content_size); - let (tx, rx) = ipc::channel::().unwrap(); let cmd: String = format!( "window.navbar.addTab('{}', {})", serde_json::to_string(&webview.webview_id).unwrap(), true, ); - send_to_constellation( + + let _ = execute_script( constellation_sender, - ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand( - self.panel.as_ref().unwrap().webview.webview_id.into(), - WebDriverScriptCommand::ExecuteScript(cmd, tx), - )), + &self.panel.as_ref().unwrap().webview.webview_id, + cmd, ); - let _ = rx.recv(); self.tab_manager.append_tab(webview, true); @@ -268,23 +262,18 @@ impl Window { /// Close a tab pub fn close_tab(&mut self, compositor: &mut IOCompositor, tab_id: WebViewId) { - let sender = compositor.constellation_chan.clone(); // if there are more than 2 tabs, we need to ask for the new active tab after tab is closed if self.tab_manager.count() > 1 { - let (tx, rx) = ipc::channel::().unwrap(); let cmd: String = format!( "window.navbar.closeTab('{}')", serde_json::to_string(&tab_id).unwrap() ); - send_to_constellation( - &sender, - ConstellationMsg::WebDriverCommand(WebDriverCommandMsg::ScriptCommand( - self.panel.as_ref().unwrap().webview.webview_id.into(), - WebDriverScriptCommand::ExecuteScript(cmd, tx), - )), - ); - - let active_tab_id = rx.recv().unwrap().unwrap(); + let active_tab_id = execute_script( + &compositor.constellation_chan, + &self.panel.as_ref().unwrap().webview.webview_id, + cmd, + ) + .unwrap(); match active_tab_id { WebDriverJSValue::String(resp) => { let active_id: WebViewId = serde_json::from_str(&resp).unwrap(); @@ -293,7 +282,10 @@ impl Window { _ => {} } } - send_to_constellation(&sender, ConstellationMsg::CloseWebView(tab_id)); + send_to_constellation( + &compositor.constellation_chan, + ConstellationMsg::CloseWebView(tab_id), + ); } /// Activate a tab From a82cccfd6dc95374dc0fdb3bd827d6eadd884255 Mon Sep 17 00:00:00 2001 From: Tony Date: Sun, 2 Feb 2025 12:23:08 +0800 Subject: [PATCH 06/11] format --- src/webview/mod.rs | 2 +- src/window.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/webview/mod.rs b/src/webview/mod.rs index 725c866a..f1002a1e 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -1,6 +1,6 @@ mod webview; /// WebView -pub use webview::{Panel, WebView, execute_script}; +pub use webview::{execute_script, Panel, WebView}; /// Context Menu pub mod context_menu; /// Prompt Dialog diff --git a/src/window.rs b/src/window.rs index 1ef17a23..21176a3b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -246,11 +246,7 @@ impl Window { true, ); - let _ = execute_script( - constellation_sender, - panel.webview.webview_id, - cmd, - ); + let _ = execute_script(constellation_sender, panel.webview.webview_id, cmd); } self.tab_manager.append_tab(webview, true); From 9430c5247d62e1a846bf799854893f5d16184b90 Mon Sep 17 00:00:00 2001 From: Tony Date: Sun, 2 Feb 2025 13:47:44 +0800 Subject: [PATCH 07/11] Should pass in reference --- src/window.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/window.rs b/src/window.rs index 21176a3b..e97657a2 100644 --- a/src/window.rs +++ b/src/window.rs @@ -246,7 +246,7 @@ impl Window { true, ); - let _ = execute_script(constellation_sender, panel.webview.webview_id, cmd); + let _ = execute_script(constellation_sender, &panel.webview.webview_id, cmd); } self.tab_manager.append_tab(webview, true); @@ -269,7 +269,7 @@ impl Window { ); let active_tab_id = execute_script( &compositor.constellation_chan, - panel.webview.webview_id, + &panel.webview.webview_id, cmd, ) .unwrap(); From 8fb3d920397c0ff5e3d292b68f1223536a3e3166 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 4 Feb 2025 12:16:21 +0800 Subject: [PATCH 08/11] Merge conflict --- src/webview/webview.rs | 7 ++----- src/window.rs | 5 +---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/webview/webview.rs b/src/webview/webview.rs index 0fa6e47a..8781a0df 100644 --- a/src/webview/webview.rs +++ b/src/webview/webview.rs @@ -7,10 +7,7 @@ use embedder_traits::{ PromptCredentialsInput, PromptDefinition, PromptResult, TraversalDirection, }; use ipc_channel::ipc; -use script_traits::{ - webdriver_msg::{WebDriverJSResult, WebDriverScriptCommand}, - -}; +use script_traits::webdriver_msg::{WebDriverJSResult, WebDriverScriptCommand}; use servo_url::ServoUrl; use url::Url; use webrender_api::units::DeviceIntRect; @@ -77,7 +74,7 @@ impl Window { ) { log::trace!("Verso WebView {webview_id:?} is handling Embedder message: {message:?}",); match message { - EmbedderMsg::HeadParsed + EmbedderMsg::HeadParsed(_) | EmbedderMsg::WebViewOpened(_) | EmbedderMsg::WebViewClosed(_) => { // Most WebView messages are ignored because it's done by compositor. diff --git a/src/window.rs b/src/window.rs index f5e506f2..95b3a967 100644 --- a/src/window.rs +++ b/src/window.rs @@ -18,10 +18,7 @@ use keyboard_types::{Code, KeyState, KeyboardEvent, Modifiers}; use muda::{Menu as MudaMenu, MenuEvent, MenuEventReceiver, MenuItem}; #[cfg(any(target_os = "macos", target_os = "windows"))] use raw_window_handle::HasWindowHandle; -use script_traits::{ - webdriver_msg::{WebDriverJSResult, WebDriverJSValue, WebDriverScriptCommand}, - WebDriverCommandMsg, -}; +use script_traits::webdriver_msg::WebDriverJSValue; use servo_url::ServoUrl; use webrender_api::{ units::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, LayoutVector2D}, From 7aed2e57c15597351959be9d001422b45f1e8589 Mon Sep 17 00:00:00 2001 From: Tony Date: Tue, 4 Feb 2025 23:40:12 +0800 Subject: [PATCH 09/11] Merge conflict missing import --- src/window.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/window.rs b/src/window.rs index ce9280c4..3656db21 100644 --- a/src/window.rs +++ b/src/window.rs @@ -13,6 +13,7 @@ use glutin::{ surface::{Surface, WindowSurface}, }; use glutin_winit::DisplayBuilder; +use ipc_channel::ipc::IpcSender; use keyboard_types::{Code, KeyState, KeyboardEvent, Modifiers}; #[cfg(any(target_os = "macos", target_os = "windows"))] use muda::{Menu as MudaMenu, MenuEvent, MenuEventReceiver, MenuItem}; @@ -602,7 +603,7 @@ impl Window { webview_id: WebViewId, message: EmbedderMsg, sender: &Sender, - to_controller_sender: &Option>, + to_controller_sender: &Option>, clipboard: Option<&mut Clipboard>, compositor: &mut IOCompositor, ) -> bool { From e3ca233748ec2316e986666a8977a7f7cf26e296 Mon Sep 17 00:00:00 2001 From: Tony Date: Thu, 6 Feb 2025 18:14:31 +0800 Subject: [PATCH 10/11] Use sync version of execute script for init script --- src/webview/webview.rs | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/src/webview/webview.rs b/src/webview/webview.rs index 72cc9aa7..0ce9c272 100644 --- a/src/webview/webview.rs +++ b/src/webview/webview.rs @@ -96,7 +96,7 @@ impl Window { } EmbedderMsg::LoadStart(_) => { if let Some(init_script) = &self.init_script { - execute_script_async(&sender, &webview_id, init_script); + let _ = execute_script(&sender, &webview_id, init_script); } } EmbedderMsg::LoadComplete(_webview_id) => { @@ -639,30 +639,3 @@ pub fn execute_script( ); result_receiver.recv().unwrap() } - -/// Execute a script asynchronous on this webview -pub fn execute_script_async( - constellation_sender: &Sender, - webview: &WebViewId, - js: impl ToString, -) { - execute_script_async_with_callback(constellation_sender, webview, js, |_| {}) -} - -/// Execute a script asynchronous on this webview with a callback processing the result -pub fn execute_script_async_with_callback( - constellation_sender: &Sender, - webview: &WebViewId, - js: impl ToString, - callback: impl FnOnce(WebDriverJSResult) + Send + 'static, -) { - let (result_sender, result_receiver) = ipc::channel::().unwrap(); - send_to_constellation( - constellation_sender, - ConstellationMsg::WebDriverCommand(script_traits::WebDriverCommandMsg::ScriptCommand( - webview.0, - WebDriverScriptCommand::ExecuteAsyncScript(js.to_string(), result_sender), - )), - ); - std::thread::spawn(move || callback(result_receiver.recv().unwrap())); -} From 8a7d005e7f6068e466c085287626fd7292475af3 Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Thu, 6 Feb 2025 19:24:36 +0800 Subject: [PATCH 11/11] Update src/webview/webview.rs Co-authored-by: Jason Tsai Signed-off-by: Tony <68118705+Legend-Master@users.noreply.github.com> --- src/webview/webview.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webview/webview.rs b/src/webview/webview.rs index 0ce9c272..c7ffe223 100644 --- a/src/webview/webview.rs +++ b/src/webview/webview.rs @@ -96,7 +96,7 @@ impl Window { } EmbedderMsg::LoadStart(_) => { if let Some(init_script) = &self.init_script { - let _ = execute_script(&sender, &webview_id, init_script); + let _ = execute_script(sender, &webview_id, init_script); } } EmbedderMsg::LoadComplete(_webview_id) => {