[LayoutReloaded] Collect out-of-flow positioned boxes for a given formatting context.
https://bugs.webkit.org/show_bug.cgi?id=183730

Reviewed by Antti Koivisto.

Collect and layout out-of-flow positioned boxes as the final step of the formatting context layout.

* LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js:
(BlockFormattingContext.prototype.layout):
(BlockFormattingContext.prototype._placeInFlowPositionedChildren):
(BlockFormattingContext.prototype._layoutOutOfFlowDescendants):
(BlockFormattingContext.prototype._placePositionedDescendants): Deleted.
(BlockFormattingContext.prototype._placeOutOfFlowDescendants): Deleted.
* LayoutReloaded/FormattingContext/FormattingContext.js:
(FormattingContext.prototype._toAbsolutePosition):
(FormattingContext.prototype._outOfFlowDescendants):
(FormattingContext):
* LayoutReloaded/LayoutTree/Box.js:
(Layout.Box.prototype.nextInFlowOrFloatSibling):
(Layout.Box.prototype.isDescendantOf):
* LayoutReloaded/LayoutTree/Container.js:
(Layout.Container.prototype.firstInFlowOrFloatChild):
(Layout.Container.prototype.hasInFlowOrFloatChild):
(Layout.Container.prototype.outOfFlowDescendants):
(Layout.Container):
* LayoutReloaded/Utils.js:
(Utils.isDescendantOf): Deleted.
(Utils.collectOutOfFlowDescendants): Deleted.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@229701 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Tools/LayoutReloaded/FormattingContext/FormattingContext.js b/Tools/LayoutReloaded/FormattingContext/FormattingContext.js
index e9251f6..921d07a 100644
--- a/Tools/LayoutReloaded/FormattingContext/FormattingContext.js
+++ b/Tools/LayoutReloaded/FormattingContext/FormattingContext.js
@@ -96,7 +96,7 @@
     _toAbsolutePosition(layoutBox) {
         // We should never need to go beyond the root container.
         let containingBlock = layoutBox.containingBlock();
-        ASSERT(containingBlock == this.rootContainer() || Utils.isDescendantOf(containingBlock, this.rootContainer()));
+        ASSERT(containingBlock == this.rootContainer() || containingBlock.isDescendantOf(this.rootContainer()));
         let topLeft = layoutBox.rect().topLeft();
         let ascendant = layoutBox.parent();
         while (ascendant && ascendant != containingBlock) {
@@ -147,4 +147,39 @@
         ASSERT(this.m_displayToLayout.has(displayBox));
         return this.m_displayToLayout.get(layout);
     }
+
+    _outOfFlowDescendants() {
+        // FIXME: This is highly inefficient but will do for now.
+        // 1. Collect all the out-of-flow descendants first.
+        // 2. Check if they are all belong to this formatting context.
+        //    - either the root container is the containing block.
+        //    - or a descendant of the root container is the containing block
+        //      and there is not other formatting context inbetween.
+        let allOutOfFlowBoxes = new Array();
+        let descendants = new Array();
+        for (let child = this.rootContainer().firstChild(); child; child = child.nextSibling())
+            descendants.push(child);
+        while (descendants.length) {
+            let descendant = descendants.pop();
+            if (descendant.isOutOfFlowPositioned())
+                allOutOfFlowBoxes.push(descendant);
+            if (!descendant.isContainer())
+                continue;
+            for (let child = descendant.lastChild(); child; child = child.previousSibling())
+                descendants.push(child);
+        }
+        let outOfFlowBoxes = new Array();
+        for (let outOfFlowBox of allOutOfFlowBoxes) {
+            let containingBlock = outOfFlowBox.containingBlock();
+            // Collect the out-of-flow descendant that belong to this formatting context.
+            if (containingBlock == this.rootContainer())
+                outOfFlowBoxes.push(outOfFlowBox);
+            else if (containingBlock.isDescendantOf(this.rootContainer())) {
+                if (!containingBlock.establishedFormattingContext() || !containingBlock.isPositioned())
+                    outOfFlowBoxes.push(outOfFlowBox);
+            }
+        }
+        return outOfFlowBoxes;
+    }
+
 }