1 use webcore::once::Once;
2 use webcore::value::Value;
3 use webcore::reference_type::ReferenceType;
4 
funcall_adapter< F: FnOnce() >( callback: *mut F )5 extern fn funcall_adapter< F: FnOnce() >( callback: *mut F ) {
6     let callback = unsafe {
7         Box::from_raw( callback )
8     };
9 
10     callback();
11 }
12 
13 /// The `IWindowOrWorker` mixin describes several features common to
14 /// the `Window` and the global scope of web workers.
15 ///
16 /// You most likely don't want to `use` this directly; instead
17 /// you should `use stdweb::traits::*;`.
18 ///
19 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope)
20 // https://html.spec.whatwg.org/#windoworworkerglobalscope
21 pub trait IWindowOrWorker: ReferenceType {
22     /// Sets a timer which executes a function once after the timer expires.
23     ///
24     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)
25     // https://html.spec.whatwg.org/#windoworworkerglobalscope-mixin:dom-settimeout
set_timeout< F: FnOnce() + 'static >( &self, callback: F, timeout: u32 )26     fn set_timeout< F: FnOnce() + 'static >( &self, callback: F, timeout: u32 ) {
27         let callback = Box::into_raw( Box::new( callback ) );
28         __js_raw_asm!( "\
29             Module.STDWEB_PRIVATE.acquire_js_reference( $0 ).setTimeout( function() {\
30                 Module.STDWEB_PRIVATE.dyncall( 'vi', $1, [$2] );\
31             }, $3 );\
32         ", self.as_ref().as_raw(), funcall_adapter::< F > as extern fn( *mut F ), callback, timeout );
33     }
34 
35     /// Sets a timer which executes a function once after the timer expires and can be cleared
36     ///
37     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout)
38     // https://html.spec.whatwg.org/#windoworworkerglobalscope-mixin:dom-settimeout
set_clearable_timeout< F: FnOnce() + 'static >( &self, callback: F, timeout: u32 ) -> TimeoutHandle39     fn set_clearable_timeout< F: FnOnce() + 'static >( &self, callback: F, timeout: u32 ) -> TimeoutHandle {
40         TimeoutHandle(js! (
41             const callback = @{Once(callback)};
42             return {
43                 id: setTimeout(callback, @{timeout}),
44                 callback
45             };
46         ))
47     }
48 }
49 
50 #[derive(Debug)]
51 /// A reference to a timeout object created by set_clearable_timeout
52 pub struct TimeoutHandle(Value);
53 
54 impl TimeoutHandle {
55     /// Clears a timer previously established by set_clearable_timeout
56     ///
57     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout)
58     // https://html.spec.whatwg.org/#windoworworkerglobalscope-mixin:dom-clear-timeout
clear( self )59      pub fn clear( self ) {
60         js! { @(no_return)
61             var val = @{&self.0};
62             clearTimeout(val.id);
63             val.callback.drop();
64         }
65     }
66 }
67