[LFC][IFC] Add support for min/max-width/height
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Jun 2020 16:55:06 +0000 (16:55 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Jun 2020 16:55:06 +0000 (16:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=212904

Reviewed by Antti Koivisto.

Source/WebCore:

Test: fast/layoutformattingcontext/inline-max-width-height-simple.html

* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedWidthValue): Adjust assert to check inline, non-replaced boxes only (inline-block is an
inline level element but not an inline element)
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computeWidthAndMargin):
(WebCore::Layout::InlineFormattingContext::computeHeightAndMargin):

LayoutTests:

* fast/layoutformattingcontext/inline-max-width-height-simple-expected.html: Added.
* fast/layoutformattingcontext/inline-max-width-height-simple.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/layoutformattingcontext/inline-max-width-height-simple-expected.html [new file with mode: 0644]
LayoutTests/fast/layoutformattingcontext/inline-max-width-height-simple.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/layout/FormattingContextGeometry.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp

index 9e0ca56..30f5b2e 100644 (file)
@@ -1,3 +1,13 @@
+2020-06-08  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Add support for min/max-width/height
+        https://bugs.webkit.org/show_bug.cgi?id=212904
+
+        Reviewed by Antti Koivisto.
+
+        * fast/layoutformattingcontext/inline-max-width-height-simple-expected.html: Added.
+        * fast/layoutformattingcontext/inline-max-width-height-simple.html: Added.
+
 2020-06-05  Sergio Villar Senin  <svillar@igalia.com>
 
         [WebXR] Add missing interfaces from the AR module
diff --git a/LayoutTests/fast/layoutformattingcontext/inline-max-width-height-simple-expected.html b/LayoutTests/fast/layoutformattingcontext/inline-max-width-height-simple-expected.html
new file mode 100644 (file)
index 0000000..757fce6
--- /dev/null
@@ -0,0 +1,10 @@
+<!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+div {
+    position: relative;
+    width: 50px;
+    height: 50px;
+}
+</style>
+<div style="background-color: green;"></div>
+<div style="left: 50px; top: -50px; background-color: blue;"></div>
diff --git a/LayoutTests/fast/layoutformattingcontext/inline-max-width-height-simple.html b/LayoutTests/fast/layoutformattingcontext/inline-max-width-height-simple.html
new file mode 100644 (file)
index 0000000..e176648
--- /dev/null
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- webkit-test-runner [ internal:LayoutFormattingContextEnabled=true internal:LayoutFormattingContextIntegrationEnabled=false ] -->
+<style>
+.container {
+    width: 100px;
+    height: 50px;
+    background: blue;
+}
+.inline_content {
+    max-width: 50px;
+    height: 1000px;
+    max-height: 100%;
+    background: green;
+}
+</style>
+<div class=container>
+  <div></div>
+  <img class=inline_content src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
+</div>
index 9d02716..ba342a9 100644 (file)
@@ -1,3 +1,19 @@
+2020-06-08  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Add support for min/max-width/height
+        https://bugs.webkit.org/show_bug.cgi?id=212904
+
+        Reviewed by Antti Koivisto.
+
+        Test: fast/layoutformattingcontext/inline-max-width-height-simple.html
+
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedWidthValue): Adjust assert to check inline, non-replaced boxes only (inline-block is an
+        inline level element but not an inline element) 
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::computeWidthAndMargin):
+        (WebCore::Layout::InlineFormattingContext::computeHeightAndMargin):
+
 2020-06-05  Sergio Villar Senin  <svillar@igalia.com>
 
         [WebXR] Add missing interfaces from the AR module
index 6b2187f..78a6bd4 100644 (file)
@@ -111,7 +111,7 @@ Optional<LayoutUnit> FormattingContext::Geometry::computedHeight(const Box& layo
 Optional<LayoutUnit> FormattingContext::Geometry::computedWidthValue(const Box& layoutBox, WidthType widthType, LayoutUnit containingBlockWidth)
 {
     // Applies to: all elements except non-replaced inlines (out-of-flow check is required for positioned <br> as for some reason we don't blockify them).
-    ASSERT(layoutBox.isReplacedBox() || !layoutBox.isInlineLevelBox() || layoutBox.isOutOfFlowPositioned());
+    ASSERT(!layoutBox.isInlineBox() || layoutBox.isOutOfFlowPositioned());
 
     auto width = [&] {
         auto& style = layoutBox.style();
index b81a137..89bb076 100644 (file)
@@ -288,17 +288,30 @@ void InlineFormattingContext::computeHorizontalMargin(const Box& layoutBox, cons
 
 void InlineFormattingContext::computeWidthAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints)
 {
-    ContentWidthAndMargin contentWidthAndMargin;
-    // FIXME: Add support for min/max-width.
-    auto usedWidth = OverrideHorizontalValues { };
-    if (layoutBox.isFloatingPositioned())
-        contentWidthAndMargin = geometry().floatingWidthAndMargin(layoutBox, horizontalConstraints, usedWidth);
-    else if (layoutBox.isInlineBlockBox())
-        contentWidthAndMargin = geometry().inlineBlockWidthAndMargin(layoutBox, horizontalConstraints, usedWidth);
-    else if (layoutBox.isReplacedBox())
-        contentWidthAndMargin = geometry().inlineReplacedWidthAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, { }, usedWidth);
-    else
+    auto compute = [&](Optional<LayoutUnit> usedWidth) {
+        if (layoutBox.isFloatingPositioned())
+            return geometry().floatingWidthAndMargin(layoutBox, horizontalConstraints, { usedWidth, { } });
+        if (layoutBox.isInlineBlockBox())
+            return geometry().inlineBlockWidthAndMargin(layoutBox, horizontalConstraints, { usedWidth, { } });
+        if (layoutBox.isReplacedBox())
+            return geometry().inlineReplacedWidthAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, { }, { usedWidth, { } });
         ASSERT_NOT_REACHED();
+        return ContentWidthAndMargin { };
+    };
+
+    auto contentWidthAndMargin = compute({ });
+
+    auto availableWidth = horizontalConstraints.logicalWidth;
+    if (auto maxWidth = geometry().computedMaxWidth(layoutBox, availableWidth)) {
+        auto maxWidthAndMargin = compute(maxWidth);
+        if (contentWidthAndMargin.contentWidth > maxWidthAndMargin.contentWidth)
+            contentWidthAndMargin = maxWidthAndMargin;
+    }
+
+    auto minWidth = geometry().computedMinWidth(layoutBox, availableWidth).valueOr(0);
+    auto minWidthAndMargin = compute(minWidth);
+    if (contentWidthAndMargin.contentWidth < minWidthAndMargin.contentWidth)
+        contentWidthAndMargin = minWidthAndMargin;
 
     auto& displayBox = formattingState().displayBox(layoutBox);
     displayBox.setContentBoxWidth(contentWidthAndMargin.contentWidth);
@@ -308,18 +321,29 @@ void InlineFormattingContext::computeWidthAndMargin(const Box& layoutBox, const
 
 void InlineFormattingContext::computeHeightAndMargin(const Box& layoutBox, const HorizontalConstraints& horizontalConstraints)
 {
-    ContentHeightAndMargin contentHeightAndMargin;
-    // FIXME: Add min/max-height support.
-    auto usedHeight = OverrideVerticalValues { };
-    if (layoutBox.isFloatingPositioned())
-        contentHeightAndMargin = geometry().floatingHeightAndMargin(layoutBox, horizontalConstraints, usedHeight);
-    else if (layoutBox.isInlineBlockBox())
-        contentHeightAndMargin = geometry().inlineBlockHeightAndMargin(layoutBox, horizontalConstraints, usedHeight);
-    else if (layoutBox.isReplacedBox())
-        contentHeightAndMargin = geometry().inlineReplacedHeightAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, { }, usedHeight);
-    else
+    auto compute = [&](Optional<LayoutUnit> usedHeight) {
+        if (layoutBox.isFloatingPositioned())
+            return geometry().floatingHeightAndMargin(layoutBox, horizontalConstraints, { usedHeight });
+        if (layoutBox.isInlineBlockBox())
+            return geometry().inlineBlockHeightAndMargin(layoutBox, horizontalConstraints, { usedHeight });
+        if (layoutBox.isReplacedBox())
+            return geometry().inlineReplacedHeightAndMargin(downcast<ReplacedBox>(layoutBox), horizontalConstraints, { }, { usedHeight });
         ASSERT_NOT_REACHED();
+        return ContentHeightAndMargin { };
+    };
+
+    auto contentHeightAndMargin = compute({ });
+    if (auto maxHeight = geometry().computedMaxHeight(layoutBox)) {
+        auto maxHeightAndMargin = compute(maxHeight);
+        if (contentHeightAndMargin.contentHeight > maxHeightAndMargin.contentHeight)
+            contentHeightAndMargin = maxHeightAndMargin;
+    }
 
+    if (auto minHeight = geometry().computedMinHeight(layoutBox)) {
+        auto minHeightAndMargin = compute(minHeight);
+        if (contentHeightAndMargin.contentHeight < minHeightAndMargin.contentHeight)
+            contentHeightAndMargin = minHeightAndMargin;
+    }
     auto& displayBox = formattingState().displayBox(layoutBox);
     displayBox.setContentBoxHeight(contentHeightAndMargin.contentHeight);
     displayBox.setVerticalMargin({ contentHeightAndMargin.nonCollapsedMargin, { } });