2023-05-04 16:04:06 +00:00
|
|
|
use dioxus::prelude::*;
|
|
|
|
use dioxus_desktop::DesktopContext;
|
|
|
|
|
|
|
|
pub(crate) fn check_app_exits(app: Component) {
|
2023-05-05 16:11:50 +00:00
|
|
|
use dioxus_desktop::Config;
|
2024-01-05 00:48:53 +00:00
|
|
|
use tao::window::WindowBuilder;
|
2023-05-04 16:04:06 +00:00
|
|
|
// This is a deadman's switch to ensure that the app exits
|
|
|
|
let should_panic = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(true));
|
|
|
|
let should_panic_clone = should_panic.clone();
|
|
|
|
std::thread::spawn(move || {
|
|
|
|
std::thread::sleep(std::time::Duration::from_secs(100));
|
|
|
|
if should_panic_clone.load(std::sync::atomic::Ordering::SeqCst) {
|
|
|
|
std::process::exit(exitcode::SOFTWARE);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-05-05 16:11:50 +00:00
|
|
|
dioxus_desktop::launch_cfg(
|
|
|
|
app,
|
2023-12-17 17:30:17 +00:00
|
|
|
Config::new().with_window(WindowBuilder::new().with_visible(true)),
|
2023-05-05 16:11:50 +00:00
|
|
|
);
|
2023-05-04 16:04:06 +00:00
|
|
|
|
|
|
|
should_panic.store(false, std::sync::atomic::Ordering::SeqCst);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
check_app_exits(check_html_renders);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn use_inner_html(cx: &ScopeState, id: &'static str) -> Option<String> {
|
2023-07-21 22:36:25 +00:00
|
|
|
let eval_provider = use_eval(cx);
|
|
|
|
|
2023-05-04 16:04:06 +00:00
|
|
|
let value: &UseRef<Option<String>> = use_ref(cx, || None);
|
|
|
|
use_effect(cx, (), |_| {
|
2023-07-21 22:36:25 +00:00
|
|
|
to_owned![value, eval_provider];
|
2023-05-04 16:04:06 +00:00
|
|
|
async move {
|
|
|
|
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
2023-07-21 22:36:25 +00:00
|
|
|
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 {
|
2023-05-04 16:04:06 +00:00
|
|
|
println!("html: {}", html);
|
|
|
|
value.set(Some(html));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
value.read().clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
const EXPECTED_HTML: &str = r#"<div id="5" style="width: 100px; height: 100px; color: rgb(0, 0, 0);"><input type="checkbox"><h1>text</h1><div><p>hello world</p></div></div>"#;
|
|
|
|
|
|
|
|
fn check_html_renders(cx: Scope) -> Element {
|
|
|
|
let inner_html = use_inner_html(cx, "main_div");
|
2023-07-21 22:36:25 +00:00
|
|
|
|
2023-05-04 16:04:06 +00:00
|
|
|
let desktop_context: DesktopContext = cx.consume_context().unwrap();
|
|
|
|
|
2023-07-21 22:36:25 +00:00
|
|
|
if let Some(raw_html) = inner_html {
|
|
|
|
println!("{}", raw_html);
|
|
|
|
let fragment = scraper::Html::parse_fragment(&raw_html);
|
|
|
|
println!("fragment: {}", fragment.html());
|
2023-05-04 16:04:06 +00:00
|
|
|
let expected = scraper::Html::parse_fragment(EXPECTED_HTML);
|
2023-07-21 22:36:25 +00:00
|
|
|
println!("expected: {}", expected.html());
|
2023-05-04 16:04:06 +00:00
|
|
|
if fragment == expected {
|
|
|
|
println!("html matches");
|
|
|
|
desktop_context.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let dyn_value = 0;
|
|
|
|
let dyn_element = rsx! {
|
|
|
|
div {
|
|
|
|
dangerous_inner_html: "<p>hello world</p>",
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
render! {
|
|
|
|
div {
|
|
|
|
id: "main_div",
|
|
|
|
div {
|
|
|
|
width: "100px",
|
|
|
|
height: "100px",
|
|
|
|
color: "rgb({dyn_value}, {dyn_value}, {dyn_value})",
|
|
|
|
id: 5,
|
|
|
|
input {
|
|
|
|
"type": "checkbox",
|
|
|
|
},
|
|
|
|
h1 {
|
|
|
|
"text"
|
|
|
|
}
|
|
|
|
dyn_element
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|