webview.rs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! Items specific to the [`Runtime`](crate::Runtime)'s webview.
  5. use crate::{window::DetachedWindow, Icon};
  6. #[cfg(feature = "menu")]
  7. use crate::menu::Menu;
  8. use serde::Deserialize;
  9. use serde_json::Value as JsonValue;
  10. use tauri_utils::config::{WindowConfig, WindowUrl};
  11. #[cfg(windows)]
  12. use winapi::shared::windef::HWND;
  13. use std::{collections::HashMap, path::PathBuf};
  14. type UriSchemeProtocol =
  15. dyn Fn(&str) -> Result<Vec<u8>, Box<dyn std::error::Error>> + Send + Sync + 'static;
  16. /// The attributes used to create an webview.
  17. pub struct WebviewAttributes {
  18. pub url: WindowUrl,
  19. pub initialization_scripts: Vec<String>,
  20. pub data_directory: Option<PathBuf>,
  21. pub uri_scheme_protocols: HashMap<String, Box<UriSchemeProtocol>>,
  22. pub file_drop_handler_enabled: bool,
  23. }
  24. impl WebviewAttributes {
  25. /// Initializes the default attributes for a webview.
  26. pub fn new(url: WindowUrl) -> Self {
  27. Self {
  28. url,
  29. initialization_scripts: Vec::new(),
  30. data_directory: None,
  31. uri_scheme_protocols: Default::default(),
  32. file_drop_handler_enabled: true,
  33. }
  34. }
  35. /// Sets the init script.
  36. pub fn initialization_script(mut self, script: &str) -> Self {
  37. self.initialization_scripts.push(script.to_string());
  38. self
  39. }
  40. /// Data directory for the webview.
  41. pub fn data_directory(mut self, data_directory: PathBuf) -> Self {
  42. self.data_directory.replace(data_directory);
  43. self
  44. }
  45. /// Whether the webview URI scheme protocol is defined or not.
  46. pub fn has_uri_scheme_protocol(&self, name: &str) -> bool {
  47. self.uri_scheme_protocols.contains_key(name)
  48. }
  49. /// Registers a webview protocol handler.
  50. /// Leverages [setURLSchemeHandler](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/2875766-seturlschemehandler) on macOS,
  51. /// [AddWebResourceRequestedFilter](https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.addwebresourcerequestedfilter?view=webview2-dotnet-1.0.774.44) on Windows
  52. /// and [webkit-web-context-register-uri-scheme](https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebContext.html#webkit-web-context-register-uri-scheme) on Linux.
  53. ///
  54. /// # Arguments
  55. ///
  56. /// * `uri_scheme` The URI scheme to register, such as `example`.
  57. /// * `protocol` the protocol associated with the given URI scheme. It's a function that takes an URL such as `example://localhost/asset.css`.
  58. pub fn register_uri_scheme_protocol<
  59. N: Into<String>,
  60. H: Fn(&str) -> Result<Vec<u8>, Box<dyn std::error::Error>> + Send + Sync + 'static,
  61. >(
  62. mut self,
  63. uri_scheme: N,
  64. protocol: H,
  65. ) -> Self {
  66. let uri_scheme = uri_scheme.into();
  67. self
  68. .uri_scheme_protocols
  69. .insert(uri_scheme, Box::new(move |data| (protocol)(data)));
  70. self
  71. }
  72. /// Disables the file drop handler. This is required to use drag and drop APIs on the front end on Windows.
  73. pub fn disable_file_drop_handler(mut self) -> Self {
  74. self.file_drop_handler_enabled = false;
  75. self
  76. }
  77. }
  78. /// Do **NOT** implement this trait except for use in a custom [`Runtime`](crate::Runtime).
  79. ///
  80. /// This trait is separate from [`WindowBuilder`] to prevent "accidental" implementation.
  81. pub trait WindowBuilderBase: Sized {}
  82. /// A builder for all attributes related to a single webview.
  83. ///
  84. /// This trait is only meant to be implemented by a custom [`Runtime`](crate::Runtime)
  85. /// and not by applications.
  86. pub trait WindowBuilder: WindowBuilderBase {
  87. /// Initializes a new window attributes builder.
  88. fn new() -> Self;
  89. /// Initializes a new webview builder from a [`WindowConfig`]
  90. fn with_config(config: WindowConfig) -> Self;
  91. /// Sets the menu for the window.
  92. #[cfg(feature = "menu")]
  93. #[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
  94. fn menu(self, menu: Menu) -> Self;
  95. /// Show window in the center of the screen.
  96. fn center(self) -> Self;
  97. /// The initial position of the window's.
  98. fn position(self, x: f64, y: f64) -> Self;
  99. /// Window size.
  100. fn inner_size(self, min_width: f64, min_height: f64) -> Self;
  101. /// Window min inner size.
  102. fn min_inner_size(self, min_width: f64, min_height: f64) -> Self;
  103. /// Window max inner size.
  104. fn max_inner_size(self, max_width: f64, max_height: f64) -> Self;
  105. /// Whether the window is resizable or not.
  106. fn resizable(self, resizable: bool) -> Self;
  107. /// The title of the window in the title bar.
  108. fn title<S: Into<String>>(self, title: S) -> Self;
  109. /// Whether to start the window in fullscreen or not.
  110. fn fullscreen(self, fullscreen: bool) -> Self;
  111. /// Whether the window will be initially hidden or focused.
  112. fn focus(self) -> Self;
  113. /// Whether the window should be maximized upon creation.
  114. fn maximized(self, maximized: bool) -> Self;
  115. /// Whether the window should be immediately visible upon creation.
  116. fn visible(self, visible: bool) -> Self;
  117. /// Whether the the window should be transparent. If this is true, writing colors
  118. /// with alpha values different than `1.0` will produce a transparent window.
  119. fn transparent(self, transparent: bool) -> Self;
  120. /// Whether the window should have borders and bars.
  121. fn decorations(self, decorations: bool) -> Self;
  122. /// Whether the window should always be on top of other windows.
  123. fn always_on_top(self, always_on_top: bool) -> Self;
  124. /// Sets the window icon.
  125. fn icon(self, icon: Icon) -> crate::Result<Self>;
  126. /// Sets whether or not the window icon should be added to the taskbar.
  127. fn skip_taskbar(self, skip: bool) -> Self;
  128. /// Sets a parent to the window to be created.
  129. ///
  130. /// A child window has the WS_CHILD style and is confined to the client area of its parent window.
  131. ///
  132. /// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#child-windows>
  133. #[cfg(windows)]
  134. fn parent_window(self, parent: HWND) -> Self;
  135. /// Set an owner to the window to be created.
  136. ///
  137. /// From MSDN:
  138. /// - An owned window is always above its owner in the z-order.
  139. /// - The system automatically destroys an owned window when its owner is destroyed.
  140. /// - An owned window is hidden when its owner is minimized.
  141. ///
  142. /// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
  143. #[cfg(windows)]
  144. fn owner_window(self, owner: HWND) -> Self;
  145. /// Whether the icon was set or not.
  146. fn has_icon(&self) -> bool;
  147. /// Whether the menu was set or not.
  148. #[cfg(feature = "menu")]
  149. #[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
  150. fn has_menu(&self) -> bool;
  151. }
  152. /// Rpc request.
  153. pub struct RpcRequest {
  154. /// RPC command.
  155. pub command: String,
  156. /// Params.
  157. pub params: Option<JsonValue>,
  158. }
  159. /// Uses a custom URI scheme handler to resolve file requests
  160. pub struct CustomProtocol {
  161. /// Handler for protocol
  162. #[allow(clippy::type_complexity)]
  163. pub protocol: Box<dyn Fn(&str) -> Result<Vec<u8>, Box<dyn std::error::Error>> + Send + Sync>,
  164. }
  165. /// The file drop event payload.
  166. #[derive(Debug, Clone)]
  167. #[non_exhaustive]
  168. pub enum FileDropEvent {
  169. /// The file(s) have been dragged onto the window, but have not been dropped yet.
  170. Hovered(Vec<PathBuf>),
  171. /// The file(s) have been dropped onto the window.
  172. Dropped(Vec<PathBuf>),
  173. /// The file drop was aborted.
  174. Cancelled,
  175. }
  176. /// Rpc handler.
  177. pub type WebviewRpcHandler<R> = Box<dyn Fn(DetachedWindow<R>, RpcRequest) + Send>;
  178. /// File drop handler callback
  179. /// Return `true` in the callback to block the OS' default behavior of handling a file drop.
  180. pub type FileDropHandler<R> = Box<dyn Fn(FileDropEvent, DetachedWindow<R>) -> bool + Send>;
  181. #[derive(Deserialize)]
  182. pub struct InvokePayload {
  183. #[serde(rename = "__tauriModule")]
  184. pub tauri_module: Option<String>,
  185. pub callback: String,
  186. pub error: String,
  187. #[serde(rename = "__invokeKey")]
  188. pub key: u32,
  189. #[serde(flatten)]
  190. pub inner: JsonValue,
  191. }