Skip to content

Commit

Permalink
Expose wry navigation_handler via WindowBuilder closes #4080 (#5686)
Browse files Browse the repository at this point in the history
Co-authored-by: silvanshade <silvanshade@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
  • Loading branch information
3 people authored Dec 27, 2022
1 parent 146a794 commit 3f35b45
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changes/core-navigation-handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri": minor
---

Added `Window::on_navigation`.
5 changes: 5 additions & 0 deletions .changes/runtime-navigation-handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-runtime": minor
---

Added `navigation_handler` field on `PendingWindow`.
5 changes: 5 additions & 0 deletions .changes/wry-navigation-handler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-runtime-wry": minor
---

Implement the webview navigation handler.
5 changes: 5 additions & 0 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3061,6 +3061,11 @@ fn create_webview<T: UserEvent>(
webview_builder = webview_builder
.with_file_drop_handler(create_file_drop_handler(window_event_listeners.clone()));
}
if let Some(navigation_handler) = pending.navigation_handler {
webview_builder = webview_builder.with_navigation_handler(move |url| {
Url::parse(&url).map(&navigation_handler).unwrap_or(true)
});
}
if let Some(user_agent) = webview_attributes.user_agent {
webview_builder = webview_builder.with_user_agent(&user_agent);
}
Expand Down
6 changes: 6 additions & 0 deletions core/tauri-runtime/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
};
use serde::{Deserialize, Deserializer, Serialize};
use tauri_utils::{config::WindowConfig, Theme};
use url::Url;

use std::{
collections::{HashMap, HashSet},
Expand Down Expand Up @@ -232,6 +233,9 @@ pub struct PendingWindow<T: UserEvent, R: Runtime<T>> {

/// A HashMap mapping JS event names with associated listener ids.
pub js_event_listeners: Arc<Mutex<HashMap<JsEventListenerKey, HashSet<u64>>>>,

/// A handler to decide if incoming url is allowed to navigate.
pub navigation_handler: Option<Box<dyn Fn(Url) -> bool + Send>>,
}

pub fn is_label_valid(label: &str) -> bool {
Expand Down Expand Up @@ -271,6 +275,7 @@ impl<T: UserEvent, R: Runtime<T>> PendingWindow<T, R> {
url: "tauri://localhost".to_string(),
menu_ids: Arc::new(Mutex::new(menu_ids)),
js_event_listeners: Default::default(),
navigation_handler: Default::default(),
})
}
}
Expand Down Expand Up @@ -300,6 +305,7 @@ impl<T: UserEvent, R: Runtime<T>> PendingWindow<T, R> {
url: "tauri://localhost".to_string(),
menu_ids: Arc::new(Mutex::new(menu_ids)),
js_event_listeners: Default::default(),
navigation_handler: Default::default(),
})
}
}
Expand Down
33 changes: 32 additions & 1 deletion core/tauri/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ use std::{
};

pub(crate) type WebResourceRequestHandler = dyn Fn(&HttpRequest, &mut HttpResponse) + Send + Sync;
pub(crate) type NavigationHandler = dyn Fn(Url) -> bool + Send;

#[derive(Clone, Serialize)]
struct WindowCreatedEvent {
Expand Down Expand Up @@ -109,6 +110,7 @@ pub struct WindowBuilder<'a, R: Runtime> {
pub(crate) window_builder: <R::Dispatcher as Dispatch<EventLoopMessage>>::WindowBuilder,
pub(crate) webview_attributes: WebviewAttributes,
web_resource_request_handler: Option<Box<WebResourceRequestHandler>>,
navigation_handler: Option<Box<NavigationHandler>>,
}

impl<'a, R: Runtime> fmt::Debug for WindowBuilder<'a, R> {
Expand Down Expand Up @@ -182,6 +184,7 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
window_builder: <R::Dispatcher as Dispatch<EventLoopMessage>>::WindowBuilder::new(),
webview_attributes: WebviewAttributes::new(url),
web_resource_request_handler: None,
navigation_handler: None,
}
}

Expand Down Expand Up @@ -230,6 +233,33 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
self
}

/// Defines a closure to be executed when the webview navigates to a URL. Returning `false` cancels the navigation.
///
/// # Examples
///
/// ```rust,no_run
/// use tauri::{
/// utils::config::{Csp, CspDirectiveSources, WindowUrl},
/// http::header::HeaderValue,
/// window::WindowBuilder,
/// };
/// use std::collections::HashMap;
/// tauri::Builder::default()
/// .setup(|app| {
/// WindowBuilder::new(app, "core", WindowUrl::App("index.html".into()))
/// .on_navigation(|url| {
/// // allow the production URL or localhost on dev
/// url.scheme() == "tauri" || (cfg!(dev) && url.host_str() == Some("localhost"))
/// })
/// .build()?;
/// Ok(())
/// });
/// ```
pub fn on_navigation<F: Fn(Url) -> bool + Send + 'static>(mut self, f: F) -> Self {
self.navigation_handler.replace(Box::new(f));
self
}

/// Creates a new webview window.
pub fn build(mut self) -> crate::Result<Window<R>> {
let web_resource_request_handler = self.web_resource_request_handler.take();
Expand All @@ -239,12 +269,13 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> {
self.label.clone(),
)?;
let labels = self.manager.labels().into_iter().collect::<Vec<_>>();
let pending = self.manager.prepare_window(
let mut pending = self.manager.prepare_window(
self.app_handle.clone(),
pending,
&labels,
web_resource_request_handler,
)?;
pending.navigation_handler = self.navigation_handler.take();
let window = match &mut self.runtime {
RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending),
RuntimeOrDispatch::RuntimeHandle(handle) => handle.create_window(pending),
Expand Down
84 changes: 60 additions & 24 deletions examples/api/src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tooling/cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 3f35b45

Please sign in to comment.