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. :^)
This commit is contained in:
Andreas Kling 2022-03-27 15:29:00 +02:00
parent 153370e7f4
commit c49c036c84
Notes: sideshowbarker 2024-07-17 16:40:53 +09:00
2 changed files with 12 additions and 6 deletions

View file

@ -438,8 +438,7 @@ void BlockFormattingContext::place_block_level_element_in_normal_flow_vertically
compute_vertical_box_model_metrics(child_box, containing_block); compute_vertical_box_model_metrics(child_box, containing_block);
float y = box_state.border_box_top() float y = box_state.border_box_top();
+ box_state.inset_top;
Vector<float> collapsible_margins; Vector<float> 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) { if (containing_block.computed_values().text_align() == CSS::TextAlign::LibwebCenter) {
x += (available_width_within_containing_block / 2) - box_state.content_width / 2; x += (available_width_within_containing_block / 2) - box_state.content_width / 2;
} else { } 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() }; 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.) // 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 we have a LineBuilder, we're in the middle of inline layout, otherwise this is block layout.
if (line_builder) { 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()); line_builder->break_if_needed(layout_mode, box_state.border_box_width());
box_state.offset.set_y(line_builder->current_y() + y_offset); 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()); line_builder->adjust_last_line_after_inserting_floating_box({}, box.computed_values().float_(), box_state.border_box_width());

View file

@ -59,11 +59,18 @@ void PaintableBox::set_content_size(Gfx::FloatSize const& size)
Gfx::FloatPoint PaintableBox::effective_offset() const Gfx::FloatPoint PaintableBox::effective_offset() const
{ {
Gfx::FloatPoint offset;
if (m_containing_line_box_fragment.has_value()) { 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]; 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 Gfx::FloatRect PaintableBox::compute_absolute_rect() const