LibWeb: Apply vertical clearance to next line after <br> with clear:

We were introducing a line break and applying vertical clearance to the
inline formatting context, but that vertical clearance only applied to
new floating boxes. We should move the current block offset to the
vertical clearance to make sure the next line box starts beyond the
cleared floats.

There was a layout test for `<br>` with `clear: ..` set, but that test
did not actually do anything - removing the `clear` property would
result in the same layout. Replace that test with something that
actually tests float clearing.

Relates to #4058.
This commit is contained in:
Jelle Raaijmakers 2025-03-27 11:34:20 +00:00
parent fbdabace8e
commit 9dcc505e46
4 changed files with 25 additions and 45 deletions

View file

@ -13,8 +13,6 @@
#include <LibWeb/Layout/InlineFormattingContext.h>
#include <LibWeb/Layout/InlineLevelIterator.h>
#include <LibWeb/Layout/LineBuilder.h>
#include <LibWeb/Layout/ReplacedBox.h>
#include <LibWeb/Layout/SVGSVGBox.h>
namespace Web::Layout {
@ -285,8 +283,10 @@ void InlineFormattingContext::generate_line_boxes()
line_builder.break_line(LineBuilder::ForcedBreak::Yes);
if (item.node) {
auto introduce_clearance = parent().clear_floating_boxes(*item.node, *this);
if (introduce_clearance == BlockFormattingContext::DidIntroduceClearance::Yes)
if (introduce_clearance == BlockFormattingContext::DidIntroduceClearance::Yes) {
line_builder.set_current_block_offset(vertical_float_clearance());
parent().reset_margin_state();
}
}
break;
}
@ -392,9 +392,8 @@ void InlineFormattingContext::generate_line_boxes()
}
}
for (auto& line_box : line_boxes) {
for (auto& line_box : line_boxes)
line_box.trim_trailing_whitespace();
}
line_builder.remove_last_line_if_empty();

View file

@ -8,7 +8,6 @@
#include <AK/Utf8View.h>
#include <LibWeb/DOM/Position.h>
#include <LibWeb/Layout/Box.h>
#include <LibWeb/Layout/BreakNode.h>
#include <LibWeb/Layout/LineBox.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Layout/TextNode.h>

View file

@ -1,34 +1,15 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x34 children: inline
BlockContainer <span.a> at (8,8) content-size 100x17 floating [BFC] children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 14.265625x17] baseline: 13.296875
"A"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [108,8 6.34375x17] baseline: 13.296875
"1"
TextNode <#text>
BlockContainer <html> at (0,0) content-size 800x133 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x117 children: inline
frag 0 from TextNode start: 1, length: 3, rect: [8,108 27.15625x17] baseline: 13.296875
"foo"
BlockContainer <div.a> at (8,8) content-size 100x100 floating [BFC] children: not-inline
TextNode <#text>
BreakNode <br>
BreakNode <br.b>
TextNode <#text>
BlockContainer <span.a> at (8,25) content-size 100x17 floating [BFC] children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,25 9.34375x17] baseline: 13.296875
"B"
TextNode <#text>
InlineNode <span>
frag 0 from TextNode start: 0, length: 1, rect: [108,25 8.8125x17] baseline: 13.296875
"2"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x34]
PaintableWithLines (BlockContainer<SPAN>.a) [8,8 100x17]
TextPaintable (TextNode<#text>)
PaintableWithLines (InlineNode<SPAN>)
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<SPAN>.a) [8,25 100x17]
TextPaintable (TextNode<#text>)
PaintableWithLines (InlineNode<SPAN>)
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<HTML>) [0,0 800x133]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x117]
PaintableWithLines (BlockContainer<DIV>.a) [8,8 100x100]
TextPaintable (TextNode<#text>)

View file

@ -1,14 +1,15 @@
<!DOCTYPE html>
<style>
.a {
.a {
background: green;
float: left;
height: 100px;
width: 100px;
}
br {
clear: left;
}
}
.b {
clear: both;
}
</style>
<span class="a">A</span><span>1</span>
<br>
<span class="a">B</span><span>2</span>
<div class="a"></div>
<br class="b">
foo