1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:57:35 +00:00

LibWeb: Account for absolutely positioned table wrappers

Table wrappers don't quite behave the same as most elements, in that
their computed height and width are not meant to be used for layout.
Instead, we now calculate suitable widths and heights based on the
contents of the table wrapper when performing absolute layout.

Fixes the layout of
http://wpt.live/css/css-position/position-absolute-center-007.html
This commit is contained in:
implicitfield 2024-03-04 22:11:04 +04:00 committed by Andreas Kling
parent 096ddb0021
commit 0243278587
6 changed files with 333 additions and 188 deletions

View file

@ -410,48 +410,6 @@ void BlockFormattingContext::compute_width_for_block_level_replaced_element_in_n
box_state.padding_right = padding_right;
}
CSSPixels BlockFormattingContext::compute_table_box_width_inside_table_wrapper(Box const& box, AvailableSpace const& available_space)
{
// 17.5.2
// Table wrapper width should be equal to width of table box it contains
auto const& computed_values = box.computed_values();
auto width_of_containing_block = available_space.width.to_px_or_zero();
auto zero_value = CSS::Length::make_px(0);
auto margin_left = computed_values.margin().left().resolved(box, width_of_containing_block);
auto margin_right = computed_values.margin().right().resolved(box, width_of_containing_block);
// If 'margin-left', or 'margin-right' are computed as 'auto', their used value is '0'.
if (margin_left.is_auto())
margin_left = zero_value;
if (margin_right.is_auto())
margin_right = zero_value;
// table-wrapper can't have borders or paddings but it might have margin taken from table-root.
auto available_width = width_of_containing_block - margin_left.to_px(box) - margin_right.to_px(box);
LayoutState throwaway_state(&m_state);
auto context = create_independent_formatting_context_if_needed(throwaway_state, box);
VERIFY(context);
context->run(box, LayoutMode::IntrinsicSizing, m_state.get(box).available_inner_space_or_constraints_from(available_space));
Optional<Box const&> table_box;
box.for_each_in_subtree_of_type<Box>([&](Box const& child_box) {
if (child_box.display().is_table_inside()) {
table_box = child_box;
return IterationDecision::Break;
}
return IterationDecision::Continue;
});
VERIFY(table_box.has_value());
auto table_used_width = throwaway_state.get(*table_box).border_box_width();
return available_space.width.is_definite() ? min(table_used_width, available_width) : table_used_width;
}
void BlockFormattingContext::compute_height(Box const& box, AvailableSpace const& available_space)
{
auto const& computed_values = box.computed_values();