mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-24 10:22:05 -05:00
LibWeb: Handle overlapping floating box and left margin
Allow the left margin of a box which creates a block formatting context to overlap with left floating boxes which are siblings in the document tree. Fixes #20233 and the comment layout on https://lobste.rs.
This commit is contained in:
parent
34c702e6e8
commit
6a17a30e2e
6 changed files with 100 additions and 2 deletions
|
@ -8,12 +8,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
|||
BlockContainer <div.ab> at (108,8) content-size 684x17.46875 children: not-inline
|
||||
BlockContainer <(anonymous)> at (108,8) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div> at (108,8) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.a> at (108,8) content-size 14.265625x17.46875 floating [BFC] children: inline
|
||||
line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [108,8 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (108,8) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.b> at (122.265625,8) content-size 669.734375x17.46875 [BFC] children: inline
|
||||
line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [122.265625,8 9.34375x17.46875]
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
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.9375 children: not-inline
|
||||
BlockContainer <div> at (8,8) content-size 784x34.9375 children: not-inline
|
||||
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div> at (8,8) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.a> at (8,8) content-size 57.0625x34.9375 floating [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (8,8) content-size 57.0625x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.a4> at (8,8) content-size 57.0625x17.46875 children: inline
|
||||
line 0 width: 57.0625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 4, rect: [8,8 57.0625x17.46875]
|
||||
"AAAA"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,25.46875) content-size 57.0625x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div> at (8,25.46875) content-size 57.0625x17.46875 children: inline
|
||||
line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [8,25.46875 14.265625x17.46875]
|
||||
"A"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,42.9375) content-size 57.0625x0 children: inline
|
||||
TextNode <#text>
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div> at (108,8) content-size 684x34.9375 children: not-inline
|
||||
BlockContainer <(anonymous)> at (108,8) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div> at (108,8) content-size 684x17.46875 children: inline
|
||||
line 0 width: 9.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [108,8 9.34375x17.46875]
|
||||
"B"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (108,25.46875) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <div.c> at (108,25.46875) content-size 684x17.46875 [BFC] children: inline
|
||||
line 0 width: 10.3125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||
frag 0 from TextNode start: 0, length: 1, rect: [108,25.46875 10.3125x17.46875]
|
||||
"C"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (108,42.9375) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,42.9375) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
<body>
|
||||
<div class="ab">
|
||||
<div class="a">A</div>
|
||||
<div>
|
||||
<div class="a">A</div>
|
||||
</div>
|
||||
<div class="b">B</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<style>
|
||||
.a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.a4 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.c {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div class="a">
|
||||
<div class="a4">AAAA</div>
|
||||
<div>A</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-left: 100px">
|
||||
<div>B</div>
|
||||
<div class="c">C</div>
|
||||
</div>
|
||||
</div>
|
|
@ -802,6 +802,18 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_vertically
|
|||
box_state.set_content_offset(CSSPixelPoint { box_state.offset.x(), y });
|
||||
}
|
||||
|
||||
// Returns whether the given box has the given ancestor on the path to root, ignoring the anonymous blocks.
|
||||
static bool box_has_ancestor_in_non_anonymous_containing_block_chain(Box const* box, Box const& ancestor, Box const& root)
|
||||
{
|
||||
Box const* current_ancestor = box ? box->non_anonymous_containing_block() : &root;
|
||||
while (current_ancestor != &root) {
|
||||
if (current_ancestor == &ancestor)
|
||||
return true;
|
||||
current_ancestor = current_ancestor->non_anonymous_containing_block();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontally(Box const& child_box, AvailableSpace const& available_space)
|
||||
{
|
||||
auto& box_state = m_state.get_mutable(child_box);
|
||||
|
@ -814,7 +826,12 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal
|
|||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(child_box, root());
|
||||
auto space_and_containing_margin = space_used_and_containing_margin_for_floats(box_in_root_rect.y());
|
||||
available_width_within_containing_block -= space_and_containing_margin.left_used_space + space_and_containing_margin.right_used_space;
|
||||
x += space_and_containing_margin.left_used_space;
|
||||
auto const& containing_box_state = m_state.get(*child_box.containing_block());
|
||||
if (box_has_ancestor_in_non_anonymous_containing_block_chain(space_and_containing_margin.matching_left_float_box, *child_box.non_anonymous_containing_block(), root()))
|
||||
x = space_and_containing_margin.left_used_space;
|
||||
else
|
||||
// If the floating box doesn't share a containing block with the child box, the child box margin should overlap with the width of the floating box.
|
||||
x = max(space_and_containing_margin.left_used_space - containing_box_state.margin_left, 0);
|
||||
}
|
||||
|
||||
if (child_box.containing_block()->computed_values().text_align() == CSS::TextAlign::LibwebCenter) {
|
||||
|
@ -1056,6 +1073,7 @@ BlockFormattingContext::SpaceUsedAndContainingMarginForFloats BlockFormattingCon
|
|||
+ floating_box_state.content_width()
|
||||
+ floating_box_state.margin_box_right();
|
||||
space_and_containing_margin.left_total_containing_margin = offset_from_containing_block_chain_margins_between_here_and_root;
|
||||
space_and_containing_margin.matching_left_float_box = floating_box.box.ptr();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ protected:
|
|||
// Each block in the containing chain adds its own margin and we store the total here.
|
||||
CSSPixels left_total_containing_margin;
|
||||
CSSPixels right_total_containing_margin;
|
||||
Box const* matching_left_float_box { nullptr };
|
||||
};
|
||||
|
||||
struct ShrinkToFitResult {
|
||||
|
|
Loading…
Add table
Reference in a new issue