Changeset 222920 in webkit
- Timestamp:
- Oct 5, 2017 10:59:49 AM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r222917 r222920 1 2017-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 1 31 2017-10-05 Darin Adler <darin@apple.com> 2 32 -
trunk/Source/WebCore/rendering/RenderMultiColumnFlow.cpp
r222911 r222920 41 41 RenderMultiColumnFlow::RenderMultiColumnFlow(Document& document, RenderStyle&& style) 42 42 : RenderFragmentedFlow(document, WTFMove(style)) 43 , m_spannerMap(std::make_unique<SpannerMap>()) 43 44 , m_lastSetWorkedOn(nullptr) 44 45 , m_columnCount(1) … … 141 142 } 142 143 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 content150 // now. At this point there's obviously nothing after the flow thread, but renderers (column151 // 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();188 144 } 189 145 … … 417 373 // We have to nuke the placeholder, since the ancestor already lost the mapping to it when 418 374 // we shifted the placeholder down into this flow thread. 419 placeholder.fragmentedFlow()-> m_spannerMap.remove(spanner);375 placeholder.fragmentedFlow()->spannerMap().remove(spanner); 420 376 421 377 spannersToDelete.append(placeholder.parent()->takeChild(placeholder)); … … 428 384 } 429 385 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)); 432 388 ASSERT(!placeholder.firstChild()); // There should be no children here, but if there are, we ought to skip them. 433 389 continue; … … 440 396 { 441 397 // 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))) 443 399 placeholder->removeFromParentAndDestroy(); 444 400 … … 462 418 // in the tree. 463 419 ASSERT(relative.isDescendantOf(this)); 464 m_spannerMap.remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner());420 spannerMap().remove(downcast<RenderMultiColumnSpannerPlaceholder>(relative).spanner()); 465 421 return; 466 422 } -
trunk/Source/WebCore/rendering/RenderMultiColumnFlow.h
r222874 r222920 44 44 RenderMultiColumnSet* lastMultiColumnSet() const; 45 45 RenderBox* firstColumnSetOrSpanner() const; 46 bool hasColumnSpanner() const { return !m_spannerMap .isEmpty(); }46 bool hasColumnSpanner() const { return !m_spannerMap->isEmpty(); } 47 47 static RenderBox* nextColumnSetOrSpannerSiblingOf(const RenderBox*); 48 48 static RenderBox* previousColumnSetOrSpannerSiblingOf(const RenderBox*); 49 49 50 RenderMultiColumnSpannerPlaceholder* findColumnSpannerPlaceholder(RenderBox* spanner) const { return m_spannerMap .get(spanner).get(); }50 RenderMultiColumnSpannerPlaceholder* findColumnSpannerPlaceholder(RenderBox* spanner) const { return m_spannerMap->get(spanner).get(); } 51 51 52 52 void layout() override; 53 54 // Populate the flow thread with what's currently its siblings. Called when a regular block55 // becomes a multicol container.56 void populate();57 58 // Empty the flow thread by moving everything to the parent. Remove all multicol specific59 // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular60 // block.61 void evacuateAndDestroy();62 53 63 54 unsigned columnCount() const { return m_columnCount; } … … 106 97 bool shouldCheckColumnBreaks() const override; 107 98 99 typedef HashMap<RenderBox*, WeakPtr<RenderMultiColumnSpannerPlaceholder>> SpannerMap; 100 std::unique_ptr<SpannerMap> takeSpannerMap() { return WTFMove(m_spannerMap); } 101 108 102 private: 109 103 bool isRenderMultiColumnFlow() const override { return true; } … … 126 120 void handleSpannerRemoval(RenderObject& spanner); 127 121 RenderObject* processPossibleSpannerDescendant(RenderObject*& subtreeRoot, RenderObject& descendant); 122 123 SpannerMap& spannerMap() { return *m_spannerMap; } 128 124 129 125 private: 130 typedef HashMap<RenderBox*, WeakPtr<RenderMultiColumnSpannerPlaceholder>> SpannerMap; 131 SpannerMap m_spannerMap; 126 std::unique_ptr<SpannerMap> m_spannerMap; 132 127 133 128 // 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 26 26 27 27 #include "RenderBlockFlow.h" 28 #include "RenderChildIterator.h" 28 29 #include "RenderMultiColumnFlow.h" 30 #include "RenderMultiColumnSet.h" 31 #include "RenderMultiColumnSpannerPlaceholder.h" 29 32 30 33 namespace WebCore { … … 33 36 { 34 37 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); 42 42 return; 43 43 } 44 if (!multiColumnFlow) 45 createFragmentedFlow(flow); 44 if (hasFragmentedFlow && !needsFragmentedFlow) { 45 destroyFragmentedFlow(flow); 46 return; 47 } 46 48 } 47 49 … … 54 56 auto& fragmentedFlow = *newFragmentedFlow; 55 57 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 57 69 flow.setMultiColumnFlow(fragmentedFlow); 58 70 } 59 71 72 void 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 } 60 95 61 96 } -
trunk/Source/WebCore/style/RenderTreeUpdaterMultiColumn.h
r222575 r222920 38 38 private: 39 39 static void createFragmentedFlow(RenderBlockFlow&); 40 static void destroyFragmentedFlow(RenderBlockFlow&); 40 41 }; 41 42
Note: See TracChangeset
for help on using the changeset viewer.