Skip to content

Commit

Permalink
Merge branch 'dev' into webkitgtk-data_manager-directory
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir authored Sep 26, 2024
2 parents 4fbe694 + e332eff commit 1e10f4d
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 184 deletions.
5 changes: 5 additions & 0 deletions .changes/load-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": minor
---

Add `Webview::load_html`.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## \[0.44.1]

- [`5111eb0`](https://github.com/tauri-apps/wry/commit/5111eb013e1b049d12aad38b96b2017a4fc54c72) ([#1362](https://github.com/tauri-apps/wry/pull/1362) by [@lucasfernog](https://github.com/tauri-apps/wry/../../lucasfernog)) Fixes `WebView::clear_all_browsing_data` crashing with a segfault on macOS.

## \[0.44.0]

- [`b863d38`](https://github.com/tauri-apps/wry/commit/b863d38ff705e037b297c1651e17775d3dbe473c) ([#1356](https://github.com/tauri-apps/wry/pull/1356) by [@SpikeHD](https://github.com/tauri-apps/wry/../../SpikeHD)) Expose ability to enable browser extensions in WebView2
- [`9220793`](https://github.com/tauri-apps/wry/commit/92207933c9de4a0c1ef65ecbacb0c303619ced4c) ([#1361](https://github.com/tauri-apps/wry/pull/1361) by [@amrbashir](https://github.com/tauri-apps/wry/../../amrbashir)) Ignore duplicate custom protocols in `WebviewBuilder::with_custom_protocol` and `WebviewBuilder::with_async_custom_protocol` and use the last registered one.
- [`9220793`](https://github.com/tauri-apps/wry/commit/92207933c9de4a0c1ef65ecbacb0c303619ced4c) ([#1361](https://github.com/tauri-apps/wry/pull/1361) by [@amrbashir](https://github.com/tauri-apps/wry/../../amrbashir)) Removed `Error::DuplicateCustomProtocol` variant.
- [`5915341`](https://github.com/tauri-apps/wry/commit/59153413d87549964b885ad3ed84473acf4b70df) ([#1354](https://github.com/tauri-apps/wry/pull/1354) by [@millermk](https://github.com/tauri-apps/wry/../../millermk)) Fixes Android webview error page flashing when a redirect to the app is performed.
- [`170095b`](https://github.com/tauri-apps/wry/commit/170095b9a5829ac9279cfeea3fac0da2c922d448) ([#1360](https://github.com/tauri-apps/wry/pull/1360) by [@Steve-xmh](https://github.com/tauri-apps/wry/../../Steve-xmh)) Fix web resource loading in android binding by skip duplicate Content-Type/Content-Length headers.
- [`5915341`](https://github.com/tauri-apps/wry/commit/59153413d87549964b885ad3ed84473acf4b70df) ([#1354](https://github.com/tauri-apps/wry/pull/1354) by [@millermk](https://github.com/tauri-apps/wry/../../millermk)) Fix navigation error handling to trigger custom protocol on Android.

## \[0.43.1]

- [`5cea504`](https://github.com/tauri-apps/wry/commit/5cea5045c9e646ace1f94767d91b746c2afd3c14) ([#1352](https://github.com/tauri-apps/wry/pull/1352) by [@lucasfernog](https://github.com/tauri-apps/wry/../../lucasfernog)) Fixes Android file picker result processing.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ workspace = { }

[package]
name = "wry"
version = "0.43.1"
version = "0.44.1"
authors = [ "Tauri Programme within The Commons Conservancy" ]
edition = "2021"
license = "Apache-2.0 OR MIT"
Expand Down
7 changes: 6 additions & 1 deletion src/android/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT

use http::{
header::{HeaderName, HeaderValue, CONTENT_TYPE},
header::{HeaderName, HeaderValue, CONTENT_LENGTH, CONTENT_TYPE},
Request,
};
use jni::errors::Result as JniResult;
Expand Down Expand Up @@ -216,6 +216,11 @@ fn handle_request(
let response_headers = {
let headers_map = JMap::from_env(env, &obj)?;
for (name, value) in headers.iter() {
// WebResourceResponse will automatically generate Content-Type and
// Content-Length headers so we should skip them to avoid duplication.
if name == CONTENT_TYPE || name == CONTENT_LENGTH {
continue;
}
let key = env.new_string(name)?;
let value = env.new_string(value.to_str().unwrap_or_default())?;
headers_map.put(env, &key, &value)?;
Expand Down
36 changes: 26 additions & 10 deletions src/android/kotlin/RustWebViewClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ import android.net.Uri
import android.webkit.*
import android.content.Context
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import androidx.webkit.WebViewAssetLoader

class RustWebViewClient(context: Context): WebViewClient() {
private val interceptedState = mutableMapOf<String, Boolean>()
var currentUrl: String = "about:blank"
var lastInterceptedUrl: Uri? = null
private var lastInterceptedUrl: Uri? = null
private var pendingUrlRedirect: String? = null

private val assetLoader = WebViewAssetLoader.Builder()
.setDomain(assetLoaderDomain())
Expand All @@ -24,6 +27,14 @@ class RustWebViewClient(context: Context): WebViewClient() {
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
pendingUrlRedirect?.let {
Handler(Looper.getMainLooper()).post {
view.loadUrl(it)
}
pendingUrlRedirect = null
return null
}

lastInterceptedUrl = request.url
return if (withAssetLoader()) {
assetLoader.shouldInterceptRequest(request.url)
Expand Down Expand Up @@ -53,22 +64,27 @@ class RustWebViewClient(context: Context): WebViewClient() {
}

override fun onPageFinished(view: WebView, url: String) {
return onPageLoaded(url)
onPageLoaded(url)
}

override fun onReceivedError(
view: WebView,
request: WebResourceRequest,
error: WebResourceError
) {
// we get a net::ERR_CONNECTION_REFUSED when an external URL redirects to a custom protocol
// e.g. oauth flow, because shouldInterceptRequest is not called on redirects
// so we must force retry here with loadUrl() to get a chance of the custom protocol to kick in
if (error.errorCode == ERROR_CONNECT && request.url != lastInterceptedUrl) {
view.loadUrl(request.url.toString())
} else {
super.onReceivedError(view, request, error)
}
// we get a net::ERR_CONNECTION_REFUSED when an external URL redirects to a custom protocol
// e.g. oauth flow, because shouldInterceptRequest is not called on redirects
// so we must force retry here with loadUrl() to get a chance of the custom protocol to kick in
if (error.errorCode == ERROR_CONNECT && request.isForMainFrame && request.url != lastInterceptedUrl) {
// prevent the default error page from showing
view.stopLoading()
// without this initial loadUrl the app is stuck
view.loadUrl(request.url.toString())
// ensure the URL is actually loaded - for some reason there's a race condition and we need to call loadUrl() again later
pendingUrlRedirect = request.url.toString()
} else {
super.onReceivedError(view, request, error)
}
}

companion object {
Expand Down
7 changes: 7 additions & 0 deletions src/android/main_pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ impl<'a> MainPipe<'a> {
.call_method(webview, "clearAllBrowsingData", "()V", &[])?;
}
}
WebViewMessage::LoadHtml(html) => {
if let Some(webview) = &self.webview {
let html = self.env.new_string(html)?;
load_html(&mut self.env, webview.as_obj(), &html)?;
}
}
}
}
Ok(())
Expand Down Expand Up @@ -369,6 +375,7 @@ pub(crate) enum WebViewMessage {
GetUrl(Sender<String>),
Jni(Box<dyn FnOnce(&mut JNIEnv, &JObject, &JObject) + Send>),
LoadUrl(String, Option<http::HeaderMap>),
LoadHtml(String),
ClearAllBrowsingData,
}

Expand Down
5 changes: 5 additions & 0 deletions src/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ impl InnerWebView {
Ok(())
}

pub fn load_html(&self, html: &str) -> Result<()> {
MainPipe::send(WebViewMessage::LoadHtml(html.to_string()));
Ok(())
}

pub fn clear_all_browsing_data(&self) -> Result<()> {
MainPipe::send(WebViewMessage::ClearAllBrowsingData);
Ok(())
Expand Down
2 changes: 0 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ pub enum Error {
#[cfg(target_os = "windows")]
#[error("WebView2 error: {0}")]
WebView2Error(webview2_com::Error),
#[error("Duplicate custom protocol registered: {0}")]
DuplicateCustomProtocol(String),
#[error(transparent)]
HttpError(#[from] http::Error),
#[error("Infallible error, something went really wrong: {0}")]
Expand Down
42 changes: 33 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ use self::webview2::*;
#[cfg(target_os = "windows")]
use webview2_com::Microsoft::Web::WebView2::Win32::ICoreWebView2Controller;

use std::{borrow::Cow, path::PathBuf, rc::Rc};
use std::{borrow::Cow, collections::HashMap, path::PathBuf, rc::Rc};

use http::{Request, Response};

Expand Down Expand Up @@ -377,7 +377,7 @@ pub struct WebViewAttributes {
/// - Android: Android has `assets` and `resource` path finder to
/// locate your files in those directories. For more information, see [Loading in-app content](https://developer.android.com/guide/webapps/load-local-content) page.
/// - iOS: To get the path of your assets, you can call [`CFBundle::resources_path`](https://docs.rs/core-foundation/latest/core_foundation/bundle/struct.CFBundle.html#method.resources_path). So url like `wry://assets/index.html` could get the html file in assets directory.
pub custom_protocols: Vec<(String, Box<dyn Fn(Request<Vec<u8>>, RequestAsyncResponder)>)>,
pub custom_protocols: HashMap<String, Box<dyn Fn(Request<Vec<u8>>, RequestAsyncResponder)>>,

/// The IPC handler to receive the message from Javascript on webview
/// using `window.ipc.postMessage("insert_message_here")` to host Rust code.
Expand Down Expand Up @@ -515,8 +515,8 @@ impl Default for WebViewAttributes {
url: None,
headers: None,
html: None,
initialization_scripts: vec![],
custom_protocols: vec![],
initialization_scripts: Default::default(),
custom_protocols: Default::default(),
ipc_handler: None,
drag_drop_handler: None,
navigation_handler: None,
Expand Down Expand Up @@ -696,6 +696,8 @@ impl<'a> WebViewBuilder<'a> {
///
/// The closure takes a [Request] and returns a [Response]
///
/// When registering a custom protocol with the same name, only the last regisered one will be used.
///
/// # Warning
///
/// Pages loaded from custom protocol will have different Origin on different platforms. And
Expand All @@ -719,18 +721,20 @@ impl<'a> WebViewBuilder<'a> {
where
F: Fn(Request<Vec<u8>>) -> Response<Cow<'static, [u8]>> + 'static,
{
self.attrs.custom_protocols.push((
self.attrs.custom_protocols.insert(
name,
Box::new(move |request, responder| {
let http_response = handler(request);
responder.respond(http_response);
}),
));
);
self
}

/// Same as [`Self::with_custom_protocol`] but with an asynchronous responder.
///
/// When registering a custom protocol with the same name, only the last regisered one will be used.
///
/// # Examples
///
/// ```no_run
Expand Down Expand Up @@ -761,7 +765,7 @@ impl<'a> WebViewBuilder<'a> {
where
F: Fn(Request<Vec<u8>>, RequestAsyncResponder) + 'static,
{
self.attrs.custom_protocols.push((name, Box::new(handler)));
self.attrs.custom_protocols.insert(name, Box::new(handler));
self
}

Expand Down Expand Up @@ -1091,6 +1095,7 @@ pub(crate) struct PlatformSpecificWebViewAttributes {
theme: Option<Theme>,
use_https: bool,
scroll_bar_style: ScrollBarStyle,
browser_extensions_enabled: bool,
}

#[cfg(windows)]
Expand All @@ -1102,6 +1107,7 @@ impl Default for PlatformSpecificWebViewAttributes {
theme: None,
use_https: false, // To match macOS & Linux behavior in the context of mixed content.
scroll_bar_style: ScrollBarStyle::default(),
browser_extensions_enabled: false,
}
}
}
Expand Down Expand Up @@ -1153,6 +1159,14 @@ pub trait WebViewBuilderExtWindows {
/// Requires WebView2 Runtime version 125.0.2535.41 or higher, does nothing on older versions,
/// see https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/?tabs=dotnetcsharp#10253541
fn with_scroll_bar_style(self, style: ScrollBarStyle) -> Self;

/// Determines whether the ability to install and enable extensions is enabled.
///
/// By default, extensions are disabled.
///
/// Requires WebView2 Runtime version 1.0.2210.55 or higher, does nothing on older versions,
/// see https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/archive?tabs=dotnetcsharp#10221055
fn with_browser_extensions_enabled(self, enabled: bool) -> Self;
}

#[cfg(windows)]
Expand Down Expand Up @@ -1181,6 +1195,11 @@ impl WebViewBuilderExtWindows for WebViewBuilder<'_> {
self.platform_specific.scroll_bar_style = style;
self
}

fn with_browser_extensions_enabled(mut self, enabled: bool) -> Self {
self.platform_specific.browser_extensions_enabled = enabled;
self
}
}

#[cfg(target_os = "android")]
Expand Down Expand Up @@ -1237,12 +1256,12 @@ impl WebViewBuilderExtAndroid for WebViewBuilder<'_> {
// register custom protocol with empty Response return,
// this is necessary due to the need of fixing a domain
// in WebViewAssetLoader.
self.attrs.custom_protocols.push((
self.attrs.custom_protocols.insert(
protocol.clone(),
Box::new(|_, api| {
api.respond(Response::builder().body(Vec::new()).unwrap());
}),
));
);
self.platform_specific.with_asset_loader = true;
self.platform_specific.asset_loader_domain = Some(format!("{}.assets", protocol));
self
Expand Down Expand Up @@ -1458,6 +1477,11 @@ impl WebView {
self.webview.load_url_with_headers(url, headers)
}

/// Load html content into the webview
pub fn load_html(&self, html: &str) -> Result<()> {
self.webview.load_html(html)
}

/// Clear all browsing data
pub fn clear_all_browsing_data(&self) -> Result<()> {
self.webview.clear_all_browsing_data()
Expand Down
5 changes: 5 additions & 0 deletions src/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ impl InnerWebView {
Ok(())
}

pub fn load_html(&self, html: &str) -> Result<()> {
self.webview.load_html(html, None);
Ok(())
}

pub fn clear_all_browsing_data(&self) -> Result<()> {
if let Some(context) = self.webview.context() {
if let Some(data_manger) = context.website_data_manager() {
Expand Down
Loading

0 comments on commit 1e10f4d

Please sign in to comment.