[LayoutReloaded] BlockFormattingContext::placePositionedDescendants takes care of...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Mar 2018 00:24:57 +0000 (00:24 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 18 Mar 2018 00:24:57 +0000 (00:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183727

Reviewed by Antti Koivisto.

* LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js:
(BlockFormattingContext.prototype.layout):
(BlockFormattingContext.prototype._placePositionedDescendants):
(BlockFormattingContext.prototype._placeInFlowPositionedChildren):
(BlockFormattingContext.prototype._placeOutOfFlowDescendants):
* LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context.html: Added.
* LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context2.html: Added.
* LayoutReloaded/test/index.html:
* LayoutReloaded/test/relative-position-when-containing-block-is-not-in-the-formatting-context.html: Added.

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

Tools/ChangeLog
Tools/LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js
Tools/LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context.html [new file with mode: 0644]
Tools/LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context2.html [new file with mode: 0644]
Tools/LayoutReloaded/test/index.html
Tools/LayoutReloaded/test/relative-position-when-containing-block-is-not-in-the-formatting-context.html [new file with mode: 0644]

index 3727e97..bbe1934 100644 (file)
@@ -1,5 +1,22 @@
 2018-03-17  Zalan Bujtas  <zalan@apple.com>
 
+        [LayoutReloaded] BlockFormattingContext::placePositionedDescendants takes care of both in- and out-of-flow placement
+        https://bugs.webkit.org/show_bug.cgi?id=183727
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js:
+        (BlockFormattingContext.prototype.layout):
+        (BlockFormattingContext.prototype._placePositionedDescendants):
+        (BlockFormattingContext.prototype._placeInFlowPositionedChildren):
+        (BlockFormattingContext.prototype._placeOutOfFlowDescendants):
+        * LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context.html: Added.
+        * LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context2.html: Added.
+        * LayoutReloaded/test/index.html:
+        * LayoutReloaded/test/relative-position-when-containing-block-is-not-in-the-formatting-context.html: Added.
+
+2018-03-17  Zalan Bujtas  <zalan@apple.com>
+
         [LayoutReloaded] Ensure that positioning happens within the formatting context
         https://bugs.webkit.org/show_bug.cgi?id=183722
 
index a76ce0f..6fc3943 100644 (file)
@@ -65,9 +65,8 @@ class BlockFormattingContext extends FormattingContext {
                 this.computeHeight(layoutBox);
                 // Adjust position now that we have all the previous floats placed in this context -if needed.
                 this.floatingContext().computePosition(layoutBox);
-                // Move in-flow positioned children to their final position. If this layoutBox also establishes a formatting context, then positioning already has happend.
-                if (layoutBox.isContainer() && !layoutBox.establishesFormattingContext())
-                    this._placeInFlowPositionedChildren(layoutBox);
+                // Move positioned children to their final position.
+                this._placePositionedDescendants(layoutBox);
                 // We are done with laying out this box.
                 this._removeFromLayoutQueue(layoutBox);
                 if (layoutBox.nextSibling()) {
@@ -77,8 +76,7 @@ class BlockFormattingContext extends FormattingContext {
             }
         }
         // And finally place the in- and out-of-flow descendants.
-        this._placeInFlowPositionedChildren(this.rootContainer());
-        this._placeOutOfFlowDescendants(this.rootContainer());
+        this._placePositionedDescendants(this.rootContainer());
    }
 
     computeWidth(layoutBox) {
@@ -118,15 +116,27 @@ class BlockFormattingContext extends FormattingContext {
         layoutBox.setTopLeft(position);
     }
 
+    _placePositionedDescendants(layoutBox) {
+        if (!layoutBox.isContainer())
+            return;
+        // If this layoutBox also establishes a formatting context, then positioning already has happend at the formatting context.
+        if (layoutBox.establishesFormattingContext() && layoutBox != this.rootContainer())
+            return;
+        this._placeInFlowPositionedChildren(layoutBox);
+        this._placeOutOfFlowDescendants(layoutBox);
+    }
+
     _placeInFlowPositionedChildren(container) {
+        ASSERT(container.isContainer());
         for (let inFlowChild = container.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling()) {
             if (!inFlowChild.isInFlowPositioned())
                 continue;
-             this._computeInFlowPositionedPosition(inFlowChild);
+            this._computeInFlowPositionedPosition(inFlowChild);
         }
     }
 
     _placeOutOfFlowDescendants(container) {
+        ASSERT(container.isContainer());
         let outOfFlowDescendants = Utils.collectOutOfFlowDescendants(container);
         for (let outOfFlowBox of outOfFlowDescendants)
             this._computeOutOfFlowPosition(outOfFlowBox);
diff --git a/Tools/LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context.html b/Tools/LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context.html
new file mode 100644 (file)
index 0000000..80e0006
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="position: relative; top: 100px; left: 100px; width: 100px; height: 100px; padding: 20px;">
+    <div style="overflow: hidden; width: 50px; height: 50px">
+        <div style="position: absolute; left: -5px; top: -5px; width: 10px; height: 10px;"></div>
+    </div>
+</div>
+</body>
+</html>
diff --git a/Tools/LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context2.html b/Tools/LayoutReloaded/test/absolute-position-when-containing-block-is-not-in-the-formatting-context2.html
new file mode 100644 (file)
index 0000000..5772ba0
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="position: relative; overflow: hidden; top: 100px; left: 100px; width: 100px; height: 100px; padding: 20px;">
+    <div style="overflow: hidden; width: 50px; height: 50px">
+        <div style="position: absolute; left: -5px; top: -5px; width: 10px; height: 10px;"></div>
+    </div>
+</div>
+</body>
+</html>
index fef9173..a2c91a1 100644 (file)
@@ -13,6 +13,7 @@ let testFiles = [
     "relative-right.html",
     "relative-auto.html",
     "relative-auto-with-parent-offset.html",
+    "relative-position-when-containing-block-is-not-in-the-formatting-context.html",
     "relative-siblings.html",
     "padding-simple.html",
     "padding-nested.html",
@@ -41,6 +42,8 @@ let testFiles = [
     "absolute-width-shrink-to-fit.html",
     "absolute-width-stretch.html",
     "absolute-with-static-block-position-nested.html",
+    "absolute-position-when-containing-block-is-not-in-the-formatting-context.html",
+    "absolute-position-when-containing-block-is-not-in-the-formatting-context2.html",
     "fixed-nested.html",
     "floating-box-left-and-right-multiple.html",
     "floating-box-right-simple.html",
diff --git a/Tools/LayoutReloaded/test/relative-position-when-containing-block-is-not-in-the-formatting-context.html b/Tools/LayoutReloaded/test/relative-position-when-containing-block-is-not-in-the-formatting-context.html
new file mode 100644 (file)
index 0000000..4c6e181
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="border: 1px solid green; position: relative; top: 100px; left: 100px; width: 100px; height: 100px; padding: 20px;">
+    <div style="overflow: hidden; border: 1px solid red; width: 50px; height: 50px">
+        <div style="position: relative; left: -5px; top: -5px; width: 10px; height: 10px; border: 1px solid blue"></div>
+    </div>
+</div>
+</body>
+</html>