1use std::{fmt::Debug, ops::Deref};
2
3use wasm_bindgen::{convert::FromWasmAbi, prelude::Closure, JsCast, JsValue};
4use web_sys::EventTarget;
5
6#[derive(Debug)]
12pub struct Listener<Element: Deref<Target = EventTarget>, Arg: FromWasmAbi + 'static = JsValue> {
13 element: Element,
14 name: &'static str,
15 cb: Closure<dyn Fn(Arg)>,
16}
17
18impl<Element: Deref<Target = EventTarget>, Arg: FromWasmAbi + 'static> Listener<Element, Arg> {
19 pub fn new<F>(element: Element, name: &'static str, cb: F) -> Self
21 where
22 F: Fn(Arg) + 'static,
23 {
24 let cb = Closure::wrap(Box::new(cb) as Box<dyn Fn(Arg)>);
25
26 element
27 .add_event_listener_with_callback(name, cb.as_ref().unchecked_ref())
28 .unwrap();
29 Self { element, name, cb }
30 }
31
32 pub fn element(&self) -> &Element {
34 &self.element
35 }
36
37 pub fn name(&self) -> &'static str {
39 self.name
40 }
41
42 pub fn callback(&self) -> &Closure<dyn Fn(Arg)> {
44 &self.cb
45 }
46}
47
48impl<Element: Deref<Target = EventTarget>, Arg: FromWasmAbi + 'static> Drop
49 for Listener<Element, Arg>
50{
51 fn drop(&mut self) {
52 self.element
53 .remove_event_listener_with_callback(self.name, self.cb.as_ref().unchecked_ref())
54 .unwrap();
55 }
56}