Ver Fonte

LibWeb: Add borders functionality to CSS Grid

martinfalisse há 2 anos atrás
pai
commit
289285cd6e

+ 164 - 0
Tests/LibWeb/Layout/expected/grid/borders.txt

@@ -0,0 +1,164 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x444.28125 children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x428.28125 children: not-inline
+      Box <div.grid-container> at (8,8) content-size 784x74.9375 children: not-inline
+        BlockContainer <(anonymous)> at (8,8) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,18) content-size 372.140625x17.46875 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: [18,18 6.34375x17.46875]
+              "1"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,8) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (410.140625,18) content-size 372x17.46875 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: [410.140625,18 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,8) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,55.46875) content-size 372.140625x17.46875 children: inline
+          line 0 width: 9.09375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 1, rect: [18,55.46875 9.09375x17.46875]
+              "3"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,8) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (410.140625,55.46875) content-size 372x17.46875 children: inline
+          line 0 width: 7.75, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 1, rect: [410.140625,55.46875 7.75x17.46875]
+              "4"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,8) content-size 0x0 children: inline
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,82.9375) content-size 784x0 children: inline
+        TextNode <#text>
+      Box <div.grid-container> at (8,82.9375) content-size 784x107.46875 children: not-inline
+        BlockContainer <(anonymous)> at (8,82.9375) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,92.9375) content-size 372.140625x50 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: [18,92.9375 6.34375x17.46875]
+              "1"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,82.9375) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (410.140625,92.9375) content-size 372x50 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: [410.140625,92.9375 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,82.9375) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,162.9375) content-size 372.140625x17.46875 children: inline
+          line 0 width: 9.09375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 1, rect: [18,162.9375 9.09375x17.46875]
+              "3"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,82.9375) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (410.140625,162.9375) content-size 372x17.46875 children: inline
+          line 0 width: 7.75, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 1, rect: [410.140625,162.9375 7.75x17.46875]
+              "4"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,82.9375) content-size 0x0 children: inline
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,190.40625) content-size 784x0 children: inline
+        TextNode <#text>
+      Box <div.grid-container> at (8,190.40625) content-size 784x84.9375 children: not-inline
+        BlockContainer <(anonymous)> at (8,190.40625) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,200.40625) content-size 347.140625x17.46875 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: [18,200.40625 6.34375x17.46875]
+              "1"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,190.40625) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (435.140625,200.40625) content-size 347x17.46875 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: [435.140625,200.40625 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,190.40625) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,247.875) content-size 347.140625x17.46875 children: inline
+          line 0 width: 9.09375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 1, rect: [18,247.875 9.09375x17.46875]
+              "3"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,190.40625) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (435.140625,247.875) content-size 347x17.46875 children: inline
+          line 0 width: 7.75, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 1, rect: [435.140625,247.875 7.75x17.46875]
+              "4"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,190.40625) content-size 0x0 children: inline
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,275.34375) content-size 784x0 children: inline
+        TextNode <#text>
+      Box <div.grid-container> at (8,275.34375) content-size 784x90.9375 children: not-inline
+        BlockContainer <(anonymous)> at (8,275.34375) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (445.434356,285.34375) content-size 337.800018x17.46875 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: [445.434356,285.34375 6.34375x17.46875]
+              "1"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,275.34375) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,338.8125) content-size 339.034362x17.46875 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: [18,338.8125 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,275.34375) content-size 0x0 children: inline
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,366.28125) content-size 784x0 children: inline
+        TextNode <#text>
+      Box <div.grid-container> at (8,366.28125) content-size 784x50 children: not-inline
+        BlockContainer <(anonymous)> at (8,366.28125) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,376.28125) content-size 280x5 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: [18,376.28125 6.34375x17.46875]
+              "1"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,366.28125) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (318,376.28125) content-size 280x5 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: [318,376.28125 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,366.28125) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,401.28125) content-size 280x5 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: [18,401.28125 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,366.28125) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (318,401.28125) content-size 280x5 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: [318,401.28125 8.8125x17.46875]
+              "2"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,366.28125) content-size 0x0 children: inline
+          TextNode <#text>
+      BlockContainer <(anonymous)> at (8,416.28125) content-size 784x0 children: inline
+        TextNode <#text>
+      Box <div.grid-container> at (8,416.28125) content-size 784x20 children: not-inline
+        BlockContainer <(anonymous)> at (8,416.28125) content-size 0x0 children: inline
+          TextNode <#text>
+        BlockContainer <div.grid-item> at (18,426.28125) content-size 764x0 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: [18,426.28125 6.34375x17.46875]
+              "1"
+          TextNode <#text>
+        BlockContainer <(anonymous)> at (8,416.28125) content-size 0x0 children: inline
+          TextNode <#text>

+ 62 - 0
Tests/LibWeb/Layout/input/grid/borders.html

@@ -0,0 +1,62 @@
+<style>
+  body {
+    font-family: 'SerenitySans';
+  }
+
+  .grid-container {
+    display: grid;
+    background-color: lightsalmon;
+  }
+
+  .grid-item {
+    background-color: lightblue;
+    border: 10px solid black;
+  }
+</style>
+
+<div class="grid-container" style="grid-template-columns: auto auto;">
+  <div class="grid-item">1</div>
+  <div class="grid-item">2</div>
+  <div class="grid-item">3</div>
+  <div class="grid-item">4</div>
+</div>
+
+<div class="grid-container" style="grid-template-columns: auto auto;">
+  <div class="grid-item" style="height: 50px;">1</div>
+  <div class="grid-item">2</div>
+  <div class="grid-item">3</div>
+  <div class="grid-item">4</div>
+</div>
+
+<div class="grid-container" style="
+    grid-template-columns: auto auto;
+    gap: 10px 50px;
+  ">
+  <div class="grid-item">1</div>
+  <div class="grid-item">2</div>
+  <div class="grid-item">3</div>
+  <div class="grid-item">4</div>
+</div>
+
+<div class="grid-container" style="
+    grid-template-columns: auto auto;
+    gap: calc(1vh + 10px) calc(10% - 10px);
+  ">
+  <div class="grid-item" style="grid-column: 2 / span 1">1</div>
+  <div class="grid-item">2</div>
+</div>
+
+<div class="grid-container" style="
+    height: 50px;
+    grid-template-columns: minmax(150px, 300px) minmax(150px, 300px);
+    grid-template-rows: minmax(25px, 50px) minmax(25px, 50px);
+  ">
+  <div class="grid-item">1</div>
+  <div class="grid-item">2</div>
+  <div class="grid-item">2</div>
+  <div class="grid-item">2</div>
+</div>
+
+<div class="grid-container" style="grid-template-rows: 20px;">
+  <div class="grid-item">1</div>
+</div>

+ 42 - 17
Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp

@@ -743,15 +743,19 @@ void GridFormattingContext::calculate_sizes_of_columns(Box const& box, Available
             ++index;
             continue;
         }
-        if (!grid_column.min_track_sizing_function.is_intrinsic_track_sizing()) {
-            ++index;
-            continue;
-        }
 
         Vector<Box const&> boxes_of_column;
         for (auto& grid_item : m_grid_items) {
-            if (grid_item.gap_adjusted_column(box) == index && grid_item.raw_column_span() == 1)
+            if (grid_item.gap_adjusted_column(box) == index && grid_item.raw_column_span() == 1) {
                 boxes_of_column.append(grid_item.box());
+                grid_column.border_left = max(grid_column.border_left, grid_item.box().computed_values().border_left().width);
+                grid_column.border_right = max(grid_column.border_right, grid_item.box().computed_values().border_right().width);
+            }
+        }
+
+        if (!grid_column.min_track_sizing_function.is_intrinsic_track_sizing()) {
+            ++index;
+            continue;
         }
 
         switch (grid_column.min_track_sizing_function.type()) {
@@ -1243,15 +1247,19 @@ void GridFormattingContext::calculate_sizes_of_rows(Box const& box)
             ++index;
             continue;
         }
-        if (!grid_row.min_track_sizing_function.is_intrinsic_track_sizing()) {
-            ++index;
-            continue;
-        }
 
         Vector<GridItem&> grid_items_of_row;
         for (auto& grid_item : m_grid_items) {
-            if (grid_item.gap_adjusted_row(box) == index && grid_item.raw_row_span() == 1)
+            if (grid_item.gap_adjusted_row(box) == index && grid_item.raw_row_span() == 1) {
                 grid_items_of_row.append(grid_item);
+                grid_row.border_top = max(grid_row.border_top, grid_item.box().computed_values().border_top().width);
+                grid_row.border_bottom = max(grid_row.border_bottom, grid_item.box().computed_values().border_bottom().width);
+            }
+        }
+
+        if (!grid_row.min_track_sizing_function.is_intrinsic_track_sizing()) {
+            ++index;
+            continue;
         }
 
         switch (grid_row.min_track_sizing_function.type()) {
@@ -1585,8 +1593,14 @@ void GridFormattingContext::calculate_sizes_of_rows(Box const& box)
             count_of_auto_max_row_tracks++;
     }
     for (auto& grid_row : m_grid_rows) {
+        if (grid_row.is_gap)
+            continue;
         if (grid_row.max_track_sizing_function.is_length() && grid_row.max_track_sizing_function.length().is_auto())
             grid_row.base_size = max(grid_row.base_size, remaining_vertical_space / count_of_auto_max_row_tracks);
+        if (grid_row.full_vertical_size() > grid_row.growth_limit && grid_row.growth_limit != -1)
+            grid_row.base_size = max(CSSPixels(0), grid_row.base_size + (grid_row.growth_limit - grid_row.full_vertical_size()));
+        if (grid_row.min_track_sizing_function.is_length() && !grid_row.min_track_sizing_function.length().is_auto() && grid_row.full_vertical_size() > grid_row.min_track_sizing_function.length().to_px(box) && free_space != -1)
+            grid_row.base_size = max(CSSPixels(0), grid_row.base_size + (grid_row.min_track_sizing_function.length().to_px(box) - grid_row.full_vertical_size()));
     }
 }
 
@@ -1851,6 +1865,8 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
     // purpose.
 
     auto layout_box = [&](int row_start, int row_end, int column_start, int column_end, Box const& child_box) -> void {
+        if (column_start < 0 || row_start < 0)
+            return;
         auto& child_box_state = m_state.get_mutable(child_box);
         CSSPixels x_start = 0;
         CSSPixels x_end = 0;
@@ -1861,12 +1877,21 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
         for (int i = 0; i < column_end; i++)
             x_end += m_grid_columns[i].base_size;
         for (int i = 0; i < row_start; i++)
-            y_start += m_grid_rows[i].base_size;
-        for (int i = 0; i < row_end; i++)
-            y_end += m_grid_rows[i].base_size;
-        child_box_state.set_content_width((x_end - x_start));
-        child_box_state.set_content_height((y_end - y_start));
-        child_box_state.offset = { x_start, y_start };
+            y_start += m_grid_rows[i].full_vertical_size();
+        for (int i = 0; i < row_end; i++) {
+            if (i >= row_start)
+                y_end += m_grid_rows[i].base_size;
+            else
+                y_end += m_grid_rows[i].full_vertical_size();
+        }
+        child_box_state.set_content_width(max(CSSPixels(0), x_end - x_start - m_grid_columns[column_start].border_left - m_grid_columns[column_start].border_right));
+        child_box_state.set_content_height(y_end - y_start);
+        child_box_state.offset = { x_start + m_grid_columns[column_start].border_left, y_start + m_grid_rows[row_start].border_top };
+
+        child_box_state.border_left = child_box.computed_values().border_left().width;
+        child_box_state.border_right = child_box.computed_values().border_right().width;
+        child_box_state.border_top = child_box.computed_values().border_top().width;
+        child_box_state.border_bottom = child_box.computed_values().border_bottom().width;
 
         auto available_space_for_children = AvailableSpace(AvailableSize::make_definite(child_box_state.content_width()), AvailableSize::make_definite(child_box_state.content_height()));
         if (auto independent_formatting_context = layout_inside(child_box, LayoutMode::Normal, available_space_for_children))
@@ -1896,7 +1921,7 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const
 
     CSSPixels total_y = 0;
     for (auto& grid_row : m_grid_rows)
-        total_y += grid_row.base_size;
+        total_y += grid_row.full_vertical_size();
     m_automatic_content_height = total_y;
 }
 

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

@@ -80,6 +80,21 @@ private:
         CSSPixels planned_increase { 0 };
         bool is_gap { false };
 
+        CSSPixels border_left { 0 };
+        CSSPixels border_right { 0 };
+        CSSPixels border_top { 0 };
+        CSSPixels border_bottom { 0 };
+
+        CSSPixels full_horizontal_size() const
+        {
+            return base_size + border_left + border_right;
+        }
+
+        CSSPixels full_vertical_size() const
+        {
+            return base_size + border_top + border_bottom;
+        }
+
         TemporaryTrack(CSS::GridSize min_track_sizing_function, CSS::GridSize max_track_sizing_function)
             : min_track_sizing_function(min_track_sizing_function)
             , max_track_sizing_function(max_track_sizing_function)