[LayoutReloaded] Ensure that positioning happens within the formatting context
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Mar 2018 20:49:54 +0000 (20:49 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 17 Mar 2018 20:49:54 +0000 (20:49 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183722

Reviewed by Antti Koivisto.

All sizing and positioning need to happen in the formatting context that the box lives in
including the final position of in- and out-of-flow descendants.

* LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js:
(BlockFormattingContext.prototype.layout):
(BlockFormattingContext.prototype._placeInFlowPositionedChildren):
* LayoutReloaded/LayoutTree/Box.js:
(Layout.Box.prototype.establishesBlockFormattingContext):
(Layout.Box.prototype.isPositioned):
(Layout.Box.prototype.isRelativelyPositioned):
(Layout.Box.prototype.isAbsolutelyPositioned):
(Layout.Box.prototype.isOutOfFlowPositioned):
(Layout.Box.prototype.containingBlock):
(Layout.Box.prototype.isRelativePositioned): Deleted.
(Layout.Box.prototype.isAbsolutePositioned): Deleted.
* LayoutReloaded/Utils.js:
(Utils.isRelativelyPositioned):
(Utils.isAbsolutelyPositioned):
(Utils.isRelativePositioned): Deleted.
(Utils.isAbsolutePositioned): Deleted.
* LayoutReloaded/misc/headers/Box.h:

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

Tools/ChangeLog
Tools/LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js
Tools/LayoutReloaded/LayoutTree/Box.js
Tools/LayoutReloaded/Utils.js
Tools/LayoutReloaded/misc/headers/Box.h

index 40980f9f470a2c49328eaeeccb996741f2ff6f42..3727e97ed2cbc9b8d0b59fb1d936423286db8c77 100644 (file)
@@ -1,3 +1,32 @@
+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
+
+        Reviewed by Antti Koivisto.
+
+        All sizing and positioning need to happen in the formatting context that the box lives in
+        including the final position of in- and out-of-flow descendants.
+
+        * LayoutReloaded/FormattingContext/BlockFormatting/BlockFormattingContext.js:
+        (BlockFormattingContext.prototype.layout):
+        (BlockFormattingContext.prototype._placeInFlowPositionedChildren):
+        * LayoutReloaded/LayoutTree/Box.js:
+        (Layout.Box.prototype.establishesBlockFormattingContext):
+        (Layout.Box.prototype.isPositioned):
+        (Layout.Box.prototype.isRelativelyPositioned):
+        (Layout.Box.prototype.isAbsolutelyPositioned):
+        (Layout.Box.prototype.isOutOfFlowPositioned):
+        (Layout.Box.prototype.containingBlock):
+        (Layout.Box.prototype.isRelativePositioned): Deleted.
+        (Layout.Box.prototype.isAbsolutePositioned): Deleted.
+        * LayoutReloaded/Utils.js:
+        (Utils.isRelativelyPositioned):
+        (Utils.isAbsolutelyPositioned):
+        (Utils.isRelativePositioned): Deleted.
+        (Utils.isAbsolutePositioned): Deleted.
+        * LayoutReloaded/misc/headers/Box.h:
+
 2018-03-16  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Unreviewed, rolling out r229688.
index 2d2ba6095ae5a7ff9cbded054201bfad142d0e12..a76ce0f5f0175e7f3a20a41985c0304803432bbd 100644 (file)
@@ -65,12 +65,9 @@ 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 positioned children to their final position.
-                if (layoutBox.isContainer()) {
+                // 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);
-                    // Place the out of flow content.
-                    this._placeOutOfFlowDescendants(layoutBox);
-                }
                 // We are done with laying out this box.
                 this._removeFromLayoutQueue(layoutBox);
                 if (layoutBox.nextSibling()) {
@@ -79,7 +76,8 @@ class BlockFormattingContext extends FormattingContext {
                 }
             }
         }
-        // And finally place the out of flow descendants for the root.
+        // And finally place the in- and out-of-flow descendants.
+        this._placeInFlowPositionedChildren(this.rootContainer());
         this._placeOutOfFlowDescendants(this.rootContainer());
    }
 
@@ -121,8 +119,11 @@ class BlockFormattingContext extends FormattingContext {
     }
 
     _placeInFlowPositionedChildren(container) {
-        for (let inFlowChild = container.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling())
-            this._computeInFlowPositionedPosition(inFlowChild);
+        for (let inFlowChild = container.firstInFlowChild(); inFlowChild; inFlowChild = inFlowChild.nextInFlowSibling()) {
+            if (!inFlowChild.isInFlowPositioned())
+                continue;
+             this._computeInFlowPositionedPosition(inFlowChild);
+        }
     }
 
     _placeOutOfFlowDescendants(container) {
index 2161ff98bbf5eb89d81aa40bb231e14fa32769aa..d8ed8a80d7ee3106b52f57bc732118280743d6e3 100644 (file)
@@ -177,7 +177,7 @@ Layout.Box = class Box {
         // Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions)
         // that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport)
         // establish new block formatting contexts for their contents.
-        return this.isFloatingPositioned() || this.isAbsolutePositioned() || (this.isBlockContainerBox() && !this.isBlockLevelBox())
+        return this.isFloatingPositioned() || this.isAbsolutelyPositioned() || (this.isBlockContainerBox() && !this.isBlockLevelBox())
             || (this.isBlockLevelBox() && !Utils.isOverflowVisible(this));
     }
 
@@ -186,15 +186,15 @@ Layout.Box = class Box {
     }
 
     isPositioned() {
-        return this.isOutOfFlowPositioned() || this.isRelativePositioned();
+        return this.isOutOfFlowPositioned() || this.isRelativelyPositioned();
     }
 
-    isRelativePositioned() {
-        return Utils.isRelativePositioned(this);
+    isRelativelyPositioned() {
+        return Utils.isRelativelyPositioned(this);
     }
 
-    isAbsolutePositioned() {
-        return Utils.isAbsolutePositioned(this);
+    isAbsolutelyPositioned() {
+        return Utils.isAbsolutelyPositioned(this) || this.isFixedPositioned();
     }
 
     isFixedPositioned() {
@@ -208,7 +208,7 @@ Layout.Box = class Box {
     }
 
     isOutOfFlowPositioned() {
-        return this.isAbsolutePositioned() || this.isFixedPositioned();
+        return this.isAbsolutelyPositioned() || this.isFixedPositioned();
     }
 
     isInFlowPositioned() {
@@ -234,13 +234,20 @@ Layout.Box = class Box {
             return null;
         if (!this.isPositioned() || this.isInFlowPositioned())
             return this.parent();
-        let parent = this.parent();
-        while (parent.parent()) {
-            if (this.isAbsolutePositioned() && parent.isPositioned())
-                return parent;
-            parent = parent.parent();
+        if (this.isAbsolutelyPositioned() && !this.isFixedPositioned()) {
+            let ascendant = this.parent();
+            while (ascendant.parent() && !ascendant.isPositioned())
+                ascendant = ascendant.parent();
+            return ascendant;
         }
-        return parent;
+        if (this.isFixedPositioned()) {
+            let ascendant = this.parent();
+            while (ascendant.parent())
+                ascendant = ascendant.parent();
+            return ascendant;
+        }
+        ASSERT_NOT_REACHED();
+        return null;
     }
 
     borderBox() {
index de1b133b5f4492bae7bfcb703d3b98a627486161..287f519d1e27379530304c75503ed98829951bc3 100644 (file)
@@ -431,14 +431,14 @@ class Utils {
         return  display == "table" || display == "inline-table";
     }
 
-    static isRelativePositioned(box) {
+    static isRelativelyPositioned(box) {
         if (box.isAnonymous())
             return false;
         let node = box.node();
         return window.getComputedStyle(node).position == "relative";
     }
 
-    static isAbsolutePositioned(box) {
+    static isAbsolutelyPositioned(box) {
         if (box.isAnonymous())
             return false;
         let node = box.node();
index aa5cd24054abaf44c32d9748746c42d93478fc82..440be978149fc12799347430cd0c55c6c683f967 100644 (file)
@@ -68,8 +68,8 @@ class Box {
 
     bool isInFlow() const;
     bool isPositioned() const;
-    bool isRelativePositioned() const;
-    bool isAbsolutePositioned() const;
+    bool isRelativelyPositioned() const;
+    bool isAbsolutelyPositioned() const;
     bool isFixedPositioned() const;
     bool isOutOfFlowPositioned() const;
     bool isInFlowPositioned() const;