Use "= default" to denote default constructor or destructor
[WebKit-https.git] / Source / WebCore / rendering / RenderMultiColumnFlow.cpp
index 4a9d9d5..851c4a2 100644 (file)
@@ -40,6 +40,7 @@ bool RenderMultiColumnFlow::gShiftingSpanner = false;
 
 RenderMultiColumnFlow::RenderMultiColumnFlow(Document& document, RenderStyle&& style)
     : RenderFragmentedFlow(document, WTFMove(style))
+    , m_spannerMap(std::make_unique<SpannerMap>())
     , m_lastSetWorkedOn(nullptr)
     , m_columnCount(1)
     , m_columnWidth(0)
@@ -49,14 +50,11 @@ RenderMultiColumnFlow::RenderMultiColumnFlow(Document& document, RenderStyle&& s
     , m_needsHeightsRecalculation(false)
     , m_progressionIsInline(false)
     , m_progressionIsReversed(false)
-    , m_beingEvacuated(false)
 {
     setFragmentedFlowState(InsideInFragmentedFlow);
 }
 
-RenderMultiColumnFlow::~RenderMultiColumnFlow()
-{
-}
+RenderMultiColumnFlow::~RenderMultiColumnFlow() = default;
 
 const char* RenderMultiColumnFlow::renderName() const
 {    
@@ -143,64 +141,6 @@ static RenderMultiColumnSet* findSetRendering(const RenderMultiColumnFlow& fragm
     return nullptr;
 }
 
-void RenderMultiColumnFlow::populate()
-{
-    RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
-    ASSERT(!nextSibling());
-    // Reparent children preceding the flow thread into the flow thread. It's multicol content
-    // now. At this point there's obviously nothing after the flow thread, but renderers (column
-    // sets and spanners) will be inserted there as we insert elements into the flow thread.
-    LayoutStateDisabler layoutStateDisabler(view());
-    RenderTreeInternalMutationScope reparentingIsOn(view());
-    multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this, true);
-    
-    if (multicolContainer->isFieldset()) {
-        // Keep legends out of the flow thread.
-        for (auto& box : childrenOfType<RenderBox>(*this)) {
-            if (box.isLegend())
-                moveChildTo(multicolContainer, &box, true);
-        }
-    }
-}
-
-void RenderMultiColumnFlow::evacuateAndDestroy()
-{
-    RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
-    m_beingEvacuated = true;
-    
-    // Delete the line box tree.
-    deleteLines();
-    
-    LayoutStateDisabler layoutStateDisabler(view());
-
-    // First promote all children of the flow thread. Before we move them to the flow thread's
-    // container, we need to unregister the flow thread, so that they aren't just re-added again to
-    // the flow thread that we're trying to empty.
-    multicolContainer->setMultiColumnFlow(nullptr);
-    RenderTreeInternalMutationScope reparentingIsOn(view());
-    moveAllChildrenTo(multicolContainer, true);
-
-    // Move spanners back to their original DOM position in the tree, and destroy the placeholders.
-    SpannerMap::iterator it;
-    while ((it = m_spannerMap.begin()) != m_spannerMap.end()) {
-        RenderBox* spanner = it->key;
-        auto takenSpanner = multicolContainer->takeChild(*spanner);
-        ASSERT(it->value.get());
-        if (RenderMultiColumnSpannerPlaceholder* placeholder = it->value.get()) {
-            RenderBlockFlow& originalContainer = downcast<RenderBlockFlow>(*placeholder->parent());
-            originalContainer.addChild(WTFMove(takenSpanner), placeholder);
-            placeholder->destroy();
-        }
-        m_spannerMap.remove(it);
-    }
-
-    // Remove all sets.
-    while (RenderMultiColumnSet* columnSet = firstMultiColumnSet())
-        columnSet->destroy();
-    
-    destroy();
-}
-
 void RenderMultiColumnFlow::addFragmentToThread(RenderFragmentContainer* RenderFragmentContainer)
 {
     auto* columnSet = downcast<RenderMultiColumnSet>(RenderFragmentContainer);
@@ -220,7 +160,6 @@ void RenderMultiColumnFlow::willBeRemovedFromTree()
     // further up on the call stack.
     for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet())
         columnSet->detachFragment();
-    multiColumnBlockFlow()->setMultiColumnFlow(nullptr);
     RenderFragmentedFlow::willBeRemovedFromTree();
 }
 
@@ -348,7 +287,7 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
         // content before and after the spanner, so that it becomes separate line boxes. Secondly,
         // this placeholder serves as a break point for column sets, so that, when encountered, we
         // end flowing one column set and move to the next one.
-        auto newPlaceholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(this, downcast<RenderBox>(descendant), &container->style());
+        auto newPlaceholder = RenderMultiColumnSpannerPlaceholder::createAnonymous(*this, downcast<RenderBox>(descendant), container->style());
         auto& placeholder = *newPlaceholder;
         container->addChild(WTFMove(newPlaceholder), descendant.nextSibling());
         auto takenDescendant = container->takeChild(descendant);
@@ -405,8 +344,11 @@ RenderObject* RenderMultiColumnFlow::processPossibleSpannerDescendant(RenderObje
 
 void RenderMultiColumnFlow::fragmentedFlowDescendantInserted(RenderObject& newDescendant)
 {
-    if (gShiftingSpanner || m_beingEvacuated || newDescendant.isInFlowRenderFragmentedFlow())
+    if (gShiftingSpanner || newDescendant.isInFlowRenderFragmentedFlow())
         return;
+
+    Vector<RenderPtr<RenderObject>> spannersToDelete;
+
     RenderObject* subtreeRoot = &newDescendant;
     for (auto* descendant = &newDescendant; descendant; descendant = (descendant ? descendant->nextInPreOrder(subtreeRoot) : nullptr)) {
         if (is<RenderMultiColumnSpannerPlaceholder>(*descendant)) {
@@ -428,12 +370,9 @@ void RenderMultiColumnFlow::fragmentedFlowDescendantInserted(RenderObject& newDe
                 
                 // We have to nuke the placeholder, since the ancestor already lost the mapping to it when
                 // we shifted the placeholder down into this flow thread.
-                placeholder.fragmentedFlow()->m_spannerMap.remove(spanner);
+                placeholder.fragmentedFlow()->spannerMap().remove(spanner);
 
-                auto takenChild = placeholder.parent()->takeChild(placeholder);
-                // FIXME: Memory management.
-                auto* leakenPtr = takenChild.leakPtr();
-                UNUSED_PARAM(leakenPtr);
+                spannersToDelete.append(placeholder.parent()->takeChild(placeholder));
 
                 if (subtreeRoot == descendant)
                     subtreeRoot = spanner;
@@ -442,8 +381,8 @@ void RenderMultiColumnFlow::fragmentedFlowDescendantInserted(RenderObject& newDe
                 continue;
             }
             
-            ASSERT(!m_spannerMap.get(placeholder.spanner()));
-            m_spannerMap.add(placeholder.spanner(), placeholder.createWeakPtr<RenderMultiColumnSpannerPlaceholder>());
+            ASSERT(!spannerMap().get(placeholder.spanner()));
+            spannerMap().add(placeholder.spanner(), makeWeakPtr(placeholder));
             ASSERT(!placeholder.firstChild()); // There should be no children here, but if there are, we ought to skip them.
             continue;
         }
@@ -454,20 +393,14 @@ void RenderMultiColumnFlow::fragmentedFlowDescendantInserted(RenderObject& newDe
 void RenderMultiColumnFlow::handleSpannerRemoval(RenderObject& spanner)
 {
     // The placeholder may already have been removed, but if it hasn't, do so now.
-    if (RenderMultiColumnSpannerPlaceholder* placeholder = m_spannerMap.get(&downcast<RenderBox>(spanner)).get()) {
-        auto takenChild = placeholder->parent()->takeChild(*placeholder);
-        // FIXME: Memory management.
-        auto* leakenPtr = takenChild.leakPtr();
-        UNUSED_PARAM(leakenPtr);
-
-        m_spannerMap.remove(&downcast<RenderBox>(spanner));
-    }
+    if (auto placeholder = spannerMap().take(&downcast<RenderBox>(spanner)))
+        placeholder->removeFromParentAndDestroy();
 
     if (RenderObject* next = spanner.nextSibling()) {
         if (RenderObject* previous = spanner.previousSibling()) {
             if (previous->isRenderMultiColumnSet() && next->isRenderMultiColumnSet()) {
                 // Merge two sets that no longer will be separated by a spanner.
-                next->destroy();
+                next->removeFromParentAndDestroy();
                 previous->setNeedsLayout();
             }
         }
@@ -476,15 +409,13 @@ void RenderMultiColumnFlow::handleSpannerRemoval(RenderObject& spanner)
 
 void RenderMultiColumnFlow::fragmentedFlowRelativeWillBeRemoved(RenderObject& relative)
 {
-    if (m_beingEvacuated)
-        return;
     invalidateFragments();
     if (is<RenderMultiColumnSpannerPlaceholder>(relative)) {
         // Remove the map entry for this spanner, but leave the actual spanner renderer alone. Also
         // keep the reference to the spanner, since the placeholder may be about to be re-inserted
         // in the tree.
         ASSERT(relative.isDescendantOf(this));
-        m_spannerMap.remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner());
+        spannerMap().remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner());
         return;
     }
     if (relative.style().columnSpan() == ColumnSpanAll) {