sauron_core/dom/
window.rs1use crate::dom::{dom_node::intern, util, window, Cmd};
2use futures::channel::mpsc;
3use wasm_bindgen::{prelude::*, JsCast};
4use web_sys::MouseEvent;
5
6#[derive(Clone, Copy)]
8pub struct Window;
9
10impl Window {
11 pub fn on_resize<F, MSG>(mut cb: F) -> Cmd<MSG>
14 where
15 F: FnMut(i32, i32) -> MSG + Clone + 'static,
16 MSG: 'static,
17 {
18 let (mut tx, rx) = mpsc::unbounded();
19 let resize_callback: Closure<dyn FnMut(web_sys::Event)> =
20 Closure::new(move |_e: web_sys::Event| {
21 let (w, h) = util::get_window_size();
22 let msg = cb(w, h);
23 tx.start_send(msg).expect("send");
24 });
25 window()
26 .add_event_listener_with_callback(
27 intern("resize"),
28 resize_callback.as_ref().unchecked_ref(),
29 )
30 .expect("add event callback");
31
32 Cmd::recurring(rx, resize_callback)
33 }
34
35 pub fn on_mousemove<F, MSG>(mut cb: F) -> Cmd<MSG>
37 where
38 F: FnMut(web_sys::MouseEvent) -> MSG + Clone + 'static,
39 MSG: 'static,
40 {
41 let (mut tx, rx) = mpsc::unbounded();
42 let mousemove_cb: Closure<dyn FnMut(web_sys::Event)> =
43 Closure::new(move |event: web_sys::Event| {
44 let mouse_event: MouseEvent = event.dyn_into().expect("must be mouse event");
45 let msg = cb(mouse_event);
46 tx.start_send(msg).expect("send");
47 });
48 window()
49 .add_event_listener_with_callback(
50 intern("mousemove"),
51 mousemove_cb.as_ref().unchecked_ref(),
52 )
53 .expect("add event callback");
54 Cmd::recurring(rx, mousemove_cb)
55 }
56
57 pub fn on_mouseup<F, MSG>(mut cb: F) -> Cmd<MSG>
59 where
60 F: FnMut(web_sys::MouseEvent) -> MSG + Clone + 'static,
61 MSG: 'static,
62 {
63 let (mut tx, rx) = mpsc::unbounded();
64 let mousemove_cb: Closure<dyn FnMut(web_sys::Event)> =
65 Closure::new(move |event: web_sys::Event| {
66 let mouse_event: MouseEvent = event.dyn_into().expect("must be mouse event");
67 let msg = cb(mouse_event);
68 tx.start_send(msg).expect("send");
69 });
70 window()
71 .add_event_listener_with_callback(
72 intern("mouseup"),
73 mousemove_cb.as_ref().unchecked_ref(),
74 )
75 .expect("add event callback");
76 Cmd::recurring(rx, mousemove_cb)
77 }
78
79 pub fn on_mousedown<F, MSG>(mut cb: F) -> Cmd<MSG>
81 where
82 F: FnMut(web_sys::MouseEvent) -> MSG + Clone + 'static,
83 MSG: 'static,
84 {
85 let (mut tx, rx) = mpsc::unbounded();
86 let mousemove_cb: Closure<dyn FnMut(web_sys::Event)> =
87 Closure::new(move |event: web_sys::Event| {
88 let mouse_event: MouseEvent = event.dyn_into().expect("must be mouse event");
89 let msg = cb(mouse_event);
90 tx.start_send(msg).expect("send");
91 });
92 window()
93 .add_event_listener_with_callback(
94 intern("mousedown"),
95 mousemove_cb.as_ref().unchecked_ref(),
96 )
97 .expect("add event callback");
98 Cmd::recurring(rx, mousemove_cb)
99 }
100
101 pub fn on_click<F, MSG>(mut cb: F) -> Cmd<MSG>
103 where
104 F: FnMut(web_sys::MouseEvent) -> MSG + Clone + 'static,
105 MSG: 'static,
106 {
107 let (mut tx, rx) = mpsc::unbounded();
108 let mousemove_cb: Closure<dyn FnMut(web_sys::Event)> =
109 Closure::new(move |event: web_sys::Event| {
110 let mouse_event: MouseEvent = event.dyn_into().expect("must be mouse event");
111 let msg = cb(mouse_event);
112 tx.start_send(msg).expect("send");
113 });
114 window()
115 .add_event_listener_with_callback(
116 intern("click"),
117 mousemove_cb.as_ref().unchecked_ref(),
118 )
119 .expect("add event callback");
120 Cmd::recurring(rx, mousemove_cb)
121 }
122
123 pub fn on_keyup<F, MSG>(mut cb: F) -> Cmd<MSG>
125 where
126 F: FnMut(web_sys::KeyboardEvent) -> MSG + Clone + 'static,
127 MSG: 'static,
128 {
129 let (mut tx, rx) = mpsc::unbounded();
130 let closure_cb: Closure<dyn FnMut(web_sys::Event)> =
131 Closure::new(move |event: web_sys::Event| {
132 let key_event: web_sys::KeyboardEvent =
133 event.dyn_into().expect("must be key event");
134 let msg = cb(key_event);
135 tx.start_send(msg).expect("send");
136 });
137 window()
138 .add_event_listener_with_callback(intern("keyup"), closure_cb.as_ref().unchecked_ref())
139 .expect("add event callback");
140 Cmd::recurring(rx, closure_cb)
141 }
142
143 pub fn on_keydown<F, MSG>(mut cb: F) -> Cmd<MSG>
145 where
146 F: FnMut(web_sys::KeyboardEvent) -> MSG + Clone + 'static,
147 MSG: 'static,
148 {
149 let (mut tx, rx) = mpsc::unbounded();
150 let closure_cb: Closure<dyn FnMut(web_sys::Event)> =
151 Closure::new(move |event: web_sys::Event| {
152 let key_event: web_sys::KeyboardEvent =
153 event.dyn_into().expect("must be key event");
154 let msg = cb(key_event);
155 tx.start_send(msg).expect("send");
156 });
157 window()
158 .add_event_listener_with_callback(
159 intern("keydown"),
160 closure_cb.as_ref().unchecked_ref(),
161 )
162 .expect("add event callback");
163 Cmd::recurring(rx, closure_cb)
164 }
165
166 pub fn scroll_to_top<MSG>(msg: MSG) -> Cmd<MSG>
168 where
169 MSG: 'static,
170 {
171 use std::future::ready;
172 Cmd::once(ready({
173 util::scroll_window_to_top();
174 msg
175 }))
176 }
177
178 pub fn on_popstate<F, MSG>(mut cb: F) -> Cmd<MSG>
180 where
181 F: FnMut(web_sys::PopStateEvent) -> MSG + 'static,
182 MSG: 'static,
183 {
184 let (mut tx, rx) = mpsc::unbounded();
185 let closure_cb: Closure<dyn FnMut(web_sys::Event)> =
186 Closure::new(move |event: web_sys::Event| {
187 let popstate_event: web_sys::PopStateEvent =
188 event.dyn_into().expect("popstate event");
189 let msg = cb(popstate_event);
190 tx.start_send(msg).expect("send");
191 });
192 window()
193 .add_event_listener_with_callback(
194 intern("popstate"),
195 closure_cb.as_ref().unchecked_ref(),
196 )
197 .expect("add event callback");
198 Cmd::recurring(rx, closure_cb)
199 }
200}