webview.rs 7.2 KB

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