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;
18
19mod event_handlers;
20mod event_name;
21mod virtual_events;
22#[cfg(feature = "web")]
23mod web;
24
25pub struct Events<Dom: RealDom> {
27 events: HashMap<EventName, EventHandler<Dom>>,
30}
31
32impl<Dom: RealDom> PartialEq for Events<Dom> {
33 fn eq(&self, other: &Self) -> bool {
34 let Events { events: lhs_events } = self;
35 let Events { events: rhs_events } = other;
36
37 lhs_events == rhs_events
38 }
39}
40
41impl<Dom: RealDom> Events<Dom> {
42 pub fn has_events(&self) -> bool {
44 !self.events.is_empty()
45 }
46
47 pub fn events(&self) -> &HashMap<EventName, EventHandler<Dom>> {
49 &self.events
50 }
51
52 pub fn insert_no_args(&mut self, event_name: EventName, event: Rc<RefCell<dyn FnMut()>>) {
54 self.events
55 .insert(event_name, EventHandler::<Dom>::NoArgs(event));
56 }
57
58 #[doc(hidden)]
60 pub fn __insert_unsupported_signature(
61 &mut self,
62 event_name: EventName,
63 event: Dom::EventCallback,
64 ) {
65 self.events.insert(event_name, EventHandler::Custom(event));
66 }
67
68 pub fn insert_mouse_event(
70 &mut self,
71 event_name: EventName,
72 event: Rc<RefCell<dyn FnMut(Dom::MouseEvent)>>,
73 ) {
74 self.events
75 .insert(event_name, EventHandler::MouseEvent(event));
76 }
77
78 pub fn take_events(&mut self) -> Drain<'_, EventName, EventHandler<Dom>> {
80 self.events.drain()
81 }
82
83 pub fn convert_all<New: RealDom>(
85 mut self,
86 convert: impl Fn(EventHandler<Dom>) -> EventHandler<New>,
87 ) -> Events<New> {
88 let mut new_events = HashMap::with_capacity(self.events.len());
89
90 for (event_name, before) in self.events.drain() {
91 let after = convert(before);
92 new_events.insert(event_name, after);
93 }
94
95 Events { events: new_events }
96 }
97}
98
99impl<Dom: RealDom> Events<Dom> {
100 pub fn new() -> Self {
102 Events {
103 events: HashMap::new(),
104 }
105 }
106}
107
108pub trait RealDom {
121 type Event;
123 type MouseEvent;
125 type EventCallback: Clone;
127}
128
129#[cfg(feature = "web")]
131impl RealDom for web_sys::Window {
132 type Event = web_sys::Event;
133 type MouseEvent = crate::event::MouseEventWebSys;
134 type EventCallback = Rc<dyn AsRef<wasm_bindgen::JsValue>>;
135}
136
137impl RealDom for () {
138 type Event = ();
139 type MouseEvent = ();
140 type EventCallback = ();
141}
142
143#[cfg(feature = "web")]
144impl EventAttribFn {
145 #[doc(hidden)]
147 pub fn new_noop() -> EventAttribFn {
148 use wasm_bindgen::JsValue;
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}