From a3759b6e76def9551d25ee1e050a83fcb4dc4036 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 16 May 2023 14:07:51 +0300 Subject: LibWeb: Implement more of "Expand Flexible Tracks" in GFC Implements "Otherwise, if the free space is an indefinite length:" from the spec. --- .../grid/float-container-columns-1fr-1fr.txt | 6 +-- .../Layout/expected/grid/positions-and-spans.txt | 12 ++--- Tests/LibWeb/Layout/expected/grid/rows-1fr-1fr.txt | 11 +++++ Tests/LibWeb/Layout/input/grid/rows-1fr-1fr.html | 13 ++++++ .../LibWeb/Layout/GridFormattingContext.cpp | 52 +++++++++++++++++----- 5 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/grid/rows-1fr-1fr.txt create mode 100644 Tests/LibWeb/Layout/input/grid/rows-1fr-1fr.html diff --git a/Tests/LibWeb/Layout/expected/grid/float-container-columns-1fr-1fr.txt b/Tests/LibWeb/Layout/expected/grid/float-container-columns-1fr-1fr.txt index b04cec661f..aa12197572 100644 --- a/Tests/LibWeb/Layout/expected/grid/float-container-columns-1fr-1fr.txt +++ b/Tests/LibWeb/Layout/expected/grid/float-container-columns-1fr-1fr.txt @@ -1,13 +1,13 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline BlockContainer at (8,8) content-size 784x0 children: not-inline - Box at (8,8) content-size 186.53125x34.9375 floating [GFC] children: not-inline + Box at (8,8) content-size 203.28125x34.9375 floating [GFC] children: not-inline BlockContainer 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 at (109.640625,8) content-size 84.890625x17.46875 [BFC] children: inline + BlockContainer 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 at (109.640625,25.46875) content-size 84.890625x17.46875 [BFC] children: inline + BlockContainer 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" diff --git a/Tests/LibWeb/Layout/expected/grid/positions-and-spans.txt b/Tests/LibWeb/Layout/expected/grid/positions-and-spans.txt index 73e5b91230..c16c4e68f4 100644 --- a/Tests/LibWeb/Layout/expected/grid/positions-and-spans.txt +++ b/Tests/LibWeb/Layout/expected/grid/positions-and-spans.txt @@ -4,16 +4,16 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline Box 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 at (8,8) content-size 2613.33374x17.46875 [BFC] children: inline + BlockContainer 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 at (2621.33374,8) content-size 1306.666992x17.46875 [BFC] children: inline + BlockContainer 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 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 at (8,25.46875) content-size 1306.666748x17.46875 [BFC] children: inline + BlockContainer 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 at (1314.666748,25.46875) content-size 2613.333984x17.46875 [BFC] children: inline + BlockContainer 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 diff --git a/Tests/LibWeb/Layout/expected/grid/rows-1fr-1fr.txt b/Tests/LibWeb/Layout/expected/grid/rows-1fr-1fr.txt new file mode 100644 index 0000000000..f071889acb --- /dev/null +++ b/Tests/LibWeb/Layout/expected/grid/rows-1fr-1fr.txt @@ -0,0 +1,11 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x34.9375 children: not-inline + Box at (8,8) content-size 784x34.9375 [GFC] children: not-inline + BlockContainer 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> diff --git a/Tests/LibWeb/Layout/input/grid/rows-1fr-1fr.html b/Tests/LibWeb/Layout/input/grid/rows-1fr-1fr.html new file mode 100644 index 0000000000..611a9ca146 --- /dev/null +++ b/Tests/LibWeb/Layout/input/grid/rows-1fr-1fr.html @@ -0,0 +1,13 @@ + +
Uno
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index 153592dc30..abcdb0f8de 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -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 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 track’s flex factor is greater than one, the result of dividing + // the track’s base size by its flex factor; otherwise, the track’s 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 item’s max-content contribution. + for (auto& item : m_grid_items) { + Vector 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; } }(); -- cgit v1.2.3