[CSS Grid Layout] Support for the justify-self and justify-items in grid layout
authorjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Apr 2015 17:24:44 +0000 (17:24 +0000)
committerjfernandez@igalia.com <jfernandez@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Apr 2015 17:24:44 +0000 (17:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=133280

Source/WebCore:

Reviewed by David Hyatt.

Implementation of justify-self and justify-items properties for grid. It supports
different writing-modes and direction. Margins, borders and paddings are also
considered when computing the final position and stretched size.

This patch applies also a quite important refactoring of the alignment logic in
order to share code between the two alignment dimensions, row-axis and column-axis.

Overflow handling is still missing and will be added later in a follow-up bug.

Tests: fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html
       fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html
       fast/css-grid-layout/grid-align-justify-margin-border-padding.html
       fast/css-grid-layout/justify-self-cell.html

* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutGridItems):
(WebCore::RenderGrid::columnAxisPositionForChild):
(WebCore::RenderGrid::rowAxisPositionForChild):
(WebCore::RenderGrid::rowPositionForChild):
(WebCore::RenderGrid::columnPositionForChild):
(WebCore::RenderGrid::findChildLogicalPosition):
(WebCore::RenderGrid::allowedToStretchLogicalHeightForChild): Deleted.
(WebCore::RenderGrid::needToStretchChildLogicalHeight): Deleted.
(WebCore::RenderGrid::marginLogicalHeightForChild): Deleted.
(WebCore::RenderGrid::availableAlignmentSpaceForChildBeforeStretching): Deleted.
(WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded): Deleted.
* rendering/RenderGrid.h:
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::resolveJustification):
* rendering/style/RenderStyle.h:

LayoutTests:

Implementation of justify-self and justify-items properties for grid.
Added additional testing for ensuring margin, padding and border are considered when
computing grid item's position.

Reviewed by David Hyatt.

* fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt: Added.
* fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt: Added.
* fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html: Added.
* fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt: Added.
* fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html: Added.
* fast/css-grid-layout/grid-align-justify-margin-border-padding.html: Added.
* fast/css-grid-layout/justify-self-cell-expected.txt: Added.
* fast/css-grid-layout/justify-self-cell.html: Added.
* fast/css-grid-layout/resources/grid.css:
(.directionLTR): Added. Useful for defining orthogonal flows.

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

15 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/justify-self-cell-expected.txt [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/justify-self-cell.html [new file with mode: 0644]
LayoutTests/fast/css-grid-layout/resources/grid.css
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/RenderGrid.h
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h

index 7c679d7..38c99af 100644 (file)
@@ -1,3 +1,25 @@
+2015-04-27  Javier Fernandez  <jfernandez@igalia.com>
+
+        [CSS Grid Layout] Support for the justify-self and justify-items in grid layout
+        https://bugs.webkit.org/show_bug.cgi?id=133280
+
+        Implementation of justify-self and justify-items properties for grid.
+        Added additional testing for ensuring margin, padding and border are considered when
+        computing grid item's position.
+
+        Reviewed by David Hyatt.
+
+        * fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt: Added.
+        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt: Added.
+        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html: Added.
+        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt: Added.
+        * fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html: Added.
+        * fast/css-grid-layout/grid-align-justify-margin-border-padding.html: Added.
+        * fast/css-grid-layout/justify-self-cell-expected.txt: Added.
+        * fast/css-grid-layout/justify-self-cell.html: Added.
+        * fast/css-grid-layout/resources/grid.css:
+        (.directionLTR): Added. Useful for defining orthogonal flows.
+
 2015-04-27  Youenn Fablet  <youenn.fablet@crf.canon.fr> and Xabier Rodriguez Calvar  <calvaris@igalia.com>
 
         Unreviewed.
diff --git a/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt b/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-expected.txt
new file mode 100644 (file)
index 0000000..cd3e44f
--- /dev/null
@@ -0,0 +1,74 @@
+This test checks that the 'margin', 'border' and 'padding' properties are applied together correctly for 'align' and 'justify' properties.
+
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'auto' | justify-items: 'auto'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'center' | justify-items: 'center'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'end' | justify-items: 'end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'left' | justify-items: 'left'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'right' | justify-items: 'right'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (ortho) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (ortho) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (parall) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR - (parall) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'auto' | justify-items: 'auto'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'center' | justify-items: 'center'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'end' | justify-items: 'end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'left' | justify-items: 'left'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'right' | justify-items: 'right'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (ortho) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (ortho) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (parall) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (parall) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt b/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr-expected.txt
new file mode 100644 (file)
index 0000000..3ef9b59
--- /dev/null
@@ -0,0 +1,74 @@
+This test checks that the 'margin', 'border' and 'padding' properties are applied together correctly for 'align' and 'justify' properties on vertical-LR grids.
+
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'auto' | justify-items: 'auto'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'center' | justify-items: 'center'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'end' | justify-items: 'end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'left' | justify-items: 'left'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'right' | justify-items: 'right'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (ortho) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (ortho) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (parall) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (parall) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'auto' | justify-items: 'auto'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'center' | justify-items: 'center'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'end' | justify-items: 'end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'left' | justify-items: 'left'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'right' | justify-items: 'right'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (ortho) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (ortho) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (parall) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (parall) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html b/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html
new file mode 100644 (file)
index 0000000..6c0afce
--- /dev/null
@@ -0,0 +1,269 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link href="resources/grid.css" rel="stylesheet">
+<script src="../../resources/check-layout.js"></script>
+<style>
+body {
+    margin: 0;
+}
+
+.grid {
+    -webkit-grid-template-columns: 100px 200px;
+    -webkit-grid-template-rows: 200px 200px;
+    padding: 10px 15px 20px 30px;
+    border-width: 5px 10px 15px 20px;
+    border-style: dotted;
+    border-color: blue;
+    width: -webkit-fit-content;
+    position: relative;
+}
+
+.cell {
+    width: 20px;
+    height: 40px;
+    margin: 4px 8px 12px 16px;
+}
+
+.itemsCenter {
+    align-items: center;
+    justify-items: center;
+}
+
+.itemsEnd {
+    align-items: end;
+    justify-items: end;
+}
+
+.itemsLeft {
+    align-items: left;
+    justify-items: left;
+}
+
+.itemsRight {
+    align-items: right;
+    justify-items: right;
+}
+
+.itemsSelfStart {
+    align-items: self-start;
+    justify-items: self-start;
+}
+
+.itemsSelfEnd {
+    align-items: self-end;
+    justify-items: self-end;
+}
+
+.stretch {
+    align-self: stretch;
+    justify-self: stretch;
+}
+
+</style>
+</head>
+<body onload="checkLayout('.grid')">
+
+<p>This test checks that the 'margin', 'border' and 'padding' properties are applied together correctly for 'align' and 'justify' properties on vertical-LR grids.</p>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'auto' | justify-items: 'auto'</p>
+    <div class="grid verticalLR" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"   data-offset-x="46"  data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell firstRowSecondColumn"  data-offset-x="46"  data-offset-y="114" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowFirstColumn"  data-offset-x="246" data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowSecondColumn" data-offset-x="246" data-offset-y="114" data-expected-width="20" data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'center' | justify-items: 'center'</p>
+    <div class="grid verticalLR itemsCenter" data-expected-width="475" data-expected-height="350">
+        <div class="firstRowFirstColumn cell"     data-offset-x="124"  data-offset-y="36"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"   data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="324"  data-offset-y="186" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'end' | justify-items: 'end'</p>
+    <div class="grid verticalLR itemsEnd" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="202" data-offset-y="58" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="402" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'left' | justify-items: 'left'</p>
+    <div class="grid verticalLR itemsLeft" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="114" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'right' | justify-items: 'right'</p>
+    <div class="grid verticalLR itemsRight" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="58" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (ortho) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionLTR verticalLR itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="58" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (ortho) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionLTR verticalLR itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="202" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="402" data-offset-y="114" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (parall) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionLTR verticalLR itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="14" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="114" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (parall) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionLTR verticalLR itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="202" data-offset-y="58"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="402" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<!-- RTL direction. -->
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'auto' | justify-items: 'auto'</p>
+    <div class="grid verticalLR directionRTL" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"   data-offset-x="46"  data-offset-y="258" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell firstRowSecondColumn"  data-offset-x="46"  data-offset-y="158" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowFirstColumn"  data-offset-x="246" data-offset-y="258" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowSecondColumn" data-offset-x="246" data-offset-y="158" data-expected-width="20" data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'center' | justify-items: 'center'</p>
+    <div class="grid verticalLR directionRTL itemsCenter" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="124" data-offset-y="236" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="324" data-offset-y="86" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'end' | justify-items: 'end'</p>
+    <div class="grid verticalLR directionRTL itemsEnd"       data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="202" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="402" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'left' | justify-items: 'left'</p>
+    <div class="grid verticalLR directionRTL itemsLeft"      data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'right' | justify-items: 'right'</p>
+    <div class="grid verticalLR directionRTL itemsRight"     data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (ortho) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid verticalLR directionRTL itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (ortho) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid verticalLR directionRTL itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="202" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="402" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (parall) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid verticalLR directionRTL itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="246" data-offset-y="158"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (parall) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid verticalLR directionRTL itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="202" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="402" data-offset-y="14" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt b/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl-expected.txt
new file mode 100644 (file)
index 0000000..565e92c
--- /dev/null
@@ -0,0 +1,74 @@
+This test checks that the 'margin', 'border' and 'padding' properties are applied together correctly for 'align' and 'justify' properties on vertical-RL grids.
+
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'auto' | justify-items: 'auto'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'center' | justify-items: 'center'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'end' | justify-items: 'end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'left' | justify-items: 'left'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR | align-items: 'right' | justify-items: 'right'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (ortho) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (ortho) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (parall) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: LTR (parall) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'auto' | justify-items: 'auto'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'center' | justify-items: 'center'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'end' | justify-items: 'end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'left' | justify-items: 'left'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL | align-items: 'right' | justify-items: 'right'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (ortho) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (ortho) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (parall) | align-items: 'self-start' | justify-items: 'self-start'
+
+PASS
+border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px
+direction: RTL (parall) | align-items: 'self-end' | justify-items: 'self-end'
+
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html b/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html
new file mode 100644 (file)
index 0000000..b2c2f6e
--- /dev/null
@@ -0,0 +1,270 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link href="resources/grid.css" rel="stylesheet">
+<script src="../../resources/check-layout.js"></script>
+<style>
+body {
+    margin: 0;
+}
+
+.grid {
+    -webkit-grid-template-columns: 100px 200px;
+    -webkit-grid-template-rows: 200px 200px;
+    padding: 10px 15px 20px 30px;
+    border-width: 5px 10px 15px 20px;
+    border-style: dotted;
+    border-color: blue;
+    width: -webkit-fit-content;
+    position: relative;
+}
+
+.cell {
+    width: 20px;
+    height: 40px;
+    margin: 4px 8px 12px 16px;
+}
+
+.itemsCenter {
+    align-items: center;
+    justify-items: center;
+}
+
+.itemsEnd {
+    align-items: end;
+    justify-items: end;
+}
+
+.itemsLeft {
+    align-items: left;
+    justify-items: left;
+}
+
+.itemsRight {
+    align-items: right;
+    justify-items: right;
+}
+
+.itemsSelfStart {
+    align-items: self-start;
+    justify-items: self-start;
+}
+
+.itemsSelfEnd {
+    align-items: self-end;
+    justify-items: self-end;
+}
+
+.stretch {
+    align-self: stretch;
+    justify-self: stretch;
+}
+
+</style>
+</head>
+<body onload="checkLayout('.grid')">
+
+<p>This test checks that the 'margin', 'border' and 'padding' properties are applied together correctly for 'align' and 'justify' properties on vertical-RL grids.</p>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'auto' | justify-items: 'auto'</p>
+    <div class="grid verticalRL" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"   data-offset-x="402" data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell firstRowSecondColumn"  data-offset-x="402" data-offset-y="114" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowFirstColumn"  data-offset-x="202" data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowSecondColumn" data-offset-x="202" data-offset-y="114" data-expected-width="20" data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'center' | justify-items: 'center'</p>
+    <div class="grid verticalRL itemsCenter" data-expected-width="475" data-expected-height="350">
+        <div class="firstRowFirstColumn cell"     data-offset-x="324" data-offset-y="36"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="124" data-offset-y="186" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'end' | justify-items: 'end'</p>
+    <div class="grid verticalRL itemsEnd" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="58" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'left' | justify-items: 'left'</p>
+    <div class="grid verticalRL itemsLeft" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="114" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'right' | justify-items: 'right'</p>
+    <div class="grid verticalRL itemsRight" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="58" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (ortho) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionLTR verticalRL itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="58" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (ortho) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionLTR verticalRL itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="114" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (parall) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionLTR verticalRL itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="14" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="114" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (parall) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionLTR verticalRL itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="58"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="110" data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+
+<!-- RTL direction. -->
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'auto' | justify-items: 'auto'</p>
+    <div class="grid verticalRL directionRTL" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"   data-offset-x="402" data-offset-y="258" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell firstRowSecondColumn"  data-offset-x="402" data-offset-y="158" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowFirstColumn"  data-offset-x="202" data-offset-y="258" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowSecondColumn" data-offset-x="202" data-offset-y="158" data-expected-width="20" data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'center' | justify-items: 'center'</p>
+    <div class="grid verticalRL directionRTL itemsCenter" data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="324" data-offset-y="236" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="124" data-offset-y="86" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'end' | justify-items: 'end'</p>
+    <div class="grid verticalRL directionRTL itemsEnd"       data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'left' | justify-items: 'left'</p>
+    <div class="grid verticalRL directionRTL itemsLeft"      data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'right' | justify-items: 'right'</p>
+    <div class="grid verticalRL directionRTL itemsRight"     data-expected-width="475" data-expected-height="350">
+        <div class="cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (ortho) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid verticalRL directionRTL itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (ortho) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid verticalRL directionRTL itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (parall) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid verticalRL directionRTL itemsSelfStart" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="402" data-offset-y="258" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="158"  data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (parall) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid verticalRL directionRTL itemsSelfEnd" data-expected-width="475" data-expected-height="350">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="230" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="200" data-expected-height="100"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="14" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding.html b/LayoutTests/fast/css-grid-layout/grid-align-justify-margin-border-padding.html
new file mode 100644 (file)
index 0000000..0aba8ad
--- /dev/null
@@ -0,0 +1,269 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link href="resources/grid.css" rel="stylesheet">
+<script src="../../resources/check-layout.js"></script>
+<style>
+body {
+    margin: 0;
+}
+
+.grid {
+    -webkit-grid-template-columns: 100px 200px;
+    -webkit-grid-template-rows: 200px 200px;
+    padding: 10px 15px 20px 30px;
+    border-width: 5px 10px 15px 20px;
+    border-style: dotted;
+    border-color: blue;
+    width: -webkit-fit-content;
+    position: relative;
+}
+
+.cell {
+    width: 20px;
+    height: 40px;
+    margin: 4px 8px 12px 16px;
+}
+
+.itemsCenter {
+    align-items: center;
+    justify-items: center;
+}
+
+.itemsEnd {
+    align-items: end;
+    justify-items: end;
+}
+
+.itemsLeft {
+    align-items: left;
+    justify-items: left;
+}
+
+.itemsRight {
+    align-items: right;
+    justify-items: right;
+}
+
+.itemsSelfStart {
+    align-items: self-start;
+    justify-items: self-start;
+}
+
+.itemsSelfEnd {
+    align-items: self-end;
+    justify-items: self-end;
+}
+
+.stretch {
+    align-self: stretch;
+    justify-self: stretch;
+}
+
+</style>
+</head>
+<body onload="checkLayout('.grid')">
+
+<p>This test checks that the 'margin', 'border' and 'padding' properties are applied together correctly for 'align' and 'justify' properties.</p>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'auto' | justify-items: 'auto'</p>
+    <div class="grid" data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"   data-offset-x="46"  data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell firstRowSecondColumn"  data-offset-x="146" data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowFirstColumn"  data-offset-x="46"  data-offset-y="214" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowSecondColumn" data-offset-x="146" data-offset-y="214" data-expected-width="20" data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'center' | justify-items: 'center'</p>
+    <div class="grid itemsCenter" data-expected-width="375" data-expected-height="450">
+        <div class="firstRowFirstColumn cell"     data-offset-x="74"  data-offset-y="86" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="224" data-offset-y="286" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'end' | justify-items: 'end'</p>
+    <div class="grid itemsEnd" data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="102" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="302" data-offset-y="358" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'left' | justify-items: 'left'</p>
+    <div class="grid itemsLeft" data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="146" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR | align-items: 'right' | justify-items: 'right'</p>
+    <div class="grid itemsRight" data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="102" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="302" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (ortho) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionLTR itemsSelfStart" data-expected-width="375" data-expected-height="450">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="102" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="302" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (ortho) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionLTR itemsSelfEnd" data-expected-width="375" data-expected-height="450">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="46"  data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="146" data-offset-y="358" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR (parall) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionLTR itemsSelfStart" data-expected-width="375" data-expected-height="450">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="46" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="146" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: LTR - (parall) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionLTR itemsSelfEnd" data-expected-width="375" data-expected-height="450">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="102"  data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="130" data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="30"  data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="302" data-offset-y="358" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<!-- RTL direction. -->
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'auto' | justify-items: 'auto'</p>
+    <div class="grid directionRTL" data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"   data-offset-x="302" data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell firstRowSecondColumn"  data-offset-x="202" data-offset-y="14"  data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowFirstColumn"  data-offset-x="302" data-offset-y="214" data-expected-width="20" data-expected-height="40"></div>
+        <div class="cell secondRowSecondColumn" data-offset-x="202" data-offset-y="214" data-expected-width="20" data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'center' | justify-items: 'center'</p>
+    <div class="grid directionRTL itemsCenter" data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="274" data-offset-y="86" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="124" data-offset-y="286" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'end' | justify-items: 'end'</p>
+    <div class="grid directionRTL itemsEnd"       data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="358" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'left' | justify-items: 'left'</p>
+    <div class="grid directionRTL itemsLeft"      data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL | align-items: 'right' | justify-items: 'right'</p>
+    <div class="grid directionRTL itemsRight"     data-expected-width="375" data-expected-height="450">
+        <div class="cell firstRowFirstColumn"     data-offset-x="302" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (ortho) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionRTL itemsSelfStart" data-expected-width="375" data-expected-height="450">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="46"  data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (ortho) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionRTL itemsSelfEnd" data-expected-width="375" data-expected-height="450">
+        <div class="directionLTR cell firstRowFirstColumn"     data-offset-x="302" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionLTR stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionLTR stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionLTR cell secondRowSecondColumn"   data-offset-x="202" data-offset-y="358" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (parall) | align-items: 'self-start' | justify-items: 'self-start'</p>
+    <div class="grid directionRTL itemsSelfStart" data-expected-width="375" data-expected-height="450">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="302" data-offset-y="14"  data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="202"  data-offset-y="214" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+<div>
+    <p>border: 5px 10px 15px 20px | padding: 10px 15px 20px 30px | margin: 4px 8px 12px 16px<br>
+        direction: RTL (parall) | align-items: 'self-end' | justify-items: 'self-end'</p>
+    <div class="grid directionRTL itemsSelfEnd" data-expected-width="375" data-expected-height="450">
+        <div class="directionRTL cell firstRowFirstColumn"     data-offset-x="246" data-offset-y="158" data-expected-width="20"  data-expected-height="40"></div>
+        <div class="directionRTL stretch firstRowSecondColumn" data-offset-x="30"  data-offset-y="10"  data-expected-width="200" data-expected-height="200"></div>
+        <div class="directionRTL stretch secondRowFirstColumn" data-offset-x="230" data-offset-y="210" data-expected-width="100" data-expected-height="200"></div>
+        <div class="directionRTL cell secondRowSecondColumn"   data-offset-x="46" data-offset-y="358" data-expected-width="20"  data-expected-height="40"></div>
+    </div>
+</div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/css-grid-layout/justify-self-cell-expected.txt b/LayoutTests/fast/css-grid-layout/justify-self-cell-expected.txt
new file mode 100644 (file)
index 0000000..55581a2
--- /dev/null
@@ -0,0 +1,12 @@
+This test checks that the justify-self property is applied correctly.
+
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
diff --git a/LayoutTests/fast/css-grid-layout/justify-self-cell.html b/LayoutTests/fast/css-grid-layout/justify-self-cell.html
new file mode 100644 (file)
index 0000000..1c6aa5e
--- /dev/null
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html>
+<link href="resources/grid.css" rel="stylesheet">
+<style>
+.grid {
+    -webkit-grid-template-columns: 100px 100px;
+    -webkit-grid-template-rows: 200px 200px;
+    width: -webkit-fit-content;
+}
+
+.cell {
+    width: 10px;
+    height: 20px;
+}
+
+.justifySelfAuto {
+    justify-self: auto;
+}
+
+.justifySelfStretch {
+    justify-self: stretch;
+}
+
+.justifySelfStart {
+    justify-self: start;
+}
+
+.justifySelfEnd {
+    justify-self: end;
+}
+
+.justifySelfCenter {
+    justify-self: center;
+}
+
+.justifySelfRight {
+    justify-self: right;
+}
+
+.justifySelfLeft {
+    justify-self: left;
+}
+
+.justifySelfFlexStart {
+    justify-self: flex-start;
+}
+
+.justifySelfFlexEnd {
+    justify-self: flex-end;
+}
+
+.justifySelfSelfStart {
+    justify-self: self-start;
+}
+
+.justifySelfSelfEnd {
+    justify-self: self-end;
+}
+
+.justifyItemsCenter {
+    justify-items: center;
+}
+</style>
+<script src="../../resources/check-layout.js"></script>
+<body onload="checkLayout('.grid')">
+
+<p>This test checks that the justify-self property is applied correctly.</p>
+
+<div style="position: relative" class="constrainedContainer">
+<div class="grid" data-expected-width="200" data-expected-height="400">
+    <div class="justifySelfStretch firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
+    <div class="cell justifySelfStart firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfEnd firstRowSecondColumn" data-offset-x="190" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfCenter secondRowFirstColumn" data-offset-x="45" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfRight secondRowSecondColumn" data-offset-x="190" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfLeft secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+</div>
+
+<div style="position: relative" class="constrainedContainer">
+<div class="grid" data-expected-width="200" data-expected-height="400">
+    <div class="cell justifySelfFlexEnd firstRowFirstColumn" data-offset-x="90" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfFlexStart firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfStart secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfEnd secondRowSecondColumn" data-offset-x="190" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+</div>
+</div>
+
+<!-- Default justification and initial values. -->
+<div style="position: relative">
+    <div class="grid justifyItemsCenter" data-expected-width="200" data-expected-height="400">
+        <div class="cell justifySelfAuto firstRowFirstColumn" data-offset-x="45" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+        <div class="cell firstRowSecondColumn" data-offset-x="145" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+        <div class="cell justifySelfSelfStart secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+        <div class="cell justifySelfSelfEnd secondRowSecondColumn" data-offset-x="190" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    </div>
+</div>
+
+<div style="position: relative">
+    <div class="grid" data-expected-width="200" data-expected-height="400">
+        <div class="justifySelfAuto firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
+        <div class="cell firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+        <div class="cell justifySelfStart secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+        <div class="cell justifySelfEnd secondRowSecondColumn" data-offset-x="190" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    </div>
+</div>
+
+<!-- Vertical writing mode. -->
+<div style="position: relative" class="constrainedContainer">
+<div class="grid verticalRL" data-expected-width="400" data-expected-height="200">
+    <div class="justifySelfStretch firstRowFirstColumn" data-offset-x="200" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
+    <div class="cell justifySelfStart firstRowSecondColumn" data-offset-x="390" data-offset-y="100" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfEnd firstRowSecondColumn" data-offset-x="390" data-offset-y="180" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfCenter secondRowFirstColumn" data-offset-x="190" data-offset-y="40" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfRight secondRowSecondColumn" data-offset-x="190" data-offset-y="180" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfLeft secondRowSecondColumn" data-offset-x="190" data-offset-y="100" data-expected-width="10" data-expected-height="20"></div>
+</div>
+
+<div style="position: relative" class="constrainedContainer">
+<div class="grid verticalLR" data-expected-width="400" data-expected-height="200">
+    <div class="cell justifySelfFlexEnd firstRowFirstColumn" data-offset-x="0" data-offset-y="80" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfFlexStart firstRowSecondColumn" data-offset-x="0" data-offset-y="100" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfStart secondRowFirstColumn" data-offset-x="200" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfEnd secondRowSecondColumn" data-offset-x="200" data-offset-y="180" data-expected-width="10" data-expected-height="20"></div>
+</div>
+</div>
+
+<!-- RTL direction. -->
+<div style="position: relative" class="constrainedContainer">
+<div class="grid directionRTL" data-expected-width="200" data-expected-height="400">
+    <div class="justifySelfStretch firstRowFirstColumn" data-offset-x="100" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
+    <div class="cell justifySelfStart firstRowSecondColumn" data-offset-x="90" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfEnd firstRowSecondColumn" data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfCenter secondRowFirstColumn" data-offset-x="145" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfRight secondRowSecondColumn" data-offset-x="90" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfLeft secondRowSecondColumn" data-offset-x="0" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+</div>
+
+<div style="position: relative" class="constrainedContainer">
+<div class="grid directionRTL" data-expected-width="200" data-expected-height="400">
+    <div class="cell justifySelfFlexEnd firstRowFirstColumn" data-offset-x="100" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfFlexStart firstRowSecondColumn" data-offset-x="90" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfStart secondRowFirstColumn" data-offset-x="190" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfEnd secondRowSecondColumn" data-offset-x="0" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+</div>
+</div>
+
+<!-- RTL direction with opposite directions grid container vs grid item. -->
+<div style="position: relative" class="constrainedContainer">
+<div class="grid" data-expected-width="200" data-expected-height="400">
+    <div class="justifySelfStretch firstRowFirstColumn directionRTL" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
+    <div class="cell justifySelfStart firstRowSecondColumn directionRTL" data-offset-x="100" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfEnd firstRowSecondColumn directionRTL" data-offset-x="190" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfCenter secondRowFirstColumn directionRTL" data-offset-x="45" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfRight secondRowSecondColumn directionRTL" data-offset-x="190" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfLeft secondRowSecondColumn directionRTL" data-offset-x="100" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+</div>
+
+<div style="position: relative" class="constrainedContainer">
+<div class="grid" data-expected-width="200" data-expected-height="400">
+    <div class="cell justifySelfFlexEnd firstRowFirstColumn directionRTL" data-offset-x="90" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfFlexStart firstRowSecondColumn directionRTL" data-offset-x="100" data-offset-y="0" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfStart secondRowFirstColumn directionRTL" data-offset-x="90" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+    <div class="cell justifySelfSelfEnd secondRowSecondColumn directionRTL" data-offset-x="100" data-offset-y="200" data-expected-width="10" data-expected-height="20"></div>
+</div>
+</div>
+
+</body>
+</html>
index 169a0c5..20e10bc 100644 (file)
 .directionRTL {
     direction: rtl;
 }
+
+.directionLTR {
+    direction: ltr;
+}
index 3bc3d55..7b8595a 100644 (file)
@@ -1,3 +1,41 @@
+2015-04-27  Javier Fernandez  <jfernandez@igalia.com>
+
+        [CSS Grid Layout] Support for the justify-self and justify-items in grid layout
+        https://bugs.webkit.org/show_bug.cgi?id=133280
+
+        Reviewed by David Hyatt.
+
+        Implementation of justify-self and justify-items properties for grid. It supports
+        different writing-modes and direction. Margins, borders and paddings are also
+        considered when computing the final position and stretched size.
+
+        This patch applies also a quite important refactoring of the alignment logic in
+        order to share code between the two alignment dimensions, row-axis and column-axis.
+
+        Overflow handling is still missing and will be added later in a follow-up bug.
+
+        Tests: fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-lr.html
+               fast/css-grid-layout/grid-align-justify-margin-border-padding-vertical-rl.html
+               fast/css-grid-layout/grid-align-justify-margin-border-padding.html
+               fast/css-grid-layout/justify-self-cell.html
+
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::layoutGridItems):
+        (WebCore::RenderGrid::columnAxisPositionForChild):
+        (WebCore::RenderGrid::rowAxisPositionForChild):
+        (WebCore::RenderGrid::rowPositionForChild):
+        (WebCore::RenderGrid::columnPositionForChild):
+        (WebCore::RenderGrid::findChildLogicalPosition):
+        (WebCore::RenderGrid::allowedToStretchLogicalHeightForChild): Deleted.
+        (WebCore::RenderGrid::needToStretchChildLogicalHeight): Deleted.
+        (WebCore::RenderGrid::marginLogicalHeightForChild): Deleted.
+        (WebCore::RenderGrid::availableAlignmentSpaceForChildBeforeStretching): Deleted.
+        (WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded): Deleted.
+        * rendering/RenderGrid.h:
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::resolveJustification):
+        * rendering/style/RenderStyle.h:
+
 2015-04-27  Darin Adler  <darin@apple.com>
 
         Crashes under IDBDatabase::closeConnection
index 4810e7c..6733cb8 100644 (file)
@@ -40,8 +40,6 @@ namespace WebCore {
 
 static const int infinity = -1;
 
-enum GridAxisPosition {GridAxisStart, GridAxisEnd, GridAxisCenter};
-
 class GridTrack {
 public:
     GridTrack() {}
@@ -1186,7 +1184,7 @@ void RenderGrid::layoutGridItems()
 
         child->layoutIfNeeded();
 
-        child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
+        child->setLogicalLocation(findChildLogicalPosition(*child));
 
         // If the child moved, we have to repaint it as well as any floating/positioned
         // descendants. An exception is if we need a layout. In this case, we know we're going to
@@ -1240,42 +1238,6 @@ void RenderGrid::populateGridPositions(const GridSizingData& sizingData)
         m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].baseSize();
 }
 
-LayoutUnit RenderGrid::endOfRowForChild(const RenderBox& child) const
-{
-    const GridCoordinate& coordinate = cachedGridCoordinate(child);
-
-    LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
-    // The grid items should be inside the grid container's border box, that's why they need to be shifted.
-    LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child);
-
-    LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.next().toInt()];
-    // FIXME: This should account for the grid item's <overflow-position>.
-    return rowPosition + std::max<LayoutUnit>(0, endOfRow - startOfRow - child.logicalHeight());
-}
-
-LayoutUnit RenderGrid::startOfRowForChild(const RenderBox& child) const
-{
-    const GridCoordinate& coordinate = cachedGridCoordinate(child);
-
-    LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
-    // The grid items should be inside the grid container's border box, that's why they need to be shifted.
-    // FIXME: This should account for the grid item's <overflow-position>.
-    LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child);
-
-    return rowPosition;
-}
-
-LayoutUnit RenderGrid::centeredRowPositionForChild(const RenderBox& child) const
-{
-    const GridCoordinate& coordinate = cachedGridCoordinate(child);
-
-    // The grid items should be inside the grid container's border box, that's why they need to be shifted.
-    LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
-    LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.next().toInt()];
-    // FIXME: This should account for the grid item's <overflow-position>.
-    return startOfRow + std::max<LayoutUnit>(0, endOfRow - startOfRow - child.logicalHeight()) / 2;
-}
-
 bool RenderGrid::allowedToStretchLogicalHeightForChild(const RenderBox& child) const
 {
     return child.style().logicalHeight().isAuto() && !child.style().marginBeforeUsing(&style()).isAuto() && !child.style().marginAfterUsing(&style()).isAuto();
@@ -1327,9 +1289,12 @@ void RenderGrid::applyStretchAlignmentToChildIfNeeded(RenderBox& child, LayoutUn
     }
 }
 
-static GridAxisPosition columnAxisPosition(ItemPosition position, bool hasOrthogonalWritingMode, bool hasSameWritingMode)
+GridAxisPosition RenderGrid::columnAxisPositionForChild(const RenderBox& child) const
 {
-    switch (position) {
+    bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
+    bool hasSameWritingMode = child.style().writingMode() == style().writingMode();
+
+    switch (RenderStyle::resolveAlignment(style(), child.style(), ItemPositionStretch)) {
     case ItemPositionSelfStart:
         // If orthogonal writing-modes, this computes to 'start'.
         // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
@@ -1362,7 +1327,7 @@ static GridAxisPosition columnAxisPosition(ItemPosition position, bool hasOrthog
         return GridAxisStart;
     case ItemPositionBaseline:
     case ItemPositionLastBaseline:
-        // FIXME: Implement the ItemPositionBaseline value. For now, we always 'start' align the child.
+        // FIXME: Implement the previous values. For now, we always 'start' align the child.
         return GridAxisStart;
     case ItemPositionAuto:
         break;
@@ -1372,32 +1337,96 @@ static GridAxisPosition columnAxisPosition(ItemPosition position, bool hasOrthog
     return GridAxisStart;
 }
 
-LayoutUnit RenderGrid::rowPositionForChild(const RenderBox& child) const
+GridAxisPosition RenderGrid::rowAxisPositionForChild(const RenderBox& child) const
 {
     bool hasOrthogonalWritingMode = child.isHorizontalWritingMode() != isHorizontalWritingMode();
-    bool hasSameWritingMode = child.style().writingMode() == style().writingMode();
-    ItemPosition position = RenderStyle::resolveAlignment(style(), child.style(), ItemPositionStretch);
+    bool hasSameDirection = child.style().direction() == style().direction();
+    bool isLTR = style().isLeftToRightDirection();
+
+    switch (RenderStyle::resolveJustification(style(), child.style(), ItemPositionStretch)) {
+    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 (hasOrthogonalWritingMode || 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 (hasOrthogonalWritingMode || hasSameDirection) ? GridAxisEnd : GridAxisStart;
+    case ItemPositionLeft:
+        return isLTR ? GridAxisStart : GridAxisEnd;
+    case ItemPositionRight:
+        return isLTR ? GridAxisEnd : GridAxisStart;
+    case ItemPositionCenter:
+        return GridAxisCenter;
+    case ItemPositionFlexStart: // Only used in flex layout, otherwise equivalent to 'start'.
+    case ItemPositionStart:
+        return GridAxisStart;
+    case ItemPositionFlexEnd: // Only used in flex layout, otherwise equivalent to 'end'.
+    case ItemPositionEnd:
+        return GridAxisEnd;
+    case ItemPositionStretch:
+        return GridAxisStart;
+    case ItemPositionBaseline:
+    case ItemPositionLastBaseline:
+        // FIXME: Implement the previous values. For now, we always 'start' align the child.
+        return GridAxisStart;
+    case ItemPositionAuto:
+        break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return GridAxisStart;
+}
+
+LayoutUnit RenderGrid::rowPositionForChild(const RenderBox& child) const
+{
+    const GridCoordinate& coordinate = cachedGridCoordinate(child);
+    LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
+    LayoutUnit endOfRow = m_rowPositions[coordinate.rows.resolvedFinalPosition.next().toInt()];
+    LayoutUnit startPosition = startOfRow + marginBeforeForChild(child);
+    // FIXME: This should account for the grid item's <overflow-position>.
+    LayoutUnit offsetFromStartPosition = endOfRow - startOfRow - child.logicalHeight() - child.marginLogicalHeight();
 
-    switch (columnAxisPosition(position, hasOrthogonalWritingMode, hasSameWritingMode)) {
+    switch (columnAxisPositionForChild(child)) {
     case GridAxisStart:
-        return startOfRowForChild(child);
+        return startPosition;
     case GridAxisEnd:
-        return endOfRowForChild(child);
+        return startPosition + offsetFromStartPosition;
     case GridAxisCenter:
-        return centeredRowPositionForChild(child);
+        return startPosition + offsetFromStartPosition / 2;
     }
 
     ASSERT_NOT_REACHED();
     return 0;
 }
 
-LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox& child, const GridSizingData& sizingData) const
+
+LayoutUnit RenderGrid::columnPositionForChild(const RenderBox& child) const
 {
     const GridCoordinate& coordinate = cachedGridCoordinate(child);
-    ASSERT_UNUSED(sizingData, coordinate.columns.resolvedInitialPosition.toInt() < sizingData.columnTracks.size());
-    ASSERT_UNUSED(sizingData, coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowTracks.size());
+    LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()];
+    LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalPosition.next().toInt()];
+    LayoutUnit startPosition = startOfColumn + marginStartForChild(child);
+    // FIXME: This should account for the grid item's <overflow-position>.
+    LayoutUnit offsetFromStartPosition = endOfColumn - startOfColumn - child.logicalWidth() - child.marginLogicalWidth();
 
-    LayoutUnit columnPosition = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()] + marginStartForChild(child);
+    switch (rowAxisPositionForChild(child)) {
+    case GridAxisStart:
+        return startPosition;
+    case GridAxisEnd:
+        return startPosition + offsetFromStartPosition;
+    case GridAxisCenter:
+        return startPosition + offsetFromStartPosition / 2;
+    }
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox& child) const
+{
+    LayoutUnit columnPosition = columnPositionForChild(child);
     // 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())
index 50e5dba..b5cce4a 100644 (file)
@@ -40,6 +40,8 @@ class GridSpan;
 class GridTrack;
 class GridItemWithSpan;
 
+enum GridAxisPosition {GridAxisStart, GridAxisEnd, GridAxisCenter};
+
 class RenderGrid final : public RenderBlock {
 public:
     RenderGrid(Element&, Ref<RenderStyle>&&);
@@ -117,13 +119,14 @@ private:
     LayoutUnit logicalContentHeightForChild(RenderBox&, Vector<GridTrack>&);
     LayoutUnit minContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
     LayoutUnit maxContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
-    LayoutUnit startOfRowForChild(const RenderBox&) const;
-    LayoutUnit endOfRowForChild(const RenderBox&) const;
-    LayoutUnit centeredRowPositionForChild(const RenderBox&) const;
+    GridAxisPosition columnAxisPositionForChild(const RenderBox&) const;
+    GridAxisPosition rowAxisPositionForChild(const RenderBox&) const;
     LayoutUnit rowPositionForChild(const RenderBox&) const;
-    LayoutPoint findChildLogicalPosition(const RenderBox&, const GridSizingData&) const;
+    LayoutUnit columnPositionForChild(const RenderBox&) const;
+    LayoutPoint findChildLogicalPosition(const RenderBox&) const;
     GridCoordinate cachedGridCoordinate(const RenderBox&) const;
 
+
     LayoutUnit gridAreaBreadthForChild(const RenderBox& child, GridTrackSizingDirection, const Vector<GridTrack>&) const;
 
     virtual void paintChildren(PaintInfo& forSelf, const LayoutPoint& paintOffset, PaintInfo& forChild, bool usePrintRect) override;
index 51d0fc8..e955251 100644 (file)
@@ -179,6 +179,13 @@ ItemPosition RenderStyle::resolveAlignment(const RenderStyle& parentStyle, const
     return childStyle.alignSelf();
 }
 
+ItemPosition RenderStyle::resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject)
+{
+    if (childStyle.justifySelf() == ItemPositionAuto)
+        return (parentStyle.justifyItems() == ItemPositionAuto) ? resolvedAutoPositionForLayoutObject : parentStyle.justifyItems();
+    return childStyle.justifySelf();
+}
+
 void RenderStyle::inheritFrom(const RenderStyle* inheritParent, IsAtShadowBoundary isAtShadowBoundary)
 {
     if (isAtShadowBoundary == AtShadowBoundary) {
index 33eac5b..7c6e575 100644 (file)
@@ -492,6 +492,7 @@ public:
     static Ref<RenderStyle> createStyleInheritingFromPseudoStyle(const RenderStyle& pseudoStyle);
 
     static ItemPosition resolveAlignment(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForRenderer);
+    static ItemPosition resolveJustification(const RenderStyle& parentStyle, const RenderStyle& childStyle, ItemPosition resolvedAutoPositionForLayoutObject);
 
     enum IsAtShadowBoundary {
         AtShadowBoundary,