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
use crate::{
    dom::created_node::create_closure_wrap, Attribute, Cmd, Component,
};
use std::fmt::Debug;
use wasm_bindgen::{self, prelude::*, JsCast};
use web_sys::EventTarget;

/// Provides access to the Browser window
#[derive(Copy, Clone, Debug)]
pub struct Window;

impl Window {
    /// attach an event listender to the window
    pub fn add_event_listeners<APP, MSG>(
        event_listeners: Vec<Attribute<MSG>>,
    ) -> Cmd<APP, MSG>
    where
        APP: Component<MSG> + 'static,
        MSG: 'static,
    {
        Cmd::new(move |program| {
            let window = crate::window();
            let window: &EventTarget = window
                .dyn_ref()
                .expect("unable to cast window to event target");

            for event_attr in event_listeners.iter() {
                let event_str = event_attr.name();
                for event_cb in event_attr.value() {
                    let callback =
                        event_cb.get_callback().expect("expecting a callback");

                    let closure_wrap: Closure<dyn FnMut(web_sys::Event)> =
                        create_closure_wrap(&program, &callback);
                    window
                        .add_event_listener_with_callback(
                            event_str,
                            closure_wrap.as_ref().unchecked_ref(),
                        )
                        .expect("Unable to attached event listener");

                    closure_wrap.forget();
                }
            }
        })
    }

    /// set the title of the document
    pub fn set_title(title: &str) {
        crate::document().set_title(title);
    }
}