virtual_node/event/
non_delegated_event_wrapper.rs

1use crate::event::virtual_events::ElementEventsId;
2use crate::event::{EventHandler, EventName, MouseEvent, VirtualEvents, ELEMENT_EVENTS_ID_PROP};
3use js_sys::Reflect;
4use std::rc::Rc;
5use wasm_bindgen::closure::Closure;
6use wasm_bindgen::{JsCast, JsValue};
7
8/// Insert a non-delegated event
9pub fn insert_non_delegated_event(
10    element: &web_sys::Element,
11    onevent: &EventName,
12    callback: &EventHandler,
13    events_id: ElementEventsId,
14    events: &VirtualEvents,
15) {
16    let events_clone = events.clone();
17
18    let event_name = onevent.without_on_prefix();
19
20    let on_event = onevent.with_on_prefix().to_string();
21    let on_event_clone = on_event.clone();
22
23    let callback_wrapper = move |event: web_sys::Event| {
24        let this_elem = event.current_target().unwrap();
25
26        let events_id = Reflect::get(&this_elem, &ELEMENT_EVENTS_ID_PROP.into()).unwrap();
27        let events_id = events_id.as_string();
28        let events_id = events_id.unwrap();
29
30        let events_id =
31            events_id.trim_start_matches(&events_clone.events_id_props_prefix().to_string());
32        let events_id: u32 = events_id.parse().unwrap();
33
34        let event_name = EventName::new(on_event_clone.clone().into());
35        let cb = events_clone
36            .get_event_handler(&ElementEventsId::new(events_id), &event_name)
37            .unwrap();
38
39        match cb {
40            EventHandler::NoArgs(no_args) => (no_args.borrow_mut())(),
41            EventHandler::MouseEvent(mouse) => {
42                (mouse.borrow_mut())(MouseEvent::new(event.dyn_into().unwrap()));
43            }
44            EventHandler::UnsupportedSignature(cb) => {
45                let cb: &js_sys::Function = cb.as_ref().as_ref().unchecked_ref();
46
47                let context = JsValue::NULL;
48                cb.call1(&context, &event).unwrap();
49            }
50        };
51    };
52
53    let callback_wrapper = Box::new(callback_wrapper) as Box<dyn FnMut(_) -> ()>;
54    let callback_wrapper = Closure::wrap(callback_wrapper);
55
56    let current_elem: &web_sys::EventTarget = element.dyn_ref().unwrap();
57    current_elem
58        .add_event_listener_with_callback(
59            event_name,
60            callback_wrapper.as_ref().as_ref().unchecked_ref(),
61        )
62        .unwrap();
63
64    events.insert_event(
65        events_id,
66        onevent.clone(),
67        callback.clone(),
68        Some(Rc::new(callback_wrapper)),
69    );
70}