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
use crate::dom::window;
use wasm_bindgen::closure::Closure;
use wasm_bindgen::{JsCast, JsValue};

/// request idle callback handle
pub struct IdleCallbackHandle {
    handle: u32,
    _closure: Closure<dyn FnMut(JsValue)>,
}

/// when dropped, cancel the idle callback
impl Drop for IdleCallbackHandle {
    fn drop(&mut self) {
        window().cancel_idle_callback(self.handle);
    }
}

/// request and idle callback
pub fn request_idle_callback<F>(mut f: F) -> Result<IdleCallbackHandle, JsValue>
where
    F: FnMut(web_sys::IdleDeadline) + 'static,
{
    let closure = Closure::once(move |v: JsValue| {
        let deadline = v
            .dyn_into::<web_sys::IdleDeadline>()
            .expect("must have an idle deadline");
        f(deadline);
    });

    let handle = window().request_idle_callback(closure.as_ref().unchecked_ref())?;
    Ok(IdleCallbackHandle {
        handle,
        _closure: closure,
    })
}