Skip to main content

dioxus_html/events/
mod.rs

1#![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:expr )?;
12        )*
13    ) => {
14        $(
15            $( #[$attr] )*
16            /// <details open>
17            /// <summary>General Event Handler Information</summary>
18            ///
19            #[doc = include_str!("../../docs/event_handlers.md")]
20            ///
21            /// </details>
22            ///
23            #[doc = include_str!("../../docs/common_event_handler_errors.md")]
24            #[inline]
25            pub fn $name<__Marker>(mut _f: impl ::dioxus_core::SuperInto<::dioxus_core::ListenerCallback<$data>, __Marker>) -> ::dioxus_core::Attribute {
26                let event_handler = _f.super_into();
27                ::dioxus_core::Attribute::new(
28                    impl_event!(@name $name $($js_name)?),
29                    ::dioxus_core::AttributeValue::listener(move |e: ::dioxus_core::Event<crate::PlatformEventData>| {
30                        let event: ::dioxus_core::Event<$data> = e.map(|data| {
31                            data.into()
32                        });
33                        event_handler.call(event.into_any());
34                    }),
35                    None,
36                    false,
37                ).into()
38            }
39
40            #[doc(hidden)]
41            $( #[$attr] )*
42            pub mod $name {
43                use super::*;
44
45                // When expanding the macro, we use this version of the function if we see an inline closure to give better type inference
46                $( #[$attr] )*
47                pub fn call_with_explicit_closure<
48                    __Marker,
49                    Return: ::dioxus_core::SpawnIfAsync<__Marker> + 'static,
50                >(
51                    event_handler: impl FnMut(::dioxus_core::Event<$data>) -> Return + 'static,
52                ) -> ::dioxus_core::Attribute {
53                    #[allow(deprecated)]
54                    super::$name(event_handler)
55                }
56            }
57        )*
58    };
59
60    (@name $name:ident $js_name:expr) => {
61        $js_name
62    };
63    (@name $name:ident) => {
64        stringify!($name)
65    };
66}
67
68static EVENT_CONVERTER: RwLock<Option<Box<dyn HtmlEventConverter>>> = RwLock::new(None);
69
70#[inline]
71pub fn set_event_converter(converter: Box<dyn HtmlEventConverter>) {
72    *EVENT_CONVERTER.write().unwrap() = Some(converter);
73}
74
75#[inline]
76pub(crate) fn with_event_converter<F, R>(f: F) -> R
77where
78    F: FnOnce(&dyn HtmlEventConverter) -> R,
79{
80    let converter = EVENT_CONVERTER.read().unwrap();
81    f(converter.as_ref().unwrap().as_ref())
82}
83
84/// A platform specific event.
85pub struct PlatformEventData {
86    event: Box<dyn Any>,
87}
88
89impl PlatformEventData {
90    pub fn new(event: Box<dyn Any>) -> Self {
91        Self { event }
92    }
93
94    pub fn inner(&self) -> &Box<dyn Any> {
95        &self.event
96    }
97
98    pub fn downcast<T: 'static>(&self) -> Option<&T> {
99        self.event.downcast_ref::<T>()
100    }
101
102    pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
103        self.event.downcast_mut::<T>()
104    }
105
106    pub fn into_inner<T: 'static>(self) -> Option<T> {
107        self.event.downcast::<T>().ok().map(|e| *e)
108    }
109}
110
111mod generated;
112
113mod animation;
114mod before_input;
115mod cancel;
116mod clipboard;
117mod composition;
118mod drag;
119mod focus;
120mod form;
121mod image;
122mod keyboard;
123mod media;
124mod mounted;
125mod mouse;
126mod pointer;
127mod resize;
128mod scroll;
129mod selection;
130mod toggle;
131mod touch;
132mod transition;
133mod visible;
134mod wheel;
135
136pub use animation::*;
137pub use before_input::*;
138pub use cancel::*;
139pub use clipboard::*;
140pub use composition::*;
141pub use drag::*;
142pub use focus::*;
143pub use form::*;
144pub use generated::*;
145pub use image::*;
146pub use keyboard::*;
147pub use media::*;
148pub use mounted::*;
149pub use mouse::*;
150pub use pointer::*;
151pub use resize::*;
152pub use scroll::*;
153pub use selection::*;
154pub use toggle::*;
155pub use touch::*;
156pub use transition::*;
157pub use visible::*;
158pub use wheel::*;