diff --git a/components/layout/block.rs b/components/layout/block.rs index b84e0da50f7..ba17b417963 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -1448,6 +1448,10 @@ impl Flow for BlockFlow { self.fragment.style().get_box().clear } + fn float_kind(&self) -> float::T { + self.fragment.style().get_box().float + } + /// Pass 1 of reflow: computes minimum and preferred inline-sizes. /// /// Recursively (bottom-up) determine the flow's minimum and preferred inline-sizes. When called on @@ -1473,25 +1477,45 @@ impl Flow for BlockFlow { // Find the maximum inline-size from children. let mut intrinsic_inline_sizes = IntrinsicISizes::new(); + let mut left_float_width = Au(0); + let mut right_float_width = Au(0); for child_ctx in self.base.child_iter() { assert!(child_ctx.is_block_flow() || child_ctx.is_inline_flow() || child_ctx.is_table_kind()); + let float_kind = child_ctx.float_kind(); let child_base = flow::mut_base(child_ctx); if !fixed_width { intrinsic_inline_sizes.minimum_inline_size = geometry::max(intrinsic_inline_sizes.minimum_inline_size, child_base.intrinsic_inline_sizes.total_minimum_inline_size()); - intrinsic_inline_sizes.preferred_inline_size = - geometry::max(intrinsic_inline_sizes.preferred_inline_size, + + match float_kind { + float::none => { + intrinsic_inline_sizes.preferred_inline_size = + geometry::max(intrinsic_inline_sizes.preferred_inline_size, child_base.intrinsic_inline_sizes.total_preferred_inline_size()); + } + float::left => { + left_float_width = left_float_width + + child_base.intrinsic_inline_sizes.total_preferred_inline_size(); + } + float::right => { + right_float_width = right_float_width + + child_base.intrinsic_inline_sizes.total_preferred_inline_size(); + } + } } flags.union_floated_descendants_flags(child_base.flags); } + intrinsic_inline_sizes.preferred_inline_size = + geometry::max(intrinsic_inline_sizes.preferred_inline_size, + left_float_width + right_float_width); + let fragment_intrinsic_inline_sizes = self.fragment.intrinsic_inline_sizes(); intrinsic_inline_sizes.minimum_inline_size = geometry::max(intrinsic_inline_sizes.minimum_inline_size, fragment_intrinsic_inline_sizes.minimum_inline_size); diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 2759ebbe74b..7a4c98a8361 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -61,7 +61,7 @@ use std::iter::Zip; use std::raw; use std::sync::atomics::{AtomicUint, Relaxed, SeqCst}; use std::slice::MutItems; -use style::computed_values::{clear, position, text_align}; +use style::computed_values::{clear, float, position, text_align}; /// Virtual methods that make up a float context. /// @@ -195,6 +195,10 @@ pub trait Flow: fmt::Show + ToString + Share { clear::none } + fn float_kind(&self) -> float::T { + float::none + } + /// Returns true if this float is a block formatting context and false otherwise. The default /// implementation returns false. fn is_block_formatting_context(&self, _only_impactable_by_floats: bool) -> bool { diff --git a/tests/ref/abs_float_pref_width_a.html b/tests/ref/abs_float_pref_width_a.html new file mode 100644 index 00000000000..65714506722 --- /dev/null +++ b/tests/ref/abs_float_pref_width_a.html @@ -0,0 +1,30 @@ + + + + + + +
+ X + X +
+ + diff --git a/tests/ref/abs_float_pref_width_ref.html b/tests/ref/abs_float_pref_width_ref.html new file mode 100644 index 00000000000..2b35cb62eb4 --- /dev/null +++ b/tests/ref/abs_float_pref_width_ref.html @@ -0,0 +1,21 @@ + + + + + + +
+
+ + diff --git a/tests/ref/basic.list b/tests/ref/basic.list index 0ffafba5dca..b785ddbd4c1 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -110,3 +110,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html == float_intrinsic_width_a.html float_intrinsic_width_ref.html == float_right_intrinsic_width_a.html float_right_intrinsic_width_ref.html == fixed_width_overrides_child_intrinsic_width_a.html fixed_width_overrides_child_intrinsic_width_ref.html +== abs_float_pref_width_a.html abs_float_pref_width_ref.html