1pub use self::event_handlers::*;
2pub use self::event_name::EventName;
3pub use self::non_delegated_event_wrapper::insert_non_delegated_event;
4pub(crate) use self::virtual_events::set_events_id;
5pub use self::virtual_events::{
6 ElementEventsId, VirtualEventElement, VirtualEventNode, VirtualEvents, ELEMENT_EVENTS_ID_PROP,
7};
8use std::cell::RefCell;
9use std::collections::HashMap;
10use std::fmt;
11use std::fmt::Formatter;
12use std::ops::{Deref, DerefMut};
13use std::rc::Rc;
14use wasm_bindgen::JsValue;
15use web_sys::Event;
16
17mod event_handlers;
18mod event_name;
19mod non_delegated_event_wrapper;
20mod virtual_events;
21
22pub(crate) type EventWrapper = std::rc::Rc<dyn EventCallback>;
24
25#[derive(Clone)]
27pub struct EventAttribFn(EventWrapper);
28
29#[derive(PartialEq)]
31pub struct Events {
32 events: HashMap<EventName, EventHandler>,
33}
34
35impl Events {
36 pub fn has_events(&self) -> bool {
38 !self.events.is_empty()
39 }
40
41 pub fn events(&self) -> &HashMap<EventName, EventHandler> {
43 &self.events
44 }
45
46 pub fn insert_no_args(&mut self, event_name: EventName, event: Rc<RefCell<dyn FnMut()>>) {
48 self.events.insert(event_name, EventHandler::NoArgs(event));
49 }
50
51 #[doc(hidden)]
53 pub fn __insert_unsupported_signature(&mut self, event_name: EventName, event: EventWrapper) {
54 self.events
55 .insert(event_name, EventHandler::UnsupportedSignature(event.into()));
56 }
57
58 pub fn insert_mouse_event(
60 &mut self,
61 event_name: EventName,
62 event: Rc<RefCell<dyn FnMut(MouseEvent)>>,
63 ) {
64 self.events
65 .insert(event_name, EventHandler::MouseEvent(event));
66 }
67}
68
69impl Events {
70 pub fn new() -> Self {
72 Events {
73 events: HashMap::new(),
74 }
75 }
76}
77
78pub trait EventCallback {
82 fn call(&self, event: &web_sys::Event);
84
85 fn as_js_value(&self) -> Option<&wasm_bindgen::JsValue>;
87}
88
89impl<T: ?Sized> EventCallback for wasm_bindgen::closure::Closure<T> {
90 fn call(&self, event: &web_sys::Event) {
91 use wasm_bindgen::JsCast;
92
93 let context = wasm_bindgen::JsValue::NULL;
94 let callback: &js_sys::Function = self.as_ref().as_ref().unchecked_ref();
95 callback.call1(&context, &event).unwrap();
96 }
97
98 fn as_js_value(&self) -> Option<&wasm_bindgen::JsValue> {
99 Some(self.as_ref())
100 }
101}
102
103impl EventAttribFn {
104 #[doc(hidden)]
106 pub fn new_noop() -> Self {
107 struct Noop;
108 impl EventCallback for Noop {
109 fn call(&self, _event: &Event) {}
110
111 fn as_js_value(&self) -> Option<&JsValue> {
112 None
113 }
114 }
115 Self(Rc::new(Noop))
116 }
117
118 pub(crate) fn call(&self, event: &web_sys::Event) {
119 self.0.call(event)
120 }
121}
122
123impl PartialEq for EventAttribFn {
128 fn eq(&self, _other: &Self) -> bool {
129 true
130 }
131}
132
133impl fmt::Debug for Events {
134 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136 let events: String = self
137 .events
138 .keys()
139 .map(|key| " ".to_string() + key.with_on_prefix())
140 .collect();
141 write!(f, "{}", events)
142 }
143}
144
145impl fmt::Debug for EventAttribFn {
146 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
147 write!(f, "event_handler()")
148 }
149}
150
151impl From<EventWrapper> for EventAttribFn {
152 fn from(inner: EventWrapper) -> Self {
153 EventAttribFn(inner)
154 }
155}
156
157impl Deref for Events {
158 type Target = HashMap<EventName, EventHandler>;
159
160 fn deref(&self) -> &Self::Target {
161 &self.events
162 }
163}
164
165impl DerefMut for Events {
166 fn deref_mut(&mut self) -> &mut Self::Target {
167 &mut self.events
168 }
169}