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 LayoutRubyBase::moveChildren(LayoutRubyBase* toBase, LayoutObject* beforeChild) { // This function removes all children that are before (!) beforeChild // and appends them to toBase. ASSERT_ARG(toBase, toBase); // Callers should have handled the percent height descendant map. ASSERT(!hasPercentHeightDescendants()); if (beforeChild && beforeChild->parent() != this) beforeChild = splitAnonymousBoxesAroundChild(beforeChild); if (childrenInline()) moveInlineChildren(toBase, beforeChild); else moveBlockChildren(toBase, beforeChild); setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvalidationReason::Unknown); toBase->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(LayoutInvalidationReason::Unknown); }