[LFC] Adjust static position for out-of-flow positioned boxes.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jun 2018 01:22:10 +0000 (01:22 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 26 Jun 2018 01:22:10 +0000 (01:22 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187000

Reviewed by Antti Koivisto.

The static position of an out-of-flow positioned box is the the position where box would go
if it was in-flow positioned. This position needs to the resolved in the containing block's coordinate system.

* layout/blockformatting/BlockFormattingContext.h:
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin):
(WebCore::Layout::BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned):
(WebCore::Layout::BlockFormattingContext::Geometry::staticPosition):

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

Source/WebCore/ChangeLog
Source/WebCore/layout/blockformatting/BlockFormattingContext.h
Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp

index ee8b94e..0e5c357 100644 (file)
@@ -1,3 +1,19 @@
+2018-06-25  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC] Adjust static position for out-of-flow positioned boxes.
+        https://bugs.webkit.org/show_bug.cgi?id=187000
+
+        Reviewed by Antti Koivisto.
+
+        The static position of an out-of-flow positioned box is the the position where box would go
+        if it was in-flow positioned. This position needs to the resolved in the containing block's coordinate system.
+
+        * layout/blockformatting/BlockFormattingContext.h:
+        * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+        (WebCore::Layout::BlockFormattingContext::Geometry::inFlowReplacedWidthAndMargin):
+        (WebCore::Layout::BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned):
+        (WebCore::Layout::BlockFormattingContext::Geometry::staticPosition):
+
 2018-06-25  Brady Eidson  <beidson@apple.com>
 
         Remove RELEASE_ASSERT added in r230875.
index 5072851..311b229 100644 (file)
@@ -72,6 +72,7 @@ private:
         static FormattingContext::Geometry::HeightAndMargin inFlowNonReplacedHeightAndMargin(LayoutContext&, const Box&);
         static FormattingContext::Geometry::WidthAndMargin inFlowNonReplacedWidthAndMargin(LayoutContext&, const Box&, std::optional<LayoutUnit> precomputedWidth = std::nullopt);
         static FormattingContext::Geometry::WidthAndMargin inFlowReplacedWidthAndMargin(LayoutContext&, const Box&);
+        static FormattingContext::Geometry::Position staticPositionForOutOfFlowPositioned(const LayoutContext&, const Box&);
     };
     
     // This class implements margin collapsing for block formatting context.
index 5b71b49..345c800 100644 (file)
@@ -262,6 +262,32 @@ FormattingContext::Geometry::WidthAndMargin BlockFormattingContext::Geometry::in
     return { width, margin };
 }
 
+FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPositionForOutOfFlowPositioned(const LayoutContext& layoutContext, const Box& layoutBox)
+{
+    // FIXME: This is certainly only really needed when top/bottom left/right are auto.
+    ASSERT(layoutBox.isOutOfFlowPositioned());
+    LayoutUnit top;
+    LayoutUnit left;
+    // Resolve top/left all the way up to the containing block.
+    auto* containingBlock = layoutBox.containingBlock();
+    for (auto* parent = layoutBox.parent(); parent; parent = parent->parent()) {
+        auto& displayBox = *layoutContext.displayBoxForLayoutBox(*parent);
+        top += (displayBox.top() + displayBox.contentBoxTop());
+        left += (displayBox.left() + displayBox.contentBoxLeft());
+        if (parent == containingBlock)
+            break;
+    }
+    // Add sibling offset
+    if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
+        auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
+        top += previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom();
+    }
+
+    LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> out-of-flow -> static -> top(" << top << "px) left(" << left << "px) layoutBox(" << &layoutBox << ")");
+    return { left, top };
+}
+
+
 FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPosition(LayoutContext& layoutContext, const Box& layoutBox)
 {
     // https://www.w3.org/TR/CSS22/visuren.html#block-formatting
@@ -270,13 +296,17 @@ FormattingContext::Geometry::Position BlockFormattingContext::Geometry::staticPo
     // Vertical margins between adjacent block-level boxes in a block formatting context collapse.
     // In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).
 
-    auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
+    if (layoutBox.isOutOfFlowPositioned())
+        return staticPositionForOutOfFlowPositioned(layoutContext, layoutBox);
+
     LayoutUnit top;
+    auto& containingBlockDisplayBox = *layoutContext.displayBoxForLayoutBox(*layoutBox.containingBlock());
     if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
         auto& previousInFlowDisplayBox = *layoutContext.displayBoxForLayoutBox(*previousInFlowSibling);
         top = previousInFlowDisplayBox.bottom() + previousInFlowDisplayBox.marginBottom();
     } else
         top = containingBlockDisplayBox.contentBoxTop();
+
     auto left = containingBlockDisplayBox.contentBoxLeft();
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position] -> static -> top(" << top << "px) left(" << left << "px) layoutBox(" << &layoutBox << ")");
     return { left, top };