From 9ff3349c0b602267bfbcaa3dc968fb5470bcc43f Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Thu, 27 Mar 2025 14:59:49 +0000 Subject: [PATCH] LibWeb: Apply remaining vertical float clearance to next block level box Whenever we generate line boxes, we might end up with a residual vertical float clearance by way of having a `
` with `clear: ..` set. Set the Y offset of the next block level box to place by this vertical clearance. Relates to #4058. --- .../LibWeb/Layout/BlockFormattingContext.cpp | 11 ++++++--- .../LibWeb/Layout/InlineFormattingContext.cpp | 3 +-- ...-clear-by-line-break-followed-by-block.txt | 23 +++++++++++++++++++ ...lear-by-line-break-followed-by-inline.txt} | 0 ...clear-by-line-break-followed-by-block.html | 15 ++++++++++++ ...ear-by-line-break-followed-by-inline.html} | 0 6 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt rename Tests/LibWeb/Layout/expected/block-and-inline/{float-clear-by-line-break.txt => float-clear-by-line-break-followed-by-inline.txt} (100%) create mode 100644 Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html rename Tests/LibWeb/Layout/input/block-and-inline/{float-clear-by-line-break.html => float-clear-by-line-break-followed-by-inline.html} (100%) diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 8930a91dbd8..34508b1256e 100644 --- a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -564,6 +564,10 @@ void BlockFormattingContext::layout_inline_children(BlockContainer const& block_ block_container_state.set_content_width(used_width_px); block_container_state.set_content_height(context.automatic_content_height()); } + + // If we end up with remaining vertical clearance, we should make sure the next block is moved down accordingly. + if (context.vertical_float_clearance() > 0) + m_y_offset_of_current_block_container = context.vertical_float_clearance(); } CSSPixels BlockFormattingContext::compute_auto_height_for_block_level_element(Box const& box, AvailableSpace const& available_space) @@ -704,9 +708,8 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain && box.computed_values().height().is_auto(); // NOTE: In quirks mode, the html element's height matches the viewport so it can be treated as definite - if (box_state.has_definite_height() || box_is_html_element_in_quirks_mode) { + if (box_state.has_definite_height() || box_is_html_element_in_quirks_mode) resolve_used_height_if_treated_as_auto(box, available_space); - } auto independent_formatting_context = create_independent_formatting_context_if_needed(m_state, m_layout_mode, box); @@ -817,7 +820,9 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain if (!m_margin_state.box_last_in_flow_child_margin_bottom_collapsed) { m_margin_state.reset(); } - m_y_offset_of_current_block_container = box_state.offset.y() + box_state.content_height() + box_state.border_box_bottom(); + auto box_height = box_state.offset.y() + box_state.content_height() + box_state.border_box_bottom(); + if (!m_y_offset_of_current_block_container.has_value() || box_height > m_y_offset_of_current_block_container.value()) + m_y_offset_of_current_block_container = box_height; } m_margin_state.box_last_in_flow_child_margin_bottom_collapsed = false; diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index c988b6811a0..fd0f5e545e8 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -84,9 +84,8 @@ void InlineFormattingContext::run(AvailableSpace const& available_space) CSSPixels content_height = 0; - for (auto& line_box : m_containing_block_used_values.line_boxes) { + for (auto& line_box : m_containing_block_used_values.line_boxes) content_height += line_box.height(); - } // NOTE: We ask the parent BFC to calculate the automatic content width of this IFC. // This ensures that any floated boxes are taken into account. diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt new file mode 100644 index 00000000000..a05bd3ab745 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-block.txt @@ -0,0 +1,23 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x157 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x133 children: not-inline + BlockContainer at (8,8) content-size 100x100 floating [BFC] children: not-inline + BlockContainer <(anonymous)> at (8,8) content-size 784x17 children: inline + TextNode <#text> + BreakNode + TextNode <#text> + BlockContainer

at (8,124) content-size 784x17 children: inline + frag 0 from TextNode start: 0, length: 3, rect: [8,124 27.15625x17] baseline: 13.296875 + "foo" + TextNode <#text> + BlockContainer <(anonymous)> at (8,157) content-size 784x0 children: inline + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x157] + PaintableWithLines (BlockContainer) [8,8 784x133] + PaintableWithLines (BlockContainer

.a) [8,8 100x100] + PaintableWithLines (BlockContainer(anonymous)) [8,8 784x17] + PaintableWithLines (BlockContainer

) [8,124 784x17] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,157 784x0] diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break.txt b/Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-inline.txt similarity index 100% rename from Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break.txt rename to Tests/LibWeb/Layout/expected/block-and-inline/float-clear-by-line-break-followed-by-inline.txt diff --git a/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html new file mode 100644 index 00000000000..b14b79a9186 --- /dev/null +++ b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-block.html @@ -0,0 +1,15 @@ + + +

+
+

foo

diff --git a/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break.html b/Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-inline.html similarity index 100% rename from Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break.html rename to Tests/LibWeb/Layout/input/block-and-inline/float-clear-by-line-break-followed-by-inline.html