Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions packages/desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ async-trait = "0.1.68"
tao = { workspace = true, features = ["rwh_05"] }
once_cell = { workspace = true }
dioxus-history.workspace = true
base64.workspace = true


[target.'cfg(unix)'.dependencies]
Expand Down
27 changes: 27 additions & 0 deletions packages/desktop/headless_tests/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ fn app() -> Element {
test_form_input {}
test_form_submit {}
test_select_multiple_options {}
test_unicode {}
}
}
}
Expand Down Expand Up @@ -576,3 +577,29 @@ fn test_select_multiple_options() -> Element {
}
}
}

fn test_unicode() -> Element {
// emulate an oninput event with a unicode character
utils::mock_event_with_extra(
"unicode",
r#"new InputEvent("input", {
inputType: 'insertText',
bubbles: true,
cancelable: true,
})"#,
r#"
element.value = "🦀";
"#,
);

rsx! {
input {
id: "unicode",
oninput: move |event| {
println!("{:?}", event.data);
assert_eq!(event.data.value(), "🦀");
RECEIVED_EVENTS.with_mut(|x| *x += 1);
}
}
}
}
39 changes: 25 additions & 14 deletions packages/desktop/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
waker::tao_waker,
Config, DesktopContext, DesktopService,
};
use base64::prelude::BASE64_STANDARD;
use dioxus_core::{Runtime, ScopeId, VirtualDom};
use dioxus_document::Document;
use dioxus_history::{History, MemoryHistory};
Expand Down Expand Up @@ -48,21 +49,37 @@ impl WebviewEdits {
request: wry::http::Request<Vec<u8>>,
responder: wry::RequestAsyncResponder,
) {
let body = self.try_handle_event(request).unwrap_or_default();
let body = self
.try_handle_event(request)
.expect("Writing bodies to succeed");
responder.respond(wry::http::Response::new(body))
}

pub fn try_handle_event(
&self,
request: wry::http::Request<Vec<u8>>,
) -> Result<Vec<u8>, serde_json::Error> {
let data_from_header = request
use serde::de::Error;

// todo(jon):
//
// I'm a small bit worried about the size of the header being too big on some platforms.
// It's unlikely we'll hit the 256k limit (from 2010 browsers...) but it's important to think about
// https://stackoverflow.com/questions/3326210/can-http-headers-be-too-big-for-browsers
//
// Also important to remember here that we don't pass a body from the JavaScript side of things
let data = request
.headers()
.get("dioxus-data")
.map(|f| f.as_bytes())
.expect("dioxus-data header is not a string");
.ok_or_else(|| Error::custom("dioxus-data header not set"))?;

let as_utf = std::str::from_utf8(data.as_bytes())
.map_err(|_| Error::custom("dioxus-data header is not a valid (utf-8) string"))?;

let data_from_header = base64::Engine::decode(&BASE64_STANDARD, as_utf)
.map_err(|_| Error::custom("dioxus-data header is not a base64 string"))?;

let response = match serde_json::from_slice(data_from_header) {
let response = match serde_json::from_slice(&data_from_header) {
Ok(event) => {
// we need to wait for the mutex lock to let us munge the main thread..
let _lock = crate::android_sync_lock::android_runtime_lock();
Expand All @@ -79,15 +96,9 @@ impl WebviewEdits {
}
};

let body = match serde_json::to_vec(&response) {
Ok(body) => body,
Err(err) => {
tracing::error!("failed to serialize SynchronousEventResponse: {err:?}");
return Err(err);
}
};

Ok(body)
serde_json::to_vec(&response).inspect_err(|err| {
tracing::error!("failed to serialize SynchronousEventResponse: {err:?}");
})
}

pub fn handle_html_event(&self, event: HtmlEvent) -> SynchronousEventResponse {
Expand Down
2 changes: 1 addition & 1 deletion packages/interpreter/src/js/hash.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[6449103750905854967, 17669692872757955279, 13069001215487072322, 11420464406527728232, 3770103091118609057, 5444526391971481782, 12156139214887111728, 5052021921702764563, 12925655762638175824, 5638004933879392817]
[6449103750905854967, 17669692872757955279, 13069001215487072322, 11420464406527728232, 3770103091118609057, 5444526391971481782, 10130882040196587188, 5052021921702764563, 12925655762638175824, 5638004933879392817]
2 changes: 1 addition & 1 deletion packages/interpreter/src/js/native.js

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions packages/interpreter/src/ts/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,10 @@ function handleVirtualdomEventSync(
// https://developer.android.com/reference/android/webkit/WebViewClient#shouldInterceptRequest(android.webkit.WebView,%20android.webkit.WebResourceRequest)
//
// the issue here isn't that big, tbh, but there's a small chance we lose the event due to header max size (16k per header, 32k max)
xhr.setRequestHeader("dioxus-data", contents);
xhr.send(contents);
const contents_bytes = new TextEncoder().encode(contents);
const contents_base64 = btoa(String.fromCharCode.apply(null, contents_bytes));
xhr.setRequestHeader("dioxus-data", contents_base64)
xhr.send();

// Deserialize the response, and then prevent the default/capture the event if the virtualdom wants to
return JSON.parse(xhr.responseText);
Expand Down
Loading