Need to implement flex-line-pack
authortony@chromium.org <tony@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Mar 2012 17:16:39 +0000 (17:16 +0000)
committertony@chromium.org <tony@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Mar 2012 17:16:39 +0000 (17:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=70794

Reviewed by Ojan Vafai.

Source/WebCore:

Tests: css3/flexbox/multiline-line-pack-horizontal-column.html
       css3/flexbox/multiline-line-pack.html

* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::repositionLogicalHeightDependentFlexItems):
(WebCore::initialLinePackingOffset): Similar to initialPackingOffset.
(WebCore):
(WebCore::linePackingSpaceBetweenChildren): Similar to packingSpaceBetweenChildren.
(WebCore::RenderFlexibleBox::packFlexLines): Move lines based on flex-line-pack.
    Note that we don't need to relayout on stretch because
    alignChildren will do that for us (only auto size needs stretching).
(WebCore::RenderFlexibleBox::flipForWrapReverse): Pull out the initial
    cross axis offset before calling packFlexLines because we can
    move the the line contexts.
* rendering/RenderFlexibleBox.h:

LayoutTests:

Updated the old multiline tests to have -webkit-flex-line-pack: start,
which was the previous default behavior. The correct default behavior
is stretch.

* css3/flexbox/multiline-align.html:
* css3/flexbox/multiline-column-auto.html:
* css3/flexbox/multiline-line-pack-expected.txt: Added.
* css3/flexbox/multiline-line-pack-horizontal-column-expected.txt: Added.
* css3/flexbox/multiline-line-pack-horizontal-column.html: Added.
* css3/flexbox/multiline-line-pack.html: Added.
* css3/flexbox/multiline-pack.html:
* css3/flexbox/multiline-reverse-wrap-overflow.html:
* css3/flexbox/multiline-shrink-to-fit.html:
* css3/flexbox/multiline.html:

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/flexbox/multiline-align.html
LayoutTests/css3/flexbox/multiline-column-auto.html
LayoutTests/css3/flexbox/multiline-line-pack-expected.txt [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline-line-pack-horizontal-column-expected.txt [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline-line-pack-horizontal-column.html [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline-line-pack.html [new file with mode: 0644]
LayoutTests/css3/flexbox/multiline-pack.html
LayoutTests/css3/flexbox/multiline-reverse-wrap-overflow.html
LayoutTests/css3/flexbox/multiline-shrink-to-fit.html
LayoutTests/css3/flexbox/multiline.html
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderFlexibleBox.h

index b2d3736..8b8c1d0 100644 (file)
@@ -1,3 +1,25 @@
+2012-03-29  Tony Chang  <tony@chromium.org>
+
+        Need to implement flex-line-pack
+        https://bugs.webkit.org/show_bug.cgi?id=70794
+
+        Reviewed by Ojan Vafai.
+
+        Updated the old multiline tests to have -webkit-flex-line-pack: start,
+        which was the previous default behavior. The correct default behavior
+        is stretch.
+
+        * css3/flexbox/multiline-align.html:
+        * css3/flexbox/multiline-column-auto.html:
+        * css3/flexbox/multiline-line-pack-expected.txt: Added.
+        * css3/flexbox/multiline-line-pack-horizontal-column-expected.txt: Added.
+        * css3/flexbox/multiline-line-pack-horizontal-column.html: Added.
+        * css3/flexbox/multiline-line-pack.html: Added.
+        * css3/flexbox/multiline-pack.html:
+        * css3/flexbox/multiline-reverse-wrap-overflow.html:
+        * css3/flexbox/multiline-shrink-to-fit.html:
+        * css3/flexbox/multiline.html:
+
 2012-03-29  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         [Qt] Unreviewed gardening after r112514. Fix the accidental r112532 fix.
index dd55386..1476fb9 100644 (file)
@@ -6,6 +6,7 @@
     display: -webkit-flexbox;
     background-color: grey;
     max-width: 600px;
+    -webkit-flex-line-pack: start;
 }
 .title {
     margin-top: 1em;
index 3f9344d..0c5a52a 100644 (file)
@@ -7,6 +7,7 @@
     position: relative;
     -webkit-flex-flow: column wrap;
     margin-top: 20px;
+    -webkit-flex-line-pack: start;
 }
 .flexbox > div {
     border: 0;
diff --git a/LayoutTests/css3/flexbox/multiline-line-pack-expected.txt b/LayoutTests/css3/flexbox/multiline-line-pack-expected.txt
new file mode 100644 (file)
index 0000000..c086634
--- /dev/null
@@ -0,0 +1,38 @@
+Test to make sure that flex-line-pack works properly.
+
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
diff --git a/LayoutTests/css3/flexbox/multiline-line-pack-horizontal-column-expected.txt b/LayoutTests/css3/flexbox/multiline-line-pack-horizontal-column-expected.txt
new file mode 100644 (file)
index 0000000..8a6086d
--- /dev/null
@@ -0,0 +1,192 @@
+horizontal-tb ltr column wrap line-pack-start
+PASS
+horizontal-tb ltr column wrap line-pack-end
+PASS
+horizontal-tb ltr column wrap line-pack-center
+PASS
+horizontal-tb ltr column wrap line-pack-justify
+PASS
+horizontal-tb ltr column wrap line-pack-distribute
+PASS
+horizontal-tb ltr column wrap line-pack-stretch
+PASS
+horizontal-tb ltr column wrap-reverse line-pack-start
+PASS
+horizontal-tb ltr column wrap-reverse line-pack-end
+PASS
+horizontal-tb ltr column wrap-reverse line-pack-center
+PASS
+horizontal-tb ltr column wrap-reverse line-pack-justify
+PASS
+horizontal-tb ltr column wrap-reverse line-pack-distribute
+PASS
+horizontal-tb ltr column wrap-reverse line-pack-stretch
+PASS
+horizontal-tb rtl column wrap line-pack-start
+PASS
+horizontal-tb rtl column wrap line-pack-end
+PASS
+horizontal-tb rtl column wrap line-pack-center
+PASS
+horizontal-tb rtl column wrap line-pack-justify
+PASS
+horizontal-tb rtl column wrap line-pack-distribute
+PASS
+horizontal-tb rtl column wrap line-pack-stretch
+PASS
+horizontal-tb rtl column wrap-reverse line-pack-start
+PASS
+horizontal-tb rtl column wrap-reverse line-pack-end
+PASS
+horizontal-tb rtl column wrap-reverse line-pack-center
+PASS
+horizontal-tb rtl column wrap-reverse line-pack-justify
+PASS
+horizontal-tb rtl column wrap-reverse line-pack-distribute
+PASS
+horizontal-tb rtl column wrap-reverse line-pack-stretch
+PASS
+horizontal-tb ltr column-reverse wrap line-pack-start
+PASS
+horizontal-tb ltr column-reverse wrap line-pack-end
+PASS
+horizontal-tb ltr column-reverse wrap line-pack-center
+PASS
+horizontal-tb ltr column-reverse wrap line-pack-justify
+PASS
+horizontal-tb ltr column-reverse wrap line-pack-distribute
+PASS
+horizontal-tb ltr column-reverse wrap line-pack-stretch
+PASS
+horizontal-tb ltr column-reverse wrap-reverse line-pack-start
+PASS
+horizontal-tb ltr column-reverse wrap-reverse line-pack-end
+PASS
+horizontal-tb ltr column-reverse wrap-reverse line-pack-center
+PASS
+horizontal-tb ltr column-reverse wrap-reverse line-pack-justify
+PASS
+horizontal-tb ltr column-reverse wrap-reverse line-pack-distribute
+PASS
+horizontal-tb ltr column-reverse wrap-reverse line-pack-stretch
+PASS
+horizontal-tb rtl column-reverse wrap line-pack-start
+PASS
+horizontal-tb rtl column-reverse wrap line-pack-end
+PASS
+horizontal-tb rtl column-reverse wrap line-pack-center
+PASS
+horizontal-tb rtl column-reverse wrap line-pack-justify
+PASS
+horizontal-tb rtl column-reverse wrap line-pack-distribute
+PASS
+horizontal-tb rtl column-reverse wrap line-pack-stretch
+PASS
+horizontal-tb rtl column-reverse wrap-reverse line-pack-start
+PASS
+horizontal-tb rtl column-reverse wrap-reverse line-pack-end
+PASS
+horizontal-tb rtl column-reverse wrap-reverse line-pack-center
+PASS
+horizontal-tb rtl column-reverse wrap-reverse line-pack-justify
+PASS
+horizontal-tb rtl column-reverse wrap-reverse line-pack-distribute
+PASS
+horizontal-tb rtl column-reverse wrap-reverse line-pack-stretch
+PASS
+horizontal-bt ltr column wrap line-pack-start
+PASS
+horizontal-bt ltr column wrap line-pack-end
+PASS
+horizontal-bt ltr column wrap line-pack-center
+PASS
+horizontal-bt ltr column wrap line-pack-justify
+PASS
+horizontal-bt ltr column wrap line-pack-distribute
+PASS
+horizontal-bt ltr column wrap line-pack-stretch
+PASS
+horizontal-bt ltr column wrap-reverse line-pack-start
+PASS
+horizontal-bt ltr column wrap-reverse line-pack-end
+PASS
+horizontal-bt ltr column wrap-reverse line-pack-center
+PASS
+horizontal-bt ltr column wrap-reverse line-pack-justify
+PASS
+horizontal-bt ltr column wrap-reverse line-pack-distribute
+PASS
+horizontal-bt ltr column wrap-reverse line-pack-stretch
+PASS
+horizontal-bt rtl column wrap line-pack-start
+PASS
+horizontal-bt rtl column wrap line-pack-end
+PASS
+horizontal-bt rtl column wrap line-pack-center
+PASS
+horizontal-bt rtl column wrap line-pack-justify
+PASS
+horizontal-bt rtl column wrap line-pack-distribute
+PASS
+horizontal-bt rtl column wrap line-pack-stretch
+PASS
+horizontal-bt rtl column wrap-reverse line-pack-start
+PASS
+horizontal-bt rtl column wrap-reverse line-pack-end
+PASS
+horizontal-bt rtl column wrap-reverse line-pack-center
+PASS
+horizontal-bt rtl column wrap-reverse line-pack-justify
+PASS
+horizontal-bt rtl column wrap-reverse line-pack-distribute
+PASS
+horizontal-bt rtl column wrap-reverse line-pack-stretch
+PASS
+horizontal-bt ltr column-reverse wrap line-pack-start
+PASS
+horizontal-bt ltr column-reverse wrap line-pack-end
+PASS
+horizontal-bt ltr column-reverse wrap line-pack-center
+PASS
+horizontal-bt ltr column-reverse wrap line-pack-justify
+PASS
+horizontal-bt ltr column-reverse wrap line-pack-distribute
+PASS
+horizontal-bt ltr column-reverse wrap line-pack-stretch
+PASS
+horizontal-bt ltr column-reverse wrap-reverse line-pack-start
+PASS
+horizontal-bt ltr column-reverse wrap-reverse line-pack-end
+PASS
+horizontal-bt ltr column-reverse wrap-reverse line-pack-center
+PASS
+horizontal-bt ltr column-reverse wrap-reverse line-pack-justify
+PASS
+horizontal-bt ltr column-reverse wrap-reverse line-pack-distribute
+PASS
+horizontal-bt ltr column-reverse wrap-reverse line-pack-stretch
+PASS
+horizontal-bt rtl column-reverse wrap line-pack-start
+PASS
+horizontal-bt rtl column-reverse wrap line-pack-end
+PASS
+horizontal-bt rtl column-reverse wrap line-pack-center
+PASS
+horizontal-bt rtl column-reverse wrap line-pack-justify
+PASS
+horizontal-bt rtl column-reverse wrap line-pack-distribute
+PASS
+horizontal-bt rtl column-reverse wrap line-pack-stretch
+PASS
+horizontal-bt rtl column-reverse wrap-reverse line-pack-start
+PASS
+horizontal-bt rtl column-reverse wrap-reverse line-pack-end
+PASS
+horizontal-bt rtl column-reverse wrap-reverse line-pack-center
+PASS
+horizontal-bt rtl column-reverse wrap-reverse line-pack-justify
+PASS
+horizontal-bt rtl column-reverse wrap-reverse line-pack-distribute
+PASS
+horizontal-bt rtl column-reverse wrap-reverse line-pack-stretch
+PASS
diff --git a/LayoutTests/css3/flexbox/multiline-line-pack-horizontal-column.html b/LayoutTests/css3/flexbox/multiline-line-pack-horizontal-column.html
new file mode 100644 (file)
index 0000000..2f26297
--- /dev/null
@@ -0,0 +1,291 @@
+<!DOCTYPE html>
+<html>
+<style>
+.flexbox {
+    position: relative;
+    display: -webkit-flexbox;
+    background-color: grey;
+    width: 600px;
+    height: 20px;
+}
+.title {
+    margin-top: 1em;
+}
+.ltr {
+    direction: ltr;
+}
+.rtl {
+    direction: rtl;
+}
+.horizontal-tb {
+    -webkit-writing-mode: horizontal-tb;
+}
+.horizontal-bt {
+    -webkit-writing-mode: horizontal-bt;
+}
+.column {
+    -webkit-flex-flow: column;
+}
+.column-reverse {
+    -webkit-flex-flow: column-reverse;
+}
+.wrap {
+    -webkit-flex-wrap: wrap;
+}
+.wrap-reverse {
+    -webkit-flex-wrap: wrap-reverse;
+}
+.line-pack-start {
+    -webkit-flex-line-pack: start;
+}
+.line-pack-end {
+    -webkit-flex-line-pack: end;
+}
+.line-pack-center {
+    -webkit-flex-line-pack: center;
+}
+.line-pack-justify {
+    -webkit-flex-line-pack: justify;
+}
+.line-pack-distribute {
+    -webkit-flex-line-pack: distribute;
+}
+.line-pack-stretch {
+    -webkit-flex-line-pack: stretch;
+}
+.flexbox > :nth-child(1) {
+    background-color: blue;
+}
+.flexbox > :nth-child(2) {
+    background-color: green;
+}
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<script src="resources/flexbox.js"></script>
+<body onload="checkFlexBoxen()">
+
+<script>
+var expectations = {
+    'horizontal-tb': {
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+                'wrap-reverse': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+                'wrap-reverse': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+            },
+        },
+        // Same as column.
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+                'wrap-reverse': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+                'wrap-reverse': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+            },
+        },
+    },
+    'horizontal-bt': {
+        // Same as horizontal-tb.
+        'column': {
+            'ltr': {
+                'wrap': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+                'wrap-reverse': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+                'wrap-reverse': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+            },
+        },
+        'column-reverse': {
+            'ltr': {
+                'wrap': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+                'wrap-reverse': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+            },
+            'rtl': {
+                'wrap': {
+                    'start': [500, 400],
+                    'end': [100, 0],
+                    'center': [300, 200],
+                    'justify': [500, 0],
+                    'distribute': [400, 100],
+                    'stretch': [300, 0],
+                },
+                'wrap-reverse': {
+                    'start': [0, 100],
+                    'end': [400, 500],
+                    'center': [200, 300],
+                    'justify': [0, 500],
+                    'distribute': [100, 400],
+                    'stretch': [0, 300],
+                },
+            },
+        },
+    },
+};
+
+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, preferredSize, linePack, expected_x_offset)
+{
+    var child = document.createElement('div');
+    child.setAttribute('style', 'height: -webkit-flex(1 ' + preferredSize + 'px);'
+        + 'min-width: 100px');
+
+    child.setAttribute("data-expected-width", linePack == "stretch" ? "300" : "100");
+    child.setAttribute("data-expected-height", "20");
+    child.setAttribute("data-offset-y", "0");
+    child.setAttribute("data-offset-x", expected_x_offset);
+
+    flexbox.appendChild(child);
+}
+
+var writingModes = ['horizontal-tb', 'horizontal-bt'];
+var flexDirections = ['column', 'column-reverse'];
+var directions = ['ltr', 'rtl'];
+var wraps = ['wrap', 'wrap-reverse'];
+var linePacks = ['start', 'end', 'center', 'justify', 'distribute', 'stretch'];
+
+writingModes.forEach(function(writingMode) {
+    flexDirections.forEach(function(flexDirection) {
+        directions.forEach(function(direction) {
+            wraps.forEach(function(wrap) {
+                linePacks.forEach(function(linePack) {
+                    var flexboxClassName = writingMode + ' ' + direction + ' ' + flexDirection + ' ' + wrap + ' line-pack-' + linePack;
+                    var title = document.createElement('div');
+                    title.className = 'title';
+                    title.innerHTML = flexboxClassName;
+                    document.body.appendChild(title);
+
+                    var mainAxis = 'height';
+                    var crossAxis = 'width';
+
+                    var flexbox = document.createElement('div');
+                    flexbox.className = 'flexbox ' + flexboxClassName;
+                    flexbox.setAttribute("data-expected-width", "600");
+                    flexbox.setAttribute("data-expected-height", "20");
+
+                    var testExpectations = expectations[writingMode][flexDirection][direction][wrap][linePack];
+                    addChild(flexbox, 20, linePack, testExpectations[0]);
+                    addChild(flexbox, 5, linePack, testExpectations[1]);
+
+                    document.body.appendChild(flexbox);
+                })
+            })
+        })
+    })
+})
+</script>
+</body>
+</html>
diff --git a/LayoutTests/css3/flexbox/multiline-line-pack.html b/LayoutTests/css3/flexbox/multiline-line-pack.html
new file mode 100644 (file)
index 0000000..13329a1
--- /dev/null
@@ -0,0 +1,292 @@
+<!DOCTYPE html>
+<html>
+<style>
+.flexbox {
+    display: -webkit-flexbox;
+    background-color: #aaa;
+    position: relative;
+    -webkit-flex-wrap: wrap;
+}
+
+.horizontal {
+    width: 200px;
+    height: 120px;
+}
+.horizontal > div {
+    min-height: 20px;
+}
+.horizontal > :nth-child(1) {
+    width: 100px;
+    min-height: 10px;
+}
+.horizontal > :nth-child(2) {
+    width: 100px;
+}
+.horizontal > :nth-child(3) {
+    width: 200px;
+}
+.horizontal > :nth-child(4) {
+    width: 50px;
+}
+
+.vertical-rl {
+    -webkit-writing-mode: vertical-rl;
+    width: 120px;
+    height: 20px;
+}
+.vertical-rl > div {
+    min-width: 20px;
+}
+.vertical-rl > :nth-child(1) {
+    height: 10px;
+    min-width: 10px;
+}
+.vertical-rl > :nth-child(2) {
+    height: 10px;
+}
+.vertical-rl > :nth-child(3) {
+    height: 20px;
+}
+.vertical-rl > :nth-child(4) {
+    height: 5px;
+}
+
+.flexbox :nth-child(1) {
+    background-color: lightblue;
+}
+.flexbox :nth-child(2) {
+    background-color: lightgreen;
+}
+.flexbox :nth-child(3) {
+    background-color: pink;
+}
+.flexbox :nth-child(4) {
+    background-color: yellow;
+}
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<script src="resources/flexbox.js"></script>
+<body onload="checkFlexBoxen()">
+<p>Test to make sure that flex-line-pack works properly.</p>
+
+<div data-expected-height="120" class="flexbox horizontal">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="40"></div>
+  <div data-offset-x="100" data-offset-y="0" data-expected-height="40"></div>
+  <div data-offset-x="0" data-offset-y="40" data-expected-height="40"></div>
+  <div data-offset-x="0" data-offset-y="80" data-expected-height="40"></div>
+</div>
+
+<div data-expected-height="120" class="flexbox horizontal" style="-webkit-flex-line-pack: start">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="20" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="40" data-expected-height="20"></div>
+</div>
+
+<div data-expected-height="120" class="flexbox horizontal" style="-webkit-flex-line-pack: end">
+  <div data-offset-x="0" data-offset-y="60" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="60" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="80" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="100" data-expected-height="20"></div>
+</div>
+
+<div data-expected-height="120" class="flexbox horizontal" style="-webkit-flex-line-pack: center">
+  <div data-offset-x="0" data-offset-y="30" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="30" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="50" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="70" data-expected-height="20"></div>
+</div>
+
+<div data-expected-height="120" class="flexbox horizontal" style="-webkit-flex-line-pack: justify">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="50" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="100" data-expected-height="20"></div>
+</div>
+
+<div data-expected-height="120" class="flexbox horizontal" style="-webkit-flex-line-pack: distribute">
+  <div data-offset-x="0" data-offset-y="10" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="10" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="50" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="90" data-expected-height="20"></div>
+</div>
+
+<div data-expected-height="120" class="flexbox horizontal" style="-webkit-flex-line-pack: stretch">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="40"></div>
+  <div data-offset-x="100" data-offset-y="0" data-expected-height="40"></div>
+  <div data-offset-x="0" data-offset-y="40" data-expected-height="40"></div>
+  <div data-offset-x="0" data-offset-y="80" data-expected-height="40"></div>
+</div>
+
+<!-- Negative overflow goes out the top. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: end; height: 30px">
+  <div data-offset-x="0" data-offset-y="-30" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="-30" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="-10" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="10" data-expected-height="20"></div>
+</div>
+
+<!-- If we overflow, we should true center. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: center; height: 30px">
+  <div data-offset-x="0" data-offset-y="-15" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="-15" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="5" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="25" data-expected-height="20"></div>
+</div>
+
+<!-- If we overflow, we should be the same as start. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: justify; height: 30px">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="20" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="40" data-expected-height="20"></div>
+</div>
+
+<!-- If we overflow, we should true center. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: distribute; height: 30px">
+  <div data-offset-x="0" data-offset-y="-15" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="-15" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="5" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="25" data-expected-height="20"></div>
+</div>
+
+<!-- Stretch should only grow, not shrink. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: stretch; height: 30px">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="100" data-offset-y="0" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="20" data-expected-height="20"></div>
+  <div data-offset-x="0" data-offset-y="40" data-expected-height="20"></div>
+</div>
+
+<!-- 0 lines should not crash. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: justify; height: 30px">
+</div>
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: distribute; height: 30px">
+</div>
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: stretch; height: 30px">
+</div>
+
+<!-- 1 line should not crash. -->
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: justify; height: 30px">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="10"></div>
+</div>
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: distribute; height: 30px">
+  <div data-offset-x="0" data-offset-y="10" data-expected-height="10"></div>
+</div>
+<div data-expected-height="30" class="flexbox horizontal" style="-webkit-flex-line-pack: stretch; height: 30px">
+  <div data-offset-x="0" data-offset-y="0" data-expected-height="30"></div>
+</div>
+
+
+<div data-expected-width="120" class="flexbox vertical-rl">
+  <div data-offset-x="80" data-offset-y="0" data-expected-width="40"></div>
+  <div data-offset-x="80" data-offset-y="10" data-expected-width="40"></div>
+  <div data-offset-x="40" data-offset-y="0" data-expected-width="40"></div>
+  <div data-offset-x="0" data-offset-y="0" data-expected-width="40"></div>
+</div>
+
+<div data-expected-width="120" class="flexbox vertical-rl" style="-webkit-flex-line-pack: start">
+  <div data-offset-x="100" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="100" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="80" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="60" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<div data-expected-width="120" class="flexbox vertical-rl" style="-webkit-flex-line-pack: end">
+  <div data-offset-x="40" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="40" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="20" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="0" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<div data-expected-width="120" class="flexbox vertical-rl" style="-webkit-flex-line-pack: center">
+  <div data-offset-x="70" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="70" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="50" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="30" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<div data-expected-width="120" class="flexbox vertical-rl" style="-webkit-flex-line-pack: justify">
+  <div data-offset-x="100" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="100" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="50" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="0" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<div data-expected-width="120" class="flexbox vertical-rl" style="-webkit-flex-line-pack: distribute">
+  <div data-offset-x="90" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="90" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="50" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="10" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<div data-expected-width="120" class="flexbox vertical-rl" style="-webkit-flex-line-pack: stretch">
+  <div data-offset-x="80" data-offset-y="0" data-expected-width="40"></div>
+  <div data-offset-x="80" data-offset-y="10" data-expected-width="40"></div>
+  <div data-offset-x="40" data-offset-y="0" data-expected-width="40"></div>
+  <div data-offset-x="0" data-offset-y="0" data-expected-width="40"></div>
+</div>
+
+<!-- Negative overflow goes out the right. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: end; width: 30px;">
+  <div data-offset-x="40" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="40" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="20" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="0" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<!-- If we overflow, we should true center. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: center; width: 30px;">
+  <div data-offset-x="25" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="25" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="5" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="-15" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<!-- If we overflow, we should be the same as start. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: justify; width: 30px;">
+  <div data-offset-x="10" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="10" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="-10" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="-30" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<!-- If we overflow, we should true center. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: distribute; width: 30px;">
+  <div data-offset-x="25" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="25" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="5" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="-15" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<!-- Stretch should only grow, not shrink. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: stretch; width: 30px;">
+  <div data-offset-x="10" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="10" data-offset-y="10" data-expected-width="20"></div>
+  <div data-offset-x="-10" data-offset-y="0" data-expected-width="20"></div>
+  <div data-offset-x="-30" data-offset-y="0" data-expected-width="20"></div>
+</div>
+
+<!-- 0 lines should not crash. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: justify; width: 30px">
+</div>
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: distribute; width: 30px">
+</div>
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: stretch; width: 30px">
+</div>
+
+<!-- 1 line should not crash. -->
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: justify; width: 30px">
+  <div data-offset-x="20" data-offset-y="0" data-expected-width="10"></div>
+</div>
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: distribute; width: 30px">
+  <div data-offset-x="10" data-offset-y="0" data-expected-width="10"></div>
+</div>
+<div data-expected-width="30" class="flexbox vertical-rl" style="-webkit-flex-line-pack: stretch; width: 30px">
+  <div data-offset-x="0" data-offset-y="0" data-expected-width="30"></div>
+</div>
+</body>
+</html>
index f0a9d97..0de537d 100644 (file)
@@ -6,6 +6,7 @@
     display: -webkit-flexbox;
     background-color: grey;
     max-width: 100px;
+    -webkit-flex-line-pack: start;
 }
 .title {
     margin-top: 1em;
index a7fb75c..0cd1599 100644 (file)
@@ -7,6 +7,7 @@
     position: relative;
     -webkit-flex-wrap: wrap-reverse;
     margin-top: 20px;
+    -webkit-flex-line-pack: start;
 }
 .flexbox > div {
     border: 0;
index 05024ae..8638b8e 100644 (file)
@@ -8,6 +8,7 @@
     -webkit-flex-wrap: wrap;
     -webkit-flex-direction: column;
     float: left;
+    -webkit-flex-line-pack: start;
 }
 
 .flexbox :nth-child(1) {
index 5de8612..c4a8d7c 100644 (file)
@@ -6,6 +6,7 @@
     display: -webkit-flexbox;
     background-color: grey;
     max-width: 600px;
+    -webkit-flex-line-pack: start;
 }
 .title {
     margin-top: 1em;
     -webkit-flex-flow: column-reverse;
 }
 .wrap {
-  -webkit-flex-wrap: wrap;
+    -webkit-flex-wrap: wrap;
 }
 .wrap-reverse {
-  -webkit-flex-wrap: wrap-reverse;
+    -webkit-flex-wrap: wrap-reverse;
 }
 .flexbox > :nth-child(1) {
     background-color: #0f0;
index ad72453..ed2676e 100644 (file)
@@ -1,3 +1,26 @@
+2012-03-29  Tony Chang  <tony@chromium.org>
+
+        Need to implement flex-line-pack
+        https://bugs.webkit.org/show_bug.cgi?id=70794
+
+        Reviewed by Ojan Vafai.
+
+        Tests: css3/flexbox/multiline-line-pack-horizontal-column.html
+               css3/flexbox/multiline-line-pack.html
+
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::repositionLogicalHeightDependentFlexItems):
+        (WebCore::initialLinePackingOffset): Similar to initialPackingOffset.
+        (WebCore):
+        (WebCore::linePackingSpaceBetweenChildren): Similar to packingSpaceBetweenChildren.
+        (WebCore::RenderFlexibleBox::packFlexLines): Move lines based on flex-line-pack.
+            Note that we don't need to relayout on stretch because
+            alignChildren will do that for us (only auto size needs stretching).
+        (WebCore::RenderFlexibleBox::flipForWrapReverse): Pull out the initial
+            cross axis offset before calling packFlexLines because we can
+            move the the line contexts.
+        * rendering/RenderFlexibleBox.h:
+
 2012-03-29  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Web Inspector: SnippetsScriptMapping should process existing snippets on load.
index e39997a..d81801e 100644 (file)
@@ -296,6 +296,9 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit, BlockLayo
 
 void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(FlexOrderIterator& iterator, WTF::Vector<LineContext>& lineContexts, LayoutUnit& oldClientAfterEdge)
 {
+    LayoutUnit crossAxisStartEdge = lineContexts.isEmpty() ? 0 : lineContexts[0].crossAxisOffset;
+    packFlexLines(iterator, lineContexts);
+
     // If we have a single line flexbox, the line height is all the available space.
     // For flex-direction: row, this means we need to use the height, so we do this after calling computeLogicalHeight.
     if (!isMultiline() && lineContexts.size() == 1)
@@ -305,7 +308,7 @@ void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(FlexOrderItera
     if (style()->flexWrap() == FlexWrapReverse) {
         if (isHorizontalFlow())
             oldClientAfterEdge = clientLogicalBottom();
-        flipForWrapReverse(iterator, lineContexts);
+        flipForWrapReverse(iterator, lineContexts, crossAxisStartEdge);
     }
 
     // direction:rtl + flex-direction:column means the cross-axis direction is flipped.
@@ -973,6 +976,55 @@ void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children,
     }
 }
 
+static LayoutUnit initialLinePackingOffset(LayoutUnit availableFreeSpace, EFlexLinePack linePack, size_t numberOfLines)
+{
+    if (linePack == LinePackEnd)
+        return availableFreeSpace;
+    if (linePack == LinePackCenter)
+        return availableFreeSpace / 2;
+    if (linePack == LinePackDistribute) {
+        if (availableFreeSpace > 0 && numberOfLines)
+            return availableFreeSpace / (2 * numberOfLines);
+        if (availableFreeSpace < 0)
+            return availableFreeSpace / 2;
+    }
+    return 0;
+}
+
+static LayoutUnit linePackingSpaceBetweenChildren(LayoutUnit availableFreeSpace, EFlexLinePack linePack, size_t numberOfLines)
+{
+    if (availableFreeSpace > 0 && numberOfLines > 1) {
+        if (linePack == LinePackJustify)
+            return availableFreeSpace / (numberOfLines - 1);
+        if (linePack == LinePackDistribute || linePack == LinePackStretch)
+            return availableFreeSpace / numberOfLines;
+    }
+    return 0;
+}
+
+void RenderFlexibleBox::packFlexLines(FlexOrderIterator& iterator, WTF::Vector<LineContext>& lineContexts)
+{
+    if (!isMultiline() || style()->flexLinePack() == LinePackStart)
+        return;
+
+    LayoutUnit availableCrossAxisSpace = crossAxisContentExtent();
+    for (size_t i = 0; i < lineContexts.size(); ++i)
+        availableCrossAxisSpace -= lineContexts[i].crossAxisExtent;
+
+    RenderBox* child = iterator.first();
+    LayoutUnit lineOffset = initialLinePackingOffset(availableCrossAxisSpace, style()->flexLinePack(), lineContexts.size());
+    for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
+        lineContexts[lineNumber].crossAxisOffset += lineOffset;
+        for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next())
+            adjustAlignmentForChild(child, lineOffset);
+
+        if (style()->flexLinePack() == LinePackStretch && availableCrossAxisSpace > 0)
+            lineContexts[lineNumber].crossAxisExtent += availableCrossAxisSpace / lineContexts.size();
+
+        lineOffset += linePackingSpaceBetweenChildren(availableCrossAxisSpace, style()->flexLinePack(), lineContexts.size());
+    }
+}
+
 void RenderFlexibleBox::adjustAlignmentForChild(RenderBox* child, LayoutUnit delta)
 {
     LayoutRect oldRect = child->frameRect();
@@ -1087,7 +1139,7 @@ void RenderFlexibleBox::flipForRightToLeftColumn(FlexOrderIterator& iterator)
     }
 }
 
-void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts)
+void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WTF::Vector<LineContext>& lineContexts, LayoutUnit crossAxisStartEdge)
 {
     LayoutUnit contentExtent = crossAxisContentExtent();
     RenderBox* child = iterator.first();
@@ -1096,7 +1148,7 @@ void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WT
             ASSERT(child);
             LayoutPoint location = flowAwareLocationForChild(child);
             LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent;
-            LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - lineContexts[0].crossAxisOffset;
+            LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
             LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxisExtent;
             location.setY(location.y() + newOffset - originalOffset);
 
index 19ee93c..b4ec781 100644 (file)
@@ -122,10 +122,11 @@ private:
     void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset);
     void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, WTF::Vector<LineContext>&);
     void layoutColumnReverse(const OrderedFlexItemList&, const WTF::Vector<LayoutUnit>& childSizes, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
+    void packFlexLines(FlexOrderIterator&, WTF::Vector<LineContext>&);
     void alignChildren(FlexOrderIterator&, const WTF::Vector<LineContext>&);
     void applyStretchAlignmentToChild(RenderBox*, LayoutUnit lineCrossAxisExtent);
     void flipForRightToLeftColumn(FlexOrderIterator&);
-    void flipForWrapReverse(FlexOrderIterator&, const WTF::Vector<LineContext>&);
+    void flipForWrapReverse(FlexOrderIterator&, const WTF::Vector<LineContext>&, LayoutUnit crossAxisStartEdge);
 };
 
 } // namespace WebCore