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 cancel;
115mod clipboard;
116mod composition;
117mod drag;
118mod focus;
119mod form;
120mod image;
121mod keyboard;
122mod media;
123mod mounted;
124mod mouse;
125mod pointer;
126mod resize;
127mod scroll;
128mod selection;
129mod toggle;
130mod touch;
131mod transition;
132mod visible;
133mod wheel;
134
135pub use animation::*;
136pub use cancel::*;
137pub use clipboard::*;
138pub use composition::*;
139pub use drag::*;
140pub use focus::*;
141pub use form::*;
142pub use generated::*;
143pub use image::*;
144pub use keyboard::*;
145pub use media::*;
146pub use mounted::*;
147pub use mouse::*;
148pub use pointer::*;
149pub use resize::*;
150pub use scroll::*;
151pub use selection::*;
152pub use toggle::*;
153pub use touch::*;
154pub use transition::*;
155pub use visible::*;
156pub use wheel::*;