webview.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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::Runtime)'s webview.
  5. use crate::runtime::Icon;
  6. use crate::{
  7. api::config::{WindowConfig, WindowUrl},
  8. runtime::window::DetachedWindow,
  9. };
  10. use serde::Deserialize;
  11. use serde_json::Value as JsonValue;
  12. use std::{collections::HashMap, path::PathBuf};
  13. type UriSchemeProtocol = dyn Fn(&str) -> crate::Result<Vec<u8>> + Send + Sync + 'static;
  14. /// The attributes used to create an webview.
  15. pub struct WebviewAttributes {
  16. pub(crate) url: WindowUrl,
  17. pub(crate) initialization_scripts: Vec<String>,
  18. pub(crate) data_directory: Option<PathBuf>,
  19. pub(crate) uri_scheme_protocols: HashMap<String, Box<UriSchemeProtocol>>,
  20. }
  21. impl WebviewAttributes {
  22. /// Initializes the default attributes for a webview.
  23. pub fn new(url: WindowUrl) -> Self {
  24. Self {
  25. url,
  26. initialization_scripts: Vec::new(),
  27. data_directory: None,
  28. uri_scheme_protocols: Default::default(),
  29. }
  30. }
  31. /// Sets the init script.
  32. pub fn initialization_script(mut self, script: &str) -> Self {
  33. self.initialization_scripts.push(script.to_string());
  34. self
  35. }
  36. /// Data directory for the webview.
  37. pub fn data_directory(mut self, data_directory: PathBuf) -> Self {
  38. self.data_directory.replace(data_directory);
  39. self
  40. }
  41. /// Whether the webview URI scheme protocol is defined or not.
  42. pub fn has_uri_scheme_protocol(&self, name: &str) -> bool {
  43. self.uri_scheme_protocols.contains_key(name)
  44. }
  45. /// Registers a webview protocol handler.
  46. /// Leverages [setURLSchemeHandler](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/2875766-seturlschemehandler) on macOS,
  47. /// [AddWebResourceRequestedFilter](https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.addwebresourcerequestedfilter?view=webview2-dotnet-1.0.774.44) on Windows
  48. /// and [webkit-web-context-register-uri-scheme](https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebContext.html#webkit-web-context-register-uri-scheme) on Linux.
  49. ///
  50. /// # Arguments
  51. ///
  52. /// * `uri_scheme` The URI scheme to register, such as `example`.
  53. /// * `protocol` the protocol associated with the given URI scheme. It's a function that takes an URL such as `example://localhost/asset.css`.
  54. pub fn register_uri_scheme_protocol<
  55. N: Into<String>,
  56. H: Fn(&str) -> crate::Result<Vec<u8>> + Send + Sync + 'static,
  57. >(
  58. mut self,
  59. uri_scheme: N,
  60. protocol: H,
  61. ) -> Self {
  62. let uri_scheme = uri_scheme.into();
  63. self
  64. .uri_scheme_protocols
  65. .insert(uri_scheme, Box::new(move |data| (protocol)(data)));
  66. self
  67. }
  68. }
  69. /// Do **NOT** implement this trait except for use in a custom [`Runtime`](crate::runtime::Runtime).
  70. ///
  71. /// This trait is separate from [`WindowBuilder`] to prevent "accidental" implementation.
  72. pub trait WindowBuilderBase: Sized {}
  73. /// A builder for all attributes related to a single webview.
  74. ///
  75. /// This trait is only meant to be implemented by a custom [`Runtime`](crate::runtime::Runtime)
  76. /// and not by applications.
  77. pub trait WindowBuilder: WindowBuilderBase {
  78. /// Initializes a new window attributes builder.
  79. fn new() -> Self;
  80. /// Initializes a new webview builder from a [`WindowConfig`]
  81. fn with_config(config: WindowConfig) -> Self;
  82. /// The initial position of the window's.
  83. fn position(self, x: f64, y: f64) -> Self;
  84. /// Window size.
  85. fn inner_size(self, min_width: f64, min_height: f64) -> Self;
  86. /// Window min inner size.
  87. fn min_inner_size(self, min_width: f64, min_height: f64) -> Self;
  88. /// Window max inner size.
  89. fn max_inner_size(self, min_width: f64, min_height: f64) -> Self;
  90. /// Whether the window is resizable or not.
  91. fn resizable(self, resizable: bool) -> Self;
  92. /// The title of the window in the title bar.
  93. fn title<S: Into<String>>(self, title: S) -> Self;
  94. /// Whether to start the window in fullscreen or not.
  95. fn fullscreen(self, fullscreen: bool) -> Self;
  96. /// Whether the window should be maximized upon creation.
  97. fn maximized(self, maximized: bool) -> Self;
  98. /// Whether the window should be immediately visible upon creation.
  99. fn visible(self, visible: bool) -> Self;
  100. /// Whether the the window should be transparent. If this is true, writing colors
  101. /// with alpha values different than `1.0` will produce a transparent window.
  102. fn transparent(self, transparent: bool) -> Self;
  103. /// Whether the window should have borders and bars.
  104. fn decorations(self, decorations: bool) -> Self;
  105. /// Whether the window should always be on top of other windows.
  106. fn always_on_top(self, always_on_top: bool) -> Self;
  107. /// Sets the window icon.
  108. fn icon(self, icon: Icon) -> crate::Result<Self>;
  109. /// Whether the icon was set or not.
  110. fn has_icon(&self) -> bool;
  111. }
  112. /// Rpc request.
  113. pub struct RpcRequest {
  114. /// RPC command.
  115. pub command: String,
  116. /// Params.
  117. pub params: Option<JsonValue>,
  118. }
  119. /// Uses a custom URI scheme handler to resolve file requests
  120. pub struct CustomProtocol {
  121. /// Handler for protocol
  122. pub protocol: Box<dyn Fn(&str) -> crate::Result<Vec<u8>> + Send + Sync>,
  123. }
  124. /// The file drop event payload.
  125. #[derive(Debug, Clone)]
  126. pub enum FileDropEvent {
  127. /// The file(s) have been dragged onto the window, but have not been dropped yet.
  128. Hovered(Vec<PathBuf>),
  129. /// The file(s) have been dropped onto the window.
  130. Dropped(Vec<PathBuf>),
  131. /// The file drop was aborted.
  132. Cancelled,
  133. }
  134. /// Rpc handler.
  135. pub(crate) type WebviewRpcHandler<M> = Box<dyn Fn(DetachedWindow<M>, RpcRequest) + Send>;
  136. /// File drop handler callback
  137. /// Return `true` in the callback to block the OS' default behavior of handling a file drop.
  138. pub(crate) type FileDropHandler<M> = Box<dyn Fn(FileDropEvent, DetachedWindow<M>) -> bool + Send>;
  139. #[derive(Deserialize)]
  140. pub(crate) struct InvokePayload {
  141. #[serde(rename = "__tauriModule")]
  142. pub(crate) tauri_module: Option<String>,
  143. pub(crate) callback: String,
  144. pub(crate) error: String,
  145. #[serde(flatten)]
  146. pub(crate) inner: JsonValue,
  147. }