Implement flex-wrap: wrap
authortony@chromium.org <tony@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Mar 2012 21:59:10 +0000 (21:59 +0000)
committertony@chromium.org <tony@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Mar 2012 21:59:10 +0000 (21:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=79930

Reviewed by David Hyatt.

Source/WebCore:

Tests: css3/flexbox/multiline-align.html
       css3/flexbox/multiline.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::sizesToIntrinsicLogicalWidth): Don't apply column+stretch optimization to multiline.
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::FlexOrderIterator::FlexOrderIterator):
(WebCore::RenderFlexibleBox::FlexOrderIterator::currentChild): Expose the current child so we can pause
in the middle of iteration and resume later.
(RenderFlexibleBox::FlexOrderIterator):
(WebCore::RenderFlexibleBox::isMultiline):
(WebCore):
(WebCore::RenderFlexibleBox::layoutFlexItems): Loop per line.
(WebCore::RenderFlexibleBox::availableAlignmentSpaceForChild): Use the line space, not the whole container space.
(WebCore::RenderFlexibleBox::computeFlexOrder): Return true for each line.
(WebCore::RenderFlexibleBox::layoutAndPlaceChildren): Use the line offset. Also compute the line height as we go.
(WebCore::RenderFlexibleBox::layoutColumnReverse): Use the line offset.
(WebCore::RenderFlexibleBox::alignChildren): Align based on the line height. For multiline + column, we have to relayout
since the width may change (same as the row case above). We'll have to do something smarter when we implement flex-line-pack.
* rendering/RenderFlexibleBox.h:
(RenderFlexibleBox):

LayoutTests:

* css3/flexbox/multiline-align-expected.txt: Added.
* css3/flexbox/multiline-align.html: Added.
* css3/flexbox/multiline-expected.txt: Added.
* css3/flexbox/multiline.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/css3/flexbox/multiline-align-expected.txt [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline-align.html [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline-expected.txt [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.h

index 98f34b4..1237b9e 100644 (file)
@@ -1,3 +1,15 @@
+2012-03-05  Tony Chang  <tony@chromium.org>
+
+        Implement flex-wrap: wrap
+        https://bugs.webkit.org/show_bug.cgi?id=79930
+
+        Reviewed by David Hyatt.
+
+        * css3/flexbox/multiline-align-expected.txt: Added.
+        * css3/flexbox/multiline-align.html: Added.
+        * css3/flexbox/multiline-expected.txt: Added.
+        * css3/flexbox/multiline.html: Added.
+
 2012-03-05  Stephen White  <senorblanco@chromium.org>
 
         [chromim] Mark http/tests/incremental/partial-jpeg.html as failing.
diff --git a/LayoutTests/css3/flexbox/multiline-align-expected.txt b/LayoutTests/css3/flexbox/multiline-align-expected.txt
new file mode 100644 (file)
index 0000000..7480b4f
--- /dev/null
@@ -0,0 +1,64 @@
+horizontal-tb ltr row wrap
+PASS
+horizontal-tb rtl row wrap
+PASS
+horizontal-tb ltr column wrap
+PASS
+horizontal-tb rtl column wrap
+PASS
+horizontal-tb ltr row-reverse wrap
+PASS
+horizontal-tb rtl row-reverse wrap
+PASS
+horizontal-tb ltr column-reverse wrap
+PASS
+horizontal-tb rtl column-reverse wrap
+PASS
+horizontal-bt ltr row wrap
+PASS
+horizontal-bt rtl row wrap
+PASS
+horizontal-bt ltr column wrap
+PASS
+horizontal-bt rtl column wrap
+PASS
+horizontal-bt ltr row-reverse wrap
+PASS
+horizontal-bt rtl row-reverse wrap
+PASS
+horizontal-bt ltr column-reverse wrap
+PASS
+horizontal-bt rtl column-reverse wrap
+PASS
+vertical-rl ltr row wrap
+PASS
+vertical-rl rtl row wrap
+PASS
+vertical-rl ltr column wrap
+PASS
+vertical-rl rtl column wrap
+PASS
+vertical-rl ltr row-reverse wrap
+PASS
+vertical-rl rtl row-reverse wrap
+PASS
+vertical-rl ltr column-reverse wrap
+PASS
+vertical-rl rtl column-reverse wrap
+PASS
+vertical-lr ltr row wrap
+PASS
+vertical-lr rtl row wrap
+PASS
+vertical-lr ltr column wrap
+PASS
+vertical-lr rtl column wrap
+PASS
+vertical-lr ltr row-reverse wrap
+PASS
+vertical-lr rtl row-reverse wrap
+PASS
+vertical-lr ltr column-reverse wrap
+PASS
+vertical-lr rtl column-reverse wrap
+PASS
diff --git a/LayoutTests/css3/flexbox/multiline-align.html b/LayoutTests/css3/flexbox/multiline-align.html
new file mode 100644 (file)
index 0000000..6b867b6
--- /dev/null
@@ -0,0 +1,827 @@
+<!DOCTYPE html>
+<html>
+<style>
+.flexbox {
+    position: relative;
+    display: -webkit-flexbox;
+    background-color: grey;
+    max-width: 600px;
+}
+.title {
+    margin-top: 1em;
+}
+.ltr {
+    direction: ltr;
+}
+.rtl {
+    direction: rtl;
+}
+.horizontal-tb {
+    -webkit-writing-mode: horizontal-tb;
+}
+.horizontal-bt {
+    -webkit-writing-mode: horizontal-bt;
+}
+.vertical-rl {
+    -webkit-writing-mode: vertical-rl;
+}
+.vertical-lr {
+    -webkit-writing-mode: vertical-lr;
+}
+.row {
+    -webkit-flex-flow: row;
+}
+.row-reverse {
+    -webkit-flex-flow: row-reverse;
+}
+.column {
+    -webkit-flex-flow: column;
+}
+.column-reverse {
+    -webkit-flex-flow: column-reverse;
+}
+.wrap {
+  -webkit-flex-wrap: wrap;
+}
+.wrap-reverse {
+  -webkit-flex-wrap: wrap-reverse;
+}
+.flexbox > :nth-child(1) {
+    background-color: #0f0;
+}
+.flexbox > :nth-child(2) {
+    background-color: #0d0;
+}
+.flexbox > :nth-child(3) {
+    background-color: #0b0;
+}
+.flexbox > :nth-child(4) {
+    background-color: #090;
+}
+.flexbox > :nth-child(5) {
+    background-color: #070;
+}
+.flexbox > :nth-child(6) {
+    background-color: #050;
+}
+.flexbox > :nth-child(7) {
+    background-color: #030;
+}
+
+.flexbox > :nth-child(8) {
+    background-color: #00f;
+}
+.flexbox > :nth-child(9) {
+    background-color: #00d;
+}
+.flexbox > :nth-child(10) {
+    background-color: #00b;
+}
+.flexbox > :nth-child(11) {
+    background-color: #009;
+}
+.flexbox > :nth-child(12) {
+    background-color: #007;
+}
+.flexbox > :nth-child(13) {
+    background-color: #005;
+}
+.flexbox > :nth-child(14) {
+    background-color: #003;
+}
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<script src="resources/flexbox.js"></script>
+<body onload="checkFlexBoxen()">
+
+<script>
+var expectations = {
+    'horizontal-tb': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 40, 5],
+                    'child6': [10, 30, 50, 0],
+                    'child7': [10, 30, 60, 0],
+                    'child8': [10, 10, 0, 30],
+                    'child9': [10, 10, 10, 40],
+                    'child10': [10, 10, 20, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 40, 35],
+                    'child13': [10, 30, 50, 30],
+                    'child14': [10, 30, 60, 30],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 0],
+                    'child2': [10, 10, 50, 10],
+                    'child3': [10, 10, 40, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 20, 5],
+                    'child6': [10, 30, 10, 0],
+                    'child7': [10, 30, 0, 0],
+                    'child8': [10, 10, 60, 30],
+                    'child9': [10, 10, 50, 40],
+                    'child10': [10, 10, 40, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 20, 35],
+                    'child13': [10, 30, 10, 30],
+                    'child14': [10, 30, 0, 30],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 40],
+                    'child6': [30, 10, 0, 50],
+                    'child7': [30, 10, 0, 60],
+                    'child8': [10, 10, 30, 0],
+                    'child9': [10, 10, 40, 10],
+                    'child10': [10, 10, 50, 20],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 40],
+                    'child13': [30, 10, 30, 50],
+                    'child14': [30, 10, 30, 60],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 590, 0],
+                    'child2': [10, 10, 580, 10],
+                    'child3': [10, 10, 570, 20],
+                    'child4': [10, 10, 585, 30],
+                    'child5': [10, 10, 585, 40],
+                    'child6': [30, 10, 570, 50],
+                    'child7': [30, 10, 570, 60],
+                    'child8': [10, 10, 560, 0],
+                    'child9': [10, 10, 550, 10],
+                    'child10': [10, 10, 540, 20],
+                    'child11': [10, 10, 555, 30],
+                    'child12': [10, 10, 555, 40],
+                    'child13': [30, 10, 540, 50],
+                    'child14': [30, 10, 540, 60],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 0],
+                    'child2': [10, 10, 50, 10],
+                    'child3': [10, 10, 40, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 20, 5],
+                    'child6': [10, 30, 10, 0],
+                    'child7': [10, 30, 0, 0],
+                    'child8': [10, 10, 60, 30],
+                    'child9': [10, 10, 50, 40],
+                    'child10': [10, 10, 40, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 20, 35],
+                    'child13': [10, 30, 10, 30],
+                    'child14': [10, 30, 0, 30],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 40, 5],
+                    'child6': [10, 30, 50, 0],
+                    'child7': [10, 30, 60, 0],
+                    'child8': [10, 10, 0, 30],
+                    'child9': [10, 10, 10, 40],
+                    'child10': [10, 10, 20, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 40, 35],
+                    'child13': [10, 30, 50, 30],
+                    'child14': [10, 30, 60, 30],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 0, 60],
+                    'child2': [10, 10, 10, 50],
+                    'child3': [10, 10, 20, 40],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 20],
+                    'child6': [30, 10, 0, 10],
+                    'child7': [30, 10, 0, 0],
+                    'child8': [10, 10, 30, 60],
+                    'child9': [10, 10, 40, 50],
+                    'child10': [10, 10, 50, 40],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 20],
+                    'child13': [30, 10, 30, 10],
+                    'child14': [30, 10, 30, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 590, 60],
+                    'child2': [10, 10, 580, 50],
+                    'child3': [10, 10, 570, 40],
+                    'child4': [10, 10, 585, 30],
+                    'child5': [10, 10, 585, 20],
+                    'child6': [30, 10, 570, 10],
+                    'child7': [30, 10, 570, 0],
+                    'child8': [10, 10, 560, 60],
+                    'child9': [10, 10, 550, 50],
+                    'child10': [10, 10, 540, 40],
+                    'child11': [10, 10, 555, 30],
+                    'child12': [10, 10, 555, 20],
+                    'child13': [30, 10, 540, 10],
+                    'child14': [30, 10, 540, 0],
+                },
+            },
+        },
+    },
+    'horizontal-bt': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 50],
+                    'child2': [10, 10, 10, 40],
+                    'child3': [10, 10, 20, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 40, 45],
+                    'child6': [10, 30, 50, 30],
+                    'child7': [10, 30, 60, 30],
+                    'child8': [10, 10, 0, 20],
+                    'child9': [10, 10, 10, 10],
+                    'child10': [10, 10, 20, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 40, 15],
+                    'child13': [10, 30, 50, 0],
+                    'child14': [10, 30, 60, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 50],
+                    'child2': [10, 10, 50, 40],
+                    'child3': [10, 10, 40, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 20, 45],
+                    'child6': [10, 30, 10, 30],
+                    'child7': [10, 30, 0, 30],
+                    'child8': [10, 10, 60, 20],
+                    'child9': [10, 10, 50, 10],
+                    'child10': [10, 10, 40, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 20, 15],
+                    'child13': [10, 30, 10, 0],
+                    'child14': [10, 30, 0, 0],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 0, 60],
+                    'child2': [10, 10, 10, 50],
+                    'child3': [10, 10, 20, 40],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 20],
+                    'child6': [30, 10, 0, 10],
+                    'child7': [30, 10, 0, 0],
+                    'child8': [10, 10, 30, 60],
+                    'child9': [10, 10, 40, 50],
+                    'child10': [10, 10, 50, 40],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 20],
+                    'child13': [30, 10, 30, 10],
+                    'child14': [30, 10, 30, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 590, 60],
+                    'child2': [10, 10, 580, 50],
+                    'child3': [10, 10, 570, 40],
+                    'child4': [10, 10, 585, 30],
+                    'child5': [10, 10, 585, 20],
+                    'child6': [30, 10, 570, 10],
+                    'child7': [30, 10, 570, 0],
+                    'child8': [10, 10, 560, 60],
+                    'child9': [10, 10, 550, 50],
+                    'child10': [10, 10, 540, 40],
+                    'child11': [10, 10, 555, 30],
+                    'child12': [10, 10, 555, 20],
+                    'child13': [30, 10, 540, 10],
+                    'child14': [30, 10, 540, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 50],
+                    'child2': [10, 10, 50, 40],
+                    'child3': [10, 10, 40, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 20, 45],
+                    'child6': [10, 30, 10, 30],
+                    'child7': [10, 30, 0, 30],
+                    'child8': [10, 10, 60, 20],
+                    'child9': [10, 10, 50, 10],
+                    'child10': [10, 10, 40, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 20, 15],
+                    'child13': [10, 30, 10, 0],
+                    'child14': [10, 30, 0, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 50],
+                    'child2': [10, 10, 10, 40],
+                    'child3': [10, 10, 20, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 40, 45],
+                    'child6': [10, 30, 50, 30],
+                    'child7': [10, 30, 60, 30],
+                    'child8': [10, 10, 0, 20],
+                    'child9': [10, 10, 10, 10],
+                    'child10': [10, 10, 20, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 40, 15],
+                    'child13': [10, 30, 50, 0],
+                    'child14': [10, 30, 60, 0],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 40],
+                    'child6': [30, 10, 0, 50],
+                    'child7': [30, 10, 0, 60],
+                    'child8': [10, 10, 30, 0],
+                    'child9': [10, 10, 40, 10],
+                    'child10': [10, 10, 50, 20],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 40],
+                    'child13': [30, 10, 30, 50],
+                    'child14': [30, 10, 30, 60],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 70],
+                    'child1': [10, 10, 590, 0],
+                    'child2': [10, 10, 580, 10],
+                    'child3': [10, 10, 570, 20],
+                    'child4': [10, 10, 585, 30],
+                    'child5': [10, 10, 585, 40],
+                    'child6': [30, 10, 570, 50],
+                    'child7': [30, 10, 570, 60],
+                    'child8': [10, 10, 560, 0],
+                    'child9': [10, 10, 550, 10],
+                    'child10': [10, 10, 540, 20],
+                    'child11': [10, 10, 555, 30],
+                    'child12': [10, 10, 555, 40],
+                    'child13': [30, 10, 540, 50],
+                    'child14': [30, 10, 540, 60],
+                },
+            },
+        },
+    },
+    'vertical-rl': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 50, 0],
+                    'child2': [10, 10, 40, 10],
+                    'child3': [10, 10, 30, 20],
+                    'child4': [10, 10, 45, 30],
+                    'child5': [10, 10, 45, 40],
+                    'child6': [30, 10, 30, 50],
+                    'child7': [30, 10, 30, 60],
+                    'child8': [10, 10, 20, 0],
+                    'child9': [10, 10, 10, 10],
+                    'child10': [10, 10, 0, 20],
+                    'child11': [10, 10, 15, 30],
+                    'child12': [10, 10, 15, 40],
+                    'child13': [30, 10, 0, 50],
+                    'child14': [30, 10, 0, 60],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 50, 60],
+                    'child2': [10, 10, 40, 50],
+                    'child3': [10, 10, 30, 40],
+                    'child4': [10, 10, 45, 30],
+                    'child5': [10, 10, 45, 20],
+                    'child6': [30, 10, 30, 10],
+                    'child7': [30, 10, 30, 0],
+                    'child8': [10, 10, 20, 60],
+                    'child9': [10, 10, 10, 50],
+                    'child10': [10, 10, 0, 40],
+                    'child11': [10, 10, 15, 30],
+                    'child12': [10, 10, 15, 20],
+                    'child13': [30, 10, 0, 10],
+                    'child14': [30, 10, 0, 0],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 0],
+                    'child2': [10, 10, 50, 10],
+                    'child3': [10, 10, 40, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 20, 5],
+                    'child6': [10, 30, 10, 0],
+                    'child7': [10, 30, 0, 0],
+                    'child8': [10, 10, 60, 30],
+                    'child9': [10, 10, 50, 40],
+                    'child10': [10, 10, 40, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 20, 35],
+                    'child13': [10, 30, 10, 30],
+                    'child14': [10, 30, 0, 30],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 50],
+                    'child2': [10, 10, 50, 40],
+                    'child3': [10, 10, 40, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 20, 45],
+                    'child6': [10, 30, 10, 30],
+                    'child7': [10, 30, 0, 30],
+                    'child8': [10, 10, 60, 20],
+                    'child9': [10, 10, 50, 10],
+                    'child10': [10, 10, 40, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 20, 15],
+                    'child13': [10, 30, 10, 0],
+                    'child14': [10, 30, 0, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 50, 60],
+                    'child2': [10, 10, 40, 50],
+                    'child3': [10, 10, 30, 40],
+                    'child4': [10, 10, 45, 30],
+                    'child5': [10, 10, 45, 20],
+                    'child6': [30, 10, 30, 10],
+                    'child7': [30, 10, 30, 0],
+                    'child8': [10, 10, 20, 60],
+                    'child9': [10, 10, 10, 50],
+                    'child10': [10, 10, 0, 40],
+                    'child11': [10, 10, 15, 30],
+                    'child12': [10, 10, 15, 20],
+                    'child13': [30, 10, 0, 10],
+                    'child14': [30, 10, 0, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 50, 0],
+                    'child2': [10, 10, 40, 10],
+                    'child3': [10, 10, 30, 20],
+                    'child4': [10, 10, 45, 30],
+                    'child5': [10, 10, 45, 40],
+                    'child6': [30, 10, 30, 50],
+                    'child7': [30, 10, 30, 60],
+                    'child8': [10, 10, 20, 0],
+                    'child9': [10, 10, 10, 10],
+                    'child10': [10, 10, 0, 20],
+                    'child11': [10, 10, 15, 30],
+                    'child12': [10, 10, 15, 40],
+                    'child13': [30, 10, 0, 50],
+                    'child14': [30, 10, 0, 60],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 40, 5],
+                    'child6': [10, 30, 50, 0],
+                    'child7': [10, 30, 60, 0],
+                    'child8': [10, 10, 0, 30],
+                    'child9': [10, 10, 10, 40],
+                    'child10': [10, 10, 20, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 40, 35],
+                    'child13': [10, 30, 50, 30],
+                    'child14': [10, 30, 60, 30],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 50],
+                    'child2': [10, 10, 10, 40],
+                    'child3': [10, 10, 20, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 40, 45],
+                    'child6': [10, 30, 50, 30],
+                    'child7': [10, 30, 60, 30],
+                    'child8': [10, 10, 0, 20],
+                    'child9': [10, 10, 10, 10],
+                    'child10': [10, 10, 20, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 40, 15],
+                    'child13': [10, 30, 50, 0],
+                    'child14': [10, 30, 60, 0],
+                },
+            },
+        },
+    },
+    'vertical-lr': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 40],
+                    'child6': [30, 10, 0, 50],
+                    'child7': [30, 10, 0, 60],
+                    'child8': [10, 10, 30, 0],
+                    'child9': [10, 10, 40, 10],
+                    'child10': [10, 10, 50, 20],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 40],
+                    'child13': [30, 10, 30, 50],
+                    'child14': [30, 10, 30, 60],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 0, 60],
+                    'child2': [10, 10, 10, 50],
+                    'child3': [10, 10, 20, 40],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 20],
+                    'child6': [30, 10, 0, 10],
+                    'child7': [30, 10, 0, 0],
+                    'child8': [10, 10, 30, 60],
+                    'child9': [10, 10, 40, 50],
+                    'child10': [10, 10, 50, 40],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 20],
+                    'child13': [30, 10, 30, 10],
+                    'child14': [30, 10, 30, 0],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 40, 5],
+                    'child6': [10, 30, 50, 0],
+                    'child7': [10, 30, 60, 0],
+                    'child8': [10, 10, 0, 30],
+                    'child9': [10, 10, 10, 40],
+                    'child10': [10, 10, 20, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 40, 35],
+                    'child13': [10, 30, 50, 30],
+                    'child14': [10, 30, 60, 30],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 0, 50],
+                    'child2': [10, 10, 10, 40],
+                    'child3': [10, 10, 20, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 40, 45],
+                    'child6': [10, 30, 50, 30],
+                    'child7': [10, 30, 60, 30],
+                    'child8': [10, 10, 0, 20],
+                    'child9': [10, 10, 10, 10],
+                    'child10': [10, 10, 20, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 40, 15],
+                    'child13': [10, 30, 50, 0],
+                    'child14': [10, 30, 60, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 0, 60],
+                    'child2': [10, 10, 10, 50],
+                    'child3': [10, 10, 20, 40],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 20],
+                    'child6': [30, 10, 0, 10],
+                    'child7': [30, 10, 0, 0],
+                    'child8': [10, 10, 30, 60],
+                    'child9': [10, 10, 40, 50],
+                    'child10': [10, 10, 50, 40],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 20],
+                    'child13': [30, 10, 30, 10],
+                    'child14': [30, 10, 30, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 70],
+                    'child1': [10, 10, 0, 0],
+                    'child2': [10, 10, 10, 10],
+                    'child3': [10, 10, 20, 20],
+                    'child4': [10, 10, 5, 30],
+                    'child5': [10, 10, 5, 40],
+                    'child6': [30, 10, 0, 50],
+                    'child7': [30, 10, 0, 60],
+                    'child8': [10, 10, 30, 0],
+                    'child9': [10, 10, 40, 10],
+                    'child10': [10, 10, 50, 20],
+                    'child11': [10, 10, 35, 30],
+                    'child12': [10, 10, 35, 40],
+                    'child13': [30, 10, 30, 50],
+                    'child14': [30, 10, 30, 60],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 0],
+                    'child2': [10, 10, 50, 10],
+                    'child3': [10, 10, 40, 20],
+                    'child4': [10, 10, 30, 5],
+                    'child5': [10, 10, 20, 5],
+                    'child6': [10, 30, 10, 0],
+                    'child7': [10, 30, 0, 0],
+                    'child8': [10, 10, 60, 30],
+                    'child9': [10, 10, 50, 40],
+                    'child10': [10, 10, 40, 50],
+                    'child11': [10, 10, 30, 35],
+                    'child12': [10, 10, 20, 35],
+                    'child13': [10, 30, 10, 30],
+                    'child14': [10, 30, 0, 30],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [70, 60],
+                    'child1': [10, 10, 60, 50],
+                    'child2': [10, 10, 50, 40],
+                    'child3': [10, 10, 40, 30],
+                    'child4': [10, 10, 30, 45],
+                    'child5': [10, 10, 20, 45],
+                    'child6': [10, 30, 10, 30],
+                    'child7': [10, 30, 0, 30],
+                    'child8': [10, 10, 60, 20],
+                    'child9': [10, 10, 50, 10],
+                    'child10': [10, 10, 40, 0],
+                    'child11': [10, 10, 30, 15],
+                    'child12': [10, 10, 20, 15],
+                    'child13': [10, 30, 10, 0],
+                    'child14': [10, 30, 0, 0],
+                },
+            },
+        },
+    },
+};
+
+function mainAxisDirection(writingMode, flexDirection)
+{
+    if ((writingMode.indexOf('horizontal') != -1 && flexDirection.indexOf('row') != -1)
+        || (writingMode.indexOf('vertical') != -1 && flexDirection.indexOf('column') != -1))
+        return 'width';
+    return 'height';
+}
+
+function addChild(flexbox, mainAxis, crossAxis, preferredSize, crossAxisLength, alignment, expectations)
+{
+    var child = document.createElement('div');
+    child.setAttribute('style', mainAxis + ': -webkit-flex(1 ' + preferredSize + 'px);'
+        + crossAxis + ': ' + crossAxisLength + ';'
+        + '-webkit-flex-item-align: ' + alignment);
+
+    child.setAttribute("data-expected-width", expectations[0]);
+    child.setAttribute("data-expected-height", expectations[1]);
+    child.setAttribute("data-offset-x", expectations[2]);
+    child.setAttribute("data-offset-y", expectations[3]);
+
+    flexbox.appendChild(child);
+}
+
+var writingModes = ['horizontal-tb', 'horizontal-bt', 'vertical-rl', 'vertical-lr'];
+var flexDirections = ['row', 'column', 'row-reverse', 'column-reverse'];
+var directions = ['ltr', 'rtl'];
+// FIXME: Implement and test wrap-reverse.
+var wraps = ['wrap'];
+
+writingModes.forEach(function(writingMode) {
+    flexDirections.forEach(function(flexDirection) {
+        directions.forEach(function(direction) {
+            wraps.forEach(function(wrap) {
+                var flexboxClassName = writingMode + ' ' + direction + ' ' + flexDirection + ' ' + wrap;
+                var title = document.createElement('div');
+                title.className = 'title';
+                title.innerHTML = flexboxClassName;
+                document.body.appendChild(title);
+
+                var mainAxis = mainAxisDirection(writingMode, flexDirection);
+                var crossAxis = (mainAxis == 'width') ? 'height' : 'width';
+
+                var flexbox = document.createElement('div');
+                flexbox.className = 'flexbox ' + flexboxClassName;
+                flexbox.setAttribute('style', mainAxis + ': 70px');
+
+                var baselineMargin = (flexDirection.indexOf('row') != -1) ? '-webkit-margin-before: 5px' : '-webkit-margin-start: 5px';
+                    
+                var testExpectations = expectations[writingMode][flexDirection][direction][wrap];
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'start', testExpectations['child1']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'center', testExpectations['child2']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'end', testExpectations['child3']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'baseline', testExpectations['child4']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'baseline; ' + baselineMargin, testExpectations['child5']);
+                addChild(flexbox, mainAxis, crossAxis, 10, 'auto', 'stretch', testExpectations['child6']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '30px', 'start', testExpectations['child7']);
+
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'start', testExpectations['child8']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'center', testExpectations['child9']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'end', testExpectations['child10']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'baseline', testExpectations['child11']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '10px', 'baseline; ' + baselineMargin, testExpectations['child12']);
+                addChild(flexbox, mainAxis, crossAxis, 10, 'auto', 'stretch', testExpectations['child13']);
+                addChild(flexbox, mainAxis, crossAxis, 10, '30px', 'start', testExpectations['child14']);
+
+                flexbox.setAttribute("data-expected-width", testExpectations.flexbox[0]);
+                flexbox.setAttribute("data-expected-height", testExpectations.flexbox[1]);
+
+                document.body.appendChild(flexbox);
+            })
+        })
+    })
+})
+</script>
+</body>
+</html>
diff --git a/LayoutTests/css3/flexbox/multiline-expected.txt b/LayoutTests/css3/flexbox/multiline-expected.txt
new file mode 100644 (file)
index 0000000..7480b4f
--- /dev/null
@@ -0,0 +1,64 @@
+horizontal-tb ltr row wrap
+PASS
+horizontal-tb rtl row wrap
+PASS
+horizontal-tb ltr column wrap
+PASS
+horizontal-tb rtl column wrap
+PASS
+horizontal-tb ltr row-reverse wrap
+PASS
+horizontal-tb rtl row-reverse wrap
+PASS
+horizontal-tb ltr column-reverse wrap
+PASS
+horizontal-tb rtl column-reverse wrap
+PASS
+horizontal-bt ltr row wrap
+PASS
+horizontal-bt rtl row wrap
+PASS
+horizontal-bt ltr column wrap
+PASS
+horizontal-bt rtl column wrap
+PASS
+horizontal-bt ltr row-reverse wrap
+PASS
+horizontal-bt rtl row-reverse wrap
+PASS
+horizontal-bt ltr column-reverse wrap
+PASS
+horizontal-bt rtl column-reverse wrap
+PASS
+vertical-rl ltr row wrap
+PASS
+vertical-rl rtl row wrap
+PASS
+vertical-rl ltr column wrap
+PASS
+vertical-rl rtl column wrap
+PASS
+vertical-rl ltr row-reverse wrap
+PASS
+vertical-rl rtl row-reverse wrap
+PASS
+vertical-rl ltr column-reverse wrap
+PASS
+vertical-rl rtl column-reverse wrap
+PASS
+vertical-lr ltr row wrap
+PASS
+vertical-lr rtl row wrap
+PASS
+vertical-lr ltr column wrap
+PASS
+vertical-lr rtl column wrap
+PASS
+vertical-lr ltr row-reverse wrap
+PASS
+vertical-lr rtl row-reverse wrap
+PASS
+vertical-lr ltr column-reverse wrap
+PASS
+vertical-lr rtl column-reverse wrap
+PASS
diff --git a/LayoutTests/css3/flexbox/multiline.html b/LayoutTests/css3/flexbox/multiline.html
new file mode 100644 (file)
index 0000000..e0b6a6c
--- /dev/null
@@ -0,0 +1,498 @@
+<!DOCTYPE html>
+<html>
+<style>
+.flexbox {
+    position: relative;
+    display: -webkit-flexbox;
+    background-color: grey;
+    max-width: 600px;
+}
+.title {
+    margin-top: 1em;
+}
+.ltr {
+    direction: ltr;
+}
+.rtl {
+    direction: rtl;
+}
+.horizontal-tb {
+    -webkit-writing-mode: horizontal-tb;
+}
+.horizontal-bt {
+    -webkit-writing-mode: horizontal-bt;
+}
+.vertical-rl {
+    -webkit-writing-mode: vertical-rl;
+}
+.vertical-lr {
+    -webkit-writing-mode: vertical-lr;
+}
+.row {
+    -webkit-flex-flow: row;
+}
+.row-reverse {
+    -webkit-flex-flow: row-reverse;
+}
+.column {
+    -webkit-flex-flow: column;
+}
+.column-reverse {
+    -webkit-flex-flow: column-reverse;
+}
+.wrap {
+  -webkit-flex-wrap: wrap;
+}
+.wrap-reverse {
+  -webkit-flex-wrap: wrap-reverse;
+}
+.flexbox > :nth-child(1) {
+    background-color: #0f0;
+}
+.flexbox > :nth-child(2) {
+    background-color: #0d0;
+}
+.flexbox > :nth-child(3) {
+    background-color: #090;
+}
+.flexbox > :nth-child(4) {
+    background-color: #060;
+}
+.flexbox > :nth-child(5) {
+    background-color: #030;
+}
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<script src="resources/flexbox.js"></script>
+<body onload="checkFlexBoxen()">
+
+<script>
+var expectations = {
+    'horizontal-tb': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 0],
+                    'child2': [30, 10, 30, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, 0, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 0],
+                    'child2': [30, 10, 0, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, -10, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 0, 0],
+                    'child2': [10, 30, 0, 30],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, 0],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 595, 0],
+                    'child2': [10, 30, 590, 30],
+                    'child3': [5, 60, 585, 0],
+                    'child4': [20, 70, 565, 0],
+                    'child5': [10, 60, 555, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 0],
+                    'child2': [30, 10, 0, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, -10, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 0],
+                    'child2': [30, 10, 30, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, 0, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 0, 30],
+                    'child2': [10, 30, 0, 0],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, -10],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 595, 30],
+                    'child2': [10, 30, 590, 0],
+                    'child3': [5, 60, 585, 0],
+                    'child4': [20, 70, 565, -10],
+                    'child5': [10, 60, 555, 0],
+                },
+            },
+        },
+    },
+    'horizontal-bt': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 40],
+                    'child2': [30, 10, 30, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, 0, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 40],
+                    'child2': [30, 10, 0, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, -10, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 0, 30],
+                    'child2': [10, 30, 0, 0],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, -10],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 595, 30],
+                    'child2': [10, 30, 590, 0],
+                    'child3': [5, 60, 585, 0],
+                    'child4': [20, 70, 565, -10],
+                    'child5': [10, 60, 555, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 40],
+                    'child2': [30, 10, 0, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, -10, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 40],
+                    'child2': [30, 10, 30, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, 0, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 0, 0],
+                    'child2': [10, 30, 0, 30],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, 0],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [600, 60],
+                    'child1': [5, 30, 595, 0],
+                    'child2': [10, 30, 590, 30],
+                    'child3': [5, 60, 585, 0],
+                    'child4': [20, 70, 565, 0],
+                    'child5': [10, 60, 555, 0],
+                },
+            },
+        },
+    },
+    'vertical-rl': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 40, 0],
+                    'child2': [10, 30, 35, 30],
+                    'child3': [5, 60, 30, 0],
+                    'child4': [20, 70, 10, 0],
+                    'child5': [10, 60, 0, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 40, 30],
+                    'child2': [10, 30, 35, 0],
+                    'child3': [5, 60, 30, 0],
+                    'child4': [20, 70, 10, -10],
+                    'child5': [10, 60, 0, 0],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 0],
+                    'child2': [30, 10, 0, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, -10, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 40],
+                    'child2': [30, 10, 0, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, -10, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 40, 30],
+                    'child2': [10, 30, 35, 0],
+                    'child3': [5, 60, 30, 0],
+                    'child4': [20, 70, 10, -10],
+                    'child5': [10, 60, 0, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 40, 0],
+                    'child2': [10, 30, 35, 30],
+                    'child3': [5, 60, 30, 0],
+                    'child4': [20, 70, 10, 0],
+                    'child5': [10, 60, 0, 0],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 0],
+                    'child2': [30, 10, 30, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, 0, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 40],
+                    'child2': [30, 10, 30, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, 0, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+        },
+    },
+    'vertical-lr': {
+        'row': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 0, 0],
+                    'child2': [10, 30, 0, 30],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, 0],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 0, 30],
+                    'child2': [10, 30, 0, 0],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, -10],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+        },
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 0],
+                    'child2': [30, 10, 30, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, 0, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 0, 40],
+                    'child2': [30, 10, 30, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, 0, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+        },
+        'row-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 0, 30],
+                    'child2': [10, 30, 0, 0],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, -10],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [45, 60],
+                    'child1': [5, 30, 0, 0],
+                    'child2': [10, 30, 0, 30],
+                    'child3': [5, 60, 10, 0],
+                    'child4': [20, 70, 15, 0],
+                    'child5': [10, 60, 35, 0],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 0],
+                    'child2': [30, 10, 0, 0],
+                    'child3': [60, 5, 0, 10],
+                    'child4': [70, 20, -10, 15],
+                    'child5': [60, 10, 0, 35],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'flexbox': [60, 45],
+                    'child1': [30, 5, 30, 40],
+                    'child2': [30, 10, 0, 35],
+                    'child3': [60, 5, 0, 30],
+                    'child4': [70, 20, -10, 10],
+                    'child5': [60, 10, 0, 0],
+                },
+            },
+        },
+    },
+};
+
+function mainAxisDirection(writingMode, flexDirection)
+{
+    if ((writingMode.indexOf('horizontal') != -1 && flexDirection.indexOf('row') != -1)
+        || (writingMode.indexOf('vertical') != -1 && flexDirection.indexOf('column') != -1))
+        return 'width';
+    return 'height';
+}
+
+function addChild(flexbox, mainAxis, crossAxis, preferredSize, crossAxisLength, expectations)
+{
+    var child = document.createElement('div');
+    child.setAttribute('style', mainAxis + ': -webkit-flex(1 ' + preferredSize + 'px);'
+        + crossAxis + ': ' + crossAxisLength + 'px;');
+
+    child.setAttribute("data-expected-width", expectations[0]);
+    child.setAttribute("data-expected-height", expectations[1]);
+    child.setAttribute("data-offset-x", expectations[2]);
+    child.setAttribute("data-offset-y", expectations[3]);
+
+    flexbox.appendChild(child);
+}
+
+var writingModes = ['horizontal-tb', 'horizontal-bt', 'vertical-rl', 'vertical-lr'];
+var flexDirections = ['row', 'column', 'row-reverse', 'column-reverse'];
+var directions = ['ltr', 'rtl'];
+// FIXME: Implement and test wrap-reverse.
+var wraps = ['wrap'];
+
+writingModes.forEach(function(writingMode) {
+    flexDirections.forEach(function(flexDirection) {
+        directions.forEach(function(direction) {
+            wraps.forEach(function(wrap) {
+                var flexboxClassName = writingMode + ' ' + direction + ' ' + flexDirection + ' ' + wrap;
+                var title = document.createElement('div');
+                title.className = 'title';
+                title.innerHTML = flexboxClassName;
+                document.body.appendChild(title);
+
+                var mainAxis = mainAxisDirection(writingMode, flexDirection);
+                var crossAxis = (mainAxis == 'width') ? 'height' : 'width';
+
+                var flexbox = document.createElement('div');
+                flexbox.className = 'flexbox ' + flexboxClassName;
+                flexbox.setAttribute('style', mainAxis + ': 60px');
+
+                var testExpectations = expectations[writingMode][flexDirection][direction][wrap];
+                addChild(flexbox, mainAxis, crossAxis, 25, 5, testExpectations['child1']);
+                addChild(flexbox, mainAxis, crossAxis, 25, 10, testExpectations['child2']);
+                addChild(flexbox, mainAxis, crossAxis, 25, 5, testExpectations['child3']);
+                addChild(flexbox, mainAxis, crossAxis, 70, 20, testExpectations['child4']);
+                addChild(flexbox, mainAxis, crossAxis, 5, 10, testExpectations['child5']);
+
+                flexbox.setAttribute("data-expected-width", testExpectations.flexbox[0]);
+                flexbox.setAttribute("data-expected-height", testExpectations.flexbox[1]);
+
+                document.body.appendChild(flexbox);
+            })
+        })
+    })
+})
+</script>
+</body>
+</html>
index bcfa98a..b3a6322 100644 (file)
@@ -1,3 +1,32 @@
+2012-03-05  Tony Chang  <tony@chromium.org>
+
+        Implement flex-wrap: wrap
+        https://bugs.webkit.org/show_bug.cgi?id=79930
+
+        Reviewed by David Hyatt.
+
+        Tests: css3/flexbox/multiline-align.html
+               css3/flexbox/multiline.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::sizesToIntrinsicLogicalWidth): Don't apply column+stretch optimization to multiline.
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::FlexOrderIterator::FlexOrderIterator):
+        (WebCore::RenderFlexibleBox::FlexOrderIterator::currentChild): Expose the current child so we can pause
+        in the middle of iteration and resume later.
+        (RenderFlexibleBox::FlexOrderIterator):
+        (WebCore::RenderFlexibleBox::isMultiline):
+        (WebCore):
+        (WebCore::RenderFlexibleBox::layoutFlexItems): Loop per line.
+        (WebCore::RenderFlexibleBox::availableAlignmentSpaceForChild): Use the line space, not the whole container space.
+        (WebCore::RenderFlexibleBox::computeFlexOrder): Return true for each line.
+        (WebCore::RenderFlexibleBox::layoutAndPlaceChildren): Use the line offset. Also compute the line height as we go.
+        (WebCore::RenderFlexibleBox::layoutColumnReverse): Use the line offset.
+        (WebCore::RenderFlexibleBox::alignChildren): Align based on the line height. For multiline + column, we have to relayout
+        since the width may change (same as the row case above). We'll have to do something smarter when we implement flex-line-pack.
+        * rendering/RenderFlexibleBox.h:
+        (RenderFlexibleBox):
+
 2012-03-05  Ben Vanik  <benvanik@google.com>
 
         Implement WebGL extension EXT_texture_filter_anisotropic
index 54128f9..6fcd611 100644 (file)
@@ -1841,7 +1841,8 @@ bool RenderBox::sizesToIntrinsicLogicalWidth(LogicalWidthType widthType) const
     // In the case of columns that have a stretch alignment, we go ahead and layout at the
     // stretched size to avoid an extra layout when applying alignment.
     if (parent()->isFlexibleBox()) {
-        if (!parent()->style()->isColumnFlexDirection())
+        // For multiline columns, we need to apply the flex-line-pack first, so we can't stretch now.
+        if (!parent()->style()->isColumnFlexDirection() || parent()->style()->flexWrap() != FlexWrapNone)
             return true;
         EFlexAlign itemAlign = style()->flexItemAlign();
         if (itemAlign != AlignStretch && (itemAlign != AlignAuto || parent()->style()->flexAlign() != AlignStretch))
index 6d0b761..1cfd54c 100644 (file)
@@ -56,8 +56,11 @@ public:
     {
         copyToVector(flexOrderValues, m_orderValues);
         std::sort(m_orderValues.begin(), m_orderValues.end());
+        first();
     }
 
+    RenderBox* currentChild() { return m_currentChild; }
+
     RenderBox* first()
     {
         reset();
@@ -279,6 +282,11 @@ bool RenderFlexibleBox::isLeftToRightFlow() const
     return style()->isLeftToRightDirection() ^ (style()->flexDirection() == FlowRowReverse);
 }
 
+bool RenderFlexibleBox::isMultiline() const
+{
+    return style()->flexWrap() != FlexWrapNone;
+}
+
 Length RenderFlexibleBox::mainAxisLengthForChild(RenderBox* child) const
 {
     return isHorizontalFlow() ? child->style()->width() : child->style()->height();
@@ -509,17 +517,20 @@ void RenderFlexibleBox::layoutFlexItems(bool relayoutChildren)
     float totalPositiveFlexibility;
     float totalNegativeFlexibility;
     FlexOrderIterator flexIterator(this, flexOrderValues);
-    computeFlexOrder(flexIterator, orderedChildren, preferredMainAxisExtent, totalPositiveFlexibility, totalNegativeFlexibility);
-
-    LayoutUnit availableFreeSpace = mainAxisContentExtent() - preferredMainAxisExtent;
-    InflexibleFlexItemSize inflexibleItems;
-    WTF::Vector<LayoutUnit> childSizes;
-    while (!runFreeSpaceAllocationAlgorithm(orderedChildren, availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems, childSizes)) {
-        ASSERT(totalPositiveFlexibility >= 0 && totalNegativeFlexibility >= 0);
-        ASSERT(inflexibleItems.size() > 0);
-    }
 
-    layoutAndPlaceChildren(orderedChildren, childSizes, availableFreeSpace);
+    LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
+    LayoutUnit mainAxisFlexibleSpace = mainAxisContentExtent();
+    while (computeNextFlexLine(flexIterator, orderedChildren, preferredMainAxisExtent, totalPositiveFlexibility, totalNegativeFlexibility)) {
+        LayoutUnit availableFreeSpace = mainAxisFlexibleSpace - preferredMainAxisExtent;
+        InflexibleFlexItemSize inflexibleItems;
+        WTF::Vector<LayoutUnit> childSizes;
+        while (!runFreeSpaceAllocationAlgorithm(orderedChildren, availableFreeSpace, totalPositiveFlexibility, totalNegativeFlexibility, inflexibleItems, childSizes)) {
+            ASSERT(totalPositiveFlexibility >= 0 && totalNegativeFlexibility >= 0);
+            ASSERT(inflexibleItems.size() > 0);
+        }
+
+        layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace);
+    }
 
     // direction:rtl + flex-direction:column means the cross-axis direction is flipped.
     flipForRightToLeftColumn(flexIterator);
@@ -535,11 +546,10 @@ float RenderFlexibleBox::negativeFlexForChild(RenderBox* child) const
     return isHorizontalFlow() ? child->style()->flexboxWidthNegativeFlex() : child->style()->flexboxHeightNegativeFlex();
 }
 
-LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(RenderBox* child)
+LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox* child)
 {
-    LayoutUnit crossContentExtent = crossAxisContentExtent();
     LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child);
-    return crossContentExtent - childCrossExtent;
+    return lineCrossAxisExtent - childCrossExtent;
 }
 
 LayoutUnit RenderFlexibleBox::marginBoxAscent(RenderBox* child)
@@ -579,15 +589,20 @@ void RenderFlexibleBox::computeMainAxisPreferredSizes(bool relayoutChildren, Fle
     }
 }
 
-void RenderFlexibleBox::computeFlexOrder(FlexOrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
+bool RenderFlexibleBox::computeNextFlexLine(FlexOrderIterator& iterator, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalNegativeFlexibility)
 {
     orderedChildren.clear();
     preferredMainAxisExtent = 0;
     totalPositiveFlexibility = totalNegativeFlexibility = 0;
-    for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
-        orderedChildren.append(child);
-        if (child->isPositioned())
+
+    if (!iterator.currentChild())
+        return false;
+
+    for (RenderBox* child = iterator.currentChild(); child; child = iterator.next()) {
+        if (child->isPositioned()) {
+            orderedChildren.append(child);
             continue;
+        }
 
         LayoutUnit childMainAxisExtent = mainAxisBorderAndPaddingExtentForChild(child) + preferredMainAxisContentExtentForChild(child);
         if (isHorizontalFlow())
@@ -595,12 +610,14 @@ void RenderFlexibleBox::computeFlexOrder(FlexOrderIterator& iterator, OrderedFle
         else
             childMainAxisExtent += child->marginTop() + child->marginBottom();
 
-        // FIXME: When implementing multiline, we would return here if adding
-        // the child's main axis extent would cause us to overflow.
+        if (isMultiline() && preferredMainAxisExtent + childMainAxisExtent > mainAxisContentExtent() && orderedChildren.size() > 0)
+            break;
+        orderedChildren.append(child);
         preferredMainAxisExtent += childMainAxisExtent;
         totalPositiveFlexibility += positiveFlexForChild(child);
         totalNegativeFlexibility += negativeFlexForChild(child);
     }
+    return true;
 }
 
 // Returns true if we successfully ran the algorithm and sized the flex items.
@@ -714,16 +731,16 @@ static EFlexAlign flexAlignForChild(RenderBox* child)
     return align;
 }
 
-void RenderFlexibleBox::layoutAndPlaceChildren(const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
+void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
 {
     LayoutUnit mainAxisOffset = flowAwareBorderStart() + flowAwarePaddingStart();
     mainAxisOffset += initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
     if (style()->flexDirection() == FlowRowReverse)
         mainAxisOffset += isHorizontalFlow() ? verticalScrollbarWidth() : horizontalScrollbarHeight();
 
-    LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
     LayoutUnit totalMainExtent = mainAxisExtent();
     LayoutUnit maxAscent = 0, maxDescent = 0; // Used when flex-align: baseline.
+    LayoutUnit maxChildCrossAxisExtent = 0;
     bool shouldFlipMainAxis = !isColumnFlow() && !isLeftToRightFlow();
     for (size_t i = 0; i < children.size(); ++i) {
         RenderBox* child = children[i];
@@ -749,7 +766,8 @@ void RenderFlexibleBox::layoutAndPlaceChildren(const OrderedFlexItemList& childr
         } else
             childCrossAxisExtent =  crossAxisExtentForChild(child);
         if (crossAxisLength().isAuto())
-            setCrossAxisExtent(std::max(crossAxisExtent(), crossAxisBorderAndPaddingExtent() + crossAxisMarginExtentForChild(child) + childCrossAxisExtent + crossAxisScrollbarExtent()));
+            setCrossAxisExtent(std::max(crossAxisExtent(), crossAxisOffset - flowAwareBorderBefore() - flowAwarePaddingBefore() + crossAxisBorderAndPaddingExtent() + crossAxisMarginExtentForChild(child) + childCrossAxisExtent + crossAxisScrollbarExtent()));
+        maxChildCrossAxisExtent = std::max(maxChildCrossAxisExtent, childCrossAxisExtent + crossAxisMarginExtentForChild(child));
 
         mainAxisOffset += flowAwareMarginStartForChild(child);
 
@@ -771,13 +789,16 @@ void RenderFlexibleBox::layoutAndPlaceChildren(const OrderedFlexItemList& childr
         // We have to do an extra pass for column-reverse to reposition the flex items since the start depends
         // on the height of the flexbox, which we only know after we've positioned all the flex items.
         computeLogicalHeight();
-        layoutColumnReverse(children, childSizes, availableFreeSpace);
+        layoutColumnReverse(children, childSizes, crossAxisOffset, availableFreeSpace);
     }
 
-    alignChildren(children, maxAscent);
+    LayoutUnit lineCrossAxisExtent = isMultiline() ? maxChildCrossAxisExtent : crossAxisContentExtent();
+    alignChildren(children, lineCrossAxisExtent, maxAscent);
+
+    crossAxisOffset += lineCrossAxisExtent;
 }
 
-void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace)
+void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace)
 {
     // This is similar to the logic in layoutAndPlaceChildren, except we place the children
     // starting from the end of the flexbox. We also don't need to layout anything since we're
@@ -786,7 +807,6 @@ void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children,
     mainAxisOffset -= initialPackingOffset(availableFreeSpace, style()->flexPack(), childSizes.size());
     mainAxisOffset -= isHorizontalFlow() ? verticalScrollbarWidth() : horizontalScrollbarHeight();
 
-    LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
     for (size_t i = 0; i < children.size(); ++i) {
         RenderBox* child = children[i];
         if (child->isPositioned()) {
@@ -819,7 +839,7 @@ void RenderFlexibleBox::adjustAlignmentForChild(RenderBox* child, LayoutUnit del
         child->repaintDuringLayoutIfMoved(oldRect);
 }
 
-void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, LayoutUnit maxAscent)
+void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, LayoutUnit lineCrossAxisExtent, LayoutUnit maxAscent)
 {
     for (size_t i = 0; i < children.size(); ++i) {
         RenderBox* child = children[i];
@@ -830,7 +850,7 @@ void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, Layou
         case AlignStretch: {
             if (!isColumnFlow() && child->style()->logicalHeight().isAuto()) {
                 LayoutUnit logicalHeightBefore = child->logicalHeight();
-                LayoutUnit stretchedLogicalHeight = child->logicalHeight() + RenderFlexibleBox::availableAlignmentSpaceForChild(child);
+                LayoutUnit stretchedLogicalHeight = child->logicalHeight() + availableAlignmentSpaceForChild(lineCrossAxisExtent, child);
                 child->setLogicalHeight(stretchedLogicalHeight);
                 child->computeLogicalHeight();
 
@@ -840,16 +860,22 @@ void RenderFlexibleBox::alignChildren(const OrderedFlexItemList& children, Layou
                     child->setChildNeedsLayout(true);
                     child->layoutIfNeeded();
                 }
+            } else if (isColumnFlow() && child->style()->logicalWidth().isAuto() && isMultiline()) {
+                // FIXME: Handle min-width and max-width.
+                LayoutUnit childWidth = lineCrossAxisExtent - crossAxisMarginExtentForChild(child);
+                child->setOverrideWidth(std::max(0, childWidth));
+                child->setChildNeedsLayout(true);
+                child->layoutIfNeeded();
             }
             break;
         }
         case AlignStart:
             break;
         case AlignEnd:
-            adjustAlignmentForChild(child, RenderFlexibleBox::availableAlignmentSpaceForChild(child));
+            adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
             break;
         case AlignCenter:
-            adjustAlignmentForChild(child, RenderFlexibleBox::availableAlignmentSpaceForChild(child) / 2);
+            adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2);
             break;
         case AlignBaseline: {
             LayoutUnit ascent = marginBoxAscent(child);
index ca5d58a..9fb678a 100644 (file)
@@ -59,6 +59,7 @@ private:
     bool hasOrthogonalFlow(RenderBox* child) const;
     bool isColumnFlow() const;
     bool isLeftToRightFlow() const;
+    bool isMultiline() const;
     Length crossAxisLength() const;
     Length mainAxisLengthForChild(RenderBox* child) const;
     void setCrossAxisExtent(LayoutUnit);
@@ -95,17 +96,17 @@ private:
     float positiveFlexForChild(RenderBox* child) const;
     float negativeFlexForChild(RenderBox* child) const;
 
-    LayoutUnit availableAlignmentSpaceForChild(RenderBox*);
+    LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox*);
     LayoutUnit marginBoxAscent(RenderBox*);
 
     void computeMainAxisPreferredSizes(bool relayoutChildren, FlexOrderHashSet&);
-    void computeFlexOrder(FlexOrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
+    bool computeNextFlexLine(FlexOrderIterator&, OrderedFlexItemList& orderedChildren, LayoutUnit& preferredMainAxisExtent, float& totalPositiveFlexibility, float& totalNegativeFlexibility);
     bool runFreeSpaceAllocationAlgorithm(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalNegativeFlexibility, InflexibleFlexItemSize&, WTF::Vector<LayoutUnit>& childSizes);
     void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
     void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset);
-    void layoutAndPlaceChildren(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
-    void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
-    void alignChildren(const OrderedFlexItemList&, LayoutUnit maxAscent);
+    void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace);
+    void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
+    void alignChildren(const OrderedFlexItemList&, LayoutUnit lineCrossAxisExtent, LayoutUnit maxAscent);
     void flipForRightToLeftColumn(FlexOrderIterator&);
 };