Title: [239983] trunk
Revision
239983
Author
[email protected]
Date
2019-01-15 06:48:54 -0800 (Tue, 15 Jan 2019)

Log Message

[LFC] Use the containing block's padding box to position out-of-flow elements.
https://bugs.webkit.org/show_bug.cgi?id=193431

Reviewed by Antti Koivisto.

Source/WebCore:

If the element has 'position: absolute', the containing block is established by the nearest ancestor
with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:

1. In the case that the ancestor is an inline element, the containing block is the bounding box around the padding
boxes of the first and the last inline boxes generated for that element. In CSS 2.2, if the inline element is split
across multiple lines, the containing block is undefined.

2. Otherwise, the containing block is formed by the padding edge of the ancestor.

This patch covers #2.

Test: fast/block/block-only/out-of-flow-with-containing-block-border-padding.html

* layout/displaytree/DisplayBox.h:
(WebCore::Display::Box::width const):
(WebCore::Display::Box::height const):
(WebCore::Display::Box::contentBoxTop const):
(WebCore::Display::Box::contentBoxLeft const):
(WebCore::Display::Box::paddingBoxTop const):
(WebCore::Display::Box::paddingBoxLeft const):
(WebCore::Display::Box::paddingBoxBottom const):
(WebCore::Display::Box::paddingBoxRight const):
(WebCore::Display::Box::paddingBoxHeight const):
(WebCore::Display::Box::paddingBoxWidth const):
* page/FrameViewLayoutContext.cpp:
(WebCore::layoutUsingFormattingContext):

Tools:

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

LayoutTests:

* fast/block/block-only/out-of-flow-with-containing-block-border-padding-expected.txt: Added.
* fast/block/block-only/out-of-flow-with-containing-block-border-padding.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (239982 => 239983)


--- trunk/LayoutTests/ChangeLog	2019-01-15 13:14:27 UTC (rev 239982)
+++ trunk/LayoutTests/ChangeLog	2019-01-15 14:48:54 UTC (rev 239983)
@@ -1,3 +1,13 @@
+2019-01-15  Zalan Bujtas  <[email protected]>
+
+        [LFC] Use the containing block's padding box to position out-of-flow elements.
+        https://bugs.webkit.org/show_bug.cgi?id=193431
+
+        Reviewed by Antti Koivisto.
+
+        * fast/block/block-only/out-of-flow-with-containing-block-border-padding-expected.txt: Added.
+        * fast/block/block-only/out-of-flow-with-containing-block-border-padding.html: Added.
+
 2019-01-15  Guillaume Emont  <[email protected]>
 
         Skip a slow test and a flakey test on arm

Added: trunk/LayoutTests/fast/block/block-only/out-of-flow-with-containing-block-border-padding-expected.txt (0 => 239983)


--- trunk/LayoutTests/fast/block/block-only/out-of-flow-with-containing-block-border-padding-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/block/block-only/out-of-flow-with-containing-block-border-padding-expected.txt	2019-01-15 14:48:54 UTC (rev 239983)
@@ -0,0 +1,33 @@
+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
+layer at (8,8) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,0) size 56x56 [border: (3px solid #008000)]
+layer at (21,13) size 10x10
+  RenderBlock (positioned) {DIV} at (13,5) size 10x10 [bgcolor=#0000FF]
+layer at (8,64) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,56) size 56x56 [border: (3px solid #008000)]
+layer at (21,105) size 10x10
+  RenderBlock (positioned) {DIV} at (13,41) size 10x10 [bgcolor=#0000FF]
+layer at (8,120) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,112) size 56x56 [border: (3px solid #008000)]
+layer at (21,125) size 10x46
+  RenderBlock (positioned) {DIV} at (13,5) size 10x46 [bgcolor=#0000FF]
+layer at (8,176) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,168) size 56x56 [border: (3px solid #008000)]
+layer at (13,189) size 10x10
+  RenderBlock (positioned) {DIV} at (5,13) size 10x10 [bgcolor=#0000FF]
+layer at (8,232) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,224) size 56x56 [border: (3px solid #008000)]
+layer at (49,245) size 10x10
+  RenderBlock (positioned) {DIV} at (41,13) size 10x10 [bgcolor=#0000FF]
+layer at (8,288) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,280) size 56x56 [border: (3px solid #008000)]
+layer at (13,301) size 46x10
+  RenderBlock (positioned) {DIV} at (5,13) size 46x10 [bgcolor=#0000FF]
+layer at (8,344) size 56x56
+  RenderBlock (relative positioned) {DIV} at (0,336) size 56x56 [border: (3px solid #008000)]
+layer at (13,349) size 46x46
+  RenderBlock (positioned) {DIV} at (5,5) size 46x46 [bgcolor=#0000FF]

Added: trunk/LayoutTests/fast/block/block-only/out-of-flow-with-containing-block-border-padding.html (0 => 239983)


--- trunk/LayoutTests/fast/block/block-only/out-of-flow-with-containing-block-border-padding.html	                        (rev 0)
+++ trunk/LayoutTests/fast/block/block-only/out-of-flow-with-containing-block-border-padding.html	2019-01-15 14:48:54 UTC (rev 239983)
@@ -0,0 +1,35 @@
+<style>
+.container {
+	border: 3px solid green;
+	padding: 10px;
+    height: 30px;
+    width: 30px;
+    position: relative;
+}
+
+div div {
+	background: blue;
+    position: absolute;
+}
+</style>
+<div class=container>
+    <div style="top: 2px; width: 10px; height: 10px"></div>
+</div>
+<div class=container>
+    <div style="bottom: 2px; width: 10px; height: 10px"></div>
+</div>
+<div class=container>
+    <div style="top: 2px; bottom: 2px; width: 10px;"></div>
+</div>
+<div class=container>
+    <div style="left: 2px; width: 10px; height: 10px"></div>
+</div>
+<div class=container>
+    <div style="right: 2px; width: 10px; height: 10px"></div>
+</div>
+<div class=container>
+    <div style="left: 2px; right: 2px; height: 10px;"></div>
+</div>
+<div class=container>
+    <div style="top: 2px; left: 2px; right: 2px; bottom: 2px;"></div>
+</div>

Modified: trunk/Source/WebCore/ChangeLog (239982 => 239983)


--- trunk/Source/WebCore/ChangeLog	2019-01-15 13:14:27 UTC (rev 239982)
+++ trunk/Source/WebCore/ChangeLog	2019-01-15 14:48:54 UTC (rev 239983)
@@ -1,3 +1,37 @@
+2019-01-15  Zalan Bujtas  <[email protected]>
+
+        [LFC] Use the containing block's padding box to position out-of-flow elements.
+        https://bugs.webkit.org/show_bug.cgi?id=193431
+
+        Reviewed by Antti Koivisto.
+
+        If the element has 'position: absolute', the containing block is established by the nearest ancestor
+        with a 'position' of 'absolute', 'relative' or 'fixed', in the following way:
+
+        1. In the case that the ancestor is an inline element, the containing block is the bounding box around the padding
+        boxes of the first and the last inline boxes generated for that element. In CSS 2.2, if the inline element is split
+        across multiple lines, the containing block is undefined.
+
+        2. Otherwise, the containing block is formed by the padding edge of the ancestor.
+
+        This patch covers #2. 
+
+        Test: fast/block/block-only/out-of-flow-with-containing-block-border-padding.html
+
+        * layout/displaytree/DisplayBox.h:
+        (WebCore::Display::Box::width const):
+        (WebCore::Display::Box::height const):
+        (WebCore::Display::Box::contentBoxTop const):
+        (WebCore::Display::Box::contentBoxLeft const):
+        (WebCore::Display::Box::paddingBoxTop const):
+        (WebCore::Display::Box::paddingBoxLeft const):
+        (WebCore::Display::Box::paddingBoxBottom const):
+        (WebCore::Display::Box::paddingBoxRight const):
+        (WebCore::Display::Box::paddingBoxHeight const):
+        (WebCore::Display::Box::paddingBoxWidth const):
+        * page/FrameViewLayoutContext.cpp:
+        (WebCore::layoutUsingFormattingContext):
+
 2019-01-11  Antoine Quint  <[email protected]>
 
         Support parsing of additional values for the touch-action property

Modified: trunk/Source/WebCore/layout/FormattingContextGeometry.cpp (239982 => 239983)


--- trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2019-01-15 13:14:27 UTC (rev 239982)
+++ trunk/Source/WebCore/layout/FormattingContextGeometry.cpp	2019-01-15 14:48:54 UTC (rev 239983)
@@ -273,11 +273,12 @@
     auto& style = layoutBox.style();
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     auto& containingBlockDisplayBox = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock());
-    auto containingBlockHeight = containingBlockDisplayBox.height();
-    auto containingBlockWidth = containingBlockDisplayBox.width();
+    auto containingBlockHeight = containingBlockDisplayBox.paddingBoxHeight();
+    auto containingBlockWidth = containingBlockDisplayBox.paddingBoxWidth();
 
     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
+    auto isStaticallyPositioned = !top && !bottom;
     auto height = usedHeight ? usedHeight.value() : computedHeightValue(layoutState, layoutBox, HeightType::Normal);
     auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
     UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
@@ -353,6 +354,14 @@
     ASSERT(bottom);
     ASSERT(height);
 
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the non-statically positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    if (!isStaticallyPositioned) {
+        auto containingBlockPaddingVerticalEdge = containingBlockDisplayBox.paddingBoxTop();
+        *top += containingBlockPaddingVerticalEdge;
+        *bottom += containingBlockPaddingVerticalEdge;
+    }
+
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow non-replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << *height << "px) margin(" << usedVerticalMargin.before << "px, "  << usedVerticalMargin.after << "px) layoutBox(" << &layoutBox << ")");
     return { *top, *bottom, { contentHeight(), usedVerticalMargin } };
 }
@@ -390,11 +399,13 @@
     auto& style = layoutBox.style();
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     auto& containingBlock = *layoutBox.containingBlock();
-    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
+    auto& containingBlockDisplayBox = layoutState.displayBoxForLayoutBox(containingBlock);
+    auto containingBlockWidth = containingBlockDisplayBox.paddingBoxWidth();
     auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();
     
     auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
     auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth);
+    auto isStaticallyPositioned = !left && !right;
     auto width = computedValueIfNotAuto(usedWidth ? Length { usedWidth.value(), Fixed } : style.logicalWidth(), containingBlockWidth);
     auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState, layoutBox);
     UsedHorizontalMargin usedHorizontalMargin;
@@ -496,6 +507,14 @@
     ASSERT(right);
     ASSERT(width);
 
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the non-statically positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    if (!isStaticallyPositioned) {
+        auto containingBlockPaddingVerticalEdge = containingBlockDisplayBox.paddingBoxLeft();
+        *left += containingBlockPaddingVerticalEdge;
+        *right += containingBlockPaddingVerticalEdge;
+    }
+
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Width][Margin] -> out-of-flow non-replaced -> left(" << *left << "px) right("  << *right << "px) width(" << *width << "px) margin(" << usedHorizontalMargin.start << "px, "  << usedHorizontalMargin.end << "px) layoutBox(" << &layoutBox << ")");
     return { *left, *right, { contentWidth(), usedHorizontalMargin, computedHorizontalMargin } };
 }
@@ -517,11 +536,12 @@
     auto& style = layoutBox.style();
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     auto& containingBlockDisplayBox = layoutState.displayBoxForLayoutBox(*layoutBox.containingBlock());
-    auto containingBlockHeight = containingBlockDisplayBox.height();
-    auto containingBlockWidth = containingBlockDisplayBox.width();
+    auto containingBlockHeight = containingBlockDisplayBox.paddingBoxHeight();
+    auto containingBlockWidth = containingBlockDisplayBox.paddingBoxWidth();
 
     auto top = computedValueIfNotAuto(style.logicalTop(), containingBlockWidth);
     auto bottom = computedValueIfNotAuto(style.logicalBottom(), containingBlockWidth);
+    auto isStaticallyPositioned = !top && !bottom;
     auto height = inlineReplacedHeightAndMargin(layoutState, layoutBox, usedHeight).height;
     auto computedVerticalMargin = Geometry::computedVerticalMargin(layoutState, layoutBox);
     UsedVerticalMargin::NonCollapsedValues usedVerticalMargin; 
@@ -564,6 +584,14 @@
     if (boxHeight > containingBlockHeight)
         bottom = containingBlockHeight - (*top + usedVerticalMargin.before + borderTop + paddingTop + height + paddingBottom + borderBottom + usedVerticalMargin.after); 
 
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the non-statically positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    if (!isStaticallyPositioned) {
+        auto containingBlockPaddingVerticalEdge = containingBlockDisplayBox.paddingBoxTop();
+        *top += containingBlockPaddingVerticalEdge;
+        *bottom += containingBlockPaddingVerticalEdge;
+    }
+
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Height][Margin] -> out-of-flow replaced -> top(" << *top << "px) bottom("  << *bottom << "px) height(" << height << "px) margin(" << usedVerticalMargin.before << "px, "  << usedVerticalMargin.after << "px) layoutBox(" << &layoutBox << ")");
     return { *top, *bottom, { height, usedVerticalMargin } };
 }
@@ -589,11 +617,13 @@
     auto& style = layoutBox.style();
     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     auto& containingBlock = *layoutBox.containingBlock();
-    auto containingBlockWidth = layoutState.displayBoxForLayoutBox(containingBlock).contentBoxWidth();
+    auto& containingBlockDisplayBox = layoutState.displayBoxForLayoutBox(containingBlock);
+    auto containingBlockWidth = containingBlockDisplayBox.paddingBoxWidth();
     auto isLeftToRightDirection = containingBlock.style().isLeftToRightDirection();
 
     auto left = computedValueIfNotAuto(style.logicalLeft(), containingBlockWidth);
     auto right = computedValueIfNotAuto(style.logicalRight(), containingBlockWidth);
+    auto isStaticallyPositioned = !left && !right;
     auto computedHorizontalMargin = Geometry::computedHorizontalMargin(layoutState, layoutBox);
     UsedHorizontalMargin usedHorizontalMargin;
     auto width = inlineReplacedWidthAndMargin(layoutState, layoutBox, usedWidth).width;
@@ -657,6 +687,14 @@
     ASSERT(left);
     ASSERT(right);
 
+    // For out-of-flow elements the containing block is formed by the padding edge of the ancestor.
+    // At this point the non-statically positioned value is in the coordinate system of the padding box. Let's convert it to border box coordinate system.
+    if (isStaticallyPositioned) {
+        auto containingBlockPaddingVerticalEdge = containingBlockDisplayBox.paddingBoxLeft();
+        *left += containingBlockPaddingVerticalEdge;
+        *right += containingBlockPaddingVerticalEdge;
+    }
+
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Position][Width][Margin] -> out-of-flow replaced -> left(" << *left << "px) right("  << *right << "px) width(" << width << "px) margin(" << usedHorizontalMargin.start << "px, "  << usedHorizontalMargin.end << "px) layoutBox(" << &layoutBox << ")");
     return { *left, *right, { width, usedHorizontalMargin, computedHorizontalMargin } };
 }

Modified: trunk/Source/WebCore/layout/displaytree/DisplayBox.h (239982 => 239983)


--- trunk/Source/WebCore/layout/displaytree/DisplayBox.h	2019-01-15 13:14:27 UTC (rev 239982)
+++ trunk/Source/WebCore/layout/displaytree/DisplayBox.h	2019-01-15 14:48:54 UTC (rev 239983)
@@ -133,8 +133,8 @@
     LayoutPoint bottomRight() const { return { right(), bottom() }; }
 
     LayoutSize size() const { return { width(), height() }; }
-    LayoutUnit width() const { return borderLeft() + paddingLeft().valueOr(0) + contentBoxWidth() + paddingRight().valueOr(0) + borderRight(); }
-    LayoutUnit height() const { return borderTop() + paddingTop().valueOr(0) + contentBoxHeight() + paddingBottom().valueOr(0) + borderBottom(); }
+    LayoutUnit width() const { return borderLeft() + paddingBoxWidth() + borderRight(); }
+    LayoutUnit height() const { return borderTop() + paddingBoxHeight() + borderBottom(); }
     Rect rect() const { return { top(), left(), width(), height() }; }
     Rect rectWithMargin() const;
 
@@ -160,13 +160,20 @@
     Optional<LayoutUnit> paddingBottom() const;
     Optional<LayoutUnit> paddingRight() const;
 
-    LayoutUnit contentBoxTop() const { return borderTop() + paddingTop().valueOr(0); }
-    LayoutUnit contentBoxLeft() const { return borderLeft() + paddingLeft().valueOr(0); }
+    LayoutUnit contentBoxTop() const { return paddingBoxTop() + paddingTop().valueOr(0); }
+    LayoutUnit contentBoxLeft() const { return paddingBoxLeft() + paddingLeft().valueOr(0); }
     LayoutUnit contentBoxBottom() const { return contentBoxTop() + contentBoxHeight(); }
     LayoutUnit contentBoxRight() const { return contentBoxLeft() + contentBoxWidth(); }
     LayoutUnit contentBoxHeight() const;
     LayoutUnit contentBoxWidth() const;
 
+    LayoutUnit paddingBoxTop() const { return borderTop(); }
+    LayoutUnit paddingBoxLeft() const { return borderLeft(); }
+    LayoutUnit paddingBoxBottom() const { return paddingBoxTop() + paddingBoxHeight(); }
+    LayoutUnit paddingBoxRight() const { return paddingBoxLeft() + paddingBoxWidth(); }
+    LayoutUnit paddingBoxHeight() const { return paddingTop().valueOr(0) + contentBoxHeight() + paddingBottom().valueOr(0); }
+    LayoutUnit paddingBoxWidth() const { return paddingLeft().valueOr(0) + contentBoxWidth() + paddingRight().valueOr(0); }
+
     Rect marginBox() const;
     Rect nonCollapsedMarginBox() const;
 

Modified: trunk/Tools/ChangeLog (239982 => 239983)


--- trunk/Tools/ChangeLog	2019-01-15 13:14:27 UTC (rev 239982)
+++ trunk/Tools/ChangeLog	2019-01-15 14:48:54 UTC (rev 239983)
@@ -1,3 +1,12 @@
+2019-01-15  Zalan Bujtas  <[email protected]>
+
+        [LFC] Use the containing block's padding box to position out-of-flow elements.
+        https://bugs.webkit.org/show_bug.cgi?id=193431
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/misc/LFC-passing-tests.txt:
+
 2019-01-14  Tim Horton  <[email protected]>
 
         Move a test implementation file that got misplaced in the Xcode project

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


--- trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt	2019-01-15 13:14:27 UTC (rev 239982)
+++ trunk/Tools/LayoutReloaded/misc/LFC-passing-tests.txt	2019-01-15 14:48:54 UTC (rev 239983)
@@ -77,6 +77,7 @@
 fast/block/block-only/relative-siblings.html
 fast/block/block-only/relative-simple.html
 fast/block/block-only/box-sizing-inflow-out-of-flow-simple.html
+fast/block/block-only/out-of-flow-with-containing-block-border-padding.html
 fast/block/basic/002.html
 fast/block/basic/003.html
 fast/block/basic/006.html
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to