| Index: Source/WebCore/rendering/RenderBlock.cpp | 
| =================================================================== | 
| --- Source/WebCore/rendering/RenderBlock.cpp	(revision 118862) | 
| +++ Source/WebCore/rendering/RenderBlock.cpp	(working copy) | 
| @@ -932,6 +932,14 @@ | 
| } | 
|  | 
| RenderBox::addChild(newChild, beforeChild); | 
| + | 
| +    // Handle positioning of run-ins. | 
| +    if (newChild->isRunIn()) | 
| +        moveRunInUnderSiblingBlockIfNeeded(newChild); | 
| +    else if (RenderObject* prevSibling = newChild->previousSibling()) { | 
| +        if (prevSibling->isRunIn()) | 
| +            moveRunInUnderSiblingBlockIfNeeded(prevSibling); | 
| +    } | 
|  | 
| if (madeBoxesNonInline && parent() && isAnonymousBlock() && parent()->isRenderBlock()) | 
| toRenderBlock(parent())->removeLeftoverAnonymousBlock(this); | 
| @@ -1038,6 +1046,13 @@ | 
| if (!child) | 
| return; | 
|  | 
| +    // Since we are going to have block children, we have to move | 
| +    // back the run-in to its original place. | 
| +    if (child->isRunIn()) { | 
| +        moveRunInToOriginalPosition(child); | 
| +        child = firstChild(); | 
| +    } | 
| + | 
| deleteLineBoxTree(); | 
|  | 
| while (child) { | 
| @@ -1724,8 +1739,7 @@ | 
| { | 
| // Handle in the given order | 
| return handlePositionedChild(child, marginInfo) | 
| -        || handleFloatingChild(child, marginInfo) | 
| -        || handleRunInChild(child); | 
| +        || handleFloatingChild(child, marginInfo); | 
| } | 
|  | 
|  | 
| @@ -1749,77 +1763,115 @@ | 
| return false; | 
| } | 
|  | 
| -bool RenderBlock::handleRunInChild(RenderBox* child) | 
| +static void destroyRunIn(RenderBoxModelObject* runIn) | 
| { | 
| -    // See if we have a run-in element with inline children.  If the | 
| -    // children aren't inline, then just treat the run-in as a normal | 
| -    // block. | 
| -    if (!child->isRunIn() || !child->childrenInline()) | 
| -        return false; | 
| +    ASSERT(runIn->isRunIn()); | 
| +    ASSERT(!runIn->firstChild()); | 
|  | 
| +    // If it is a block run-in, delete its line box tree as well. This is needed as our | 
| +    // children got moved and our line box tree is no longer valid. | 
| +    if (runIn->isRenderBlock()) | 
| +        toRenderBlock(runIn)->deleteLineBoxTree(); | 
| +    runIn->destroy(); | 
| +} | 
| + | 
| +RenderBoxModelObject* RenderBlock::createReplacementRunIn(RenderBoxModelObject* runIn) | 
| +{ | 
| +    ASSERT(runIn->isRunIn()); | 
| + | 
| +    // First we destroy any :before/:after content. It will be regenerated by the new run-in. | 
| +    // Exception is if the run-in itself is generated. | 
| +    if (runIn->style()->styleType() != BEFORE && runIn->style()->styleType() != AFTER) { | 
| +        RenderObject* generatedContent; | 
| +        if (runIn->getCachedPseudoStyle(BEFORE) && (generatedContent = runIn->beforePseudoElementRenderer())) | 
| +            generatedContent->destroy(); | 
| +        if (runIn->getCachedPseudoStyle(AFTER) && (generatedContent = runIn->afterPseudoElementRenderer())) | 
| +            generatedContent->destroy(); | 
| +    } | 
| + | 
| +    bool newRunInShouldBeBlock = !runIn->isRenderBlock(); | 
| +    Node* runInNode = runIn->node(); | 
| +    RenderBoxModelObject* newRunIn = 0; | 
| +    if (newRunInShouldBeBlock) | 
| +        newRunIn = new (renderArena()) RenderBlock(runInNode ? runInNode : document()); | 
| +    else | 
| +        newRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document()); | 
| +    newRunIn->setStyle(runIn->style()); | 
| + | 
| +    runIn->moveAllChildrenTo(newRunIn, true); | 
| + | 
| +    // If the run-in had an element, we need to set the new renderer. | 
| +    if (runInNode) | 
| +        runInNode->setRenderer(newRunIn); | 
| + | 
| +    return newRunIn; | 
| +} | 
| + | 
| +void RenderBlock::moveRunInUnderSiblingBlockIfNeeded(RenderObject* runIn) | 
| +{ | 
| +    ASSERT(runIn->isRunIn()); | 
| + | 
| +    // See if we have inline children. If the children aren't inline, | 
| +    // then just treat the run-in as a normal block. | 
| +    if (!runIn->childrenInline()) | 
| +        return; | 
| + | 
| // FIXME: We don't handle non-block elements with run-in for now. | 
| -    if (!child->isRenderBlock()) | 
| -        return false; | 
| +    if (!runIn->isRenderBlock()) | 
| +        return; | 
|  | 
| -    // Run-in child shouldn't intrude into the sibling block if it is part of a | 
| +    // We shouldn't run in into the sibling block if we are part of a | 
| // continuation chain. In that case, treat it as a normal block. | 
| -    if (child->isElementContinuation() || child->virtualContinuation()) | 
| -        return false; | 
| +    if (runIn->isElementContinuation() || runIn->virtualContinuation()) | 
| +        return; | 
|  | 
| // Check if this node is allowed to run-in. E.g. <select> expects its renderer to | 
| // be a RenderListBox or RenderMenuList, and hence cannot be a RenderInline run-in. | 
| -    Node* runInNode = child->node(); | 
| +    Node* runInNode = runIn->node(); | 
| if (runInNode && runInNode->hasTagName(selectTag)) | 
| -        return false; | 
| +        return; | 
|  | 
| -    RenderBlock* blockRunIn = toRenderBlock(child); | 
| -    RenderObject* curr = blockRunIn->nextSibling(); | 
| -    if (!curr || !curr->isRenderBlock() || !curr->childrenInline() || curr->isRunIn() || curr->isAnonymous() || curr->isFloatingOrPositioned()) | 
| -        return false; | 
| +    RenderObject* curr = runIn->nextSibling(); | 
| +    if (!curr || !curr->isRenderBlock() || !curr->childrenInline()) | 
| +        return; | 
|  | 
| -    RenderBlock* currBlock = toRenderBlock(curr); | 
| +    // Per CSS3, "A run-in cannot run in to a block that already starts with a | 
| +    // run-in or that itself is a run-in". | 
| +    if (curr->isRunIn() || (curr->firstChild() && curr->firstChild()->isRunIn())) | 
| +        return; | 
|  | 
| -    // First we destroy any :before/:after content. It will be regenerated by the new inline. | 
| -    // Exception is if the run-in itself is generated. | 
| -    if (child->style()->styleType() != BEFORE && child->style()->styleType() != AFTER) { | 
| -        RenderObject* generatedContent; | 
| -        if (child->getCachedPseudoStyle(BEFORE) && (generatedContent = child->beforePseudoElementRenderer())) | 
| -            generatedContent->destroy(); | 
| -        if (child->getCachedPseudoStyle(AFTER) && (generatedContent = child->afterPseudoElementRenderer())) | 
| -            generatedContent->destroy(); | 
| -    } | 
| +    if (curr->isAnonymous() || curr->isFloatingOrPositioned()) | 
| +        return; | 
|  | 
| -    // Remove the old child. | 
| -    children()->removeChildNode(this, blockRunIn); | 
| +    RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn); | 
| +    RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn); | 
| +    destroyRunIn(oldRunIn); | 
|  | 
| -    // Create an inline. | 
| -    RenderInline* inlineRunIn = new (renderArena()) RenderInline(runInNode ? runInNode : document()); | 
| -    inlineRunIn->setStyle(blockRunIn->style()); | 
| +    // Now insert the new child under |curr| block. Use addChild instead of insertChildNode | 
| +    // since it handles correct placement of the children, especially where we cannot insert | 
| +    // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228. | 
| +    curr->addChild(newRunIn, curr->firstChild()); | 
| +} | 
|  | 
| -    // Move the nodes from the old child to the new child | 
| -    for (RenderObject* runInChild = blockRunIn->firstChild(); runInChild;) { | 
| -        RenderObject* nextSibling = runInChild->nextSibling(); | 
| -        blockRunIn->children()->removeChildNode(blockRunIn, runInChild); | 
| -        inlineRunIn->addChild(runInChild); // Use addChild instead of appendChildNode since it handles correct placement of the children relative to :after-generated content. | 
| -        runInChild = nextSibling; | 
| -    } | 
| +void RenderBlock::moveRunInToOriginalPosition(RenderObject* runIn) | 
| +{ | 
| +    ASSERT(runIn->isRunIn()); | 
|  | 
| -    // Now insert the new child under |currBlock|. Use addChild instead of insertChildNode since it handles correct placement of the children, esp where we cannot insert | 
| -    // anything before the first child. e.g. details tag. See https://bugs.webkit.org/show_bug.cgi?id=58228. | 
| -    currBlock->addChild(inlineRunIn, currBlock->firstChild()); | 
| - | 
| -    // If the run-in had an element, we need to set the new renderer. | 
| -    if (runInNode) | 
| -        runInNode->setRenderer(inlineRunIn); | 
| +    // If we don't have a parent, there is nothing to move. This might | 
| +    // happen if |this| got detached from parent after |runIn| run into |this|. | 
| +    if (!parent()) | 
| +        return; | 
|  | 
| -    // Destroy the block run-in, which includes deleting its line box tree. | 
| -    blockRunIn->deleteLineBoxTree(); | 
| -    blockRunIn->destroy(); | 
| +    // An intruded run-in needs to be an inline. | 
| +    if (!runIn->isRenderInline()) | 
| +        return; | 
|  | 
| -    // The block acts like an inline, so just null out its | 
| -    // position. | 
| - | 
| -    return true; | 
| +    RenderBoxModelObject* oldRunIn = toRenderBoxModelObject(runIn); | 
| +    RenderBoxModelObject* newRunIn = createReplacementRunIn(oldRunIn); | 
| +    destroyRunIn(oldRunIn); | 
| + | 
| +    // Add the run-in block as our previous sibling. | 
| +    parent()->addChild(newRunIn, this); | 
| } | 
|  | 
| LayoutUnit RenderBlock::collapseMargins(RenderBox* child, MarginInfo& marginInfo) | 
|  |