Title: [232291] trunk/Source/WebCore
Revision
232291
Author
za...@apple.com
Date
2018-05-30 08:26:51 -0700 (Wed, 30 May 2018)

Log Message

[LFC] Miscellaneous fixes to get closer to geometry correctness
https://bugs.webkit.org/show_bug.cgi?id=186083

Reviewed by Antti Koivisto.

* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::computedBorder):
* layout/LayoutContext.cpp:
(WebCore::Layout::LayoutContext::initializeRoot):
* layout/Verification.cpp:
(WebCore::Layout::outputMismatchingBoxInformationIfNeeded):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::isStretchedToViewport):
(WebCore::Layout::initialContainingBlock):
(WebCore::Layout::computedInFlowNonReplacedComputedHeight):
(WebCore::Layout::inFlowNonReplacedComputedWidth):
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeight): lambda should capture the specification part.
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidth):
* layout/displaytree/DisplayBox.cpp:
(WebCore::Display::Box::marginBox const):
(WebCore::Display::Box::paddingBox const):
(WebCore::Display::Box::contentBox const):
* layout/layouttree/LayoutBox.cpp:
(WebCore::Layout::Box::isDocumentBox const):
(WebCore::Layout::Box::isBodyBox const):
* layout/layouttree/LayoutBox.h:
* rendering/style/BorderValue.h: ignore border-width when type is hidden or none.
(WebCore::BorderValue::boxModelWidth const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (232290 => 232291)


--- trunk/Source/WebCore/ChangeLog	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/ChangeLog	2018-05-30 15:26:51 UTC (rev 232291)
@@ -1,3 +1,34 @@
+2018-05-30  Zalan Bujtas  <za...@apple.com>
+
+        [LFC] Miscellaneous fixes to get closer to geometry correctness
+        https://bugs.webkit.org/show_bug.cgi?id=186083
+
+        Reviewed by Antti Koivisto.
+
+        * layout/FormattingContextGeometry.cpp:
+        (WebCore::Layout::FormattingContext::Geometry::computedBorder):
+        * layout/LayoutContext.cpp:
+        (WebCore::Layout::LayoutContext::initializeRoot):
+        * layout/Verification.cpp:
+        (WebCore::Layout::outputMismatchingBoxInformationIfNeeded):
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::isStretchedToViewport):
+        (WebCore::Layout::initialContainingBlock):
+        (WebCore::Layout::computedInFlowNonReplacedComputedHeight):
+        (WebCore::Layout::inFlowNonReplacedComputedWidth):
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeight): lambda should capture the specification part. 
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedWidth):
+        * layout/displaytree/DisplayBox.cpp:
+        (WebCore::Display::Box::marginBox const):
+        (WebCore::Display::Box::paddingBox const):
+        (WebCore::Display::Box::contentBox const):
+        * layout/layouttree/LayoutBox.cpp:
+        (WebCore::Layout::Box::isDocumentBox const):
+        (WebCore::Layout::Box::isBodyBox const):
+        * layout/layouttree/LayoutBox.h:
+        * rendering/style/BorderValue.h: ignore border-width when type is hidden or none. 
+        (WebCore::BorderValue::boxModelWidth const):
+
 2018-05-30  Stephen McGruer  <smcgr...@chromium.org>
 
         iOS: setting 'defaultValue' of input type=date from script should cause a UI update

Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (232290 => 232291)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2018-05-30 15:26:51 UTC (rev 232291)
@@ -529,10 +529,10 @@
 {
     auto& style = layoutBox.style();
     return {
-        style.borderTop().width(),
-        style.borderLeft().width(),
-        style.borderBottom().width(),
-        style.borderRight().width()
+        style.borderTop().boxModelWidth(),
+        style.borderLeft().boxModelWidth(),
+        style.borderBottom().boxModelWidth(),
+        style.borderRight().boxModelWidth()
     };
 }
 

Modified: trunk/Source/WebCore/layout/LayoutContext.cpp (232290 => 232291)


--- trunk/Source/WebCore/layout/LayoutContext.cpp	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/LayoutContext.cpp	2018-05-30 15:26:51 UTC (rev 232291)
@@ -61,12 +61,12 @@
     displayBox.setMargin({ });
 
     auto& style = root.style();
-    // FIXME: m_root could very well be a formatting context root with ancestors and resolvable border and padding (as opposed to the topmost root)  
+    // FIXME: m_root could very well be a formatting context root with ancestors and resolvable border and padding (as opposed to the topmost root)
     displayBox.setBorder({
-        style.borderTop().width(),
-        style.borderLeft().width(),
-        style.borderBottom().width(),
-        style.borderRight().width()
+        style.borderTop().boxModelWidth(),
+        style.borderLeft().boxModelWidth(),
+        style.borderBottom().boxModelWidth(),
+        style.borderRight().boxModelWidth()
     });
 
     displayBox.setPadding({

Modified: trunk/Source/WebCore/layout/Verification.cpp (232290 => 232291)


--- trunk/Source/WebCore/layout/Verification.cpp	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/Verification.cpp	2018-05-30 15:26:51 UTC (rev 232291)
@@ -68,7 +68,7 @@
     if (renderer.paddingBoxRect() != displayBox->paddingBox())
         outputRect("paddingBox", renderer.paddingBoxRect(), displayBox->paddingBox());
 
-    if (renderer.marginBoxRect() != displayBox->contentBox())
+    if (renderer.contentBoxRect() != displayBox->contentBox())
         outputRect("contentBox", renderer.contentBoxRect(), displayBox->contentBox());
 
     stream.nextLine();

Modified: trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp (232290 => 232291)


--- trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp	2018-05-30 15:26:51 UTC (rev 232291)
@@ -33,55 +33,84 @@
 namespace WebCore {
 namespace Layout {
 
+static bool isStretchedToViewport(const Box& layoutBox)
+{
+    ASSERT(layoutBox.isInFlow());
+    // In quirks mode, body and html stretch to the viewport.
+    // if (!layoutBox.document().inQuirksMode())
+    //    return false;
+
+    if (!layoutBox.isDocumentBox() || !layoutBox.isBodyBox())
+        return false;
+
+    return layoutBox.style().logicalHeight().isAuto();
+}
+
+static const Container& initialContainingBlock(const Box& layoutBox)
+{
+    auto* containingBlock = layoutBox.containingBlock();
+    while (containingBlock->containingBlock())
+        containingBlock = containingBlock->containingBlock();
+    return *containingBlock;
+}
+
 LayoutUnit BlockFormattingContext::Geometry::inFlowNonReplacedHeight(LayoutContext& layoutContext, const Box& layoutBox)
 {
     ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
 
-    // https://www.w3.org/TR/CSS22/visudet.html
-    // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
-    // The element's height is the distance from its top content edge to the first applicable of the following:
-    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
-    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
-    //    does not collapse with the element's bottom margin
-    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
-    // 4. zero, otherwise
-    // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
-    // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
-    if (!layoutBox.style().logicalHeight().isAuto()) {
-        // FIXME: Only fixed values yet.
-        return layoutBox.style().logicalHeight().value();
-    }
+    auto compute = [&]() -> LayoutUnit {
+        // https://www.w3.org/TR/CSS22/visudet.html
+        // If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
+        // The element's height is the distance from its top content edge to the first applicable of the following:
+        // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+        // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin
+        //    does not collapse with the element's bottom margin
+        // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+        // 4. zero, otherwise
+        // Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored,
+        // and relatively positioned boxes are considered without their offset). Note that the child box may be an anonymous block box.
+        if (!layoutBox.style().logicalHeight().isAuto()) {
+            // FIXME: Only fixed values yet.
+            return layoutBox.style().logicalHeight().value();
+        }
 
-    if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
-        return 0;
+        if (!is<Container>(layoutBox) || !downcast<Container>(layoutBox).hasInFlowChild())
+            return 0;
 
-    // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
-    if (layoutBox.establishesInlineFormattingContext()) {
-        // height = lastLineBox().bottom();
-        return 0;
-    }
+        // 1. the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
+        if (layoutBox.establishesInlineFormattingContext()) {
+            // height = lastLineBox().bottom();
+            return 0;
+        }
 
-    // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
-    auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
-    ASSERT(lastInFlowChild);
-    if (!BlockFormattingContext::MarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
-        auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
-        ASSERT(lastInFlowDisplayBox);
-        return lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom();
-    }
+        // 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
+        auto* lastInFlowChild = downcast<Container>(layoutBox).lastInFlowChild();
+        ASSERT(lastInFlowChild);
+        if (!BlockFormattingContext::MarginCollapse::isMarginBottomCollapsedWithParent(*lastInFlowChild)) {
+            auto* lastInFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*lastInFlowChild);
+            ASSERT(lastInFlowDisplayBox);
+            return lastInFlowDisplayBox->bottom() + lastInFlowDisplayBox->marginBottom();
+        }
 
-    // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
-    auto* inFlowChild = lastInFlowChild;
-    while (inFlowChild && BlockFormattingContext::MarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
-        inFlowChild = inFlowChild->previousInFlowSibling();
-    if (inFlowChild) {
-        auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
-        ASSERT(inFlowDisplayBox);
-        return inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height();
-    }
+        // 3. the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
+        auto* inFlowChild = lastInFlowChild;
+        while (inFlowChild && BlockFormattingContext::MarginCollapse::isMarginTopCollapsedWithParentMarginBottom(*inFlowChild))
+            inFlowChild = inFlowChild->previousInFlowSibling();
+        if (inFlowChild) {
+            auto* inFlowDisplayBox = layoutContext.displayBoxForLayoutBox(*inFlowChild);
+            ASSERT(inFlowDisplayBox);
+            return inFlowDisplayBox->top() + inFlowDisplayBox->borderBox().height();
+        }
 
-    // 4. zero, otherwise
-    return 0;
+        // 4. zero, otherwise
+        return 0;
+    };
+
+    auto computedHeight = compute();
+    if (!isStretchedToViewport(layoutBox))
+        return computedHeight;
+    auto initialContainingBlockHeight = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox))->contentBox().height();
+    return std::max(computedHeight, initialContainingBlockHeight);
 }
 
 LayoutUnit BlockFormattingContext::Geometry::inFlowNonReplacedWidth(LayoutContext& layoutContext, const Box& layoutBox)
@@ -88,32 +117,40 @@
 {
     ASSERT(layoutBox.isInFlow() && !layoutBox.replaced());
 
-    // 10.3.3 Block-level, non-replaced elements in normal flow
-    // The following constraints must hold among the used values of the other properties:
-    // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
+    auto compute = [&]() {
+        // 10.3.3 Block-level, non-replaced elements in normal flow
+        // The following constraints must hold among the used values of the other properties:
+        // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
 
-    // If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
-    auto& style = layoutBox.style();
-    auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
+        // If 'width' is set to 'auto', any other 'auto' values become '0' and 'width' follows from the resulting equality.
+        auto& style = layoutBox.style();
+        auto containingBlockWidth = layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock())->width();
 
-    LayoutUnit computedWidthValue;
-    auto width = style.logicalWidth();
-    if (width.isAuto()) {
-        auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
-        auto marginLeft = displayBox.marginLeft();
-        auto marginRight = displayBox.marginRight();
+        LayoutUnit computedWidthValue;
+        auto width = style.logicalWidth();
+        if (width.isAuto()) {
+            auto& displayBox = *layoutContext.displayBoxForLayoutBox(layoutBox);
+            auto marginLeft = displayBox.marginLeft();
+            auto marginRight = displayBox.marginRight();
 
-        auto paddingLeft = displayBox.paddingLeft();
-        auto paddingRight = displayBox.paddingRight();
+            auto paddingLeft = displayBox.paddingLeft();
+            auto paddingRight = displayBox.paddingRight();
 
-        auto borderLeft = displayBox.borderLeft();
-        auto borderRight = displayBox.borderRight();
+            auto borderLeft = displayBox.borderLeft();
+            auto borderRight = displayBox.borderRight();
 
-        computedWidthValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight);
-    } else
-        computedWidthValue = valueForLength(width, containingBlockWidth);
+            computedWidthValue = containingBlockWidth - (marginLeft + borderLeft + paddingLeft + paddingRight + borderRight + marginRight);
+        } else
+            computedWidthValue = valueForLength(width, containingBlockWidth);
 
-    return computedWidthValue;
+        return computedWidthValue;
+    };
+
+    auto computedWidth = compute();
+    if (!isStretchedToViewport(layoutBox))
+        return computedWidth;
+    auto initialContainingBlockWidth = layoutContext.displayBoxForLayoutBox(initialContainingBlock(layoutBox))->contentBox().width();
+    return std::max(computedWidth, initialContainingBlockWidth);
 }
 
 LayoutPoint BlockFormattingContext::Geometry::staticPosition(LayoutContext& layoutContext, const Box& layoutBox)

Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp (232290 => 232291)


--- trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.cpp	2018-05-30 15:26:51 UTC (rev 232291)
@@ -56,7 +56,7 @@
     auto marginBox = borderBox();
 
     marginBox.shiftLeftTo(marginBox.left() + m_margin.left);
-    marginBox.shiftBottomTo(marginBox.top() + m_margin.top);
+    marginBox.shiftTopTo(marginBox.top() + m_margin.top);
     marginBox.shiftRightTo(marginBox.right() - m_margin.right);
     marginBox.shiftBottomTo(marginBox.bottom() - m_margin.bottom);
 
@@ -85,7 +85,7 @@
 
     paddingBox.shiftLeftTo(paddingBox.left() + m_border.left);
     paddingBox.shiftTopTo(paddingBox.top() + m_border.top);
-    paddingBox.shiftRightTo(paddingBox.left() - m_border.right);
+    paddingBox.shiftRightTo(paddingBox.right() - m_border.right);
     paddingBox.shiftBottomTo(paddingBox.bottom() - m_border.bottom);
 
     return paddingBox;
@@ -105,8 +105,8 @@
 
     contentBox.shiftLeftTo(contentBox.left() + m_padding.left);
     contentBox.shiftTopTo(contentBox.top() + m_padding.top);
+    contentBox.shiftRightTo(contentBox.right() - m_padding.right);
     contentBox.shiftBottomTo(contentBox.bottom() - m_padding.bottom);
-    contentBox.shiftRightTo(contentBox.right() - m_padding.right);
 
     return contentBox;
 }

Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp (232290 => 232291)


--- trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.cpp	2018-05-30 15:26:51 UTC (rev 232291)
@@ -181,6 +181,18 @@
     return !parent();
 }
 
+bool Box::isDocumentBox() const
+{
+    // return document().documentElement() == &element();
+    return false;
+}
+
+bool Box::isBodyBox() const
+{
+    // return element().hasTagName(HTMLNames::bodyTag);
+    return false;
+}
+
 const Box* Box::nextInFlowSibling() const
 {
     if (auto* nextSibling = this->nextSibling()) {

Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (232290 => 232291)


--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h	2018-05-30 15:26:51 UTC (rev 232291)
@@ -74,6 +74,9 @@
     bool isBlockContainerBox() const;
     bool isInitialContainingBlock() const;
 
+    bool isDocumentBox() const;
+    bool isBodyBox() const;
+
     const Container* parent() const { return m_parent; }
     const Box* nextSibling() const { return m_nextSibling; }
     const Box* nextInFlowSibling() const;

Modified: trunk/Source/WebCore/rendering/style/BorderValue.h (232290 => 232291)


--- trunk/Source/WebCore/rendering/style/BorderValue.h	2018-05-30 14:13:22 UTC (rev 232290)
+++ trunk/Source/WebCore/rendering/style/BorderValue.h	2018-05-30 15:26:51 UTC (rev 232291)
@@ -72,6 +72,8 @@
 
     float width() const { return m_width; }
     BorderStyle style() const { return static_cast<BorderStyle>(m_style); }
+    
+    float boxModelWidth() const;
 
 protected:
     float m_width { 3 };
@@ -83,4 +85,13 @@
     unsigned m_isAuto : 1; // OutlineIsAuto
 };
 
+inline float BorderValue::boxModelWidth() const
+{
+    auto style = this->style();
+    if (style == BorderStyle::None || style == BorderStyle::Hidden)
+        return 0;
+
+    return width();
+}
+
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to