script: Reflow 200 milliseconds after the <body> is parsed, like Gecko

does.
This commit is contained in:
Patrick Walton 2015-05-12 17:09:04 -07:00
parent 8759d42559
commit 9e34e82aec
5 changed files with 65 additions and 7 deletions

View file

@ -148,6 +148,8 @@ pub struct Document {
loader: DOMRefCell<DocumentLoader>,
/// The current active HTML parser, to allow resuming after interruptions.
current_parser: MutNullableHeap<JS<ServoHTMLParser>>,
/// When we should kick off a reflow. This happens during parsing.
reflow_timeout: Cell<Option<u64>>,
}
impl DocumentDerived for EventTarget {
@ -226,6 +228,9 @@ pub trait DocumentHelpers<'a> {
fn set_encoding_name(self, name: DOMString);
fn content_changed(self, node: JSRef<Node>, damage: NodeDamage);
fn content_and_heritage_changed(self, node: JSRef<Node>, damage: NodeDamage);
fn reflow_if_reflow_timer_expired(self);
fn set_reflow_timeout(self, timeout: u64);
fn disarm_reflow_timeout(self);
fn unregister_named_element(self, to_unregister: JSRef<Element>, id: Atom);
fn register_named_element(self, element: JSRef<Element>, id: Atom);
fn load_anchor_href(self, href: DOMString);
@ -343,11 +348,42 @@ impl<'a> DocumentHelpers<'a> for JSRef<'a, Document> {
}
fn content_and_heritage_changed(self, node: JSRef<Node>, damage: NodeDamage) {
debug!("content_and_heritage_changed on {}", node.debug_str());
node.force_dirty_ancestors(damage);
node.dirty(damage);
}
/// Reflows and disarms the timer if the reflow timer has expired.
fn reflow_if_reflow_timer_expired(self) {
if let Some(reflow_timeout) = self.reflow_timeout.get() {
if time::precise_time_ns() < reflow_timeout {
return
}
self.reflow_timeout.set(None);
let window = self.window.root();
window.r().reflow(ReflowGoal::ForDisplay,
ReflowQueryType::NoQuery,
ReflowReason::RefreshTick);
}
}
/// Schedules a reflow to be kicked off at the given `timeout` (in `time::precise_time_ns()`
/// units). This reflow happens even if the event loop is busy. This is used to display initial
/// page content during parsing.
fn set_reflow_timeout(self, timeout: u64) {
if let Some(existing_timeout) = self.reflow_timeout.get() {
if existing_timeout > timeout {
return
}
}
self.reflow_timeout.set(Some(timeout))
}
/// Disables any pending reflow timeouts.
fn disarm_reflow_timeout(self) {
self.reflow_timeout.set(None)
}
/// Remove any existing association between the provided id and any elements in this document.
fn unregister_named_element(self,
to_unregister: JSRef<Element>,
@ -1004,6 +1040,7 @@ impl Document {
animation_frame_list: RefCell::new(HashMap::new()),
loader: DOMRefCell::new(doc_loader),
current_parser: Default::default(),
reflow_timeout: Cell::new(None),
}
}