diff --git a/Tests/LibWeb/Layout/expected/grid/restart-fr-algorithm-if-less-than-base-size.txt b/Tests/LibWeb/Layout/expected/grid/restart-fr-algorithm-if-less-than-base-size.txt new file mode 100644 index 00000000000..4990de0a71b --- /dev/null +++ b/Tests/LibWeb/Layout/expected/grid/restart-fr-algorithm-if-less-than-base-size.txt @@ -0,0 +1,17 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x33 [BFC] children: not-inline + Box at (8,8) content-size 200x17 [GFC] children: not-inline + BlockContainer
at (8,8) content-size 0x17 [BFC] children: not-inline + BlockContainer at (8,8) content-size 202.5x17 [BFC] children: inline + frag 0 from TextNode start: 0, length: 24, rect: [8,8 202.5x17] baseline: 13.296875 + "HelloFriendsHelloFriends" + TextNode <#text> + BlockContainer
at (210.5,8) content-size 0x17 [BFC] children: not-inline + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x33] + PaintableBox (Box) [8,8 200x17] overflow: [8,8 202.5x17] + PaintableWithLines (BlockContainer
) [8,8 0x17] + PaintableWithLines (BlockContainer
.nowrap) [8,8 202.5x17] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer
) [210.5,8 0x17] diff --git a/Tests/LibWeb/Layout/input/grid/restart-fr-algorithm-if-less-than-base-size.html b/Tests/LibWeb/Layout/input/grid/restart-fr-algorithm-if-less-than-base-size.html new file mode 100644 index 00000000000..3fe75670d4d --- /dev/null +++ b/Tests/LibWeb/Layout/input/grid/restart-fr-algorithm-if-less-than-base-size.html @@ -0,0 +1,20 @@ + + +
HelloFriendsHelloFriends
\ No newline at end of file diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 648e3274989..41e23621861 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -1012,33 +1012,50 @@ void GridFormattingContext::expand_flexible_tracks(GridDimension const dimension // FIXME: This should idealy take a Span, as that is more idomatic, but Span does not yet support holding references auto find_the_size_of_an_fr = [&](Vector const& tracks, CSSPixels space_to_fill) -> CSSPixelFraction { // https://www.w3.org/TR/css-grid-2/#algo-find-fr-size - - // 1. Let leftover space be the space to fill minus the base sizes of the non-flexible grid tracks. - auto leftover_space = space_to_fill; - for (auto& track : tracks) { - if (!track.max_track_sizing_function.is_flexible_length()) { - leftover_space -= track.base_size; + auto treat_track_as_inflexiable = MUST(AK::Bitmap::create(tracks.size(), false)); + do { + // 1. Let leftover space be the space to fill minus the base sizes of the non-flexible grid tracks. + auto leftover_space = space_to_fill; + for (auto track_index = 0u; track_index < tracks.size(); track_index++) { + if (treat_track_as_inflexiable.view().get(track_index) || !tracks[track_index].max_track_sizing_function.is_flexible_length()) { + leftover_space -= tracks[track_index].base_size; + } } - } - // 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. - CSSPixels flex_factor_sum = 0; - for (auto& track : tracks) { - if (track.max_track_sizing_function.is_flexible_length()) - flex_factor_sum += CSSPixels::nearest_value_for(track.max_track_sizing_function.flex_factor()); - } - if (flex_factor_sum < 1) - flex_factor_sum = 1; + // 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. + CSSPixels flex_factor_sum = 0; + for (auto track_index = 0u; track_index < tracks.size(); track_index++) { + if (treat_track_as_inflexiable.view().get(track_index) || !tracks[track_index].max_track_sizing_function.is_flexible_length()) + continue; + flex_factor_sum += CSSPixels::nearest_value_for(tracks[track_index].max_track_sizing_function.flex_factor()); + } + if (flex_factor_sum < 1) + flex_factor_sum = 1; - // 3. Let the hypothetical fr size be the leftover space divided by the flex factor sum. - auto hypothetical_fr_size = leftover_space / flex_factor_sum; + // 3. Let the hypothetical fr size be the leftover space divided by the flex factor sum. + auto hypothetical_fr_size = leftover_space / flex_factor_sum; - // FIXME: 4. If the product of the hypothetical fr size and a flexible track’s flex factor is less than the track’s - // base size, restart this algorithm treating all such tracks as inflexible. + // 4. If the product of the hypothetical fr size and a flexible track’s flex factor is less than the track’s + // base size, restart this algorithm treating all such tracks as inflexible. + bool need_to_restart = false; + for (auto track_index = 0u; track_index < tracks.size(); track_index++) { + if (treat_track_as_inflexiable.view().get(track_index) || !tracks[track_index].max_track_sizing_function.is_flexible_length()) + continue; + auto scaled_fraction = CSSPixels::nearest_value_for(tracks[track_index].max_track_sizing_function.flex_factor()) * hypothetical_fr_size; + if (scaled_fraction < tracks[track_index].base_size) { + treat_track_as_inflexiable.set(track_index, true); + need_to_restart = true; + } + } + if (need_to_restart) + continue; - // 5. Return the hypothetical fr size. - return hypothetical_fr_size; + // 5. Return the hypothetical fr size. + return hypothetical_fr_size; + } while (true); + + VERIFY_NOT_REACHED(); }; // First, find the grid’s used flex fraction: