mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-03 10:11:15 +02:00
Co-authored-by: Lucas Nogueira <lucas@tauri.studio> closes #7330
This commit is contained in:
5
.changes/plugin-custom-protocol.md
Normal file
5
.changes/plugin-custom-protocol.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'tauri': 'minor:feat'
|
||||
---
|
||||
|
||||
Add `tauri::plugin::Builder::register_uri_scheme_protocol`
|
||||
@@ -1462,6 +1462,15 @@ impl<R: Runtime> Builder<R> {
|
||||
///
|
||||
/// * `uri_scheme` The URI scheme to register, such as `example`.
|
||||
/// * `protocol` the protocol associated with the given URI scheme. It's a function that takes an URL such as `example://localhost/asset.css`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// tauri::Builder::default()
|
||||
/// .register_uri_scheme_protocol("myscheme", |app, req| {
|
||||
/// tauri::http::ResponseBuilder::new().body(Vec::new())
|
||||
/// });
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn register_uri_scheme_protocol<
|
||||
N: Into<String>,
|
||||
|
||||
@@ -219,7 +219,7 @@ pub struct InnerWindowManager<R: Runtime> {
|
||||
|
||||
package_info: PackageInfo,
|
||||
/// The webview protocols available to all windows.
|
||||
uri_scheme_protocols: HashMap<String, Arc<CustomProtocol<R>>>,
|
||||
uri_scheme_protocols: Mutex<HashMap<String, Arc<CustomProtocol<R>>>>,
|
||||
/// The menu set to all windows.
|
||||
menu: Option<Menu>,
|
||||
/// Menu event listeners to all windows.
|
||||
@@ -321,7 +321,7 @@ impl<R: Runtime> WindowManager<R> {
|
||||
tray_icon: context.system_tray_icon,
|
||||
package_info: context.package_info,
|
||||
pattern: context.pattern,
|
||||
uri_scheme_protocols,
|
||||
uri_scheme_protocols: Mutex::new(uri_scheme_protocols),
|
||||
menu,
|
||||
menu_event_listeners: Arc::new(menu_event_listeners),
|
||||
window_event_listeners: Arc::new(window_event_listeners),
|
||||
@@ -350,6 +350,20 @@ impl<R: Runtime> WindowManager<R> {
|
||||
self.inner.invoke_responder.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn register_uri_scheme_protocol<N: Into<String>>(
|
||||
&self,
|
||||
uri_scheme: N,
|
||||
protocol: Arc<CustomProtocol<R>>,
|
||||
) {
|
||||
let uri_scheme = uri_scheme.into();
|
||||
self
|
||||
.inner
|
||||
.uri_scheme_protocols
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(uri_scheme, protocol);
|
||||
}
|
||||
|
||||
/// Get the base path to serve data from.
|
||||
///
|
||||
/// * In dev mode, this will be based on the `devPath` configuration value.
|
||||
@@ -461,7 +475,7 @@ impl<R: Runtime> WindowManager<R> {
|
||||
|
||||
let mut registered_scheme_protocols = Vec::new();
|
||||
|
||||
for (uri_scheme, protocol) in &self.inner.uri_scheme_protocols {
|
||||
for (uri_scheme, protocol) in &*self.inner.uri_scheme_protocols.lock().unwrap() {
|
||||
registered_scheme_protocols.push(uri_scheme.clone());
|
||||
let protocol = protocol.clone();
|
||||
let app_handle = Mutex::new(app_handle.clone());
|
||||
|
||||
@@ -5,14 +5,16 @@
|
||||
//! The Tauri plugin extension to expand Tauri functionality.
|
||||
|
||||
use crate::{
|
||||
utils::config::PluginConfig, AppHandle, Invoke, InvokeHandler, PageLoadPayload, RunEvent,
|
||||
Runtime, Window,
|
||||
http::{Request as HttpRequest, Response as HttpResponse},
|
||||
manager::CustomProtocol,
|
||||
utils::config::PluginConfig,
|
||||
AppHandle, Invoke, InvokeHandler, PageLoadPayload, RunEvent, Runtime, Window,
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde_json::Value as JsonValue;
|
||||
use tauri_macros::default_runtime;
|
||||
|
||||
use std::{collections::HashMap, fmt};
|
||||
use std::{collections::HashMap, fmt, sync::Arc};
|
||||
|
||||
/// The result type of Tauri plugin module.
|
||||
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
@@ -146,6 +148,7 @@ pub struct Builder<R: Runtime, C: DeserializeOwned = ()> {
|
||||
on_webview_ready: Box<OnWebviewReady<R>>,
|
||||
on_event: Box<OnEvent<R>>,
|
||||
on_drop: Option<Box<OnDrop<R>>>,
|
||||
uri_scheme_protocols: HashMap<String, Arc<CustomProtocol<R>>>,
|
||||
}
|
||||
|
||||
impl<R: Runtime, C: DeserializeOwned> Builder<R, C> {
|
||||
@@ -161,6 +164,7 @@ impl<R: Runtime, C: DeserializeOwned> Builder<R, C> {
|
||||
on_webview_ready: Box::new(|_| ()),
|
||||
on_event: Box::new(|_, _| ()),
|
||||
on_drop: None,
|
||||
uri_scheme_protocols: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,6 +415,57 @@ impl<R: Runtime, C: DeserializeOwned> Builder<R, C> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Registers a URI scheme protocol available to all webviews.
|
||||
/// Leverages [setURLSchemeHandler](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/2875766-seturlschemehandler) on macOS,
|
||||
/// [AddWebResourceRequestedFilter](https://docs.microsoft.com/en-us/dotnet/api/microsoft.web.webview2.core.corewebview2.addwebresourcerequestedfilter?view=webview2-dotnet-1.0.774.44) on Windows
|
||||
/// and [webkit-web-context-register-uri-scheme](https://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebContext.html#webkit-web-context-register-uri-scheme) on Linux.
|
||||
///
|
||||
/// # Known limitations
|
||||
///
|
||||
/// URI scheme protocols are registered when the webview is created. Due to this limitation, if the plugin is registed after a webview has been created, this protocol won't be available.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `uri_scheme` The URI scheme to register, such as `example`.
|
||||
/// * `protocol` the protocol associated with the given URI scheme. It's a function that takes an URL such as `example://localhost/asset.css`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// use tauri::{plugin::{Builder, TauriPlugin}, Runtime};
|
||||
///
|
||||
/// fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
/// Builder::new("myplugin")
|
||||
/// .register_uri_scheme_protocol("myscheme", |app, req| {
|
||||
/// tauri::http::ResponseBuilder::new().body(Vec::new())
|
||||
/// })
|
||||
/// .build()
|
||||
/// }
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn register_uri_scheme_protocol<
|
||||
N: Into<String>,
|
||||
H: Fn(
|
||||
&AppHandle<R>,
|
||||
&HttpRequest,
|
||||
) -> std::result::Result<HttpResponse, Box<dyn std::error::Error>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>(
|
||||
mut self,
|
||||
uri_scheme: N,
|
||||
protocol: H,
|
||||
) -> Self {
|
||||
self.uri_scheme_protocols.insert(
|
||||
uri_scheme.into(),
|
||||
Arc::new(CustomProtocol {
|
||||
protocol: Box::new(protocol),
|
||||
}),
|
||||
);
|
||||
self
|
||||
}
|
||||
|
||||
/// Builds the [TauriPlugin].
|
||||
pub fn build(self) -> TauriPlugin<R, C> {
|
||||
TauriPlugin {
|
||||
@@ -424,6 +479,7 @@ impl<R: Runtime, C: DeserializeOwned> Builder<R, C> {
|
||||
on_webview_ready: self.on_webview_ready,
|
||||
on_event: self.on_event,
|
||||
on_drop: self.on_drop,
|
||||
uri_scheme_protocols: self.uri_scheme_protocols,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -440,6 +496,7 @@ pub struct TauriPlugin<R: Runtime, C: DeserializeOwned = ()> {
|
||||
on_webview_ready: Box<OnWebviewReady<R>>,
|
||||
on_event: Box<OnEvent<R>>,
|
||||
on_drop: Option<Box<OnDrop<R>>>,
|
||||
uri_scheme_protocols: HashMap<String, Arc<CustomProtocol<R>>>,
|
||||
}
|
||||
|
||||
impl<R: Runtime, C: DeserializeOwned> Drop for TauriPlugin<R, C> {
|
||||
@@ -463,6 +520,11 @@ impl<R: Runtime, C: DeserializeOwned> Plugin<R> for TauriPlugin<R, C> {
|
||||
if let Some(s) = self.setup_with_config.take() {
|
||||
(s)(app, serde_json::from_value(config)?)?;
|
||||
}
|
||||
for (uri_scheme, protocol) in &self.uri_scheme_protocols {
|
||||
app
|
||||
.manager
|
||||
.register_uri_scheme_protocol(uri_scheme, protocol.clone())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user