aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2014-11-18 16:39:25 -0700
committerbors-servo <metajack+bors@gmail.com>2014-11-18 16:39:25 -0700
commita07401ca4e9ab26d66c7a02e710cea143caca401 (patch)
tree4b82babcaccd0c3f59b34c480eeb11d99d6f6289
parentf5c6146de0b3bfda97edff6662033f4a981df3f6 (diff)
parent55da2c97d5499c3451cdf2a2afee6932128b35a9 (diff)
downloadservo-a07401ca4e9ab26d66c7a02e710cea143caca401.tar.gz
servo-a07401ca4e9ab26d66c7a02e710cea143caca401.zip
auto merge of #3904 : pcwalton/servo/maze-solver-float-placement, r=cgaebel
r? @glennw @cgaebel
-rw-r--r--components/layout/block.rs97
-rw-r--r--components/layout/flow.rs39
-rw-r--r--components/layout/inline.rs7
-rw-r--r--components/layout/table.rs4
-rw-r--r--components/layout/table_colgroup.rs4
-rw-r--r--components/layout/table_row.rs5
-rw-r--r--components/layout/table_rowgroup.rs5
-rw-r--r--components/layout/table_wrapper.rs20
-rw-r--r--tests/ref/basic.list1
-rw-r--r--tests/ref/incremental_float_a.html36
-rw-r--r--tests/ref/incremental_float_ref.html31
11 files changed, 176 insertions, 73 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 336dac78f5c..8d2438de783 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -32,8 +32,9 @@ use context::LayoutContext;
use css::node_style::StyledNode;
use display_list_builder::{BlockFlowDisplayListBuilding, BlockLevel, FragmentDisplayListBuilding};
use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo};
-use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
-use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal, mut_base};
+use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FloatIfNecessary, FlowClass, Flow};
+use flow::{ForceNonfloated, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
+use flow::{PostorderFlowTraversal, mut_base};
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
@@ -569,7 +570,7 @@ impl BlockFlow {
pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
- base: BaseFlow::new(Some((*node).clone()), writing_mode),
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
fragment: Fragment::new(constructor, node),
static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0),
@@ -583,7 +584,7 @@ impl BlockFlow {
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
- base: BaseFlow::new(Some((*node).clone()), writing_mode),
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
fragment: fragment,
static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0),
@@ -600,7 +601,7 @@ impl BlockFlow {
-> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
- base: BaseFlow::new(Some((*node).clone()), writing_mode),
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
fragment: Fragment::new(constructor, node),
static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0),
@@ -617,7 +618,7 @@ impl BlockFlow {
-> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
- base: BaseFlow::new(Some((*node).clone()), writing_mode),
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
fragment: fragment,
static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0),
@@ -639,7 +640,7 @@ impl BlockFlow {
} else {
AbsoluteNonReplacedType
}
- } else if self.is_float() {
+ } else if self.base.flags.is_float() {
if self.is_replaced_content() {
FloatReplacedType
} else {
@@ -866,7 +867,10 @@ impl BlockFlow {
// Assume that the *hypothetical box* for an absolute flow starts immediately
// after the block-end border edge of the previous flow.
kid.as_block().hypothetical_position.b = cur_b;
- kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ kid.place_float_if_applicable(layout_context);
+ if !flow::base(kid).flags.is_float() {
+ kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ }
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
// Skip the collapsing and float processing for absolute flow kids and continue
@@ -877,7 +881,7 @@ impl BlockFlow {
// Assign block-size now for the child if it was impacted by floats and we couldn't
// before.
flow::mut_base(kid).floats = floats.clone();
- if kid.is_float() {
+ if flow::base(kid).flags.is_float() {
flow::mut_base(kid).position.start.b = cur_b;
{
let kid_block = kid.as_block();
@@ -885,10 +889,7 @@ impl BlockFlow {
margin_collapse_info.current_float_ceiling();
}
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
-
- let need_to_process_child_floats =
- kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
- assert!(need_to_process_child_floats); // As it was a float itself...
+ kid.place_float_if_applicable(layout_context);
let kid_base = flow::mut_base(kid);
floats = kid_base.floats.clone();
@@ -907,8 +908,12 @@ impl BlockFlow {
}
// Lay the child out if this was an in-order traversal.
- let need_to_process_child_floats =
- kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ let need_to_process_child_floats = if flow::base(kid).flags.is_float() {
+ kid.place_float_if_applicable(layout_context);
+ true
+ } else {
+ kid.assign_block_size_for_inorder_child_if_necessary(layout_context)
+ };
// Mark flows for layerization if necessary to handle painting order correctly.
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
@@ -1066,8 +1071,9 @@ impl BlockFlow {
// has not been calculated yet. (See `calculate_absolute_block_size_and_margins` for that.)
// Also don't remove the dirty bits if we're a block formatting context since our inline
// size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
- if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
- self.formatting_context_type() == NonformattingContext {
+ if (self.base.flags.is_float() ||
+ self.formatting_context_type() == NonformattingContext) &&
+ !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
}
}
@@ -1113,8 +1119,13 @@ impl BlockFlow {
self.fragment.margin.block_start);
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
- self.base.position = self.base.position.translate(&float_offset)
- .translate(&margin_offset);
+ let mut origin = LogicalPoint::new(self.base.writing_mode,
+ self.hypothetical_position.i,
+ self.base.position.start.b);
+ origin = origin.add_point(&float_offset).add_point(&margin_offset);
+ self.base.position = LogicalRect::from_point_size(self.base.writing_mode,
+ origin,
+ self.base.position.size);
}
}
@@ -1225,7 +1236,7 @@ impl BlockFlow {
pub fn propagate_and_compute_used_inline_size(&mut self, layout_context: &LayoutContext) {
let containing_block_inline_size = self.base.block_container_inline_size;
self.compute_used_inline_size(layout_context, containing_block_inline_size);
- if self.is_float() {
+ if self.base.flags.is_float() {
self.float.as_mut().unwrap().containing_inline_size = containing_block_inline_size;
}
}
@@ -1321,7 +1332,8 @@ impl BlockFlow {
// and its inline-size is our content inline-size.
{
let kid_base = flow::mut_base(kid);
- if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
+ if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
+ !kid_base.flags.is_float() {
kid_base.position.start.i = inline_start_content_edge
}
kid_base.block_container_inline_size = content_inline_size;
@@ -1414,11 +1426,11 @@ impl BlockFlow {
}
let info = PlacementInfo {
- size: LogicalSize::new(
- self.fragment.style.writing_mode,
- self.base.position.size.inline + self.fragment.margin.inline_start_end() +
- self.fragment.border_padding.inline_start_end(),
- self.fragment.border_box.size.block),
+ size: LogicalSize::new(self.fragment.style.writing_mode,
+ self.base.position.size.inline +
+ self.fragment.margin.inline_start_end() +
+ self.fragment.border_padding.inline_start_end(),
+ self.fragment.border_box.size.block),
ceiling: self.base.position.start.b,
max_inline_size: MAX_AU,
kind: FloatLeft,
@@ -1426,10 +1438,12 @@ impl BlockFlow {
// Offset our position by whatever displacement is needed to not impact the floats.
let rect = self.base.floats.place_between_floats(&info);
- self.base.position.start.i = self.base.position.start.i + rect.start.i;
+ self.base.position.start.i = self.hypothetical_position.i + rect.start.i;
// TODO(pcwalton): If the inline-size of this flow is different from the size we estimated
// earlier, lay it out again.
+
+ self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
}
fn is_inline_block(&self) -> bool {
@@ -1547,7 +1561,7 @@ impl Flow for BlockFlow {
}
debug!("assign_inline_sizes({}): assigning inline_size for flow",
- if self.is_float() {
+ if self.base.flags.is_float() {
"float"
} else {
"block"
@@ -1602,19 +1616,17 @@ impl Flow for BlockFlow {
None);
}
- /// Assigns block-sizes in-order; or, if this is a float, places the float. The default
- /// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
- /// if this child affected the floats in the flow somehow or false otherwise; thus, if true,
- /// then the parent flow is expected to take the `floats` member of this flow into account.
- ///
- /// This is called on child flows by the parent. Hence, we can assume that `assign_block_size`
- /// has already been called on the child (because of the bottom-up traversal).
+ fn place_float_if_applicable<'a>(&mut self, _: &'a LayoutContext<'a>) {
+ if self.base.flags.is_float() {
+ self.place_float();
+ }
+ }
+
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
layout_context: &'a LayoutContext<'a>)
-> bool {
- if self.is_float() {
- self.place_float();
- return true
+ if self.base.flags.is_float() {
+ return false
}
let is_formatting_context = self.formatting_context_type() != NonformattingContext;
@@ -1655,7 +1667,7 @@ impl Flow for BlockFlow {
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.position.size.block = self.fragment.border_box.size.block;
}
- } else if self.is_root() || self.is_float() || self.is_inline_block() {
+ } else if self.is_root() || self.base.flags.is_float() || self.is_inline_block() {
// Root element margins should never be collapsed according to CSS § 8.3.1.
debug!("assign_block_size: assigning block_size for root flow");
self.assign_block_size_block_base(ctx, MarginsMayNotCollapse);
@@ -1772,10 +1784,6 @@ impl Flow for BlockFlow {
self.flags.contains(IS_ROOT)
}
- fn is_float(&self) -> bool {
- self.float.is_some()
- }
-
/// The 'position' property of this flow.
fn positioning(&self) -> position::T {
self.fragment.style.get_box().position
@@ -1822,7 +1830,7 @@ impl Flow for BlockFlow {
}
fn build_display_list(&mut self, layout_context: &LayoutContext) {
- if self.is_float() {
+ if self.base.flags.is_float() {
// TODO(#2009, pcwalton): This is a pseudo-stacking context. We need to merge `z-index:
// auto` kids into the parent stacking context, when that is supported.
self.build_display_list_for_floating_block(layout_context)
@@ -2014,7 +2022,6 @@ pub trait ISizeAndMarginsComputer {
// We also resize the block itself, to ensure that overflow is not calculated
// as the inline-size of our parent. We might be smaller and we might be larger if we
// overflow.
-
flow::mut_base(block).position.size.inline = inline_size + extra_inline_size_from_margin;
}
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 64357ab90a6..d95154a6746 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -191,6 +191,9 @@ pub trait Flow: fmt::Show + ToString + Sync {
panic!("assign_block_size not yet implemented")
}
+ /// If this is a float, places it. The default implementation does nothing.
+ fn place_float_if_applicable<'a>(&mut self, _: &'a LayoutContext<'a>) {}
+
/// Assigns block-sizes in-order; or, if this is a float, places the float. The default
/// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
/// if this child was impacted by floats or false otherwise.
@@ -241,10 +244,6 @@ pub trait Flow: fmt::Show + ToString + Sync {
false
}
- fn is_float(&self) -> bool {
- false
- }
-
/// The 'position' property of this flow.
fn positioning(&self) -> position::T {
position::static_
@@ -571,6 +570,11 @@ impl FlowFlags {
}
#[inline]
+ pub fn is_float(&self) -> bool {
+ self.contains(FLOATS_LEFT) || self.contains(FLOATS_RIGHT)
+ }
+
+ #[inline]
pub fn clears_floats(&self) -> bool {
self.contains(CLEARS_LEFT) || self.contains(CLEARS_RIGHT)
}
@@ -834,9 +838,22 @@ impl Drop for BaseFlow {
}
}
+/// Whether a base flow should be forced to be nonfloated. This can affect e.g. `TableFlow`, which
+/// is never floated because the table wrapper flow is the floated one.
+#[deriving(Clone, PartialEq)]
+pub enum ForceNonfloatedFlag {
+ /// The flow should be floated if the node has a `float` property.
+ FloatIfNecessary,
+ /// The flow should be forced to be nonfloated.
+ ForceNonfloated,
+}
+
impl BaseFlow {
#[inline]
- pub fn new(node: Option<ThreadSafeLayoutNode>, writing_mode: WritingMode) -> BaseFlow {
+ pub fn new(node: Option<ThreadSafeLayoutNode>,
+ writing_mode: WritingMode,
+ force_nonfloated: ForceNonfloatedFlag)
+ -> BaseFlow {
let mut flags = FlowFlags::empty();
match node {
None => {}
@@ -848,11 +865,15 @@ impl BaseFlow {
}
_ => {}
}
- match node_style.get_box().float {
- float::none => {}
- float::left => flags.insert(FLOATS_LEFT),
- float::right => flags.insert(FLOATS_RIGHT),
+
+ if force_nonfloated == FloatIfNecessary {
+ match node_style.get_box().float {
+ float::none => {}
+ float::left => flags.insert(FLOATS_LEFT),
+ float::right => flags.insert(FLOATS_RIGHT),
+ }
}
+
match node_style.get_box().clear {
clear::none => {}
clear::left => flags.insert(CLEARS_LEFT),
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 78e89b31b31..73332023d5d 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -8,7 +8,7 @@ use css::node_style::StyledNode;
use context::LayoutContext;
use display_list_builder::{ContentLevel, DisplayListResult, FragmentDisplayListBuilding};
use floats::{FloatLeft, Floats, PlacementInfo};
-use flow::{BaseFlow, FlowClass, Flow, InlineFlowClass, MutableFlowUtils};
+use flow::{BaseFlow, FlowClass, Flow, ForceNonfloated, InlineFlowClass, MutableFlowUtils};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow;
use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
@@ -706,7 +706,7 @@ pub struct InlineFlow {
impl InlineFlow {
pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
InlineFlow {
- base: BaseFlow::new(None, writing_mode),
+ base: BaseFlow::new(None, writing_mode, ForceNonfloated),
fragments: fragments,
lines: Vec::new(),
minimum_block_size_above_baseline: Au(0),
@@ -1116,7 +1116,8 @@ impl Flow for InlineFlow {
// Assign block sizes for any inline-block descendants.
for kid in self.base.child_iter() {
- if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) || kid.is_float() {
+ if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) ||
+ flow::base(kid).flags.is_float() {
continue
}
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 773e18faf05..72f11d66fbf 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -11,8 +11,8 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution};
use construct::FlowConstructor;
use context::LayoutContext;
use floats::FloatKind;
-use flow::{TableFlowClass, FlowClass, Flow, ImmutableFlowUtils};
-use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
+use flow::{Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, ImmutableFlowUtils};
+use flow::{TableFlowClass};
use fragment::{Fragment, FragmentBoundsIterator};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution};
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index dbc826db9f2..e8caa10e88d 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -8,7 +8,7 @@
use context::LayoutContext;
use css::node_style::StyledNode;
-use flow::{BaseFlow, TableColGroupFlowClass, FlowClass, Flow};
+use flow::{BaseFlow, ForceNonfloated, TableColGroupFlowClass, FlowClass, Flow};
use fragment::{Fragment, FragmentBoundsIterator, TableColumnFragment};
use layout_debug;
use wrapper::ThreadSafeLayoutNode;
@@ -44,7 +44,7 @@ impl TableColGroupFlow {
-> TableColGroupFlow {
let writing_mode = node.style().writing_mode;
TableColGroupFlow {
- base: BaseFlow::new(Some((*node).clone()), writing_mode),
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
fragment: Some(fragment),
cols: fragments,
inline_sizes: vec!(),
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index d834ecd144f..4c12ef1ef87 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -79,7 +79,10 @@ impl TableRowFlow {
// cells).
let mut max_y = Au(0);
for kid in self.block_flow.base.child_iter() {
- kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ kid.place_float_if_applicable(layout_context);
+ if !flow::base(kid).flags.is_float() {
+ kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ }
{
let child_fragment = kid.as_table_cell().fragment();
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 50e35e40c73..865c0a3c081 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -74,7 +74,10 @@ impl TableRowGroupFlow {
let mut cur_y = block_start_offset;
for kid in self.block_flow.base.child_iter() {
- kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ kid.place_float_if_applicable(layout_context);
+ if !flow::base(kid).flags.is_float() {
+ kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
+ }
let child_node = flow::mut_base(kid);
child_node.position.start.b = cur_y;
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index 57a34b2f216..7ec0ed874a4 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -191,7 +191,7 @@ impl TableWrapperFlow {
layout_context: &LayoutContext,
parent_flow_inline_size: Au) {
// Delegate to the appropriate inline size computer to find the constraint inputs.
- let input = if self.is_float() {
+ let input = if self.block_flow.base.flags.is_float() {
FloatNonReplaced.compute_inline_size_constraint_inputs(&mut self.block_flow,
parent_flow_inline_size,
layout_context)
@@ -202,7 +202,7 @@ impl TableWrapperFlow {
};
// Delegate to the appropriate inline size computer to write the constraint solutions in.
- if self.is_float() {
+ if self.block_flow.base.flags.is_float() {
let solution = FloatNonReplaced.solve_inline_size_constraints(&mut self.block_flow,
&input);
FloatNonReplaced.set_inline_size_constraint_solutions(&mut self.block_flow, solution);
@@ -221,10 +221,6 @@ impl Flow for TableWrapperFlow {
TableWrapperFlowClass
}
- fn is_float(&self) -> bool {
- self.block_flow.is_float()
- }
-
fn as_table_wrapper<'a>(&'a mut self) -> &'a mut TableWrapperFlow {
self
}
@@ -251,7 +247,7 @@ impl Flow for TableWrapperFlow {
fn assign_inline_sizes(&mut self, layout_context: &LayoutContext) {
debug!("assign_inline_sizes({}): assigning inline_size for flow",
- if self.is_float() {
+ if self.block_flow.base.flags.is_float() {
"floated table_wrapper"
} else {
"table_wrapper"
@@ -267,7 +263,7 @@ impl Flow for TableWrapperFlow {
// Our inline-size was set to the inline-size of the containing block by the flow's parent.
// Now compute the real value.
let containing_block_inline_size = self.block_flow.base.block_container_inline_size;
- if self.is_float() {
+ if self.block_flow.base.flags.is_float() {
self.block_flow.float.as_mut().unwrap().containing_inline_size =
containing_block_inline_size;
}
@@ -305,10 +301,14 @@ impl Flow for TableWrapperFlow {
self.block_flow.compute_absolute_position()
}
+ fn place_float_if_applicable<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
+ self.block_flow.place_float_if_applicable(layout_context)
+ }
+
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
layout_context: &'a LayoutContext<'a>)
-> bool {
- if self.block_flow.is_float() {
+ if self.block_flow.base.flags.is_float() {
self.block_flow.place_float();
return true
}
@@ -343,7 +343,7 @@ impl Flow for TableWrapperFlow {
impl fmt::Show for TableWrapperFlow {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if self.is_float() {
+ if self.block_flow.base.flags.is_float() {
write!(f, "TableWrapperFlow(Float): {}", self.block_flow.fragment)
} else {
write!(f, "TableWrapperFlow: {}", self.block_flow.fragment)
diff --git a/tests/ref/basic.list b/tests/ref/basic.list
index c4d7c923c4c..b1480e1d856 100644
--- a/tests/ref/basic.list
+++ b/tests/ref/basic.list
@@ -184,3 +184,4 @@ fragment=top != ../html/acid2.html acid2_ref.html
== linear_gradients_reverse_a.html linear_gradients_reverse_ref.html
!= linear_gradients_corners_a.html linear_gradients_corners_ref.html
== linear_gradients_lengths_a.html linear_gradients_lengths_ref.html
+== incremental_float_a.html incremental_float_ref.html
diff --git a/tests/ref/incremental_float_a.html b/tests/ref/incremental_float_a.html
new file mode 100644
index 00000000000..02e762b82e9
--- /dev/null
+++ b/tests/ref/incremental_float_a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+nav.floaty {
+ float: left;
+}
+section {
+ clear: both;
+ position: relative;
+}
+</style>
+</head>
+<body>
+<section>
+<nav>This floats</nav>
+<div>This doesn't</div>
+</section>
+<section>
+<nav>This floats</nav>
+<div style="overflow: hidden;">This is a block formatting context</div>
+</section>
+<section>
+<nav>This floats</nav>
+<div style="position: absolute; top: 0; left: 0; width: 100px; height: 100px;">
+ This is abspos
+</div>
+</section>
+<script>
+var elements = document.getElementsByTagName('nav');
+for (var i = 0; i < elements.length; i++)
+ elements[i].setAttribute('class', 'floaty');
+</script>
+</body>
+</html>
+
diff --git a/tests/ref/incremental_float_ref.html b/tests/ref/incremental_float_ref.html
new file mode 100644
index 00000000000..7b52f8a8f49
--- /dev/null
+++ b/tests/ref/incremental_float_ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+nav {
+ float: left;
+}
+section {
+ clear: both;
+ position: relative;
+}
+</style>
+</head>
+<body>
+<section>
+<nav>This floats</nav>
+<div>This doesn't</div>
+</section>
+<section>
+<nav>This floats</nav>
+<div style="overflow: hidden;">This is a block formatting context</div>
+</section>
+<section>
+<nav>This floats</nav>
+<div style="position: absolute; top: 0; left: 0; width: 100px; height: 100px;">
+ This is abspos
+</div>
+</section>
+</body>
+</html>
+