1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 11:15:06 +00:00

LibWeb: Ensure preceding offset is non-negative in float_box()

When calculating the edge offset of the next floating item based on the
offset of the preceding floating item, we need to ensure that the
preceding offset is always > 0. This isn't explicitly written in the
spec, but all other popular engines do that.

Fixes https://github.com/SerenityOS/serenity/issues/21023
This commit is contained in:
Aliaksandr Kalenik 2023-09-12 00:58:51 +02:00 committed by Andreas Kling
parent 81ddad3fcf
commit d1e542999c
3 changed files with 51 additions and 1 deletions

View file

@ -0,0 +1,28 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x208 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 600x0 children: not-inline
BlockContainer <div#top> at (8,8) content-size 100x100 floating [BFC] children: inline
line 0 width: 26.640625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 3, rect: [8,8 26.640625x17.46875]
"top"
TextNode <#text>
BlockContainer <div#left> at (8,108) content-size 100x100 floating [BFC] children: inline
line 0 width: 26.25, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 4, rect: [8,108 26.25x17.46875]
"left"
TextNode <#text>
BlockContainer <div#right> at (208,108) content-size 100x100 floating [BFC] children: inline
line 0 width: 37.109375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 5, rect: [208,108 37.109375x17.46875]
"right"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x208]
PaintableWithLines (BlockContainer<BODY>) [8,8 600x0] overflow: [8,8 300x200]
PaintableWithLines (BlockContainer<DIV>#top) [8,8 100x100]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>#left) [8,108 100x100]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>#right) [208,108 100x100]
TextPaintable (TextNode<#text>)

View file

@ -0,0 +1,22 @@
<!DOCTYPE html><style>
* { outline: 1px solid black; }
body { width: 600px; }
div {
width: 100px;
height: 100px;
float: left;
}
#top {
background: green;
}
#left {
background: pink;
margin-right: -100%;
clear: both;
}
#right {
background: orange;
margin-left: 200px;
margin-right: -100%;
}
</style><body><div id="top">top</div><div id="left">left</div><div id="right">right

View file

@ -962,7 +962,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
CSSPixels tentative_offset_from_edge = 0; CSSPixels tentative_offset_from_edge = 0;
bool fits_next_to_preceding_float = false; bool fits_next_to_preceding_float = false;
if (side == FloatSide::Left) { if (side == FloatSide::Left) {
tentative_offset_from_edge = preceding_float.offset_from_edge + preceding_float_state.content_width() + preceding_float_state.margin_box_right() + box_state.margin_box_left(); tentative_offset_from_edge = max(preceding_float.offset_from_edge + preceding_float_state.content_width() + preceding_float_state.margin_box_right(), 0) + box_state.margin_box_left();
if (available_space.width.is_definite()) { if (available_space.width.is_definite()) {
fits_next_to_preceding_float = (tentative_offset_from_edge + box_state.content_width() + box_state.margin_box_right()) <= available_space.width.to_px_or_zero(); fits_next_to_preceding_float = (tentative_offset_from_edge + box_state.content_width() + box_state.margin_box_right()) <= available_space.width.to_px_or_zero();
} else if (available_space.width.is_max_content() || available_space.width.is_indefinite()) { } else if (available_space.width.is_max_content() || available_space.width.is_indefinite()) {