[LFC] Add support for min/max-height percentage values.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Sep 2018 02:27:37 +0000 (02:27 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Sep 2018 02:27:37 +0000 (02:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189391

Reviewed by Antti Koivisto.

Source/WebCore:

The percentage is calculated with respect to the height of the generated box's containing block.
If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element
is not absolutely positioned, the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').

Test: fast/block/block-only/min-max-height-percentage.html

* layout/FormattingContext.cpp:
(WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
* layout/FormattingContext.h:
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedValueIfNotAuto):
(WebCore::Layout::FormattingContext::Geometry::computedMaxHeight):
(WebCore::Layout::FormattingContext::Geometry::computedMinHeight):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):

Tools:

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

LayoutTests:

* fast/block/block-only/min-max-height-percentage-expected.txt: Added.
* fast/block/block-only/min-max-height-percentage.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/block/block-only/min-max-height-percentage-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/block-only/min-max-height-percentage.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
Tools/ChangeLog
Tools/LayoutReloaded/misc/LFC-passing-tests.txt

index 1532da3..f5a27fd 100644 (file)
@@ -1,3 +1,13 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC] Add support for min/max-height percentage values.
+        https://bugs.webkit.org/show_bug.cgi?id=189391
+
+        Reviewed by Antti Koivisto.
+
+        * fast/block/block-only/min-max-height-percentage-expected.txt: Added.
+        * fast/block/block-only/min-max-height-percentage.html: Added.
+
 2018-09-06  Megan Gardner  <megan_gardner@apple.com>
 
         Add Support for Conic Gradients
 2018-09-06  Megan Gardner  <megan_gardner@apple.com>
 
         Add Support for Conic Gradients
diff --git a/LayoutTests/fast/block/block-only/min-max-height-percentage-expected.txt b/LayoutTests/fast/block/block-only/min-max-height-percentage-expected.txt
new file mode 100644 (file)
index 0000000..8cbf2ad
--- /dev/null
@@ -0,0 +1,25 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x586
+  RenderBlock {HTML} at (0,0) size 800x586
+    RenderBody {BODY} at (8,8) size 784x570
+      RenderBlock {DIV} at (0,0) size 200x100
+        RenderBlock {DIV} at (0,0) size 100x50
+          RenderBlock {DIV} at (0,0) size 20x80
+      RenderBlock {DIV} at (0,100) size 200x100
+        RenderBlock {DIV} at (0,0) size 100x50
+          RenderBlock {DIV} at (0,0) size 20x10
+      RenderBlock {DIV} at (0,200) size 200x10
+        RenderBlock {DIV} at (0,0) size 100x10
+          RenderBlock {DIV} at (0,0) size 20x10
+layer at (8,318) size 200x80
+  RenderBlock (relative positioned) {DIV} at (0,310) size 200x80
+    RenderBlock {DIV} at (0,0) size 20x80
+layer at (8,318) size 100x40
+  RenderBlock (positioned) {DIV} at (0,0) size 100x40
+    RenderBlock {DIV} at (0,0) size 20x80
+layer at (8,498) size 200x80
+  RenderBlock (relative positioned) {DIV} at (0,490) size 200x80
+    RenderBlock {DIV} at (0,0) size 20x80
+layer at (8,498) size 100x40
+  RenderBlock (positioned) {DIV} at (0,0) size 100x40
diff --git a/LayoutTests/fast/block/block-only/min-max-height-percentage.html b/LayoutTests/fast/block/block-only/min-max-height-percentage.html
new file mode 100644 (file)
index 0000000..4e9aa6a
--- /dev/null
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="width: 200px; height: 100px;">
+    <div style="width: 100px; max-height: 50%;">
+           <div style="width: 20px; height: 80px;"></div>
+    </div>
+</div>
+
+<div style="width: 200px; height: 100px;">
+    <div style="width: 100px; min-height: 50%;">
+           <div style="width: 20px; height: 10px;"></div>
+    </div>
+</div>
+
+<div style="width: 200px; margin-bottom: 100px;">
+    <div style="width: 100px; min-height: 50%;">
+           <div style="width: 20px; height: 10px;"></div>
+    </div>
+</div>
+
+<div style="position: relative; width: 200px; margin-bottom: 100px;">
+    <div style="position: absolute; width: 100px; max-height: 50%;">
+               <div style="width: 20px; height: 80px;"></div>
+    </div>
+       <div style="width: 20px; height: 80px;"></div>
+</div>
+
+<div style="position: relative; width: 200px;">
+    <div style="position: absolute; width: 100px; min-height: 50%;"></div>
+       <div style="width: 20px; height: 80px;"></div>
+</div>
+
+</body>
+</html>
index 87c7f14..764bfd0 100644 (file)
@@ -1,3 +1,26 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC] Add support for min/max-height percentage values.
+        https://bugs.webkit.org/show_bug.cgi?id=189391
+
+        Reviewed by Antti Koivisto.
+
+        The percentage is calculated with respect to the height of the generated box's containing block.
+        If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element
+        is not absolutely positioned, the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').
+
+        Test: fast/block/block-only/min-max-height-percentage.html
+
+        * layout/FormattingContext.cpp:
+        (WebCore::Layout::FormattingContext::computeOutOfFlowVerticalGeometry const):
+        * layout/FormattingContext.h:
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedValueIfNotAuto):
+        (WebCore::Layout::FormattingContext::Geometry::computedMaxHeight):
+        (WebCore::Layout::FormattingContext::Geometry::computedMinHeight):
+        * layout/blockformatting/BlockFormattingContext.cpp:
+        (WebCore::Layout::BlockFormattingContext::computeHeightAndMargin const):
+
 2018-09-06  Megan Gardner  <megan_gardner@apple.com>
 
         Add Support for Conic Gradients
 2018-09-06  Megan Gardner  <megan_gardner@apple.com>
 
         Add Support for Conic Gradients
index 8eaaf3c..86d9728 100644 (file)
@@ -86,14 +86,13 @@ void FormattingContext::computeOutOfFlowVerticalGeometry(const LayoutContext& la
     };
 
     auto verticalGeometry = compute({ });
     };
 
     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())) {
+    if (auto maxHeight = Geometry::computedMaxHeight(layoutContext, layoutBox)) {
         auto maxVerticalGeometry = compute(maxHeight);
         if (verticalGeometry.heightAndMargin.height > maxVerticalGeometry.heightAndMargin.height)
             verticalGeometry = maxVerticalGeometry;
     }
 
         auto maxVerticalGeometry = compute(maxHeight);
         if (verticalGeometry.heightAndMargin.height > maxVerticalGeometry.heightAndMargin.height)
             verticalGeometry = maxVerticalGeometry;
     }
 
-    if (auto minHeight = Geometry::fixedValue(layoutBox.style().logicalMinHeight())) {
+    if (auto minHeight = Geometry::computedMinHeight(layoutContext, layoutBox)) {
         auto minVerticalGeometry = compute(minHeight);
         if (verticalGeometry.heightAndMargin.height < minVerticalGeometry.heightAndMargin.height)
             verticalGeometry = minVerticalGeometry;
         auto minVerticalGeometry = compute(minHeight);
         if (verticalGeometry.heightAndMargin.height < minVerticalGeometry.heightAndMargin.height)
             verticalGeometry = minVerticalGeometry;
index 3d7b98c..374f17c 100644 (file)
@@ -103,6 +103,9 @@ protected:
         static std::optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth);
         static std::optional<LayoutUnit> fixedValue(const Length& geometryProperty);
 
         static std::optional<LayoutUnit> computedValueIfNotAuto(const Length& geometryProperty, LayoutUnit containingBlockWidth);
         static std::optional<LayoutUnit> fixedValue(const Length& geometryProperty);
 
+        static std::optional<LayoutUnit> computedMinHeight(const LayoutContext&, const Box&);
+        static std::optional<LayoutUnit> computedMaxHeight(const LayoutContext&, const Box&);
+
     private:
         static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
     private:
         static VerticalGeometry outOfFlowReplacedVerticalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedHeight = { });
         static HorizontalGeometry outOfFlowReplacedHorizontalGeometry(const LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = { });
index 02e644d..81634d0 100644 (file)
@@ -82,6 +82,7 @@ std::optional<LayoutUnit> FormattingContext::Geometry::computedValueIfNotAuto(co
 
     if (geometryProperty.isAuto())
         return std::nullopt;
 
     if (geometryProperty.isAuto())
         return std::nullopt;
+
     return valueForLength(geometryProperty, containingBlockWidth);
 }
 
     return valueForLength(geometryProperty, containingBlockWidth);
 }
 
@@ -92,6 +93,58 @@ std::optional<LayoutUnit> FormattingContext::Geometry::fixedValue(const Length&
     return { geometryProperty.value() };
 }
 
     return { geometryProperty.value() };
 }
 
+// https://www.w3.org/TR/CSS22/visudet.html#min-max-heights
+// Specifies a percentage for determining the used value. The percentage is calculated with respect to the height of the generated box's containing block.
+// If the height of the containing block is not specified explicitly (i.e., it depends on content height), and this element is not absolutely positioned,
+// the percentage value is treated as '0' (for 'min-height') or 'none' (for 'max-height').
+std::optional<LayoutUnit> FormattingContext::Geometry::computedMaxHeight(const LayoutContext& layoutContext, const Box& layoutBox)
+{
+    auto maxHeight = layoutBox.style().logicalMaxHeight();
+    if (maxHeight.isUndefined() || maxHeight.isAuto())
+        return { };
+
+    if (maxHeight.isFixed())
+        return { maxHeight.value() };
+
+    std::optional<LayoutUnit> containingBlockHeightValue;
+    auto height = layoutBox.containingBlock()->style().logicalHeight();
+    if (height.isFixed())
+        containingBlockHeightValue = { height.value() };
+    else if (layoutBox.isOutOfFlowPositioned()) {
+        // Containing block's height is already computed.
+        containingBlockHeightValue = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).height();
+    }
+
+    if (containingBlockHeightValue)
+        return valueForLength(maxHeight, *containingBlockHeightValue);
+
+    return { };
+}
+
+std::optional<LayoutUnit> FormattingContext::Geometry::computedMinHeight(const LayoutContext& layoutContext, const Box& layoutBox)
+{
+    auto minHeight = layoutBox.style().logicalMinHeight();
+    if (minHeight.isUndefined() || minHeight.isAuto())
+        return { };
+
+    if (minHeight.isFixed())
+        return { minHeight.value() };
+
+    std::optional<LayoutUnit> containingBlockHeightValue;
+    auto height = layoutBox.containingBlock()->style().logicalHeight();
+    if (height.isFixed())
+        containingBlockHeightValue = { height.value() };
+    else if (layoutBox.isOutOfFlowPositioned()) {
+        // Containing block's height is already computed.
+        containingBlockHeightValue = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock()).height();
+    }
+
+    if (containingBlockHeightValue)
+        return valueForLength(minHeight, *containingBlockHeightValue);
+
+    return { 0 };
+}
+
 static LayoutUnit staticVerticalPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned());
 static LayoutUnit staticVerticalPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox)
 {
     ASSERT(layoutBox.isOutOfFlowPositioned());
index ada5b46..ac9d215 100644 (file)
@@ -291,14 +291,13 @@ void BlockFormattingContext::computeHeightAndMargin(const LayoutContext& layoutC
     };
 
     auto heightAndMargin = compute({ });
     };
 
     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())) {
+    if (auto maxHeight = Geometry::computedMaxHeight(layoutContext, layoutBox)) {
         auto maxHeightAndMargin = compute(maxHeight);
         if (heightAndMargin.height > maxHeightAndMargin.height)
             heightAndMargin = maxHeightAndMargin;
     }
 
         auto maxHeightAndMargin = compute(maxHeight);
         if (heightAndMargin.height > maxHeightAndMargin.height)
             heightAndMargin = maxHeightAndMargin;
     }
 
-    if (auto minHeight = Geometry::fixedValue(layoutBox.style().logicalMinHeight())) {
+    if (auto minHeight = Geometry::computedMinHeight(layoutContext, layoutBox)) {
         auto minHeightAndMargin = compute(minHeight);
         if (heightAndMargin.height < minHeightAndMargin.height)
             heightAndMargin = minHeightAndMargin;
         auto minHeightAndMargin = compute(minHeight);
         if (heightAndMargin.height < minHeightAndMargin.height)
             heightAndMargin = minHeightAndMargin;
index 69f9607..051a402 100644 (file)
@@ -1,3 +1,12 @@
+2018-09-06  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC] Add support for min/max-height percentage values.
+        https://bugs.webkit.org/show_bug.cgi?id=189391
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
 2018-09-06  Simon Fraser  <simon.fraser@apple.com>
 
         Log when leak detection changes the test result
 2018-09-06  Simon Fraser  <simon.fraser@apple.com>
 
         Log when leak detection changes the test result
index 3bfae6c..bbe8c23 100644 (file)
@@ -61,3 +61,4 @@ 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
 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
+fast/block/block-only/min-max-height-percentage.html