Safari (WebKit) doesn't wrap element within flex when width comes below min-width
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Nov 2016 16:04:41 +0000 (16:04 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 29 Nov 2016 16:04:41 +0000 (16:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136041
<rdar://problem/25569370>

Reviewed by Darin Adler.

Source/WebCore:

While figuring out whether a particular flex item fits the current line, we need to take
the min-width into account too. This matches both FF and Chrome behaviour.

Tests: fast/flexbox/flex-wrap-when-min-widht-is-set-1.html
       fast/flexbox/flex-wrap-when-min-widht-is-set-2.html

* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::computeNextFlexLine):

LayoutTests:

* fast/flexbox/flex-wrap-when-min-widht-is-set-1-expected.html: Added.
* fast/flexbox/flex-wrap-when-min-widht-is-set-1.html: Added.
* fast/flexbox/flex-wrap-when-min-widht-is-set-2-expected.html: Added.
* fast/flexbox/flex-wrap-when-min-widht-is-set-2.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-1-expected.html [new file with mode: 0644]
LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-1.html [new file with mode: 0644]
LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-2-expected.html [new file with mode: 0644]
LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-2.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderFlexibleBox.cpp

index b5d519c..aba0494 100644 (file)
@@ -1,3 +1,16 @@
+2016-11-29  Zalan Bujtas  <zalan@apple.com>
+
+        Safari (WebKit) doesn't wrap element within flex when width comes below min-width
+        https://bugs.webkit.org/show_bug.cgi?id=136041
+        <rdar://problem/25569370>
+
+        Reviewed by Darin Adler.
+
+        * fast/flexbox/flex-wrap-when-min-widht-is-set-1-expected.html: Added.
+        * fast/flexbox/flex-wrap-when-min-widht-is-set-1.html: Added.
+        * fast/flexbox/flex-wrap-when-min-widht-is-set-2-expected.html: Added.
+        * fast/flexbox/flex-wrap-when-min-widht-is-set-2.html: Added.
+
 2016-11-28  Antti Koivisto  <antti@apple.com>
 
         Slotted nodes ignore transition
diff --git a/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-1-expected.html b/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-1-expected.html
new file mode 100644 (file)
index 0000000..8435eb4
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This test that we wrap flex content properly with min-width is set.</title>
+<style>
+div {
+  width: 500px;
+  height: 200px;
+  background: green;
+}
+</style>
+</head>
+<body> 
+<div></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-1.html b/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-1.html
new file mode 100644 (file)
index 0000000..d9b442d
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This test that we wrap flex content properly with min-width is set.</title>
+<style>
+.flex {
+  display: flex;
+  flex-wrap: wrap;
+}
+               
+.item {
+  box-sizing: border-box;
+  min-width: 500px;
+  flex-basis: 200px;
+  height: 100px;
+  background: green;
+}
+</style>
+</head>
+<body> 
+<div class="flex"><div class="item"></div><div class="item"></div></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-2-expected.html b/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-2-expected.html
new file mode 100644 (file)
index 0000000..657a439
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This test that we wrap flex content properly with min-width is set.</title>
+<style>
+div {
+  height: 200px;
+  background: green;
+}
+</style>
+</head>
+<body> 
+<div></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-2.html b/LayoutTests/fast/flexbox/flex-wrap-when-min-widht-is-set-2.html
new file mode 100644 (file)
index 0000000..1e16c07
--- /dev/null
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This test that we wrap flex content properly with min-width is set.</title>
+<style>
+<style>
+.flex {
+  display: flex;
+  flex-wrap: wrap;
+}
+               
+.item {
+  flex-grow: 1;
+  flex-basis: 35%;
+  min-width: 600px;
+  height: 100px;
+  background: green;
+}
+</style>
+</head>
+</body>
+<div class="flex"><div class="item"></div><div class="item"></div></div>
+</body>
+</html>
index b32db79..7192b48 100644 (file)
@@ -1,3 +1,20 @@
+2016-11-29  Zalan Bujtas  <zalan@apple.com>
+
+        Safari (WebKit) doesn't wrap element within flex when width comes below min-width
+        https://bugs.webkit.org/show_bug.cgi?id=136041
+        <rdar://problem/25569370>
+
+        Reviewed by Darin Adler.
+
+        While figuring out whether a particular flex item fits the current line, we need to take
+        the min-width into account too. This matches both FF and Chrome behaviour.
+
+        Tests: fast/flexbox/flex-wrap-when-min-widht-is-set-1.html
+               fast/flexbox/flex-wrap-when-min-widht-is-set-2.html
+
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::computeNextFlexLine):
+
 2016-11-29  Antti Koivisto  <antti@apple.com>
 
         Try to fix win/gtk build.
index c5d0f70..9be37e8 100644 (file)
@@ -983,6 +983,7 @@ bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren
 
     bool lineHasInFlowItem = false;
 
+    LayoutUnit preferredMainAxisExtentWithMinWidthConstraint;
     for (RenderBox* child = m_orderIterator.currentChild(); child; child = m_orderIterator.next()) {
         if (child->isOutOfFlowPositioned()) {
             orderedChildren.append(child);
@@ -990,19 +991,26 @@ bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren
         }
 
         LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild(*child, hasInfiniteLineLength);
-        LayoutUnit childMainAxisMarginBoxExtent = mainAxisBorderAndPaddingExtentForChild(*child) + childMainAxisExtent;
-        childMainAxisMarginBoxExtent += isHorizontalFlow() ? child->horizontalMarginExtent() : child->verticalMarginExtent();
+        LayoutUnit borderMarginAndPaddingSpace = mainAxisBorderAndPaddingExtentForChild(*child) + (isHorizontalFlow() ? child->horizontalMarginExtent() : child->verticalMarginExtent());
 
-        if (isMultiline() && preferredMainAxisExtent + childMainAxisMarginBoxExtent > lineBreakLength && lineHasInFlowItem)
+        LayoutUnit childMainAxisExtentWithMinWidthConstraint = childMainAxisExtent;
+        if (child->style().logicalMinWidth().isSpecifiedOrIntrinsic()) {
+            if (auto minWidthForChild = computeMainAxisExtentForChild(*child, MinSize, child->style().logicalMinWidth()))
+                childMainAxisExtentWithMinWidthConstraint = std::max(childMainAxisExtent, minWidthForChild.value());
+        }
+        preferredMainAxisExtentWithMinWidthConstraint += childMainAxisExtentWithMinWidthConstraint + borderMarginAndPaddingSpace;
+
+        if (isMultiline() && preferredMainAxisExtentWithMinWidthConstraint > lineBreakLength && lineHasInFlowItem)
             break;
         orderedChildren.append(child);
         lineHasInFlowItem  = true;
-        preferredMainAxisExtent += childMainAxisMarginBoxExtent;
+
+        preferredMainAxisExtent += childMainAxisExtent + borderMarginAndPaddingSpace;
         totalFlexGrow += child->style().flexGrow();
         totalWeightedFlexShrink += child->style().flexShrink() * childMainAxisExtent;
 
         LayoutUnit childMinMaxAppliedMainAxisExtent = adjustChildSizeForMinAndMax(*child, childMainAxisExtent);
-        minMaxAppliedMainAxisExtent += childMinMaxAppliedMainAxisExtent - childMainAxisExtent + childMainAxisMarginBoxExtent;
+        minMaxAppliedMainAxisExtent += childMinMaxAppliedMainAxisExtent + borderMarginAndPaddingSpace;
     }
     return true;
 }