1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use seed::prelude::*;
use wasm_bindgen::JsCast;

pub struct Events<Msg> {
    pub events: Vec<EventHandler<Msg>>,
}

impl<Msg> Clone for Events<Msg> {
    fn clone(&self) -> Self {
        Self {
            events: self.events.clone(),
        }
    }
}

impl<Msg> Default for Events<Msg> {
    fn default() -> Self {
        Self { events: vec![] }
    }
}

impl<Msg> UpdateEl<El<Msg>> for Events<Msg> {
    fn update(self, el: &mut El<Msg>) {
        self.events.update(el)
    }
}

macro mouse_events( $( $event:ident: $ty:ty { $( $(#[$doc:meta])? $name:ident = $ev:expr $(,)? )* } $(,)? )* ) {
    $(
        impl<Msg> Events<Msg> {
            $(
                $( #[$doc] )?
                pub fn $name(
                    &mut self,
                    handler: impl FnOnce($ty) -> Msg + 'static + Clone,
                ) -> &mut Self {
                    self.events.push($event($ev, handler));
                    self
                }
            )*
        }
    )*
}

mouse_events! {
    ev: web_sys::Event {
        load = Ev::Load,
        unload = Ev::Unload,
        abort = Ev::Abort,
        error = Ev::Error,
        select = Ev::Select,
    }
    focus_ev: web_sys::FocusEvent {
        blur = Ev::Blur,
        focus = Ev::Focus,
        focus_in = Ev::from("focusin"),
        focus_out = Ev::from("focusout"),
    }
    mouse_ev: web_sys::MouseEvent {
        aux_click = Ev::AuxClick,
        click = Ev::Click,
        double_click = Ev::DblClick,
        mouse_down = Ev::MouseDown,
        mouse_enter = Ev::MouseEnter,
        mouse_leave = Ev::MouseLeave,
        mouse_move = Ev::MouseMove,
        mouse_out = Ev::MouseOut,
        mouse_over = Ev::MouseOver,
        mouse_up = Ev::MouseUp,
    }
    pointer_ev: web_sys::PointerEvent {
        pointer_cancel = Ev::PointerCancel,
        pointer_down = Ev::PointerDown,
        pointer_enter = Ev::PointerEnter,
        pointer_leave = Ev::PointerLeave,
        pointer_move = Ev::PointerMove,
        pointer_out = Ev::PointerOut,
        pointer_over = Ev::PointerOver,
        pointer_up = Ev::PointerUp,
        lost_pointer_capture = Ev::LostPointerCapture,
        got_pointer_capture = Ev::GotPointerCapture,
    }
    wheel_ev: web_sys::WheelEvent {
        wheel = Ev::Wheel,
    }
    // NOTE: that `InputEvent` doesn't provied access to data property yet, use
    // seed::browser::util::{get_value, set_value} access these value for now.
    input_ev: web_sys::InputEvent {
        before_input = Ev::from("beforeinput")
        input = Ev::Input,
    }
    keyboard_ev: web_sys::KeyboardEvent {
        key_down = Ev::KeyDown,
        key_up = Ev::KeyUp,
    }
    composition_ev: web_sys::CompositionEvent {
        composition_start = Ev::CompositionStart,
        composition_update = Ev::CompositionUpdate,
        composition_end = Ev::CompositionEnd,
    }
    drag_ev: web_sys::DragEvent {
        drag = Ev::Drag,
        drag_end = Ev::DragEnd,
        drag_enter = Ev::DragEnter,
        drag_leave = Ev::DragLeave,
        drag_over = Ev::DragOver,
        drag_start = Ev::DragStart,
        drop = Ev::Drop,
    }
}

macro event_creator( $( $(#[$doc:meta])? $name:ident($ty:ty) $(,)? )* ) {
    $(
        $( #[$doc] )?
        fn $name<Ms>(
            trigger: impl Into<Ev>,
            handler: impl FnOnce($ty) -> Ms + 'static + Clone,
        ) -> EventHandler<Ms> {
            let closure_handler = move |event: web_sys::Event| {
                (handler.clone())(event.dyn_ref::<$ty>().unwrap().clone())
            };
            EventHandler::new(trigger, closure_handler)
        }
    )*
}

event_creator! {
    /// create `EventHandler` with `web_sys::WheelEvent`
    wheel_ev(web_sys::WheelEvent),
    /// create `EventHandler` with `web_sys::CompositionEvent`
    composition_ev(web_sys::CompositionEvent),
    /// create `EventHandler` with `web_sys::FocusEvent`
    focus_ev(web_sys::FocusEvent),
    /// create `EventHandler` with `web_sys::DragEvent`
    drag_ev(web_sys::DragEvent),
    /// create `EventHandler` with `web_sys::InputEvent`
    input_ev(web_sys::InputEvent)
}