mika 0.0.0

A framework for building wasm front-end web application in Rust
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())");
                }
            }
            // All events that emit with an $EventType argument
            $(
                #[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))
                    }
                }
                //impl $EventType for $EventName {}
                #[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",
    }
}