+2007-03-15 Beth Dakin <bdakin@apple.com>
+
+ Reviewed by Hyatt.
+
+ Fix for <rdar://problem/5065396> REGRESSION: leaks in
+ RenderBlock::layoutInlineChildren seen on buildbot
+
+ This leak appeared after http://trac.webkit.org/projects/webkit/
+ changeset/20188. This change shifted line boxes around in
+ removeChild(). But since removeChild() calls
+ setNeedsLayoutAndMinMaxRecalc(), all of the line boxes will be
+ removed once we actually lay out anyway. So this patch fixes the
+ leak by deleting the line boxes instead of shifting them around.
+
+ * editing/IndentOutdentCommand.cpp:
+ (WebCore::IndentOutdentCommand::outdentParagraph): Call into
+ updateLayout(). This fixes an assertion I got in editing/
+ execCommand/4976800.html This is very similar to the line box fix I
+ made recently (http://trac.webkit.org/projects/webkit/changeset/
+ 20177). We need to update layout before relying on VisiblePositions
+ after removing a node.
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::deleteLinesForBlock): New helper function
+ since this functionality is needed in three places now.
+ (WebCore::RenderBlock::makeChildrenNonInline): Call into new
+ deleteLinesForBlock().
+ (WebCore::RenderBlock::removeChild): Same.
+ * rendering/RenderBlock.h:
+
2007-03-15 Timothy Hatcher <timothy@apple.com>
Reviewed by John.
visibleEndOfParagraph == endOfEnclosingBlock) {
// The blockquote doesn't contain anything outside the paragraph, so it can be totally removed.
removeNodePreservingChildren(enclosingNode);
+ updateLayout();
if (visibleStartOfParagraph.isNotNull() && !isStartOfParagraph(visibleStartOfParagraph))
insertNodeAt(createBreakElement(document()).get(), visibleStartOfParagraph.deepEquivalent().node(), visibleStartOfParagraph.deepEquivalent().offset());
if (visibleEndOfParagraph.isNotNull() && !isEndOfParagraph(visibleEndOfParagraph))
} while (!sawInline);
}
+void RenderBlock::deleteLineBoxTree()
+{
+ InlineFlowBox* line = m_firstLineBox;
+ InlineFlowBox* nextLine;
+ while (line) {
+ nextLine = line->nextFlowBox();
+ line->deleteLine(renderArena());
+ line = nextLine;
+ }
+ m_firstLineBox = m_lastLineBox = 0;
+}
+
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
{
// makeChildrenNonInline takes a block whose children are *all* inline and it
m_childrenInline = false;
- InlineFlowBox* line = m_firstLineBox;
- InlineFlowBox* nextLine;
- while (line) {
- nextLine = line->nextFlowBox();
- line->deleteLine(renderArena());
- line = nextLine;
- }
- m_firstLineBox = m_lastLineBox = 0;
+ deleteLineBoxTree();
RenderObject *child = firstChild();
prev->appendChildNode(next->removeChildNode(no));
no->setNeedsLayoutAndMinMaxRecalc();
}
-
- // Do the same with line boxes.
- RenderBlock* prevBlock = static_cast<RenderBlock*>(prev);
+
RenderBlock* nextBlock = static_cast<RenderBlock*>(next);
- if (RootInlineBox* box = nextBlock->firstRootBox()) {
- if (prevBlock->lastRootBox()) {
- prevBlock->lastRootBox()->setNextLineBox(box);
- box->setPreviousLineBox(prevBlock->lastRootBox());
- } else
- prevBlock->m_firstLineBox = box;
-
- while (box) {
- prevBlock->m_lastLineBox = box;
- box->m_object = prevBlock;
- box = box->nextRootBox();
- }
- nextBlock->m_firstLineBox = 0;
- nextBlock->m_lastLineBox = 0;
- }
+ nextBlock->deleteLineBoxTree();
// Nuke the now-empty block.
next->destroy();
no->setNeedsLayoutAndMinMaxRecalc();
}
- // Take over the anonymous child's line boxes.
- RootInlineBox* box = anonBlock->firstRootBox();
- m_firstLineBox = box;
- while (box) {
- m_lastLineBox = box;
- box->m_object = this;
- box = box->nextRootBox();
- }
- anonBlock->m_firstLineBox = 0;
- anonBlock->m_lastLineBox = 0;
-
- // Nuke the now-empty block.
+ // Delete the now-empty block's lines and nuke it.
+ anonBlock->deleteLineBoxTree();
anonBlock->destroy();
}
}