diff --git a/components/layout/block.rs b/components/layout/block.rs index 0df2bbe3f3a..a0fcc5f25a8 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -33,7 +33,7 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list_builder::{FragmentDisplayListBuilding}; use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow}; -use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal}; +use flow::{ImmutableFlowUtils, PreorderFlowTraversal}; use flow::{PostorderFlowTraversal, mut_base}; use flow::{BLOCK_POSITION_IS_STATIC, HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS}; use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC}; @@ -1631,6 +1631,7 @@ impl Flow for BlockFlow { self.base.thread_id = parent_thread_id; if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) { self.assign_block_size(layout_context); + self.store_overflow(layout_context); // Don't remove the restyle damage; `assign_block_size` decides whether that is // appropriate (which in the case of e.g. absolutely-positioned flows, it is not). } diff --git a/components/layout/flow.rs b/components/layout/flow.rs index f868983e6c2..33940f8a8c6 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -221,11 +221,55 @@ pub trait Flow: fmt::Debug + Sync { if impacted { mut_base(self).thread_id = parent_thread_id; self.assign_block_size(layout_context); + self.store_overflow(layout_context); mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW); } impacted } + /// Calculate and set overflow for current flow. + /// + /// CSS Section 11.1 + /// This is the union of rectangles of the flows for which we define the + /// Containing Block. + /// + /// FIXME(pcwalton): This should not be a virtual method, but currently is due to a compiler + /// bug ("the trait `Sized` is not implemented for `self`"). + /// + /// Assumption: This is called in a bottom-up traversal, so kids' overflows have + /// already been set. + /// Assumption: Absolute descendants have had their overflow calculated. + fn store_overflow(&mut self, _: &LayoutContext) { + // Calculate overflow on a per-fragment basis. + let mut overflow = self.compute_overflow(); + match self.class() { + FlowClass::Block | + FlowClass::TableCaption | + FlowClass::TableCell if base(self).children.len() != 0 => { + // FIXME(#2795): Get the real container size. + let container_size = Size2D::zero(); + for kid in mut_base(self).children.iter_mut() { + if base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) { + continue + } + let kid_overflow = base(kid).overflow; + let kid_position = base(kid).position.to_physical(base(kid).writing_mode, + container_size); + overflow = overflow.union(&kid_overflow.translate(&kid_position.origin)) + } + + for kid in mut_base(self).abs_descendants.iter() { + let kid_overflow = base(kid).overflow; + let kid_position = base(kid).position.to_physical(base(kid).writing_mode, + container_size); + overflow = overflow.union(&kid_overflow.translate(&kid_position.origin)) + } + } + _ => {} + } + mut_base(self).overflow = overflow; + } + /// Phase 4 of reflow: computes absolute positions. fn compute_absolute_position(&mut self) { // The default implementation is a no-op. @@ -429,9 +473,6 @@ pub trait MutableFlowUtils { // Mutators - /// Computes the overflow region for this flow. - fn store_overflow(self, _: &LayoutContext); - /// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of /// calling them individually, since there is no reason not to perform both operations. fn repair_style_and_bubble_inline_sizes(self, style: &Arc); @@ -1228,41 +1269,6 @@ impl<'a> MutableFlowUtils for &'a mut (Flow + 'a) { } } - /// Calculate and set overflow for current flow. - /// - /// CSS Section 11.1 - /// This is the union of rectangles of the flows for which we define the - /// Containing Block. - /// - /// Assumption: This is called in a bottom-up traversal, so kids' overflows have - /// already been set. - /// Assumption: Absolute descendants have had their overflow calculated. - fn store_overflow(self, _: &LayoutContext) { - // Calculate overflow on a per-fragment basis. - let mut overflow = self.compute_overflow(); - if self.is_block_container() { - // FIXME(#2795): Get the real container size. - let container_size = Size2D::zero(); - for kid in child_iter(self) { - if base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) { - continue - } - let kid_overflow = base(kid).overflow; - let kid_position = base(kid).position.to_physical(base(kid).writing_mode, - container_size); - overflow = overflow.union(&kid_overflow.translate(&kid_position.origin)) - } - - for kid in mut_base(self).abs_descendants.iter() { - let kid_overflow = base(kid).overflow; - let kid_position = base(kid).position.to_physical(base(kid).writing_mode, - container_size); - overflow = overflow.union(&kid_overflow.translate(&kid_position.origin)) - } - } - - mut_base(self).overflow = overflow; - } /// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of /// calling them individually, since there is no reason not to perform both operations. diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index cfedc0ae3f1..b362ac6975f 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -10,9 +10,8 @@ use css::node_style::StyledNode; use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult}; use construct::FlowConstructor; use context::LayoutContext; -use flow::{Flow, MutableFlowUtils}; +use flow::{self, Flow}; use flow::{PreorderFlowTraversal, PostorderFlowTraversal}; -use flow; use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage}; use script::layout_interface::ReflowGoal; use wrapper::{layout_node_to_unsafe_layout_node, LayoutNode}; diff --git a/tests/ref/basic.list b/tests/ref/basic.list index b1c87ce6ea7..27ee5e2c327 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -92,6 +92,7 @@ flaky_cpu == append_style_a.html append_style_b.html == float_clearance_intrinsic_width_a.html float_clearance_intrinsic_width_ref.html == float_intrinsic_height.html float_intrinsic_height_ref.html == float_intrinsic_width_a.html float_intrinsic_width_ref.html +== float_overflow_area_a.html float_overflow_area_ref.html == float_right_intrinsic_width_a.html float_right_intrinsic_width_ref.html == float_table_a.html float_table_ref.html == float_under_top_margin_a.html float_under_top_margin_ref.html diff --git a/tests/ref/float_overflow_area_a.html b/tests/ref/float_overflow_area_a.html new file mode 100644 index 00000000000..9597f2a6d97 --- /dev/null +++ b/tests/ref/float_overflow_area_a.html @@ -0,0 +1,13 @@ + + + + + + +
Y
+ + diff --git a/tests/ref/float_overflow_area_ref.html b/tests/ref/float_overflow_area_ref.html new file mode 100644 index 00000000000..a313c3a1359 --- /dev/null +++ b/tests/ref/float_overflow_area_ref.html @@ -0,0 +1,13 @@ + + + + + + +
Y
+ +