mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 13:30:31 +00:00
LibWeb: Fix the x coordinate of a block after a float
The margin from the containing blocks shouldn't be included in the amount by which we increment x after a float was places. That coordinate should be relative to the containing block. Fixes the comments layout on https://lobste.rs.
This commit is contained in:
parent
0db8ac7465
commit
ce186dca70
Notes:
sideshowbarker
2024-07-17 01:55:29 +09:00
Author: https://github.com/axgallo Commit: https://github.com/SerenityOS/serenity/commit/ce186dca70 Pull-request: https://github.com/SerenityOS/serenity/pull/19391 Reviewed-by: https://github.com/awesomekling
6 changed files with 86 additions and 19 deletions
|
@ -0,0 +1,25 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x33.46875 [BFC] children: not-inline
|
||||
BlockContainer <(anonymous)> at (0,0) content-size 800x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <body> at (8,8) content-size 784x17.46875 children: not-inline
|
||||
BlockContainer <(anonymous)> at (8,8) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
||||
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.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 <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]
|
||||
"B"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (108,25.46875) content-size 684x0 children: inline
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,25.46875) content-size 784x0 children: inline
|
||||
TextNode <#text>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>Block with hidden overflow after float</title>
|
||||
<style>
|
||||
.ab {
|
||||
margin-left: 100px;
|
||||
}
|
||||
|
||||
.a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.b {
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="ab">
|
||||
<div class="a">A</div>
|
||||
<div class="b">B</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -808,9 +808,9 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal
|
|||
if ((!m_left_floats.current_boxes.is_empty() || !m_right_floats.current_boxes.is_empty())
|
||||
&& creates_block_formatting_context(child_box)) {
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(child_box, root());
|
||||
auto space = space_used_by_floats(box_in_root_rect.y());
|
||||
available_width_within_containing_block -= space.left + space.right;
|
||||
x += space.left;
|
||||
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;
|
||||
}
|
||||
|
||||
if (child_box.containing_block()->computed_values().text_align() == CSS::TextAlign::LibwebCenter) {
|
||||
|
@ -1027,9 +1027,9 @@ void BlockFormattingContext::layout_list_item_marker(ListItemBox const& list_ite
|
|||
list_item_state.set_content_height(marker_state.content_height());
|
||||
}
|
||||
|
||||
BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_floats(CSSPixels y) const
|
||||
BlockFormattingContext::SpaceUsedAndContainingMarginForFloats BlockFormattingContext::space_used_and_containing_margin_for_floats(CSSPixels y) const
|
||||
{
|
||||
SpaceUsedByFloats space_used_by_floats;
|
||||
SpaceUsedAndContainingMarginForFloats space_and_containing_margin;
|
||||
|
||||
for (auto const& floating_box_ptr : m_left_floats.all_boxes.in_reverse()) {
|
||||
auto const& floating_box = *floating_box_ptr;
|
||||
|
@ -1042,10 +1042,10 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_
|
|||
auto const& containing_block_state = m_state.get(*containing_block);
|
||||
offset_from_containing_block_chain_margins_between_here_and_root += containing_block_state.margin_box_left();
|
||||
}
|
||||
space_used_by_floats.left = offset_from_containing_block_chain_margins_between_here_and_root
|
||||
+ floating_box.offset_from_edge
|
||||
space_and_containing_margin.left_used_space = floating_box.offset_from_edge
|
||||
+ 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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1061,14 +1061,14 @@ BlockFormattingContext::SpaceUsedByFloats BlockFormattingContext::space_used_by_
|
|||
auto const& containing_block_state = m_state.get(*containing_block);
|
||||
offset_from_containing_block_chain_margins_between_here_and_root += containing_block_state.margin_box_right();
|
||||
}
|
||||
space_used_by_floats.right = offset_from_containing_block_chain_margins_between_here_and_root
|
||||
+ floating_box.offset_from_edge
|
||||
space_and_containing_margin.right_used_space = floating_box.offset_from_edge
|
||||
+ floating_box_state.margin_box_left();
|
||||
space_and_containing_margin.right_total_containing_margin = offset_from_containing_block_chain_margins_between_here_and_root;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return space_used_by_floats;
|
||||
return space_and_containing_margin;
|
||||
}
|
||||
|
||||
FormattingContext::SpaceUsedByFloats BlockFormattingContext::intrusion_by_floats_into_box(Box const& box, CSSPixels y_in_box) const
|
||||
|
@ -1076,16 +1076,18 @@ FormattingContext::SpaceUsedByFloats BlockFormattingContext::intrusion_by_floats
|
|||
// NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(box, root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y() + y_in_box;
|
||||
auto space_used_by_floats_in_root = space_used_by_floats(y_in_root);
|
||||
auto space_and_containing_margin = space_used_and_containing_margin_for_floats(y_in_root);
|
||||
auto left_side_floats_limit_to_right = space_and_containing_margin.left_total_containing_margin + space_and_containing_margin.left_used_space;
|
||||
auto right_side_floats_limit_to_right = space_and_containing_margin.right_used_space + space_and_containing_margin.right_total_containing_margin;
|
||||
|
||||
auto left_intrusion = max(CSSPixels(0), space_used_by_floats_in_root.left - max(CSSPixels(0), box_in_root_rect.x()));
|
||||
auto left_intrusion = max(CSSPixels(0), left_side_floats_limit_to_right - max(CSSPixels(0), box_in_root_rect.x()));
|
||||
|
||||
CSSPixels offset_from_containing_block_chain_margins_between_here_and_root = 0;
|
||||
for (auto const* containing_block = static_cast<Box const*>(&box); containing_block && containing_block != &root(); containing_block = containing_block->containing_block()) {
|
||||
auto const& containing_block_state = m_state.get(*containing_block);
|
||||
offset_from_containing_block_chain_margins_between_here_and_root = max(offset_from_containing_block_chain_margins_between_here_and_root, containing_block_state.margin_box_right());
|
||||
}
|
||||
auto right_intrusion = max(CSSPixels(0), space_used_by_floats_in_root.right - offset_from_containing_block_chain_margins_between_here_and_root);
|
||||
auto right_intrusion = max(CSSPixels(0), right_side_floats_limit_to_right - offset_from_containing_block_chain_margins_between_here_and_root);
|
||||
|
||||
return { left_intrusion, right_intrusion };
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
void add_absolutely_positioned_box(Box const& box) { m_absolutely_positioned_boxes.append(box); }
|
||||
|
||||
SpaceUsedByFloats space_used_by_floats(CSSPixels y) const;
|
||||
SpaceUsedAndContainingMarginForFloats space_used_and_containing_margin_for_floats(CSSPixels y) const;
|
||||
SpaceUsedByFloats intrusion_by_floats_into_box(Box const&, CSSPixels y_in_box) const;
|
||||
|
||||
virtual CSSPixels greatest_child_width(Box const&) const override;
|
||||
|
|
|
@ -107,6 +107,16 @@ protected:
|
|||
CSSPixels right { 0 };
|
||||
};
|
||||
|
||||
struct SpaceUsedAndContainingMarginForFloats {
|
||||
// Width for left / right floats, including their own margins.
|
||||
CSSPixels left_used_space;
|
||||
CSSPixels right_used_space;
|
||||
// Left / right total margins from the outermost containing block to the floating element.
|
||||
// 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;
|
||||
};
|
||||
|
||||
struct ShrinkToFitResult {
|
||||
CSSPixels preferred_width { 0 };
|
||||
CSSPixels preferred_minimum_width { 0 };
|
||||
|
|
|
@ -41,15 +41,16 @@ CSSPixels InlineFormattingContext::leftmost_x_offset_at(CSSPixels y) const
|
|||
// NOTE: Floats are relative to the BFC root box, not necessarily the containing block of this IFC.
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y() + y;
|
||||
auto space = parent().space_used_by_floats(y_in_root);
|
||||
if (box_in_root_rect.x() >= space.left) {
|
||||
auto space_and_containing_margin = parent().space_used_and_containing_margin_for_floats(y_in_root);
|
||||
auto left_side_floats_limit_to_right = space_and_containing_margin.left_total_containing_margin + space_and_containing_margin.left_used_space;
|
||||
if (box_in_root_rect.x() >= left_side_floats_limit_to_right) {
|
||||
// The left edge of the containing block is to the right of the rightmost left-side float.
|
||||
// We start placing inline content at the left edge of the containing block.
|
||||
return 0;
|
||||
}
|
||||
// The left edge of the containing block is to the left of the rightmost left-side float.
|
||||
// We adjust the inline content insertion point by the overlap between the containing block and the float.
|
||||
return space.left - max(CSSPixels(0), box_in_root_rect.x());
|
||||
return left_side_floats_limit_to_right - max(CSSPixels(0), box_in_root_rect.x());
|
||||
}
|
||||
|
||||
CSSPixels InlineFormattingContext::available_space_for_line(CSSPixels y) const
|
||||
|
@ -319,8 +320,8 @@ bool InlineFormattingContext::any_floats_intrude_at_y(CSSPixels y) const
|
|||
{
|
||||
auto box_in_root_rect = content_box_rect_in_ancestor_coordinate_space(containing_block(), parent().root());
|
||||
CSSPixels y_in_root = box_in_root_rect.y() + y;
|
||||
auto space = parent().space_used_by_floats(y_in_root);
|
||||
return space.left > 0 || space.right > 0;
|
||||
auto space_and_containing_margin = parent().space_used_and_containing_margin_for_floats(y_in_root);
|
||||
return space_and_containing_margin.left_used_space > 0 || space_and_containing_margin.right_used_space > 0;
|
||||
}
|
||||
|
||||
bool InlineFormattingContext::can_fit_new_line_at_y(CSSPixels y) const
|
||||
|
|
Loading…
Reference in a new issue