silkenweb_base/
lib.rs

1use wasm_bindgen::UnwrapThrowExt;
2
3pub mod window {
4    use js_sys::Function;
5    use wasm_bindgen::{JsValue, UnwrapThrowExt};
6
7    use super::WINDOW;
8
9    pub fn request_animation_frame(callback: &::js_sys::Function) {
10        WINDOW.with(|win| win.request_animation_frame(callback).unwrap_throw());
11    }
12
13    pub fn history() -> web_sys::History {
14        WINDOW.with(|win| win.history().unwrap_throw())
15    }
16
17    pub fn location() -> web_sys::Location {
18        WINDOW.with(|win| win.location())
19    }
20
21    pub fn set_onpopstate(value: Option<&Function>) {
22        WINDOW.with(|win| win.set_onpopstate(value));
23    }
24
25    pub fn local_storage() -> Result<web_sys::Storage, JsValue> {
26        WINDOW.with(|w| w.local_storage().map(|w| w.unwrap_throw()))
27    }
28
29    pub fn session_storage() -> Result<web_sys::Storage, JsValue> {
30        WINDOW.with(|w| w.session_storage().map(|w| w.unwrap_throw()))
31    }
32
33    pub fn performance() -> Option<web_sys::Performance> {
34        WINDOW.with(|w| w.performance())
35    }
36}
37
38pub mod document {
39    use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
40    use web_sys::HtmlBaseElement;
41
42    use super::DOCUMENT;
43
44    pub fn get_element_by_id(id: &str) -> Option<web_sys::Element> {
45        DOCUMENT.with(|doc| doc.get_element_by_id(id))
46    }
47
48    pub fn create_element(tag: &str) -> web_sys::Element {
49        DOCUMENT.with(|doc| doc.create_element(tag).unwrap_throw())
50    }
51
52    pub fn create_element_ns(namespace: &str, tag: &str) -> web_sys::Element {
53        DOCUMENT.with(|doc| doc.create_element_ns(Some(namespace), tag).unwrap_throw())
54    }
55
56    pub fn create_text_node(text: &str) -> web_sys::Text {
57        DOCUMENT.with(|doc| doc.create_text_node(text))
58    }
59
60    pub fn base_uri() -> Option<String> {
61        DOCUMENT
62            .with(|doc| doc.query_selector("base[href]"))
63            .unwrap_throw()
64            .map(|base_elem| {
65                base_elem
66                    .dyn_into::<HtmlBaseElement>()
67                    .unwrap_throw()
68                    .href()
69            })
70    }
71
72    pub fn query_selector(selectors: &str) -> Result<Option<web_sys::Element>, JsValue> {
73        DOCUMENT.with(|doc| doc.query_selector(selectors))
74    }
75
76    pub fn head() -> Option<web_sys::HtmlHeadElement> {
77        DOCUMENT.with(|doc| doc.head())
78    }
79
80    pub fn body() -> Option<web_sys::HtmlElement> {
81        DOCUMENT.with(|doc| doc.body())
82    }
83}
84
85pub trait GlobalEventTarget {
86    fn add_event_listener_with_callback(name: &'static str, listener: &::js_sys::Function);
87
88    fn remove_event_listener_with_callback(name: &'static str, listener: &::js_sys::Function);
89}
90
91pub struct Document;
92
93impl GlobalEventTarget for Document {
94    fn add_event_listener_with_callback(name: &'static str, listener: &::js_sys::Function) {
95        DOCUMENT.with(|doc| {
96            doc.add_event_listener_with_callback(name, listener)
97                .unwrap_throw()
98        })
99    }
100
101    fn remove_event_listener_with_callback(name: &'static str, listener: &::js_sys::Function) {
102        DOCUMENT.with(|doc| {
103            doc.remove_event_listener_with_callback(name, listener)
104                .unwrap_throw()
105        })
106    }
107}
108
109pub struct Window;
110
111impl GlobalEventTarget for Window {
112    fn add_event_listener_with_callback(name: &'static str, listener: &::js_sys::Function) {
113        WINDOW.with(|win| {
114            win.add_event_listener_with_callback(name, listener)
115                .unwrap_throw()
116        })
117    }
118
119    fn remove_event_listener_with_callback(name: &'static str, listener: &::js_sys::Function) {
120        WINDOW.with(|win| {
121            win.remove_event_listener_with_callback(name, listener)
122                .unwrap_throw()
123        })
124    }
125}
126
127thread_local!(
128    static WINDOW: web_sys::Window = web_sys::window().expect_throw("Window must be available");
129    static DOCUMENT: web_sys::Document = WINDOW.with(|win| {
130        win.document()
131            .expect_throw("Window must contain a document")
132    });
133);