rendering.rs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. use dioxus::prelude::*;
  2. use dioxus_desktop::DesktopContext;
  3. pub(crate) fn check_app_exits(app: Component) {
  4. use dioxus_desktop::Config;
  5. use tao::window::WindowBuilder;
  6. // This is a deadman's switch to ensure that the app exits
  7. let should_panic = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(true));
  8. let should_panic_clone = should_panic.clone();
  9. std::thread::spawn(move || {
  10. std::thread::sleep(std::time::Duration::from_secs(100));
  11. if should_panic_clone.load(std::sync::atomic::Ordering::SeqCst) {
  12. std::process::exit(exitcode::SOFTWARE);
  13. }
  14. });
  15. dioxus_desktop::launch_cfg(
  16. app,
  17. Config::new().with_window(WindowBuilder::new().with_visible(true)),
  18. );
  19. should_panic.store(false, std::sync::atomic::Ordering::SeqCst);
  20. }
  21. fn main() {
  22. check_app_exits(check_html_renders);
  23. }
  24. fn use_inner_html(d: &'static str) -> Option<String> {
  25. let eval_provider = use_eval(cx);
  26. let value: Signal<Option<String>> = use_signal(|| None);
  27. use_effect((), |_| {
  28. to_owned![value, eval_provider];
  29. async move {
  30. tokio::time::sleep(std::time::Duration::from_millis(100)).await;
  31. let html = eval_provider(&format!(
  32. r#"let element = document.getElementById('{}');
  33. return element.innerHTML"#,
  34. id
  35. ))
  36. .unwrap();
  37. if let Ok(serde_json::Value::String(html)) = html.await {
  38. println!("html: {}", html);
  39. value.set(Some(html));
  40. }
  41. }
  42. });
  43. value.read().clone()
  44. }
  45. 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>"#;
  46. fn check_html_renders() -> Element {
  47. let inner_html = use_inner_html("main_div");
  48. let desktop_context: DesktopContext = cx.consume_context().unwrap();
  49. if let Some(raw_html) = inner_html {
  50. println!("{}", raw_html);
  51. let fragment = scraper::Html::parse_fragment(&raw_html);
  52. println!("fragment: {}", fragment.html());
  53. let expected = scraper::Html::parse_fragment(EXPECTED_HTML);
  54. println!("expected: {}", expected.html());
  55. if fragment == expected {
  56. println!("html matches");
  57. desktop_context.close();
  58. }
  59. }
  60. let dyn_value = 0;
  61. let dyn_element = rsx! {
  62. div {
  63. dangerous_inner_html: "<p>hello world</p>",
  64. }
  65. };
  66. render! {
  67. div {
  68. id: "main_div",
  69. div {
  70. width: "100px",
  71. height: "100px",
  72. color: "rgb({dyn_value}, {dyn_value}, {dyn_value})",
  73. id: 5,
  74. input {
  75. "type": "checkbox",
  76. },
  77. h1 {
  78. "text"
  79. }
  80. {dyn_element}
  81. }
  82. }
  83. }
  84. }