Convert use_eval to use send/recv system (#1080)

* progress: reworked

don't run this, it'll kill your web browser

* feat: use_eval but with comms

* revision: async recv & recv_sync

* revision: use_eval

* revision: standard eval interface

* revision: use serde_json::Value instead of JsValue

* revision: docs

* revision: error message

* create: desktop eval (wip)

* fix: desktop eval

* revision: wrap use_eval in Rc<RefCell<_>>

* fix: fmt, clippy

* fix: desktop tests

* revision: change to channel system

- fixes clippy errors
- fixes playwright tests

* fix: tests

* fix: eval example

* fix: fmt

* fix: tests, desktop stuff

* fix: tests

* feat: drop handler

* fix: tests

* fix: rustfmt

* revision: web promise/callback system

* fix: recv error

* revision: IntoFuture, functionation

* fix: ci

* revision: playwright web

* remove: unescessary code

* remove dioxus-html from public examples

* prototype-patch

* fix web eval

* fix: rustfmt

* fix: CI

* make use_eval more efficient

* implement eval for liveview as well

* fix playwright tests

* fix clippy

* more clippy fixes

* fix clippy

* fix stack overflow

* fix desktop mock

* fix clippy

---------

Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
Miles MurgawandEvan Almloff authored and GitHub committed 2023-07-21 17:36:25 -05:00
1 parent b36a7a3993
commit 6210c6fefe
31 files changed
+1025 -410

No files matched your search

+103 -100
View File
@@ -29,21 +29,24 @@ pub fn main() {
}
fn mock_event(cx: &ScopeState, id: &'static str, value: &'static str) {
use_effect(cx, (), |_| {
let desktop_context: DesktopContext = cx.consume_context().unwrap();
async move {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
desktop_context.eval(&format!(
r#"let element = document.getElementById('{}');
let eval_provider = use_eval(cx).clone();
use_effect(cx, (), move |_| async move {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
let js = format!(
r#"
//console.log("ran");
// Dispatch a synthetic event
const event = {};
let event = {};
let element = document.getElementById('{}');
console.log(element, event);
element.dispatchEvent(event);
"#,
id, value
));
}
});
value, id
);
eval_provider(&js).unwrap();
})
}
#[allow(deprecated)]
@@ -56,149 +59,149 @@ fn app(cx: Scope) -> Element {
cx,
"button",
r#"new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true,
button: 0,
})"#,
view: window,
bubbles: true,
cancelable: true,
button: 0,
})"#,
);
// mouse_move_div
mock_event(
cx,
"mouse_move_div",
r#"new MouseEvent("mousemove", {
view: window,
bubbles: true,
cancelable: true,
buttons: 2,
})"#,
view: window,
bubbles: true,
cancelable: true,
buttons: 2,
})"#,
);
// mouse_click_div
mock_event(
cx,
"mouse_click_div",
r#"new MouseEvent("click", {
view: window,
bubbles: true,
cancelable: true,
buttons: 2,
button: 2,
})"#,
view: window,
bubbles: true,
cancelable: true,
buttons: 2,
button: 2,
})"#,
);
// mouse_dblclick_div
mock_event(
cx,
"mouse_dblclick_div",
r#"new MouseEvent("dblclick", {
view: window,
bubbles: true,
cancelable: true,
buttons: 1|2,
button: 2,
})"#,
view: window,
bubbles: true,
cancelable: true,
buttons: 1|2,
button: 2,
})"#,
);
// mouse_down_div
mock_event(
cx,
"mouse_down_div",
r#"new MouseEvent("mousedown", {
view: window,
bubbles: true,
cancelable: true,
buttons: 2,
button: 2,
})"#,
view: window,
bubbles: true,
cancelable: true,
buttons: 2,
button: 2,
})"#,
);
// mouse_up_div
mock_event(
cx,
"mouse_up_div",
r#"new MouseEvent("mouseup", {
view: window,
bubbles: true,
cancelable: true,
buttons: 0,
button: 0,
})"#,
view: window,
bubbles: true,
cancelable: true,
buttons: 0,
button: 0,
})"#,
);
// wheel_div
mock_event(
cx,
"wheel_div",
r#"new WheelEvent("wheel", {
view: window,
deltaX: 1.0,
deltaY: 2.0,
deltaZ: 3.0,
deltaMode: 0x00,
bubbles: true,
})"#,
view: window,
deltaX: 1.0,
deltaY: 2.0,
deltaZ: 3.0,
deltaMode: 0x00,
bubbles: true,
})"#,
);
// key_down_div
mock_event(
cx,
"key_down_div",
r#"new KeyboardEvent("keydown", {
key: "a",
code: "KeyA",
location: 0,
repeat: true,
keyCode: 65,
charCode: 97,
char: "a",
charCode: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
isComposing: false,
which: 65,
bubbles: true,
})"#,
key: "a",
code: "KeyA",
location: 0,
repeat: true,
keyCode: 65,
charCode: 97,
char: "a",
charCode: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
isComposing: false,
which: 65,
bubbles: true,
})"#,
);
// key_up_div
mock_event(
cx,
"key_up_div",
r#"new KeyboardEvent("keyup", {
key: "a",
code: "KeyA",
location: 0,
repeat: false,
keyCode: 65,
charCode: 97,
char: "a",
charCode: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
isComposing: false,
which: 65,
bubbles: true,
})"#,
key: "a",
code: "KeyA",
location: 0,
repeat: false,
keyCode: 65,
charCode: 97,
char: "a",
charCode: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
isComposing: false,
which: 65,
bubbles: true,
})"#,
);
// key_press_div
mock_event(
cx,
"key_press_div",
r#"new KeyboardEvent("keypress", {
key: "a",
code: "KeyA",
location: 0,
repeat: false,
keyCode: 65,
charCode: 97,
char: "a",
charCode: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
isComposing: false,
which: 65,
bubbles: true,
})"#,
key: "a",
code: "KeyA",
location: 0,
repeat: false,
keyCode: 65,
charCode: 97,
char: "a",
charCode: 0,
altKey: false,
ctrlKey: false,
metaKey: false,
shiftKey: false,
isComposing: false,
which: 65,
bubbles: true,
})"#,
);
// focus_in_div
mock_event(
+16 -14
View File
@@ -27,20 +27,20 @@ fn main() {
}
fn use_inner_html(cx: &ScopeState, id: &'static str) -> Option<String> {
let eval_provider = use_eval(cx);
let value: &UseRef<Option<String>> = use_ref(cx, || None);
use_effect(cx, (), |_| {
to_owned![value];
let desktop_context: DesktopContext = cx.consume_context().unwrap();
to_owned![value, eval_provider];
async move {
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
let html = desktop_context
.eval(&format!(
r#"let element = document.getElementById('{}');
return element.innerHTML;"#,
id
))
.await;
if let Ok(serde_json::Value::String(html)) = html {
let html = eval_provider(&format!(
r#"let element = document.getElementById('{}');
return element.innerHTML"#,
id
))
.unwrap();
if let Ok(serde_json::Value::String(html)) = html.await {
println!("html: {}", html);
value.set(Some(html));
}
@@ -53,13 +53,15 @@ const EXPECTED_HTML: &str = r#"<div id="5" style="width: 100px; height: 100px; c
fn check_html_renders(cx: Scope) -> Element {
let inner_html = use_inner_html(cx, "main_div");
let desktop_context: DesktopContext = cx.consume_context().unwrap();
if let Some(raw_html) = inner_html.as_deref() {
let fragment = scraper::Html::parse_fragment(raw_html);
println!("fragment: {:?}", fragment.html());
if let Some(raw_html) = inner_html {
println!("{}", raw_html);
let fragment = scraper::Html::parse_fragment(&raw_html);
println!("fragment: {}", fragment.html());
let expected = scraper::Html::parse_fragment(EXPECTED_HTML);
println!("fragment: {:?}", expected.html());
println!("expected: {}", expected.html());
if fragment == expected {
println!("html matches");
desktop_context.close();