event_propagation.rs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. let mut dom = VirtualDom::new(app);
  8. _ = dom.rebuild();
  9. // Top-level click is registered
  10. dom.handle_event("click", Rc::new(MouseData::default()), ElementId(1), true);
  11. assert_eq!(*CLICKS.lock().unwrap(), 1);
  12. // break reference....
  13. for _ in 0..5 {
  14. dom.mark_dirty(ScopeId(0));
  15. _ = dom.render_immediate();
  16. }
  17. // Lower click is registered
  18. dom.handle_event("click", Rc::new(MouseData::default()), ElementId(2), true);
  19. assert_eq!(*CLICKS.lock().unwrap(), 3);
  20. // break reference....
  21. for _ in 0..5 {
  22. dom.mark_dirty(ScopeId(0));
  23. _ = dom.render_immediate();
  24. }
  25. // Stop propagation occurs
  26. dom.handle_event("click", Rc::new(MouseData::default()), ElementId(2), true);
  27. assert_eq!(*CLICKS.lock().unwrap(), 3);
  28. }
  29. fn app(cx: Scope) -> Element {
  30. render! {
  31. div {
  32. 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 {
  47. onclick: move |evt| {
  48. println!("bottom clicked");
  49. let mut clicks = CLICKS.lock().unwrap();
  50. if *clicks == 3 {
  51. evt.stop_propagation();
  52. } else {
  53. *clicks += 1;
  54. }
  55. }
  56. }
  57. }
  58. }