Skip to content

Commit

Permalink
refactor: consistent with_html across platforms (#966)
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir authored Jun 8, 2023
1 parent c09dd7b commit 2b56bfa
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .changes/android-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": "patch"
---

Add support for `WebViewBuilder::with_html` and `WebViewAttributes.html` on Android.
5 changes: 5 additions & 0 deletions .changes/html-origin-null.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wry": "minor"
---

Set base url and origin to null for `WebViewBuilder::with_html` and `WebViewAttributes.html` for consistency on all platforms.
6 changes: 6 additions & 0 deletions src/webview/android/kotlin/RustWebView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ class RustWebView(context: Context): WebView(context) {
}
}

fun loadHTMLMainThread(html: String) {
post {
super.loadData(html, "text/html", null)
}
}

fun clearAllBrowsingData() {
try {
super.getContext().deleteDatabase("webviewCache.db")
Expand Down
1 change: 1 addition & 0 deletions src/webview/android/kotlin/proguard-wry.pro
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
public <init>(...);

void loadUrlMainThread(...);
void loadHTMLMainThread(...);
void setAutoPlay(...);
void setUserAgent(...);
}
Expand Down
26 changes: 22 additions & 4 deletions src/webview/android/main_pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl MainPipe<'_> {
WebViewMessage::CreateWebView(attrs) => {
let CreateWebViewAttributes {
url,
html,
#[cfg(any(debug_assertions, feature = "devtools"))]
devtools,
transparent,
Expand Down Expand Up @@ -90,9 +91,15 @@ impl MainPipe<'_> {
&[webview.into()],
)?;

// Load URL
if let Ok(url) = env.new_string(url) {
load_url(env, webview, url, headers, true)?;
// Navigation
if let Some(u) = url {
if let Ok(url) = env.new_string(u) {
load_url(env, webview, url, headers, true)?;
}
} else if let Some(h) = html {
if let Ok(html) = env.new_string(h) {
load_html(env, webview, html)?;
}
}

// Enable devtools
Expand Down Expand Up @@ -261,6 +268,16 @@ fn load_url<'a>(
Ok(())
}

fn load_html<'a>(env: JNIEnv<'a>, webview: JObject<'a>, html: JString<'a>) -> Result<(), JniError> {
env.call_method(
webview,
"loadHTMLMainThread",
"(Ljava/lang/String;)V",
&[html.into()],
)?;
Ok(())
}

fn set_background_color<'a>(
env: JNIEnv<'a>,
webview: JObject<'a>,
Expand Down Expand Up @@ -294,7 +311,8 @@ pub(crate) enum WebViewMessage {
}

pub(crate) struct CreateWebViewAttributes {
pub url: String,
pub url: Option<String>,
pub html: Option<String>,
#[cfg(any(debug_assertions, feature = "devtools"))]
pub devtools: bool,
pub transparent: bool,
Expand Down
34 changes: 20 additions & 14 deletions src/webview/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use super::{WebContext, WebViewAttributes, RGBA};
use crate::{application::window::Window, Result};
use base64::{engine::general_purpose, Engine};
use crossbeam_channel::*;
use html5ever::{interface::QualName, namespace_url, ns, tendril::TendrilSink, LocalName};
use http::{
Expand Down Expand Up @@ -173,6 +174,7 @@ impl InnerWebView {
) -> Result<Self> {
let WebViewAttributes {
url,
html,
initialization_scripts,
ipc_handler,
#[cfg(any(debug_assertions, feature = "devtools"))]
Expand All @@ -192,7 +194,7 @@ impl InnerWebView {
asset_loader_domain,
} = pl_attrs;

if let Some(u) = url {
let url = if let Some(u) = url {
let mut url_string = String::from(u.as_str());
let name = u.scheme();
let is_custom_protocol = custom_protocols.iter().any(|(n, _)| n == name);
Expand All @@ -201,19 +203,23 @@ impl InnerWebView {
.as_str()
.replace(&format!("{}://", name), &format!("https://{}.", name))
}
Some(url_string)
} else {
None
};

MainPipe::send(WebViewMessage::CreateWebView(CreateWebViewAttributes {
url: url_string,
#[cfg(any(debug_assertions, feature = "devtools"))]
devtools,
background_color,
transparent,
headers,
on_webview_created,
autoplay,
user_agent,
}));
}
MainPipe::send(WebViewMessage::CreateWebView(CreateWebViewAttributes {
url,
html,
#[cfg(any(debug_assertions, feature = "devtools"))]
devtools,
background_color,
transparent,
headers,
on_webview_created,
autoplay,
user_agent,
}));

WITH_ASSET_LOADER.get_or_init(move || with_asset_loader);
if let Some(domain) = asset_loader_domain {
Expand Down Expand Up @@ -386,7 +392,7 @@ fn hash_script(script: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(script);
let hash = hasher.finalize();
format!("'sha256-{}'", base64::encode(hash))
format!("'sha256-{}'", general_purpose::STANDARD.encode(hash))
}

/// Finds a class in the project scope.
Expand Down
24 changes: 6 additions & 18 deletions src/webview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,12 @@ pub struct WebViewAttributes {
/// This will be ignored if the `url` is provided.
///
/// # Warning
/// The loaded from html string will have different Origin on different platforms. And
/// servers which enforce CORS will need to add exact same Origin header in `Access-Control-Allow-Origin`
/// if you wish to send requests with native `fetch` and `XmlHttpRequest` APIs. Here are the
/// different Origin headers across platforms:
///
/// - macOS: `http://localhost`
/// - Linux: `http://localhost`
/// - Windows: `null`
/// - Android: Not supported
/// - iOS: Not supported
/// The Page loaded from html string will have `null` origin.
///
/// ## PLatform-specific:
///
/// - **Windows:** the string can not be larger than 2 MB (2 * 1024 * 1024 bytes) in total size
pub html: Option<String>,
/// Initialize javascript code when loading new pages. When webview load a new page, this
/// initialization code will be executed. It is guaranteed that code is executed before
Expand Down Expand Up @@ -488,16 +484,8 @@ impl<'a> WebViewBuilder<'a> {
/// [`WebView`]. This will be ignored if `url` is provided.
///
/// # Warning
/// The Page loaded from html string will have different Origin on different platforms. And
/// servers which enforce CORS will need to add exact same Origin header in `Access-Control-Allow-Origin`
/// if you wish to send requests with native `fetch` and `XmlHttpRequest` APIs. Here are the
/// different Origin headers across platforms:
///
/// - macOS: `http://localhost`
/// - Linux: `http://localhost`
/// - Windows: `null`
/// - Android: Not supported
/// - iOS: Not supported
/// The Page loaded from html string will have `null` origin.
///
/// ## PLatform-specific:
///
Expand Down
2 changes: 1 addition & 1 deletion src/webview/webkitgtk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl InnerWebView {
web_context.queue_load_uri(Rc::clone(&w.webview), url, attributes.headers);
web_context.flush_queue_loader();
} else if let Some(html) = attributes.html {
w.webview.load_html(&html, Some("http://localhost"));
w.webview.load_html(&html, None);
}

let pending_scripts = w.pending_scripts.clone();
Expand Down
3 changes: 1 addition & 2 deletions src/webview/wkwebview/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,8 +953,7 @@ r#"Object.defineProperty(window, 'ipc', {
fn navigate_to_string(&self, html: &str) {
// Safety: objc runtime calls are unsafe
unsafe {
let url: id = msg_send![class!(NSURL), URLWithString: NSString::new("http://localhost")];
let () = msg_send![self.webview, loadHTMLString:NSString::new(html) baseURL:url];
let () = msg_send![self.webview, loadHTMLString:NSString::new(html) baseURL:nil];
}
}

Expand Down

0 comments on commit 2b56bfa

Please sign in to comment.