void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* fromBeforeChild) { if (toBase->childrenInline()) { // First check whether we move only wrapped inline objects. if (hasOnlyWrappedInlineChildren(fromBeforeChild)) { // 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 != fromBeforeChild; 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, fromBeforeChild); // 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, fromBeforeChild); }
static bool isValidColumnSpanner(RenderMultiColumnFlowThread* flowThread, RenderObject* descendant) { // We assume that we're inside the flow thread. This function is not to be called otherwise. ASSERT(descendant->isDescendantOf(flowThread)); // First make sure that the renderer itself has the right properties for becoming a spanner. RenderStyle& style = descendant->style(); if (style.columnSpan() != ColumnSpanAll || !descendant->isBox() || descendant->isFloatingOrOutOfFlowPositioned()) return false; RenderBlock* container = descendant->containingBlock(); if (!container->isRenderBlockFlow() || container->childrenInline()) { // Needs to be block-level. return false; } // This looks like a spanner, but if we're inside something unbreakable, it's not to be treated as one. for (RenderBox* ancestor = toRenderBox(descendant)->parentBox(); ancestor; ancestor = ancestor->parentBox()) { if (ancestor->isRenderFlowThread()) { // Don't allow any intervening non-multicol fragmentation contexts. The spec doesn't say // anything about disallowing this, but it's just going to be too complicated to // implement (not to mention specify behavior). return ancestor == flowThread; } ASSERT(ancestor->style().columnSpan() != ColumnSpanAll || !isValidColumnSpanner(flowThread, ancestor)); if (ancestor->isUnsplittableForPagination()) return false; } ASSERT_NOT_REACHED(); return false; }