mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 19:59:17 +00:00
LibWeb: Ensure floats are correctly placed under the preceding float
Previously floats would be placed next to the highest float that fitted the new float on its line. However, this violates the rule that floats should be placed under the preceding float if it does not fit next to it.
This commit is contained in:
parent
3bf7f94150
commit
09f5ce42f6
Notes:
github-actions[bot]
2025-05-23 08:59:19 +00:00
Author: https://github.com/rubenqwertyuiop 🔰
Commit: 09f5ce42f6
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4805
Reviewed-by: https://github.com/gmta ✅
5 changed files with 94 additions and 17 deletions
|
@ -1147,6 +1147,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer
|
|||
.margin_box_rect_in_root_coordinate_space = margin_box_rect_in_ancestor_coordinate_space(box_state, root()),
|
||||
}));
|
||||
side_data.current_boxes.append(*side_data.all_boxes.last());
|
||||
m_last_inserted_float = *side_data.all_boxes.last();
|
||||
|
||||
if (side == FloatSide::Left) {
|
||||
side_data.current_width = offset_from_edge + box_state.content_width() + box_state.margin_box_right();
|
||||
|
|
|
@ -74,6 +74,25 @@ public:
|
|||
|
||||
void reset_margin_state() { m_margin_state.reset(); }
|
||||
|
||||
struct FloatingBox {
|
||||
GC::Ref<Box const> box;
|
||||
|
||||
LayoutState::UsedValues& used_values;
|
||||
|
||||
// Offset from left/right edge to the left content edge of `box`.
|
||||
CSSPixels offset_from_edge { 0 };
|
||||
|
||||
// Top margin edge of `box`.
|
||||
CSSPixels top_margin_edge { 0 };
|
||||
|
||||
// Bottom margin edge of `box`.
|
||||
CSSPixels bottom_margin_edge { 0 };
|
||||
|
||||
CSSPixelRect margin_box_rect_in_root_coordinate_space;
|
||||
};
|
||||
|
||||
Optional<FloatingBox&> last_inserted_float() { return m_last_inserted_float; }
|
||||
|
||||
private:
|
||||
CSSPixels compute_auto_height_for_block_level_element(Box const&, AvailableSpace const&);
|
||||
|
||||
|
@ -99,23 +118,6 @@ private:
|
|||
Right,
|
||||
};
|
||||
|
||||
struct FloatingBox {
|
||||
GC::Ref<Box const> box;
|
||||
|
||||
LayoutState::UsedValues& used_values;
|
||||
|
||||
// Offset from left/right edge to the left content edge of `box`.
|
||||
CSSPixels offset_from_edge { 0 };
|
||||
|
||||
// Top margin edge of `box`.
|
||||
CSSPixels top_margin_edge { 0 };
|
||||
|
||||
// Bottom margin edge of `box`.
|
||||
CSSPixels bottom_margin_edge { 0 };
|
||||
|
||||
CSSPixelRect margin_box_rect_in_root_coordinate_space;
|
||||
};
|
||||
|
||||
struct FloatSideData {
|
||||
// Floating boxes currently accumulating on this side.
|
||||
Vector<FloatingBox&> current_boxes;
|
||||
|
@ -189,6 +191,7 @@ private:
|
|||
|
||||
FloatSideData m_left_floats;
|
||||
FloatSideData m_right_floats;
|
||||
Optional<FloatingBox&> m_last_inserted_float;
|
||||
|
||||
bool m_was_notified_after_parent_dimensioned_my_root_box { false };
|
||||
};
|
||||
|
|
|
@ -129,6 +129,14 @@ CSSPixels LineBuilder::y_for_float_to_be_inserted_here(Box const& box)
|
|||
// Then, look for the next Y position where we can fit the new float.
|
||||
auto box_in_root_rect = m_context.parent().content_box_rect_in_ancestor_coordinate_space(box_state, m_context.parent().root());
|
||||
|
||||
// New floats will always be placed vertically at or below the lowest float.
|
||||
// This applies to all floats, so the last inserted float will always be the lowest.
|
||||
auto last_float = m_context.parent().last_inserted_float();
|
||||
if (last_float.has_value()) {
|
||||
auto float_box_top = last_float->margin_box_rect_in_root_coordinate_space.top() - box_in_root_rect.y();
|
||||
candidate_block_offset = max(candidate_block_offset, float_box_top);
|
||||
}
|
||||
|
||||
HashMap<CSSPixels, AvailableSize> available_space_cache;
|
||||
for (;;) {
|
||||
Optional<CSSPixels> highest_intersection_bottom;
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x168 [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <body> at (8,8) content-size 784x152 children: not-inline
|
||||
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.container> at (9,9) content-size 100x150 children: inline
|
||||
frag 0 from TextNode start: 1, length: 11, rect: [9,9 99.109375x18] baseline: 13.796875
|
||||
"abc abc abc"
|
||||
frag 1 from TextNode start: 13, length: 11, rect: [9,27 99.109375x18] baseline: 13.796875
|
||||
"abc abc abc"
|
||||
TextNode <#text>
|
||||
BlockContainer <div.left.w80.red> at (9,45) content-size 80x50 floating [BFC] children: not-inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.left.w40.yellow> at (9,95) content-size 40x50 floating [BFC] children: not-inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.left.w20.blue> at (49,95) content-size 20x50 floating [BFC] children: not-inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,160) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x168]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [0,0 800x0]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x152]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,8 784x0]
|
||||
PaintableWithLines (BlockContainer<DIV>.container) [8,8 102x152]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer<DIV>.left.w80.red) [9,45 80x50]
|
||||
PaintableWithLines (BlockContainer<DIV>.left.w40.yellow) [9,95 40x50]
|
||||
PaintableWithLines (BlockContainer<DIV>.left.w20.blue) [49,95 20x50]
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,160 784x0]
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<head>
|
||||
<style>
|
||||
.container {
|
||||
width: 100px;
|
||||
height: 150px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.w80 { width: 80px; }
|
||||
.w40 { width: 40px; }
|
||||
.w20 { width: 20px; }
|
||||
|
||||
.red { background: red; }
|
||||
.blue { background: blue; }
|
||||
.yellow { background: yellow; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
abc abc abc
|
||||
abc abc abc
|
||||
<div class="left w80 red"></div>
|
||||
<div class="left w40 yellow"></div>
|
||||
<div class="left w20 blue"></div>
|
||||
</div>
|
||||
</body>
|
Loading…
Add table
Add a link
Reference in a new issue