diff options
Diffstat (limited to 'src/components/main/layout/layout_task.rs')
-rw-r--r-- | src/components/main/layout/layout_task.rs | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index b8e8b022c9a..0fdacec78ad 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -23,6 +23,7 @@ use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode}; use extra::url::Url; use extra::arc::{Arc, MutexArc}; +use geom::point::Point2D; use geom::rect::Rect; use geom::size::Size2D; use gfx::display_list::{ClipDisplayItemClass, DisplayItem, DisplayItemIterator}; @@ -211,7 +212,11 @@ impl<'a> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.assign_height(self.layout_context); - flow.store_overflow(self.layout_context); + // Skip store-overflow for absolutely positioned flows. That will be + // done in a separate traversal. + if !flow.is_store_overflow_delayed() { + flow.store_overflow(self.layout_context); + } true } @@ -276,7 +281,7 @@ impl LayoutTask { chan: LayoutChan, constellation_chan: ConstellationChan, script_chan: ScriptChan, - render_chan: RenderChan<OpaqueNode>, + render_chan: RenderChan<OpaqueNode>, image_cache_task: ImageCacheTask, opts: &Opts, profiler_chan: ProfilerChan) @@ -402,7 +407,7 @@ impl LayoutTask { /// crash. fn exit_now(&mut self) { let (response_port, response_chan) = Chan::new(); - + match self.parallel_traversal { None => {} Some(ref mut traversal) => traversal.shutdown(), @@ -426,7 +431,17 @@ impl LayoutTask { None => fail!("no layout data for root node"), }; let mut flow = match result { - FlowConstructionResult(flow) => flow, + FlowConstructionResult(mut flow, abs_descendants, fixed_descendants) => { + // Note: Assuming that the root has display 'static' (as per + // CSS Section 9.3.1). Otherwise, if it were absolutely + // positioned, it would return a reference to itself in + // `abs_descendants` and would lead to a circular reference. + // Set Root as CB for any remaining absolute descendants. + flow.set_abs_descendants(abs_descendants); + // Set Root as CB for all fixed descendants. + flow.set_fixed_descendants(fixed_descendants); + flow + } _ => fail!("Flow construction didn't result in a flow at the root of the tree!"), }; flow.mark_as_root(); @@ -614,6 +629,7 @@ impl LayoutTask { if data.goal == ReflowForDisplay { profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone(), || { let root_size = flow::base(layout_root).position.size; + let root_abs_position = Point2D(Au::new(0), Au::new(0)); let mut display_list_collection = DisplayListCollection::new(); display_list_collection.add_list(DisplayList::<OpaqueNode>::new()); let display_list_collection = ~RefCell::new(display_list_collection); @@ -621,14 +637,16 @@ impl LayoutTask { let display_list_builder = DisplayListBuilder { ctx: &layout_ctx, }; - layout_root.build_display_lists(&display_list_builder, &root_size, &dirty, 0u, display_list_collection); + layout_root.build_display_lists(&display_list_builder, &root_size, + root_abs_position, + &dirty, 0u, display_list_collection); let display_list_collection = Arc::new(display_list_collection.unwrap()); let mut color = color::rgba(255.0, 255.0, 255.0, 255.0); for child in node.traverse_preorder() { - if child.type_id() == ElementNodeTypeId(HTMLHtmlElementTypeId) || + if child.type_id() == ElementNodeTypeId(HTMLHtmlElementTypeId) || child.type_id() == ElementNodeTypeId(HTMLBodyElementTypeId) { let element_bg_color = { let thread_safe_child = ThreadSafeLayoutNode::new(&child); @@ -768,7 +786,7 @@ impl LayoutTask { Au::from_frac_px(point.y as f64)); let resp = hit_test(x,y,display_list.list); if resp.is_some() { - reply_chan.send(Ok(resp.unwrap())); + reply_chan.send(Ok(resp.unwrap())); return } } @@ -842,4 +860,3 @@ impl LayoutTask { util::replace(layout_data_ref.get(), None)); } } - |