Title: [237679] trunk
Revision
237679
Author
za...@apple.com
Date
2018-11-01 07:20:48 -0700 (Thu, 01 Nov 2018)

Log Message

[LFC][IFC] Add support for inline-block elements.
https://bugs.webkit.org/show_bug.cgi?id=191143

Reviewed by Antti Koivisto.

Source/WebCore:

This patch add support for laying out non-shrink-to-width inline-block elements.

Test: fast/inline/simple-inline-block.html

* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::contentHeightForFormattingContextRoot):
(WebCore::Layout::FormattingContext::Geometry::shrinkToFitWidth):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layoutFormattingContextRoot const):
* layout/inlineformatting/InlineFormattingContextGeometry.cpp:
(WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockWidthAndMargin):
(WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockHeightAndMargin):
* layout/layouttree/LayoutInlineContainer.cpp:
(WebCore::Layout::InlineContainer::establishesInlineFormattingContext const):
* layout/layouttree/LayoutInlineContainer.h:
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::TreeBuilder::createSubTree):

Tools:

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

LayoutTests:

* fast/inline/simple-inline-block-expected.txt: Added.
* fast/inline/simple-inline-block.html: Added.
* platform/ios/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (237678 => 237679)


--- trunk/LayoutTests/ChangeLog	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/LayoutTests/ChangeLog	2018-11-01 14:20:48 UTC (rev 237679)
@@ -1,3 +1,14 @@
+2018-10-31  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Add support for inline-block elements.
+        https://bugs.webkit.org/show_bug.cgi?id=191143
+
+        Reviewed by Antti Koivisto.
+
+        * fast/inline/simple-inline-block-expected.txt: Added.
+        * fast/inline/simple-inline-block.html: Added.
+        * platform/ios/TestExpectations:
+
 2018-11-01  YUHAN WU  <yuhan...@apple.com>
 
         MediaRecorder should fire dataavailable event when all tracks are ended and stop() is called

Added: trunk/LayoutTests/fast/inline/simple-inline-block-expected.txt (0 => 237679)


--- trunk/LayoutTests/fast/inline/simple-inline-block-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/simple-inline-block-expected.txt	2018-11-01 14:20:48 UTC (rev 237679)
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {DIV} at (0,0) size 300x102
+        RenderText {#text} at (0,1) size 90x18
+          text run at (0,1) width 90: "first line with "
+        RenderBlock {DIV} at (89,0) size 103x102 [border: (1px solid #FF0000)]
+          RenderText {#text} at (1,1) size 76x18
+            text run at (1,1) width 76: "inline block"
+        RenderText {#text} at (191,1) size 52x18
+          text run at (191,1) width 52: " content"

Added: trunk/LayoutTests/fast/inline/simple-inline-block.html (0 => 237679)


--- trunk/LayoutTests/fast/inline/simple-inline-block.html	                        (rev 0)
+++ trunk/LayoutTests/fast/inline/simple-inline-block.html	2018-11-01 14:20:48 UTC (rev 237679)
@@ -0,0 +1,15 @@
+<style>
+div {
+	width: 300px;
+}
+
+#inline-b {
+	border: 1px solid red;
+	display: inline-block;
+	height: 100px;
+	width: 100px;
+}
+
+</style>
+
+<div>first line with <div id=inline-b>inline block</div> content</div>

Modified: trunk/LayoutTests/platform/ios/TestExpectations (237678 => 237679)


--- trunk/LayoutTests/platform/ios/TestExpectations	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2018-11-01 14:20:48 UTC (rev 237679)
@@ -3112,6 +3112,7 @@
 fast/inline/simple-intruding-float1.html [ Failure ]
 fast/inline/simple-intruding-floats2.html [ Failure ]
 fast/inline/simple-intruding-floats3.html [ Failure ]
+fast/inline/simple-inline-block.html [ Failure ]
 
 # Datalist
 webkit.org/b/186714 fast/forms/datalist/datalist-textinput-keydown.html [ Skip ]

Modified: trunk/Source/WebCore/ChangeLog (237678 => 237679)


--- trunk/Source/WebCore/ChangeLog	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/ChangeLog	2018-11-01 14:20:48 UTC (rev 237679)
@@ -1,3 +1,30 @@
+2018-10-31  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Add support for inline-block elements.
+        https://bugs.webkit.org/show_bug.cgi?id=191143
+
+        Reviewed by Antti Koivisto.
+
+        This patch add support for laying out non-shrink-to-width inline-block elements.
+
+        Test: fast/inline/simple-inline-block.html
+
+        * layout/FormattingContext.h:
+        (WebCore::Layout::FormattingContext::Geometry::floatingNonReplacedWidthAndMargin):
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::contentHeightForFormattingContextRoot):
+        (WebCore::Layout::FormattingContext::Geometry::shrinkToFitWidth):
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layoutFormattingContextRoot const):
+        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
+        (WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockWidthAndMargin):
+        (WebCore::Layout::InlineFormattingContext::Geometry::inlineBlockHeightAndMargin):
+        * layout/layouttree/LayoutInlineContainer.cpp:
+        (WebCore::Layout::InlineContainer::establishesInlineFormattingContext const):
+        * layout/layouttree/LayoutInlineContainer.h:
+        * layout/layouttree/LayoutTreeBuilder.cpp:
+        (WebCore::Layout::TreeBuilder::createSubTree):
+
 2018-11-01  Claudio Saavedra  <csaave...@igalia.com>
 
         Fix build with VIDEO and WEB_AUDIO disabled

Modified: trunk/Source/WebCore/layout/FormattingContext.h (237678 => 237679)


--- trunk/Source/WebCore/layout/FormattingContext.h	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/FormattingContext.h	2018-11-01 14:20:48 UTC (rev 237679)
@@ -94,6 +94,7 @@
             std::optional<LayoutUnit> precomputedMarginLeft = { }, std::optional<LayoutUnit> precomputedMarginRight = { });
 
         static HeightAndMargin complicatedCases(const LayoutState&, const Box&, std::optional<LayoutUnit> usedHeight = { });
+        static LayoutUnit shrinkToFitWidth(const LayoutState&, const FormattingContext&, const Box&);
 
         static Edges computedBorder(const LayoutState&, const Box&);
         static std::optional<Edges> computedPadding(const LayoutState&, const Box&);
@@ -118,8 +119,6 @@
         static WidthAndMargin floatingReplacedWidthAndMargin(const LayoutState&, const Box&, std::optional<LayoutUnit> usedWidth = { });
 
         static WidthAndMargin floatingNonReplacedWidthAndMargin(LayoutState&, const FormattingContext&, const Box&, std::optional<LayoutUnit> usedWidth = { });
-
-        static LayoutUnit shrinkToFitWidth(LayoutState&, const FormattingContext&, const Box&);
     };
 
 private:

Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (237678 => 237679)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-11-01 14:20:48 UTC (rev 237679)
@@ -30,6 +30,7 @@
 
 #include "FloatingState.h"
 #include "FormattingState.h"
+#include "InlineFormattingState.h"
 
 namespace WebCore {
 namespace Layout {
@@ -50,15 +51,23 @@
     if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowOrFloatingChild())
         return 0;
 
+    LayoutUnit top;
+    LayoutUnit bottom;
     auto& formattingRootContainer = downcast<Container>(layoutBox);
-    if (formattingRootContainer.establishesInlineFormattingContext())
-        return 0;
+    if (formattingRootContainer.establishesInlineFormattingContext()) {
+        // This is temp and will be replaced by the correct display box once inline runs move over to the display tree.
+        auto& inlineRuns = downcast<InlineFormattingState>(layoutState.establishedFormattingState(layoutBox)).inlineRuns();
+        if (!inlineRuns.isEmpty()) {
+            top = inlineRuns[0].logicalTop();
+            bottom =  inlineRuns.last().logicalBottom();
+        }
+    } else if (formattingRootContainer.establishesBlockFormattingContext() || layoutBox.isDocumentBox()) {
+        auto& firstDisplayBox = layoutState.displayBoxForLayoutBox(*formattingRootContainer.firstInFlowChild());
+        auto& lastDisplayBox = layoutState.displayBoxForLayoutBox(*formattingRootContainer.lastInFlowChild());
+        top = firstDisplayBox.rectWithMargin().top();
+        bottom = lastDisplayBox.rectWithMargin().bottom();
+    }
 
-    auto& firstDisplayBox = layoutState.displayBoxForLayoutBox(*formattingRootContainer.firstInFlowChild());
-    auto& lastDisplayBox = layoutState.displayBoxForLayoutBox(*formattingRootContainer.lastInFlowChild());
-    auto top = firstDisplayBox.rectWithMargin().top();
-    auto bottom = lastDisplayBox.rectWithMargin().bottom();
-
     auto* formattingContextRoot = &layoutBox;
     // TODO: The document renderer is not a formatting context root by default at all. Need to find out what it is.
     if (!layoutBox.establishesFormattingContext()) {
@@ -199,7 +208,7 @@
     return left;
 }
 
-LayoutUnit FormattingContext::Geometry::shrinkToFitWidth(LayoutState& layoutState, const FormattingContext& formattingContext, const Box& layoutBox)
+LayoutUnit FormattingContext::Geometry::shrinkToFitWidth(const LayoutState& layoutState, const FormattingContext& formattingContext, const Box& layoutBox)
 {
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Width] -> shrink to fit -> unsupported -> width(" << LayoutUnit { } << "px) layoutBox: " << &layoutBox << ")");
     // Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm.

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (237678 => 237679)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2018-11-01 14:20:48 UTC (rev 237679)
@@ -241,11 +241,12 @@
         displayBox.setVerticalMargin(heightAndMargin.collapsedMargin.value_or(heightAndMargin.margin));
     };
 
+    layoutState.createFormattingStateForFormattingRootIfNeeded(layoutBox);
     computeBorderAndPadding(layoutBox);
     computeWidthAndMargin();
 
     // Swich over to the new formatting context (the one that the root creates).
-    layoutState.createFormattingStateForFormattingRootIfNeeded(layoutBox).formattingContext(layoutBox)->layout();
+    layoutState.establishedFormattingState(layoutBox).formattingContext(layoutBox)->layout();
 
     // Come back and finalize the root's height and margin.
     computeHeightAndMargin();

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp (237678 => 237679)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2018-11-01 14:20:48 UTC (rev 237679)
@@ -29,18 +29,54 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "FormattingContext.h"
+#include "InlineFormattingState.h"
+#include "LayoutBox.h"
+#include "LayoutContainer.h"
+#include "LayoutFormattingState.h"
 
 namespace WebCore {
 namespace Layout {
 
-WidthAndMargin InlineFormattingContext::Geometry::inlineBlockWidthAndMargin(const LayoutState&, const Box&)
+WidthAndMargin InlineFormattingContext::Geometry::inlineBlockWidthAndMargin(const LayoutState& layoutState, const Box& formattingContextRoot)
 {
-    return { };
+    ASSERT(formattingContextRoot.isInFlow());
+
+    // 10.3.10 'Inline-block', replaced elements in normal flow
+
+    // Exactly as inline replaced elements.
+    if (formattingContextRoot.replaced())
+        return inlineReplacedWidthAndMargin(layoutState, formattingContextRoot);
+
+    // 10.3.9 'Inline-block', non-replaced elements in normal flow
+
+    // If 'width' is 'auto', the used value is the shrink-to-fit width as for floating elements.
+    // A computed value of 'auto' for 'margin-left' or 'margin-right' becomes a used value of '0'.
+    auto& containingBlock = *formattingContextRoot.containingBlock();
+    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
+    // #1
+    auto width = computedValueIfNotAuto(formattingContextRoot.style().logicalWidth(), containingBlockWidth);
+    if (!width) {
+        auto formattingContext = layoutState.establishedFormattingState(formattingContextRoot).formattingContext(formattingContextRoot);
+        width = shrinkToFitWidth(layoutState, *formattingContext, formattingContextRoot);
+    }
+
+    // #2
+    auto margin = computedNonCollapsedHorizontalMarginValue(layoutState, formattingContextRoot);
+
+    return WidthAndMargin { *width, margin, margin };
 }
 
-HeightAndMargin InlineFormattingContext::Geometry::inlineBlockHeightAndMargin(const LayoutState&, const Box&)
+HeightAndMargin InlineFormattingContext::Geometry::inlineBlockHeightAndMargin(const LayoutState& layoutState, const Box& layoutBox)
 {
-    return { };
+    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(layoutState, layoutBox);
+
+    // 10.6.6 Complicated cases
+    // - 'Inline-block', non-replaced elements.
+    return complicatedCases(layoutState, layoutBox);
 }
 
 }

Modified: trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.cpp (237678 => 237679)


--- trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.cpp	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.cpp	2018-11-01 14:20:48 UTC (rev 237679)
@@ -41,7 +41,20 @@
 {
 }
 
+bool InlineContainer::establishesInlineFormattingContext() const
+{
+    if (!isInlineBlockBox())
+        return false;
+
+    // 9.4.2 Inline formatting contexts
+    // An inline formatting context is established by a block container box that contains no block-level boxes.
+    if (auto* firstInFlowChild = this->firstInFlowChild())
+        return firstInFlowChild->isInlineLevelBox();
+
+    return false;
 }
+
 }
+}
 
 #endif

Modified: trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.h (237678 => 237679)


--- trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.h	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/layouttree/LayoutInlineContainer.h	2018-11-01 14:20:48 UTC (rev 237679)
@@ -40,6 +40,8 @@
     WTF_MAKE_ISO_ALLOCATED(InlineContainer);
 public:
     InlineContainer(std::optional<ElementAttributes>, RenderStyle&&, BaseTypeFlags = InlineContainerFlag);
+
+    bool establishesInlineFormattingContext() const final;
 };
 
 }

Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (237678 => 237679)


--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp	2018-11-01 14:20:48 UTC (rev 237679)
@@ -100,6 +100,8 @@
                 box = std::make_unique<BlockContainer>(elementAttributes(renderer), RenderStyle::clone(renderer.style()));
             else if (display == DisplayType::Inline)
                 box = std::make_unique<InlineContainer>(elementAttributes(renderer), RenderStyle::clone(renderer.style()));
+            else if (display == DisplayType::InlineBlock)
+                box = std::make_unique<InlineContainer>(elementAttributes(renderer), RenderStyle::clone(renderer.style()));
             else {
                 ASSERT_NOT_IMPLEMENTED_YET();
                 continue;

Modified: trunk/Tools/ChangeLog (237678 => 237679)


--- trunk/Tools/ChangeLog	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Tools/ChangeLog	2018-11-01 14:20:48 UTC (rev 237679)
@@ -1,3 +1,12 @@
+2018-10-31  Zalan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Add support for inline-block elements.
+        https://bugs.webkit.org/show_bug.cgi?id=191143
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
 2018-11-01  Claudio Saavedra  <csaave...@igalia.com>
 
         [WPE] Add missing libsoup patch to jhbuild

Modified: trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt (237678 => 237679)


--- trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt	2018-11-01 13:35:36 UTC (rev 237678)
+++ trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt	2018-11-01 14:20:48 UTC (rev 237679)
@@ -67,3 +67,4 @@
 fast/inline/simple-intruding-float1.html
 fast/inline/simple-intruding-floats2.html
 fast/inline/simple-intruding-floats3.html
+fast/inline/simple-inline-block.html
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to