Title: [230318] trunk/Tools
Revision
230318
Author
za...@apple.com
Date
2018-04-05 19:12:26 -0700 (Thu, 05 Apr 2018)

Log Message

[LayoutReloaded] Move floating box to the next line when needed
https://bugs.webkit.org/show_bug.cgi?id=184349

Reviewed by Antti Koivisto.

* LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js:
(InlineFormattingContext.prototype.layout):
(InlineFormattingContext.prototype._handleContent):
(InlineFormattingContext.prototype._handleText):
(InlineFormattingContext.prototype._handleFloatingBox):
(InlineFormattingContext.prototype._mapFloatingHorizontalPosition):
(InlineFormattingContext):
(InlineFormattingContext.prototype._handleFloatingBoxes): Deleted.
(InlineFormattingContext.prototype._floatingBoxes): Deleted.
* LayoutReloaded/FormattingContext/InlineFormatting/Line.js:
(Line.prototype.addTextLineBox):
(Line.prototype.addFloatingBox):
(Line):
* LayoutReloaded/Utils.js:
(LayoutRect.prototype.moveHorizontally):
(LayoutRect.prototype.moveVertically):
* LayoutReloaded/test/index.html:
* LayoutReloaded/test/inline-with-floats-when-they-dont-fit.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (230317 => 230318)


--- trunk/Tools/ChangeLog	2018-04-06 01:29:26 UTC (rev 230317)
+++ trunk/Tools/ChangeLog	2018-04-06 02:12:26 UTC (rev 230318)
@@ -1,3 +1,29 @@
+2018-04-05  Zalan Bujtas  <za...@apple.com>
+
+        [LayoutReloaded] Move floating box to the next line when needed
+        https://bugs.webkit.org/show_bug.cgi?id=184349
+
+        Reviewed by Antti Koivisto.
+
+        * LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js:
+        (InlineFormattingContext.prototype.layout):
+        (InlineFormattingContext.prototype._handleContent):
+        (InlineFormattingContext.prototype._handleText):
+        (InlineFormattingContext.prototype._handleFloatingBox):
+        (InlineFormattingContext.prototype._mapFloatingHorizontalPosition):
+        (InlineFormattingContext):
+        (InlineFormattingContext.prototype._handleFloatingBoxes): Deleted.
+        (InlineFormattingContext.prototype._floatingBoxes): Deleted.
+        * LayoutReloaded/FormattingContext/InlineFormatting/Line.js:
+        (Line.prototype.addTextLineBox):
+        (Line.prototype.addFloatingBox):
+        (Line):
+        * LayoutReloaded/Utils.js:
+        (LayoutRect.prototype.moveHorizontally):
+        (LayoutRect.prototype.moveVertically):
+        * LayoutReloaded/test/index.html:
+        * LayoutReloaded/test/inline-with-floats-when-they-dont-fit.html: Added.
+
 2018-04-05  Brady Eidson  <beid...@apple.com>
 
         Process Swap on Navigation causes many webpages to hang due to attempted process swap for iframe navigations.

Modified: trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js (230317 => 230318)


--- trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js	2018-04-06 01:29:26 UTC (rev 230317)
+++ trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/InlineFormattingContext.js	2018-04-06 02:12:26 UTC (rev 230318)
@@ -37,10 +37,7 @@
         // 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();
-        // Collect floating boxes and layout them first.
-        this._handleFloatingBoxes();
-        //
-        this._addToLayoutQueue(this.formattingRoot().firstInFlowChild());
+        this._addToLayoutQueue(this.formattingRoot().firstInFlowOrFloatChild());
         while (this._descendantNeedsLayout()) {
             // Travers down on the descendants until we find a leaf node.
             while (true) {
@@ -49,18 +46,17 @@
                     this.layoutState().layout(layoutBox);
                     break;
                 }
-                if (!layoutBox.isContainer() || !layoutBox.hasChild())
+                if (!layoutBox.isContainer() || !layoutBox.hasInFlowOrFloatChild())
                     break;
-                this._addToLayoutQueue(layoutBox.firstInFlowChild());
+                this._addToLayoutQueue(layoutBox.firstInFlowOrFloatChild());
             }
             while (this._descendantNeedsLayout()) {
                 let layoutBox = this._nextInLayoutQueue();
-                if (layoutBox instanceof Layout.InlineBox)
-                    this._handleInlineBox(layoutBox);
+                this._handleContent(layoutBox);
                 // We are done with laying out this box.
                 this._removeFromLayoutQueue(layoutBox);
-                if (layoutBox.nextInFlowSibling()) {
-                    this._addToLayoutQueue(layoutBox.nextInFlowSibling());
+                if (layoutBox.nextInFlowOrFloatSibling()) {
+                    this._addToLayoutQueue(layoutBox.nextInFlowOrFloatSibling());
                     break;
                 }
             }
@@ -69,6 +65,18 @@
         this._commitLine();
    }
 
+    _handleContent(layoutBox) {
+        if (layoutBox instanceof Layout.InlineBox) {
+            this._handleInlineBox(layoutBox);
+            return;
+        }
+        if (layoutBox.isFloatingPositioned()) {
+            this._handleFloatingBox(layoutBox);
+            return;
+        }
+        ASSERT_NOT_REACHED();
+    }
+
     _handleInlineBox(inlineBox) {
         if (inlineBox.text())
             return this._handleText(inlineBox);
@@ -85,25 +93,22 @@
             for (let run of textRuns)
                 this._line().addTextLineBox(run.startPosition, run.endPosition, new LayoutSize(run.width, Utils.textHeight(inlineBox)));
             text = text.slice(textRuns[textRuns.length - 1].endPosition, text.length);
-            this._commitLine();
+            // Commit the line unless we run out of content.
+            if (text.length)
+                this._commitLine();
         }
     }
 
-    _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);
+        let displayFloatingBox = this.displayBox(floatingBox);
+        if (displayFloatingBox.width() > this._line().availableWidth())
+            this._commitLine();
+        // Position this float statically first, the floating context will figure it out the final position.
+        displayFloatingBox.setTopLeft(this._line().rect().topLeft());
         this.floatingContext().computePosition(floatingBox);
-        this._line().addFloatingBox(this.displayBox(floatingBox).size());
+        this._line().addFloatingBox(displayFloatingBox.size());
     }
 
     _commitLine() {
@@ -164,33 +169,5 @@
             return root.contentBox().left();
         return horizontalPosition - 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;
-    }
 }
 

Modified: trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/Line.js (230317 => 230318)


--- trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/Line.js	2018-04-06 01:29:26 UTC (rev 230317)
+++ trunk/Tools/LayoutReloaded/FormattingContext/InlineFormatting/Line.js	2018-04-06 02:12:26 UTC (rev 230318)
@@ -47,6 +47,7 @@
     }
 
     addTextLineBox(startPosition, endPosition, size) {
+        ASSERT(size.width() <= this.m_availableWidth);
         this.m_availableWidth -= size.width();
         // TODO: use the actual height instead of the line height.
         let lineBoxRect = new LayoutRect(this.rect().topRight(), new LayoutSize(size.width(), this.rect().height()));
@@ -55,8 +56,11 @@
     }
 
     addFloatingBox(size) {
-        // TODO: Add missing cases.
+        ASSERT(size.width() <= this.m_availableWidth);
+        // Push non-floating boxes to the right.
         this.m_availableWidth -= size.width();
-        this.m_lineRect.moveBy(new LayoutSize(size.width(), 0));
+        for (let lineBox of this.m_lineBoxes)
+            lineBox.lineBoxRect.moveHorizontally(size.width());
+        this.m_lineRect.moveHorizontally(size.width());
     }
 }

Modified: trunk/Tools/LayoutReloaded/Utils.js (230317 => 230318)


--- trunk/Tools/LayoutReloaded/Utils.js	2018-04-06 01:29:26 UTC (rev 230317)
+++ trunk/Tools/LayoutReloaded/Utils.js	2018-04-06 02:12:26 UTC (rev 230318)
@@ -207,7 +207,15 @@
     moveBy(distance) {
         this.m_topLeft.moveBy(distance);
     }
-    
+
+    moveHorizontally(distance) {
+        this.m_topLeft.shiftLeft(distance);
+    }
+
+    moveVertically(distance) {
+        this.m_topLeft.shiftTop(distance);
+    }
+
     isEmpty() {
         return this.m_size.isEmpty();
     }

Modified: trunk/Tools/LayoutReloaded/test/index.html (230317 => 230318)


--- trunk/Tools/LayoutReloaded/test/index.html	2018-04-06 01:29:26 UTC (rev 230317)
+++ trunk/Tools/LayoutReloaded/test/index.html	2018-04-06 02:12:26 UTC (rev 230318)
@@ -69,7 +69,8 @@
     "inline-formatting-context-with-floats2.html",
     "float-is-inside-inline-formatting-context-simple.html",
     "multiple-left-floats-on-line-simple.html",
-    "multiple-left-floats-on-line-from-parent-formatting-context.html"
+    "multiple-left-floats-on-line-from-parent-formatting-context.html",
+    "inline-with-floats-when-they-dont-fit.html"
 ];
 
 let debugThis = [];

Added: trunk/Tools/LayoutReloaded/test/inline-with-floats-when-they-dont-fit.html (0 => 230318)


--- trunk/Tools/LayoutReloaded/test/inline-with-floats-when-they-dont-fit.html	                        (rev 0)
+++ trunk/Tools/LayoutReloaded/test/inline-with-floats-when-they-dont-fit.html	2018-04-06 02:12:26 UTC (rev 230318)
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="width: 100px; height: 100px;">foobar<div style="float: left; width: 20px; height: 20px;"></div><div style="float: left; width: 60px; height: 20px;"></div></div>
+</body>
+</html>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to