LibWeb: Implement more of "Expand Flexible Tracks" in GFC

Implements "Otherwise, if the free space is an indefinite length:" from
the spec.
This commit is contained in:
Aliaksandr Kalenik 2023-05-16 14:07:51 +03:00 committed by Andreas Kling
parent 2e13f65ff4
commit a3759b6e76
Notes: sideshowbarker 2024-07-17 03:05:16 +09:00
5 changed files with 75 additions and 19 deletions

View File

@ -1,13 +1,13 @@
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 784x0 children: not-inline
Box <div.container> at (8,8) content-size 186.53125x34.9375 floating [GFC] children: not-inline
Box <div.container> at (8,8) content-size 203.28125x34.9375 floating [GFC] children: not-inline
BlockContainer <div.item> at (8,8) content-size 101.640625x17.46875 [BFC] children: inline
line 0 width: 79.25, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 9, rect: [8,8 79.25x17.46875]
"some-text"
TextNode <#text>
BlockContainer <div.item> at (109.640625,8) content-size 84.890625x17.46875 [BFC] children: inline
BlockContainer <div.item> at (109.640625,8) content-size 101.640625x17.46875 [BFC] children: inline
line 0 width: 78.03125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 9, rect: [109.640625,8 78.03125x17.46875]
"goes-here"
@ -17,7 +17,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
frag 0 from TextNode start: 0, length: 12, rect: [8,25.46875 101.640625x17.46875]
"another-text"
TextNode <#text>
BlockContainer <div.item> at (109.640625,25.46875) content-size 84.890625x17.46875 [BFC] children: inline
BlockContainer <div.item> at (109.640625,25.46875) content-size 101.640625x17.46875 [BFC] children: inline
line 0 width: 84.890625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 10, rect: [109.640625,25.46875 84.890625x17.46875]
"goes-there"

View File

@ -4,16 +4,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
Box <div.grid-container> at (8,8) content-size 784x17.46875 [GFC] children: not-inline
BlockContainer <(anonymous)> at (8,8) content-size 0x0 [BFC] children: inline
TextNode <#text>
BlockContainer <div.grid-item> at (8,8) content-size 2613.33374x17.46875 [BFC] children: inline
BlockContainer <div.grid-item> at (8,8) content-size 522.666687x17.46875 [BFC] children: inline
line 0 width: 6.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 1, rect: [8,8 6.34375x17.46875]
"1"
TextNode <#text>
BlockContainer <(anonymous)> at (8,8) content-size 0x0 [BFC] children: inline
TextNode <#text>
BlockContainer <div.grid-item> at (2621.33374,8) content-size 1306.666992x17.46875 [BFC] children: inline
BlockContainer <div.grid-item> at (530.666687,8) content-size 261.333251x17.46875 [BFC] children: inline
line 0 width: 8.8125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 1, rect: [2621.33374,8 8.8125x17.46875]
frag 0 from TextNode start: 0, length: 1, rect: [530.666687,8 8.8125x17.46875]
"2"
TextNode <#text>
BlockContainer <(anonymous)> at (8,8) content-size 0x0 [BFC] children: inline
@ -25,16 +25,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
Box <div.grid-container> at (8,25.46875) content-size 784x17.46875 [GFC] children: not-inline
BlockContainer <(anonymous)> at (8,25.46875) content-size 0x0 [BFC] children: inline
TextNode <#text>
BlockContainer <div.grid-item> at (8,25.46875) content-size 1306.666748x17.46875 [BFC] children: inline
BlockContainer <div.grid-item> at (8,25.46875) content-size 261.333343x17.46875 [BFC] children: inline
line 0 width: 6.34375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 1, rect: [8,25.46875 6.34375x17.46875]
"1"
TextNode <#text>
BlockContainer <(anonymous)> at (8,25.46875) content-size 0x0 [BFC] children: inline
TextNode <#text>
BlockContainer <div.grid-item> at (1314.666748,25.46875) content-size 2613.333984x17.46875 [BFC] children: inline
BlockContainer <div.grid-item> at (269.333343,25.46875) content-size 522.666625x17.46875 [BFC] children: inline
line 0 width: 8.8125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 1, rect: [1314.666748,25.46875 8.8125x17.46875]
frag 0 from TextNode start: 0, length: 1, rect: [269.333343,25.46875 8.8125x17.46875]
"2"
TextNode <#text>
BlockContainer <(anonymous)> at (8,25.46875) content-size 0x0 [BFC] children: inline

View File

@ -0,0 +1,11 @@
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 784x34.9375 children: not-inline
Box <div.container> at (8,8) content-size 784x34.9375 [GFC] children: not-inline
BlockContainer <div.item> at (8,8) content-size 784x17.46875 [BFC] children: inline
line 0 width: 31.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 3, rect: [8,8 31.265625x17.46875]
"Uno"
TextNode <#text>
BlockContainer <(anonymous)> at (8,42.9375) content-size 784x0 children: inline
TextNode <#text>

View File

@ -0,0 +1,13 @@
<style>
.container {
background-color: palevioletred;
display: grid;
grid-template-columns: auto;
grid-template-rows: 1fr 1fr;
}
.item {
background-color: yellowgreen;
}
</style>
<div class="container"><div class="item">Uno</div></div>

View File

@ -1055,16 +1055,15 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
// the available space.
auto& tracks_and_gaps = dimension == GridDimension::Column ? m_grid_columns_and_gaps : m_grid_rows_and_gaps;
auto& tracks = dimension == GridDimension::Column ? m_grid_columns : m_grid_rows;
auto& available_size = dimension == GridDimension::Column ? available_space.width : available_space.height;
auto find_the_size_of_an_fr = [&]() -> CSSPixels {
auto find_the_size_of_an_fr = [&](Vector<TemporaryTrack&> tracks, CSSPixels space_to_fill) -> CSSPixels {
// https://www.w3.org/TR/css-grid-2/#algo-find-fr-size
VERIFY(available_size.is_definite());
// 1. Let leftover space be the space to fill minus the base sizes of the non-flexible grid tracks.
auto leftover_space = available_size.to_px();
for (auto& track : tracks_and_gaps) {
auto leftover_space = space_to_fill;
for (auto& track : tracks) {
if (!track.max_track_sizing_function.is_flexible_length()) {
leftover_space -= track.base_size;
}
@ -1073,9 +1072,9 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
// 2. Let flex factor sum be the sum of the flex factors of the flexible tracks.
// If this value is less than 1, set it to 1 instead.
auto flex_factor_sum = 0;
for (auto& track : tracks_and_gaps) {
for (auto& track : tracks) {
if (track.max_track_sizing_function.is_flexible_length())
flex_factor_sum++;
flex_factor_sum += track.max_track_sizing_function.flexible_length();
}
if (flex_factor_sum < 1)
flex_factor_sum = 1;
@ -1101,10 +1100,43 @@ void GridFormattingContext::expand_flexible_tracks(AvailableSpace const& availab
} else if (free_space.is_definite()) {
// The used flex fraction is the result of finding the size of an fr using all of the grid tracks and a space
// to fill of the available grid space.
return find_the_size_of_an_fr();
return find_the_size_of_an_fr(tracks_and_gaps, available_size.to_px());
} else {
// FIXME
return CSSPixels(0);
// Otherwise, if the free space is an indefinite length:
// The used flex fraction is the maximum of:
CSSPixels result = 0;
// For each flexible track, if the flexible tracks flex factor is greater than one, the result of dividing
// the tracks base size by its flex factor; otherwise, the tracks base size.
for (auto& track : tracks) {
if (track.max_track_sizing_function.is_flexible_length()) {
if (track.max_track_sizing_function.flexible_length() > 1) {
result = max(result, track.base_size / track.max_track_sizing_function.flexible_length());
} else {
result = max(result, track.base_size);
}
}
}
// For each grid item that crosses a flexible track, the result of finding the size of an fr using all the
// grid tracks that the item crosses and a space to fill of the items max-content contribution.
for (auto& item : m_grid_items) {
Vector<TemporaryTrack&> spanned_tracks;
bool crosses_flexible_track = false;
for (size_t span = 0; span < item.span(dimension); span++) {
// FIXME: This check should not be need if grid item positioning works correct
if (item.raw_position(dimension) + span >= tracks.size())
break;
auto& track = tracks[item.raw_position(dimension) + span];
spanned_tracks.append(track);
if (track.max_track_sizing_function.is_flexible_length())
crosses_flexible_track = true;
}
if (crosses_flexible_track)
result = max(result, find_the_size_of_an_fr(spanned_tracks, calculate_max_content_size(item, dimension)));
}
return result;
}
}();