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
use crate::{Cmd, Component, Dispatch};
use std::fmt::Debug;
use wasm_bindgen::{closure::Closure, JsCast};
use web_sys::ScrollToOptions;
#[derive(Copy, Clone, Debug)]
pub struct Browser;
impl Browser {
pub fn on_resize<F, APP, MSG>(cb: F) -> Cmd<APP, MSG>
where
F: Fn(i32, i32) -> MSG + Clone + 'static,
MSG: 'static,
APP: Component<MSG> + 'static,
{
let cmd: Cmd<APP, MSG> = Cmd::new(move |program| {
let cb_clone = cb.clone();
let resize_callback: Closure<dyn Fn(web_sys::Event)> =
Closure::wrap(Box::new(move |_| {
let (window_width, window_height) = Self::get_size();
let msg = cb_clone(window_width, window_height);
program.dispatch(msg);
}));
crate::window()
.set_onresize(Some(resize_callback.as_ref().unchecked_ref()));
resize_callback.forget();
});
cmd
}
pub fn on_hashchange<F, APP, MSG>(cb: F) -> Cmd<APP, MSG>
where
F: Fn(String) -> MSG + Clone + 'static,
MSG: 'static,
APP: Component<MSG> + 'static,
{
let cmd: Cmd<APP, MSG> = Cmd::new(move |program| {
let cb_clone = cb.clone();
let hashchange_callback: Closure<dyn Fn(web_sys::Event)> =
Closure::wrap(Box::new(move |_| {
let hash = Self::get_hash();
let msg = cb_clone(hash);
program.dispatch(msg);
}));
crate::window().set_onhashchange(Some(
hashchange_callback.as_ref().unchecked_ref(),
));
hashchange_callback.forget();
});
cmd
}
pub fn get_size() -> (i32, i32) {
let window = crate::window();
let window_width = window
.inner_width()
.expect("unable to get window width")
.as_f64()
.expect("cant convert to f64");
let window_height = window
.inner_height()
.expect("unable to get height")
.as_f64()
.expect("cant convert to f64");
(window_width as i32, window_height as i32)
}
pub fn get_hash() -> String {
let window = crate::window();
let hash = window.location().hash().expect("must have a hash");
hash
}
pub fn scroll_to_top() {
let mut options = ScrollToOptions::new();
options.top(0.0);
options.left(0.0);
crate::window().scroll_to_with_scroll_to_options(&options);
}
}