aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/block.rs94
-rw-r--r--tests/ref/basic.list1
-rw-r--r--tests/ref/block_formatting_context_complex_a.html43
-rw-r--r--tests/ref/block_formatting_context_complex_ref.html43
4 files changed, 151 insertions, 30 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 64056147bf0..ed442ece546 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -510,9 +510,13 @@ pub struct BlockFlow {
/// Static y offset of an absolute flow from its CB.
pub static_b_offset: Au,
- /// The inline-size of the last float prior to this block. This is used to speculatively lay out
- /// block formatting contexts.
- previous_float_inline_size: Option<Au>,
+ /// The sum of the inline-sizes of all logically left floats that precede this block. This is
+ /// used to speculatively lay out block formatting contexts.
+ inline_size_of_preceding_left_floats: Au,
+
+ /// The sum of the inline-sizes of all logically right floats that precede this block. This is
+ /// used to speculatively lay out block formatting contexts.
+ inline_size_of_preceding_right_floats: Au,
/// Additional floating flow members.
pub float: Option<Box<FloatedBlockInfo>>
@@ -525,7 +529,8 @@ impl BlockFlow {
fragment: Fragment::new(constructor, node),
is_root: false,
static_b_offset: Au::new(0),
- previous_float_inline_size: None,
+ inline_size_of_preceding_left_floats: Au(0),
+ inline_size_of_preceding_right_floats: Au(0),
float: None
}
}
@@ -536,7 +541,8 @@ impl BlockFlow {
fragment: fragment,
is_root: false,
static_b_offset: Au::new(0),
- previous_float_inline_size: None,
+ inline_size_of_preceding_left_floats: Au(0),
+ inline_size_of_preceding_right_floats: Au(0),
float: None
}
}
@@ -550,7 +556,8 @@ impl BlockFlow {
fragment: Fragment::new(constructor, node),
is_root: false,
static_b_offset: Au::new(0),
- previous_float_inline_size: None,
+ inline_size_of_preceding_left_floats: Au(0),
+ inline_size_of_preceding_right_floats: Au(0),
float: Some(box FloatedBlockInfo::new(float_kind)),
base: base,
}
@@ -565,7 +572,8 @@ impl BlockFlow {
fragment: fragment,
is_root: false,
static_b_offset: Au::new(0),
- previous_float_inline_size: None,
+ inline_size_of_preceding_left_floats: Au(0),
+ inline_size_of_preceding_right_floats: Au(0),
float: Some(box FloatedBlockInfo::new(float_kind)),
base: base,
}
@@ -1321,11 +1329,17 @@ impl BlockFlow {
// This value is used only for table cells.
let mut inline_start_margin_edge = inline_start_content_edge;
- // The inline-size of the last float, if there was one. This is used for estimating the
- // inline-sizes of block formatting contexts. (We estimate that the inline-size of any
- // block formatting context that we see will be based on the inline-size of the containing
- // block as well as the last float seen before it.)
- let mut last_float_inline_size = None;
+ // Remember the inline-sizes of the last left and right floats, if there were any. These
+ // are used for estimating the inline-sizes of block formatting contexts. (We estimate that
+ // the inline-size of any block formatting context that we see will be based on the
+ // inline-size of the containing block as well as the last float seen before it in each
+ // direction.)
+ let mut inline_size_of_preceding_left_floats = Au(0);
+ let mut inline_size_of_preceding_right_floats = Au(0);
+ if self.formatting_context_type() == NonformattingContext {
+ inline_size_of_preceding_left_floats = self.inline_size_of_preceding_left_floats;
+ inline_size_of_preceding_right_floats = self.inline_size_of_preceding_right_floats;
+ }
// Calculate non-auto block size to pass to children.
let content_block_size = self.fragment.style().content_block_size();
@@ -1345,29 +1359,44 @@ impl BlockFlow {
let kid_block = kid.as_block();
kid_block.base.absolute_static_i_offset = absolute_static_i_offset;
kid_block.base.fixed_static_i_offset = fixed_static_i_offset;
+ }
- if kid_block.is_float() {
- last_float_inline_size = Some(kid_block.base.intrinsic_inline_sizes.preferred_inline_size)
- } else {
- kid_block.previous_float_inline_size = last_float_inline_size
+ match kid.float_kind() {
+ float::none => {}
+ float::left => {
+ inline_size_of_preceding_left_floats = inline_size_of_preceding_left_floats +
+ flow::base(kid).intrinsic_inline_sizes.preferred_inline_size;
+ }
+ float::right => {
+ inline_size_of_preceding_right_floats = inline_size_of_preceding_right_floats +
+ flow::base(kid).intrinsic_inline_sizes.preferred_inline_size;
}
}
- // The inline-start margin edge of the child flow is at our inline-start content edge, and its inline-size
- // is our content inline-size.
+ // The inline-start margin edge of the child flow is at our inline-start content edge,
+ // and its inline-size is our content inline-size.
flow::mut_base(kid).position.start.i = inline_start_content_edge;
flow::mut_base(kid).position.size.inline = content_inline_size;
// Determine float impaction.
match kid.float_clearance() {
clear::none => {}
- clear::left => inline_start_floats_impact_child = false,
- clear::right => inline_end_floats_impact_child = false,
+ clear::left => {
+ inline_start_floats_impact_child = false;
+ inline_size_of_preceding_left_floats = Au(0);
+ }
+ clear::right => {
+ inline_end_floats_impact_child = false;
+ inline_size_of_preceding_right_floats = Au(0);
+ }
clear::both => {
inline_start_floats_impact_child = false;
inline_end_floats_impact_child = false;
+ inline_size_of_preceding_left_floats = Au(0);
+ inline_size_of_preceding_right_floats = Au(0);
}
}
+
{
let kid_base = flow::mut_base(kid);
inline_start_floats_impact_child = inline_start_floats_impact_child ||
@@ -1378,6 +1407,14 @@ impl BlockFlow {
kid_base.flags.set_impacted_by_right_floats(inline_end_floats_impact_child);
}
+ if kid.is_block_flow() {
+ let kid_block = kid.as_block();
+ kid_block.inline_size_of_preceding_left_floats =
+ inline_size_of_preceding_left_floats;
+ kid_block.inline_size_of_preceding_right_floats =
+ inline_size_of_preceding_right_floats;
+ }
+
// Handle tables.
match opt_col_inline_sizes {
Some(ref col_inline_sizes) => {
@@ -1591,16 +1628,13 @@ impl Flow for BlockFlow {
self.base.flags.set_impacted_by_left_floats(false);
self.base.flags.set_impacted_by_right_floats(false);
- // We can't actually compute the inline-size of this block now, because floats might
- // affect it. Speculate that its inline-size is equal to the inline-size computed above minus
- // the inline-size of the previous float.
- match self.previous_float_inline_size {
- None => {}
- Some(previous_float_inline_size) => {
- self.fragment.border_box.size.inline =
- self.fragment.border_box.size.inline - previous_float_inline_size
- }
- }
+ // We can't actually compute the inline-size of this block now, because floats
+ // might affect it. Speculate that its inline-size is equal to the inline-size
+ // computed above minus the inline-size of the previous left and/or right floats.
+ self.fragment.border_box.size.inline =
+ self.fragment.border_box.size.inline -
+ self.inline_size_of_preceding_left_floats -
+ self.inline_size_of_preceding_right_floats;
}
OtherFormattingContext => {
self.base.flags.set_impacted_by_left_floats(false);
diff --git a/tests/ref/basic.list b/tests/ref/basic.list
index dce827a76b6..c342c3bec9c 100644
--- a/tests/ref/basic.list
+++ b/tests/ref/basic.list
@@ -146,3 +146,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html
== block_formatting_context_translation_a.html block_formatting_context_translation_ref.html
== floated_table_with_margin_a.html floated_table_with_margin_ref.html
== margins_inside_floats_a.html margins_inside_floats_ref.html
+== block_formatting_context_complex_a.html block_formatting_context_complex_ref.html
diff --git a/tests/ref/block_formatting_context_complex_a.html b/tests/ref/block_formatting_context_complex_a.html
new file mode 100644
index 00000000000..aa79a65a6af
--- /dev/null
+++ b/tests/ref/block_formatting_context_complex_a.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.a {
+ height: 999999px;
+ color: white;
+}
+</style>
+</head>
+<body>
+<div class=a style="float: right; width: 200px; background: blue;">Meow</div>
+<div class=a style="float: left; width: 50px; background: orange;">Mimi</div>
+<div class=a style="float: left; width: 50px; background: green;">the</div>
+<div class=a style="float: left; width: 50px; background: violet;">cat</div>
+<div style="overflow: hidden;">
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+</div>
+</body>
+</html>
+
diff --git a/tests/ref/block_formatting_context_complex_ref.html b/tests/ref/block_formatting_context_complex_ref.html
new file mode 100644
index 00000000000..8a894c3106b
--- /dev/null
+++ b/tests/ref/block_formatting_context_complex_ref.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.a {
+ height: 999999px;
+ color: white;
+}
+</style>
+</head>
+<body>
+<div class=a style="float: right; width: 200px; background: blue;">Meow</div>
+<div class=a style="float: left; width: 50px; background: orange;">Mimi</div>
+<div class=a style="float: left; width: 50px; background: green;">the</div>
+<div class=a style="float: left; width: 50px; background: violet;">cat</div>
+<div>
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+There once was an engine named Servo
+</div>
+</body>
+</html>
+