dioxus_html/events/
mod.rs1#![doc = include_str!("../../docs/event_handlers.md")]
2
3use std::any::Any;
4use std::sync::RwLock;
5
6macro_rules! impl_event {
7 (
8 $data:ty;
9 $(
10 $( #[$attr:meta] )*
11 $name:ident $(: $js_name:literal)?
12 )*
13 ) => {
14 $(
15 $( #[$attr] )*
16 #[doc = include_str!("../../docs/event_handlers.md")]
20 #[doc = include_str!("../../docs/common_event_handler_errors.md")]
24 $(
25 #[doc(alias = $js_name)]
26 )?
27 #[inline]
28 pub fn $name<__Marker>(mut _f: impl ::dioxus_core::SuperInto<::dioxus_core::ListenerCallback<$data>, __Marker>) -> ::dioxus_core::Attribute {
29 let event_handler = _f.super_into();
30 ::dioxus_core::Attribute::new(
31 impl_event!(@name $name $($js_name)?),
32 ::dioxus_core::AttributeValue::listener(move |e: ::dioxus_core::Event<crate::PlatformEventData>| {
33 let event: ::dioxus_core::Event<$data> = e.map(|data| {
34 data.into()
35 });
36 event_handler.call(event.into_any());
37 }),
38 None,
39 false,
40 ).into()
41 }
42
43 #[doc(hidden)]
44 $( #[$attr] )*
45 pub mod $name {
46 use super::*;
47
48 $( #[$attr] )*
50 pub fn call_with_explicit_closure<
51 __Marker,
52 Return: ::dioxus_core::SpawnIfAsync<__Marker> + 'static,
53 >(
54 event_handler: impl FnMut(::dioxus_core::Event<$data>) -> Return + 'static,
55 ) -> ::dioxus_core::Attribute {
56 #[allow(deprecated)]
57 super::$name(event_handler)
58 }
59 }
60 )*
61 };
62
63 (@name $name:ident $js_name:literal) => {
64 $js_name
65 };
66 (@name $name:ident) => {
67 stringify!($name)
68 };
69}
70
71static EVENT_CONVERTER: RwLock<Option<Box<dyn HtmlEventConverter>>> = RwLock::new(None);
72
73#[inline]
74pub fn set_event_converter(converter: Box<dyn HtmlEventConverter>) {
75 *EVENT_CONVERTER.write().unwrap() = Some(converter);
76}
77
78#[inline]
79pub(crate) fn with_event_converter<F, R>(f: F) -> R
80where
81 F: FnOnce(&dyn HtmlEventConverter) -> R,
82{
83 let converter = EVENT_CONVERTER.read().unwrap();
84 f(converter.as_ref().unwrap().as_ref())
85}
86
87pub struct PlatformEventData {
89 event: Box<dyn Any>,
90}
91
92impl PlatformEventData {
93 pub fn new(event: Box<dyn Any>) -> Self {
94 Self { event }
95 }
96
97 pub fn inner(&self) -> &Box<dyn Any> {
98 &self.event
99 }
100
101 pub fn downcast<T: 'static>(&self) -> Option<&T> {
102 self.event.downcast_ref::<T>()
103 }
104
105 pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
106 self.event.downcast_mut::<T>()
107 }
108
109 pub fn into_inner<T: 'static>(self) -> Option<T> {
110 self.event.downcast::<T>().ok().map(|e| *e)
111 }
112}
113
114pub trait HtmlEventConverter: Send + Sync {
116 fn convert_animation_data(&self, event: &PlatformEventData) -> AnimationData;
118 fn convert_clipboard_data(&self, event: &PlatformEventData) -> ClipboardData;
120 fn convert_composition_data(&self, event: &PlatformEventData) -> CompositionData;
122 fn convert_drag_data(&self, event: &PlatformEventData) -> DragData;
124 fn convert_focus_data(&self, event: &PlatformEventData) -> FocusData;
126 fn convert_form_data(&self, event: &PlatformEventData) -> FormData;
128 fn convert_image_data(&self, event: &PlatformEventData) -> ImageData;
130 fn convert_keyboard_data(&self, event: &PlatformEventData) -> KeyboardData;
132 fn convert_media_data(&self, event: &PlatformEventData) -> MediaData;
134 fn convert_mounted_data(&self, event: &PlatformEventData) -> MountedData;
136 fn convert_mouse_data(&self, event: &PlatformEventData) -> MouseData;
138 fn convert_pointer_data(&self, event: &PlatformEventData) -> PointerData;
140 fn convert_resize_data(&self, event: &PlatformEventData) -> ResizeData;
142 fn convert_scroll_data(&self, event: &PlatformEventData) -> ScrollData;
144 fn convert_selection_data(&self, event: &PlatformEventData) -> SelectionData;
146 fn convert_toggle_data(&self, event: &PlatformEventData) -> ToggleData;
148 fn convert_touch_data(&self, event: &PlatformEventData) -> TouchData;
150 fn convert_transition_data(&self, event: &PlatformEventData) -> TransitionData;
152 fn convert_visible_data(&self, event: &PlatformEventData) -> VisibleData;
154 fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData;
156}
157
158impl From<&PlatformEventData> for AnimationData {
159 fn from(val: &PlatformEventData) -> Self {
160 with_event_converter(|c| c.convert_animation_data(val))
161 }
162}
163
164impl From<&PlatformEventData> for ClipboardData {
165 fn from(val: &PlatformEventData) -> Self {
166 with_event_converter(|c| c.convert_clipboard_data(val))
167 }
168}
169
170impl From<&PlatformEventData> for CompositionData {
171 fn from(val: &PlatformEventData) -> Self {
172 with_event_converter(|c| c.convert_composition_data(val))
173 }
174}
175
176impl From<&PlatformEventData> for DragData {
177 fn from(val: &PlatformEventData) -> Self {
178 with_event_converter(|c| c.convert_drag_data(val))
179 }
180}
181
182impl From<&PlatformEventData> for FocusData {
183 fn from(val: &PlatformEventData) -> Self {
184 with_event_converter(|c| c.convert_focus_data(val))
185 }
186}
187
188impl From<&PlatformEventData> for FormData {
189 fn from(val: &PlatformEventData) -> Self {
190 with_event_converter(|c| c.convert_form_data(val))
191 }
192}
193
194impl From<&PlatformEventData> for ImageData {
195 fn from(val: &PlatformEventData) -> Self {
196 with_event_converter(|c| c.convert_image_data(val))
197 }
198}
199
200impl From<&PlatformEventData> for KeyboardData {
201 fn from(val: &PlatformEventData) -> Self {
202 with_event_converter(|c| c.convert_keyboard_data(val))
203 }
204}
205
206impl From<&PlatformEventData> for MediaData {
207 fn from(val: &PlatformEventData) -> Self {
208 with_event_converter(|c| c.convert_media_data(val))
209 }
210}
211
212impl From<&PlatformEventData> for MountedData {
213 fn from(val: &PlatformEventData) -> Self {
214 with_event_converter(|c| c.convert_mounted_data(val))
215 }
216}
217
218impl From<&PlatformEventData> for MouseData {
219 fn from(val: &PlatformEventData) -> Self {
220 with_event_converter(|c| c.convert_mouse_data(val))
221 }
222}
223
224impl From<&PlatformEventData> for PointerData {
225 fn from(val: &PlatformEventData) -> Self {
226 with_event_converter(|c| c.convert_pointer_data(val))
227 }
228}
229
230impl From<&PlatformEventData> for ResizeData {
231 fn from(val: &PlatformEventData) -> Self {
232 with_event_converter(|c| c.convert_resize_data(val))
233 }
234}
235
236impl From<&PlatformEventData> for ScrollData {
237 fn from(val: &PlatformEventData) -> Self {
238 with_event_converter(|c| c.convert_scroll_data(val))
239 }
240}
241
242impl From<&PlatformEventData> for SelectionData {
243 fn from(val: &PlatformEventData) -> Self {
244 with_event_converter(|c| c.convert_selection_data(val))
245 }
246}
247
248impl From<&PlatformEventData> for ToggleData {
249 fn from(val: &PlatformEventData) -> Self {
250 with_event_converter(|c| c.convert_toggle_data(val))
251 }
252}
253
254impl From<&PlatformEventData> for TouchData {
255 fn from(val: &PlatformEventData) -> Self {
256 with_event_converter(|c| c.convert_touch_data(val))
257 }
258}
259
260impl From<&PlatformEventData> for TransitionData {
261 fn from(val: &PlatformEventData) -> Self {
262 with_event_converter(|c| c.convert_transition_data(val))
263 }
264}
265
266impl From<&PlatformEventData> for VisibleData {
267 fn from(val: &PlatformEventData) -> Self {
268 with_event_converter(|c| c.convert_visible_data(val))
269 }
270}
271
272impl From<&PlatformEventData> for WheelData {
273 fn from(val: &PlatformEventData) -> Self {
274 with_event_converter(|c| c.convert_wheel_data(val))
275 }
276}
277
278mod animation;
279mod clipboard;
280mod composition;
281mod drag;
282mod focus;
283mod form;
284mod image;
285mod keyboard;
286mod media;
287mod mounted;
288mod mouse;
289mod pointer;
290mod resize;
291mod scroll;
292mod selection;
293mod toggle;
294mod touch;
295mod transition;
296mod visible;
297mod wheel;
298
299pub use animation::*;
300pub use clipboard::*;
301pub use composition::*;
302pub use drag::*;
303pub use focus::*;
304pub use form::*;
305pub use image::*;
306pub use keyboard::*;
307pub use media::*;
308pub use mounted::*;
309pub use mouse::*;
310pub use pointer::*;
311pub use resize::*;
312pub use scroll::*;
313pub use selection::*;
314pub use toggle::*;
315pub use touch::*;
316pub use transition::*;
317pub use visible::*;
318pub use wheel::*;