event_propagation.rs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use dioxus::prelude::*;
  2. use dioxus_core::ElementId;
  3. use std::{rc::Rc, sync::Mutex};
  4. static CLICKS: Mutex<usize> = Mutex::new(0);
  5. #[test]
  6. fn events_propagate() {
  7. set_event_converter(Box::new(dioxus_html::SerializedHtmlEventConverter));
  8. let mut dom = VirtualDom::new(app);
  9. _ = dom.rebuild();
  10. // Top-level click is registered
  11. dom.handle_event("click", Rc::new(PlatformEventData::new(Box::<SerializedMouseData>::default())), ElementId(1), true);
  12. assert_eq!(*CLICKS.lock().unwrap(), 1);
  13. // break reference....
  14. for _ in 0..5 {
  15. dom.mark_dirty(ScopeId(0));
  16. _ = dom.render_immediate();
  17. }
  18. // Lower click is registered
  19. dom.handle_event("click", Rc::new(PlatformEventData::new(Box::<SerializedMouseData>::default())), ElementId(2), true);
  20. assert_eq!(*CLICKS.lock().unwrap(), 3);
  21. // break reference....
  22. for _ in 0..5 {
  23. dom.mark_dirty(ScopeId(0));
  24. _ = dom.render_immediate();
  25. }
  26. // Stop propagation occurs
  27. dom.handle_event("click", Rc::new(PlatformEventData::new(Box::<SerializedMouseData>::default())), ElementId(2), true);
  28. assert_eq!(*CLICKS.lock().unwrap(), 3);
  29. }
  30. fn app(cx: Scope) -> Element {
  31. render! {
  32. div { onclick: move |_| {
  33. println!("top clicked");
  34. *CLICKS.lock().unwrap() += 1;
  35. },
  36. vec![
  37. render! {
  38. problematic_child {}
  39. }
  40. ].into_iter()
  41. }
  42. }
  43. }
  44. fn problematic_child(cx: Scope) -> Element {
  45. render! {
  46. button { onclick: move |evt| {
  47. println!("bottom clicked");
  48. let mut clicks = CLICKS.lock().unwrap();
  49. if *clicks == 3 {
  50. evt.stop_propagation();
  51. } else {
  52. *clicks += 1;
  53. }
  54. } }
  55. }
  56. }