From c49c036c840177bdd052a68cd99d39df06d79d70 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 27 Mar 2022 15:29:00 +0200 Subject: [PATCH] LibWeb: Stop allowing position:relative to affect layout Relatively positioned boxes should not affect the *layout* of their siblings. So instead of applying relative inset as a layout-time translation on the box, we now perform the adjustment at the paintable level instead. This makes position:relative actually work as expected, and exposes some new bugs we need to take care of for Acid2. :^) --- .../LibWeb/Layout/BlockFormattingContext.cpp | 7 +++---- Userland/Libraries/LibWeb/Painting/PaintableBox.cpp | 11 +++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 7ff85556f66..b342858f2bc 100644 --- a/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -438,8 +438,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_vertically compute_vertical_box_model_metrics(child_box, containing_block); - float y = box_state.border_box_top() - + box_state.inset_top; + float y = box_state.border_box_top(); Vector collapsible_margins; @@ -529,7 +528,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_horizontal if (containing_block.computed_values().text_align() == CSS::TextAlign::LibwebCenter) { x += (available_width_within_containing_block / 2) - box_state.content_width / 2; } else { - x += box_state.margin_box_left() + box_state.inset_left; + x += box_state.margin_box_left(); } box_state.offset = Gfx::FloatPoint { x, box_state.offset.y() }; @@ -592,7 +591,7 @@ void BlockFormattingContext::layout_floating_box(Box const& box, BlockContainer // First we place the box normally (to get the right y coordinate.) // If we have a LineBuilder, we're in the middle of inline layout, otherwise this is block layout. if (line_builder) { - float y_offset = box_state.margin_box_top() + box_state.inset_top; + float y_offset = box_state.margin_box_top(); line_builder->break_if_needed(layout_mode, box_state.border_box_width()); box_state.offset.set_y(line_builder->current_y() + y_offset); line_builder->adjust_last_line_after_inserting_floating_box({}, box.computed_values().float_(), box_state.border_box_width()); diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index 1f533ed3092..007d8848691 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -59,11 +59,18 @@ void PaintableBox::set_content_size(Gfx::FloatSize const& size) Gfx::FloatPoint PaintableBox::effective_offset() const { + Gfx::FloatPoint offset; if (m_containing_line_box_fragment.has_value()) { auto const& fragment = containing_block()->paint_box()->line_boxes()[m_containing_line_box_fragment->line_box_index].fragments()[m_containing_line_box_fragment->fragment_index]; - return fragment.offset(); + offset = fragment.offset(); + } else { + offset = m_offset; } - return m_offset; + if (layout_box().computed_values().position() == CSS::Position::Relative) { + auto const& inset = layout_box().box_model().inset; + offset.translate_by(inset.left, inset.top); + } + return offset; } Gfx::FloatRect PaintableBox::compute_absolute_rect() const