Fix #3936 – {Window,WorkerGlobalScope}.set{Timeout,Interval}(DOMString)

This commit is contained in:
Guillaume Bort 2014-11-19 12:06:36 +01:00
parent ca876edc05
commit 5fe3a3e54f
16 changed files with 126 additions and 55 deletions

View file

@ -8,9 +8,12 @@ use dom::bindings::codegen::Bindings::FunctionBinding::Function;
use dom::bindings::js::JSRef;
use dom::bindings::utils::Reflectable;
use dom::window::ScriptHelpers;
use script_task::{ScriptChan, ScriptMsg, TimerSource};
use servo_util::task::spawn_named;
use servo_util::str::DOMString;
use js::jsval::JSVal;
@ -35,6 +38,13 @@ struct TimerHandle {
cancel_chan: Option<Sender<()>>,
}
#[jstraceable]
#[deriving(Clone)]
pub enum TimerCallback {
StringTimerCallback(DOMString),
FunctionTimerCallback(Function)
}
impl Hash for TimerId {
fn hash(&self, state: &mut sip::SipState) {
let TimerId(id) = *self;
@ -82,7 +92,7 @@ pub enum IsInterval {
#[deriving(Clone)]
struct TimerData {
is_interval: IsInterval,
funval: Function,
callback: TimerCallback,
args: Vec<JSVal>
}
@ -95,7 +105,7 @@ impl TimerManager {
}
pub fn set_timeout_or_interval(&self,
callback: Function,
callback: TimerCallback,
arguments: Vec<JSVal>,
timeout: i32,
is_interval: IsInterval,
@ -151,7 +161,7 @@ impl TimerManager {
cancel_chan: Some(cancel_chan),
data: TimerData {
is_interval: is_interval,
funval: callback,
callback: callback,
args: arguments
}
};
@ -163,7 +173,7 @@ impl TimerManager {
let mut timer_handle = self.active_timers.borrow_mut().remove(&TimerId(handle));
match timer_handle {
Some(ref mut handle) => handle.cancel(),
None => { }
None => {}
}
}
@ -175,7 +185,14 @@ impl TimerManager {
};
// TODO: Must handle rooting of funval and args when movable GC is turned on
let _ = data.funval.Call_(this, data.args, ReportExceptions);
match data.callback {
TimerCallback::FunctionTimerCallback(function) => {
let _ = function.Call_(this, data.args, ReportExceptions);
}
TimerCallback::StringTimerCallback(code_str) => {
this.evaluate_js_on_global_with_result(code_str.as_slice());
}
};
if data.is_interval == IsInterval::NonInterval {
self.active_timers.borrow_mut().remove(&timer_id);