use std::any::Any; use std::sync::RwLock; macro_rules! impl_event { ( $data:ty; $( $( #[$attr:meta] )* $name:ident )* ) => { $( $( #[$attr] )* #[inline] pub fn $name<'a, E: crate::EventReturn, T>(_cx: &'a ::dioxus_core::ScopeState, mut _f: impl FnMut(::dioxus_core::Event<$data>) -> E + 'a) -> ::dioxus_core::Attribute<'a> { ::dioxus_core::Attribute::new( stringify!($name), _cx.listener(move |e: ::dioxus_core::Event| { _f(e.map(|e|e.into())).spawn(_cx); }), None, false, ) } )* }; } static EVENT_CONVERTER: RwLock>> = RwLock::new(None); pub fn set_event_converter(converter: Box) { *EVENT_CONVERTER.write().unwrap() = Some(converter); } pub(crate) fn with_event_converter(f: F) -> R where F: FnOnce(&dyn HtmlEventConverter) -> R, { let converter = EVENT_CONVERTER.read().unwrap(); f(converter.as_ref().unwrap().as_ref()) } /// A platform specific event. pub struct PlatformEventData { event: Box, } impl PlatformEventData { pub fn new(event: Box) -> Self { Self { event } } pub fn downcast(&self) -> Option<&T> { self.event.downcast_ref::() } pub fn downcast_mut(&mut self) -> Option<&mut T> { self.event.downcast_mut::() } pub fn into_inner(self) -> Option { self.event.downcast::().ok().map(|e| *e) } } pub trait HtmlEventConverter: Send + Sync { fn convert_animation_data(&self, event: &PlatformEventData) -> AnimationData; fn convert_clipboard_data(&self, event: &PlatformEventData) -> ClipboardData; fn convert_composition_data(&self, event: &PlatformEventData) -> CompositionData; fn convert_drag_data(&self, event: &PlatformEventData) -> DragData; fn convert_focus_data(&self, event: &PlatformEventData) -> FocusData; fn convert_form_data(&self, event: &PlatformEventData) -> FormData; fn convert_image_data(&self, event: &PlatformEventData) -> ImageData; fn convert_keyboard_data(&self, event: &PlatformEventData) -> KeyboardData; fn convert_media_data(&self, event: &PlatformEventData) -> MediaData; fn convert_mounted_data(&self, event: &PlatformEventData) -> MountedData; fn convert_mouse_data(&self, event: &PlatformEventData) -> MouseData; fn convert_pointer_data(&self, event: &PlatformEventData) -> PointerData; fn convert_scroll_data(&self, event: &PlatformEventData) -> ScrollData; fn convert_selection_data(&self, event: &PlatformEventData) -> SelectionData; fn convert_toggle_data(&self, event: &PlatformEventData) -> ToggleData; fn convert_touch_data(&self, event: &PlatformEventData) -> TouchData; fn convert_transition_data(&self, event: &PlatformEventData) -> TransitionData; fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData; } impl Into for &PlatformEventData { fn into(self) -> AnimationData { with_event_converter(|c| c.convert_animation_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> ClipboardData { with_event_converter(|c| c.convert_clipboard_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> CompositionData { with_event_converter(|c| c.convert_composition_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> DragData { with_event_converter(|c| c.convert_drag_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> FocusData { with_event_converter(|c| c.convert_focus_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> FormData { with_event_converter(|c| c.convert_form_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> ImageData { with_event_converter(|c| c.convert_image_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> KeyboardData { with_event_converter(|c| c.convert_keyboard_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> MediaData { with_event_converter(|c| c.convert_media_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> MountedData { with_event_converter(|c| c.convert_mounted_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> MouseData { with_event_converter(|c| c.convert_mouse_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> PointerData { with_event_converter(|c| c.convert_pointer_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> ScrollData { with_event_converter(|c| c.convert_scroll_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> SelectionData { with_event_converter(|c| c.convert_selection_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> ToggleData { with_event_converter(|c| c.convert_toggle_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> TouchData { with_event_converter(|c| c.convert_touch_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> TransitionData { with_event_converter(|c| c.convert_transition_data(self)) } } impl Into for &PlatformEventData { fn into(self) -> WheelData { with_event_converter(|c| c.convert_wheel_data(self)) } } mod animation; mod clipboard; mod composition; mod drag; mod focus; mod form; mod image; mod keyboard; mod media; mod mounted; mod mouse; mod pointer; mod scroll; mod selection; mod toggle; mod touch; mod transition; mod wheel; pub use animation::*; pub use clipboard::*; pub use composition::*; pub use drag::*; pub use focus::*; pub use form::*; pub use image::*; pub use keyboard::*; pub use media::*; pub use mounted::*; pub use mouse::*; pub use pointer::*; pub use scroll::*; pub use selection::*; pub use toggle::*; pub use touch::*; pub use transition::*; pub use wheel::*; pub fn event_bubbles(evt: &str) -> bool { match evt { "copy" => true, "cut" => true, "paste" => true, "compositionend" => true, "compositionstart" => true, "compositionupdate" => true, "keydown" => true, "keypress" => true, "keyup" => true, "focus" => false, "focusout" => true, "focusin" => true, "blur" => false, "change" => true, "input" => true, "invalid" => true, "reset" => true, "submit" => true, "click" => true, "contextmenu" => true, "doubleclick" => true, "dblclick" => true, "drag" => true, "dragend" => true, "dragenter" => false, "dragexit" => false, "dragleave" => true, "dragover" => true, "dragstart" => true, "drop" => true, "mousedown" => true, "mouseenter" => false, "mouseleave" => false, "mousemove" => true, "mouseout" => true, "scroll" => false, "mouseover" => true, "mouseup" => true, "pointerdown" => true, "pointermove" => true, "pointerup" => true, "pointercancel" => true, "gotpointercapture" => true, "lostpointercapture" => true, "pointerenter" => false, "pointerleave" => false, "pointerover" => true, "pointerout" => true, "select" => true, "touchcancel" => true, "touchend" => true, "touchmove" => true, "touchstart" => true, "wheel" => true, "abort" => false, "canplay" => false, "canplaythrough" => false, "durationchange" => false, "emptied" => false, "encrypted" => true, "ended" => false, "error" => false, "loadeddata" => false, "loadedmetadata" => false, "loadstart" => false, "load" => false, "pause" => false, "play" => false, "playing" => false, "progress" => false, "ratechange" => false, "seeked" => false, "seeking" => false, "stalled" => false, "suspend" => false, "timeupdate" => false, "volumechange" => false, "waiting" => false, "animationstart" => true, "animationend" => true, "animationiteration" => true, "transitionend" => true, "toggle" => true, "mounted" => false, _ => true, } } #[doc(hidden)] pub trait EventReturn

: Sized { fn spawn(self, _cx: &dioxus_core::ScopeState) {} } impl EventReturn<()> for () {} #[doc(hidden)] pub struct AsyncMarker; impl EventReturn for T where T: std::future::Future + 'static, { #[inline] fn spawn(self, cx: &dioxus_core::ScopeState) { cx.spawn(self); } }