- Revision
- 199101
- Author
- za...@apple.com
- Date
- 2016-04-06 08:56:06 -0700 (Wed, 06 Apr 2016)
Log Message
ASSERTION FAILED: !floatingObject->originatingLine() in WebCore::RenderBlockFlow::linkToEndLineIfNeeded
https://bugs.webkit.org/show_bug.cgi?id=153001
Reviewed by Dan Bernstein.
1. Float boxes are always attached to the line where we see them first.
2. Float box can only be attached to one line.
3. RenderBlockFlow can perform partial layout on dirty lines only.
In certain cases, the last dirty line can "pull up" float boxes from the first clean line.
It simply means that due to some layout changes on previous lines now we see those floats on this last dirty line first.
If after placing the float we still find it on the same position, the line below is still considered clean.
Source/WebCore:
Remove the float box from its original line if the line above already placed it.
Test: fast/block/float/float-moves-between-lines.html
* rendering/RenderBlockFlow.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlockFlow::reattachCleanLineFloats):
(WebCore::RenderBlockFlow::linkToEndLineIfNeeded):
(WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange): Deleted.
LayoutTests:
Remove the float box from its original line if the line above already placed it.
* fast/block/float/float-moves-between-lines-expected.txt: Added.
* fast/block/float/float-moves-between-lines.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (199100 => 199101)
--- trunk/LayoutTests/ChangeLog 2016-04-06 15:44:35 UTC (rev 199100)
+++ trunk/LayoutTests/ChangeLog 2016-04-06 15:56:06 UTC (rev 199101)
@@ -1,3 +1,23 @@
+2016-04-06 Zalan Bujtas <za...@apple.com>
+
+ ASSERTION FAILED: !floatingObject->originatingLine() in WebCore::RenderBlockFlow::linkToEndLineIfNeeded
+ https://bugs.webkit.org/show_bug.cgi?id=153001
+
+ Reviewed by Dan Bernstein.
+
+ 1. Float boxes are always attached to the line where we see them first.
+ 2. Float box can only be attached to one line.
+ 3. RenderBlockFlow can perform partial layout on dirty lines only.
+
+ In certain cases, the last dirty line can "pull up" float boxes from the first clean line.
+ It simply means that due to some layout changes on previous lines now we see those floats on this last dirty line first.
+ If after placing the float we still find it on the same position, the line below is still considered clean.
+
+ Remove the float box from its original line if the line above already placed it.
+
+ * fast/block/float/float-moves-between-lines-expected.txt: Added.
+ * fast/block/float/float-moves-between-lines.html: Added.
+
2016-04-06 Antti Koivisto <an...@apple.com>
REGRESSION(r196629): Messages text size only changes for sending text, conversation text size does not change
Added: trunk/LayoutTests/fast/block/float/float-moves-between-lines-expected.txt (0 => 199101)
--- trunk/LayoutTests/fast/block/float/float-moves-between-lines-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/block/float/float-moves-between-lines-expected.txt 2016-04-06 15:56:06 UTC (rev 199101)
@@ -0,0 +1 @@
+fooPass if no assert in debug.
Added: trunk/LayoutTests/fast/block/float/float-moves-between-lines.html (0 => 199101)
--- trunk/LayoutTests/fast/block/float/float-moves-between-lines.html (rev 0)
+++ trunk/LayoutTests/fast/block/float/float-moves-between-lines.html 2016-04-06 15:56:06 UTC (rev 199101)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>This tests that when a float box gets assigned to a new line, we can properly disconnect it from its original line.</title>
+</head>
+<body>
+<div style="width: 5px;"><img id="makeTaller" style="height: 50px; width: 1px"><img id="removeThis" style="width: 5px; height: 5px;"> <div style="float: left;">foo</div>Pass if no assert in debug.</div>
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+var removeThis = document.getElementById("removeThis");
+removeThis.offsetTop;
+removeThis.parentNode.removeChild(removeThis);
+var makeTaller = document.getElementById("makeTaller");
+makeTaller.style.height = '55px';
+</script>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (199100 => 199101)
--- trunk/Source/WebCore/ChangeLog 2016-04-06 15:44:35 UTC (rev 199100)
+++ trunk/Source/WebCore/ChangeLog 2016-04-06 15:56:06 UTC (rev 199101)
@@ -1,3 +1,28 @@
+2016-04-06 Zalan Bujtas <za...@apple.com>
+
+ ASSERTION FAILED: !floatingObject->originatingLine() in WebCore::RenderBlockFlow::linkToEndLineIfNeeded
+ https://bugs.webkit.org/show_bug.cgi?id=153001
+
+ Reviewed by Dan Bernstein.
+
+ 1. Float boxes are always attached to the line where we see them first.
+ 2. Float box can only be attached to one line.
+ 3. RenderBlockFlow can perform partial layout on dirty lines only.
+
+ In certain cases, the last dirty line can "pull up" float boxes from the first clean line.
+ It simply means that due to some layout changes on previous lines now we see those floats on this last dirty line first.
+ If after placing the float we still find it on the same position, the line below is still considered clean.
+
+ Remove the float box from its original line if the line above already placed it.
+
+ Test: fast/block/float/float-moves-between-lines.html
+
+ * rendering/RenderBlockFlow.h:
+ * rendering/RenderBlockLineLayout.cpp:
+ (WebCore::RenderBlockFlow::reattachCleanLineFloats):
+ (WebCore::RenderBlockFlow::linkToEndLineIfNeeded):
+ (WebCore::RenderBlockFlow::layoutRunsAndFloatsInRange): Deleted.
+
2016-04-06 Antti Koivisto <an...@apple.com>
REGRESSION(r196629): Messages text size only changes for sending text, conversation text size does not change
Modified: trunk/Source/WebCore/rendering/RenderBlockFlow.h (199100 => 199101)
--- trunk/Source/WebCore/rendering/RenderBlockFlow.h 2016-04-06 15:44:35 UTC (rev 199100)
+++ trunk/Source/WebCore/rendering/RenderBlockFlow.h 2016-04-06 15:56:06 UTC (rev 199101)
@@ -571,6 +571,7 @@
void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&, const InlineIterator&);
void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
+ void reattachCleanLineFloats(RootInlineBox& cleanLine, LayoutUnit delta, bool isFirstCleanLine);
void linkToEndLineIfNeeded(LineLayoutState&);
static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
Modified: trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp (199100 => 199101)
--- trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2016-04-06 15:44:35 UTC (rev 199100)
+++ trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp 2016-04-06 15:56:06 UTC (rev 199101)
@@ -1518,18 +1518,39 @@
markLinesDirtyInBlockRange(lastRootBox()->lineBottomWithLeading(), lineBox->lineBottomWithLeading(), lineBox);
}
}
-
clearDidBreakAtLineToAvoidWidow();
}
+void RenderBlockFlow::reattachCleanLineFloats(RootInlineBox& cleanLine, LayoutUnit delta, bool isFirstCleanLine)
+{
+ auto* cleanLineFloats = cleanLine.floatsPtr();
+ if (!cleanLineFloats)
+ return;
+
+ for (auto* floatingBox : *cleanLineFloats) {
+ auto* floatingObject = insertFloatingObject(*floatingBox);
+ if (isFirstCleanLine && floatingObject->originatingLine()) {
+ // Float box does not belong to this line anymore.
+ ASSERT(cleanLine.prevRootBox() == floatingObject->originatingLine());
+ cleanLine.removeFloat(*floatingBox);
+ continue;
+ }
+ ASSERT(!floatingObject->originatingLine());
+ floatingObject->setOriginatingLine(&cleanLine);
+ setLogicalHeight(logicalTopForChild(*floatingBox) - marginBeforeForChild(*floatingBox) + delta);
+ positionNewFloats();
+ }
+}
+
void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
{
- if (layoutState.endLine()) {
+ auto* firstCleanLine = layoutState.endLine();
+ if (firstCleanLine) {
if (layoutState.endLineMatched()) {
bool paginated = view().layoutState() && view().layoutState()->isPaginated();
// Attach all the remaining lines, and then adjust their y-positions as needed.
LayoutUnit delta = logicalHeight() - layoutState.endLineLogicalTop();
- for (RootInlineBox* line = layoutState.endLine(); line; line = line->nextRootBox()) {
+ for (auto* line = firstCleanLine; line; line = line->nextRootBox()) {
line->attachLine();
if (paginated) {
delta -= line->paginationStrut();
@@ -1542,16 +1563,7 @@
}
if (layoutState.flowThread())
updateRegionForLine(line);
- if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
- for (auto it = cleanLineFloats->begin(), end = cleanLineFloats->end(); it != end; ++it) {
- RenderBox* floatingBox = *it;
- FloatingObject* floatingObject = insertFloatingObject(*floatingBox);
- ASSERT(!floatingObject->originatingLine());
- floatingObject->setOriginatingLine(line);
- setLogicalHeight(logicalTopForChild(*floatingBox) - marginBeforeForChild(*floatingBox) + delta);
- positionNewFloats();
- }
- }
+ reattachCleanLineFloats(*line, delta, line == firstCleanLine);
}
setLogicalHeight(lastRootBox()->lineBottomWithLeading());
} else {