From 4abd12c2a42b5ace8527114ab64da38f4486754f Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Thu, 23 Jul 2020 08:38:40 -0300 Subject: [PATCH] fix(tauri) webview initialization on windows, fixes #879 (#885) --- .changes/tauri-windows.md | 6 +++++ cli/tauri.js/templates/tauri.js | 22 ------------------ tauri/Cargo.toml | 2 +- tauri/src/app.rs | 12 +++++----- tauri/src/app/runner.rs | 36 +++++++++++++++-------------- tauri/src/endpoints.rs | 8 +++---- tauri/src/endpoints/asset.rs | 2 +- tauri/src/endpoints/dialog.rs | 6 ++--- tauri/src/endpoints/file_system.rs | 20 ++++++++-------- tauri/src/endpoints/http.rs | 2 +- tauri/src/endpoints/notification.rs | 11 ++++++--- tauri/src/endpoints/salt.rs | 2 +- tauri/src/lib.rs | 8 +++---- tauri/src/plugin.rs | 12 +++++----- 14 files changed, 70 insertions(+), 79 deletions(-) create mode 100644 .changes/tauri-windows.md diff --git a/.changes/tauri-windows.md b/.changes/tauri-windows.md new file mode 100644 index 000000000..5fefe16a8 --- /dev/null +++ b/.changes/tauri-windows.md @@ -0,0 +1,6 @@ +--- +"tauri": minor +"tauri.js": minor +--- + +Fixes the Webview initialization on Windows. diff --git a/cli/tauri.js/templates/tauri.js b/cli/tauri.js/templates/tauri.js index e3efca6c1..3f605a79f 100644 --- a/cli/tauri.js/templates/tauri.js +++ b/cli/tauri.js/templates/tauri.js @@ -7,28 +7,6 @@ if (!String.prototype.startsWith) { } (function () { - function webviewBind (name) { - var RPC = window._rpc = (window._rpc || { nextSeq: 1 }); - window[name] = function () { - var seq = RPC.nextSeq++; - var promise = new Promise(function (resolve, reject) { - RPC[seq] = { - resolve: resolve, - reject: reject, - }; - }); - window.external.invoke(JSON.stringify({ - id: seq, - method: name, - params: Array.prototype.slice.call(arguments), - })); - return promise; - } - } - if (!window.__TAURI_INVOKE_HANDLER__) { - webviewBind('__TAURI_INVOKE_HANDLER__') - } - function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) diff --git a/tauri/Cargo.toml b/tauri/Cargo.toml index 041839c76..7ce5975eb 100644 --- a/tauri/Cargo.toml +++ b/tauri/Cargo.toml @@ -20,7 +20,7 @@ features = [ "all-api" ] [dependencies] serde_json = "1.0" serde = { version = "1.0", features = [ "derive" ] } -webview_official = "0.0.1" +webview_official = "0.0.2" tauri_includedir = "0.6.0" phf = "0.8.0" base64 = "0.12.3" diff --git a/tauri/src/app.rs b/tauri/src/app.rs index 41269129e..2064f84fa 100644 --- a/tauri/src/app.rs +++ b/tauri/src/app.rs @@ -2,8 +2,8 @@ use webview_official::Webview; mod runner; -type InvokeHandler = Box Result<(), String>>; -type Setup = Box; +type InvokeHandler = Box, &str) -> Result<(), String>>; +type Setup = Box, String)>; /// The application runner. pub struct App { @@ -26,7 +26,7 @@ impl App { /// The message is considered consumed if the handler exists and returns an Ok Result. pub(crate) fn run_invoke_handler( &mut self, - webview: &mut Webview, + webview: &mut Webview<'_>, arg: &str, ) -> Result { if let Some(ref mut invoke_handler) = self.invoke_handler { @@ -37,7 +37,7 @@ impl App { } /// Runs the setup callback if defined. - pub(crate) fn run_setup(&mut self, webview: &mut Webview, source: String) { + pub(crate) fn run_setup(&mut self, webview: &mut Webview<'_>, source: String) { if let Some(ref mut setup) = self.setup { setup(webview, source); } @@ -71,7 +71,7 @@ impl AppBuilder { } /// Defines the JS message handler callback. - pub fn invoke_handler Result<(), String> + 'static>( + pub fn invoke_handler, &str) -> Result<(), String> + 'static>( mut self, invoke_handler: F, ) -> Self { @@ -80,7 +80,7 @@ impl AppBuilder { } /// Defines the setup callback. - pub fn setup(mut self, setup: F) -> Self { + pub fn setup, String) + 'static>(mut self, setup: F) -> Self { self.setup = Some(Box::new(setup)); self } diff --git a/tauri/src/app/runner.rs b/tauri/src/app/runner.rs index 519d43a1e..234fd37ad 100644 --- a/tauri/src/app/runner.rs +++ b/tauri/src/app/runner.rs @@ -236,7 +236,7 @@ fn build_webview( application: &mut App, content: Content, splashscreen_content: Option>, -) -> crate::Result { +) -> crate::Result> { let config = get()?; let content_clone = match content { Content::Html(ref html) => Content::Html(html.clone()), @@ -264,28 +264,30 @@ fn build_webview( }, }; - let mut webview = WebviewBuilder::new() - .init(&format!( - r#" - {event_init} - if (window.__TAURI_INVOKE_HANDLER__) {{ + let init = format!( + r#" + {event_init} + if (window.__TAURI_INVOKE_HANDLER__) {{ + window.__TAURI_INVOKE_HANDLER__({{ cmd: "__initialized" }}) + }} else {{ + window.addEventListener('DOMContentLoaded', function () {{ window.__TAURI_INVOKE_HANDLER__({{ cmd: "__initialized" }}) - }} else {{ - window.addEventListener('DOMContentLoaded', function () {{ - window.__TAURI_INVOKE_HANDLER__({{ cmd: "__initialized" }}) - }}) - }} - {plugin_init} - "#, - event_init = init(), - plugin_init = crate::plugin::init_script() - )) + }}) + }} + {plugin_init} + "#, + event_init = init(), + plugin_init = crate::plugin::init_script() + ); + + let mut webview = WebviewBuilder::new() + .init(Box::leak(init.into_boxed_str())) .title(Box::leak(title)) .width(width as usize) .height(height as usize) .resize(resizable) .debug(debug) - .url(&url) + .url(Box::leak(url.into_boxed_str())) .build(); // TODO waiting for webview window API // webview.set_fullscreen(fullscreen); diff --git a/tauri/src/endpoints.rs b/tauri/src/endpoints.rs index 21984ba4c..6d39268c6 100644 --- a/tauri/src/endpoints.rs +++ b/tauri/src/endpoints.rs @@ -18,7 +18,7 @@ mod notification; use webview_official::Webview; #[allow(unused_variables)] -pub(crate) fn handle(webview: &mut Webview, arg: &str) -> crate::Result<()> { +pub(crate) fn handle(webview: &mut Webview<'_>, arg: &str) -> crate::Result<()> { use cmd::Cmd::*; match serde_json::from_str(arg) { Err(e) => Err(e.into()), @@ -304,13 +304,13 @@ pub(crate) fn handle(webview: &mut Webview, arg: &str) -> crate::Result<()> { } #[allow(dead_code)] -fn api_error(webview: &mut Webview, error_fn: String, message: &str) { +fn api_error(webview: &mut Webview<'_>, error_fn: String, message: &str) { let reject_code = tauri_api::rpc::format_callback(error_fn, message); webview.eval(&reject_code) } #[allow(dead_code)] -fn allowlist_error(webview: &mut Webview, error_fn: String, allowlist_key: &str) { +fn allowlist_error(webview: &mut Webview<'_>, error_fn: String, allowlist_key: &str) { api_error( webview, error_fn, @@ -322,7 +322,7 @@ fn allowlist_error(webview: &mut Webview, error_fn: String, allowlist_key: &str) } #[allow(dead_code)] -fn throw_allowlist_error(webview: &mut Webview, allowlist_key: &str) { +fn throw_allowlist_error(webview: &mut Webview<'_>, allowlist_key: &str) { let reject_code = format!( r#"throw new Error("'{}' not on the allowlist")"#, allowlist_key diff --git a/tauri/src/endpoints/asset.rs b/tauri/src/endpoints/asset.rs index 8f66b40a8..9f5bb779e 100644 --- a/tauri/src/endpoints/asset.rs +++ b/tauri/src/endpoints/asset.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use webview_official::Webview; pub fn load( - webview: &mut Webview, + webview: &mut Webview<'_>, asset: String, asset_type: String, callback: String, diff --git a/tauri/src/endpoints/dialog.rs b/tauri/src/endpoints/dialog.rs index 7a8d3a322..d0056047f 100644 --- a/tauri/src/endpoints/dialog.rs +++ b/tauri/src/endpoints/dialog.rs @@ -19,7 +19,7 @@ fn map_response(response: Response) -> JsonValue { /// Shows an open dialog. #[cfg(open_dialog)] pub fn open( - webview: &mut Webview, + webview: &mut Webview<'_>, options: OpenDialogOptions, callback: String, error: String, @@ -45,7 +45,7 @@ pub fn open( /// Shows a save dialog. #[cfg(save_dialog)] pub fn save( - webview: &mut Webview, + webview: &mut Webview<'_>, options: SaveDialogOptions, callback: String, error: String, @@ -66,7 +66,7 @@ pub fn message(title: String, message: String) { /// Shows a dialog with a yes/no question. pub fn ask( - webview: &mut Webview, + webview: &mut Webview<'_>, title: String, message: String, callback: String, diff --git a/tauri/src/endpoints/file_system.rs b/tauri/src/endpoints/file_system.rs index 6528c9dcb..d247d1ce0 100644 --- a/tauri/src/endpoints/file_system.rs +++ b/tauri/src/endpoints/file_system.rs @@ -14,7 +14,7 @@ use super::cmd::{DirOperationOptions, FileOperationOptions}; /// Reads a directory. #[cfg(read_dir)] pub fn read_dir( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, options: Option, callback: String, @@ -38,7 +38,7 @@ pub fn read_dir( /// Copies a file. #[cfg(copy_file)] pub fn copy_file( - webview: &mut Webview, + webview: &mut Webview<'_>, source: PathBuf, destination: PathBuf, options: Option, @@ -65,7 +65,7 @@ pub fn copy_file( /// Creates a directory. #[cfg(create_dir)] pub fn create_dir( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, options: Option, callback: String, @@ -96,7 +96,7 @@ pub fn create_dir( /// Removes a directory. #[cfg(remove_dir)] pub fn remove_dir( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, options: Option, callback: String, @@ -127,7 +127,7 @@ pub fn remove_dir( /// Removes a file #[cfg(remove_file)] pub fn remove_file( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, options: Option, callback: String, @@ -147,7 +147,7 @@ pub fn remove_file( /// Renames a file. #[cfg(rename_file)] pub fn rename_file( - webview: &mut Webview, + webview: &mut Webview<'_>, old_path: PathBuf, new_path: PathBuf, options: Option, @@ -174,7 +174,7 @@ pub fn rename_file( /// Writes a text file. #[cfg(write_file)] pub fn write_file( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, contents: String, options: Option, @@ -196,7 +196,7 @@ pub fn write_file( /// Writes a binary file. #[cfg(write_binary_file)] pub fn write_binary_file( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, contents: String, options: Option, @@ -222,7 +222,7 @@ pub fn write_binary_file( /// Reads a text file. #[cfg(read_text_file)] pub fn read_text_file( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, options: Option, callback: String, @@ -239,7 +239,7 @@ pub fn read_text_file( /// Reads a binary file. #[cfg(read_binary_file)] pub fn read_binary_file( - webview: &mut Webview, + webview: &mut Webview<'_>, path: PathBuf, options: Option, callback: String, diff --git a/tauri/src/endpoints/http.rs b/tauri/src/endpoints/http.rs index c0c90e75d..45e158224 100644 --- a/tauri/src/endpoints/http.rs +++ b/tauri/src/endpoints/http.rs @@ -3,7 +3,7 @@ use webview_official::Webview; /// Makes an HTTP request and resolves the response to the webview pub fn make_request( - webview: &mut Webview, + webview: &mut Webview<'_>, options: HttpRequestOptions, callback: String, error: String, diff --git a/tauri/src/endpoints/notification.rs b/tauri/src/endpoints/notification.rs index 67c11a181..12dec6b39 100644 --- a/tauri/src/endpoints/notification.rs +++ b/tauri/src/endpoints/notification.rs @@ -2,7 +2,12 @@ use super::cmd::NotificationOptions; use serde_json::Value as JsonValue; use webview_official::Webview; -pub fn send(webview: &mut Webview, options: NotificationOptions, callback: String, error: String) { +pub fn send( + webview: &mut Webview<'_>, + options: NotificationOptions, + callback: String, + error: String, +) { crate::execute_promise( webview, move || { @@ -21,7 +26,7 @@ pub fn send(webview: &mut Webview, options: NotificationOptions, callback: Strin ); } -pub fn is_permission_granted(webview: &mut Webview, callback: String, error: String) { +pub fn is_permission_granted(webview: &mut Webview<'_>, callback: String, error: String) { crate::execute_promise( webview, move || { @@ -38,7 +43,7 @@ pub fn is_permission_granted(webview: &mut Webview, callback: String, error: Str } pub fn request_permission( - webview: &mut Webview, + webview: &mut Webview<'_>, callback: String, error: String, ) -> crate::Result<()> { diff --git a/tauri/src/endpoints/salt.rs b/tauri/src/endpoints/salt.rs index d58044203..fa77e2aaa 100644 --- a/tauri/src/endpoints/salt.rs +++ b/tauri/src/endpoints/salt.rs @@ -2,7 +2,7 @@ use webview_official::Webview; /// Validates a salt. pub fn validate( - webview: &mut Webview, + webview: &mut Webview<'_>, salt: String, callback: String, error: String, diff --git a/tauri/src/lib.rs b/tauri/src/lib.rs index f9998e266..2375ce4c9 100644 --- a/tauri/src/lib.rs +++ b/tauri/src/lib.rs @@ -61,7 +61,7 @@ pub fn spawn () + Send + 'static>(task: F) { /// Synchronously executes the given task /// and evaluates its Result to the JS promise described by the `callback` and `error` function names. pub fn execute_promise_sync crate::Result + Send + 'static>( - webview: &mut Webview, + webview: &mut Webview<'_>, task: F, callback: String, error: String, @@ -78,7 +78,7 @@ pub fn execute_promise_sync crate::Result + Send /// If the Result `is_ok()`, the callback will be the `success_callback` function name and the argument will be the Ok value. /// If the Result `is_err()`, the callback will be the `error_callback` function name and the argument will be the Err value. pub fn execute_promise crate::Result + Send + 'static>( - webview: &mut Webview, + webview: &mut Webview<'_>, task: F, success_callback: String, error_callback: String, @@ -103,7 +103,7 @@ pub fn execute_promise crate::Result + Send + 's /// Calls the given command and evaluates its output to the JS promise described by the `callback` and `error` function names. pub fn call( - webview: &mut Webview, + webview: &mut Webview<'_>, command: String, args: Vec, callback: String, @@ -118,7 +118,7 @@ pub fn call( } /// Closes the splashscreen. -pub fn close_splashscreen(webview: &mut Webview) -> crate::Result<()> { +pub fn close_splashscreen(webview: &mut Webview<'_>) -> crate::Result<()> { // send a signal to the runner so it knows that it should redirect to the main app content webview.eval(r#"window.__TAURI_INVOKE_HANDLER__({ cmd: "closeSplashscreen" })"#); diff --git a/tauri/src/plugin.rs b/tauri/src/plugin.rs index 49d63e559..4c45352ca 100644 --- a/tauri/src/plugin.rs +++ b/tauri/src/plugin.rs @@ -9,15 +9,15 @@ pub trait Plugin { } /// Callback invoked when the webview is created. #[allow(unused_variables)] - fn created(&self, webview: &mut Webview) {} + fn created(&self, webview: &mut Webview<'_>) {} /// Callback invoked when the webview is ready. #[allow(unused_variables)] - fn ready(&self, webview: &mut Webview) {} + fn ready(&self, webview: &mut Webview<'_>) {} /// Add invoke_handler API extension commands. #[allow(unused_variables)] - fn extend_api(&self, webview: &mut Webview, payload: &str) -> Result { + fn extend_api(&self, webview: &mut Webview<'_>, payload: &str) -> Result { Err("unknown variant".to_string()) } } @@ -53,19 +53,19 @@ pub(crate) fn init_script() -> String { init } -pub(crate) fn created(webview: &mut Webview) { +pub(crate) fn created(webview: &mut Webview<'_>) { run_plugin(|ext| { ext.created(webview); }); } -pub(crate) fn ready(webview: &mut Webview) { +pub(crate) fn ready(webview: &mut Webview<'_>) { run_plugin(|ext| { ext.ready(webview); }); } -pub(crate) fn extend_api(webview: &mut Webview, arg: &str) -> Result { +pub(crate) fn extend_api(webview: &mut Webview<'_>, arg: &str) -> Result { PLUGINS.with(|plugins| { let exts = plugins.lock().unwrap(); for ext in exts.iter() {