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::prelude::SuperInto<::dioxus_core::prelude::EventHandler<::dioxus_core::Event<$data>>, __Marker>) -> ::dioxus_core::Attribute {
29 let owner = <::generational_box::UnsyncStorage as ::generational_box::AnyStorage>::owner();
33 let event_handler = ::dioxus_core::prelude::with_owner(owner.clone(), || _f.super_into());
34 ::dioxus_core::Attribute::new(
35 impl_event!(@name $name $($js_name)?),
36 ::dioxus_core::AttributeValue::listener(move |e: ::dioxus_core::Event<crate::PlatformEventData>| {
37 _ = &owner;
39 event_handler.call(e.map(|e| e.into()));
40 }),
41 None,
42 false,
43 ).into()
44 }
45
46 #[doc(hidden)]
47 $( #[$attr] )*
48 pub mod $name {
49 use super::*;
50
51 $( #[$attr] )*
53 pub fn call_with_explicit_closure<
54 __Marker,
55 Return: ::dioxus_core::SpawnIfAsync<__Marker> + 'static,
56 >(
57 event_handler: impl FnMut(::dioxus_core::Event<$data>) -> Return + 'static,
58 ) -> ::dioxus_core::Attribute {
59 #[allow(deprecated)]
60 super::$name(event_handler)
61 }
62 }
63 )*
64 };
65
66 (@name $name:ident $js_name:literal) => {
67 $js_name
68 };
69 (@name $name:ident) => {
70 stringify!($name)
71 };
72}
73
74static EVENT_CONVERTER: RwLock<Option<Box<dyn HtmlEventConverter>>> = RwLock::new(None);
75
76#[inline]
77pub fn set_event_converter(converter: Box<dyn HtmlEventConverter>) {
78 *EVENT_CONVERTER.write().unwrap() = Some(converter);
79}
80
81#[inline]
82pub(crate) fn with_event_converter<F, R>(f: F) -> R
83where
84 F: FnOnce(&dyn HtmlEventConverter) -> R,
85{
86 let converter = EVENT_CONVERTER.read().unwrap();
87 f(converter.as_ref().unwrap().as_ref())
88}
89
90pub struct PlatformEventData {
92 event: Box<dyn Any>,
93}
94
95impl PlatformEventData {
96 pub fn new(event: Box<dyn Any>) -> Self {
97 Self { event }
98 }
99
100 pub fn inner(&self) -> &Box<dyn Any> {
101 &self.event
102 }
103
104 pub fn downcast<T: 'static>(&self) -> Option<&T> {
105 self.event.downcast_ref::<T>()
106 }
107
108 pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
109 self.event.downcast_mut::<T>()
110 }
111
112 pub fn into_inner<T: 'static>(self) -> Option<T> {
113 self.event.downcast::<T>().ok().map(|e| *e)
114 }
115}
116
117pub trait HtmlEventConverter: Send + Sync {
119 fn convert_animation_data(&self, event: &PlatformEventData) -> AnimationData;
121 fn convert_clipboard_data(&self, event: &PlatformEventData) -> ClipboardData;
123 fn convert_composition_data(&self, event: &PlatformEventData) -> CompositionData;
125 fn convert_drag_data(&self, event: &PlatformEventData) -> DragData;
127 fn convert_focus_data(&self, event: &PlatformEventData) -> FocusData;
129 fn convert_form_data(&self, event: &PlatformEventData) -> FormData;
131 fn convert_image_data(&self, event: &PlatformEventData) -> ImageData;
133 fn convert_keyboard_data(&self, event: &PlatformEventData) -> KeyboardData;
135 fn convert_media_data(&self, event: &PlatformEventData) -> MediaData;
137 fn convert_mounted_data(&self, event: &PlatformEventData) -> MountedData;
139 fn convert_mouse_data(&self, event: &PlatformEventData) -> MouseData;
141 fn convert_pointer_data(&self, event: &PlatformEventData) -> PointerData;
143 fn convert_resize_data(&self, event: &PlatformEventData) -> ResizeData;
145 fn convert_scroll_data(&self, event: &PlatformEventData) -> ScrollData;
147 fn convert_selection_data(&self, event: &PlatformEventData) -> SelectionData;
149 fn convert_toggle_data(&self, event: &PlatformEventData) -> ToggleData;
151 fn convert_touch_data(&self, event: &PlatformEventData) -> TouchData;
153 fn convert_transition_data(&self, event: &PlatformEventData) -> TransitionData;
155 fn convert_visible_data(&self, event: &PlatformEventData) -> VisibleData;
157 fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData;
159}
160
161impl From<&PlatformEventData> for AnimationData {
162 fn from(val: &PlatformEventData) -> Self {
163 with_event_converter(|c| c.convert_animation_data(val))
164 }
165}
166
167impl From<&PlatformEventData> for ClipboardData {
168 fn from(val: &PlatformEventData) -> Self {
169 with_event_converter(|c| c.convert_clipboard_data(val))
170 }
171}
172
173impl From<&PlatformEventData> for CompositionData {
174 fn from(val: &PlatformEventData) -> Self {
175 with_event_converter(|c| c.convert_composition_data(val))
176 }
177}
178
179impl From<&PlatformEventData> for DragData {
180 fn from(val: &PlatformEventData) -> Self {
181 with_event_converter(|c| c.convert_drag_data(val))
182 }
183}
184
185impl From<&PlatformEventData> for FocusData {
186 fn from(val: &PlatformEventData) -> Self {
187 with_event_converter(|c| c.convert_focus_data(val))
188 }
189}
190
191impl From<&PlatformEventData> for FormData {
192 fn from(val: &PlatformEventData) -> Self {
193 with_event_converter(|c| c.convert_form_data(val))
194 }
195}
196
197impl From<&PlatformEventData> for ImageData {
198 fn from(val: &PlatformEventData) -> Self {
199 with_event_converter(|c| c.convert_image_data(val))
200 }
201}
202
203impl From<&PlatformEventData> for KeyboardData {
204 fn from(val: &PlatformEventData) -> Self {
205 with_event_converter(|c| c.convert_keyboard_data(val))
206 }
207}
208
209impl From<&PlatformEventData> for MediaData {
210 fn from(val: &PlatformEventData) -> Self {
211 with_event_converter(|c| c.convert_media_data(val))
212 }
213}
214
215impl From<&PlatformEventData> for MountedData {
216 fn from(val: &PlatformEventData) -> Self {
217 with_event_converter(|c| c.convert_mounted_data(val))
218 }
219}
220
221impl From<&PlatformEventData> for MouseData {
222 fn from(val: &PlatformEventData) -> Self {
223 with_event_converter(|c| c.convert_mouse_data(val))
224 }
225}
226
227impl From<&PlatformEventData> for PointerData {
228 fn from(val: &PlatformEventData) -> Self {
229 with_event_converter(|c| c.convert_pointer_data(val))
230 }
231}
232
233impl From<&PlatformEventData> for ResizeData {
234 fn from(val: &PlatformEventData) -> Self {
235 with_event_converter(|c| c.convert_resize_data(val))
236 }
237}
238
239impl From<&PlatformEventData> for ScrollData {
240 fn from(val: &PlatformEventData) -> Self {
241 with_event_converter(|c| c.convert_scroll_data(val))
242 }
243}
244
245impl From<&PlatformEventData> for SelectionData {
246 fn from(val: &PlatformEventData) -> Self {
247 with_event_converter(|c| c.convert_selection_data(val))
248 }
249}
250
251impl From<&PlatformEventData> for ToggleData {
252 fn from(val: &PlatformEventData) -> Self {
253 with_event_converter(|c| c.convert_toggle_data(val))
254 }
255}
256
257impl From<&PlatformEventData> for TouchData {
258 fn from(val: &PlatformEventData) -> Self {
259 with_event_converter(|c| c.convert_touch_data(val))
260 }
261}
262
263impl From<&PlatformEventData> for TransitionData {
264 fn from(val: &PlatformEventData) -> Self {
265 with_event_converter(|c| c.convert_transition_data(val))
266 }
267}
268
269impl From<&PlatformEventData> for VisibleData {
270 fn from(val: &PlatformEventData) -> Self {
271 with_event_converter(|c| c.convert_visible_data(val))
272 }
273}
274
275impl From<&PlatformEventData> for WheelData {
276 fn from(val: &PlatformEventData) -> Self {
277 with_event_converter(|c| c.convert_wheel_data(val))
278 }
279}
280
281mod animation;
282mod clipboard;
283mod composition;
284mod drag;
285mod focus;
286mod form;
287mod image;
288mod keyboard;
289mod media;
290mod mounted;
291mod mouse;
292mod pointer;
293mod resize;
294mod scroll;
295mod selection;
296mod toggle;
297mod touch;
298mod transition;
299mod visible;
300mod wheel;
301
302pub use animation::*;
303pub use clipboard::*;
304pub use composition::*;
305pub use drag::*;
306pub use focus::*;
307pub use form::*;
308pub use image::*;
309pub use keyboard::*;
310pub use media::*;
311pub use mounted::*;
312pub use mouse::*;
313pub use pointer::*;
314pub use resize::*;
315pub use scroll::*;
316pub use selection::*;
317pub use toggle::*;
318pub use touch::*;
319pub use transition::*;
320pub use visible::*;
321pub use wheel::*;