mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 20:15:17 +00:00
LibWeb: Support alignment of abspos grid items
Grid items should respect alignment properties if top/right/bottom/left are not specified. This change adds a separate implementation of layout_absolutely_positioned_element that is extended with support for alignment.
This commit is contained in:
parent
2def1de4be
commit
719b12b19d
Notes:
sideshowbarker
2024-07-17 06:35:16 +09:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/SerenityOS/serenity/commit/719b12b19d Pull-request: https://github.com/SerenityOS/serenity/pull/21526
4 changed files with 120 additions and 0 deletions
|
@ -0,0 +1,11 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (1,1) content-size 798x220 [BFC] children: not-inline
|
||||
BlockContainer <body> at (10,10) content-size 780x202 children: not-inline
|
||||
Box <div.container> at (11,11) content-size 200x200 positioned [GFC] children: not-inline
|
||||
BlockContainer <div.box> at (61,61) content-size 100x100 positioned [BFC] children: not-inline
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x222]
|
||||
PaintableWithLines (BlockContainer<BODY>) [9,9 782x204]
|
||||
PaintableBox (Box<DIV>.container) [10,10 202x202]
|
||||
PaintableWithLines (BlockContainer<DIV>.box) [60,60 102x102]
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html><style type="text/css">
|
||||
* {
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.box {
|
||||
position: absolute;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
</style><div class="container"><div class="box"></div></div>
|
|
@ -1879,6 +1879,95 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
|
|||
}
|
||||
}
|
||||
|
||||
void GridFormattingContext::layout_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space)
|
||||
{
|
||||
auto& containing_block_state = m_state.get_mutable(*box.containing_block());
|
||||
auto& box_state = m_state.get_mutable(box);
|
||||
auto const& computed_values = box.computed_values();
|
||||
|
||||
// The border computed values are not changed by the compute_height & width calculations below.
|
||||
// The spec only adjusts and computes sizes, insets and margins.
|
||||
box_state.border_left = box.computed_values().border_left().width;
|
||||
box_state.border_right = box.computed_values().border_right().width;
|
||||
box_state.border_top = box.computed_values().border_top().width;
|
||||
box_state.border_bottom = box.computed_values().border_bottom().width;
|
||||
|
||||
compute_width_for_absolutely_positioned_element(box, available_space);
|
||||
|
||||
// NOTE: We compute height before *and* after doing inside layout.
|
||||
// This is done so that inside layout can resolve percentage heights.
|
||||
// In some situations, e.g with non-auto top & bottom values, the height can be determined early.
|
||||
compute_height_for_absolutely_positioned_element(box, available_space, BeforeOrAfterInsideLayout::Before);
|
||||
|
||||
auto independent_formatting_context = layout_inside(box, LayoutMode::Normal, box_state.available_inner_space_or_constraints_from(available_space));
|
||||
|
||||
compute_height_for_absolutely_positioned_element(box, available_space, BeforeOrAfterInsideLayout::After);
|
||||
|
||||
if (computed_values.inset().left().is_auto() && computed_values.inset().right().is_auto()) {
|
||||
auto containing_block_width = containing_block_state.content_width();
|
||||
auto width_left_for_alignment = containing_block_width - box_state.margin_box_width();
|
||||
switch (justification_for_item(box)) {
|
||||
case CSS::JustifyItems::Normal:
|
||||
case CSS::JustifyItems::Stretch:
|
||||
break;
|
||||
case CSS::JustifyItems::Center:
|
||||
box_state.inset_left = width_left_for_alignment / 2;
|
||||
box_state.inset_right = width_left_for_alignment / 2;
|
||||
break;
|
||||
case CSS::JustifyItems::Start:
|
||||
case CSS::JustifyItems::FlexStart:
|
||||
box_state.inset_right = width_left_for_alignment;
|
||||
break;
|
||||
case CSS::JustifyItems::End:
|
||||
case CSS::JustifyItems::FlexEnd:
|
||||
box_state.inset_left = width_left_for_alignment;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (computed_values.inset().top().is_auto() && computed_values.inset().bottom().is_auto()) {
|
||||
auto containing_block_height = containing_block_state.content_height();
|
||||
auto height_left_for_alignment = containing_block_height - box_state.margin_box_height();
|
||||
switch (alignment_for_item(box)) {
|
||||
case CSS::AlignItems::Baseline:
|
||||
// FIXME: Not implemented
|
||||
case CSS::AlignItems::Stretch:
|
||||
case CSS::AlignItems::Normal:
|
||||
break;
|
||||
case CSS::AlignItems::Start:
|
||||
case CSS::AlignItems::FlexStart:
|
||||
case CSS::AlignItems::SelfStart:
|
||||
box_state.inset_bottom = height_left_for_alignment;
|
||||
break;
|
||||
case CSS::AlignItems::End:
|
||||
case CSS::AlignItems::SelfEnd:
|
||||
case CSS::AlignItems::FlexEnd: {
|
||||
box_state.inset_top = height_left_for_alignment;
|
||||
break;
|
||||
}
|
||||
case CSS::AlignItems::Center:
|
||||
box_state.inset_top = height_left_for_alignment / 2;
|
||||
box_state.inset_bottom = height_left_for_alignment / 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CSSPixelPoint used_offset;
|
||||
used_offset.set_x(box_state.inset_left + box_state.margin_box_left());
|
||||
used_offset.set_y(box_state.inset_top + box_state.margin_box_top());
|
||||
|
||||
// NOTE: Absolutely positioned boxes are relative to the *padding edge* of the containing block.
|
||||
used_offset.translate_by(-containing_block_state.padding_left, -containing_block_state.padding_top);
|
||||
box_state.set_content_offset(used_offset);
|
||||
|
||||
if (independent_formatting_context)
|
||||
independent_formatting_context->parent_context_did_dimension_child_root_box();
|
||||
}
|
||||
|
||||
void GridFormattingContext::parent_context_did_dimension_child_root_box()
|
||||
{
|
||||
grid_container().for_each_child_of_type<Box>([&](Layout::Box& box) {
|
||||
|
|
|
@ -223,6 +223,7 @@ private:
|
|||
void determine_grid_container_height();
|
||||
void determine_intrinsic_size_of_grid_container(AvailableSpace const& available_space);
|
||||
|
||||
void layout_absolutely_positioned_element(Box const&, AvailableSpace const&);
|
||||
virtual void parent_context_did_dimension_child_root_box() override;
|
||||
|
||||
void resolve_grid_item_widths();
|
||||
|
|
Loading…
Add table
Reference in a new issue