[LayoutReloaded] Collect floating boxes in inline formatting context and layout them...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Apr 2018 15:21:15 +0000 (15:21 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 5 Apr 2018 15:21:15 +0000 (15:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184329

Reviewed by Antti Koivisto.

Let's do this for now. There might be some cases where this violates layout.

* LayoutReloaded/FormattingContext/FormattingContext.js:
(FormattingContext.prototype._outOfFlowDescendants):
(FormattingContext):
* LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js:
(InlineFormattingContext.prototype.layout):
(InlineFormattingContext.prototype._handleFloatingBoxes):
(InlineFormattingContext.prototype._handleFloatingBox):
(InlineFormattingContext.prototype._floatingBoxes):
(InlineFormattingContext):
* LayoutReloaded/test/index.html:
* LayoutReloaded/test/multiple-left-floats-on-line-simple.html: Added.

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

Tools/ChangeLog
Tools/LayoutReloaded/FormattingContext/FormattingContext.js
Tools/LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js
Tools/LayoutReloaded/test/index.html
Tools/LayoutReloaded/test/multiple-left-floats-on-line-simple.html [new file with mode: 0644]

index 12b1620cdf004ba3877233fcd1be1829b917a6b6..8feb0e0f49a190dc65ce2d3faa89f73975f7a0b5 100644 (file)
@@ -1,3 +1,24 @@
+2018-04-05  Zalan Bujtas  <zalan@apple.com>
+
+        [LayoutReloaded] Collect floating boxes in inline formatting context and layout them first.
+        https://bugs.webkit.org/show_bug.cgi?id=184329
+
+        Reviewed by Antti Koivisto.
+
+        Let's do this for now. There might be some cases where this violates layout.
+
+        * LayoutReloaded/FormattingContext/FormattingContext.js:
+        (FormattingContext.prototype._outOfFlowDescendants):
+        (FormattingContext):
+        * LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js:
+        (InlineFormattingContext.prototype.layout):
+        (InlineFormattingContext.prototype._handleFloatingBoxes):
+        (InlineFormattingContext.prototype._handleFloatingBox):
+        (InlineFormattingContext.prototype._floatingBoxes):
+        (InlineFormattingContext):
+        * LayoutReloaded/test/index.html:
+        * LayoutReloaded/test/multiple-left-floats-on-line-simple.html: Added.
+
 2018-04-04  Youenn Fablet  <youenn@apple.com>
 
         WebRTC data channel only applications require capture permissions for direct connections
index 25b755697973533afaed3d52b56bfdd62ad9b2ea..4f5c475be9fb4338ce7f2ee33694e13d4cc70e62 100644 (file)
@@ -148,5 +148,4 @@ class FormattingContext {
         }
         return outOfFlowBoxes;
     }
-
 }
index bacd8fa88a57a03bff6c8a9315ae2ebd6c9b8c46..89c14710b248038fb4d7bd867cea807c109cbb76 100644 (file)
@@ -37,7 +37,10 @@ class InlineFormattingContext extends FormattingContext {
         // This is a post-order tree traversal layout.
         // The root container layout is done in the formatting context it lives in, not that one it creates, so let's start with the first child.
         this.m_line = this._createNewLine();
-        this._addToLayoutQueue(this.formattingRoot().firstChild());
+        // Collect floating boxes and layout them first.
+        this._handleFloatingBoxes();
+        //
+        this._addToLayoutQueue(this.formattingRoot().firstInFlowChild());
         while (this._descendantNeedsLayout()) {
             // Travers down on the descendants until we find a leaf node.
             while (true) {
@@ -48,18 +51,16 @@ class InlineFormattingContext extends FormattingContext {
                 }
                 if (!layoutBox.isContainer() || !layoutBox.hasChild())
                     break;
-                this._addToLayoutQueue(layoutBox.firstChild());
+                this._addToLayoutQueue(layoutBox.firstInFlowChild());
             }
             while (this._descendantNeedsLayout()) {
                 let layoutBox = this._nextInLayoutQueue();
                 if (layoutBox instanceof Layout.InlineBox)
                     this._handleInlineBox(layoutBox);
-                else if (layoutBox.isFloatingPositioned())
-                    this._handleFloatingBox(layoutBox);
                 // We are done with laying out this box.
                 this._removeFromLayoutQueue(layoutBox);
-                if (layoutBox.nextSibling()) {
-                    this._addToLayoutQueue(layoutBox.nextSibling());
+                if (layoutBox.nextInFlowSibling()) {
+                    this._addToLayoutQueue(layoutBox.nextInFlowSibling());
                     break;
                 }
             }
@@ -88,7 +89,17 @@ class InlineFormattingContext extends FormattingContext {
         }
     }
 
+    _handleFloatingBoxes() {
+        let floatingBoxes = this._floatingBoxes();
+        for (let floatingBox of floatingBoxes) {
+            this._addToLayoutQueue(floatingBox);
+            this._handleFloatingBox(floatingBox);
+            this._removeFromLayoutQueue(floatingBox);
+        }
+    }
+
     _handleFloatingBox(floatingBox) {
+        this.layoutState().layout(floatingBox);
         this._computeFloatingWidth(floatingBox);
         this._computeFloatingHeight(floatingBox);
         this.floatingContext().computePosition(floatingBox);
@@ -141,5 +152,33 @@ class InlineFormattingContext extends FormattingContext {
             return root.contentBox().left();
         return verticalPosition - rootLeft;
      }
+
+    _floatingBoxes() {
+        ASSERT(this.formattingRoot().firstChild());
+        // FIXME: This is highly inefficient but will do for now.
+        let floatingBoxes = new Array();
+        let stack = new Array();
+        stack.push(this.formattingRoot().firstChild());
+        while (stack.length) {
+            while (true) {
+                let box = stack[stack.length - 1];
+                if (box.isFloatingPositioned())
+                    floatingBoxes.push(box);
+                if (box.establishesFormattingContext())
+                    break;
+                if (!box.isContainer() || !box.hasChild())
+                    break;
+                stack.push(box.firstChild());
+            }
+            while (stack.length) {
+                let box = stack.pop();
+                if (box.nextSibling()) {
+                    stack.push(box.nextSibling());
+                    break;
+                }
+            }
+        }
+        return floatingBoxes;
+    }
 }
 
index 292a16c773461015aee619c1aae143b6ee14af4d..3279b1a2008a2c88e9a3bec41ffbd5e2ccd4ec66 100644 (file)
@@ -67,7 +67,8 @@ let testFiles = [
     "inline-formatting-context-with-floats.html",
     "inline-with-floats-right-left-simple.html",
     "inline-formatting-context-with-floats2.html",
-    "float-is-inside-inline-formatting-context-simple.html"
+    "float-is-inside-inline-formatting-context-simple.html",
+    "multiple-left-floats-on-line-simple.html"
 ];
 
 let debugThis = [];
diff --git a/Tools/LayoutReloaded/test/multiple-left-floats-on-line-simple.html b/Tools/LayoutReloaded/test/multiple-left-floats-on-line-simple.html
new file mode 100644 (file)
index 0000000..af8885f
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div><div style="float: left; width: 10px; height: 10px;"></div>foobar foobar<div style="float: left; width: 10px; height: 10px;"></div><div style="float: left; width: 10px; height: 10px;"></div></div>
+</body>
+</html>