1pub use self::event_handlers::*;
2pub use self::event_name::EventName;
3#[cfg(feature = "web")]
4pub(crate) use self::virtual_events::set_events_id;
5#[cfg(feature = "web")]
6pub use self::virtual_events::VirtualEventsWebSys;
7pub use self::virtual_events::{
8 ElementEventsId, VirtualEventElement, VirtualEventNode, VirtualEvents, ELEMENT_EVENTS_ID_PROP,
9};
10#[cfg(feature = "web")]
11pub use self::web::{insert_non_delegated_event, EventAttribFn};
12use std::cell::RefCell;
13use std::collections::hash_map::Drain;
14use std::collections::HashMap;
15use std::fmt;
16use std::ops::{Deref, DerefMut};
17use std::rc::Rc;
18use wasm_bindgen::JsValue;
19
20mod event_handlers;
21mod event_name;
22mod virtual_events;
23#[cfg(feature = "web")]
24mod web;
25
26pub struct Events<Dom: RealDom> {
28 events: HashMap<EventName, EventHandler<Dom>>,
31}
32
33impl<Dom: RealDom> PartialEq for Events<Dom> {
34 fn eq(&self, other: &Self) -> bool {
35 let Events { events: lhs_events } = self;
36 let Events { events: rhs_events } = other;
37
38 lhs_events == rhs_events
39 }
40}
41
42impl<Dom: RealDom> Events<Dom> {
43 pub fn has_events(&self) -> bool {
45 !self.events.is_empty()
46 }
47
48 pub fn events(&self) -> &HashMap<EventName, EventHandler<Dom>> {
50 &self.events
51 }
52
53 pub fn insert_no_args(&mut self, event_name: EventName, event: Rc<RefCell<dyn FnMut()>>) {
55 self.events
56 .insert(event_name, EventHandler::<Dom>::NoArgs(event));
57 }
58
59 #[doc(hidden)]
61 pub fn __insert_unsupported_signature(
62 &mut self,
63 event_name: EventName,
64 event: Dom::EventCallback,
65 ) {
66 self.events.insert(event_name, EventHandler::Custom(event));
67 }
68
69 pub fn insert_mouse_event(
71 &mut self,
72 event_name: EventName,
73 event: Rc<RefCell<dyn FnMut(Dom::MouseEvent)>>,
74 ) {
75 self.events
76 .insert(event_name, EventHandler::MouseEvent(event));
77 }
78
79 pub fn take_events(&mut self) -> Drain<'_, EventName, EventHandler<Dom>> {
81 self.events.drain()
82 }
83
84 pub fn convert_all<New: RealDom>(
86 mut self,
87 convert: impl Fn(EventHandler<Dom>) -> EventHandler<New>,
88 ) -> Events<New> {
89 let mut new_events = HashMap::with_capacity(self.events.len());
90
91 for (event_name, before) in self.events.drain() {
92 let after = convert(before);
93 new_events.insert(event_name, after);
94 }
95
96 Events { events: new_events }
97 }
98}
99
100impl<Dom: RealDom> Events<Dom> {
101 pub fn new() -> Self {
103 Events {
104 events: HashMap::new(),
105 }
106 }
107}
108
109pub trait RealDom {
122 type Event;
124 type MouseEvent;
126 type EventCallback: Clone;
128}
129
130#[cfg(feature = "web")]
132impl RealDom for web_sys::Window {
133 type Event = web_sys::Event;
134 type MouseEvent = crate::event::MouseEventWebSys;
135 type EventCallback = Rc<dyn AsRef<wasm_bindgen::JsValue>>;
136}
137
138impl RealDom for () {
139 type Event = ();
140 type MouseEvent = ();
141 type EventCallback = ();
142}
143
144#[cfg(feature = "web")]
145impl EventAttribFn {
146 #[doc(hidden)]
148 pub fn new_noop() -> EventAttribFn {
149 let noop = Rc::new(JsValue::NULL);
150 EventAttribFn::new(noop)
151 }
152}
153
154impl<Dom: RealDom> fmt::Debug for Events<Dom> {
155 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 let events: String = self
158 .events
159 .keys()
160 .map(|key| " ".to_string() + key.with_on_prefix())
161 .collect();
162 write!(f, "{}", events)
163 }
164}
165
166impl<Dom: RealDom> Deref for Events<Dom> {
167 type Target = HashMap<EventName, EventHandler<Dom>>;
168
169 fn deref(&self) -> &Self::Target {
170 &self.events
171 }
172}
173
174impl<Dom: RealDom> DerefMut for Events<Dom> {
175 fn deref_mut(&mut self) -> &mut Self::Target {
176 &mut self.events
177 }
178}