[LFC][BFC] Add support for min(max)-width
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Sep 2018 18:03:31 +0000 (18:03 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 6 Sep 2018 18:03:31 +0000 (18:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189358

Reviewed by Antti Koivisto.

Source/WebCore:

See https://www.w3.org/TR/CSS22/visudet.html#min-max-widths for details.

Tests: fast/block/block-only/absolute-position-min-max-width.html
       fast/block/block-only/float-min-max-width.html
       fast/block/block-only/inflow-min-max-width.html

* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowHorizontalGeometry const):
* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::Geometry::outOfFlowHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingReplacedWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedValueIfNotAuto):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::floatingReplacedWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowHorizontalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingWidthAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeWidthAndMargin const):
* layout/blockformatting/BlockFormattingContext.h:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):

Tools:

* LayoutReloaded/misc/LFC-passing-tests.txt:

LayoutTests:

* fast/block/block-only/absolute-position-min-max-width-expected.txt: Added.
* fast/block/block-only/absolute-position-min-max-width.html: Added.
* fast/block/block-only/float-min-max-width-expected.txt: Added.
* fast/block/block-only/float-min-max-width.html: Added.
* fast/block/block-only/inflow-min-max-width-expected.txt: Added.
* fast/block/block-only/inflow-min-max-width.html: Added.

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

16 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/block/block-only/absolute-position-min-max-width-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/absolute-position-min-max-width.html [new file with mode: 0644]
LayoutTests/fast/block/block-only/float-min-max-width-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/float-min-max-width.html [new file with mode: 0644]
LayoutTests/fast/block/block-only/inflow-min-max-width-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/inflow-min-max-width.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/layout/FormattingContext.cpp
Source/WebCore/layout/FormattingContext.h
Source/WebCore/layout/FormattingContextGeometry.cpp
Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp
Source/WebCore/layout/blockformatting/BlockFormattingContext.h
Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
Tools/ChangeLog
Tools/LayoutReloaded/misc/LFC-passing-tests.txt

index 2afba80..9bc9d08 100644 (file)
@@ -1,3 +1,17 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Add support for min(max)-width
+        https://bugs.webkit.org/show_bug.cgi?id=189358
+
+        Reviewed by Antti Koivisto.
+
+        * fast/block/block-only/absolute-position-min-max-width-expected.txt: Added.
+        * fast/block/block-only/absolute-position-min-max-width.html: Added.
+        * fast/block/block-only/float-min-max-width-expected.txt: Added.
+        * fast/block/block-only/float-min-max-width.html: Added.
+        * fast/block/block-only/inflow-min-max-width-expected.txt: Added.
+        * fast/block/block-only/inflow-min-max-width.html: Added.
+
 2018-09-06  Miguel Gomez  <magomez@igalia.com>
 
         Unreviewed GTK+ gardening after r235732.
diff --git a/LayoutTests/fast/block/block-only/absolute-position-min-max-width-expected.txt b/LayoutTests/fast/block/block-only/absolute-position-min-max-width-expected.txt
new file mode 100644 (file)
index 0000000..257f165
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  RenderBlock {HTML} at (0,0) size 800x8
+    RenderBody {BODY} at (8,8) size 784x0
+layer at (8,8) size 204x102
+  RenderBlock (positioned) {DIV} at (8,8) size 204x102 [border: (1px solid #008000)]
+    RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+layer at (8,150) size 102x102
+  RenderBlock (positioned) {DIV} at (8,150) size 102x102 [border: (1px solid #008000)]
+    RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+layer at (8,300) size 302x102
+  RenderBlock (positioned) {DIV} at (8,300) size 302x102 [border: (1px solid #008000)]
+    RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
diff --git a/LayoutTests/fast/block/block-only/absolute-position-min-max-width.html b/LayoutTests/fast/block/block-only/absolute-position-min-max-width.html
new file mode 100644 (file)
index 0000000..67bf305
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+    border: 1px solid green;
+}
+
+div > div {
+    border: 1px solid red;
+}
+</style>
+</head>
+<body>
+<div style="position: absolute;  height: 100px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="position: absolute; top: 150px; height: 100px; max-width: 100px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="position: absolute; top: 300px; height: 100px; min-width: 300px">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/block/block-only/float-min-max-width-expected.txt b/LayoutTests/fast/block/block-only/float-min-max-width-expected.txt
new file mode 100644 (file)
index 0000000..446cc30
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x212
+  RenderBlock {HTML} at (0,0) size 800x212
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock (floating) {DIV} at (0,0) size 204x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+      RenderBlock (floating) {DIV} at (304,0) size 102x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+      RenderBlock (floating) {DIV} at (0,102) size 302x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
diff --git a/LayoutTests/fast/block/block-only/float-min-max-width.html b/LayoutTests/fast/block/block-only/float-min-max-width.html
new file mode 100644 (file)
index 0000000..6c0854f
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+    border: 1px solid green;
+}
+
+div > div {
+    border: 1px solid red;
+}
+</style>
+</head>
+<body>
+<div style="float: left; height: 100px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="float: left; margin-left: 100px; margin-right: 200px; height: 100px; max-width: 100px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="float: left; height: 100px; min-width: 300px">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/block/block-only/inflow-min-max-width-expected.txt b/LayoutTests/fast/block/block-only/inflow-min-max-width-expected.txt
new file mode 100644 (file)
index 0000000..25d976a
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x464
+  RenderBlock {HTML} at (0,0) size 800x464
+    RenderBody {BODY} at (8,8) size 784x406
+      RenderBlock {DIV} at (0,0) size 784x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+      RenderBlock {DIV} at (0,152) size 102x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+      RenderBlock {DIV} at (0,304) size 784x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
diff --git a/LayoutTests/fast/block/block-only/inflow-min-max-width.html b/LayoutTests/fast/block/block-only/inflow-min-max-width.html
new file mode 100644 (file)
index 0000000..9b1a1f9
--- /dev/null
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+    border: 1px solid green;
+    margin-bottom: 50px;
+}
+
+div > div {
+    border: 1px solid red;
+}
+</style>
+</head>
+<body>
+<div style="height: 100px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="height: 100px; max-width: 100px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="height: 100px; min-width: 300px">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
index 2ce7186..2daab46 100644 (file)
@@ -1,3 +1,46 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Add support for min(max)-width
+        https://bugs.webkit.org/show_bug.cgi?id=189358
+
+        Reviewed by Antti Koivisto.
+
+        See https://www.w3.org/TR/CSS22/visudet.html#min-max-widths for details.
+
+        Tests: fast/block/block-only/absolute-position-min-max-width.html
+               fast/block/block-only/float-min-max-width.html
+               fast/block/block-only/inflow-min-max-width.html
+
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeOutOfFlowHorizontalGeometry const):
+        * layout/FormattingContext.h:
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowHorizontalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingWidthAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingReplacedWidthAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedValueIfNotAuto):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::floatingReplacedWidthAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowHorizontalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingWidthAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedWidthAndMargin):
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeWidthAndMargin const):
+        * layout/blockformatting/BlockFormattingContext.h:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin):
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowWidthAndMargin):
+
 2018-09-06  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] Initialize AVVideoCapture video presets
index 9529b31..b7a78e2 100644 (file)
@@ -53,7 +53,24 @@ FormattingContext::~FormattingContext()
 
 void FormattingContext::computeOutOfFlowHorizontalGeometry(LayoutContext& layoutContext, const Box& layoutBox) const
 {
-    auto horizontalGeometry = Geometry::outOfFlowHorizontalGeometry(layoutContext, *this, layoutBox);
+    auto compute = [&](std::optional<LayoutUnit> precomputedWidth) {
+        return Geometry::outOfFlowHorizontalGeometry(layoutContext, *this, layoutBox, precomputedWidth);
+    };
+
+    auto horizontalGeometry = compute({ });
+    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
+
+    if (auto maxWidth = Geometry::computedValueIfNotAuto(layoutBox.style().logicalMaxWidth(), containingBlockWidth)) {
+        auto maxHorizontalGeometry = compute(maxWidth);
+        if (horizontalGeometry.widthAndMargin.width > maxHorizontalGeometry.widthAndMargin.width)
+            horizontalGeometry = maxHorizontalGeometry;
+    }
+
+    if (auto minWidth = Geometry::computedValueIfNotAuto(layoutBox.style().logicalMinWidth(), containingBlockWidth)) {
+        auto minHorizontalGeometry = compute(minWidth);
+        if (horizontalGeometry.widthAndMargin.width < minHorizontalGeometry.widthAndMargin.width)
+            horizontalGeometry = minHorizontalGeometry;
+    }
 
     auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
     displayBox.setLeft(horizontalGeometry.left + horizontalGeometry.widthAndMargin.margin.left);
index 0292830..3bcfee8 100644 (file)
@@ -83,14 +83,14 @@ protected:
     class Geometry {
     public:
         static VerticalGeometry outOfFlowVerticalGeometry(const LayoutContext&, const Box&);
-        static HorizontalGeometry outOfFlowHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&);
+        static HorizontalGeometry outOfFlowHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static HeightAndMargin floatingHeightAndMargin(const LayoutContext&, const Box&);
-        static WidthAndMargin floatingWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&);
+        static WidthAndMargin floatingWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static HeightAndMargin inlineReplacedHeightAndMargin(const LayoutContext&, const Box&);
-        static WidthAndMargin inlineReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedMarginLeft = { },
-            std::optional<LayoutUnit> precomputedMarginRight = { });
+        static WidthAndMargin inlineReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { }, 
+            std::optional<LayoutUnit> precomputedMarginLeft = { }, std::optional<LayoutUnit> precomputedMarginRight = { });
 
         static HeightAndMargin complicatedCases(const LayoutContext&, const Box&);
 
@@ -105,15 +105,15 @@ protected:
 
     private:
         static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&);
-        static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const LayoutContext&, const Box&);
+        static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const LayoutContext&, const Box&);
-        static HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&);
+        static HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static HeightAndMargin floatingReplacedHeightAndMargin(const LayoutContext&, const Box&);
-        static WidthAndMargin floatingReplacedWidthAndMargin(const LayoutContext&, const Box&);
+        static WidthAndMargin floatingReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
-        static WidthAndMargin floatingNonReplacedWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&);
+        static WidthAndMargin floatingNonReplacedWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static LayoutUnit shrinkToFitWidth(LayoutContext&, const FormattingContext&, const Box&);
     };
index 2b0dc14..45fd5ad 100644 (file)
@@ -77,6 +77,9 @@ static LayoutUnit contentHeightForFormattingContextRoot(const LayoutContext& lay
 
 std::optional<LayoutUnit> FormattingContext::Geometry::computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth)
 {
+    if (geometryProperty.isUndefined())
+        return std::nullopt;
+
     if (geometryProperty.isAuto())
         return std::nullopt;
     return valueForLength(geometryProperty, containingBlockWidth);
@@ -274,7 +277,7 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeomet
     return { *top, *bottom, { *height, { *marginTop, *marginBottom }, { } } };
 }
 
-HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox)
+HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGeometry(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
     
@@ -312,7 +315,7 @@ HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGe
     
     auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
     auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth);
-    auto width = computedValueIfNotAuto(style.logicalWidth(), containingBlockWidth);
+    auto width = computedValueIfNotAuto(precomputedWidth ? Length { precomputedWidth.value(), Fixed } : style.logicalWidth(), containingBlockWidth);
     auto marginLeft = computedValueIfNotAuto(style.marginLeft(), containingBlockWidth);
     auto marginRight = computedValueIfNotAuto(style.marginRight(), containingBlockWidth);
     auto nonComputedMarginLeft = marginLeft.value_or(0);
@@ -489,7 +492,7 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(
     return { *top, *bottom, { height, { *marginTop, *marginBottom }, { } } };
 }
 
-HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
 
@@ -519,7 +522,7 @@ HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeome
     auto marginRight = computedValueIfNotAuto(style.marginRight(), containingBlockWidth);
     auto nonComputedMarginLeft = marginLeft.value_or(0);
     auto nonComputedMarginRight = marginRight.value_or(0);
-    auto width = inlineReplacedWidthAndMargin(layoutContext, layoutBox).width;
+    auto width = inlineReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth).width;
     auto paddingLeft = displayBox.paddingLeft().value_or(0);
     auto paddingRight = displayBox.paddingRight().value_or(0);
     auto borderLeft = displayBox.borderLeft();
@@ -630,7 +633,7 @@ HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutContex
     return HeightAndMargin { *height, { *marginTop, *marginBottom }, { } };
 }
 
-WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox)
+WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isFloatingPositioned() && !layoutBox.replaced());
 
@@ -644,8 +647,8 @@ WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(La
 
     // #1
     auto margin = computedNonCollapsedHorizontalMarginValue(layoutContext, layoutBox);
-      // #2
-    auto width = computedValueIfNotAuto(layoutBox.style().logicalWidth(), containingBlockWidth);
+    // #2
+    auto width = computedValueIfNotAuto(precomputedWidth ? Length { precomputedWidth.value(), Fixed } : layoutBox.style().logicalWidth(), containingBlockWidth);
     if (!width)
         width = shrinkToFitWidth(layoutContext, formattingContext, layoutBox);
 
@@ -663,7 +666,7 @@ HeightAndMargin FormattingContext::Geometry::floatingReplacedHeightAndMargin(con
     return inlineReplacedHeightAndMargin(layoutContext, layoutBox);
 }
 
-WidthAndMargin FormattingContext::Geometry::floatingReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+WidthAndMargin FormattingContext::Geometry::floatingReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isFloatingPositioned() && layoutBox.replaced());
 
@@ -674,7 +677,7 @@ WidthAndMargin FormattingContext::Geometry::floatingReplacedWidthAndMargin(const
     auto margin = computedNonCollapsedHorizontalMarginValue(layoutContext, layoutBox);
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
-    return inlineReplacedWidthAndMargin(layoutContext, layoutBox, margin.left, margin.right);
+    return inlineReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth, margin.left, margin.right);
 }
 
 VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
@@ -686,13 +689,13 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const La
     return outOfFlowReplacedVerticalGeometry(layoutContext, layoutBox);
 }
 
-HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox)
+HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned());
 
     if (!layoutBox.replaced())
-        return outOfFlowNonReplacedHorizontalGeometry(layoutContext, formattingContext, layoutBox);
-    return outOfFlowReplacedHorizontalGeometry(layoutContext, layoutBox);
+        return outOfFlowNonReplacedHorizontalGeometry(layoutContext, formattingContext, layoutBox, precomputedWidth);
+    return outOfFlowReplacedHorizontalGeometry(layoutContext, layoutBox, precomputedWidth);
 }
 
 HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
@@ -704,13 +707,13 @@ HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(const Layou
     return floatingReplacedHeightAndMargin(layoutContext, layoutBox);
 }
 
-WidthAndMargin FormattingContext::Geometry::floatingWidthAndMargin(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox)
+WidthAndMargin FormattingContext::Geometry::floatingWidthAndMargin(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isFloatingPositioned());
 
     if (!layoutBox.replaced())
-        return floatingNonReplacedWidthAndMargin(layoutContext, formattingContext, layoutBox);
-    return floatingReplacedWidthAndMargin(layoutContext, layoutBox);
+        return floatingNonReplacedWidthAndMargin(layoutContext, formattingContext, layoutBox, precomputedWidth);
+    return floatingReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth);
 }
 
 HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
@@ -763,7 +766,7 @@ HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const
 }
 
 WidthAndMargin FormattingContext::Geometry::inlineReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox,
-    std::optional<LayoutUnit> precomputedMarginLeft, std::optional<LayoutUnit> precomputedMarginRight)
+    std::optional<LayoutUnit> precomputedWidth, std::optional<LayoutUnit> precomputedMarginLeft, std::optional<LayoutUnit> precomputedMarginRight)
 {
     ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
 
@@ -811,7 +814,7 @@ WidthAndMargin FormattingContext::Geometry::inlineReplacedWidthAndMargin(const L
     auto marginRight = computeMarginRight();
     auto nonComputedMarginLeft = computedValueIfNotAuto(style.marginLeft(), containingBlockWidth).value_or(0);
     auto nonComputedMarginRight = computedValueIfNotAuto(style.marginRight(), containingBlockWidth).value_or(0);
-    auto width = computedValueIfNotAuto(style.logicalWidth(), containingBlockWidth);
+    auto width = computedValueIfNotAuto(precomputedWidth ? Length { precomputedWidth.value(), Fixed } : style.logicalWidth(), containingBlockWidth);
 
     auto heightIsAuto = style.logicalHeight().isAuto();
     auto height = fixedValue(style.logicalHeight());
index 9f0bd58..179c576 100644 (file)
@@ -242,14 +242,32 @@ void BlockFormattingContext::computeInFlowPositionedPosition(const LayoutContext
 
 void BlockFormattingContext::computeWidthAndMargin(LayoutContext& layoutContext, const Box& layoutBox) const
 {
-    WidthAndMargin widthAndMargin;
+    auto compute = [&](std::optional<LayoutUnit> precomputedWidth) -> WidthAndMargin {
+
+        if (layoutBox.isInFlow())
+            return Geometry::inFlowWidthAndMargin(layoutContext, layoutBox, precomputedWidth);
+
+        if (layoutBox.isFloatingPositioned())
+            return Geometry::floatingWidthAndMargin(layoutContext, *this, layoutBox, precomputedWidth);
 
-    if (layoutBox.isInFlow())
-        widthAndMargin = Geometry::inFlowWidthAndMargin(layoutContext, layoutBox);
-    else if (layoutBox.isFloatingPositioned())
-        widthAndMargin = Geometry::floatingWidthAndMargin(layoutContext, *this, layoutBox);
-    else
         ASSERT_NOT_REACHED();
+        return { };
+    };
+
+    auto widthAndMargin = compute({ });
+    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).contentBoxWidth();
+
+    if (auto maxWidth = Geometry::computedValueIfNotAuto(layoutBox.style().logicalMaxWidth(), containingBlockWidth)) {
+        auto maxWidthAndMargin = compute(maxWidth);
+        if (widthAndMargin.width > maxWidthAndMargin.width)
+            widthAndMargin = maxWidthAndMargin;
+    }
+
+    if (auto minWidth = Geometry::computedValueIfNotAuto(layoutBox.style().logicalMinWidth(), containingBlockWidth)) {
+        auto minWidthAndMargin = compute(minWidth);
+        if (widthAndMargin.width < minWidthAndMargin.width)
+            widthAndMargin = minWidthAndMargin;
+    }
 
     auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
     displayBox.setContentBoxWidth(widthAndMargin.width);
index 7d2773a..9f3b600 100644 (file)
@@ -70,7 +70,7 @@ private:
     class Geometry : public FormattingContext::Geometry {
     public:
         static HeightAndMargin inFlowHeightAndMargin(const LayoutContext&, const Box&);
-        static WidthAndMargin inFlowWidthAndMargin(const LayoutContext&, const Box&);
+        static WidthAndMargin inFlowWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static Position staticPosition(const LayoutContext&, const Box&);
         static Position inFlowPositionedPosition(const LayoutContext&, const Box&);
@@ -102,8 +102,8 @@ private:
         };
 
         static HeightAndMargin inFlowNonReplacedHeightAndMargin(const LayoutContext&, const Box&);
-        static WidthAndMargin inFlowNonReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = std::nullopt);
-        static WidthAndMargin inFlowReplacedWidthAndMargin(const LayoutContext&, const Box&);
+        static WidthAndMargin inFlowNonReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
+        static WidthAndMargin inFlowReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
         static Position staticPositionForOutOfFlowPositioned(const LayoutContext&, const Box&);
     };
 };
index ae36d1c..072e590 100644 (file)
@@ -151,8 +151,7 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg
     return heightAndMargin;
 }
 
-WidthAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox,
-    std::optional<LayoutUnit> precomputedWidth)
+WidthAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
 
@@ -252,7 +251,7 @@ WidthAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedWidthAndMargin
     return widthAndMargin;
 }
 
-WidthAndMargin BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+WidthAndMargin BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isInFlow() && layoutBox.replaced());
 
@@ -262,7 +261,7 @@ WidthAndMargin BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin(co
     // 2. Then the rules for non-replaced block-level elements are applied to determine the margins.
 
     // #1
-    auto width = inlineReplacedWidthAndMargin(layoutContext, layoutBox).width;
+    auto width = inlineReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth).width;
     // #2
     auto nonReplacedWidthAndMargin = inFlowNonReplacedWidthAndMargin(layoutContext, layoutBox, width);
 
@@ -397,13 +396,13 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const La
     return heightAndMargin;
 }
 
-WidthAndMargin BlockFormattingContext::Geometry::inFlowWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+WidthAndMargin BlockFormattingContext::Geometry::inFlowWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
 {
     ASSERT(layoutBox.isInFlow());
 
     if (!layoutBox.replaced())
-        return inFlowNonReplacedWidthAndMargin(layoutContext, layoutBox);
-    return inFlowReplacedWidthAndMargin(layoutContext, layoutBox);
+        return inFlowNonReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth);
+    return inFlowReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth);
 }
 
 bool BlockFormattingContext::Geometry::instrinsicWidthConstraintsNeedChildrenWidth(const Box& layoutBox)
index 1a1e216..451a5f2 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Add support for min(max)-width
+        https://bugs.webkit.org/show_bug.cgi?id=189358
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
 2018-09-06  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [WHLSL] The parser is too slow
index 640ef44..ff0e63c 100644 (file)
@@ -55,3 +55,6 @@ fast/block/block-only/float-avoider-simple-left.html
 fast/block/block-only/float-avoider-simple-right.html
 fast/block/block-only/float-avoider-multiple-roots.html
 fast/block/block-only/float-avoider-with-margins.html
+fast/block/block-only/inflow-min-max-width.html
+fast/block/block-only/absolute-position-min-max-width.html
+fast/block/block-only/float-min-max-width.html