event_propagation.rs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. let mut clicks = CLICKS.lock().unwrap();
  49. if *clicks == 3 {
  50. evt.stop_propagation();
  51. } else {
  52. *clicks += 1;
  53. }
  54. }
  55. }
  56. }
  57. }