mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-30 15:02:56 +00:00
LibWeb/Layout: Improve grid item sizing for replaced boxes
With this change we no longer stretch "width: auto" for replaced elements and also use "width calculation rules for block-level replaced elements", like suggested by the spec.
This commit is contained in:
parent
2dd657f530
commit
1f8e7c3cca
Notes:
github-actions[bot]
2025-03-20 02:37:49 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 1f8e7c3cca
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4011
13 changed files with 83 additions and 54 deletions
|
@ -1549,6 +1549,7 @@ void GridFormattingContext::resolve_grid_item_widths()
|
|||
{
|
||||
for (auto& item : m_grid_items) {
|
||||
CSSPixels containing_block_width = containing_block_size_for_item(item, GridDimension::Column);
|
||||
CSS::JustifyItems justification = justification_for_item(item.box);
|
||||
|
||||
auto const& computed_values = item.box->computed_values();
|
||||
auto const& computed_width = computed_values.width();
|
||||
|
@ -1559,16 +1560,15 @@ void GridFormattingContext::resolve_grid_item_widths()
|
|||
CSSPixels width;
|
||||
};
|
||||
|
||||
ItemAlignment initial {
|
||||
auto try_compute_width = [&item, containing_block_width, justification](CSSPixels a_width, CSS::Size const& computed_width) -> ItemAlignment {
|
||||
auto const& computed_values = item.box->computed_values();
|
||||
|
||||
ItemAlignment result = {
|
||||
.margin_left = item.used_values.margin_left,
|
||||
.margin_right = item.used_values.margin_right,
|
||||
.width = item.used_values.content_width()
|
||||
.width = a_width
|
||||
};
|
||||
|
||||
auto try_compute_width = [&](CSSPixels a_width, CSS::Size const& computed_width) -> ItemAlignment {
|
||||
ItemAlignment result = initial;
|
||||
result.width = a_width;
|
||||
|
||||
// Auto margins absorb positive free space prior to alignment via the box alignment properties.
|
||||
auto free_space_left_for_margins = containing_block_width - result.width - item.used_values.border_left - item.used_values.border_right - item.used_values.padding_left - item.used_values.padding_right - item.used_values.margin_left - item.used_values.margin_right;
|
||||
if (computed_values.margin().left().is_auto() && computed_values.margin().right().is_auto()) {
|
||||
|
@ -1578,13 +1578,14 @@ void GridFormattingContext::resolve_grid_item_widths()
|
|||
result.margin_left = free_space_left_for_margins;
|
||||
} else if (computed_values.margin().right().is_auto()) {
|
||||
result.margin_right = free_space_left_for_margins;
|
||||
} else if (computed_width.is_auto()) {
|
||||
} else if (computed_width.is_auto() && !item.box->is_replaced_box()) {
|
||||
result.width += free_space_left_for_margins;
|
||||
}
|
||||
|
||||
auto free_space_left_for_alignment = containing_block_width - a_width - item.used_values.border_left - item.used_values.border_right - item.used_values.padding_left - item.used_values.padding_right - item.used_values.margin_left - item.used_values.margin_right;
|
||||
switch (justification_for_item(item.box)) {
|
||||
switch (justification) {
|
||||
case CSS::JustifyItems::Normal:
|
||||
break;
|
||||
case CSS::JustifyItems::Stretch:
|
||||
break;
|
||||
case CSS::JustifyItems::Center:
|
||||
|
@ -1613,14 +1614,19 @@ void GridFormattingContext::resolve_grid_item_widths()
|
|||
|
||||
ItemAlignment used_alignment;
|
||||
AvailableSpace available_space { AvailableSize::make_definite(containing_block_width), AvailableSize::make_indefinite() };
|
||||
if (computed_width.is_auto()) {
|
||||
used_alignment = try_compute_width(calculate_fit_content_width(item.box, available_space), computed_width);
|
||||
} else if (computed_width.is_fit_content()) {
|
||||
if (item.box->is_replaced_box() && item.box->has_natural_width()) {
|
||||
auto width = tentative_width_for_replaced_element(item.box, computed_values.width(), available_space);
|
||||
used_alignment = try_compute_width(width, computed_width);
|
||||
} else {
|
||||
if (computed_width.is_auto() || computed_width.is_fit_content()) {
|
||||
auto fit_content_width = calculate_fit_content_width(item.box, available_space);
|
||||
used_alignment = try_compute_width(fit_content_width, computed_width);
|
||||
used_alignment = try_compute_width(calculate_fit_content_width(item.box, available_space), computed_width);
|
||||
} else {
|
||||
auto width_px = calculate_inner_width(item.box, available_space.width, computed_width);
|
||||
used_alignment = try_compute_width(width_px, computed_width);
|
||||
}
|
||||
}
|
||||
|
||||
if (!should_treat_max_width_as_none(item.box, m_available_space->width)) {
|
||||
auto max_width_px = calculate_inner_width(item.box, available_space.width, computed_values.max_width());
|
||||
|
@ -1648,6 +1654,7 @@ void GridFormattingContext::resolve_grid_item_heights()
|
|||
{
|
||||
for (auto& item : m_grid_items) {
|
||||
CSSPixels containing_block_height = containing_block_size_for_item(item, GridDimension::Row);
|
||||
CSS::AlignItems alignment = alignment_for_item(item.box);
|
||||
|
||||
auto const& computed_values = item.box->computed_values();
|
||||
auto const& computed_height = computed_values.height();
|
||||
|
@ -1658,16 +1665,15 @@ void GridFormattingContext::resolve_grid_item_heights()
|
|||
CSSPixels height;
|
||||
};
|
||||
|
||||
ItemAlignment initial {
|
||||
auto try_compute_height = [&item, containing_block_height, alignment](CSSPixels a_height) -> ItemAlignment {
|
||||
auto const& computed_values = item.box->computed_values();
|
||||
|
||||
ItemAlignment result = {
|
||||
.margin_top = item.used_values.margin_top,
|
||||
.margin_bottom = item.used_values.margin_bottom,
|
||||
.height = item.used_values.content_height()
|
||||
.height = a_height
|
||||
};
|
||||
|
||||
auto try_compute_height = [&](CSSPixels a_height) -> ItemAlignment {
|
||||
ItemAlignment result = initial;
|
||||
result.height = a_height;
|
||||
|
||||
CSSPixels height = a_height;
|
||||
auto underflow_px = containing_block_height - height - item.used_values.border_top - item.used_values.border_bottom - item.used_values.padding_top - item.used_values.padding_bottom - item.used_values.margin_top - item.used_values.margin_bottom;
|
||||
if (computed_values.margin().top().is_auto() && computed_values.margin().bottom().is_auto()) {
|
||||
|
@ -1678,13 +1684,14 @@ void GridFormattingContext::resolve_grid_item_heights()
|
|||
result.margin_top = underflow_px;
|
||||
} else if (computed_values.margin().bottom().is_auto()) {
|
||||
result.margin_bottom = underflow_px;
|
||||
} else if (computed_values.height().is_auto()) {
|
||||
} else if (computed_values.height().is_auto() && !item.box->is_replaced_box()) {
|
||||
height += underflow_px;
|
||||
}
|
||||
|
||||
switch (alignment_for_item(item.box)) {
|
||||
switch (alignment) {
|
||||
case CSS::AlignItems::Baseline:
|
||||
// FIXME: Not implemented
|
||||
break;
|
||||
case CSS::AlignItems::Stretch:
|
||||
case CSS::AlignItems::Normal:
|
||||
result.height = height;
|
||||
|
|
11
Tests/LibWeb/Layout/expected/grid/replaced-item-2.txt
Normal file
11
Tests/LibWeb/Layout/expected/grid/replaced-item-2.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x116 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 100x100 children: not-inline
|
||||
Box <div.img-wrapper> at (8,8) content-size 100x100 [GFC] children: not-inline
|
||||
ImageBox <img> at (8,8) content-size 10x10 children: not-inline
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x116]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 100x100]
|
||||
PaintableBox (Box<DIV>.img-wrapper) [8,8 100x100]
|
||||
ImagePaintable (ImageBox<IMG>) [8,8 10x10]
|
12
Tests/LibWeb/Layout/input/grid/replaced-item-2.html
Normal file
12
Tests/LibWeb/Layout/input/grid/replaced-item-2.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html><style>
|
||||
body {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.img-wrapper {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: darkorchid;
|
||||
}
|
||||
</style><div class="img-wrapper"><img src="data:image/webp;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAADUlEQVR4nGNgGAWkAwABNgABVtF/yAAAAABJRU5ErkJggg=="></div>
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
2 Fail
|
||||
1 Pass
|
||||
1 Fail
|
||||
Fail .before 1
|
||||
Fail .after 2
|
||||
Pass .after 2
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
2 Fail
|
||||
Fail .before 1
|
||||
1 Pass
|
||||
1 Fail
|
||||
Pass .before 1
|
||||
Fail .after 2
|
|
@ -2,7 +2,6 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
1 Pass
|
||||
1 Fail
|
||||
2 Pass
|
||||
Pass .before 1
|
||||
Fail .after 2
|
||||
Pass .after 2
|
|
@ -2,7 +2,6 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
1 Pass
|
||||
1 Fail
|
||||
Fail .before 1
|
||||
2 Pass
|
||||
Pass .before 1
|
||||
Pass .after 2
|
|
@ -2,6 +2,7 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
2 Fail
|
||||
1 Pass
|
||||
1 Fail
|
||||
Fail .before 1
|
||||
Fail .after 2
|
||||
Pass .after 2
|
|
@ -4,5 +4,5 @@ Found 2 tests
|
|||
|
||||
1 Pass
|
||||
1 Fail
|
||||
Fail .before 1
|
||||
Pass .after 2
|
||||
Pass .before 1
|
||||
Fail .after 2
|
|
@ -2,7 +2,6 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
1 Pass
|
||||
1 Fail
|
||||
2 Pass
|
||||
Pass .before 1
|
||||
Fail .after 2
|
||||
Pass .after 2
|
|
@ -2,7 +2,6 @@ Harness status: OK
|
|||
|
||||
Found 2 tests
|
||||
|
||||
1 Pass
|
||||
1 Fail
|
||||
Fail .before 1
|
||||
2 Pass
|
||||
Pass .before 1
|
||||
Pass .after 2
|
|
@ -2,11 +2,11 @@ Harness status: OK
|
|||
|
||||
Found 6 tests
|
||||
|
||||
1 Pass
|
||||
5 Fail
|
||||
3 Pass
|
||||
3 Fail
|
||||
Fail .before 1
|
||||
Fail .before 2
|
||||
Pass .before 2
|
||||
Fail .before 3
|
||||
Fail .after 4
|
||||
Pass .after 5
|
||||
Fail .after 6
|
||||
Pass .after 6
|
|
@ -2,11 +2,11 @@ Harness status: OK
|
|||
|
||||
Found 6 tests
|
||||
|
||||
1 Pass
|
||||
5 Fail
|
||||
3 Pass
|
||||
3 Fail
|
||||
Fail .before 1
|
||||
Pass .before 2
|
||||
Fail .before 3
|
||||
Pass .before 3
|
||||
Fail .after 4
|
||||
Fail .after 5
|
||||
Pass .after 5
|
||||
Fail .after 6
|
Loading…
Add table
Add a link
Reference in a new issue