void LayoutRubyAsInline::addChild(LayoutObject* child, LayoutObject* beforeChild)
{
    // If the child is a ruby run, just add it normally.
    if (child->isRubyRun()) {
        LayoutInline::addChild(child, beforeChild);
        return;
    }

    if (beforeChild) {
        // insert child into run
        LayoutObject* run = beforeChild;
        while (run && !run->isRubyRun())
            run = run->parent();
        if (run) {
            if (beforeChild == run)
                beforeChild = toLayoutRubyRun(beforeChild)->firstChild();
            ASSERT(!beforeChild || beforeChild->isDescendantOf(run));
            run->addChild(child, beforeChild);
            return;
        }
        ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
        // Emergency fallback: fall through and just append.
    }

    // If the new child would be appended, try to add the child to the previous run
    // if possible, or create a new run otherwise.
    // (The LayoutRubyRun object will handle the details)
    LayoutRubyRun* lastRun = lastRubyRun(this);
    if (!lastRun || lastRun->hasRubyText()) {
        lastRun = LayoutRubyRun::staticCreateRubyRun(this);
        LayoutInline::addChild(lastRun, beforeChild);
    }
    lastRun->addChild(child);
}
LayoutRubyRun* LayoutRubyRun::staticCreateRubyRun(const LayoutObject* parentRuby)
{
    ASSERT(parentRuby && parentRuby->isRuby());
    LayoutRubyRun* rr = new LayoutRubyRun();
    rr->setDocumentForAnonymous(&parentRuby->document());
    RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisplay(parentRuby->styleRef(), INLINE_BLOCK);
    rr->setStyle(newStyle.release());
    return rr;
}
void LayoutRubyRun::addChild(LayoutObject* child, LayoutObject* beforeChild)
{
    ASSERT(child);

    if (child->isRubyText()) {
        if (!beforeChild) {
            // LayoutRuby has already ascertained that we can add the child here.
            ASSERT(!hasRubyText());
            // prepend ruby texts as first child
            LayoutBlockFlow::addChild(child, firstChild());
        }  else if (beforeChild->isRubyText()) {
            // New text is inserted just before another.
            // In this case the new text takes the place of the old one, and
            // the old text goes into a new run that is inserted as next sibling.
            ASSERT(beforeChild->parent() == this);
            LayoutObject* ruby = parent();
            ASSERT(ruby->isRuby());
            LayoutBlock* newRun = staticCreateRubyRun(ruby);
            ruby->addChild(newRun, nextSibling());
            // Add the new ruby text and move the old one to the new run
            // Note: Doing it in this order and not using LayoutRubyRun's methods,
            // in order to avoid automatic removal of the ruby run in case there is no
            // other child besides the old ruby text.
            LayoutBlockFlow::addChild(child, beforeChild);
            LayoutBlockFlow::removeChild(beforeChild);
            newRun->addChild(beforeChild);
        } else if (hasRubyBase()) {
            // Insertion before a ruby base object.
            // In this case we need insert a new run before the current one and split the base.
            LayoutObject* ruby = parent();
            LayoutRubyRun* newRun = staticCreateRubyRun(ruby);
            ruby->addChild(newRun, this);
            newRun->addChild(child);

            // Make sure we don't leave anything in the percentage descendant
            // map before moving the children to the new base.
            if (hasPercentHeightDescendants())
                clearPercentHeightDescendants();
            rubyBaseSafe()->moveChildren(newRun->rubyBaseSafe(), beforeChild);
        }
    } else {
        // child is not a text -> insert it into the base
        // (append it instead if beforeChild is the ruby text)
        LayoutRubyBase* base = rubyBaseSafe();
        if (beforeChild == base)
            beforeChild = base->firstChild();
        if (beforeChild && beforeChild->isRubyText())
            beforeChild = 0;
        ASSERT(!beforeChild || beforeChild->isDescendantOf(base));
        base->addChild(child, beforeChild);
    }
}
void LayoutRubyAsBlock::removeChild(LayoutObject* child)
{
    // If the child's parent is *this (must be a ruby run), just use the normal remove method.
    if (child->parent() == this) {
        ASSERT(child->isRubyRun());
        LayoutBlockFlow::removeChild(child);
        return;
    }

    // Otherwise find the containing run and remove it from there.
    LayoutRubyRun* run = findRubyRunParent(child);
    ASSERT(run);
    run->removeChild(child);
}
void LayoutRubyRun::removeChild(LayoutObject* child)
{
    // If the child is a ruby text, then merge the ruby base with the base of
    // the right sibling run, if possible.
    if (!beingDestroyed() && !documentBeingDestroyed() && child->isRubyText()) {
        LayoutRubyBase* base = rubyBase();
        LayoutObject* rightNeighbour = nextSibling();
        if (base && rightNeighbour && rightNeighbour->isRubyRun()) {
            // Ruby run without a base can happen only at the first run.
            LayoutRubyRun* rightRun = toLayoutRubyRun(rightNeighbour);
            if (rightRun->hasRubyBase()) {
                LayoutRubyBase* rightBase = rightRun->rubyBaseSafe();
                // Collect all children in a single base, then swap the bases.
                rightBase->moveChildren(base);
                moveChildTo(rightRun, base);
                rightRun->moveChildTo(this, rightBase);
                // The now empty ruby base will be removed below.
                ASSERT(!rubyBase()->firstChild());
            }
        }
    }

    LayoutBlockFlow::removeChild(child);

    if (!beingDestroyed() && !documentBeingDestroyed()) {
        // Check if our base (if any) is now empty. If so, destroy it.
        LayoutBlock* base = rubyBase();
        if (base && !base->firstChild()) {
            LayoutBlockFlow::removeChild(base);
            base->deleteLineBoxTree();
            base->destroy();
        }

        // If any of the above leaves the run empty, destroy it as well.
        if (!hasRubyText() && !hasRubyBase()) {
            deleteLineBoxTree();
            destroy();
        }
    }
}