mirror of
https://github.com/servo/servo.git
synced 2025-06-09 00:53:26 +00:00
XHR timeouts use same abstraction as scripts timers. (fixes #3396)
This commit is contained in:
parent
13226f8472
commit
d27a3244f2
6 changed files with 139 additions and 49 deletions
|
@ -7,6 +7,7 @@ use dom::bindings::cell::DOMRefCell;
|
|||
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||
use dom::bindings::global::global_object_for_js_object;
|
||||
use dom::bindings::reflector::Reflectable;
|
||||
use dom::bindings::trace::JSTraceable;
|
||||
use dom::window::ScriptHelpers;
|
||||
use euclid::length::Length;
|
||||
use js::jsapi::{HandleValue, Heap, RootedValue};
|
||||
|
@ -106,6 +107,7 @@ pub enum TimerCallback {
|
|||
enum InternalTimerCallback {
|
||||
StringTimerCallback(DOMString),
|
||||
FunctionTimerCallback(Rc<Function>, Rc<Vec<Heap<JSVal>>>),
|
||||
InternalCallback(Box<ScheduledCallback>),
|
||||
}
|
||||
|
||||
impl HeapSizeOf for InternalTimerCallback {
|
||||
|
@ -115,6 +117,18 @@ impl HeapSizeOf for InternalTimerCallback {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait ScheduledCallback: JSTraceable + HeapSizeOf {
|
||||
fn invoke(self: Box<Self>);
|
||||
|
||||
fn box_clone(&self) -> Box<ScheduledCallback>;
|
||||
}
|
||||
|
||||
impl Clone for Box<ScheduledCallback> {
|
||||
fn clone(&self) -> Box<ScheduledCallback> {
|
||||
self.box_clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveTimers {
|
||||
pub fn new(timer_event_chan: Box<TimerEventChan + Send>,
|
||||
scheduler_chan: Sender<TimerEventRequest>)
|
||||
|
@ -139,15 +153,6 @@ impl ActiveTimers {
|
|||
is_interval: IsInterval,
|
||||
source: TimerSource)
|
||||
-> i32 {
|
||||
// step 3
|
||||
let TimerHandle(new_handle) = self.next_timer_handle.get();
|
||||
self.next_timer_handle.set(TimerHandle(new_handle + 1));
|
||||
|
||||
let timeout = cmp::max(0, timeout);
|
||||
// step 7
|
||||
let duration = self.clamp_duration(Length::new(timeout as u64));
|
||||
let next_call = self.base_time() + duration;
|
||||
|
||||
let callback = match callback {
|
||||
TimerCallback::StringTimerCallback(code_str) =>
|
||||
InternalTimerCallback::StringTimerCallback(code_str),
|
||||
|
@ -165,6 +170,38 @@ impl ActiveTimers {
|
|||
}
|
||||
};
|
||||
|
||||
let timeout = cmp::max(0, timeout);
|
||||
// step 7
|
||||
let duration = self.clamp_duration(Length::new(timeout as u64));
|
||||
|
||||
let TimerHandle(handle) = self.schedule_internal_callback(callback, duration, is_interval, source);
|
||||
handle
|
||||
}
|
||||
|
||||
pub fn schedule_callback(&self,
|
||||
callback: Box<ScheduledCallback>,
|
||||
duration: MsDuration,
|
||||
source: TimerSource) -> TimerHandle {
|
||||
self.schedule_internal_callback(InternalTimerCallback::InternalCallback(callback),
|
||||
duration,
|
||||
IsInterval::NonInterval,
|
||||
source)
|
||||
}
|
||||
|
||||
// see https://html.spec.whatwg.org/multipage/#timer-initialisation-steps
|
||||
fn schedule_internal_callback(&self,
|
||||
callback: InternalTimerCallback,
|
||||
duration: MsDuration,
|
||||
is_interval: IsInterval,
|
||||
source: TimerSource) -> TimerHandle {
|
||||
assert!(self.suspended_since.get().is_none());
|
||||
|
||||
// step 3
|
||||
let TimerHandle(new_handle) = self.next_timer_handle.get();
|
||||
self.next_timer_handle.set(TimerHandle(new_handle + 1));
|
||||
|
||||
let next_call = self.base_time() + duration;
|
||||
|
||||
let timer = Timer {
|
||||
handle: TimerHandle(new_handle),
|
||||
source: source,
|
||||
|
@ -184,11 +221,14 @@ impl ActiveTimers {
|
|||
}
|
||||
|
||||
// step 10
|
||||
new_handle
|
||||
TimerHandle(new_handle)
|
||||
}
|
||||
|
||||
pub fn clear_timeout_or_interval(&self, handle: i32) {
|
||||
let handle = TimerHandle(handle);
|
||||
self.unschedule_callback(TimerHandle(handle));
|
||||
}
|
||||
|
||||
pub fn unschedule_callback(&self, handle: TimerHandle) {
|
||||
let was_next = self.is_next_timer(handle);
|
||||
|
||||
self.timers.borrow_mut().retain(|t| t.handle != handle);
|
||||
|
@ -258,7 +298,10 @@ impl ActiveTimers {
|
|||
}).collect();
|
||||
|
||||
let _ = function.Call_(this, arguments, Report);
|
||||
}
|
||||
},
|
||||
InternalTimerCallback::InternalCallback(callback) => {
|
||||
callback.invoke();
|
||||
},
|
||||
};
|
||||
|
||||
self.nesting_level.set(0);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue