From 937fcfc75c417b37030e47b97050c2a705a174d0 Mon Sep 17 00:00:00 2001 From: martinfalisse Date: Sun, 30 Oct 2022 13:49:47 +0100 Subject: [PATCH] LibWeb+Base: Use line names for positioning grid items When there are grid tracks with line names, use these to resolve line-names passed to positioned grid items. --- Base/res/html/misc/display-grid.html | 104 +++++++++++++++++ .../LibWeb/Layout/GridFormattingContext.cpp | 105 ++++++++++++++++++ .../LibWeb/Layout/GridFormattingContext.h | 2 + 3 files changed, 211 insertions(+) diff --git a/Base/res/html/misc/display-grid.html b/Base/res/html/misc/display-grid.html index 8dd6237c253..c88118d0e23 100644 --- a/Base/res/html/misc/display-grid.html +++ b/Base/res/html/misc/display-grid.html @@ -80,6 +80,34 @@ style="grid-template-columns: minmax(0, calc(100% - var(--Layout-sidebar-width) - var(--Layout-gutter)));"> + +
+
1
+
+ + +
+
1
+
+ + +
+
1
+
+

End of crash tests

@@ -228,3 +256,79 @@ length value, and as a minimum two lengths with an auto. -->
Article content
3
+ + +

Named tracks there should be 4 grid items in a circle with a space in the middle

+
+
1
+
2
+
3
+
4
+
+ +

Should render a 2 columned grid

+
+
1
+
2
+
+ + +

Should render 2 50px columns and 2 100px columns

+
+
1
+
2
+
3
+
4
+
+ + +

Should render 2 50px columns and 2 100px columns, with grid-item 1 starting at column 2

+
+
1
+
2
+
3
+
4
+
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index fc8bd48a097..d9d9e80c36d 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -242,6 +242,42 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const // https://www.w3.org/TR/css-grid-2/#common-uses-named-lines // 8.1.3. Named Lines and Spans // Instead of counting lines by number, lines can be referenced by their line name: + if (child_box.computed_values().grid_column_start().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_column_start().line_name(), grid_template_columns); + if (found_flag_and_index > -1) + column_start = 1 + found_flag_and_index; + else + column_start = 1; // FIXME + } + if (child_box.computed_values().grid_column_end().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_column_end().line_name(), grid_template_columns); + if (found_flag_and_index > -1) { + column_end = 1 + found_flag_and_index; + if (!child_box.computed_values().grid_column_start().is_position()) + column_start = column_end - column_span; + } else { + column_end = 2; // FIXME + column_start = 1; // FIXME + } + } + if (child_box.computed_values().grid_row_start().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_row_start().line_name(), grid_template_rows); + if (found_flag_and_index > -1) + row_start = 1 + found_flag_and_index; + else + row_start = 1; // FIXME + } + if (child_box.computed_values().grid_row_end().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_row_end().line_name(), grid_template_rows); + if (found_flag_and_index > -1) { + row_end = 1 + found_flag_and_index; + if (!child_box.computed_values().grid_row_start().is_position()) + row_start = row_end - row_span; + } else { + row_end = 2; // FIXME + row_start = 1; // FIXME + } + } // If there are multiple lines of the same name, they effectively establish a named set of grid // lines, which can be exclusively indexed by filtering the placement by name: @@ -343,6 +379,24 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const // https://www.w3.org/TR/css-grid-2/#common-uses-named-lines // 8.1.3. Named Lines and Spans // Instead of counting lines by number, lines can be referenced by their line name: + if (child_box.computed_values().grid_row_start().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_row_start().line_name(), grid_template_rows); + if (found_flag_and_index > -1) + row_start = 1 + found_flag_and_index; + else + row_start = 1; // FIXME + } + if (child_box.computed_values().grid_row_end().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_row_end().line_name(), grid_template_rows); + if (found_flag_and_index > -1) { + row_end = 1 + found_flag_and_index; + if (!child_box.computed_values().grid_row_start().is_position()) + row_start = row_end - row_span; + } else { + row_start = 1; // FIXME + row_end = 2; // FIXME + } + } // If there are multiple lines of the same name, they effectively establish a named set of grid // lines, which can be exclusively indexed by filtering the placement by name: @@ -480,6 +534,24 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const // https://www.w3.org/TR/css-grid-2/#common-uses-named-lines // 8.1.3. Named Lines and Spans // Instead of counting lines by number, lines can be referenced by their line name: + if (child_box.computed_values().grid_column_start().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_column_start().line_name(), grid_template_columns); + if (found_flag_and_index > -1) + column_start = 1 + found_flag_and_index; + else + column_start = 1; // FIXME + } + if (child_box.computed_values().grid_column_end().has_line_name()) { + auto found_flag_and_index = get_line_index_by_line_name(child_box.computed_values().grid_column_end().line_name(), grid_template_columns); + if (found_flag_and_index > -1) { + column_end = 1 + found_flag_and_index; + if (!child_box.computed_values().grid_column_start().is_position()) + column_start = column_end - column_span; + } else { + column_end = 2; // FIXME + column_start = 1; // FIXME + } + } // If there are multiple lines of the same name, they effectively establish a named set of grid // lines, which can be exclusively indexed by filtering the placement by name: @@ -1460,6 +1532,39 @@ float GridFormattingContext::get_free_space_y(Box const& box) return -1; } +int GridFormattingContext::get_line_index_by_line_name(String const& needle, CSS::GridTrackSizeList grid_track_size_list) +{ + if (grid_track_size_list.track_list().size() == 0) + return -1; + + auto repeated_tracks_count = 0; + for (size_t x = 0; x < grid_track_size_list.track_list().size(); x++) { + if (grid_track_size_list.track_list()[x].is_repeat()) { + // FIXME: Calculate amount of columns/rows if auto-fill/fit + if (!grid_track_size_list.track_list()[x].repeat().is_default()) + return -1; + auto repeat = grid_track_size_list.track_list()[x].repeat().grid_track_size_list(); + for (size_t y = 0; y < repeat.track_list().size(); y++) { + for (size_t z = 0; z < repeat.line_names()[y].size(); z++) { + if (repeat.line_names()[y][z] == needle) + return x + repeated_tracks_count; + repeated_tracks_count++; + } + } + } else { + for (size_t y = 0; y < grid_track_size_list.line_names()[x].size(); y++) { + if (grid_track_size_list.line_names()[x][y] == needle) + return x + repeated_tracks_count; + } + } + } + for (size_t y = 0; y < grid_track_size_list.line_names()[grid_track_size_list.track_list().size()].size(); y++) { + if (grid_track_size_list.line_names()[grid_track_size_list.track_list().size()][y] == needle) + return grid_track_size_list.track_list().size() + repeated_tracks_count; + } + return -1; +} + OccupationGrid::OccupationGrid(int column_count, int row_count) { Vector occupation_grid_row; diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h index 2d43271e681..d38666f3983 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h @@ -40,6 +40,8 @@ private: float get_free_space_x(Box const&); float get_free_space_y(Box const&); + + int get_line_index_by_line_name(String const& line_name, CSS::GridTrackSizeList); }; class OccupationGrid {