diff --git a/tests/layout/test_float.py b/tests/layout/test_float.py index d3b1bc234..96d72f197 100644 --- a/tests/layout/test_float.py +++ b/tests/layout/test_float.py @@ -302,6 +302,42 @@ def test_floats_page_breaks_3(): assert positions_y == [[10, 40], [10, 40], [10]] +@assert_no_logs +def test_float_overflow_splits_formatting_context(): + # A deferred (overflowing) float must not inflate its block formatting + # context on the current page, or the whole block is pushed to the next page + # instead of being split across the page break. + page_1, page_2 = render_pages(''' + +
+
+

a

+
+

b

+
+ ''') + + # Page 1 keeps the spacer and the first paragraph: the block is split, not + # deferred whole. + html, = page_1.children + body, = html.children + spacer, bfc_1 = body.children + assert spacer.height == 70 + paragraph_a, = bfc_1.children + assert paragraph_a.element_tag == 'p' + assert paragraph_a.position_y == 70 + + # Page 2 resumes the block with the deferred float and the last paragraph. + html, = page_2.children + body, = html.children + bfc_2, = body.children + float_box, paragraph_b = bfc_2.children + assert float_box.is_floated() + assert float_box.position_y == 0 + assert paragraph_b.element_tag == 'p' + assert paragraph_b.position_y == 0 + + @assert_no_logs def test_preferred_widths_1(): def get_float_width(body_width): diff --git a/weasyprint/layout/block.py b/weasyprint/layout/block.py index e259adb9a..4fc79373a 100644 --- a/weasyprint/layout/block.py +++ b/weasyprint/layout/block.py @@ -285,6 +285,7 @@ def _out_of_flow_layout(context, box, index, child, new_children, resume_at = {index: None} out_of_flow_resume_at = None stop = True + remove_placeholders(context, [new_child], absolute_boxes, fixed_boxes) if new_children and avoid_page_break(page_break, context): # Can’t break inside float, find an earlier page break. result = find_earlier_page_break( @@ -1106,8 +1107,7 @@ def remove_placeholders(context, box_list, absolute_boxes, fixed_boxes): """ for box in box_list: if isinstance(box, boxes.ParentBox): - remove_placeholders( - context, box.children, absolute_boxes, fixed_boxes) + remove_placeholders(context, box.children, absolute_boxes, fixed_boxes) if box.style['position'] == 'absolute' and box in absolute_boxes: absolute_boxes.remove(box) elif box.style['position'] == 'fixed' and box in fixed_boxes: @@ -1116,6 +1116,8 @@ def remove_placeholders(context, box_list, absolute_boxes, fixed_boxes): context.unlayout_footnote(box.footnote) if box in context.broken_out_of_flow: context.broken_out_of_flow.pop(box) + if box in context.excluded_shapes: + context.excluded_shapes.remove(box) def avoid_page_break(page_break, context):