use wasm_bindgen::prelude::Closure;
use wasm_bindgen::JsCast;
use web_sys::MediaQueryList;
pub(super) struct MediaQueryListHandle {
mql: MediaQueryList,
closure: Closure<dyn FnMut()>,
}
impl MediaQueryListHandle {
pub fn new<F>(window: &web_sys::Window, media_query: &str, mut listener: F) -> Self
where
F: 'static + FnMut(&MediaQueryList),
{
let mql = window
.match_media(media_query)
.expect("Failed to parse media query")
.expect("Found empty media query");
let closure = Closure::new({
let mql = mql.clone();
move || listener(&mql)
});
mql.add_listener_with_opt_callback(Some(closure.as_ref().unchecked_ref()))
.expect("Invalid listener");
Self { mql, closure }
}
pub fn mql(&self) -> &MediaQueryList {
&self.mql
}
}
impl Drop for MediaQueryListHandle {
fn drop(&mut self) {
remove_listener(&self.mql, &self.closure);
}
}
fn remove_listener(mql: &MediaQueryList, listener: &Closure<dyn FnMut()>) {
mql.remove_listener_with_opt_callback(Some(listener.as_ref().unchecked_ref()))
.unwrap_or_else(|e| {
web_sys::console::error_2(&"Error removing media query listener".into(), &e)
});
}