virtual_node/event/
web.rs1use crate::event::virtual_events::ElementEventsId;
2use crate::event::{
3 EventHandler, EventName, MouseEventWebSys, VirtualEvents, ELEMENT_EVENTS_ID_PROP,
4};
5use js_sys::Reflect;
6use std::fmt;
7use std::fmt::Formatter;
8use std::rc::Rc;
9use wasm_bindgen::closure::Closure;
10use wasm_bindgen::JsCast;
11
12pub(crate) type EventWrapper = std::rc::Rc<dyn AsRef<wasm_bindgen::JsValue>>;
14
15#[derive(Clone)]
17pub struct EventAttribFn(pub EventWrapper);
18
19impl EventAttribFn {
20 pub fn new(callback: EventWrapper) -> Self {
22 Self(callback)
23 }
24}
25
26pub fn insert_non_delegated_event(
30 element: &web_sys::Element,
31 onevent: &EventName,
32 callback: &EventHandler<web_sys::Window>,
33 events_id: ElementEventsId,
34 events: &VirtualEvents<web_sys::Window>,
35) {
36 let events_clone = events.clone();
37
38 let event_name = onevent.without_on_prefix();
39
40 let on_event = onevent.with_on_prefix().to_string();
41 let on_event_clone = on_event.clone();
42
43 let callback_wrapper = move |event: web_sys::Event| {
44 let this_elem = event.current_target().unwrap();
45
46 let events_id = Reflect::get(&this_elem, &ELEMENT_EVENTS_ID_PROP.into()).unwrap();
47 let events_id = events_id.as_string();
48 let events_id = events_id.unwrap();
49
50 let events_id =
51 events_id.trim_start_matches(&events_clone.events_id_props_prefix().to_string());
52 let events_id: u32 = events_id.parse().unwrap();
53
54 let event_name = EventName::new(on_event_clone.clone().into());
55 let cb = events_clone
56 .get_event_handler(&ElementEventsId::new(events_id), &event_name)
57 .unwrap();
58
59 match cb {
60 EventHandler::NoArgs(no_args) => (no_args.borrow_mut())(),
61 EventHandler::MouseEvent(mouse) => {
62 (mouse.borrow_mut())(MouseEventWebSys::new(event.dyn_into().unwrap()));
63 }
64 EventHandler::Custom(cb) => {
65 use wasm_bindgen::JsCast;
66
67 let context = wasm_bindgen::JsValue::NULL;
68 let callback: &js_sys::Function = cb.as_ref().as_ref().unchecked_ref();
69 callback.call1(&context, &event).unwrap();
70 }
71 };
72 };
73
74 let callback_wrapper = Box::new(callback_wrapper) as Box<dyn FnMut(_) -> ()>;
75 let callback_wrapper = Closure::wrap(callback_wrapper);
76
77 let current_elem: &web_sys::EventTarget = element.dyn_ref().unwrap();
78 current_elem
79 .add_event_listener_with_callback(
80 event_name,
81 callback_wrapper.as_ref().as_ref().unchecked_ref(),
82 )
83 .unwrap();
84
85 let event_wrapper = Rc::new(callback_wrapper);
86 events.insert_event(
87 events_id,
88 onevent.clone(),
89 callback.clone(),
90 Some(event_wrapper),
91 );
92}
93
94impl PartialEq for EventAttribFn {
99 fn eq(&self, _other: &Self) -> bool {
100 true
101 }
102}
103
104impl fmt::Debug for EventAttribFn {
105 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
106 write!(f, "event_handler()")
107 }
108}
109
110impl From<EventWrapper> for EventAttribFn {
111 fn from(inner: EventWrapper) -> Self {
112 EventAttribFn(inner)
113 }
114}