mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:37:36 +00:00
LibWeb: Implement more of "Resolve Intrinsic Track Sizes" in GFC
Implements some parts of "Resolve Intrinsic Track Sizes" algorithm from spec to make it more spec compliant.
This commit is contained in:
parent
1ada6a43e2
commit
14cb0067bb
3 changed files with 104 additions and 48 deletions
14
Tests/LibWeb/Layout/expected/grid/basic-2.txt
Normal file
14
Tests/LibWeb/Layout/expected/grid/basic-2.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x17.46875 children: not-inline
|
||||||
|
Box <div#grid> at (8,8) content-size 784x17.46875 [GFC] children: not-inline
|
||||||
|
BlockContainer <div#title> at (8,8) content-size 88.171875x17.46875 [BFC] children: inline
|
||||||
|
line 0 width: 88.171875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||||
|
frag 0 from TextNode start: 0, length: 10, rect: [8,8 88.171875x17.46875]
|
||||||
|
"Game Title"
|
||||||
|
TextNode <#text>
|
||||||
|
BlockContainer <div#board> at (96.171875,8) content-size 695.828125x17.46875 [BFC] children: inline
|
||||||
|
line 0 width: 45.734375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||||
|
frag 0 from TextNode start: 0, length: 5, rect: [96.171875,8 45.734375x17.46875]
|
||||||
|
"Board"
|
||||||
|
TextNode <#text>
|
23
Tests/LibWeb/Layout/input/grid/basic-2.html
Normal file
23
Tests/LibWeb/Layout/input/grid/basic-2.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<style>
|
||||||
|
#grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns:
|
||||||
|
auto
|
||||||
|
1fr;
|
||||||
|
grid-template-rows:
|
||||||
|
auto
|
||||||
|
auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1;
|
||||||
|
background-color: lightblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#board {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1;
|
||||||
|
background-color: lightgreen;
|
||||||
|
}
|
||||||
|
</style><div id="grid"><div id="title">Game Title</div><div id="board">Board</div></div>
|
|
@ -704,6 +704,18 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto calculate_item_max_content_contribution = [&](GridItem const& item) {
|
||||||
|
if (dimension == GridDimension::Column) {
|
||||||
|
return calculate_max_content_width(item.box());
|
||||||
|
} else {
|
||||||
|
auto available_width = AvailableSize::make_definite(m_grid_columns[item.gap_adjusted_column(grid_container())].base_size);
|
||||||
|
return calculate_max_content_height(item.box(), available_width);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Size tracks to fit non-spanning items: For each track with an intrinsic track sizing function and
|
||||||
|
// not a flexible sizing function, consider the items in it with a span of 1:
|
||||||
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (auto& track : tracks) {
|
for (auto& track : tracks) {
|
||||||
if (track.is_gap) {
|
if (track.is_gap) {
|
||||||
|
@ -736,27 +748,27 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (track.min_track_sizing_function.type()) {
|
switch (track.min_track_sizing_function.type()) {
|
||||||
// - For min-content minimums:
|
case CSS::GridSize::Type::MinContent: {
|
||||||
// If the track has a min-content min track sizing function, set its base size to the maximum of the
|
// If the track has a min-content min track sizing function, set its base size to the maximum of the
|
||||||
// items’ min-content contributions, floored at zero.
|
// items’ min-content contributions, floored at zero.
|
||||||
case CSS::GridSize::Type::MinContent: {
|
|
||||||
CSSPixels base_size = 0;
|
CSSPixels base_size = 0;
|
||||||
for (auto& item : grid_items_of_track) {
|
for (auto& item : grid_items_of_track) {
|
||||||
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
||||||
}
|
}
|
||||||
track.base_size = base_size;
|
track.base_size = base_size;
|
||||||
} break;
|
} break;
|
||||||
// - For max-content minimums:
|
case CSS::GridSize::Type::MaxContent: {
|
||||||
// If the track has a max-content min track sizing function, set its base size to the maximum of the
|
// If the track has a max-content min track sizing function, set its base size to the maximum of the
|
||||||
// items’ max-content contributions, floored at zero.
|
// items’ max-content contributions, floored at zero.
|
||||||
case CSS::GridSize::Type::MaxContent: {
|
|
||||||
CSSPixels base_size = 0;
|
CSSPixels base_size = 0;
|
||||||
for (auto& item : grid_items_of_track) {
|
for (auto& item : grid_items_of_track) {
|
||||||
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
||||||
}
|
}
|
||||||
track.base_size = base_size;
|
track.base_size = base_size;
|
||||||
} break;
|
} break;
|
||||||
// - For auto minimums:
|
case CSS::GridSize::Type::Length:
|
||||||
|
case CSS::GridSize::Type::Percentage: {
|
||||||
|
if (track.min_track_sizing_function.length().is_auto() && available_size.is_intrinsic_sizing_constraint()) {
|
||||||
// If the track has an auto min track sizing function and the grid container is being sized under a
|
// If the track has an auto min track sizing function and the grid container is being sized under a
|
||||||
// min-/max-content constraint, set the track’s base size to the maximum of its items’ limited
|
// min-/max-content constraint, set the track’s base size to the maximum of its items’ limited
|
||||||
// min-/max-content contributions (respectively), floored at zero. The limited min-/max-content
|
// min-/max-content contributions (respectively), floored at zero. The limited min-/max-content
|
||||||
|
@ -764,8 +776,20 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
|
||||||
// limited by the max track sizing function (which could be the argument to a fit-content() track
|
// limited by the max track sizing function (which could be the argument to a fit-content() track
|
||||||
// sizing function) if that is fixed and ultimately floored by its minimum contribution (defined
|
// sizing function) if that is fixed and ultimately floored by its minimum contribution (defined
|
||||||
// below).
|
// below).
|
||||||
// FIXME: Container min/max-content
|
if (available_size.is_min_content()) {
|
||||||
case CSS::GridSize::Type::Length:
|
CSSPixels base_size = 0;
|
||||||
|
for (auto& item : grid_items_of_track) {
|
||||||
|
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
||||||
|
}
|
||||||
|
track.base_size = base_size;
|
||||||
|
} else if (available_size.is_max_content()) {
|
||||||
|
CSSPixels base_size = 0;
|
||||||
|
for (auto& item : grid_items_of_track) {
|
||||||
|
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
||||||
|
}
|
||||||
|
track.base_size = base_size;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Otherwise, set the track’s base size to the maximum of its items’ minimum contributions, floored
|
// Otherwise, set the track’s base size to the maximum of its items’ minimum contributions, floored
|
||||||
// at zero. The minimum contribution of an item is the smallest outer size it can have.
|
// at zero. The minimum contribution of an item is the smallest outer size it can have.
|
||||||
// Specifically, if the item’s computed preferred size behaves as auto or depends on the size of its
|
// Specifically, if the item’s computed preferred size behaves as auto or depends on the size of its
|
||||||
|
@ -773,46 +797,41 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
|
||||||
// result from assuming the item’s used minimum size as its preferred size; else the item’s minimum
|
// result from assuming the item’s used minimum size as its preferred size; else the item’s minimum
|
||||||
// contribution is its min-content contribution. Because the minimum contribution often depends on
|
// contribution is its min-content contribution. Because the minimum contribution often depends on
|
||||||
// the size of the item’s content, it is considered a type of intrinsic size contribution.
|
// the size of the item’s content, it is considered a type of intrinsic size contribution.
|
||||||
case CSS::GridSize::Type::Percentage:
|
|
||||||
case CSS::GridSize::Type::FlexibleLength: {
|
|
||||||
CSSPixels base_size = 0;
|
CSSPixels base_size = 0;
|
||||||
for (auto& item : grid_items_of_track) {
|
for (auto& item : grid_items_of_track) {
|
||||||
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
base_size = max(base_size, calculate_item_min_content_contribution(item));
|
||||||
}
|
}
|
||||||
track.base_size = base_size;
|
track.base_size = base_size;
|
||||||
} break;
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CSS::GridSize::Type::FlexibleLength: {
|
||||||
|
// do nothing
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (track.max_track_sizing_function.type()) {
|
auto const& max_track_sizing_function = track.max_track_sizing_function;
|
||||||
// - For min-content maximums:
|
if (max_track_sizing_function.is_min_content()) {
|
||||||
// If the track has a min-content max track sizing function, set its growth limit to the maximum of
|
// If the track has a min-content max track sizing function, set its growth limit to the maximum of
|
||||||
// the items’ min-content contributions.
|
// the items’ min-content contributions.
|
||||||
case CSS::GridSize::Type::MinContent: {
|
|
||||||
CSSPixels growth_limit = 0;
|
CSSPixels growth_limit = 0;
|
||||||
for (auto& item : grid_items_of_track) {
|
for (auto& item : grid_items_of_track) {
|
||||||
growth_limit = max(growth_limit, calculate_item_min_content_contribution(item));
|
growth_limit = max(growth_limit, calculate_item_min_content_contribution(item));
|
||||||
}
|
}
|
||||||
track.growth_limit = growth_limit;
|
track.growth_limit = growth_limit;
|
||||||
} break;
|
} else if (max_track_sizing_function.is_max_content() || (max_track_sizing_function.is_length() && max_track_sizing_function.length().is_auto())) {
|
||||||
// - For max-content maximums:
|
|
||||||
// If the track has a max-content max track sizing function, set its growth limit to the maximum of
|
// If the track has a max-content max track sizing function, set its growth limit to the maximum of
|
||||||
// the items’ max-content contributions. For fit-content() maximums, furthermore clamp this growth
|
// the items’ max-content contributions. For fit-content() maximums, furthermore clamp this growth
|
||||||
// limit by the fit-content() argument.
|
// limit by the fit-content() argument.
|
||||||
case CSS::GridSize::Type::MaxContent: {
|
|
||||||
CSSPixels growth_limit = 0;
|
CSSPixels growth_limit = 0;
|
||||||
for (auto& item : grid_items_of_track) {
|
for (auto& item : grid_items_of_track) {
|
||||||
growth_limit = max(growth_limit, calculate_item_min_content_contribution(item));
|
growth_limit = max(growth_limit, calculate_item_max_content_contribution(item));
|
||||||
}
|
}
|
||||||
track.growth_limit = growth_limit;
|
track.growth_limit = growth_limit;
|
||||||
} break;
|
|
||||||
case CSS::GridSize::Type::Length:
|
|
||||||
case CSS::GridSize::Type::Percentage:
|
|
||||||
case CSS::GridSize::Type::FlexibleLength:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In all cases, if a track’s growth limit is now less than its base size, increase the growth limit
|
// In all cases, if a track’s growth limit is now less than its base size, increase the growth limit
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue