Skip to content

Commit

Permalink
LibWeb: Implement more of "Resolve Intrinsic Track Sizes" in GFC
Browse files Browse the repository at this point in the history
Implements some parts of "Resolve Intrinsic Track Sizes" algorithm
from spec to make it more spec compliant.
  • Loading branch information
kalenikaliaksandr authored and awesomekling committed May 10, 2023
1 parent 1ada6a4 commit 14cb006
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 48 deletions.
14 changes: 14 additions & 0 deletions Tests/LibWeb/Layout/expected/grid/basic-2.txt
Original file line number Diff line number Diff line change
@@ -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 changes: 23 additions & 0 deletions Tests/LibWeb/Layout/input/grid/basic-2.html
Original file line number Diff line number Diff line change
@@ -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>
115 changes: 67 additions & 48 deletions Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
for (auto& track : tracks) {
if (track.is_gap) {
Expand Down Expand Up @@ -736,83 +748,90 @@ void GridFormattingContext::resolve_intrinsic_track_sizes(GridDimension const di
}

switch (track.min_track_sizing_function.type()) {
// - For min-content minimums:
// 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.
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
// items’ min-content contributions, floored at zero.
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;
} break;
// - For max-content minimums:
// 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.
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
// items’ max-content contributions, floored at zero.
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;
} break;
// - For auto minimums:
// 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 contributions (respectively), floored at zero. The limited min-/max-content
// contribution of an item is (for this purpose) its min-/max-content contribution (accordingly),
// 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
// below).
// FIXME: Container min/max-content
case CSS::GridSize::Type::Length:
// 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.
// Specifically, if the item’s computed preferred size behaves as auto or depends on the size of its
// containing block in the relevant axis, its minimum contribution is the outer size that would
// 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
// 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;
for (auto& item : grid_items_of_track) {
base_size = max(base_size, calculate_item_min_content_contribution(item));
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
// 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
// contribution of an item is (for this purpose) its min-/max-content contribution (accordingly),
// 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
// below).
if (available_size.is_min_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 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
// 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
// containing block in the relevant axis, its minimum contribution is the outer size that would
// 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
// the size of the item’s content, it is considered a type of intrinsic size contribution.
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;
}
track.base_size = base_size;
} break;

break;
}
case CSS::GridSize::Type::FlexibleLength: {
// do nothing
break;
}
default:
VERIFY_NOT_REACHED();
}

switch (track.max_track_sizing_function.type()) {
// - For min-content maximums:
// If the track has a min-content max track sizing function, set its growth limit to the maximum of
// the items’ min-content contributions.
case CSS::GridSize::Type::MinContent: {
auto const& max_track_sizing_function = track.max_track_sizing_function;
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
// the items’ min-content contributions.
CSSPixels growth_limit = 0;
for (auto& item : grid_items_of_track) {
growth_limit = max(growth_limit, calculate_item_min_content_contribution(item));
}
track.growth_limit = growth_limit;
} break;
// - For max-content maximums:
// 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
// limit by the fit-content() argument.
case CSS::GridSize::Type::MaxContent: {
} else if (max_track_sizing_function.is_max_content() || (max_track_sizing_function.is_length() && max_track_sizing_function.length().is_auto())) {
// 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
// limit by the fit-content() argument.
CSSPixels growth_limit = 0;
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;
} 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
Expand Down

0 comments on commit 14cb006

Please sign in to comment.