diff --git a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp index 4d1424a423c..a11d60753b4 100644 --- a/Libraries/LibWeb/Layout/BlockFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/BlockFormattingContext.cpp @@ -672,8 +672,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain if (box.is_absolutely_positioned()) { StaticPositionRect static_position; - auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block()); - static_position.rect = { offset_to_static_parent.location().translated(0, m_y_offset_of_current_block_container.value()), { 0, 0 } }; + static_position.rect = { { 0, m_y_offset_of_current_block_container.value() }, { 0, 0 } }; box_state.set_static_position_rect(static_position); return; } diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index ae8a73cba60..28a72296edd 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -2253,14 +2253,11 @@ StaticPositionRect FlexFormattingContext::calculate_static_position_rect(Box con break; } - auto absolute_position_of_flex_container = absolute_content_rect(flex_container()).location(); - auto absolute_position_of_abspos_containing_block = absolute_content_rect(*box.containing_block()).location(); - auto flex_container_width = is_row_layout() ? inner_main_size(m_flex_container_state) : inner_cross_size(m_flex_container_state); auto flex_container_height = is_row_layout() ? inner_cross_size(m_flex_container_state) : inner_main_size(m_flex_container_state); StaticPositionRect static_position_rect; - static_position_rect.rect = { absolute_position_of_flex_container - absolute_position_of_abspos_containing_block, { flex_container_width, flex_container_height } }; + static_position_rect.rect = { { 0, 0 }, { flex_container_width, flex_container_height } }; static_position_rect.horizontal_alignment = is_row_layout() ? main_axis_alignment : cross_axis_alignment; static_position_rect.vertical_alignment = is_row_layout() ? cross_axis_alignment : main_axis_alignment; return static_position_rect; diff --git a/Libraries/LibWeb/Layout/FormattingContext.cpp b/Libraries/LibWeb/Layout/FormattingContext.cpp index 37bdf7d584d..6acb33d1c6f 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -1179,7 +1179,6 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el box_state.margin_bottom = margin_bottom.to_px(box, width_of_containing_block); } -// NOTE: This is different from content_box_rect_in_ancestor_coordinate_space() as this does *not* follow the containing block chain up, but rather the parent() chain. CSSPixelRect FormattingContext::content_box_rect_in_static_position_ancestor_coordinate_space(Box const& box, Box const& ancestor_box) const { auto rect = content_box_rect(box); @@ -1261,6 +1260,8 @@ void FormattingContext::layout_absolutely_positioned_element(Box const& box, Ava CSSPixelPoint used_offset; auto static_position = m_state.get(box).static_position(); + auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block()); + static_position += offset_to_static_parent.location(); if (box.computed_values().inset().top().is_auto() && box.computed_values().inset().bottom().is_auto()) { used_offset.set_y(static_position.y()); diff --git a/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 2768d4832c5..94ba44d5177 100644 --- a/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -2632,8 +2632,7 @@ StaticPositionRect GridFormattingContext::calculate_static_position_rect(Box con // layout_absolutely_positioned_element() defined for GFC knows how to handle this case. StaticPositionRect static_position; auto const& box_state = m_state.get(box); - auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block()); - static_position.rect = { offset_to_static_parent.location().translated(0, 0), { box_state.content_width(), box_state.content_height() } }; + static_position.rect = { { 0, 0 }, { box_state.content_width(), box_state.content_height() } }; return static_position; } } diff --git a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp index 28f2b8fe732..50469a5d922 100644 --- a/Libraries/LibWeb/Layout/InlineFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/InlineFormattingContext.cpp @@ -411,6 +411,16 @@ void InlineFormattingContext::generate_line_boxes() } } + for (auto& line_box : line_boxes) { + for (auto& fragment : line_box.fragments()) { + if (fragment.layout_node().is_inline_block()) { + auto& box = as(fragment.layout_node()); + auto& box_state = m_state.get_mutable(box); + box_state.set_content_offset(fragment.offset()); + } + } + } + for (auto* box : absolute_boxes) { auto& box_state = m_state.get_mutable(*box); box_state.set_static_position_rect(calculate_static_position_rect(*box)); @@ -494,9 +504,8 @@ StaticPositionRect InlineFormattingContext::calculate_static_position_rect(Box c } else { // Easy case: no previous sibling, we're at the top of the containing block. } - auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block()); StaticPositionRect static_position_rect; - static_position_rect.rect = { offset_to_static_parent.location().translated(x, y), { 0, 0 } }; + static_position_rect.rect = { { x, y }, { 0, 0 } }; return static_position_rect; } diff --git a/Libraries/LibWeb/Layout/LayoutState.h b/Libraries/LibWeb/Layout/LayoutState.h index dd913fbd3bf..e39ab1b2b05 100644 --- a/Libraries/LibWeb/Layout/LayoutState.h +++ b/Libraries/LibWeb/Layout/LayoutState.h @@ -90,6 +90,7 @@ struct LayoutState { void set_content_x(CSSPixels x) { offset.set_x(x); } void set_content_y(CSSPixels y) { offset.set_y(y); } + // offset from top-left corner of content area of box's containing block to top-left corner of box's content area CSSPixelPoint offset; SizeConstraint width_constraint { SizeConstraint::None }; diff --git a/Libraries/LibWeb/Layout/Node.cpp b/Libraries/LibWeb/Layout/Node.cpp index 7d98c5853b8..275fcb37d5a 100644 --- a/Libraries/LibWeb/Layout/Node.cpp +++ b/Libraries/LibWeb/Layout/Node.cpp @@ -140,6 +140,7 @@ Box const* Node::containing_block() const return nearest_ancestor_capable_of_forming_a_containing_block(*this); } +// returns containing block this node would have had if its position was static Box const* Node::static_position_containing_block() const { return nearest_ancestor_capable_of_forming_a_containing_block(*this); diff --git a/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 43611e759cc..c9e80f33522 100644 --- a/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -1853,12 +1853,11 @@ CSSPixels TableFormattingContext::border_spacing_vertical() const return computed_values.border_spacing_vertical().to_px(table_box()); } -StaticPositionRect TableFormattingContext::calculate_static_position_rect(Box const& box) const +StaticPositionRect TableFormattingContext::calculate_static_position_rect(Box const&) const { // FIXME: Implement static position calculation for table descendants instead of always returning a rectangle with zero position and size. StaticPositionRect static_position; - auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block()); - static_position.rect = { offset_to_static_parent.location(), { 0, 0 } }; + static_position.rect = { { 0, 0 }, { 0, 0 } }; return static_position; } diff --git a/Tests/LibWeb/Layout/expected/blockify-layout-internal-box-without-crashing.txt b/Tests/LibWeb/Layout/expected/blockify-layout-internal-box-without-crashing.txt index 6ee93b215d0..e0c6559f28e 100644 --- a/Tests/LibWeb/Layout/expected/blockify-layout-internal-box-without-crashing.txt +++ b/Tests/LibWeb/Layout/expected/blockify-layout-internal-box-without-crashing.txt @@ -6,7 +6,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline Box at (10,10) content-size 0x0 table-row-group children: not-inline Box at (10,10) content-size 0x0 table-row children: not-inline BlockContainer <(anonymous)> at (10,10) content-size 0x0 table-cell [BFC] children: not-inline - BlockContainer at (9,9) content-size 0x0 positioned [BFC] children: not-inline + BlockContainer at (11,11) content-size 0x0 positioned [BFC] children: not-inline ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x20] @@ -16,4 +16,4 @@ ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableBox (Box) [10,10 0x0] PaintableBox (Box) [10,10 0x0] PaintableWithLines (BlockContainer(anonymous)) [10,10 0x0] - PaintableWithLines (BlockContainer) [8,8 2x2] + PaintableWithLines (BlockContainer) [10,10 2x2] diff --git a/Tests/LibWeb/Ref/expected/wpt-import/css/CSS2/abspos/static-inside-inline-block-ref.html b/Tests/LibWeb/Ref/expected/wpt-import/css/CSS2/abspos/static-inside-inline-block-ref.html new file mode 100644 index 00000000000..e76a2ccb972 --- /dev/null +++ b/Tests/LibWeb/Ref/expected/wpt-import/css/CSS2/abspos/static-inside-inline-block-ref.html @@ -0,0 +1,11 @@ + +Static position inside inline-block + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
+
diff --git a/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/abspos/static-inside-inline-block.html b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/abspos/static-inside-inline-block.html new file mode 100644 index 00000000000..f646ffff70f --- /dev/null +++ b/Tests/LibWeb/Ref/input/wpt-import/css/CSS2/abspos/static-inside-inline-block.html @@ -0,0 +1,12 @@ + +Static position inside inline-block + + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
+