use wasm_bindgen::closure::Closure;
use wasm_bindgen::{JsCast, UnwrapThrowExt};
pub trait Listener {
}
macro_rules! impl_event_helpers {
($($EventType:ident $EventListener:ident { $($EventName:ident => $event_name:literal,)+ })+) => {
$(
//pub trait $EventType {}
pub struct $EventListener {
event_name: &'static str,
event_target: web_sys::EventTarget,
closure: Closure<Fn(web_sys::$EventType)>,
}
impl $EventListener {
fn new(event_name: &'static str, event_target: &web_sys::EventTarget, closure: Closure<Fn(web_sys::$EventType)>) -> Self {
event_target.add_event_listener_with_callback(event_name, closure.as_ref().unchecked_ref()).expect_throw("event_target.add_event_listener_with_callback(event_name, closure.as_ref().unchecked_ref())");
Self {
event_name,
event_target: event_target.clone(),
closure,
}
}
}
impl Listener for $EventListener {
}
impl Drop for $EventListener {
#[inline]
fn drop(&mut self) {
self.event_target
.remove_event_listener_with_callback(self.event_name, self.closure.as_ref().unchecked_ref()).expect_throw("self.event_target.remove_event_listener_with_callback(self.event_name, self.closure.as_ref().unchecked_ref())");
}
}
$(
#[doc = "Represent "]
#[doc = $event_name]
#[doc = " event"]
pub struct $EventName;
#[cfg(feature = "message-like-elm")]
impl $EventName
{
#[doc = "Create and register a kaar callback to "]
#[doc = $event_name]
#[doc = " on the Window"]
pub fn on_window<A, F>(main: &crate::app::WeakMain<A>, closure: F) -> Box<Listener>
where
A: crate::app::Application,
F: Fn(web_sys::$EventType) -> A::Message + 'static,
{
Self::on(crate::window().as_ref(), main, closure)
}
#[doc = "Create and register a kaar callback to "]
#[doc = $event_name]
#[doc = " on the given target"]
pub fn on<A, F>(target: &web_sys::EventTarget, main: &crate::app::WeakMain<A>, closure: F) -> Box<Listener>
where
A: crate::app::Application,
F: Fn(web_sys::$EventType) -> A::Message + 'static,
{
let main = main.clone();
let closure = move |val: web_sys::$EventType| {
main.send_message(closure(val));
};
let closure = Closure::wrap(Box::new(closure) as Box<Fn(web_sys::$EventType)>);
Box::new($EventListener::new($event_name, target, closure))
}
}
#[cfg(not(feature = "message-like-elm"))]
impl $EventName
{
#[doc = "Create and register a kaar callback to "]
#[doc = $event_name]
#[doc = " on the given target"]
pub fn on<F>(target: &web_sys::EventTarget, closure: F) -> Box<Listener>
where F: Fn(web_sys::$EventType) + 'static
{
let closure = Closure::wrap(Box::new(closure) as Box<Fn(web_sys::$EventType)>);
Box::new($EventListener::new($event_name, target, closure))
}
}
)+
)+
};
}
impl_event_helpers! {
FocusEvent FocusEventListener {
Focus => "focus",
Blur => "blur",
}
MouseEvent MouseEventListener {
AuxClick => "auxclick",
Click => "click",
DblClick => "dblclick",
DoubleClick => "dblclick",
MouseEnter => "mouseenter",
MouseOver => "mouseover",
MouseMove => "mousemove",
MouseDown => "mousedown",
MouseUp => "mouseup",
MouseLeave => "mouseleave",
MouseOut => "mouseout",
ContextMenu => "contextmenu",
}
WheelEvent WheelEventListener {
Wheel => "wheel",
}
UiEvent UiEventListener {
UiSelect => "select",
}
InputEvent InputEventListener {
Input => "input",
}
KeyboardEvent KeyboardEventListener {
KeyDown => "keydown",
KeyPress => "keypress",
KeyUp => "keyup",
}
Event EventListener {
Change => "change",
Reset => "reset",
Submit => "submit",
PointerLockChange => "pointerlockchange",
PointerLockError => "pointerlockerror",
}
}