[css-grid] Different width of grid container between initial load and refresh
authorjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Oct 2016 12:33:28 +0000 (12:33 +0000)
committerjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Oct 2016 12:33:28 +0000 (12:33 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163535

Reviewed by Manuel Rego Casasnovas.

Source/WebCore:

Grid's layout logic manages two different override sizes; one it's
designed to implement the grid item's stretching behavior, identified
with the concept of 'overrideContentLogicalSize'; there is another
override size, known as overrideContainingBlockContentLogicalSize,
used to implement the Grid Area abstraction, which will behave as
the actual containing block of any grid item.

During grid's layout logic these override sizes are set according
to the CSS style rules. This affects how the grid container and its
children are going to be sized during layout. Grid Tracks sizing
algorithm depends on these override sizes.

In order to ensure that the tracks sizing algorithm produces the
same results when it's run consecutively several times, we need to
clear these override sizes and perform a layout of the affected grid
items. Otherwise, the affected items will return sizing values which
depend on the override values set in the previous layout, which in
some cases, like orthogonal flows, may change through different runs
of the sizing algorithm.

Test: fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutBlock):

LayoutTests:

Tests to ensure repeated layouts on grid elements produce the same results when using
orthogonal grid items.

* fast/css-grid-layout/repeating-layout-must-produce-the-same-results-expected.txt: Added.
* fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@207460 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/grid-track-sizing-with-orthogonal-flows.html
LayoutTests/fast/css-grid-layout/grid-track-sizing-with-percentages-and-orthogonal-flows.html
LayoutTests/fast/css-grid-layout/repeating-layout-must-produce-the-same-results-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderGrid.cpp

index fd40c62..d02a13a 100644 (file)
@@ -1,3 +1,16 @@
+2016-10-18  Javier Fernandez  <jfernandez@igalia.com>
+
+        [css-grid] Different width of grid container between initial load and refresh
+        https://bugs.webkit.org/show_bug.cgi?id=163535
+
+        Reviewed by Manuel Rego Casasnovas.
+
+        Tests to ensure repeated layouts on grid elements produce the same results when using
+        orthogonal grid items.
+
+        * fast/css-grid-layout/repeating-layout-must-produce-the-same-results-expected.txt: Added.
+        * fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html: Added.
+
 2016-10-17  Sergio Villar Senin  <svillar@igalia.com>
 
         [css-grid] Constrain by min|max-height on auto repeat computation
index 90c6da1..7bed25f 100644 (file)
@@ -46,7 +46,7 @@ body {
 
 <div class="container">
     <p>Grid width under <b>min-content</b> constrain and <b>fixed</b> height.<br> All grid items sized with <b>min-{width, height} auto</b>.<br> Orthogonal green row track assumed as infinity, hence 10px for the column track. Actual row tracks size is different, hence overflowing. </p>
-    <div class="grid itemsStart contentStart min-content height200" data-expected-width="30" data-expected-height="200">
+    <div class="grid itemsStart contentStart min-content height200" data-expected-width="50" data-expected-height="200">
         <div class="firstRowFirstColumn"             data-offset-x="0"  data-offset-y="0"   data-expected-width="30" data-expected-height="50">XX XXX X XXX XX</div>
         <div class="verticalLR firstRowSecondColumn" data-offset-x="30" data-offset-y="0"   data-expected-width="40" data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
         <div class="verticalLR secondRowFirstColumn" data-offset-x="0"  data-offset-y="105" data-expected-width="20" data-expected-height="95">XXXX XX X XX XXX</div>
@@ -55,18 +55,18 @@ body {
 
 <div class="container">
     <p>Grid width under <b>max-content</b> constrain and <b>fixed</b> height.<br> All grid items sized with <b>min-{width, height} auto</b>.<br> Parallel blue column track sized as its max of 150x, while Orthogonal green row, assumed as infinity, sized as 10px. Since actual row tracks size is different, green column track will occupy some space initally assigned to the blue one.</p>
-    <div class="grid itemsStart contentStart max-content height200" data-expected-width="150" data-expected-height="200">
-        <div class="firstRowFirstColumn"             data-offset-x="0"   data-offset-y="0"   data-expected-width="110" data-expected-height="20">XX XXX X XXX XX</div>
-        <div class="verticalLR firstRowSecondColumn" data-offset-x="110" data-offset-y="0"   data-expected-width="40"  data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
+    <div class="grid itemsStart contentStart max-content height200" data-expected-width="170" data-expected-height="200">
+        <div class="firstRowFirstColumn"             data-offset-x="0"   data-offset-y="0"   data-expected-width="130" data-expected-height="20">XX XXX X XXX XX</div>
+        <div class="verticalLR firstRowSecondColumn" data-offset-x="130" data-offset-y="0"   data-expected-width="40"  data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
         <div class="verticalLR secondRowFirstColumn" data-offset-x="0"   data-offset-y="105" data-expected-width="20"  data-expected-height="95">XXXX XX X XX XXX</div>
     </div>
 </div>
 
 <div class="container">
     <p>Grid width under <b>fit-content</b> constrain and <b>fixed</b> height.<br >All grid items sized with <b>min-{width, height} auto</b>.<br> Since we use assumed row tracks sizes, minimum and maximum will be the same, hence fit-content will produce the same result than max-content.</p>
-    <div class="grid itemsStart contentStart fit-content height200" data-expected-width="150" data-expected-height="200">
-        <div class="firstRowFirstColumn"             data-offset-x="0"   data-offset-y="0"   data-expected-width="110" data-expected-height="20">XX XXX X XXX XX</div>
-        <div class="verticalLR firstRowSecondColumn" data-offset-x="110" data-offset-y="0"   data-expected-width="40"  data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
+    <div class="grid itemsStart contentStart fit-content height200" data-expected-width="170" data-expected-height="200">
+        <div class="firstRowFirstColumn"             data-offset-x="0"   data-offset-y="0"   data-expected-width="130" data-expected-height="20">XX XXX X XXX XX</div>
+        <div class="verticalLR firstRowSecondColumn" data-offset-x="130" data-offset-y="0"   data-expected-width="40"  data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
         <div class="verticalLR secondRowFirstColumn" data-offset-x="0"   data-offset-y="105" data-expected-width="20"  data-expected-height="95">XXXX XX X XX XXX</div>
     </div>
 </div>
@@ -120,9 +120,9 @@ body {
 
 <div class="container">
     <p>Grid width under <b>max-content</b> constrain and <b>fixed</b> height.<br> All grid items sized with <b>min-width: 0px, min-height: auto</b>.<br> Since container is sized under max-content, tracks will use its maximum size.</p>
-    <div class="grid itemsStart contentStart max-content height200" data-expected-width="160" data-expected-height="200">
-        <div class="minWidthZero firstRowFirstColumn"               data-offset-x="0"   data-offset-y="0"   data-expected-width="120" data-expected-height="20">XX XXX X XXX XX</div>
-        <div class="minWidthZero verticalLR firstRowSecondColumn"   data-offset-x="120" data-offset-y="0"   data-expected-width="40"  data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
+    <div class="grid itemsStart contentStart max-content height200" data-expected-width="170" data-expected-height="200">
+        <div class="minWidthZero firstRowFirstColumn"               data-offset-x="0"   data-offset-y="0"   data-expected-width="130" data-expected-height="20">XX XXX X XXX XX</div>
+        <div class="minWidthZero verticalLR firstRowSecondColumn"   data-offset-x="130" data-offset-y="0"   data-expected-width="40"  data-expected-height="105">X XXX XX XXXXX XX XXX X XXXX X XX</div>
         <div class="minWidthZero verticalLR secondRowFirstColumn"   data-offset-x="0"   data-offset-y="105" data-expected-width="20"  data-expected-height="95">XXXX XX X XX XXX</div>
     </div>
 </div>
index ebd0f4e..9dc3fbc 100644 (file)
@@ -24,7 +24,7 @@ body {
 
 <p>HORIZONTAL-TB container with VERTICAL-LR items.</p>
 <div class="container">
-    <div class="grid itemsStart contentStart fit-content" data-expected-width="100" data-expected-height="260">
+    <div class="grid itemsStart contentStart fit-content" data-expected-width="110" data-expected-height="260">
         <div class="firstRowFirstColumn   verticalLR" data-offset-x="0"  data-offset-y="0"  data-expected-width="10" data-expected-height="50">X X X</div>
         <div class="firstRowSecondColumn  verticalLR" data-offset-x="100" data-offset-y="0"  data-expected-width="10" data-expected-height="110">X X X X X X</div>
         <div class="secondRowFirstColumn  verticalLR" data-offset-x="0"  data-offset-y="110" data-expected-width="10" data-expected-height="110">X X X X X X</div>
@@ -34,7 +34,7 @@ body {
 
 <p>HORIZONTAL-TB container with VERTICAL-RL items.</p>
 <div class="container">
-    <div class="grid itemsStart contentStart fit-content" data-expected-width="100" data-expected-height="260">
+    <div class="grid itemsStart contentStart fit-content" data-expected-width="110" data-expected-height="260">
         <div class="firstRowFirstColumn   verticalRL" data-offset-x="0"  data-offset-y="0"  data-expected-width="10" data-expected-height="50">X X X</div>
         <div class="firstRowSecondColumn  verticalRL" data-offset-x="100" data-offset-y="0"  data-expected-width="10" data-expected-height="110">X X X X X X</div>
         <div class="secondRowFirstColumn  verticalRL" data-offset-x="0"  data-offset-y="110" data-expected-width="10" data-expected-height="110">X X X X X X</div>
@@ -44,7 +44,7 @@ body {
 
 <p>VERTICAL-LR container with HORIZONTAL-TB items.</p>
 <div class="container">
-    <div class="grid itemsStart contentStart verticalLR fit-content" data-expected-width="260" data-expected-height="120">
+    <div class="grid itemsStart contentStart verticalLR fit-content" data-expected-width="260" data-expected-height="110">
         <div class="firstRowFirstColumn   horizontalTB" data-offset-x="0"   data-offset-y="0"  data-expected-width="50" data-expected-height="10">X X X</div>
         <div class="firstRowSecondColumn  horizontalTB" data-offset-x="0" data-offset-y="100" data-expected-width="110" data-expected-height="10">X X X X X X</div>
         <div class="secondRowFirstColumn  horizontalTB" data-offset-x="110"   data-offset-y="0"  data-expected-width="110" data-expected-height="10">X X X X X X</div>
@@ -54,7 +54,7 @@ body {
 
 <p>VERTICAL-RL container with HORIZONTAL-TB items.</p>
 <div class="container">
-    <div class="grid itemsStart contentStart verticalRL fit-content" data-expected-width="260" data-expected-height="100">
+    <div class="grid itemsStart contentStart verticalRL fit-content" data-expected-width="260" data-expected-height="110">
         <div class="firstRowFirstColumn   horizontalTB" data-offset-x="210"   data-offset-y="0"  data-expected-width="50" data-expected-height="10">X X X</div>
         <div class="firstRowSecondColumn  horizontalTB" data-offset-x="150" data-offset-y="100" data-expected-width="110" data-expected-height="10">X X X X X X</div>
         <div class="secondRowFirstColumn  horizontalTB" data-offset-x="40"   data-offset-y="0"  data-expected-width="110" data-expected-height="10">X X X X X X</div>
diff --git a/LayoutTests/fast/css-grid-layout/repeating-layout-must-produce-the-same-results-expected.txt b/LayoutTests/fast/css-grid-layout/repeating-layout-must-produce-the-same-results-expected.txt
new file mode 100644 (file)
index 0000000..f66442c
--- /dev/null
@@ -0,0 +1,13 @@
+Regresison test for bug 628565 - Ensure that we get the same sizing results when doing several layouts.
+
+XX X
+XX X
+PASS
+
+XX X
+XX X
+PASS
+
+XX X
+XX X
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html b/LayoutTests/fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html
new file mode 100644 (file)
index 0000000..f4c246d
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<link href="resources/grid.css" rel="stylesheet">
+<link href="../css-intrinsic-dimensions/resources/width-keyword-classes.css" rel="stylesheet">
+<style>
+body {
+   margin: 0;
+}
+.container {
+   width: 100px;
+}
+.grid {
+  border: 5px solid;
+  grid-template-rows: 50px;
+  font: 25px/1 Ahem;
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+<script>
+    function runTest() {
+       document.body.offsetTop;
+       document.body.style.width = "99%";
+       document.body.offsetTop;
+       document.body.style.width = "100%";
+       checkLayout('.grid');
+    }
+</script>
+<body onload="runTest();">
+<p>Regresison test for bug 628565 - Ensure that we get the same sizing results when doing several layouts.</p>
+<div class="grid fit-content" data-expected-width="135" data-expected-height="60">
+  <div class="firstRowFirstColumn verticalLR" data-expected-width="50" data-expected-height="50">XX X</div>
+  <div class="firstRowSecondColumn" data-expected-width="75" data-expected-height="50">XX X</div>
+</div>
+<br>
+<div class="grid min-content" data-expected-width="85" data-expected-height="60">
+  <div class="firstRowFirstColumn verticalLR" data-expected-width="50" data-expected-height="50">XX X</div>
+  <div class="firstRowSecondColumn" data-expected-width="50" data-expected-height="50">XX X</div>
+</div>
+<br>
+<div class="grid max-content" data-expected-width="135" data-expected-height="60">
+  <div class="firstRowFirstColumn verticalLR" data-expected-width="50" data-expected-height="50">XX X</div>
+  <div class="firstRowSecondColumn" data-expected-width="75" data-expected-height="50">XX X</div>
+</div>
+</body>
index 1e43ef6..b24df94 100644 (file)
@@ -1,3 +1,35 @@
+2016-10-18  Javier Fernandez  <jfernandez@igalia.com>
+
+        [css-grid] Different width of grid container between initial load and refresh
+        https://bugs.webkit.org/show_bug.cgi?id=163535
+
+        Reviewed by Manuel Rego Casasnovas.
+
+        Grid's layout logic manages two different override sizes; one it's
+        designed to implement the grid item's stretching behavior, identified
+        with the concept of 'overrideContentLogicalSize'; there is another
+        override size, known as overrideContainingBlockContentLogicalSize,
+        used to implement the Grid Area abstraction, which will behave as
+        the actual containing block of any grid item.
+
+        During grid's layout logic these override sizes are set according
+        to the CSS style rules. This affects how the grid container and its
+        children are going to be sized during layout. Grid Tracks sizing
+        algorithm depends on these override sizes.
+
+        In order to ensure that the tracks sizing algorithm produces the
+        same results when it's run consecutively several times, we need to
+        clear these override sizes and perform a layout of the affected grid
+        items. Otherwise, the affected items will return sizing values which
+        depend on the override values set in the previous layout, which in
+        some cases, like orthogonal flows, may change through different runs
+        of the sizing algorithm.
+
+        Test: fast/css-grid-layout/repeating-layout-must-produce-the-same-results.html
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::layoutBlock):
+
 2016-10-18  Youenn Fablet  <youenn@apple.com>
 
         CachedResourceLoader should not need to remove fragment identifier
index 83a4563..a51c487 100644 (file)
@@ -460,6 +460,19 @@ void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
 
     LayoutSize previousSize = size();
 
+    // We need to clear both own and containingBlock override sizes of orthogonal items to ensure we get the
+    // same result when grid's intrinsic size is computed again in the updateLogicalWidth call bellow.
+    if (sizesLogicalWidthToFitContent(MaxSize) || style().logicalWidth().isIntrinsicOrAuto()) {
+        for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+            if (child->isOutOfFlowPositioned() || !isOrthogonalChild(*child))
+                continue;
+            child->clearOverrideSize();
+            child->clearContainingBlockOverrideSize();
+            child->setNeedsLayout();
+            child->layoutIfNeeded();
+        }
+    }
+
     setLogicalHeight(0);
     updateLogicalWidth();