[css-grid] Handle alignment with orthogonal flows
authorjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Jul 2016 10:07:19 +0000 (10:07 +0000)
committerjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Jul 2016 10:07:19 +0000 (10:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=159295

Reviewed by Darin Adler.

Now that grid sizing and positioning issues wrt orthogonal flows have
been clarified in the last spec draft, we can adapt now our alignment
logic to work with orthogonal flows.

Source/WebCore:

Even though basic alignment would work with orthogonal flows with
this patch, we still doesn't allow stretching in that case. I'll provide a
patch for that feature since it's a complex logic and better have an
isolated change.

Tests: fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html
       fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html
       fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html

* rendering/RenderGrid.cpp:
(WebCore::computeOverflowAlignmentOffset): Using 'size' instead of 'breadth' as concept.
(WebCore::RenderGrid::columnAxisPositionForChild): Dealing with orthogonal flow cases.
(WebCore::RenderGrid::rowAxisPositionForChild): Dealing with orthogonal flow cases.
(WebCore::RenderGrid::columnAxisOffsetForChild): Using 'size' instead of 'breadth' as concept.
(WebCore::RenderGrid::rowAxisOffsetForChild): Using 'size' instead of 'breadth' as concept.
(WebCore::RenderGrid::findChildLogicalPosition): Dealing with orthogonal flow cases.

LayoutTests:

These tests ensure that alignment works as expected in the cases where
grid and its children are orthogonal.

* fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-expected.txt: Added.
* fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr-expected.txt: Added.
* fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html: Added.
* fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl-expected.txt: Added.
* fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html: Added.
* fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html: Added.
* fast/css-grid-layout/resources/grid-alignment.css:
(.alignContentSpaceBetween):
(.alignContentSpaceAround):
(.alignContentSpaceEvenly):
(.alignContentStretch):
(.selfStart):
(.selfEnd):
(.selfCenter):
(.selfRight):
(.selfLeft):
(.selfSelfStart):
(.selfSelfEnd):
(.itemsSelfEnd): Deleted.

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

LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/resources/grid-alignment.css
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderGrid.cpp

index eb9fd61..357cd29 100644 (file)
@@ -1,3 +1,37 @@
+2016-07-27  Javier Fernandez  <jfernandez@igalia.com>
+
+        [css-grid] Handle alignment with orthogonal flows
+        https://bugs.webkit.org/show_bug.cgi?id=159295
+
+        Reviewed by Darin Adler.
+
+        Now that grid sizing and positioning issues wrt orthogonal flows have
+        been clarified in the last spec draft, we can adapt now our alignment
+        logic to work with orthogonal flows.
+
+        These tests ensure that alignment works as expected in the cases where
+        grid and its children are orthogonal.
+
+        * fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-expected.txt: Added.
+        * fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr-expected.txt: Added.
+        * fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html: Added.
+        * fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl-expected.txt: Added.
+        * fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html: Added.
+        * fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html: Added.
+        * fast/css-grid-layout/resources/grid-alignment.css:
+        (.alignContentSpaceBetween):
+        (.alignContentSpaceAround):
+        (.alignContentSpaceEvenly):
+        (.alignContentStretch):
+        (.selfStart):
+        (.selfEnd):
+        (.selfCenter):
+        (.selfRight):
+        (.selfLeft):
+        (.selfSelfStart):
+        (.selfSelfEnd):
+        (.itemsSelfEnd): Deleted.
+
 2016-07-26  Youenn Fablet  <youennf@gmail.com>
 
         JS Built-ins should throw this-error messages consistently with binding generated code
diff --git a/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-expected.txt b/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-expected.txt
new file mode 100644 (file)
index 0000000..37cc748
--- /dev/null
@@ -0,0 +1,97 @@
+This test checks that grid items alignment works as expected with HORIZONTAL-TB vs VERTICAL-RL orthogonal flows.
+
+Orthogonal flows: HORIZONTAL-TB vs VERTICAL-RL
+
+Direction: LTR vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: LTR vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Orthogonal flows: HORIZONTAL-TB vs VERTICAL-LR
+
+Direction: LTR vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr-expected.txt b/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr-expected.txt
new file mode 100644 (file)
index 0000000..3f7296e
--- /dev/null
@@ -0,0 +1,54 @@
+This test checks that grid items alignment works as expected with VERTICAL-LR vs HORIZONTAL-TB orthogonal flows.
+
+Direction: LTR vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: LTR vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html b/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html
new file mode 100644 (file)
index 0000000..8cf9379
--- /dev/null
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<link href="resources/grid.css" rel="stylesheet">
+<link href="resources/grid-alignment.css" rel="stylesheet">
+<link href="../css-intrinsic-dimensions/resources/width-keyword-classes.css" rel="stylesheet">
+<script src="../../resources/check-layout.js"></script>
+<style>
+body {
+    margin: 0;
+}
+.container {
+    position: relative;
+}
+.grid {
+    grid-template-columns: 100px 100px;
+    grid-template-rows: 150px 150px;
+    font-size: 10px;
+}
+.item {
+   width: 50px;
+   height: 20px;
+}
+</style>
+<body onload="checkLayout('.grid')">
+
+<p>This test checks that grid items alignment works as expected with VERTICAL-LR vs HORIZONTAL-TB orthogonal flows.</p>
+
+<p>Direction: LTR vs LTR</p>
+<div class="container">
+    <div class="grid fit-content verticalLR directionLTR">
+        <div class="item firstRowFirstColumn   horizontalTB selfEnd"    data-offset-x="100" data-offset-y="80">end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfCenter" data-offset-x="50"  data-offset-y="140">center</div>
+        <div class="item secondRowFirstColumn  horizontalTB selfLeft"   data-offset-x="150" data-offset-y="0">left</div>
+        <div class="item secondRowSecondColumn horizontalTB selfRight"  data-offset-x="150" data-offset-y="180">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalLR directionLTR">
+        <div class="item firstRowFirstColumn   horizontalTB selfSelfEnd"   data-offset-x="100" data-offset-y="80">s-end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfStart"     data-offset-x="0"   data-offset-y="100">start</div>
+        <div class="item secondRowFirstColumn  horizontalTB"               data-offset-x="150" data-offset-y="0">default</div>
+        <div class="item secondRowSecondColumn horizontalTB selfSelfStart" data-offset-x="150" data-offset-y="100">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs LTR</p>
+<div class="container">
+    <div class="grid fit-content verticalLR directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR horizontalTB selfEnd"    data-offset-x="100" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  directionLTR horizontalTB selfCenter" data-offset-x="50"  data-offset-y="40">center</div>
+        <div class="item secondRowFirstColumn  directionLTR horizontalTB selfLeft"   data-offset-x="150" data-offset-y="100">left</div>
+        <div class="item secondRowSecondColumn directionLTR horizontalTB selfRight"  data-offset-x="150" data-offset-y="80">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalLR directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR horizontalTB selfSelfEnd"   data-offset-x="100" data-offset-y="180">s-end</div>
+        <div class="item firstRowSecondColumn  directionLTR horizontalTB selfStart"     data-offset-x="0"   data-offset-y="80">start</div>
+        <div class="item secondRowFirstColumn  directionLTR horizontalTB"               data-offset-x="150" data-offset-y="180">default</div>
+        <div class="item secondRowSecondColumn directionLTR horizontalTB selfSelfStart" data-offset-x="150" data-offset-y="0">s-start</div>
+    </div>
+</div>
+
+<p>Direction: LTR vs RTL</p>
+<div class="container">
+    <div class="grid fit-content verticalLR directionLTR">
+        <div class="item firstRowFirstColumn   directionRTL horizontalTB selfEnd"    data-offset-x="100" data-offset-y="80">end</div>
+        <div class="item firstRowSecondColumn  directionRTL horizontalTB selfCenter" data-offset-x="50"  data-offset-y="140">center</div>
+        <div class="item secondRowFirstColumn  directionRTL horizontalTB selfLeft"   data-offset-x="150" data-offset-y="0">left</div>
+        <div class="item secondRowSecondColumn directionRTL horizontalTB selfRight"  data-offset-x="150" data-offset-y="180">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalLR directionLTR">
+        <div class="item firstRowFirstColumn   directionRTL horizontalTB selfSelfEnd"   data-offset-x="0"   data-offset-y="80">s-end</div>
+        <div class="item firstRowSecondColumn  directionRTL horizontalTB selfStart"     data-offset-x="0"   data-offset-y="100">start</div>
+        <div class="item secondRowFirstColumn  directionRTL horizontalTB"               data-offset-x="150" data-offset-y="0">default</div>
+        <div class="item secondRowSecondColumn directionRTL horizontalTB selfSelfStart" data-offset-x="250" data-offset-y="100">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs RTL</p>
+<div class="container">
+    <div class="grid fit-content verticalLR directionRTL">
+        <div class="item firstRowFirstColumn   horizontalTB selfEnd"    data-offset-x="100" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfCenter" data-offset-x="50"  data-offset-y="40">center</div>
+        <div class="item secondRowFirstColumn  horizontalTB selfLeft"   data-offset-x="150" data-offset-y="100">left</div>
+        <div class="item secondRowSecondColumn horizontalTB selfRight"  data-offset-x="150" data-offset-y="80">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalLR directionRTL">
+        <div class="item firstRowFirstColumn   horizontalTB selfSelfEnd"   data-offset-x="0"   data-offset-y="180">s-end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfStart"     data-offset-x="0"   data-offset-y="80">start</div>
+        <div class="item secondRowFirstColumn  horizontalTB"               data-offset-x="150" data-offset-y="180">default</div>
+        <div class="item secondRowSecondColumn horizontalTB selfSelfStart" data-offset-x="250" data-offset-y="0">s-start</div>
+    </div>
+</div>
+</body>
diff --git a/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl-expected.txt b/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl-expected.txt
new file mode 100644 (file)
index 0000000..3db777b
--- /dev/null
@@ -0,0 +1,54 @@
+This test checks that grid items alignment works as expected with VERTICAL-RL vs HORIZONTAL-TB orthogonal flows.
+
+Direction: LTR vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs LTR
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: LTR vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
+Direction: RTL vs RTL
+
+end
+center
+left
+right
+PASS
+
+s-end
+start
+default
+s-start
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html b/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html
new file mode 100644 (file)
index 0000000..727a9af
--- /dev/null
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<link href="resources/grid.css" rel="stylesheet">
+<link href="resources/grid-alignment.css" rel="stylesheet">
+<link href="../css-intrinsic-dimensions/resources/width-keyword-classes.css" rel="stylesheet">
+<script src="../../resources/check-layout.js"></script>
+<style>
+body {
+    margin: 0;
+}
+.container {
+    position: relative;
+}
+.grid {
+    grid-template-columns: 100px 100px;
+    grid-template-rows: 150px 150px;
+    font-size: 10px;
+}
+.item {
+   width: 50px;
+   height: 20px;
+}
+</style>
+<body onload="checkLayout('.grid')">
+
+<p>This test checks that grid items alignment works as expected with VERTICAL-RL vs HORIZONTAL-TB orthogonal flows.</p>
+
+<p>Direction: LTR vs LTR</p>
+<div class="container">
+    <div class="grid fit-content verticalRL directionLTR">
+        <div class="item firstRowFirstColumn   horizontalTB selfEnd"    data-offset-x="150" data-offset-y="80">end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfCenter" data-offset-x="200" data-offset-y="140">center</div>
+        <div class="item secondRowFirstColumn  horizontalTB selfLeft"   data-offset-x="100" data-offset-y="0">left</div>
+        <div class="item secondRowSecondColumn horizontalTB selfRight"  data-offset-x="100" data-offset-y="180">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalRL directionLTR">
+        <div class="item firstRowFirstColumn   horizontalTB selfSelfEnd"   data-offset-x="250" data-offset-y="80">s-end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfStart"     data-offset-x="250" data-offset-y="100">start</div>
+        <div class="item secondRowFirstColumn  horizontalTB"               data-offset-x="100" data-offset-y="0">default</div>
+        <div class="item secondRowSecondColumn horizontalTB selfSelfStart" data-offset-x="0"   data-offset-y="100">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs LTR</p>
+<div class="container">
+    <div class="grid fit-content verticalRL directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR horizontalTB selfEnd"    data-offset-x="150" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  directionLTR horizontalTB selfCenter" data-offset-x="200" data-offset-y="40">center</div>
+        <div class="item secondRowFirstColumn  directionLTR horizontalTB selfLeft"   data-offset-x="100" data-offset-y="100">left</div>
+        <div class="item secondRowSecondColumn directionLTR horizontalTB selfRight"  data-offset-x="100" data-offset-y="80">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalRL directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR horizontalTB selfSelfEnd"   data-offset-x="250" data-offset-y="180">s-end</div>
+        <div class="item firstRowSecondColumn  directionLTR horizontalTB selfStart"     data-offset-x="250" data-offset-y="80">start</div>
+        <div class="item secondRowFirstColumn  directionLTR horizontalTB"               data-offset-x="100" data-offset-y="180">default</div>
+        <div class="item secondRowSecondColumn directionLTR horizontalTB selfSelfStart" data-offset-x="0"   data-offset-y="0">s-start</div>
+    </div>
+</div>
+
+<p>Direction: LTR vs RTL</p>
+<div class="container">
+    <div class="grid fit-content verticalRL directionLTR">
+        <div class="item firstRowFirstColumn   directionRTL horizontalTB selfEnd"    data-offset-x="150" data-offset-y="80">end</div>
+        <div class="item firstRowSecondColumn  directionRTL horizontalTB selfCenter" data-offset-x="200" data-offset-y="140">center</div>
+        <div class="item secondRowFirstColumn  directionRTL horizontalTB selfLeft"   data-offset-x="100" data-offset-y="0">left</div>
+        <div class="item secondRowSecondColumn directionRTL horizontalTB selfRight"  data-offset-x="100" data-offset-y="180">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalRL directionLTR">
+        <div class="item firstRowFirstColumn   directionRTL horizontalTB selfSelfEnd"   data-offset-x="150" data-offset-y="80">s-end</div>
+        <div class="item firstRowSecondColumn  directionRTL horizontalTB selfStart"     data-offset-x="250" data-offset-y="100">start</div>
+        <div class="item secondRowFirstColumn  directionRTL horizontalTB"               data-offset-x="100" data-offset-y="0">default</div>
+        <div class="item secondRowSecondColumn directionRTL horizontalTB selfSelfStart" data-offset-x="100" data-offset-y="100">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs RTL</p>
+<div class="container">
+    <div class="grid fit-content verticalRL directionRTL">
+        <div class="item firstRowFirstColumn   horizontalTB selfEnd"    data-offset-x="150" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfCenter" data-offset-x="200" data-offset-y="40">center</div>
+        <div class="item secondRowFirstColumn  horizontalTB selfLeft"   data-offset-x="100" data-offset-y="100">left</div>
+        <div class="item secondRowSecondColumn horizontalTB selfRight"  data-offset-x="100" data-offset-y="80">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content verticalRL directionRTL">
+        <div class="item firstRowFirstColumn   horizontalTB selfSelfEnd"   data-offset-x="150" data-offset-y="180">s-end</div>
+        <div class="item firstRowSecondColumn  horizontalTB selfStart"     data-offset-x="250" data-offset-y="80">start</div>
+        <div class="item secondRowFirstColumn  horizontalTB"               data-offset-x="100" data-offset-y="180">default</div>
+        <div class="item secondRowSecondColumn horizontalTB selfSelfStart" data-offset-x="100" data-offset-y="0">s-start</div>
+    </div>
+</div>
+
+</body>
diff --git a/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html b/LayoutTests/fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html
new file mode 100644 (file)
index 0000000..a3b908f
--- /dev/null
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<link href="resources/grid.css" rel="stylesheet">
+<link href="resources/grid-alignment.css" rel="stylesheet">
+<link href="../css-intrinsic-dimensions/resources/width-keyword-classes.css" rel="stylesheet">
+<script src="../../resources/check-layout.js"></script>
+<style>
+body {
+    margin: 0;
+}
+.container {
+    position: relative;
+}
+.grid {
+    grid-template-columns: 100px 100px;
+    grid-template-rows: 150px 150px;
+    font-size: 10px;
+}
+.item {
+   width: 20px;
+   height: 50px;
+}
+</style>
+<body onload="checkLayout('.grid')">
+<div id="log"></div>
+<p>This test checks that grid items alignment works as expected with HORIZONTAL-TB vs VERTICAL-RL orthogonal flows.</p>
+
+<p>Orthogonal flows: HORIZONTAL-TB vs VERTICAL-RL</p>
+<p>Direction: LTR vs LTR</p>
+<div class="container">
+    <div class="grid fit-content directionLTR">
+        <div class="item firstRowFirstColumn   verticalRL selfEnd"    data-offset-x="80"  data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  verticalRL selfCenter" data-offset-x="140" data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  verticalRL selfLeft"   data-offset-x="0"   data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn verticalRL selfRight"  data-offset-x="180" data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content directionLTR">
+        <div class="item firstRowFirstColumn   verticalRL selfSelfEnd"   data-offset-x="0"   data-offset-y="100">s-end</div>
+        <div class="item firstRowSecondColumn  verticalRL selfStart"     data-offset-x="100" data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  verticalRL"               data-offset-x="0"   data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn verticalRL selfSelfStart" data-offset-x="180" data-offset-y="150">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs LTR</p>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR verticalRL selfEnd"    data-offset-x="100" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  directionLTR verticalRL selfCenter" data-offset-x="40"  data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  directionLTR verticalRL selfLeft"   data-offset-x="100" data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn directionLTR verticalRL selfRight"  data-offset-x="80"  data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR verticalRL selfSelfEnd"   data-offset-x="100" data-offset-y="100">s-end</div>
+        <div class="item firstRowSecondColumn  directionLTR verticalRL selfStart"     data-offset-x="80"  data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  directionLTR verticalRL"               data-offset-x="180" data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn directionLTR verticalRL selfSelfStart" data-offset-x="80"  data-offset-y="150">s-start</div>
+    </div>
+</div>
+
+<p>Direction: LTR vs RTL</p>
+<div class="container">
+    <div class="grid fit-content directionLTR">
+        <div class="item firstRowFirstColumn   directionRTL verticalRL selfEnd"    data-offset-x="80"  data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  directionRTL verticalRL selfCenter" data-offset-x="140" data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  directionRTL verticalRL selfLeft"   data-offset-x="0"   data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn directionRTL verticalRL selfRight"  data-offset-x="180" data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content directionLTR">
+        <div class="item firstRowFirstColumn   directionRTL verticalRL selfSelfEnd"   data-offset-x="0"  data-offset-y="0">s-end</div>
+        <div class="item firstRowSecondColumn  directionRTL verticalRL selfStart"     data-offset-x="100" data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  directionRTL verticalRL"               data-offset-x="0"   data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn directionRTL verticalRL selfSelfStart" data-offset-x="180" data-offset-y="250">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs RTL</p>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   verticalRL selfEnd"    data-offset-x="100" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  verticalRL selfCenter" data-offset-x="40"  data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  verticalRL selfLeft"   data-offset-x="100" data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn verticalRL selfRight"  data-offset-x="80"  data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   verticalRL selfSelfEnd"   data-offset-x="100" data-offset-y="0">s-end</div>
+        <div class="item firstRowSecondColumn  verticalRL selfStart"     data-offset-x="80"  data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  verticalRL"               data-offset-x="180" data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn verticalRL selfSelfStart" data-offset-x="80"  data-offset-y="250">s-start</div>
+    </div>
+</div>
+
+<!-- HORIZONTAL-TB vs VERTICAL-LR -->
+<p>Orthogonal flows: HORIZONTAL-TB vs VERTICAL-LR</p>
+<p>Direction: LTR vs LTR</p>
+<div class="container">
+    <div class="grid fit-content drectionLTR">
+        <div class="item firstRowFirstColumn   verticalLR selfEnd"    data-offset-x="80"  data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  verticalLR selfCenter" data-offset-x="140" data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  verticalLR selfLeft"   data-offset-x="0"   data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn verticalLR selfRight"  data-offset-x="180" data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content drectionLTR">
+        <div class="item firstRowFirstColumn   verticalLR selfSelfEnd"   data-offset-x="80"   data-offset-y="100">s-end</div>
+        <div class="item firstRowSecondColumn  verticalLR selfStart"     data-offset-x="100" data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  verticalLR"               data-offset-x="0"   data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn verticalLR selfSelfStart" data-offset-x="100" data-offset-y="150">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs LTR</p>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR verticalLR selfEnd"    data-offset-x="100" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  directionLTR verticalLR selfCenter" data-offset-x="40"  data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  directionLTR verticalLR selfLeft"   data-offset-x="100"   data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn directionLTR verticalLR selfRight"  data-offset-x="80"   data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   directionLTR verticalLR selfSelfEnd"   data-offset-x="180" data-offset-y="100">s-end</div>
+        <div class="item firstRowSecondColumn  directionLTR verticalLR selfStart"     data-offset-x="80"  data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  directionLTR verticalLR"               data-offset-x="180" data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn directionLTR verticalLR selfSelfStart" data-offset-x="0"   data-offset-y="150">s-start</div>
+    </div>
+</div>
+
+<p>Direction: RTL vs RTL</p>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   verticalLR selfEnd"    data-offset-x="100" data-offset-y="100">end</div>
+        <div class="item firstRowSecondColumn  verticalLR selfCenter" data-offset-x="40"  data-offset-y="50">center</div>
+        <div class="item secondRowFirstColumn  verticalLR selfLeft"   data-offset-x="100" data-offset-y="150">left</div>
+        <div class="item secondRowSecondColumn verticalLR selfRight"  data-offset-x="80"  data-offset-y="150">right</div>
+    </div>
+</div>
+<br>
+<div class="container">
+    <div class="grid fit-content directionRTL">
+        <div class="item firstRowFirstColumn   verticalLR selfSelfEnd"   data-offset-x="180" data-offset-y="0">s-end</div>
+        <div class="item firstRowSecondColumn  verticalLR selfStart"     data-offset-x="80"  data-offset-y="0">start</div>
+        <div class="item secondRowFirstColumn  verticalLR"               data-offset-x="180" data-offset-y="150">default</div>
+        <div class="item secondRowSecondColumn verticalLR selfSelfStart" data-offset-x="0"  data-offset-y="250">s-start</div>
+    </div>
+</div>
+</body>
index 5ebed18..c8a86bb 100644 (file)
 .alignContentRight { align-content: right; }
 .alignContentFlexStart { align-content: flex-start; }
 .alignContentFlexEnd { align-content: flex-end; }
+.alignContentSpaceBetween { align-content: space-between; }
+.alignContentSpaceAround { align-content: space-around; }
+.alignContentSpaceEvenly { align-content: space-evenly; }
+.alignContentStretch { align-content: stretch; }
 
 /* justify-self */
 .justifySelfAuto { justify-self: auto; }
@@ -91,6 +95,7 @@
     align-items: start;
     justify-items: start;
 }
+
 .itemsCenter {
     align-items: center;
     justify-items: center;
     justify-items: self-end;
 }
 
-.stretch {
-    align-self: stretch;
-    justify-self: stretch;
-}
-
 /* Both align-self and justify-self */
 .selfStretch {
     align-self: stretch;
     justify-self: stretch;
 }
+.selfStart {
+    align-self: start;
+    justify-self: start;
+}
+.selfEnd {
+    align-self: end;
+    justify-self: end;
+}
+.selfCenter {
+    align-self: center;
+    justify-self: center;
+}
+.selfRight {
+    align-self: right;
+    justify-self: right;
+}
+.selfLeft {
+    align-self: left;
+    justify-self: left;
+}
+.selfSelfStart {
+    align-self: self-start;
+    justify-self: self-start;
+}
+.selfSelfEnd {
+    align-self: self-end;
+    justify-self: self-end;
+}
 
 /* Both align-content and justify-content */
 .contentStart {
index febf110..a8a6698 100644 (file)
@@ -1,3 +1,31 @@
+2016-07-27  Javier Fernandez  <jfernandez@igalia.com>
+
+        [css-grid] Handle alignment with orthogonal flows
+        https://bugs.webkit.org/show_bug.cgi?id=159295
+
+        Reviewed by Darin Adler.
+
+        Now that grid sizing and positioning issues wrt orthogonal flows have
+        been clarified in the last spec draft, we can adapt now our alignment
+        logic to work with orthogonal flows.
+
+        Even though basic alignment would work with orthogonal flows with
+        this patch, we still doesn't allow stretching in that case. I'll provide a
+        patch for that feature since it's a complex logic and better have an
+        isolated change.
+
+        Tests: fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-lr.html
+               fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows-vertical-rl.html
+               fast/css-grid-layout/grid-item-alignment-with-orthogonal-flows.html
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::computeOverflowAlignmentOffset): Using 'size' instead of 'breadth' as concept.
+        (WebCore::RenderGrid::columnAxisPositionForChild): Dealing with orthogonal flow cases.
+        (WebCore::RenderGrid::rowAxisPositionForChild): Dealing with orthogonal flow cases.
+        (WebCore::RenderGrid::columnAxisOffsetForChild): Using 'size' instead of 'breadth' as concept.
+        (WebCore::RenderGrid::rowAxisOffsetForChild): Using 'size' instead of 'breadth' as concept.
+        (WebCore::RenderGrid::findChildLogicalPosition): Dealing with orthogonal flow cases.
+
 2016-07-26  Youenn Fablet  <youenn@apple.com>
 
         [Fetch API] Response constructor should be able to take a ReadableStream as body
index 460bf75..02d9805 100644 (file)
@@ -2112,9 +2112,9 @@ void RenderGrid::populateGridPositionsForDirection(GridSizingData& sizingData, G
     offsetBetweenTracks = offset.distributionOffset;
 }
 
-static inline LayoutUnit computeOverflowAlignmentOffset(OverflowAlignment overflow, LayoutUnit trackBreadth, LayoutUnit childBreadth)
+static LayoutUnit computeOverflowAlignmentOffset(OverflowAlignment overflow, LayoutUnit trackSize, LayoutUnit childSize)
 {
-    LayoutUnit offset = trackBreadth - childBreadth;
+    LayoutUnit offset = trackSize - childSize;
     switch (overflow) {
     case OverflowAlignmentSafe:
         // If overflow is 'safe', we have to make sure we don't overflow the 'start'
@@ -2263,34 +2263,51 @@ void RenderGrid::updateAutoMarginsInColumnAxisIfNeeded(RenderBox& child)
 GridAxisPosition RenderGrid::columnAxisPositionForChild(const RenderBox& child) const
 {
     bool hasSameWritingMode = child.style().writingMode() == style().writingMode();
+    bool childIsLTR = child.style().isLeftToRightDirection();
 
     switch (child.style().resolvedAlignSelf(style(), selfAlignmentNormalBehavior).position()) {
     case ItemPositionSelfStart:
-        // If orthogonal writing-modes, this computes to 'start'.
-        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
-        // self-start is based on the child's block axis direction. That's why we need to check against the grid container's block flow.
-        return (isOrthogonalChild(child) || hasSameWritingMode) ? GridAxisStart : GridAxisEnd;
+        // FIXME: Should we implement this logic in a generic utility function ?
+        // Aligns the alignment subject to be flush with the edge of the alignment container
+        // corresponding to the alignment subject's 'start' side in the column axis.
+        if (isOrthogonalChild(child)) {
+            // If orthogonal writing-modes, self-start will be based on the child's inline-axis
+            // direction (inline-start), because it's the one parallel to the column axis.
+            if (style().isFlippedBlocksWritingMode())
+                return childIsLTR ? GridAxisEnd : GridAxisStart;
+            return childIsLTR ? GridAxisStart : GridAxisEnd;
+        }
+        // self-start is based on the child's block-flow direction. That's why we need to check against the grid container's block-flow direction.
+        return hasSameWritingMode ? GridAxisStart : GridAxisEnd;
     case ItemPositionSelfEnd:
-        // If orthogonal writing-modes, this computes to 'end'.
-        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
-        // self-end is based on the child's block axis direction. That's why we need to check against the grid container's block flow.
-        return (isOrthogonalChild(child) || hasSameWritingMode) ? GridAxisEnd : GridAxisStart;
+        // FIXME: Should we implement this logic in a generic utility function ?
+        // Aligns the alignment subject to be flush with the edge of the alignment container
+        // corresponding to the alignment subject's 'end' side in the column axis.
+        if (isOrthogonalChild(child)) {
+            // If orthogonal writing-modes, self-end will be based on the child's inline-axis
+            // direction, (inline-end) because it's the one parallel to the column axis.
+            if (style().isFlippedBlocksWritingMode())
+                return childIsLTR ? GridAxisStart : GridAxisEnd;
+            return childIsLTR ? GridAxisEnd : GridAxisStart;
+        }
+        // self-end is based on the child's block-flow direction. That's why we need to check against the grid container's block-flow direction.
+        return hasSameWritingMode ? GridAxisEnd : GridAxisStart;
     case ItemPositionLeft:
-        // The alignment axis (column axis) and the inline axis are parallell in
-        // orthogonal writing mode. Otherwise this this is equivalent to 'start'.
-        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
+        // Aligns the alignment subject to be flush with the alignment container's 'line-left' edge.
+        // The alignment axis (column axis) is always orthogonal to the inline axis, hence this value behaves as 'start'.
         return GridAxisStart;
     case ItemPositionRight:
-        // The alignment axis (column axis) and the inline axis are parallell in
-        // orthogonal writing mode. Otherwise this this is equivalent to 'start'.
-        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
-        return isOrthogonalChild(child) ? GridAxisEnd : GridAxisStart;
+        // Aligns the alignment subject to be flush with the alignment container's 'line-right' edge.
+        // The alignment axis (column axis) is always orthogonal to the inline axis, hence this value behaves as 'start'.
+        return GridAxisStart;
     case ItemPositionCenter:
         return GridAxisCenter;
     case ItemPositionFlexStart: // Only used in flex layout, otherwise equivalent to 'start'.
+        // Aligns the alignment subject to be flush with the alignment container's 'start' edge (block-start) in the column axis.
     case ItemPositionStart:
         return GridAxisStart;
     case ItemPositionFlexEnd: // Only used in flex layout, otherwise equivalent to 'end'.
+        // Aligns the alignment subject to be flush with the alignment container's 'end' edge (block-end) in the column axis.
     case ItemPositionEnd:
         return GridAxisEnd;
     case ItemPositionStretch:
@@ -2311,28 +2328,51 @@ GridAxisPosition RenderGrid::columnAxisPositionForChild(const RenderBox& child)
 GridAxisPosition RenderGrid::rowAxisPositionForChild(const RenderBox& child) const
 {
     bool hasSameDirection = child.style().direction() == style().direction();
-    bool isLTR = style().isLeftToRightDirection();
+    bool gridIsLTR = style().isLeftToRightDirection();
 
     switch (child.style().resolvedJustifySelf(style(), selfAlignmentNormalBehavior).position()) {
     case ItemPositionSelfStart:
-        // For orthogonal writing-modes, this computes to 'start'
-        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
-        // self-start is based on the child's direction. That's why we need to check against the grid container's direction.
-        return (isOrthogonalChild(child) || hasSameDirection) ? GridAxisStart : GridAxisEnd;
+        // FIXME: Should we implement this logic in a generic utility function ?
+        // Aligns the alignment subject to be flush with the edge of the alignment container
+        // corresponding to the alignment subject's 'start' side in the row axis.
+        if (isOrthogonalChild(child)) {
+            // If orthogonal writing-modes, self-start will be based on the child's block-axis
+            // direction, because it's the one parallel to the row axis.
+            if (child.style().isFlippedBlocksWritingMode())
+                return gridIsLTR ? GridAxisEnd : GridAxisStart;
+            return gridIsLTR ? GridAxisStart : GridAxisEnd;
+        }
+        // self-start is based on the child's inline-flow direction. That's why we need to check against the grid container's direction.
+        return hasSameDirection ? GridAxisStart : GridAxisEnd;
     case ItemPositionSelfEnd:
-        // For orthogonal writing-modes, this computes to 'start'
-        // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
-        return (isOrthogonalChild(child) || hasSameDirection) ? GridAxisEnd : GridAxisStart;
+        // FIXME: Should we implement this logic in a generic utility function ?
+        // Aligns the alignment subject to be flush with the edge of the alignment container
+        // corresponding to the alignment subject's 'end' side in the row axis.
+        if (isOrthogonalChild(child)) {
+            // If orthogonal writing-modes, self-end will be based on the child's block-axis
+            // direction, because it's the one parallel to the row axis.
+            if (child.style().isFlippedBlocksWritingMode())
+                return gridIsLTR ? GridAxisStart : GridAxisEnd;
+            return gridIsLTR ? GridAxisEnd : GridAxisStart;
+        }
+        // self-end is based on the child's inline-flow direction. That's why we need to check against the grid container's direction.
+        return hasSameDirection ? GridAxisEnd : GridAxisStart;
     case ItemPositionLeft:
-        return isLTR ? GridAxisStart : GridAxisEnd;
+        // Aligns the alignment subject to be flush with the alignment container's 'line-left' edge.
+        // We want the physical 'left' side, so we have to take account, container's inline-flow direction.
+        return gridIsLTR ? GridAxisStart : GridAxisEnd;
     case ItemPositionRight:
-        return isLTR ? GridAxisEnd : GridAxisStart;
+        // Aligns the alignment subject to be flush with the alignment container's 'line-right' edge.
+        // We want the physical 'right' side, so we have to take account, container's inline-flow direction.
+        return gridIsLTR ? GridAxisEnd : GridAxisStart;
     case ItemPositionCenter:
         return GridAxisCenter;
     case ItemPositionFlexStart: // Only used in flex layout, otherwise equivalent to 'start'.
+        // Aligns the alignment subject to be flush with the alignment container's 'start' edge (inline-start) in the row axis.
     case ItemPositionStart:
         return GridAxisStart;
     case ItemPositionFlexEnd: // Only used in flex layout, otherwise equivalent to 'end'.
+        // Aligns the alignment subject to be flush with the alignment container's 'end' edge (inline-end) in the row axis.
     case ItemPositionEnd:
         return GridAxisEnd;
     case ItemPositionStretch:
@@ -2371,9 +2411,9 @@ LayoutUnit RenderGrid::columnAxisOffsetForChild(const RenderBox& child) const
         // (this does not have to be done for the last track as there are no more m_rowPositions after it).
         if (childEndLine < m_rowPositions.size() - 1)
             endOfRow -= gridGapForDirection(ForRows) + m_offsetBetweenRows;
-        LayoutUnit childBreadth = child.logicalHeight() + child.marginLogicalHeight();
+        LayoutUnit columnAxisChildSize = isOrthogonalChild(child) ? child.logicalWidth() + child.marginLogicalWidth() : child.logicalHeight() + child.marginLogicalHeight();
         auto overflow = child.style().resolvedAlignSelf(style(), selfAlignmentNormalBehavior).overflow();
-        LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(overflow, endOfRow - startOfRow, childBreadth);
+        LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(overflow, endOfRow - startOfRow, columnAxisChildSize);
         return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPosition : offsetFromStartPosition / 2);
     }
     }
@@ -2404,9 +2444,9 @@ LayoutUnit RenderGrid::rowAxisOffsetForChild(const RenderBox& child) const
         // (this does not have to be done for the last track as there are no more m_columnPositions after it).
         if (childEndLine < m_columnPositions.size() - 1)
             endOfColumn -= gridGapForDirection(ForColumns) + m_offsetBetweenColumns;
-        LayoutUnit childBreadth = child.logicalWidth() + child.marginLogicalWidth();
+        LayoutUnit rowAxisChildSize = isOrthogonalChild(child) ? child.logicalHeight() + child.marginLogicalHeight() : child.logicalWidth() + child.marginLogicalWidth();
         auto overflow = child.style().resolvedJustifySelf(style(), selfAlignmentNormalBehavior).overflow();
-        LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(overflow, endOfColumn - startOfColumn, childBreadth);
+        LayoutUnit offsetFromStartPosition = computeOverflowAlignmentOffset(overflow, endOfColumn - startOfColumn, rowAxisChildSize);
         return startPosition + (axisPosition == GridAxisEnd ? offsetFromStartPosition : offsetFromStartPosition / 2);
     }
     }
@@ -2532,7 +2572,7 @@ LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox& child) const
     // We stored m_columnPositions's data ignoring the direction, hence we might need now
     // to translate positions from RTL to LTR, as it's more convenient for painting.
     if (!style().isLeftToRightDirection())
-        rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - child.logicalWidth();
+        rowAxisOffset = translateRTLCoordinate(rowAxisOffset) - (isOrthogonalChild(child) ? child.logicalHeight()  : child.logicalWidth());
 
     // "In the positioning phase [...] calculations are performed according to the writing mode
     // of the containing block of the box establishing the orthogonal flow." However, the