diff options
author | bors-servo <release+servo@mozilla.com> | 2014-04-17 13:34:09 -0400 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-04-17 13:34:09 -0400 |
commit | 7441dae1aff4966e40ef3cf4129f307d23e2eeba (patch) | |
tree | 5d3991722d8444625f6992dd8e49fa44521d691c /src/components/script/dom | |
parent | 8aee787b9f41867a97a8120708cb37cfb23d0278 (diff) | |
parent | b7dcf62ed00b073cfc7728b23bee5540cd76e2aa (diff) | |
download | servo-7441dae1aff4966e40ef3cf4129f307d23e2eeba.tar.gz servo-7441dae1aff4966e40ef3cf4129f307d23e2eeba.zip |
auto merge of #2129 : lpy/servo/issue2116, r=jdm
see #2116
I add an `is_interval` field, so that when the `TimerData` is passed by `SetInterval`, we will not delete it from `active_timers`.
Also I think maybe we can extract the code in `ClearTimeout` and `ClearInterval` into another method to avoid duplicate.
Diffstat (limited to 'src/components/script/dom')
-rw-r--r-- | src/components/script/dom/webidls/Window.webidl | 2 | ||||
-rw-r--r-- | src/components/script/dom/window.rs | 52 |
2 files changed, 44 insertions, 10 deletions
diff --git a/src/components/script/dom/webidls/Window.webidl b/src/components/script/dom/webidls/Window.webidl index 0260324b91e..2405055c15c 100644 --- a/src/components/script/dom/webidls/Window.webidl +++ b/src/components/script/dom/webidls/Window.webidl @@ -71,6 +71,8 @@ interface WindowTimers { //XXXjdm No support for Function or variadic arguments yet long setTimeout(any handler, optional long timeout = 0/*, any... arguments*/); void clearTimeout(optional long handle = 0); + long setInterval(any handler, optional long timeout = 0/*, any... arguments*/); + void clearInterval(optional long handler = 0); /*long setTimeout(DOMString handler, optional long timeout = 0, any... arguments); long setInterval(Function handler, optional long timeout = 0, any... arguments); long setInterval(DOMString handler, optional long timeout = 0, any... arguments); diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs index 9ba9d00da82..a0b7ef3740b 100644 --- a/src/components/script/dom/window.rs +++ b/src/components/script/dom/window.rs @@ -128,6 +128,7 @@ impl Drop for Window { // to the function when calling it) pub struct TimerData { handle: i32, + is_interval: bool, funval: JSVal, args: ~[JSVal], } @@ -226,7 +227,7 @@ impl Reflectable for Window { } impl Window { - pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { + fn set_timeout_or_interval(&mut self, callback: JSVal, timeout: i32, is_interval: bool) -> i32 { let timeout = cmp::max(0, timeout) as u64; let handle = self.next_timer_handle; self.next_timer_handle += 1; @@ -236,9 +237,18 @@ impl Window { let tm = Timer::new().unwrap(); let (cancel_chan, cancel_port) = channel(); let chan = self.extra.timer_chan.clone(); - spawn_named("Window:SetTimeout", proc() { + let spawn_name = if is_interval { + "Window:SetInterval" + } else { + "Window:SetTimeout" + }; + spawn_named(spawn_name, proc() { let mut tm = tm; - let timeout_port = tm.oneshot(timeout); + let timeout_port = if is_interval { + tm.periodic(timeout) + } else { + tm.oneshot(timeout) + }; let cancel_port = cancel_port; let select = Select::new(); @@ -246,19 +256,33 @@ impl Window { unsafe { timeout_handle.add() }; let mut cancel_handle = select.handle(&cancel_port); unsafe { cancel_handle.add() }; - let id = select.wait(); - if id == timeout_handle.id() { - chan.send(TimerMessageFire(~TimerData { - handle: handle, - funval: callback, - args: ~[], - })); + + loop { + let id = select.wait(); + if id == timeout_handle.id() { + timeout_port.recv(); + chan.send(TimerMessageFire(~TimerData { + handle: handle, + is_interval: is_interval, + funval: callback, + args: ~[], + })); + if !is_interval { + break; + } + } else if id == cancel_handle.id() { + break; + } } }); self.active_timers.insert(handle, TimerHandle { handle: handle, cancel_chan: Some(cancel_chan) }); handle } + pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { + self.set_timeout_or_interval(callback, timeout, false) + } + pub fn ClearTimeout(&mut self, handle: i32) { let timer_handle = self.active_timers.pop(&handle); match timer_handle { @@ -267,6 +291,14 @@ impl Window { } } + pub fn SetInterval(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 { + self.set_timeout_or_interval(callback, timeout, true) + } + + pub fn ClearInterval(&mut self, handle: i32) { + self.ClearTimeout(handle); + } + pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) { // FIXME This should probably be ReflowForQuery, not Display. All queries currently // currently rely on the display list, which means we can't destroy it by |