Absolute positioned elements in a relative positioned CSS3 Flexbox fail to display...
authorojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 May 2012 19:28:04 +0000 (19:28 +0000)
committerojan@chromium.org <ojan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 May 2012 19:28:04 +0000 (19:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=58453

Reviewed by Tony Chang.

Source/WebCore:

Test: css3/flexbox/align-absolute-child.html

* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::prepareChildForPositionedLayout):
(WebCore::RenderFlexibleBox::layoutAndPlaceChildren):
(WebCore::RenderFlexibleBox::adjustAlignmentForChild):
When adjusting positioned items, adjust their static position, not their location.
(WebCore::RenderFlexibleBox::flipForRightToLeftColumn):
(WebCore::RenderFlexibleBox::flipForWrapReverse):
* rendering/RenderFlexibleBox.h:

LayoutTests:

* css3/flexbox/align-absolute-child-expected.txt: Added.
* css3/flexbox/align-absolute-child.html: Added.
* css3/flexbox/position-absolute-child-expected.txt:
* css3/flexbox/position-absolute-child.html:

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

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

index ee2cf77..7a97771 100644 (file)
@@ -1,3 +1,15 @@
+2012-05-25  Ojan Vafai  <ojan@chromium.org>
+
+        Absolute positioned elements in a relative positioned CSS3 Flexbox fail to display properly
+        https://bugs.webkit.org/show_bug.cgi?id=58453
+
+        Reviewed by Tony Chang.
+
+        * css3/flexbox/align-absolute-child-expected.txt: Added.
+        * css3/flexbox/align-absolute-child.html: Added.
+        * css3/flexbox/position-absolute-child-expected.txt:
+        * css3/flexbox/position-absolute-child.html:
+
 2012-05-29  Jessie Berlin  <jberlin@apple.com>
 
         [Win] ~1/2 of all the iframe seamless tests fail
diff --git a/LayoutTests/css3/flexbox/align-absolute-child-expected.txt b/LayoutTests/css3/flexbox/align-absolute-child-expected.txt
new file mode 100644 (file)
index 0000000..c0629fc
--- /dev/null
@@ -0,0 +1,13 @@
+PASS beforePosition[key] is afterPosition[key]
+PASS beforePosition[key] is afterPosition[key]
+PASS beforePosition[key] is afterPosition[key]
+PASS beforePosition[key] is afterPosition[key]
+PASS beforePosition[key] is afterPosition[key]
+PASS beforePosition[key] is afterPosition[key]
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
+PASS
diff --git a/LayoutTests/css3/flexbox/align-absolute-child.html b/LayoutTests/css3/flexbox/align-absolute-child.html
new file mode 100644 (file)
index 0000000..e0d6ec7
--- /dev/null
@@ -0,0 +1,161 @@
+<style>
+body {
+    margin: 0;
+}
+.flexbox {
+    display: -webkit-flex;
+    background-color: green;
+    height: 100px;
+    width: 100px;
+    margin: 10px;
+}
+.align-center {
+    -webkit-flex-align: center;
+}
+.stretch {
+    -webkit-flex-align: stretch;
+}
+.relative {
+    position: relative;
+}
+.flexbox > div {
+    width: 20px;
+    height: 20px;
+}
+.absolute {
+    position: absolute;
+}
+#placed-absolute {
+    top: 20px;
+    left: 20px;
+}
+
+.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;
+}
+
+.rtl {
+    direction: rtl;
+}
+.ltr {
+    direction: ltr;
+}
+
+.wrap-reverse {
+    -webkit-flex-wrap: wrap-reverse;
+}
+
+.flexbox :nth-child(1) {
+    background-color: blue;
+}
+.flexbox :nth-child(2) {
+    background-color: yellow;
+}
+.flexbox :nth-child(3) {
+    background-color: salmon;
+}
+.flexbox :nth-child(4) {
+    background-color: grey;
+}
+.flexbox :nth-child(5) {
+    background-color: red;
+}
+.flexbox :nth-child(6) {
+    background-color: orange;
+}
+.flexbox :nth-child(7) {
+    background-color: purple;
+}
+</style>
+
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/flexbox.js"></script>
+
+<body onload="checkFlexBoxen()">
+
+<div class='flexbox relative align-center'>
+    <div id='placed-absolute' class='absolute' data-offset-x=20 data-offset-y=20></div>
+</div>
+
+<div class='flexbox relative align-center'>
+    <div data-offset-x=0 data-offset-y=40></div>
+    <div class='absolute' data-offset-x=20 data-offset-y=50></div>
+    <div data-offset-x=20 data-offset-y=40></div>
+    <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div>
+</div>
+
+<div class="relative">
+<div class='flexbox align-center'>
+    <div data-offset-x=10 data-offset-y=40></div>
+    <div class='absolute' data-offset-x=30 data-offset-y=50></div>
+    <div data-offset-x=30 data-offset-y=40></div>
+    <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div>
+</div>
+</div>
+
+<div class='flexbox relative column rtl'>
+    <div data-offset-x=80 data-offset-y=0></div>
+    <div class='absolute' data-offset-x=80 data-offset-y=20></div>
+    <div data-offset-x=80 data-offset-y=20></div>
+    <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div>
+</div>
+
+<div class="relative">
+<div class='flexbox wrap-reverse'>
+    <div style="width:90px" data-offset-x=10 data-offset-y=80></div>
+    <div class="absolute" data-offset-x=100 data-offset-y=100></div>
+    <div data-offset-x=10 data-offset-y=30></div>
+    <div class="absolute" data-offset-x=30 data-offset-y=50></div>
+    <div data-offset-x=30 data-offset-y=30></div>
+    <div class="absolute" data-offset-x=50 data-offset-y=50></div>
+    <div class="absolute" style="top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div>
+</div>
+</div>
+
+<div class='flexbox relative'>
+    <div style="margin: auto;" data-offset-x=40 data-offset-y=40></div>
+    <div class="absolute" style="margin: auto;" data-offset-x=100 data-offset-y=50></div>
+    <div class="absolute" style="margin: auto;" data-offset-x=100 data-offset-y=50></div>
+    <div class="absolute" style="margin: auto; top: 5px; left: 5px" data-offset-x=5 data-offset-y=5></div>
+</div>
+
+<div class='flexbox stretch relative'>
+    <div style="height: auto" data-offset-x=0 data-offset-y=0 data-expected-height=100></div>
+    <div class="absolute" style="height: auto" data-offset-x=20 data-offset-y=0 data-expected-height=0></div>
+    <div class="absolute" style="height: auto; top: 5px; left: 5px" data-offset-x=5 data-offset-y=5 data-expected-height=0></div>
+</div>
+
+
+<script>
+var absolute = document.getElementById('placed-absolute');
+var beforePosition = absolute.getBoundingClientRect();
+document.querySelector('.flexbox').style.height = '101px';
+var afterPosition = absolute.getBoundingClientRect();
+
+// Positioned element should not change position when the height of it's parent flexbox is changed.
+for (key in beforePosition)
+    shouldBe('beforePosition[key]', 'afterPosition[key]');
+</script>
+</body>
\ No newline at end of file
index 8d7fc4f..6957252 100644 (file)
@@ -5,6 +5,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb rtl row
 PASS
 PASS
@@ -12,6 +15,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb ltr column
 PASS
 PASS
@@ -19,6 +25,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb rtl column
 PASS
 PASS
@@ -26,6 +35,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb ltr row-reverse
 PASS
 PASS
@@ -33,6 +45,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb rtl row-reverse
 PASS
 PASS
@@ -40,6 +55,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb ltr column-reverse
 PASS
 PASS
@@ -47,6 +65,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-tb rtl column-reverse
 PASS
 PASS
@@ -54,6 +75,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt ltr row
 PASS
 PASS
@@ -61,6 +85,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt rtl row
 PASS
 PASS
@@ -68,6 +95,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt ltr column
 PASS
 PASS
@@ -75,6 +105,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt rtl column
 PASS
 PASS
@@ -82,6 +115,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt ltr row-reverse
 PASS
 PASS
@@ -89,6 +125,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt rtl row-reverse
 PASS
 PASS
@@ -96,6 +135,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt ltr column-reverse
 PASS
 PASS
@@ -103,6 +145,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 horizontal-bt rtl column-reverse
 PASS
 PASS
@@ -110,6 +155,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl ltr row
 PASS
 PASS
@@ -117,6 +165,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl rtl row
 PASS
 PASS
@@ -124,6 +175,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl ltr column
 PASS
 PASS
@@ -131,6 +185,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl rtl column
 PASS
 PASS
@@ -138,6 +195,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl ltr row-reverse
 PASS
 PASS
@@ -145,6 +205,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl rtl row-reverse
 PASS
 PASS
@@ -152,6 +215,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl ltr column-reverse
 PASS
 PASS
@@ -159,6 +225,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-rl rtl column-reverse
 PASS
 PASS
@@ -166,6 +235,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr ltr row
 PASS
 PASS
@@ -173,6 +245,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr rtl row
 PASS
 PASS
@@ -180,6 +255,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr ltr column
 PASS
 PASS
@@ -187,6 +265,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr rtl column
 PASS
 PASS
@@ -194,6 +275,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr ltr row-reverse
 PASS
 PASS
@@ -201,6 +285,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr rtl row-reverse
 PASS
 PASS
@@ -208,6 +295,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr ltr column-reverse
 PASS
 PASS
@@ -215,6 +305,9 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
 vertical-lr rtl column-reverse
 PASS
 PASS
@@ -222,3 +315,6 @@ PASS
 PASS
 PASS
 PASS
+PASS
+PASS
+PASS
index c640417..cedeb24 100644 (file)
@@ -91,6 +91,9 @@ var expectations = {
                 { offsets: [0, 260, 560] },
                 { offsets: [0, 300, 560] },
                 { offsets: [0, 300, 600] },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 90], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [600, 360, 0], sizes: [0, 240, 360] },
@@ -99,6 +102,9 @@ var expectations = {
                 { offsets: [580, 300, 0] },
                 { offsets: [560, 280, 0] },
                 { offsets: [560, 260, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, -30], crossAxisOffset: 50 },
             ],
         },
         column: {
@@ -109,6 +115,9 @@ var expectations = {
                 { offsets: [0, 20, 80] },
                 { offsets: [0, 60, 80] },
                 { offsets: [0, 60, 120] },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 90], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [0, 0, 48], sizes: [0, 48, 72] },
@@ -117,6 +126,9 @@ var expectations = {
                 { offsets: [0, 20, 80] },
                 { offsets: [0, 60, 80] },
                 { offsets: [0, 60, 120] },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 90], crossAxisOffset: 10 },
             ],
         },
         'row-reverse': {
@@ -127,6 +139,9 @@ var expectations = {
                 { offsets: [600, 300, 0] },
                 { offsets: [560, 300, 0] },
                 { offsets: [560, 260, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [0, 0, 240], sizes: [0, 240, 360] },
@@ -135,6 +150,9 @@ var expectations = {
                 { offsets: [-20, 260, 560] },
                 { offsets: [0, 280, 560] },
                 { offsets: [0, 300, 580] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
             ],
         },
         'column-reverse': {
@@ -145,6 +163,9 @@ var expectations = {
                 { offsets: [120, 60, 0] },
                 { offsets: [80, 60, 0] },
                 { offsets: [80, 20, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [120, 72, 0], sizes: [0, 48, 72] },
@@ -153,6 +174,9 @@ var expectations = {
                 { offsets: [120, 60, 0] },
                 { offsets: [80, 60, 0] },
                 { offsets: [80, 20, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
             ],
         },
     },
@@ -166,6 +190,9 @@ var expectations = {
                 { offsets: [0, 260, 560] },
                 { offsets: [0, 300, 560] },
                 { offsets: [0, 300, 600] },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 90], crossAxisOffset: 10 },
             ],
             rtl: [
                 { offsets: [600, 360, 0], sizes: [0, 240, 360] },
@@ -174,6 +201,9 @@ var expectations = {
                 { offsets: [580, 300, 0] },
                 { offsets: [560, 280, 0] },
                 { offsets: [560, 260, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, -30], crossAxisOffset: 10 },
             ],
         },
         // horizontal-bt flips the main axis direction so the offsets are different from horizontal-tb.
@@ -185,6 +215,9 @@ var expectations = {
                 { offsets: [100, 60, 0] },
                 { offsets: [80, 40, 0] },
                 { offsets: [80, 20, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, -30], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [120, 72, 0], sizes: [0, 48, 72] },
@@ -193,6 +226,9 @@ var expectations = {
                 { offsets: [100, 60, 0] },
                 { offsets: [80, 40, 0] },
                 { offsets: [80, 20, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, -30], crossAxisOffset: 10 },
             ],
         },
         'row-reverse': {
@@ -203,6 +239,9 @@ var expectations = {
                 { offsets: [600, 300, 0] },
                 { offsets: [560, 300, 0] },
                 { offsets: [560, 260, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
             ],
             rtl: [
                 { offsets: [0, 0, 240], sizes: [0, 240, 360] },
@@ -211,6 +250,9 @@ var expectations = {
                 { offsets: [-20, 260, 560] },
                 { offsets: [0, 280, 560] },
                 { offsets: [0, 300, 580] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
             ],
         },
         'column-reverse': {
@@ -221,6 +263,9 @@ var expectations = {
                 { offsets: [-20, 20, 80] },
                 { offsets: [0, 40, 80] },
                 { offsets: [0, 60, 100] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [0, 0, 48], sizes: [0, 48, 72] },
@@ -229,6 +274,9 @@ var expectations = {
                 { offsets: [-20, 20, 80] },
                 { offsets: [0, 40, 80] },
                 { offsets: [0, 60, 100] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
             ],
         },
     },
@@ -242,6 +290,9 @@ var expectations = {
                 { offsets: [0, 20, 80] },
                 { offsets: [0, 60, 80] },
                 { offsets: [0, 60, 120] },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 90], crossAxisOffset: 10 },
             ],
             rtl: [
                 { offsets: [120, 72, 0], sizes: [0, 48, 72] },
@@ -250,6 +301,9 @@ var expectations = {
                 { offsets: [100, 60, 0] },
                 { offsets: [80, 40, 0] },
                 { offsets: [80, 20, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, -30], crossAxisOffset: 10 },
             ],
         },
         column: {
@@ -261,6 +315,9 @@ var expectations = {
                 { offsets: [580, 300, 0] },
                 { offsets: [560, 280, 0] },
                 { offsets: [560, 260, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, -30], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [600, 360, 0], sizes: [0, 240, 360] },
@@ -269,6 +326,9 @@ var expectations = {
                 { offsets: [580, 300, 0] },
                 { offsets: [560, 280, 0] },
                 { offsets: [560, 260, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, -30], crossAxisOffset: 10 },
             ],
         },
         'row-reverse': {
@@ -279,6 +339,9 @@ var expectations = {
                 { offsets: [120, 60, 0] },
                 { offsets: [80, 60, 0] },
                 { offsets: [80, 20, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
             ],
             rtl: [
                 { offsets: [0, 0, 48], sizes: [0, 48, 72] },
@@ -287,6 +350,9 @@ var expectations = {
                 { offsets: [-20, 20, 80] },
                 { offsets: [0, 40, 80] },
                 { offsets: [0, 60, 100] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
             ],
         },
         'column-reverse': {
@@ -297,6 +363,9 @@ var expectations = {
                 { offsets: [-20, 260, 560] },
                 { offsets: [0, 280, 560] },
                 { offsets: [0, 300, 580] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [0, 0, 240], sizes: [0, 240, 360] },
@@ -305,6 +374,9 @@ var expectations = {
                 { offsets: [-20, 260, 560] },
                 { offsets: [0, 280, 560] },
                 { offsets: [0, 300, 580] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
             ],
         }
     },
@@ -318,6 +390,9 @@ var expectations = {
                 { offsets: [0, 20, 80] },
                 { offsets: [0, 60, 80] },
                 { offsets: [0, 60, 120] },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 90], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [120, 72, 0], sizes: [0, 48, 72] },
@@ -326,6 +401,9 @@ var expectations = {
                 { offsets: [100, 60, 0] },
                 { offsets: [80, 40, 0] },
                 { offsets: [80, 20, -20] },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, -30], crossAxisOffset: 50 },
             ],
         },
         column: {
@@ -337,6 +415,9 @@ var expectations = {
                 { offsets: [0, 260, 560] },
                 { offsets: [0, 300, 560] },
                 { offsets: [0, 300, 600] },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 90], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [0, 0, 240], sizes: [0, 240, 360] },
@@ -345,6 +426,9 @@ var expectations = {
                 { offsets: [0, 260, 560] },
                 { offsets: [0, 300, 560] },
                 { offsets: [0, 300, 600] },
+                { offsets: [10, 10, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 50], crossAxisOffset: 10 },
+                { offsets: [10, 50, 90], crossAxisOffset: 10 },
             ],
         },
         'row-reverse': {
@@ -355,6 +439,9 @@ var expectations = {
                 { offsets: [120, 60, 0] },
                 { offsets: [80, 60, 0] },
                 { offsets: [80, 20, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [0, 0, 48], sizes: [0, 48, 72] },
@@ -363,6 +450,9 @@ var expectations = {
                 { offsets: [-20, 20, 80] },
                 { offsets: [0, 40, 80] },
                 { offsets: [0, 60, 100] },
+                { offsets: [-30, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 10, 50], crossAxisOffset: 50 },
+                { offsets: [10, 50, 50], crossAxisOffset: 50 },
             ],
         },
         'column-reverse': {
@@ -373,6 +463,9 @@ var expectations = {
                 { offsets: [600, 300, 0] },
                 { offsets: [560, 300, 0] },
                 { offsets: [560, 260, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 50, 10], crossAxisOffset: 50 },
+                { offsets: [50, 10, 10], crossAxisOffset: 50 },
             ],
             rtl: [
                 { offsets: [600, 360, 0], sizes: [0, 240, 360] },
@@ -381,6 +474,9 @@ var expectations = {
                 { offsets: [600, 300, 0] },
                 { offsets: [560, 300, 0] },
                 { offsets: [560, 260, 0] },
+                { offsets: [90, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 50, 10], crossAxisOffset: 10 },
+                { offsets: [50, 10, 10], crossAxisOffset: 10 },
             ],
         },
     }
@@ -399,8 +495,6 @@ function setFlexboxSize(flexbox, flexDirection)
 function addFlexPackJustifyTests(writingMode, flexFlow, direction, flexDirection)
 {
     var flexboxClassName = writingMode + ' ' + direction + ' ' + flexFlow;
-
-
     for (var absoluteIndex = 1; absoluteIndex <= 3; ++absoluteIndex) {
         var expected = expectations[writingMode][flexFlow][direction][2 + absoluteIndex];
 
@@ -434,6 +528,39 @@ function addFlexPackJustifyTests(writingMode, flexFlow, direction, flexDirection
     }
 }
 
+function addFlexAlignCenterTests(writingMode, flexFlow, direction, flexDirection)
+{
+    var flexboxClassName = writingMode + ' ' + direction + ' ' + flexFlow;
+    for (var absoluteIndex = 1; absoluteIndex <= 3; ++absoluteIndex) {
+        var expected = expectations[writingMode][flexFlow][direction][5 + absoluteIndex];
+
+        var flexbox = document.createElement('div');
+        flexbox.className = 'flexbox ' + flexboxClassName;
+        flexbox.style.height = '100px';
+        flexbox.style.width = '100px';
+        flexbox.style.margin = "20px";
+        flexbox.style.webkitFlexPack = 'center';
+        flexbox.style.webkitFlexAlign = 'center';
+
+        for (var childIndex = 1; childIndex <= 3; ++childIndex) {
+            var child = document.createElement('div');
+            if (absoluteIndex == childIndex) {
+                child.style.position = 'absolute';
+                child.style.outline = "2px solid yellow";
+            }
+            child.style.width = '40px';
+            child.style.height = '40px';
+
+            child.setAttribute('data-offset-' + (flexDirection == 'width' ? 'x' : 'y'), expected.offsets[childIndex - 1]);
+            var expectedCrossAxisOffset = (absoluteIndex == childIndex) ? expected.crossAxisOffset : 30;
+            child.setAttribute('data-offset-' + (flexDirection == 'width' ? 'y' : 'x'), expectedCrossAxisOffset);
+            flexbox.appendChild(child);
+        }
+
+        document.body.appendChild(flexbox);
+    }
+}
+
 writingModes.forEach(function(writingMode) {
     flexFlows.forEach(function(flexFlow) {
         directions.forEach(function(direction) {
@@ -444,7 +571,6 @@ writingModes.forEach(function(writingMode) {
             document.body.appendChild(title);
 
             var flexDirection = getFlexDirection(flexFlow, writingMode);
-
             for (var absoluteIndex = 1; absoluteIndex <= 3; ++absoluteIndex) {
                 var expected = expectations[writingMode][flexFlow][direction][absoluteIndex - 1];
 
@@ -468,6 +594,7 @@ writingModes.forEach(function(writingMode) {
                 document.body.appendChild(flexbox);
             }
             addFlexPackJustifyTests(writingMode, flexFlow, direction, flexDirection);
+            addFlexAlignCenterTests(writingMode, flexFlow, direction, flexDirection);
         })
     })
 })
index 91318eb..414a6ae 100644 (file)
@@ -1,3 +1,21 @@
+2012-05-25  Ojan Vafai  <ojan@chromium.org>
+
+        Absolute positioned elements in a relative positioned CSS3 Flexbox fail to display properly
+        https://bugs.webkit.org/show_bug.cgi?id=58453
+
+        Reviewed by Tony Chang.
+
+        Test: css3/flexbox/align-absolute-child.html
+
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::prepareChildForPositionedLayout):
+        (WebCore::RenderFlexibleBox::layoutAndPlaceChildren):
+        (WebCore::RenderFlexibleBox::adjustAlignmentForChild):
+        When adjusting positioned items, adjust their static position, not their location.
+        (WebCore::RenderFlexibleBox::flipForRightToLeftColumn):
+        (WebCore::RenderFlexibleBox::flipForWrapReverse):
+        * rendering/RenderFlexibleBox.h:
+
 2012-05-29  Abhishek Arya  <inferno@chromium.org>
 
         Crash due to text fragment destruction when updating first-letter block.
index 8f0997b..4ed627a 100644 (file)
@@ -698,7 +698,9 @@ bool RenderFlexibleBox::hasAutoMarginsInCrossAxis(RenderBox* child)
 
 LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox* child)
 {
-    LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child);
+    LayoutUnit childCrossExtent = 0;
+    if (!child->isPositioned())
+        childCrossExtent = crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child);
     return lineCrossAxisExtent - childCrossExtent;
 }
 
@@ -932,13 +934,13 @@ void RenderFlexibleBox::setLogicalOverrideSize(RenderBox* child, LayoutUnit chil
         child->setOverrideWidth(childPreferredSize);
 }
 
-void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset)
+void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode layoutMode)
 {
     ASSERT(child->isPositioned());
     child->containingBlock()->insertPositionedObject(child);
     RenderLayer* childLayer = child->layer();
     LayoutUnit inlinePosition = isColumnFlow() ? crossAxisOffset : mainAxisOffset;
-    if (style()->flexDirection() == FlowRowReverse)
+    if (layoutMode == FlipForRowReverse && style()->flexDirection() == FlowRowReverse)
         inlinePosition = mainAxisExtent() - mainAxisOffset;
     childLayer->setStaticInlinePosition(inlinePosition); // FIXME: Not right for regions.
 
@@ -983,7 +985,7 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
     for (size_t i = 0; i < children.size(); ++i) {
         RenderBox* child = children[i];
         if (child->isPositioned()) {
-            prepareChildForPositionedLayout(child, mainAxisOffset, crossAxisOffset);
+            prepareChildForPositionedLayout(child, mainAxisOffset, crossAxisOffset, FlipForRowReverse);
             mainAxisOffset += packingSpaceBetweenChildren(availableFreeSpace, style()->flexPack(), childSizes.size());
             continue;
         }
@@ -1115,8 +1117,17 @@ void RenderFlexibleBox::packFlexLines(FlexOrderIterator& iterator, WTF::Vector<L
 
 void RenderFlexibleBox::adjustAlignmentForChild(RenderBox* child, LayoutUnit delta)
 {
-    LayoutRect oldRect = child->frameRect();
+    if (child->isPositioned()) {
+        LayoutUnit staticInlinePosition = child->layer()->staticInlinePosition();
+        LayoutUnit staticBlockPosition = child->layer()->staticBlockPosition();
+        LayoutUnit mainAxis = isColumnFlow() ? staticBlockPosition : staticInlinePosition;
+        LayoutUnit crossAxis = isColumnFlow() ? staticInlinePosition : staticBlockPosition;
+        crossAxis += delta;
+        prepareChildForPositionedLayout(child, mainAxis, crossAxis, NoFlipForRowReverse);
+        return;
+    }
 
+    LayoutRect oldRect = child->frameRect();
     setFlowAwareLocationForChild(child, flowAwareLocationForChild(child) + LayoutSize(0, delta));
 
     // If the child moved, we have to repaint it as well as any floating/positioned
@@ -1224,6 +1235,8 @@ void RenderFlexibleBox::flipForRightToLeftColumn(FlexOrderIterator& iterator)
 
     LayoutUnit crossExtent = crossAxisExtent();
     for (RenderBox* child = iterator.first(); child; child = iterator.next()) {
+        if (child->isPositioned())
+            continue;
         LayoutPoint location = flowAwareLocationForChild(child);
         location.setY(crossExtent - crossAxisExtentForChild(child) - location.y());
         setFlowAwareLocationForChild(child, location);
@@ -1237,16 +1250,10 @@ void RenderFlexibleBox::flipForWrapReverse(FlexOrderIterator& iterator, const WT
     for (size_t lineNumber = 0; lineNumber < lineContexts.size(); ++lineNumber) {
         for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = iterator.next()) {
             ASSERT(child);
-            LayoutPoint location = flowAwareLocationForChild(child);
             LayoutUnit lineCrossAxisExtent = lineContexts[lineNumber].crossAxisExtent;
             LayoutUnit originalOffset = lineContexts[lineNumber].crossAxisOffset - crossAxisStartEdge;
             LayoutUnit newOffset = contentExtent - originalOffset - lineCrossAxisExtent;
-            location.setY(location.y() + newOffset - originalOffset);
-
-            LayoutRect oldRect = child->frameRect();
-            setFlowAwareLocationForChild(child, location);
-            if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
-                child->repaintDuringLayoutIfMoved(oldRect);
+            adjustAlignmentForChild(child, newOffset - originalOffset);
         }
     }
 }
index ae61d63..d923a53 100644 (file)
@@ -54,6 +54,11 @@ private:
         NegativeFlexibility,
     };
 
+    enum PositionedLayoutMode {
+        FlipForRowReverse,
+        NoFlipForRowReverse,
+    };
+
     struct FlexOrderHashTraits;
     typedef HashSet<int, DefaultHash<int>::Hash, FlexOrderHashTraits> FlexOrderHashSet;
 
@@ -120,7 +125,7 @@ private:
     void freezeViolations(const WTF::Vector<Violation>&, LayoutUnit& availableFreeSpace, float& totalPositiveFlexibility, float& totalWeightedNegativeFlexibility, InflexibleFlexItemSize&);
 
     void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
-    void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset);
+    void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode);
     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>&);