Newly added float should trigger full layout on the block.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jul 2018 14:23:45 +0000 (14:23 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Jul 2018 14:23:45 +0000 (14:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187251
<rdar://problem/41726137>

Reviewed by David Kilzer.

Source/WebCore:

RenderBlockFlow::determineStartPosition() is one of the places where we decide the extent of the line layout for the current block.
In here we try to figure out the first line in the block that requires layout. In certain cases when floats are present,
(due to their intrusive behavior) we just trigger a full layout on the entire block.
One of the special cases is when a new float is added to the block. determineStartPosition() checks for such floats (floats inserted
after the "last known float") and marks the block for full layout. However it missed the case when other, unrelated mutations happened
in addition to this newly inserted float. This patch fixes this case by checking if the floats after the "last know float" actually need layout.

Test: fast/inline/new-float-needs-layout-when-line-is-dirty.html

* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::determineStartPosition):

LayoutTests:

* fast/inline/new-float-needs-layout-when-line-is-dirty-expected.txt: Added.
* fast/inline/new-float-needs-layout-when-line-is-dirty.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/inline/new-float-needs-layout-when-line-is-dirty-expected.txt [new file with mode: 0644]
LayoutTests/fast/inline/new-float-needs-layout-when-line-is-dirty.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBlockLineLayout.cpp

index 634aa97..96aaac7 100644 (file)
@@ -1,3 +1,14 @@
+2018-07-12  Zalan Bujtas  <zalan@apple.com>
+
+        Newly added float should trigger full layout on the block.
+        https://bugs.webkit.org/show_bug.cgi?id=187251
+        <rdar://problem/41726137>
+
+        Reviewed by David Kilzer.
+
+        * fast/inline/new-float-needs-layout-when-line-is-dirty-expected.txt: Added.
+        * fast/inline/new-float-needs-layout-when-line-is-dirty.html: Added.
+
 2018-07-11  Youenn Fablet  <youenn@apple.com>
 
         MediaDevices should derive from EventTarget in its IDL
diff --git a/LayoutTests/fast/inline/new-float-needs-layout-when-line-is-dirty-expected.txt b/LayoutTests/fast/inline/new-float-needs-layout-when-line-is-dirty-expected.txt
new file mode 100644 (file)
index 0000000..1a4c253
--- /dev/null
@@ -0,0 +1 @@
+Pass if no crashfoobar foobar foobar foobar foobar
diff --git a/LayoutTests/fast/inline/new-float-needs-layout-when-line-is-dirty.html b/LayoutTests/fast/inline/new-float-needs-layout-when-line-is-dirty.html
new file mode 100644 (file)
index 0000000..bd5833f
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+    border: 1px solid green;
+}
+
+#container {
+    width: 100px;
+    height: 200px;
+}
+
+#inlineblock {
+       display: inline-block;
+       width: 10px;
+       height: 10px;
+}
+
+.floatBox {
+       width: 30px;
+       height: 30px;
+       float: left;
+}
+</style>
+</head>
+<body>
+<div id=container>Pass if no crash<div id=inlineblock></div>foobar foobar foobar foobar foobar</div>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+document.body.offsetHeight;
+
+let floatBox = document.createElement("div");
+floatBox.className = "floatBox";
+inlineblock.style.height = "20px";
+container.appendChild(floatBox);
+
+document.body.offsetHeight;
+</script>
+</body>
+</html>
\ No newline at end of file
index dddbadb..0a87c4b 100644 (file)
@@ -1,3 +1,23 @@
+2018-07-12  Zalan Bujtas  <zalan@apple.com>
+
+        Newly added float should trigger full layout on the block.
+        https://bugs.webkit.org/show_bug.cgi?id=187251
+        <rdar://problem/41726137>
+
+        Reviewed by David Kilzer.
+
+        RenderBlockFlow::determineStartPosition() is one of the places where we decide the extent of the line layout for the current block.
+        In here we try to figure out the first line in the block that requires layout. In certain cases when floats are present,
+        (due to their intrusive behavior) we just trigger a full layout on the entire block.
+        One of the special cases is when a new float is added to the block. determineStartPosition() checks for such floats (floats inserted
+        after the "last known float") and marks the block for full layout. However it missed the case when other, unrelated mutations happened
+        in addition to this newly inserted float. This patch fixes this case by checking if the floats after the "last know float" actually need layout.
+
+        Test: fast/inline/new-float-needs-layout-when-line-is-dirty.html
+
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlockFlow::determineStartPosition):
+
 2018-07-12  Thibault Saunier  <tsaunier@igalia.com>
 
         [GStreamer] Add pads to the GstFlowCombiner in MediaStreamSrc
index 1ec11c3..937a1e8 100644 (file)
@@ -1834,8 +1834,19 @@ RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutSt
             }
         }
         // Check if a new float has been inserted after the last known float.
-        if (!currentLine && floatsIterator != end)
-            layoutState.markForFullLayout();
+        if (floatsIterator != end) {
+            if (!currentLine)
+                layoutState.markForFullLayout();
+            else {
+                for (; floatsIterator != end; ++floatsIterator) {
+                    auto& floatWithRect = *floatsIterator;
+                    if (!floatWithRect->renderer().needsLayout())
+                        continue;
+                    layoutState.markForFullLayout();
+                    break;
+                }
+            }
+        }
     }
 
     if (layoutState.isFullLayout()) {