diff options
Diffstat (limited to 'components/script/script_task.rs')
-rw-r--r-- | components/script/script_task.rs | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 7ae23dba2a2..e01a8caff39 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -29,9 +29,7 @@ use dom::worker::{Worker, TrustedWorkerAddress}; use dom::xmlhttprequest::{TrustedXHRAddress, XMLHttpRequest, XHRProgress}; use html::hubbub_html_parser::{InputString, InputUrl, HtmlParserResult, HtmlDiscoveredScript}; use html::hubbub_html_parser; -use layout_interface::{ScriptLayoutChan, LayoutChan, MatchSelectorsDocumentDamage}; -use layout_interface::{ReflowDocumentDamage, ReflowForDisplay}; -use layout_interface::ContentChangedDocumentDamage; +use layout_interface::{ScriptLayoutChan, LayoutChan, ReflowForDisplay}; use layout_interface; use page::{Page, IterablePage, Frame}; @@ -52,6 +50,7 @@ use servo_msg::constellation_msg; use servo_net::image_cache_task::ImageCacheTask; use servo_net::resource_task::ResourceTask; use servo_util::geometry::to_frac_px; +use servo_util::smallvec::{SmallVec1, SmallVec}; use servo_util::task::spawn_named_with_send_on_failure; use geom::point::Point2D; @@ -66,6 +65,7 @@ use url::Url; use libc::size_t; use std::any::{Any, AnyRefExt}; use std::cell::RefCell; +use std::collections::HashSet; use std::comm::{channel, Sender, Receiver, Select}; use std::mem::replace; use std::rc::Rc; @@ -445,7 +445,9 @@ impl ScriptTask { } }; - // Squash any pending resize events in the queue. + let mut needs_reflow = HashSet::new(); + + // Squash any pending resize and reflow events in the queue. loop { match event { // This has to be handled before the ResizeMsg below, @@ -459,6 +461,13 @@ impl ScriptTask { let page = page.find(id).expect("resize sent to nonexistent pipeline"); page.resize_event.set(Some(size)); } + FromConstellation(SendEventMsg(id, ReflowEvent(node_addresses))) => { + let mut page = self.page.borrow_mut(); + let inner_page = page.find(id).expect("Reflow sent to nonexistent pipeline"); + let mut pending = inner_page.pending_dirty_nodes.borrow_mut(); + pending.push_all_move(node_addresses); + needs_reflow.insert(id); + } _ => { sequential.push(event); } @@ -507,6 +516,11 @@ impl ScriptTask { } } + // Now process any pending reflows. + for id in needs_reflow.into_iter() { + self.handle_event(id, ReflowEvent(SmallVec1::new())); + } + true } @@ -632,8 +646,7 @@ impl ScriptTask { if page.pending_reflows.get() > 0 { page.pending_reflows.set(0); - page.damage(MatchSelectorsDocumentDamage); - page.reflow(ReflowForDisplay, self.control_chan.clone(), &*self.compositor); + self.force_reflow(&*page); } } @@ -711,8 +724,7 @@ impl ScriptTask { Some((ref loaded, needs_reflow)) if *loaded == url => { *page.mut_url() = Some((loaded.clone(), false)); if needs_reflow { - page.damage(ContentChangedDocumentDamage); - page.reflow(ReflowForDisplay, self.control_chan.clone(), &*self.compositor); + self.force_reflow(&*page); } return; }, @@ -796,7 +808,11 @@ impl ScriptTask { // Kick off the initial reflow of the page. debug!("kicking off initial reflow of {}", url); - document.content_changed(); + { + let document_js_ref = (&*document).clone(); + let document_as_node = NodeCast::from_ref(document_js_ref); + document.content_changed(document_as_node); + } window.flush_layout(ReflowForDisplay); { @@ -856,6 +872,21 @@ impl ScriptTask { self.compositor.scroll_fragment_point(pipeline_id, LayerId::null(), point); } + fn force_reflow(&self, page: &Page) { + { + let mut pending = page.pending_dirty_nodes.borrow_mut(); + let js_runtime = self.js_runtime.deref().ptr; + + for untrusted_node in pending.into_iter() { + let node = node::from_untrusted_node_address(js_runtime, untrusted_node).root(); + node.dirty(); + } + } + + page.damage(); + page.reflow(ReflowForDisplay, self.control_chan.clone(), &*self.compositor); + } + /// This is the main entry point for receiving and dispatching DOM events. /// /// TODO: Actually perform DOM event dispatch. @@ -870,8 +901,7 @@ impl ScriptTask { let frame = page.frame(); if frame.is_some() { - page.damage(ReflowDocumentDamage); - page.reflow(ReflowForDisplay, self.control_chan.clone(), &*self.compositor) + self.force_reflow(&*page); } let fragment_node = @@ -906,8 +936,9 @@ impl ScriptTask { } // FIXME(pcwalton): This reflows the entire document and is not incremental-y. - ReflowEvent => { + ReflowEvent(to_dirty) => { debug!("script got reflow event"); + assert_eq!(to_dirty.len(), 0); let page = get_page(&*self.page.borrow(), pipeline_id); let frame = page.frame(); if frame.is_some() { @@ -915,8 +946,7 @@ impl ScriptTask { if in_layout { page.pending_reflows.set(page.pending_reflows.get() + 1); } else { - page.damage(MatchSelectorsDocumentDamage); - page.reflow(ReflowForDisplay, self.control_chan.clone(), &*self.compositor) + self.force_reflow(&*page); } } } @@ -1021,8 +1051,7 @@ impl ScriptTask { if target_compare { if mouse_over_targets.is_some() { - page.damage(MatchSelectorsDocumentDamage); - page.reflow(ReflowForDisplay, self.control_chan.clone(), &*self.compositor); + self.force_reflow(&*page); } *mouse_over_targets = Some(target_list); } |