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

Reviewed by Antti Koivisto.

Source/WebCore:

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

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

* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::complicatedCases):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::complicatedCases):
(WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
(WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
(WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
* layout/blockformatting/BlockFormattingContext.h:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):

Tools:

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

LayoutTests:

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

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

16 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/block/block-only/absolute-position-min-max-height-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/absolute-position-min-max-height.html [new file with mode: 0644]
LayoutTests/fast/block/block-only/float-min-max-height-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/float-min-max-height.html [new file with mode: 0644]
LayoutTests/fast/block/block-only/inflow-min-max-height-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/inflow-min-max-height.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 31fbd48..d0a46be 100644 (file)
@@ -1,3 +1,17 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Add support for min(max)-height
+        https://bugs.webkit.org/show_bug.cgi?id=189377
+
+        Reviewed by Antti Koivisto.
+
+        * fast/block/block-only/absolute-position-min-max-height-expected.txt: Added.
+        * fast/block/block-only/absolute-position-min-max-height.html: Added.
+        * fast/block/block-only/float-min-max-height-expected.txt: Added.
+        * fast/block/block-only/float-min-max-height.html: Added.
+        * fast/block/block-only/inflow-min-max-height-expected.txt: Added.
+        * fast/block/block-only/inflow-min-max-height.html: Added.
+
 2018-09-06  Daniel Bates  <dabates@apple.com>
 
         [iOS] Add a test to ensure that DOM keyup events have the correct details
diff --git a/LayoutTests/fast/block/block-only/absolute-position-min-max-height-expected.txt b/LayoutTests/fast/block/block-only/absolute-position-min-max-height-expected.txt
new file mode 100644 (file)
index 0000000..212f607
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 785x602
+  RenderView at (0,0) size 785x600
+layer at (0,0) size 785x8
+  RenderBlock {HTML} at (0,0) size 785x8
+    RenderBody {BODY} at (8,8) size 769x0
+layer at (8,8) size 102x54
+  RenderBlock (positioned) {DIV} at (8,8) size 102x54 [border: (1px solid #008000)]
+    RenderBlock {DIV} at (1,1) size 102x52 [border: (1px solid #FF0000)]
+layer at (8,100) size 102x102
+  RenderBlock (positioned) {DIV} at (8,100) size 102x102 [border: (1px solid #008000)]
+    RenderBlock {DIV} at (1,1) size 102x152 [border: (1px solid #FF0000)]
+layer at (8,300) size 102x302
+  RenderBlock (positioned) {DIV} at (8,300) size 102x302 [border: (1px solid #008000)]
+    RenderBlock {DIV} at (1,1) size 102x52 [border: (1px solid #FF0000)]
diff --git a/LayoutTests/fast/block/block-only/absolute-position-min-max-height.html b/LayoutTests/fast/block/block-only/absolute-position-min-max-height.html
new file mode 100644 (file)
index 0000000..2db05b8
--- /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; width: 100px;">
+    <div style="height: 50px; width: 100px;"></div>
+</div>
+
+<div style="position: absolute; top: 100px; width: 100px; max-height: 100px;">
+    <div style="height: 150px; width: 100px;"></div>
+</div>
+
+<div style="position: absolute; top: 300px; width: 100px; min-height: 300px">
+    <div style="height: 50px; width: 100px;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/block/block-only/float-min-max-height-expected.txt b/LayoutTests/fast/block/block-only/float-min-max-height-expected.txt
new file mode 100644 (file)
index 0000000..2204f4a
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x412
+  RenderBlock {HTML} at (0,0) size 800x412
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock (floating) {DIV} at (0,0) size 202x54 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+      RenderBlock (floating) {DIV} at (302,0) size 202x102 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x152 [border: (1px solid #FF0000)]
+      RenderBlock (floating) {DIV} at (0,102) size 202x302 [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-height.html b/LayoutTests/fast/block/block-only/float-min-max-height.html
new file mode 100644 (file)
index 0000000..c6e9a0d
--- /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; width: 200px;">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+
+<div style="float: left; margin-left: 100px; margin-right: 200px; width: 200px; max-height: 100px;">
+    <div style="height: 150px; width: 200px;"></div>
+</div>
+
+<div style="float: left; width: 200px; min-height: 300px">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
diff --git a/LayoutTests/fast/block/block-only/inflow-min-max-height-expected.txt b/LayoutTests/fast/block/block-only/inflow-min-max-height-expected.txt
new file mode 100644 (file)
index 0000000..adced85
--- /dev/null
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x424
+  RenderBlock {HTML} at (0,0) size 800x424
+    RenderBody {BODY} at (8,8) size 784x408
+      RenderBlock {DIV} at (0,0) size 202x54 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x52 [border: (1px solid #FF0000)]
+      RenderBlock {DIV} at (0,54) size 202x52 [border: (1px solid #008000)]
+        RenderBlock {DIV} at (1,1) size 202x202 [border: (1px solid #FF0000)]
+      RenderBlock {DIV} at (0,106) size 202x302 [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-height.html b/LayoutTests/fast/block/block-only/inflow-min-max-height.html
new file mode 100644 (file)
index 0000000..cbfaee8
--- /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="width: 200px;">
+    <div style="width: 200px; height: 50px"></div>
+</div>
+
+<div style="width: 200px; max-height: 50px;">
+    <div style="height: 200px; width: 200px;"></div>
+</div>
+
+<div style="width: 200px; min-height: 300px">
+    <div style="height: 50px; width: 200px;"></div>
+</div>
+</body>
+</html>
index fad9190..7dbbe9c 100644 (file)
@@ -1,3 +1,43 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Add support for min(max)-height
+        https://bugs.webkit.org/show_bug.cgi?id=189377
+
+        Reviewed by Antti Koivisto.
+
+        See https://www.w3.org/TR/CSS22/visudet.html#min-max-heights for details.
+
+        Tests: fast/block/block-only/absolute-position-min-max-height.html
+               fast/block/block-only/float-min-max-height.html
+               fast/block/block-only/inflow-min-max-height.html
+
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
+        * layout/FormattingContext.h:
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::complicatedCases):
+        (WebCore::Layout::FormattingContext::Geometry::floatingReplacedHeightAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::outOfFlowVerticalGeometry):
+        (WebCore::Layout::FormattingContext::Geometry::floatingHeightAndMargin):
+        (WebCore::Layout::FormattingContext::Geometry::inlineReplacedHeightAndMargin):
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
+        * layout/blockformatting/BlockFormattingContext.h:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowHeightAndMargin):
+
 2018-09-06  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] Include supported frame rates in video capture presets
index b7a78e2..8eaaf3c 100644 (file)
@@ -81,7 +81,23 @@ void FormattingContext::computeOutOfFlowHorizontalGeometry(LayoutContext& layout
 
 void FormattingContext::computeOutOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox) const
 {
-    auto verticalGeometry = Geometry::outOfFlowVerticalGeometry(layoutContext, layoutBox);
+    auto compute = [&](std::optional<LayoutUnit> precomputedHeight) {
+        return Geometry::outOfFlowVerticalGeometry(layoutContext, layoutBox, precomputedHeight);
+    };
+
+    auto verticalGeometry = compute({ });
+    // FIXME: Add support for percentage values where the containing block's height is explicitly specified.
+    if (auto maxHeight = Geometry::fixedValue(layoutBox.style().logicalMaxHeight())) {
+        auto maxVerticalGeometry = compute(maxHeight);
+        if (verticalGeometry.heightAndMargin.height > maxVerticalGeometry.heightAndMargin.height)
+            verticalGeometry = maxVerticalGeometry;
+    }
+
+    if (auto minHeight = Geometry::fixedValue(layoutBox.style().logicalMinHeight())) {
+        auto minVerticalGeometry = compute(minHeight);
+        if (verticalGeometry.heightAndMargin.height < minVerticalGeometry.heightAndMargin.height)
+            verticalGeometry = minVerticalGeometry;
+    }
 
     auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
     displayBox.setTop(verticalGeometry.top + verticalGeometry.heightAndMargin.margin.top);
index 3bcfee8..3d7b98c 100644 (file)
@@ -82,17 +82,17 @@ protected:
     // This class implements generic positioning and sizing.
     class Geometry {
     public:
-        static VerticalGeometry outOfFlowVerticalGeometry(const LayoutContext&, const Box&);
+        static VerticalGeometry outOfFlowVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static HorizontalGeometry outOfFlowHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
-        static HeightAndMargin floatingHeightAndMargin(const LayoutContext&, const Box&);
+        static HeightAndMargin floatingHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static WidthAndMargin floatingWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
-        static HeightAndMargin inlineReplacedHeightAndMargin(const LayoutContext&, const Box&);
+        static HeightAndMargin inlineReplacedHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         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&);
+        static HeightAndMargin complicatedCases(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
 
         static Edges computedBorder(const LayoutContext&, const Box&);
         static std::optional<Edges> computedPadding(const LayoutContext&, const Box&);
@@ -104,13 +104,13 @@ protected:
         static std::optional<LayoutUnit> fixedValue(const Length& geometryProperty);
 
     private:
-        static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&);
+        static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
-        static VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const LayoutContext&, const Box&);
+        static VerticalGeometry outOfFlowNonReplacedVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static HorizontalGeometry outOfFlowNonReplacedHorizontalGeometry(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
-        static HeightAndMargin floatingReplacedHeightAndMargin(const LayoutContext&, const Box&);
+        static HeightAndMargin floatingReplacedHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static WidthAndMargin floatingReplacedWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static WidthAndMargin floatingNonReplacedWidthAndMargin(LayoutContext&, const FormattingContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
index 45fd5ad..02e644d 100644 (file)
@@ -161,7 +161,7 @@ LayoutUnit FormattingContext::Geometry::shrinkToFitWidth(LayoutContext& layoutCo
     return std::min(std::max(instrinsicWidthConstraints.minimum, availableWidth), instrinsicWidthConstraints.maximum);
 }
 
-VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned() && !layoutBox.replaced());
 
@@ -197,7 +197,7 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowNonReplacedVerticalGeomet
 
     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
-    auto height = computedValueIfNotAuto(style.logicalHeight(), containingBlockHeight);
+    auto height = computedValueIfNotAuto(precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight(), containingBlockHeight);
     auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth);
     auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth);
     auto paddingTop = displayBox.paddingTop().value_or(0);
@@ -423,7 +423,7 @@ HorizontalGeometry FormattingContext::Geometry::outOfFlowNonReplacedHorizontalGe
     return { *left, *right, { *width, { *marginLeft, *marginRight }, { nonComputedMarginLeft, nonComputedMarginRight } } };
 }
 
-VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned() && layoutBox.replaced());
 
@@ -445,7 +445,7 @@ VerticalGeometry FormattingContext::Geometry::outOfFlowReplacedVerticalGeometry(
 
     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
-    auto height = inlineReplacedHeightAndMargin(layoutContext, layoutBox).height;
+    auto height = inlineReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight).height;
     auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth);
     auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth);
     auto paddingTop = displayBox.paddingTop().value_or(0);
@@ -590,7 +590,7 @@ HorizontalGeometry FormattingContext::Geometry::outOfFlowReplacedHorizontalGeome
     return { *left, *right, { width, { *marginLeft, *marginRight }, { nonComputedMarginLeft, nonComputedMarginRight } } };
 }
 
-HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(!layoutBox.replaced());
     // TODO: Use complicated-case for document renderer for now (see BlockFormattingContext::Geometry::inFlowHeightAndMargin).
@@ -610,7 +610,7 @@ HeightAndMargin FormattingContext::Geometry::complicatedCases(const LayoutContex
     auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(containingBlock);
     auto containingBlockWidth = containingBlockDisplayBox.contentBoxWidth();
 
-    auto height = fixedValue(style.logicalHeight());
+    auto height = fixedValue(precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight());
     auto marginTop = computedValueIfNotAuto(style.marginTop(), containingBlockWidth);
     auto marginBottom = computedValueIfNotAuto(style.marginBottom(), containingBlockWidth);
 
@@ -656,14 +656,14 @@ WidthAndMargin FormattingContext::Geometry::floatingNonReplacedWidthAndMargin(La
     return WidthAndMargin { *width, margin, margin };
 }
 
-HeightAndMargin FormattingContext::Geometry::floatingReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::floatingReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isFloatingPositioned() && layoutBox.replaced());
 
     // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
     // replaced elements in normal flow and floating replaced elements
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Height][Margin] -> floating replaced -> redirected to inline replaced");
-    return inlineReplacedHeightAndMargin(layoutContext, layoutBox);
+    return inlineReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
 }
 
 WidthAndMargin FormattingContext::Geometry::floatingReplacedWidthAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
@@ -680,13 +680,13 @@ WidthAndMargin FormattingContext::Geometry::floatingReplacedWidthAndMargin(const
     return inlineReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth, margin.left, margin.right);
 }
 
-VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox)
+VerticalGeometry FormattingContext::Geometry::outOfFlowVerticalGeometry(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned());
 
     if (!layoutBox.replaced())
-        return outOfFlowNonReplacedVerticalGeometry(layoutContext, layoutBox);
-    return outOfFlowReplacedVerticalGeometry(layoutContext, layoutBox);
+        return outOfFlowNonReplacedVerticalGeometry(layoutContext, layoutBox, precomputedHeight);
+    return outOfFlowReplacedVerticalGeometry(layoutContext, layoutBox, precomputedHeight);
 }
 
 HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
@@ -698,13 +698,13 @@ HorizontalGeometry FormattingContext::Geometry::outOfFlowHorizontalGeometry(Layo
     return outOfFlowReplacedHorizontalGeometry(layoutContext, layoutBox, precomputedWidth);
 }
 
-HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::floatingHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isFloatingPositioned());
 
     if (!layoutBox.replaced())
-        return complicatedCases(layoutContext, layoutBox);
-    return floatingReplacedHeightAndMargin(layoutContext, layoutBox);
+        return complicatedCases(layoutContext, layoutBox, precomputedHeight);
+    return floatingReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
 }
 
 WidthAndMargin FormattingContext::Geometry::floatingWidthAndMargin(LayoutContext& layoutContext, const FormattingContext& formattingContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedWidth)
@@ -716,7 +716,7 @@ WidthAndMargin FormattingContext::Geometry::floatingWidthAndMargin(LayoutContext
     return floatingReplacedWidthAndMargin(layoutContext, layoutBox, precomputedWidth);
 }
 
-HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT((layoutBox.isOutOfFlowPositioned() || layoutBox.isFloatingPositioned() || layoutBox.isInFlow()) && layoutBox.replaced());
 
@@ -738,7 +738,7 @@ HeightAndMargin FormattingContext::Geometry::inlineReplacedHeightAndMargin(const
     auto& containingBlockDisplayBox = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
     auto containingBlockWidth = containingBlockDisplayBox.width();
 
-    auto height = fixedValue(style.logicalHeight());
+    auto height = fixedValue(precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight());
     auto heightIsAuto = style.logicalHeight().isAuto();
     auto width = computedValueIfNotAuto(style.logicalWidth(), containingBlockWidth);
 
index 179c576..ada5b46 100644 (file)
@@ -278,29 +278,40 @@ void BlockFormattingContext::computeWidthAndMargin(LayoutContext& layoutContext,
 
 void BlockFormattingContext::computeHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox) const
 {
-    HeightAndMargin heightAndMargin;
-    std::optional<LayoutUnit> marginTopOffset;
-    auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
+    auto compute = [&](std::optional<LayoutUnit> precomputedHeight) -> HeightAndMargin {
 
-    if (layoutBox.isInFlow()) {
-        heightAndMargin = Geometry::inFlowHeightAndMargin(layoutContext, layoutBox);
+        if (layoutBox.isInFlow())
+            return Geometry::inFlowHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
 
-        // If this box has already been moved by the estimated vertical margin, no need to move it again.
-        if (!displayBox.estimatedMarginTop())
-            marginTopOffset = heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin).top;
-    } else if (layoutBox.isFloatingPositioned()) {
-        heightAndMargin = Geometry::floatingHeightAndMargin(layoutContext, layoutBox);
-        ASSERT(!heightAndMargin.collapsedMargin);
+        if (layoutBox.isFloatingPositioned())
+            return Geometry::floatingHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
 
-        marginTopOffset = heightAndMargin.margin.top;
-    } else
         ASSERT_NOT_REACHED();
+        return { };
+    };
 
+    auto heightAndMargin = compute({ });
+    // FIXME: Add support for percentage values where the containing block's height is explicitly specified.
+    if (auto maxHeight = Geometry::fixedValue(layoutBox.style().logicalMaxHeight())) {
+        auto maxHeightAndMargin = compute(maxHeight);
+        if (heightAndMargin.height > maxHeightAndMargin.height)
+            heightAndMargin = maxHeightAndMargin;
+    }
+
+    if (auto minHeight = Geometry::fixedValue(layoutBox.style().logicalMinHeight())) {
+        auto minHeightAndMargin = compute(minHeight);
+        if (heightAndMargin.height < minHeightAndMargin.height)
+            heightAndMargin = minHeightAndMargin;
+    }
+
+    auto& displayBox = layoutContext.displayBoxForLayoutBox(layoutBox);
     displayBox.setContentBoxHeight(heightAndMargin.height);
     displayBox.setVerticalNonCollapsedMargin(heightAndMargin.margin);
     displayBox.setVerticalMargin(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin));
-    if (marginTopOffset)
-        displayBox.moveVertically(*marginTopOffset);
+
+    // If this box has already been moved by the estimated vertical margin, no need to move it again.
+    if (layoutBox.isFloatingPositioned() || !displayBox.estimatedMarginTop())
+        displayBox.moveVertically(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin).top);
 }
 
 FormattingContext::InstrinsicWidthConstraints BlockFormattingContext::instrinsicWidthConstraints(LayoutContext& layoutContext, const Box& layoutBox) const
index 9f3b600..74a2eda 100644 (file)
@@ -69,7 +69,7 @@ private:
     // This class implements positioning and sizing for boxes participating in a block formatting context.
     class Geometry : public FormattingContext::Geometry {
     public:
-        static HeightAndMargin inFlowHeightAndMargin(const LayoutContext&, const Box&);
+        static HeightAndMargin inFlowHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static WidthAndMargin inFlowWidthAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
 
         static Position staticPosition(const LayoutContext&, const Box&);
@@ -101,7 +101,7 @@ private:
             static LayoutUnit nonCollapsedMarginTop(const LayoutContext&, const Box&);
         };
 
-        static HeightAndMargin inFlowNonReplacedHeightAndMargin(const LayoutContext&, const Box&);
+        static HeightAndMargin inFlowNonReplacedHeightAndMargin(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         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 072e590..a081fda 100644 (file)
@@ -77,7 +77,7 @@ static WidthAndMargin stretchWidthToInitialContainingBlock(WidthAndMargin widthA
     return widthAndMargin;
 }
 
-HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
     ASSERT(layoutBox.isOverflowVisible());
@@ -106,10 +106,10 @@ HeightAndMargin BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMarg
         VerticalEdges collapsedMargin = { MarginCollapse::marginTop(layoutContext, layoutBox), MarginCollapse::marginBottom(layoutContext, layoutBox) };
         auto borderAndPaddingTop = displayBox.borderTop() + displayBox.paddingTop().value_or(0);
         
-        auto height = style.logicalHeight();
+        auto height = precomputedHeight ? Length { precomputedHeight.value(), Fixed } : style.logicalHeight();
         if (!height.isAuto()) {
             if (height.isFixed())
-                return { style.logicalHeight().value(), nonCollapsedMargin, collapsedMargin };
+                return { height.value(), nonCollapsedMargin, collapsedMargin };
 
             // Most notably height percentage.
             ASSERT_NOT_IMPLEMENTED_YET();
@@ -367,23 +367,23 @@ Position BlockFormattingContext::Geometry::inFlowPositionedPosition(const Layout
     return { newLeftPosition, newTopPosition };
 }
 
-HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox)
+HeightAndMargin BlockFormattingContext::Geometry::inFlowHeightAndMargin(const LayoutContext& layoutContext, const Box& layoutBox, std::optional<LayoutUnit> precomputedHeight)
 {
     ASSERT(layoutBox.isInFlow());
 
     // 10.6.2 Inline replaced elements, block-level replaced elements in normal flow, 'inline-block'
     // replaced elements in normal flow and floating replaced elements
     if (layoutBox.replaced())
-        return inlineReplacedHeightAndMargin(layoutContext, layoutBox);
+        return inlineReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
 
     HeightAndMargin heightAndMargin;
     // TODO: Figure out the case for the document element. Let's just complicated-case it for now.
     if (layoutBox.isOverflowVisible() && !layoutBox.isDocumentBox())
-        heightAndMargin = inFlowNonReplacedHeightAndMargin(layoutContext, layoutBox);
+        heightAndMargin = inFlowNonReplacedHeightAndMargin(layoutContext, layoutBox, precomputedHeight);
     else {
         // 10.6.6 Complicated cases
         // Block-level, non-replaced elements in normal flow when 'overflow' does not compute to 'visible' (except if the 'overflow' property's value has been propagated to the viewport).
-        heightAndMargin = complicatedCases(layoutContext, layoutBox);
+        heightAndMargin = complicatedCases(layoutContext, layoutBox, precomputedHeight);
     }
 
     if (!isStretchedToInitialContainingBlock(layoutContext, layoutBox))
index 9dcf188..3c1eed4 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][BFC] Add support for min(max)-height
+        https://bugs.webkit.org/show_bug.cgi?id=189377
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
 2018-09-06  Dewei Zhu  <dewei_zhu@apple.com>
 
         BenchmarkResults.format should support specifying depth of tests to show.
index ff0e63c..3bfae6c 100644 (file)
@@ -58,3 +58,6 @@ 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
+fast/block/block-only/inflow-min-max-height.html
+fast/block/block-only/absolute-position-min-max-height.html
+fast/block/block-only/float-min-max-height.html