Title: [291464] trunk
Revision
291464
Author
[email protected]
Date
2022-03-17 19:33:37 -0700 (Thu, 17 Mar 2022)

Log Message

Subgrid items should always be stretched.
https://bugs.webkit.org/show_bug.cgi?id=237628

Reviewed by Alan Bujtas.

LayoutTests/imported/w3c:

* web-platform-tests/css/css-grid/subgrid/subgrid-stretch-expected.html: Added.
* web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html: Added.

Added new WPT test covering various width/height and alignement contraints that should be
ignored since subgrids are always stretched.

Source/WebCore:

Fixes https://drafts.csswg.org/css-grid-2/#subgrid-box-alignment

Test: imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::computeLogicalWidthInFragment const):
(WebCore::RenderBox::hasStretchedLogicalHeight const):
(WebCore::RenderBox::hasStretchedLogicalWidth const):
* rendering/RenderBox.h:

Makes computeLogicalWidthInFragment use the override logical width for grid items
if it's been set, as we already do for height. We don't early return, so that margins
still get computed relative to this width.

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutGridItems):
(WebCore::RenderGrid::availableAlignmentSpaceForChildBeforeStretching const):
(WebCore::RenderGrid::alignSelfForChild const):
(WebCore::RenderGrid::justifySelfForChild const):
(WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded):
(WebCore::RenderGrid::applySubgridStretchAlignmentToChildIfNeeded):
* rendering/RenderGrid.h:

Sets the required override width/height size on subgrid items so that they get
stretched.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (291463 => 291464)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2022-03-18 02:30:52 UTC (rev 291463)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2022-03-18 02:33:37 UTC (rev 291464)
@@ -1,3 +1,16 @@
+2022-03-17  Matt Woodrow  <[email protected]>
+
+        Subgrid items should always be stretched.
+        https://bugs.webkit.org/show_bug.cgi?id=237628
+
+        Reviewed by Alan Bujtas.
+
+        * web-platform-tests/css/css-grid/subgrid/subgrid-stretch-expected.html: Added.
+        * web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html: Added.
+
+        Added new WPT test covering various width/height and alignement contraints that should be
+        ignored since subgrids are always stretched.
+
 2022-03-17  Antoine Quint  <[email protected]>
 
         REGRESSION (iOS 15.4 / r287669): Mobile app stopped working due to CSS / angular animation

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch-expected.html (0 => 291464)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch-expected.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch-expected.html	2022-03-18 02:33:37 UTC (rev 291464)
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html><head>
+  <meta charset="utf-8">
+  <title>CSS Grid Test: The subgrid is always stretched in its subgridded dimension(s)</title>
+  <link rel="author" title="Matt Woodrow" href=""
+  <link rel="help" href=""
+  <style>
+   body {
+     margin: 0;
+   }
+  .grid {
+    display: inline-block;
+    width: 100px;
+    height: 100px;
+    background-color: blue;
+  }
+  </style>
+</head>
+<body>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+
+  <br>
+
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+  <div class="grid"></div>
+
+</body>
+</html>

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html (0 => 291464)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html	2022-03-18 02:33:37 UTC (rev 291464)
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML>
+<html><head>
+  <meta charset="utf-8">
+  <title>CSS Grid Test: The subgrid is always stretched in its subgridded dimension(s)</title>
+  <link rel="author" title="Matt Woodrow" href=""
+  <link rel="help" href=""
+  <link rel="match" href=""
+  <style>
+  body {
+    margin: 0;
+  }
+  .grid {
+    display: inline-grid;
+    grid-template-columns: 100px;
+    grid-template-rows: 100px;
+  }
+  .subgrid {
+    display: grid;
+    background-color: blue;
+  }
+  .rows {
+    grid-template-rows: subgrid;
+    align-self: baseline;
+  }
+  .columns {
+    grid-template-columns: subgrid;
+    justify-self: baseline;
+  }
+  .vrl {
+    writing-mode: vertical-rl;
+  }
+  .vrl.rows {
+    align-self: initial;
+    justify-self: baseline;
+  }
+  .vrl.columns {
+    justify-self: initial;
+    align-self: baseline;
+  }
+  </style>
+</head>
+<body>
+  <div class="grid">
+    <div class="subgrid rows" style="height: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid rows" style="height: 150px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid rows" style="max-height: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid rows" style="min-height: 150px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid columns" style="width: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid columns" style="width: 150px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid columns" style="max-width: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid columns" style="min-width: 150px;"></div>
+  </div>
+
+  <br>
+
+  <div class="grid">
+    <div class="subgrid vrl rows" style="width: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl rows" style="width: 150px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl rows" style="max-width: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl rows" style="min-width: 150px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl columns" style="height: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl columns" style="height: 150px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl columns" style="max-height: 50px;"></div>
+  </div>
+  <div class="grid">
+    <div class="subgrid vrl columns" style="min-height: 150px;"></div>
+  </div>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (291463 => 291464)


--- trunk/Source/WebCore/ChangeLog	2022-03-18 02:30:52 UTC (rev 291463)
+++ trunk/Source/WebCore/ChangeLog	2022-03-18 02:33:37 UTC (rev 291464)
@@ -1,3 +1,36 @@
+2022-03-17  Matt Woodrow  <[email protected]>
+
+        Subgrid items should always be stretched.
+        https://bugs.webkit.org/show_bug.cgi?id=237628
+
+        Reviewed by Alan Bujtas.
+
+        Fixes https://drafts.csswg.org/css-grid-2/#subgrid-box-alignment
+
+        Test: imported/w3c/web-platform-tests/css/css-grid/subgrid/subgrid-stretch.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::computeLogicalWidthInFragment const):
+        (WebCore::RenderBox::hasStretchedLogicalHeight const):
+        (WebCore::RenderBox::hasStretchedLogicalWidth const):
+        * rendering/RenderBox.h:
+
+        Makes computeLogicalWidthInFragment use the override logical width for grid items
+        if it's been set, as we already do for height. We don't early return, so that margins
+        still get computed relative to this width.
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::layoutGridItems):
+        (WebCore::RenderGrid::availableAlignmentSpaceForChildBeforeStretching const):
+        (WebCore::RenderGrid::alignSelfForChild const):
+        (WebCore::RenderGrid::justifySelfForChild const):
+        (WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded):
+        (WebCore::RenderGrid::applySubgridStretchAlignmentToChildIfNeeded):
+        * rendering/RenderGrid.h:
+
+        Sets the required override width/height size on subgrid items so that they get
+        stretched.
+
 2022-03-17  Alan Bujtas  <[email protected]>
 
         [IFC][Integration] Introduce LineSelection

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (291463 => 291464)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2022-03-18 02:30:52 UTC (rev 291463)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2022-03-18 02:33:37 UTC (rev 291464)
@@ -2726,7 +2726,9 @@
         containerWidthInInlineDirection = perpendicularContainingBlockLogicalHeight();
 
     // Width calculations
-    if (treatAsReplaced) {
+    if (isGridItem() && hasOverridingLogicalWidth()) {
+        computedValues.m_extent = overridingLogicalWidth();
+    } else if (treatAsReplaced) {
         computedValues.m_extent = logicalWidthLength.value() + borderAndPaddingLogicalWidth();
     } else if (shouldComputeLogicalWidthFromAspectRatio() && style().logicalWidth().isAuto()) {
         computedValues.m_extent = computeLogicalWidthFromAspectRatio(fragment);
@@ -2878,8 +2880,13 @@
         // The 'normal' value behaves like 'start' except for Flexbox Items, which obviously should have a container.
         return false;
     }
-    if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
+    if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) {
+        if (is<RenderGrid>(this) && downcast<RenderGrid>(this)->isSubgridInParentDirection(ForColumns))
+            return true;
         return style.resolvedJustifySelf(&containingBlock->style(), containingBlock->selfAlignmentNormalBehavior(this)).position() == ItemPosition::Stretch;
+    }
+    if (is<RenderGrid>(this) && downcast<RenderGrid>(this)->isSubgridInParentDirection(ForRows))
+        return true;
     return style.resolvedAlignSelf(&containingBlock->style(), containingBlock->selfAlignmentNormalBehavior(this)).position() == ItemPosition::Stretch;
 }
 
@@ -2896,8 +2903,13 @@
         return false;
     }
     auto normalItemPosition = stretchingMode == StretchingMode::Any ? containingBlock->selfAlignmentNormalBehavior(this) : ItemPosition::Normal;
-    if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
+    if (containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode()) {
+        if (is<RenderGrid>(this) && downcast<RenderGrid>(this)->isSubgridInParentDirection(ForRows))
+            return true;
         return style.resolvedAlignSelf(&containingBlock->style(), normalItemPosition).position() == ItemPosition::Stretch;
+    }
+    if (is<RenderGrid>(this) && downcast<RenderGrid>(this)->isSubgridInParentDirection(ForColumns))
+        return true;
     return style.resolvedJustifySelf(&containingBlock->style(), normalItemPosition).position() == ItemPosition::Stretch;
 }
 

Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (291463 => 291464)


--- trunk/Source/WebCore/rendering/RenderGrid.cpp	2022-03-18 02:30:52 UTC (rev 291463)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp	2022-03-18 02:33:37 UTC (rev 291464)
@@ -1055,6 +1055,7 @@
         // call to avoid unnecessary relayouts. This might imply that child margins, needed to correctly
         // determine the available space before stretching, are not set yet.
         applyStretchAlignmentToChildIfNeeded(*child);
+        applySubgridStretchAlignmentToChildIfNeeded(*child);
 
         child->layoutIfNeeded();
 
@@ -1199,17 +1200,19 @@
     return 0;
 }
 
-LayoutUnit RenderGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const RenderBox& child) const
+LayoutUnit RenderGrid::availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const RenderBox& child, GridTrackSizingDirection direction) const
 {
     // Because we want to avoid multiple layouts, stretching logic might be performed before
     // children are laid out, so we can't use the child cached values. Hence, we need to
     // compute margins in order to determine the available height before stretching.
-    GridTrackSizingDirection childBlockFlowDirection = GridLayoutFunctions::flowAwareDirectionForChild(*this, child, ForRows);
-    return std::max(0_lu, gridAreaBreadthForChild - GridLayoutFunctions::marginLogicalSizeForChild(*this, childBlockFlowDirection, child));
+    auto childFlowDirection = GridLayoutFunctions::flowAwareDirectionForChild(*this, child, direction);
+    return std::max(0_lu, gridAreaBreadthForChild - GridLayoutFunctions::marginLogicalSizeForChild(*this, childFlowDirection, child));
 }
 
 StyleSelfAlignmentData RenderGrid::alignSelfForChild(const RenderBox& child, StretchingMode stretchingMode, const RenderStyle* gridStyle) const
 {
+    if (isSubgridInParentDirection(ForRows))
+        return { ItemPosition::Stretch, OverflowAlignment::Default };
     if (!gridStyle)
         gridStyle = &style();
     auto normalBehavior = stretchingMode == StretchingMode::Any ? selfAlignmentNormalBehavior(&child) : ItemPosition::Normal;
@@ -1218,6 +1221,8 @@
 
 StyleSelfAlignmentData RenderGrid::justifySelfForChild(const RenderBox& child, StretchingMode stretchingMode, const RenderStyle* gridStyle) const
 {
+    if (isSubgridInParentDirection(ForColumns))
+        return { ItemPosition::Stretch, OverflowAlignment::Default };
     if (!gridStyle)
         gridStyle = &style();
     auto normalBehavior = stretchingMode == StretchingMode::Any ? selfAlignmentNormalBehavior(&child) : ItemPosition::Normal;
@@ -1251,7 +1256,7 @@
     bool blockFlowIsColumnAxis = childBlockDirection == ForRows;
     bool allowedToStretchChildBlockSize = blockFlowIsColumnAxis ? allowedToStretchChildAlongColumnAxis(child) : allowedToStretchChildAlongRowAxis(child);
     if (allowedToStretchChildBlockSize && !aspectRatioPrefersInline(child, blockFlowIsColumnAxis)) {
-        LayoutUnit stretchedLogicalHeight = availableAlignmentSpaceForChildBeforeStretching(GridLayoutFunctions::overridingContainingBlockContentSizeForChild(child, childBlockDirection).value(), child);
+        LayoutUnit stretchedLogicalHeight = availableAlignmentSpaceForChildBeforeStretching(GridLayoutFunctions::overridingContainingBlockContentSizeForChild(child, childBlockDirection).value(), child, ForRows);
         LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight, std::nullopt);
         child.setOverridingLogicalHeight(desiredLogicalHeight);
 
@@ -1264,14 +1269,32 @@
             child.setNeedsLayout(MarkOnlyThis);
         }
     } else if (!allowedToStretchChildBlockSize && allowedToStretchChildAlongRowAxis(child)) {
-        LayoutUnit stretchedLogicalWidth = availableAlignmentSpaceForChildBeforeStretching(GridLayoutFunctions::overridingContainingBlockContentSizeForChild(child, childInlineDirection).value(), child);
+        LayoutUnit stretchedLogicalWidth = availableAlignmentSpaceForChildBeforeStretching(GridLayoutFunctions::overridingContainingBlockContentSizeForChild(child, childInlineDirection).value(), child, ForColumns);
         LayoutUnit desiredLogicalWidth = child.constrainLogicalWidthInFragmentByMinMax(stretchedLogicalWidth, contentWidth(), *this, nullptr);
         child.setOverridingLogicalWidth(desiredLogicalWidth);
         if (desiredLogicalWidth != child.logicalWidth())
             child.setNeedsLayout(MarkOnlyThis);
-    } 
+    }
 }
 
+void RenderGrid::applySubgridStretchAlignmentToChildIfNeeded(RenderBox& child)
+{
+    if (!is<RenderGrid>(child))
+        return;
+
+    if (downcast<RenderGrid>(child).isSubgrid(ForRows)) {
+        auto childBlockDirection = GridLayoutFunctions::flowAwareDirectionForChild(*this, child, ForRows);
+        auto stretchedLogicalHeight = availableAlignmentSpaceForChildBeforeStretching(GridLayoutFunctions::overridingContainingBlockContentSizeForChild(child, childBlockDirection).value(), child, ForRows);
+        child.setOverridingLogicalHeight(stretchedLogicalHeight);
+    }
+
+    if (downcast<RenderGrid>(child).isSubgrid(ForColumns)) {
+        auto childInlineDirection = GridLayoutFunctions::flowAwareDirectionForChild(*this, child, ForColumns);
+        auto stretchedLogicalWidth = availableAlignmentSpaceForChildBeforeStretching(GridLayoutFunctions::overridingContainingBlockContentSizeForChild(child, childInlineDirection).value(), child, ForColumns);
+        child.setOverridingLogicalWidth(stretchedLogicalWidth);
+    }
+}
+
 // FIXME: This logic is shared by RenderFlexibleBox, so it should be moved to RenderBox.
 bool RenderGrid::hasAutoMarginsInColumnAxis(const RenderBox& child) const
 {

Modified: trunk/Source/WebCore/rendering/RenderGrid.h (291463 => 291464)


--- trunk/Source/WebCore/rendering/RenderGrid.h	2022-03-18 02:30:52 UTC (rev 291463)
+++ trunk/Source/WebCore/rendering/RenderGrid.h	2022-03-18 02:33:37 UTC (rev 291464)
@@ -191,10 +191,11 @@
     LayoutUnit gridAreaBreadthForChildIncludingAlignmentOffsets(const RenderBox&, GridTrackSizingDirection) const;
 
     void paintChildren(PaintInfo& forSelf, const LayoutPoint& paintOffset, PaintInfo& forChild, bool usePrintRect) override;
-    LayoutUnit availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const RenderBox&) const;
+    LayoutUnit availableAlignmentSpaceForChildBeforeStretching(LayoutUnit gridAreaBreadthForChild, const RenderBox&, GridTrackSizingDirection) const;
     StyleSelfAlignmentData justifySelfForChild(const RenderBox&, StretchingMode = StretchingMode::Any, const RenderStyle* = nullptr) const;
     StyleSelfAlignmentData alignSelfForChild(const RenderBox&, StretchingMode = StretchingMode::Any, const RenderStyle* = nullptr) const;
     void applyStretchAlignmentToChildIfNeeded(RenderBox&);
+    void applySubgridStretchAlignmentToChildIfNeeded(RenderBox&);
     bool hasAutoSizeInColumnAxis(const RenderBox& child) const;
     bool hasAutoSizeInRowAxis(const RenderBox& child) const;
     bool allowedToStretchChildAlongColumnAxis(const RenderBox& child) const { return alignSelfForChild(child).position() == ItemPosition::Stretch && hasAutoSizeInColumnAxis(child) && !hasAutoMarginsInColumnAxis(child); }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to