LibWeb: Implement "transferred size suggestion" part of GFC spec

This commit is contained in:
Aliaksandr Kalenik 2025-03-18 21:44:24 +01:00 committed by Jelle Raaijmakers
parent f0917ea150
commit b8fa355a21
Notes: github-actions[bot] 2025-03-19 09:22:56 +00:00
8 changed files with 109 additions and 4 deletions

View file

@ -2548,16 +2548,41 @@ Optional<CSSPixels> GridFormattingContext::specified_size_suggestion(GridItem co
return {};
}
Optional<CSSPixels> GridFormattingContext::transferred_size_suggestion(GridItem const& item, GridDimension dimension) const
{
// https://www.w3.org/TR/css-grid-2/#transferred-size-suggestion
// If the item has a preferred aspect ratio and its preferred size in the opposite axis is definite, then the transferred
// size suggestion is that size (clamped by the opposite-axis minimum and maximum sizes if they are definite), converted
// through the aspect ratio. It is otherwise undefined.
if (!item.box->preferred_aspect_ratio().has_value()) {
return {};
}
CSS::Size const& preferred_size_in_opposite_axis = get_item_preferred_size(item, dimension == GridDimension::Column ? GridDimension::Row : GridDimension::Column);
if (preferred_size_in_opposite_axis.is_length()) {
auto opposite_axis_size = preferred_size_in_opposite_axis.length().to_px(item.box);
// FIXME: Clamp by opposite-axis minimum and maximum sizes if they are definite
return opposite_axis_size * item.box->preferred_aspect_ratio().value();
}
return {};
}
CSSPixels GridFormattingContext::content_based_minimum_size(GridItem const& item, GridDimension const dimension) const
{
// https://www.w3.org/TR/css-grid-1/#content-based-minimum-size
// The content-based minimum size for a grid item in a given dimension is its specified size suggestion if it exists,
// otherwise its transferred size suggestion if that exists,
// else its content size suggestion, see below.
CSSPixels result = 0;
// The content-based minimum size for a grid item in a given dimension is its specified size suggestion if it exists,
if (auto specified_size_suggestion = this->specified_size_suggestion(item, dimension); specified_size_suggestion.has_value()) {
result = specified_size_suggestion.value();
} else {
}
// otherwise its transferred size suggestion if that exists,
else if (auto transferred_size_suggestion = this->transferred_size_suggestion(item, dimension); transferred_size_suggestion.has_value()) {
result = transferred_size_suggestion.value();
}
// else its content size suggestion.
else {
result = content_size_suggestion(item, dimension);
}

View file

@ -336,6 +336,7 @@ private:
CSSPixels content_size_suggestion(GridItem const&, GridDimension const) const;
Optional<CSSPixels> specified_size_suggestion(GridItem const&, GridDimension const) const;
Optional<CSSPixels> transferred_size_suggestion(GridItem const&, GridDimension const) const;
CSSPixels content_based_minimum_size(GridItem const&, GridDimension const) const;
CSSPixels automatic_minimum_size(GridItem const&, GridDimension const) const;
CSSPixels calculate_minimum_contribution(GridItem const&, GridDimension const) const;

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Reftest Reference: 100x100 green square image</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<img src="support/100x100-green.png" alt="Image download support must be enabled" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Minimum size of grid items</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="http://www.w3.org/TR/css-grid-1/#min-size-auto" title="6.6. Implied Minimum Size of Grid Items">
<link rel="match" href="../../../../../expected/wpt-import/css/css-grid/grid-items/ref-filled-green-100px-square-image.html">
<meta name="flags" content="image">
<meta name="assert" content="Checks that minimum size for grid items is the specified size for height (regardless the content size) and the transferred size of the image for width (even when content size is bigger).">
<style>
#reference-overlapped-red {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
z-index: -1;
}
#constrained-grid {
display: grid;
width: 10px;
height: 10px;
}
#test-grid-item-overlapping-green {
height: 100px;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="reference-overlapped-red"></div>
<div id="constrained-grid">
<img id="test-grid-item-overlapping-green" src="support/200x200-green.png" alt="Image download support must be enabled" />
</div>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Minimum size of grid items</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="http://www.w3.org/TR/css-grid-1/#min-size-auto" title="6.6. Implied Minimum Size of Grid Items">
<link rel="match" href="../../../../../expected/wpt-import/css/css-grid/grid-items/ref-filled-green-100px-square-image.html">
<meta name="flags" content="image">
<meta name="assert" content="Checks that minimum size for grid items is the specified size for height (regardless the content size) and the transferred size for width of the image (even when content size is smaller).">
<style>
#reference-overlapped-red {
position: absolute;
background-color: red;
width: 100px;
height: 100px;
z-index: -1;
}
#constrained-grid {
display: grid;
width: 10px;
height: 10px;
}
.test-grid-item-overlapping-green {
height: 50px;
justify-self: stretch;
align-self: stretch;
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="reference-overlapped-red"></div>
<div id="constrained-grid">
<img class="test-grid-item-overlapping-green" src="support/50x25-green.png" alt="Image download support must be enabled" />
<img class="test-grid-item-overlapping-green" src="support/50x25-green.png" alt="Image download support must be enabled" />
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B