Changeset 222920 in webkit


Ignore:
Timestamp:
Oct 5, 2017 10:59:49 AM (7 years ago)
Author:
Antti Koivisto
Message:

Move more multicolumn render tree mutation code to RenderTreeUpdater::MultiColumn
https://bugs.webkit.org/show_bug.cgi?id=177942

Reviewed by Zalan Bujtas.

  • rendering/RenderMultiColumnFlow.cpp:

(WebCore::RenderMultiColumnFlow::RenderMultiColumnFlow):

Use std::unique_ptr for the spanner map for safe owenership transfer.

(WebCore::RenderMultiColumnFlow::fragmentedFlowDescendantInserted):
(WebCore::RenderMultiColumnFlow::handleSpannerRemoval):
(WebCore::RenderMultiColumnFlow::fragmentedFlowRelativeWillBeRemoved):
(WebCore::RenderMultiColumnFlow::populate): Deleted.
(WebCore::RenderMultiColumnFlow::evacuateAndDestroy): Deleted.

This code moves to RenderTreeUpdater::MultiColumn.

  • rendering/RenderMultiColumnFlow.h:
  • style/RenderTreeUpdaterMultiColumn.cpp:

(WebCore::RenderTreeUpdater::MultiColumn::update):
(WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
(WebCore::RenderTreeUpdater::MultiColumn::destroyFragmentedFlow):

Use Hyatt's preferred 'fragmented flow' terminology.

  • style/RenderTreeUpdaterMultiColumn.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r222917 r222920  
     12017-10-05  Antti Koivisto  <antti@apple.com>
     2
     3        Move more multicolumn render tree mutation code to RenderTreeUpdater::MultiColumn
     4        https://bugs.webkit.org/show_bug.cgi?id=177942
     5
     6        Reviewed by Zalan Bujtas.
     7
     8        * rendering/RenderMultiColumnFlow.cpp:
     9        (WebCore::RenderMultiColumnFlow::RenderMultiColumnFlow):
     10
     11            Use std::unique_ptr for the spanner map for safe owenership transfer.
     12
     13        (WebCore::RenderMultiColumnFlow::fragmentedFlowDescendantInserted):
     14        (WebCore::RenderMultiColumnFlow::handleSpannerRemoval):
     15        (WebCore::RenderMultiColumnFlow::fragmentedFlowRelativeWillBeRemoved):
     16        (WebCore::RenderMultiColumnFlow::populate): Deleted.
     17        (WebCore::RenderMultiColumnFlow::evacuateAndDestroy): Deleted.
     18
     19            This code moves to RenderTreeUpdater::MultiColumn.
     20
     21        * rendering/RenderMultiColumnFlow.h:
     22        * style/RenderTreeUpdaterMultiColumn.cpp:
     23        (WebCore::RenderTreeUpdater::MultiColumn::update):
     24        (WebCore::RenderTreeUpdater::MultiColumn::createFragmentedFlow):
     25        (WebCore::RenderTreeUpdater::MultiColumn::destroyFragmentedFlow):
     26
     27            Use Hyatt's preferred 'fragmented flow' terminology.
     28
     29        * style/RenderTreeUpdaterMultiColumn.h:
     30
    1312017-10-05  Darin Adler  <darin@apple.com>
    232
  • trunk/Source/WebCore/rendering/RenderMultiColumnFlow.cpp

    r222911 r222920  
    4141RenderMultiColumnFlow::RenderMultiColumnFlow(Document& document, RenderStyle&& style)
    4242    : RenderFragmentedFlow(document, WTFMove(style))
     43    , m_spannerMap(std::make_unique<SpannerMap>())
    4344    , m_lastSetWorkedOn(nullptr)
    4445    , m_columnCount(1)
     
    141142    }
    142143    return nullptr;
    143 }
    144 
    145 void RenderMultiColumnFlow::populate()
    146 {
    147     RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
    148     ASSERT(!nextSibling());
    149     // Reparent children preceding the flow thread into the flow thread. It's multicol content
    150     // now. At this point there's obviously nothing after the flow thread, but renderers (column
    151     // sets and spanners) will be inserted there as we insert elements into the flow thread.
    152     multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this, true);
    153    
    154     if (multicolContainer->isFieldset()) {
    155         // Keep legends out of the flow thread.
    156         for (auto& box : childrenOfType<RenderBox>(*this)) {
    157             if (box.isLegend())
    158                 moveChildTo(multicolContainer, &box, true);
    159         }
    160     }
    161 }
    162 
    163 void RenderMultiColumnFlow::evacuateAndDestroy()
    164 {
    165     RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
    166     // Delete the line box tree.
    167     deleteLines();
    168     moveAllChildrenTo(multicolContainer, true);
    169     // Move spanners back to their original DOM position in the tree, and destroy the placeholders.
    170     SpannerMap::iterator it;
    171     while ((it = m_spannerMap.begin()) != m_spannerMap.end()) {
    172         RenderBox* spanner = it->key;
    173         auto takenSpanner = multicolContainer->takeChild(*spanner);
    174         ASSERT(it->value.get());
    175         if (RenderMultiColumnSpannerPlaceholder* placeholder = it->value.get()) {
    176             RenderBlockFlow& originalContainer = downcast<RenderBlockFlow>(*placeholder->parent());
    177             originalContainer.addChild(WTFMove(takenSpanner), placeholder);
    178             placeholder->removeFromParentAndDestroy();
    179         }
    180         m_spannerMap.remove(it);
    181     }
    182 
    183     // Remove all sets.
    184     while (RenderMultiColumnSet* columnSet = firstMultiColumnSet())
    185         columnSet->removeFromParentAndDestroy();
    186    
    187     removeFromParentAndDestroy();
    188144}
    189145
     
    417373                // We have to nuke the placeholder, since the ancestor already lost the mapping to it when
    418374                // we shifted the placeholder down into this flow thread.
    419                 placeholder.fragmentedFlow()->m_spannerMap.remove(spanner);
     375                placeholder.fragmentedFlow()->spannerMap().remove(spanner);
    420376
    421377                spannersToDelete.append(placeholder.parent()->takeChild(placeholder));
     
    428384            }
    429385           
    430             ASSERT(!m_spannerMap.get(placeholder.spanner()));
    431             m_spannerMap.add(placeholder.spanner(), makeWeakPtr(placeholder));
     386            ASSERT(!spannerMap().get(placeholder.spanner()));
     387            spannerMap().add(placeholder.spanner(), makeWeakPtr(placeholder));
    432388            ASSERT(!placeholder.firstChild()); // There should be no children here, but if there are, we ought to skip them.
    433389            continue;
     
    440396{
    441397    // The placeholder may already have been removed, but if it hasn't, do so now.
    442     if (auto placeholder = m_spannerMap.take(&downcast<RenderBox>(spanner)))
     398    if (auto placeholder = spannerMap().take(&downcast<RenderBox>(spanner)))
    443399        placeholder->removeFromParentAndDestroy();
    444400
     
    462418        // in the tree.
    463419        ASSERT(relative.isDescendantOf(this));
    464         m_spannerMap.remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner());
     420        spannerMap().remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner());
    465421        return;
    466422    }
  • trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h

    r222874 r222920  
    4444    RenderMultiColumnSet* lastMultiColumnSet() const;
    4545    RenderBox* firstColumnSetOrSpanner() const;
    46     bool hasColumnSpanner() const { return !m_spannerMap.isEmpty(); }
     46    bool hasColumnSpanner() const { return !m_spannerMap->isEmpty(); }
    4747    static RenderBox* nextColumnSetOrSpannerSiblingOf(const RenderBox*);
    4848    static RenderBox* previousColumnSetOrSpannerSiblingOf(const RenderBox*);
    4949
    50     RenderMultiColumnSpannerPlaceholder* findColumnSpannerPlaceholder(RenderBox* spanner) const { return m_spannerMap.get(spanner).get(); }
     50    RenderMultiColumnSpannerPlaceholder* findColumnSpannerPlaceholder(RenderBox* spanner) const { return m_spannerMap->get(spanner).get(); }
    5151
    5252    void layout() override;
    53 
    54     // Populate the flow thread with what's currently its siblings. Called when a regular block
    55     // becomes a multicol container.
    56     void populate();
    57 
    58     // Empty the flow thread by moving everything to the parent. Remove all multicol specific
    59     // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular
    60     // block.
    61     void evacuateAndDestroy();
    6253
    6354    unsigned columnCount() const { return m_columnCount; }
     
    10697    bool shouldCheckColumnBreaks() const override;
    10798
     99    typedef HashMap<RenderBox*, WeakPtr<RenderMultiColumnSpannerPlaceholder>> SpannerMap;
     100    std::unique_ptr<SpannerMap> takeSpannerMap() { return WTFMove(m_spannerMap); }
     101
    108102private:
    109103    bool isRenderMultiColumnFlow() const override { return true; }
     
    126120    void handleSpannerRemoval(RenderObject& spanner);
    127121    RenderObject* processPossibleSpannerDescendant(RenderObject*& subtreeRoot, RenderObject& descendant);
     122
     123    SpannerMap& spannerMap() { return *m_spannerMap; }
    128124   
    129125private:
    130     typedef HashMap<RenderBox*, WeakPtr<RenderMultiColumnSpannerPlaceholder>> SpannerMap;
    131     SpannerMap m_spannerMap;
     126    std::unique_ptr<SpannerMap> m_spannerMap;
    132127
    133128    // The last set we worked on. It's not to be used as the "current set". The concept of a
  • trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.cpp

    r222911 r222920  
    2626
    2727#include "RenderBlockFlow.h"
     28#include "RenderChildIterator.h"
    2829#include "RenderMultiColumnFlow.h"
     30#include "RenderMultiColumnSet.h"
     31#include "RenderMultiColumnSpannerPlaceholder.h"
    2932
    3033namespace WebCore {
     
    3336{
    3437    bool needsFragmentedFlow = flow.requiresColumns(flow.style().columnCount());
    35     auto* multiColumnFlow = flow.multiColumnFlow();
    36     if (!needsFragmentedFlow) {
    37         if (multiColumnFlow) {
    38             flow.clearMultiColumnFlow();
    39             multiColumnFlow->evacuateAndDestroy();
    40             ASSERT(!flow.multiColumnFlow());
    41         }
     38    bool hasFragmentedFlow = flow.multiColumnFlow();
     39
     40    if (!hasFragmentedFlow && needsFragmentedFlow) {
     41        createFragmentedFlow(flow);
    4242        return;
    4343    }
    44     if (!multiColumnFlow)
    45         createFragmentedFlow(flow);
     44    if (hasFragmentedFlow && !needsFragmentedFlow) {
     45        destroyFragmentedFlow(flow);
     46        return;
     47    }
    4648}
    4749
     
    5456    auto& fragmentedFlow = *newFragmentedFlow;
    5557    flow.RenderBlock::addChild(WTFMove(newFragmentedFlow));
    56     fragmentedFlow.populate(); // Called after the flow thread is inserted so that we are reachable by the flow thread.
     58
     59    // Reparent children preceding the fragmented flow into the fragmented flow.
     60    flow.moveChildrenTo(&fragmentedFlow, flow.firstChild(), &fragmentedFlow, true);
     61    if (flow.isFieldset()) {
     62        // Keep legends out of the flow thread.
     63        for (auto& box : childrenOfType<RenderBox>(fragmentedFlow)) {
     64            if (box.isLegend())
     65                fragmentedFlow.moveChildTo(&flow, &box, true);
     66        }
     67    }
     68
    5769    flow.setMultiColumnFlow(fragmentedFlow);
    5870}
    5971
     72void RenderTreeUpdater::MultiColumn::destroyFragmentedFlow(RenderBlockFlow& flow)
     73{
     74    auto& fragmentedFlow = *flow.multiColumnFlow();
     75    flow.clearMultiColumnFlow();
     76
     77    fragmentedFlow.deleteLines();
     78    fragmentedFlow.moveAllChildrenTo(&flow, true);
     79
     80    // Move spanners back to their original DOM position in the tree, and destroy the placeholders.
     81    auto spannerMap = fragmentedFlow.takeSpannerMap();
     82    for (auto& spannerAndPlaceholder : *spannerMap) {
     83        RenderBox& spanner = *spannerAndPlaceholder.key;
     84        auto& placeholder = *spannerAndPlaceholder.value;
     85        auto takenSpanner = flow.takeChild(spanner);
     86        placeholder.parent()->addChild(WTFMove(takenSpanner), &placeholder);
     87        placeholder.removeFromParentAndDestroy();
     88    }
     89
     90    while (auto* columnSet = fragmentedFlow.firstMultiColumnSet())
     91        columnSet->removeFromParentAndDestroy();
     92
     93    fragmentedFlow.removeFromParentAndDestroy();
     94}
    6095
    6196}
  • trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.h

    r222575 r222920  
    3838private:
    3939    static void createFragmentedFlow(RenderBlockFlow&);
     40    static void destroyFragmentedFlow(RenderBlockFlow&);
    4041};
    4142
Note: See TracChangeset for help on using the changeset viewer.