// Find the previous layout object that has the multicol container in its containing block chain, skipping nested multicol containers. static LayoutObject* previousInPreOrderSkippingOutOfFlow(LayoutMultiColumnFlowThread* flowThread, LayoutObject* descendant) { ASSERT(descendant->isDescendantOf(flowThread)); LayoutObject* object = descendant->previousInPreOrder(flowThread); while (object && object != flowThread) { if (object->isColumnSpanAll()) { LayoutMultiColumnFlowThread* placeholderFlowThread = toLayoutBox(object)->spannerPlaceholder()->flowThread(); if (placeholderFlowThread == flowThread) break; // We're inside an inner multicol container. We have no business there. Continue on the outside. object = placeholderFlowThread->parent(); ASSERT(object->isDescendantOf(flowThread)); continue; } if (object->flowThreadContainingBlock() == flowThread) { LayoutObject* ancestor; for (ancestor = object->parent(); ; ancestor = ancestor->parent()) { if (ancestor == flowThread) return object; if (isMultiColumnContainer(*ancestor)) { // We're inside an inner multicol container. We have no business there. break; } } object = ancestor; ASSERT(ancestor->isDescendantOf(flowThread)); continue; // Continue on the outside of the inner flow thread. } // We're inside something that's out-of-flow. Keep looking upwards and backwards in the tree. object = object->previousInPreOrder(flowThread); } if (!object || object == flowThread) return nullptr; #if ENABLE(ASSERT) // Make sure that we didn't stumble into an inner multicol container. for (LayoutObject* walker = object->parent(); walker && walker != flowThread; walker = walker->parent()) ASSERT(!isMultiColumnContainer(*walker)); #endif return object; }