Diff
Copied: branches/chromium/874/LayoutTests/fast/ruby/ruby-base-merge-block-children-crash.html (from rev 95924, trunk/LayoutTests/fast/ruby/ruby-base-merge-block-children-crash.html) (0 => 96011)
--- branches/chromium/874/LayoutTests/fast/ruby/ruby-base-merge-block-children-crash.html (rev 0)
+++ branches/chromium/874/LayoutTests/fast/ruby/ruby-base-merge-block-children-crash.html 2011-09-26 22:44:41 UTC (rev 96011)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html style="font: 1em/1 Ahem, sans-serif;">
+<body>
+<ruby>
+PASS
+<rt id="rt1"></rt>
+<i>
+<table id="table1"></table><table id="table2"><span><span>
+</i>
+</ruby>
+</body>
+<script>
+document.body.offsetTop;
+var table1 = document.getElementById('table1');
+table1.parentNode.removeChild(table1);
+document.body.offsetTop;
+var table2 = document.getElementById('table2');
+table2.parentNode.removeChild(table2);
+document.body.offsetTop;
+var rt1 = document.getElementById('rt1');
+rt1.parentNode.removeChild(rt1);
+</script>
+</body>
+</html>
Copied: branches/chromium/874/LayoutTests/platform/mac/fast/ruby/ruby-base-merge-block-children-crash-expected.txt (from rev 95924, trunk/LayoutTests/platform/mac/fast/ruby/ruby-base-merge-block-children-crash-expected.txt) (0 => 96011)
--- branches/chromium/874/LayoutTests/platform/mac/fast/ruby/ruby-base-merge-block-children-crash-expected.txt (rev 0)
+++ branches/chromium/874/LayoutTests/platform/mac/fast/ruby/ruby-base-merge-block-children-crash-expected.txt 2011-09-26 22:44:41 UTC (rev 96011)
@@ -0,0 +1,20 @@
+layer at (0,0) size 800x600
+ RenderView at (0,0) size 800x600
+layer at (0,0) size 800x32
+ RenderBlock {HTML} at (0,0) size 800x32
+ RenderBody {BODY} at (8,8) size 784x16
+ RenderRuby (inline) {RUBY} at (0,0) size 64x16
+ RenderRubyRun (anonymous) at (0,0) size 64x16
+ RenderRubyBase (anonymous) at (0,0) size 64x16
+ RenderBlock (anonymous) at (0,0) size 64x16
+ RenderText {#text} at (0,0) size 64x16
+ text run at (0,0) width 64: "PASS"
+ RenderInline {I} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
+ RenderBlock (anonymous) at (0,16) size 64x0
+ RenderInline {SPAN} at (0,0) size 0x0
+ RenderInline {SPAN} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
+ RenderText {#text} at (0,0) size 0x0
+ RenderBlock (anonymous) at (0,16) size 64x0
+ RenderInline {I} at (0,0) size 0x0
Modified: branches/chromium/874/Source/WebCore/rendering/RenderRubyBase.cpp (96010 => 96011)
--- branches/chromium/874/Source/WebCore/rendering/RenderRubyBase.cpp 2011-09-26 22:34:54 UTC (rev 96010)
+++ branches/chromium/874/Source/WebCore/rendering/RenderRubyBase.cpp 2011-09-26 22:44:41 UTC (rev 96011)
@@ -53,23 +53,11 @@
return child->isInline();
}
-bool RenderRubyBase::hasOnlyWrappedInlineChildren(RenderObject* beforeChild) const
-{
- // Tests whether all children in the base before beforeChild are either floated/positioned,
- // or inline objects wrapped in anonymous blocks.
- // Note that beforeChild may be 0, in which case all children are looked at.
- for (RenderObject* child = firstChild(); child != beforeChild; child = child->nextSibling()) {
- if (!child->isFloatingOrPositioned() && !(child->isAnonymousBlock() && child->childrenInline()))
- return false;
- }
- return true;
-}
-
void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* beforeChild)
{
// This function removes all children that are before (!) beforeChild
// and appends them to toBase.
- ASSERT(toBase);
+ ASSERT_ARG(toBase, toBase);
// First make sure that beforeChild (if set) is indeed a direct child of this.
// Inline children might be wrapped in an anonymous block if there's a continuation.
@@ -89,8 +77,13 @@
void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild)
{
- RenderBlock* toBlock;
+ ASSERT(childrenInline());
+ ASSERT_ARG(toBase, toBase);
+ if (!firstChild())
+ return;
+
+ RenderBlock* toBlock;
if (toBase->childrenInline()) {
// The standard and easy case: move the children into the target base
toBlock = toBase;
@@ -111,66 +104,15 @@
void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild)
{
- if (toBase->childrenInline()) {
- // First check whether we move only wrapped inline objects.
- if (hasOnlyWrappedInlineChildren(beforeChild)) {
- // The reason why the base is in block flow must be after beforeChild.
- // We therefore can extract the inline objects and move them to toBase.
- for (RenderObject* child = firstChild(); child != beforeChild; child = firstChild()) {
- if (child->isAnonymousBlock()) {
- RenderBlock* anonBlock = toRenderBlock(child);
- ASSERT(anonBlock->childrenInline());
- ASSERT(!anonBlock->inlineElementContinuation());
- anonBlock->moveAllChildrenTo(toBase, toBase->children());
- anonBlock->deleteLineBoxTree();
- anonBlock->destroy();
- } else {
- ASSERT(child->isFloatingOrPositioned());
- moveChildTo(toBase, child);
- }
- }
- } else {
- // Moving block children -> have to set toBase as block flow
- toBase->makeChildrenNonInline();
- // Move children, potentially collapsing anonymous block wrappers.
- mergeBlockChildren(toBase, beforeChild);
-
- // Now we need to check if the leftover children are all inline.
- // If so, make this base inline again.
- if (hasOnlyWrappedInlineChildren()) {
- RenderObject* next = 0;
- for (RenderObject* child = firstChild(); child; child = next) {
- next = child->nextSibling();
- if (child->isFloatingOrPositioned())
- continue;
- ASSERT(child->isAnonymousBlock());
-
- RenderBlock* anonBlock = toRenderBlock(child);
- ASSERT(anonBlock->childrenInline());
- ASSERT(!anonBlock->inlineElementContinuation());
- // Move inline children out of anonymous block.
- anonBlock->moveAllChildrenTo(this, anonBlock);
- anonBlock->deleteLineBoxTree();
- anonBlock->destroy();
- }
- setChildrenInline(true);
- }
- }
- } else
- mergeBlockChildren(toBase, beforeChild);
-}
-
-void RenderRubyBase::mergeBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild)
-{
- // This function removes all children that are before beforeChild and appends them to toBase.
ASSERT(!childrenInline());
- ASSERT(toBase);
- ASSERT(!toBase->childrenInline());
+ ASSERT_ARG(toBase, toBase);
- // Quick check whether we have anything to do, to simplify the following code.
if (!firstChild())
return;
+ if (toBase->childrenInline())
+ toBase->makeChildrenNonInline();
+
// If an anonymous block would be put next to another such block, then merge those.
RenderObject* firstChildHere = firstChild();
RenderObject* lastChildThere = toBase->lastChild();
Modified: branches/chromium/874/Source/WebCore/rendering/RenderRubyBase.h (96010 => 96011)
--- branches/chromium/874/Source/WebCore/rendering/RenderRubyBase.h 2011-09-26 22:34:54 UTC (rev 96010)
+++ branches/chromium/874/Source/WebCore/rendering/RenderRubyBase.h 2011-09-26 22:44:41 UTC (rev 96011)
@@ -52,12 +52,9 @@
virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const;
- bool hasOnlyWrappedInlineChildren(RenderObject* beforeChild = 0) const;
-
void moveChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
void moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
- void mergeBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
RenderRubyRun* rubyRun() const;