Browse Source

LibWeb: Adjust grid columns size to fit spanning items

This change implements following paragraph from placement algorithm in
the spec:
"If the largest column span among all the items without a definite
column position is larger than the width of the implicit grid, add
columns to the end of the implicit grid to accommodate that column
span."

There were places in the grid implementation code with copies of this
text, but those were completely unrelated to the code where they were
being pasted so I removed them.
Aliaksandr Kalenik 2 years ago
parent
commit
e2c5e31292

+ 5 - 0
Tests/LibWeb/Layout/expected/grid/item-span-exceeds-columns-size.txt

@@ -0,0 +1,5 @@
+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 784x100 children: not-inline
+      Box <div.container> at (8,8) content-size 300x100 [GFC] children: not-inline
+        BlockContainer <div.item> at (8,8) content-size 300x100 [BFC] children: not-inline

+ 13 - 0
Tests/LibWeb/Layout/input/grid/item-span-exceeds-columns-size.html

@@ -0,0 +1,13 @@
+<style>
+    .container {
+        width: 300px;
+        display: grid;
+        grid-template-columns: 100px;
+        grid-template-rows: 100px;
+    }
+
+    .item {
+        background-color: purple;
+        grid-column: span 2;
+    }
+</style><div class="container"><div class="item"></div></div>

+ 14 - 10
Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp

@@ -362,11 +362,6 @@ void GridFormattingContext::place_item_with_row_position(Box const& child_box)
 
     int column_start = 0;
     size_t column_span = child_box.computed_values().grid_column_start().is_span() ? child_box.computed_values().grid_column_start().raw_value() : 1;
-    // https://drafts.csswg.org/css-grid/#auto-placement-algo
-    // 8.5. Grid Item Placement Algorithm
-    // 3.3. If the largest column span among all the items without a definite column position is larger
-    // than the width of the implicit grid, add columns to the end of the implicit grid to accommodate
-    // that column span.
     bool found_available_column = false;
     for (size_t column_index = column_start; column_index < m_occupation_grid.column_count(); column_index++) {
         if (!m_occupation_grid.is_occupied(column_index, row_start)) {
@@ -531,11 +526,6 @@ void GridFormattingContext::place_item_with_no_declared_position(Box const& chil
         column_span = child_box.computed_values().grid_column_start().raw_value();
     else if (child_box.computed_values().grid_column_end().is_span())
         column_span = child_box.computed_values().grid_column_end().raw_value();
-    // https://drafts.csswg.org/css-grid/#auto-placement-algo
-    // 8.5. Grid Item Placement Algorithm
-    // 3.3. If the largest column span among all the items without a definite column position is larger
-    // than the width of the implicit grid, add columns to the end of the implicit grid to accommodate
-    // that column span.
     auto row_start = 0;
     size_t row_span = 1;
     if (child_box.computed_values().grid_row_start().is_span())
@@ -1371,6 +1361,20 @@ void GridFormattingContext::place_grid_items(AvailableSpace const& available_spa
     // and 2, respectively. Adding columns for "items not yet positioned but with a definite column"
     // will be done in step 4.
 
+    // 3.3. If the largest column span among all the items without a definite column position is larger
+    // than the width of the implicit grid, add columns to the end of the implicit grid to accommodate
+    // that column span.
+    for (auto const& child_box : m_boxes_to_place) {
+        int column_span = 1;
+        if (child_box->computed_values().grid_column_start().is_span())
+            column_span = child_box->computed_values().grid_column_start().raw_value();
+        else if (child_box->computed_values().grid_column_end().is_span())
+            column_span = child_box->computed_values().grid_column_end().raw_value();
+
+        if (column_span - 1 > m_occupation_grid.max_column_index())
+            m_occupation_grid.set_max_column_index(column_span - 1);
+    }
+
     // 4. Position the remaining grid items.
     // For each grid item that hasn't been positioned by the previous steps, in order-modified document
     // order:

+ 2 - 0
Userland/Libraries/LibWeb/Layout/GridFormattingContext.h

@@ -73,6 +73,8 @@ public:
         return abs(m_min_row_index) + m_max_row_index + 1;
     }
 
+    void set_max_column_index(size_t max_column_index) { m_max_column_index = max_column_index; }
+
     int min_column_index() const { return m_min_column_index; }
     int max_column_index() const { return m_max_column_index; }
     int min_row_index() const { return m_min_row_index; }