diff --git a/tests/draw/test_float.py b/tests/draw/test_float.py
index 49665d83..f31326f5 100644
--- a/tests/draw/test_float.py
+++ b/tests/draw/test_float.py
@@ -659,3 +659,84 @@ def test_float_split_10(assert_pixels):
bbbbb bbbbb
aa aa
bbb bbb
''')
+
+
+@assert_no_logs
+def test_float_split_11(assert_pixels):
+ assert_pixels('''
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBGG______BBBB
+ BBBBGG______BBBB
+ BBBB________BBBB
+ BBBB________BBBB
+ ________________
+ ''', '''
+
+
+ a
+
+ ''')
+
+
+@assert_no_logs
+def test_float_split_12(assert_pixels):
+ assert_pixels('''
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBBBBBBBBBBBBB
+ BBBBGG______BBBB
+ BBBBGG______BBBB
+ BBBB________BBBB
+ BBBB________BBBB
+ ________________
+ ''', '''
+
+
+
+
+ a
+ ''')
diff --git a/weasyprint/layout/__init__.py b/weasyprint/layout/__init__.py
index d9774b16..7fdda763 100644
--- a/weasyprint/layout/__init__.py
+++ b/weasyprint/layout/__init__.py
@@ -233,7 +233,7 @@ class LayoutContext:
self.running_elements = defaultdict(lambda: defaultdict(lambda: []))
self.current_page = None
self.forced_break = False
- self.broken_out_of_flow = []
+ self.broken_out_of_flow = {}
self.in_column = False
# Cache
diff --git a/weasyprint/layout/absolute.py b/weasyprint/layout/absolute.py
index f7d82e03..6640c09c 100644
--- a/weasyprint/layout/absolute.py
+++ b/weasyprint/layout/absolute.py
@@ -229,7 +229,8 @@ def absolute_layout(context, placeholder, containing_block, fixed_boxes,
context, box, containing_block, fixed_boxes, bottom_space, skip_stack)
placeholder.set_laid_out_box(new_box)
if resume_at:
- context.broken_out_of_flow.append((box, containing_block, resume_at))
+ context.broken_out_of_flow[placeholder] = (
+ box, containing_block, resume_at)
def absolute_box_layout(context, box, containing_block, fixed_boxes,
diff --git a/weasyprint/layout/block.py b/weasyprint/layout/block.py
index b3406f29..951622ed 100644
--- a/weasyprint/layout/block.py
+++ b/weasyprint/layout/block.py
@@ -230,7 +230,7 @@ def _out_of_flow_layout(context, box, index, child, new_children,
child.position_y += collapse_margin(adjoining_margins)
if child.is_absolutely_positioned():
- placeholder = AbsolutePlaceholder(child)
+ new_child = placeholder = AbsolutePlaceholder(child)
placeholder.index = index
new_children.append(placeholder)
if child.style['position'] == 'absolute':
@@ -262,7 +262,7 @@ def _out_of_flow_layout(context, box, index, child, new_children,
page = context.current_page
context.running_elements[running_name][page].append(child)
- return stop, resume_at, out_of_flow_resume_at
+ return stop, resume_at, new_child, out_of_flow_resume_at
def _break_line(context, box, line, new_children, lines_iterator,
@@ -629,7 +629,7 @@ def block_container_layout(context, box, bottom_space, skip_stack,
new_children = []
next_page = {'break': 'any', 'page': None}
all_footnotes = []
- broken_out_of_flow = []
+ broken_out_of_flow = {}
last_in_flow_child = None
@@ -649,12 +649,14 @@ def block_container_layout(context, box, bottom_space, skip_stack,
if not child.is_in_normal_flow():
abort = False
- stop, resume_at, out_of_flow_resume_at = _out_of_flow_layout(
- context, box, index, child, new_children, page_is_empty,
- absolute_boxes, fixed_boxes, adjoining_margins,
- bottom_space)
+ stop, resume_at, new_child, out_of_flow_resume_at = (
+ _out_of_flow_layout(
+ context, box, index, child, new_children, page_is_empty,
+ absolute_boxes, fixed_boxes, adjoining_margins,
+ bottom_space))
if out_of_flow_resume_at:
- broken_out_of_flow.append((child, box, out_of_flow_resume_at))
+ broken_out_of_flow[new_child] = (
+ child, box, out_of_flow_resume_at)
elif isinstance(child, boxes.LineBox):
(abort, stop, resume_at, position_y,
@@ -696,6 +698,8 @@ def block_container_layout(context, box, bottom_space, skip_stack,
if abort:
page = child.page_values()[0]
+ remove_placeholders(
+ context, box.children[skip:], absolute_boxes, fixed_boxes)
for footnote in new_footnotes:
context.unlayout_footnote(footnote)
return (
@@ -720,7 +724,8 @@ def block_container_layout(context, box, bottom_space, skip_stack,
return (
None, None, {'break': 'any', 'page': None}, [], False, max_lines)
- context.broken_out_of_flow.extend(broken_out_of_flow)
+ for key, value in broken_out_of_flow.items():
+ context.broken_out_of_flow[key] = value
if collapsing_with_children:
box.position_y += (
@@ -1005,6 +1010,8 @@ def remove_placeholders(context, box_list, absolute_boxes, fixed_boxes):
For boxes that have been removed in find_earlier_page_break(), remove the
matching placeholders in absolute_boxes and fixed_boxes.
+ Also takes care of removed footnotes and floats.
+
"""
for box in box_list:
if isinstance(box, boxes.ParentBox):
@@ -1017,6 +1024,8 @@ def remove_placeholders(context, box_list, absolute_boxes, fixed_boxes):
fixed_boxes.remove(box)
if box.footnote:
context.unlayout_footnote(box.footnote)
+ if box in context.broken_out_of_flow:
+ context.broken_out_of_flow.pop(box)
def avoid_page_break(page_break, context):
diff --git a/weasyprint/layout/inline.py b/weasyprint/layout/inline.py
index b6171543..e818da2d 100644
--- a/weasyprint/layout/inline.py
+++ b/weasyprint/layout/inline.py
@@ -169,8 +169,8 @@ def get_next_linebox(context, linebox, position_y, bottom_space, skip_stack,
fixed_boxes, bottom_space, skip_stack=None)
float_children.append(new_waiting_float)
if waiting_float_resume_at:
- context.broken_out_of_flow.append(
- (waiting_float, containing_block, waiting_float_resume_at))
+ context.broken_out_of_flow[new_waiting_float] = (
+ waiting_float, containing_block, waiting_float_resume_at)
if float_children:
line.children += tuple(float_children)
@@ -559,8 +559,8 @@ def _out_of_flow_layout(context, box, containing_block, index, child,
context, child, containing_block, absolute_boxes, fixed_boxes,
bottom_space, skip_stack=None)
if float_resume_at:
- context.broken_out_of_flow.append(
- (child, containing_block, float_resume_at))
+ context.broken_out_of_flow[child] = (
+ child, containing_block, float_resume_at)
waiting_children.append((index, new_child, child))
child = new_child
diff --git a/weasyprint/layout/page.py b/weasyprint/layout/page.py
index 054364e1..8865e68b 100644
--- a/weasyprint/layout/page.py
+++ b/weasyprint/layout/page.py
@@ -564,8 +564,9 @@ def make_page(context, root_box, page_type, resume_at, page_number,
adjoining_margins = []
positioned_boxes = [] # Mixed absolute and fixed
out_of_flow_boxes = []
- broken_out_of_flow = []
- for box, containing_block, skip_stack in context.broken_out_of_flow:
+ broken_out_of_flow = {}
+ context_out_of_flow = context.broken_out_of_flow.values()
+ for box, containing_block, skip_stack in context_out_of_flow:
box.position_y = 0
if box.is_floated():
out_of_flow_box, out_of_flow_resume_at = float_layout(
@@ -578,8 +579,8 @@ def make_page(context, root_box, page_type, resume_at, page_number,
skip_stack)
out_of_flow_boxes.append(out_of_flow_box)
if out_of_flow_resume_at:
- broken_out_of_flow.append(
- (box, containing_block, out_of_flow_resume_at))
+ broken_out_of_flow[out_of_flow_box] = (
+ box, containing_block, out_of_flow_resume_at)
context.broken_out_of_flow = broken_out_of_flow
root_box, resume_at, next_page, _, _, _ = block_level_layout(
context, root_box, 0, resume_at, initial_containing_block,