Changeset 268484 in webkit
- Timestamp:
- Oct 14, 2020 1:42:23 PM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 1 added
- 12 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r268483 r268484 1 2020-10-14 Megan Gardner <megan_gardner@apple.com> 2 3 Refactor HighlightData 4 https://bugs.webkit.org/show_bug.cgi?id=217711 5 6 Reviewed by Darin Adler. 7 8 HighlightData was renamed when it was used for more that selections, but 9 more than half the file was only supposed to be used to deal with the current 10 selection, so I've split it back out into a more reasonable set of files. 11 Also made offsets no longer optional, as there doesn't seem to be a need. 12 Extended the HighlightData setRenderRange into InlineTextBox, as it's a better 13 way to calculate that does not use deprecated functions. 14 15 No behavior change. 16 17 * Headers.cmake: 18 * Sources.txt: 19 * WebCore.xcodeproj/project.pbxproj: 20 * editing/FrameSelection.cpp: 21 (WebCore::FrameSelection::setNeedsSelectionUpdate): 22 (WebCore::DragCaretController::nodeWillBeRemoved): 23 (WebCore::FrameSelection::respondToNodeModification): 24 (WebCore::FrameSelection::willBeRemovedFromFrame): 25 (WebCore::FrameSelection::focusedOrActiveStateChanged): 26 (WebCore::FrameSelection::updateAppearance): 27 * page/FrameView.cpp: 28 (WebCore::FrameView::paintContentsForSnapshot): 29 * platform/DragImage.cpp: 30 (WebCore::ScopedFrameSelectionState::~ScopedFrameSelectionState): 31 (WebCore::createDragImageForRange): 32 * rendering/HighlightData.cpp: 33 (WebCore::RenderRangeIterator::RenderRangeIterator): 34 (WebCore::RenderRangeIterator::current const): 35 (WebCore::RenderRangeIterator::next): 36 (WebCore::RenderRangeIterator::checkForSpanner): 37 (WebCore::rendererAfterOffset): 38 (WebCore::HighlightData::highlightStateForRenderer): 39 (): Deleted. 40 (WebCore::isValidRendererForSelection): Deleted. 41 (WebCore::containingBlockBelowView): Deleted. 42 (WebCore::collectSelectionData): Deleted. 43 (WebCore::HighlightData::HighlightData): Deleted. 44 (WebCore::HighlightData::setSelection): Deleted. 45 (WebCore::HighlightData::clearSelection): Deleted. 46 (WebCore::HighlightData::repaintSelection const): Deleted. 47 (WebCore::HighlightData::collectBounds const): Deleted. 48 (WebCore::HighlightData::applySelection): Deleted. 49 * rendering/HighlightData.h: 50 (WebCore::RenderRange::RenderRange): 51 (WebCore::RenderRange::start const): 52 (WebCore::RenderRange::end const): 53 (WebCore::RenderRange::startOffset const): 54 (WebCore::RenderRange::endOffset const): 55 (WebCore::RenderRange::operator== const): 56 (WebCore::HighlightData::startOffset const): 57 (WebCore::HighlightData::endOffset const): 58 (WebCore::HighlightData::RenderRange::RenderRange): Deleted. 59 (WebCore::HighlightData::RenderRange::start const): Deleted. 60 (WebCore::HighlightData::RenderRange::end const): Deleted. 61 (WebCore::HighlightData::RenderRange::startOffset const): Deleted. 62 (WebCore::HighlightData::RenderRange::endOffset const): Deleted. 63 (WebCore::HighlightData::RenderRange::operator== const): Deleted. 64 (WebCore::HighlightData::bounds const): Deleted. 65 (WebCore::HighlightData::boundsClippedToVisibleContent const): Deleted. 66 * rendering/InlineTextBox.cpp: 67 (WebCore::InlineTextBox::collectMarkedTextsForHighlights const): 68 * rendering/RenderReplaced.cpp: 69 (WebCore::RenderReplaced::calculateHighlightColor const): 70 * rendering/RenderView.h: 71 * rendering/SelectionRangeData.cpp: Copied from Source/WebCore/rendering/HighlightData.cpp. 72 (WebCore::rendererAfterOffset): 73 (WebCore::isValidRendererForSelection): 74 (WebCore::containingBlockBelowView): 75 (WebCore::collectSelectionData): 76 (WebCore::SelectionRangeData::SelectionData): 77 (WebCore::SelectionRangeData::set): 78 (WebCore::SelectionRangeData::clear): 79 (WebCore::SelectionRangeData::repaint const): 80 (WebCore::SelectionRangeData::collectBounds const): 81 (WebCore::SelectionRangeData::apply): 82 * rendering/SelectionRangeData.h: Added. 83 (WebCore::SelectionRangeData::bounds const): 84 (WebCore::SelectionRangeData::boundsClippedToVisibleContent const): 85 1 86 2020-10-14 Antoine Quint <graouts@webkit.org> 2 87 -
trunk/Source/WebCore/Headers.cmake
r268423 r268484 1440 1440 rendering/RootInlineBox.h 1441 1441 rendering/ScrollAlignment.h 1442 rendering/SelectionRangeData.h 1442 1443 1443 1444 rendering/line/LineWidth.h -
trunk/Source/WebCore/Sources.txt
r268355 r268484 2222 2222 rendering/RootInlineBox.cpp 2223 2223 rendering/ScrollAlignment.cpp 2224 rendering/SelectionRangeData.cpp 2224 2225 rendering/TableLayout.cpp 2225 2226 rendering/TextDecorationPainter.cpp -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r268453 r268484 1198 1198 445775E520472F73008DCE5D /* LocalDefaultSystemAppearance.h in Headers */ = {isa = PBXBuildFile; fileRef = 445775E420472F73008DCE5D /* LocalDefaultSystemAppearance.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1199 1199 4463CF682212FA68001A8577 /* DataDetectorsCoreSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */; }; 1200 4465D7BD2536D05E0016666D /* SelectionRangeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 44B38BF42536901A00A4458D /* SelectionRangeData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1200 1201 446DC64824A29DAB0061F390 /* PlaybackTargetClientContextIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 446DC64624A29D9B0061F390 /* PlaybackTargetClientContextIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1201 1202 4471710E205AF945000A116E /* MediaQueryParserContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4471710C205AF945000A116E /* MediaQueryParserContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 7924 7925 44A28AAB12DFB8AC00AE923B /* MathMLElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MathMLElementFactory.h; path = DerivedSources/WebCore/MathMLElementFactory.h; sourceTree = BUILT_PRODUCTS_DIR; }; 7925 7926 44A28AAE12DFB8BF00AE923B /* MathMLNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MathMLNames.h; path = DerivedSources/WebCore/MathMLNames.h; sourceTree = BUILT_PRODUCTS_DIR; }; 7927 44B38BF42536901A00A4458D /* SelectionRangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionRangeData.h; sourceTree = "<group>"; }; 7928 44B38BF925369A8800A4458D /* SelectionRangeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionRangeData.cpp; sourceTree = "<group>"; }; 7926 7929 44C991810F3D1E0D00586670 /* ScrollbarThemeIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollbarThemeIOS.mm; sourceTree = "<group>"; }; 7927 7930 44C991850F3D1EBE00586670 /* ScrollbarThemeIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeIOS.h; sourceTree = "<group>"; }; … … 29256 29259 5D925B650F64D4DD00B847F0 /* ScrollAlignment.cpp */, 29257 29260 5D925B660F64D4DD00B847F0 /* ScrollAlignment.h */, 29261 44B38BF925369A8800A4458D /* SelectionRangeData.cpp */, 29262 44B38BF42536901A00A4458D /* SelectionRangeData.h */, 29258 29263 E31CD750229F749500FBDA19 /* TableLayout.cpp */, 29259 29264 A8CFF04C0A154F09000A4234 /* TableLayout.h */, … … 33878 33883 2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */, 33879 33884 B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */, 33885 4465D7BD2536D05E0016666D /* SelectionRangeData.h in Headers */, 33880 33886 BEA807C90F714A0300524199 /* SelectionRect.h in Headers */, 33881 33887 51405C89190B014400754F94 /* SelectionRectGatherer.h in Headers */, -
trunk/Source/WebCore/editing/FrameSelection.cpp
r267962 r268484 452 452 m_pendingSelectionUpdate = true; 453 453 if (RenderView* view = m_document->renderView()) 454 view->selection().clear Selection();454 view->selection().clear(); 455 455 } 456 456 … … 508 508 509 509 if (RenderView* view = node.document().renderView()) 510 view->selection().clear Selection();510 view->selection().clear(); 511 511 512 512 clear(); … … 567 567 if (clearRenderTreeSelection) { 568 568 if (auto* renderView = node.document().renderView()) { 569 renderView->selection().clear Selection();569 renderView->selection().clear(); 570 570 571 571 // Trigger a selection update so the selection will be set again. … … 1571 1571 1572 1572 if (auto* view = m_document->renderView()) 1573 view->selection().clear Selection();1573 view->selection().clear(); 1574 1574 1575 1575 setSelectionWithoutUpdatingAppearance(VisibleSelection(), defaultSetSelectionOptions(), AlignCursorOnScrollIfNeeded, TextGranularity::CharacterGranularity); … … 2059 2059 // we have to update places those colors were painted. 2060 2060 if (RenderView* view = m_document->renderView()) 2061 view->selection().repaint Selection();2061 view->selection().repaint(); 2062 2062 2063 2063 // Caret appears in the active frame. … … 2154 2154 2155 2155 if (!selection.isRange()) { 2156 view->selection().clear Selection();2156 view->selection().clear(); 2157 2157 return; 2158 2158 } … … 2179 2179 int endOffset = endPos.deprecatedEditingOffset(); 2180 2180 ASSERT(startOffset >= 0 && endOffset >= 0); 2181 view->selection().set Selection({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) });2181 view->selection().set({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) }); 2182 2182 } 2183 2183 } -
trunk/Source/WebCore/page/FrameView.cpp
r268307 r268484 4352 4352 for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) { 4353 4353 if (auto* renderView = frame->contentRenderer()) 4354 renderView->selection().clear Selection();4354 renderView->selection().clear(); 4355 4355 } 4356 4356 } -
trunk/Source/WebCore/platform/DragImage.cpp
r267962 r268484 35 35 #include "RenderElement.h" 36 36 #include "RenderView.h" 37 #include "SelectionRangeData.h" 37 38 #include "SimpleRange.h" 38 39 #include "TextIndicator.h" … … 144 145 if (auto* renderView = frame.contentRenderer()) { 145 146 ASSERT(selection); 146 renderView->selection().set Selection(selection.value(), HighlightData::RepaintMode::Nothing);147 renderView->selection().set(selection.value(), SelectionRangeData::RepaintMode::Nothing); 147 148 } 148 149 } 149 150 150 151 const Frame& frame; 151 Optional< HighlightData::RenderRange> selection;152 Optional<RenderRange> selection; 152 153 }; 153 154 … … 186 187 int endOffset = end.deprecatedEditingOffset(); 187 188 ASSERT(startOffset >= 0 && endOffset >= 0); 188 view->selection().set Selection({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) }, HighlightData::RepaintMode::Nothing);189 view->selection().set({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) }, SelectionRangeData::RepaintMode::Nothing); 189 190 // We capture using snapshotFrameRect() because we fake up the selection using 190 191 // FrameView but snapshotSelection() uses the selection from the Frame itself. -
trunk/Source/WebCore/rendering/HighlightData.cpp
r268436 r268484 47 47 namespace WebCore { 48 48 49 namespace { // See bug #177808.50 49 51 struct SelectionData {52 using RendererMap = HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>>;53 using RenderBlockMap = HashMap<const RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>>;54 50 55 Optional<unsigned> startOffset; 56 Optional<unsigned> endOffset;57 RendererMap renderers; 58 RenderBlockMap blocks;59 } ;51 RenderRangeIterator::RenderRangeIterator(RenderObject* start) 52 : m_current(start) 53 { 54 checkForSpanner(); 55 } 60 56 61 class HighlightIterator { 62 public: 63 HighlightIterator(RenderObject* start) 64 : m_current(start) 65 { 57 RenderObject* RenderRangeIterator::current() const 58 { 59 return m_current; 60 } 61 62 RenderObject* RenderRangeIterator::next() 63 { 64 RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner(); 65 m_current = m_current->nextInPreOrder(currentSpan); 66 checkForSpanner(); 67 if (!m_current && currentSpan) { 68 RenderObject* placeholder = m_spannerStack.last(); 69 m_spannerStack.removeLast(); 70 m_current = placeholder->nextInPreOrder(); 66 71 checkForSpanner(); 67 72 } 68 69 RenderObject* current() const 70 { 71 return m_current; 72 } 73 74 RenderObject* next() 75 { 76 RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner(); 77 m_current = m_current->nextInPreOrder(currentSpan); 78 checkForSpanner(); 79 if (!m_current && currentSpan) { 80 RenderObject* placeholder = m_spannerStack.last(); 81 m_spannerStack.removeLast(); 82 m_current = placeholder->nextInPreOrder(); 83 checkForSpanner(); 84 } 85 return m_current; 86 } 73 return m_current; 74 } 87 75 88 private: 89 void checkForSpanner() 90 { 91 if (!is<RenderMultiColumnSpannerPlaceholder>(m_current)) 92 return; 93 auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current); 94 m_spannerStack.append(&placeholder); 95 m_current = placeholder.spanner(); 96 } 76 void RenderRangeIterator::checkForSpanner() 77 { 78 if (!is<RenderMultiColumnSpannerPlaceholder>(m_current)) 79 return; 80 auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current); 81 m_spannerStack.append(&placeholder); 82 m_current = placeholder.spanner(); 83 } 97 84 98 RenderObject* m_current { nullptr }; 99 Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack; 100 }; 101 102 } // anonymous namespace 103 104 static RenderObject* rendererAfterOffset(const RenderObject& renderer, unsigned offset) 85 static RenderObject* rendererAfterOffset(const RenderObject& renderer, unsigned offset) // <MMG> used in both, might should not be static 105 86 { 106 87 auto* child = renderer.childAt(offset); 107 88 return child ? child : renderer.nextInPreOrderAfterChildren(); 108 }109 110 static bool isValidRendererForSelection(const RenderObject& renderer, const HighlightData::RenderRange& selection)111 {112 return (renderer.canBeSelectionLeaf() || &renderer == selection.start() || &renderer == selection.end())113 && renderer.selectionState() != RenderObject::HighlightState::None114 && renderer.containingBlock();115 }116 117 static RenderBlock* containingBlockBelowView(const RenderObject& renderer)118 {119 auto* containingBlock = renderer.containingBlock();120 return is<RenderView>(containingBlock) ? nullptr : containingBlock;121 }122 123 static SelectionData collectSelectionData(const HighlightData::RenderRange& selection, bool repaintDifference)124 {125 SelectionData oldSelectionData { selection.startOffset(), selection.endOffset(), { }, { } };126 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.127 // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise128 // the union of those rects might remain the same even when changes have occurred.129 auto* start = selection.start();130 RenderObject* stop = nullptr;131 if (selection.end())132 stop = rendererAfterOffset(*selection.end(), selection.endOffset().value());133 HighlightIterator selectionIterator(start);134 while (start && start != stop) {135 if (isValidRendererForSelection(*start, selection)) {136 // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.137 oldSelectionData.renderers.set(start, makeUnique<RenderSelectionInfo>(*start, true));138 if (repaintDifference) {139 for (auto* block = containingBlockBelowView(*start); block; block = containingBlockBelowView(*block)) {140 auto& blockInfo = oldSelectionData.blocks.add(block, nullptr).iterator->value;141 if (blockInfo)142 break;143 blockInfo = makeUnique<RenderBlockSelectionInfo>(*block);144 }145 }146 }147 start = selectionIterator.next();148 }149 return oldSelectionData;150 }151 152 HighlightData::HighlightData(RenderView& view)153 : m_renderView(view)154 #if ENABLE(SERVICE_CONTROLS)155 , m_selectionRectGatherer(view)156 #endif157 {158 89 } 159 90 … … 199 130 return RenderObject::HighlightState::End; 200 131 201 auto* highlightEnd = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset() .value());132 auto* highlightEnd = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset()); 202 133 203 HighlightIterator highlightIterator(m_renderRange.start());134 RenderRangeIterator highlightIterator(m_renderRange.start()); 204 135 for (auto* currentRenderer = m_renderRange.start(); currentRenderer && currentRenderer != highlightEnd; currentRenderer = highlightIterator.next()) { 205 136 if (currentRenderer == m_renderRange.start()) … … 213 144 } 214 145 215 void HighlightData::setSelection(const RenderRange& selection, RepaintMode blockRepaintMode)216 {217 if ((selection.start() && !selection.end()) || (selection.end() && !selection.start()))218 return;219 // Just return if the selection hasn't changed.220 auto isCaret = m_renderView.frame().selection().isCaret();221 if (selection == m_renderRange && m_selectionWasCaret == isCaret)222 return;223 #if ENABLE(SERVICE_CONTROLS)224 // Clear the current rects and create a notifier for the new rects we are about to gather.225 // The Notifier updates the Editor when it goes out of scope and is destroyed.226 auto rectNotifier = m_selectionRectGatherer.clearAndCreateNotifier();227 #endif228 m_selectionWasCaret = isCaret;229 applySelection(selection, blockRepaintMode);230 }231 232 void HighlightData::clearSelection()233 {234 m_renderView.layer()->repaintBlockSelectionGaps();235 setSelection({ }, HighlightData::RepaintMode::NewMinusOld);236 }237 238 void HighlightData::repaintSelection() const239 {240 HashSet<RenderBlock*> processedBlocks;241 RenderObject* end = nullptr;242 if (m_renderRange.end())243 end = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());244 HighlightIterator highlightIterator(m_renderRange.start());245 for (auto* renderer = highlightIterator.current(); renderer && renderer != end; renderer = highlightIterator.next()) {246 if (!renderer->canBeSelectionLeaf() && renderer != m_renderRange.start() && renderer != m_renderRange.end())247 continue;248 if (renderer->selectionState() == RenderObject::HighlightState::None)249 continue;250 RenderSelectionInfo(*renderer, true).repaint();251 // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.252 for (auto* block = containingBlockBelowView(*renderer); block; block = containingBlockBelowView(*block)) {253 if (!processedBlocks.add(block).isNewEntry)254 break;255 RenderSelectionInfo(*block, true).repaint();256 }257 }258 }259 260 IntRect HighlightData::collectBounds(ClipToVisibleContent clipToVisibleContent) const261 {262 LOG_WITH_STREAM(Selection, stream << "HighlightData::collectBounds (clip to visible " << (clipToVisibleContent == ClipToVisibleContent::Yes ? "yes" : "no"));263 264 SelectionData::RendererMap renderers;265 auto* start = m_renderRange.start();266 RenderObject* stop = nullptr;267 if (m_renderRange.end())268 stop = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());269 270 HighlightIterator highlightIterator(start);271 while (start && start != stop) {272 if ((start->canBeSelectionLeaf() || start == m_renderRange.start() || start == m_renderRange.end())273 && start->selectionState() != RenderObject::HighlightState::None) {274 // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.275 renderers.set(start, makeUnique<RenderSelectionInfo>(*start, clipToVisibleContent == ClipToVisibleContent::Yes));276 LOG_WITH_STREAM(Selection, stream << " added start " << *start << " with rect " << renderers.get(start)->rect());277 278 auto* block = start->containingBlock();279 while (block && !is<RenderView>(*block)) {280 LOG_WITH_STREAM(Scrolling, stream << " added block " << *block);281 std::unique_ptr<RenderSelectionInfo>& blockInfo = renderers.add(block, nullptr).iterator->value;282 if (blockInfo)283 break;284 blockInfo = makeUnique<RenderSelectionInfo>(*block, clipToVisibleContent == ClipToVisibleContent::Yes);285 LOG_WITH_STREAM(Selection, stream << " added containing block " << *block << " with rect " << blockInfo->rect());286 block = block->containingBlock();287 }288 }289 start = highlightIterator.next();290 }291 292 // Now create a single bounding box rect that encloses the whole selection.293 LayoutRect selectionRect;294 for (auto& info : renderers.values()) {295 // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.296 LayoutRect currentRect = info->rect();297 if (currentRect.isEmpty())298 continue;299 300 if (auto* repaintContainer = info->repaintContainer()) {301 FloatRect localRect = currentRect;302 FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(localRect);303 currentRect = absQuad.enclosingBoundingBox();304 LOG_WITH_STREAM(Selection, stream << " rect " << localRect << " mapped to " << currentRect << " in container " << *repaintContainer);305 }306 selectionRect.unite(currentRect);307 }308 309 LOG_WITH_STREAM(Selection, stream << " final rect " << selectionRect);310 return snappedIntRect(selectionRect);311 }312 313 void HighlightData::applySelection(const RenderRange& newSelection, RepaintMode blockRepaintMode)314 {315 auto oldSelectionData = collectSelectionData(m_renderRange, blockRepaintMode == RepaintMode::NewXOROld);316 // Remove current selection.317 for (auto* renderer : oldSelectionData.renderers.keys())318 renderer->setSelectionStateIfNeeded(RenderObject::HighlightState::None);319 m_renderRange = newSelection;320 auto* selectionStart = m_renderRange.start();321 // Update the selection status of all objects between selectionStart and selectionEnd322 if (selectionStart && selectionStart == m_renderRange.end())323 selectionStart->setSelectionStateIfNeeded(RenderObject::HighlightState::Both);324 else {325 if (selectionStart)326 selectionStart->setSelectionStateIfNeeded(RenderObject::HighlightState::Start);327 if (auto* end = m_renderRange.end())328 end->setSelectionStateIfNeeded(RenderObject::HighlightState::End);329 }330 331 RenderObject* selectionEnd = nullptr;332 auto* selectionDataEnd = m_renderRange.end();333 if (selectionDataEnd)334 selectionEnd = rendererAfterOffset(*selectionDataEnd, m_renderRange.endOffset().value());335 HighlightIterator selectionIterator(selectionStart);336 for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {337 if (currentRenderer == selectionStart || currentRenderer == m_renderRange.end())338 continue;339 if (!currentRenderer->canBeSelectionLeaf())340 continue;341 currentRenderer->setSelectionStateIfNeeded(RenderObject::HighlightState::Inside);342 }343 344 if (blockRepaintMode != RepaintMode::Nothing)345 m_renderView.layer()->clearBlockSelectionGapsBounds();346 347 // Now that the selection state has been updated for the new objects, walk them again and348 // put them in the new objects list.349 SelectionData::RendererMap newSelectedRenderers;350 SelectionData::RenderBlockMap newSelectedBlocks;351 selectionIterator = HighlightIterator(selectionStart);352 for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {353 if (isValidRendererForSelection(*currentRenderer, m_renderRange)) {354 std::unique_ptr<RenderSelectionInfo> selectionInfo = makeUnique<RenderSelectionInfo>(*currentRenderer, true);355 #if ENABLE(SERVICE_CONTROLS)356 for (auto& rect : selectionInfo->collectedSelectionRects())357 m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);358 if (!currentRenderer->isTextOrLineBreak())359 m_selectionRectGatherer.setTextOnly(false);360 #endif361 newSelectedRenderers.set(currentRenderer, WTFMove(selectionInfo));362 auto* containingBlock = currentRenderer->containingBlock();363 while (containingBlock && !is<RenderView>(*containingBlock)) {364 std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;365 if (blockInfo)366 break;367 blockInfo = makeUnique<RenderBlockSelectionInfo>(*containingBlock);368 containingBlock = containingBlock->containingBlock();369 #if ENABLE(SERVICE_CONTROLS)370 m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());371 #endif372 }373 }374 }375 376 if (blockRepaintMode == RepaintMode::Nothing)377 return;378 379 // Have any of the old selected objects changed compared to the new selection?380 for (auto& selectedRendererInfo : oldSelectionData.renderers) {381 auto* renderer = selectedRendererInfo.key;382 auto* newInfo = newSelectedRenderers.get(renderer);383 auto* oldInfo = selectedRendererInfo.value.get();384 if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()385 || (m_renderRange.start() == renderer && oldSelectionData.startOffset != m_renderRange.startOffset())386 || (m_renderRange.end() == renderer && oldSelectionData.endOffset != m_renderRange.endOffset())) {387 oldInfo->repaint();388 if (newInfo) {389 newInfo->repaint();390 newSelectedRenderers.remove(renderer);391 }392 }393 }394 395 // Any new objects that remain were not found in the old objects dict, and so they need to be updated.396 for (auto& selectedRendererInfo : newSelectedRenderers)397 selectedRendererInfo.value->repaint();398 399 // Have any of the old blocks changed?400 for (auto& selectedBlockInfo : oldSelectionData.blocks) {401 auto* block = selectedBlockInfo.key;402 auto* newInfo = newSelectedBlocks.get(block);403 auto* oldInfo = selectedBlockInfo.value.get();404 if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {405 oldInfo->repaint();406 if (newInfo) {407 newInfo->repaint();408 newSelectedBlocks.remove(block);409 }410 }411 }412 413 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.414 for (auto& selectedBlockInfo : newSelectedBlocks)415 selectedBlockInfo.value->repaint();416 }417 418 146 } // namespace WebCore -
trunk/Source/WebCore/rendering/HighlightData.h
r268436 r268484 31 31 #pragma once 32 32 33 #include "RenderSelectionInfo.h" 34 35 #if ENABLE(SERVICE_CONTROLS) 36 #include "SelectionRectGatherer.h" 37 #endif 33 #include "RenderObject.h" 38 34 39 35 namespace WebCore { 40 36 41 37 struct HighlightRangeData; 38 class RenderMultiColumnSpannerPlaceholder; 39 40 class RenderRange { 41 public: 42 RenderRange() = default; 43 RenderRange(RenderObject* start, RenderObject* end, unsigned startOffset, unsigned endOffset) 44 : m_start(makeWeakPtr(start)) 45 , m_end(makeWeakPtr(end)) 46 , m_startOffset(startOffset) 47 , m_endOffset(endOffset) 48 { 49 } 50 51 RenderObject* start() const { return m_start.get(); } 52 RenderObject* end() const { return m_end.get(); } 53 unsigned startOffset() const { return m_startOffset; } 54 unsigned endOffset() const { return m_endOffset; } 55 56 bool operator==(const RenderRange& other) const 57 { 58 return m_start == other.m_start && m_end == other.m_end && m_startOffset == other.m_startOffset && m_endOffset == other.m_endOffset; 59 } 60 61 private: 62 WeakPtr<RenderObject> m_start; 63 WeakPtr<RenderObject> m_end; 64 unsigned m_startOffset { 0 }; 65 unsigned m_endOffset { 0 }; 66 }; 42 67 68 class RenderRangeIterator { 69 public: 70 RenderRangeIterator(RenderObject* start); 71 RenderObject* current() const; 72 RenderObject* next(); 73 74 private: 75 void checkForSpanner(); 76 77 RenderObject* m_current { nullptr }; 78 Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack; 79 }; 80 43 81 class HighlightData { 44 82 public: 45 HighlightData(RenderView&);46 47 class RenderRange {48 public:49 RenderRange() = default;50 RenderRange(RenderObject* start, RenderObject* end, unsigned startOffset, unsigned endOffset)51 : m_start(makeWeakPtr(start))52 , m_end(makeWeakPtr(end))53 , m_startOffset(startOffset)54 , m_endOffset(endOffset)55 {56 }57 58 RenderObject* start() const { return m_start.get(); }59 RenderObject* end() const { return m_end.get(); }60 Optional<unsigned> startOffset() const { return m_startOffset; }61 Optional<unsigned> endOffset() const { return m_endOffset; }62 63 bool operator==(const RenderRange& other) const64 {65 return m_start == other.m_start && m_end == other.m_end && m_startOffset == other.m_startOffset && m_endOffset == other.m_endOffset;66 }67 68 private:69 WeakPtr<RenderObject> m_start;70 WeakPtr<RenderObject> m_end;71 Optional<unsigned> m_startOffset;72 Optional<unsigned> m_endOffset;73 };74 75 83 void setRenderRange(const RenderRange&); 76 84 bool setRenderRange(const HighlightRangeData&); // Returns true if successful. 77 78 enum class RepaintMode { NewXOROld, NewMinusOld, Nothing };79 void setSelection(const RenderRange&, RepaintMode = RepaintMode::NewXOROld);80 85 const RenderRange& get() const { return m_renderRange; } 81 86 … … 83 88 RenderObject* end() const { return m_renderRange.end(); } 84 89 85 unsigned startOffset() const { ASSERT(m_renderRange.startOffset()); return m_renderRange.startOffset().valueOr(0); }86 unsigned endOffset() const { ASSERT(m_renderRange.endOffset()); return m_renderRange.endOffset().valueOr(0); }90 unsigned startOffset() const { return m_renderRange.startOffset(); } 91 unsigned endOffset() const { return m_renderRange.endOffset(); } 87 92 88 void clearSelection();89 IntRect bounds() const { return collectBounds(ClipToVisibleContent::No); }90 IntRect boundsClippedToVisibleContent() const { return collectBounds(ClipToVisibleContent::Yes); }91 void repaintSelection() const;92 93 93 RenderObject::HighlightState highlightStateForRenderer(const RenderObject&); 94 94 95 private: 96 enum class ClipToVisibleContent { Yes, No }; 97 IntRect collectBounds(ClipToVisibleContent) const; 98 void applySelection(const RenderRange&, RepaintMode); 99 100 const RenderView& m_renderView; 101 #if ENABLE(SERVICE_CONTROLS) 102 SelectionRectGatherer m_selectionRectGatherer; 103 #endif 95 protected: 104 96 RenderRange m_renderRange; 105 bool m_selectionWasCaret { false };106 97 }; 107 98 -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r265338 r268484 1051 1051 auto& parentRenderer = parent()->renderer(); 1052 1052 auto& parentStyle = parentRenderer.style(); 1053 HighlightData highlightData; 1053 1054 for (auto& highlight : renderer().document().highlightMap().map()) { 1054 1055 auto renderStyle = parentRenderer.getUncachedPseudoStyle({ PseudoId::Highlight, highlight.key }, &parentStyle); … … 1058 1059 continue; 1059 1060 for (auto& rangeData : highlight.value->rangesData()) { 1060 if (rangeData->startPosition && rangeData->endPosition) { 1061 Position startPosition = rangeData->startPosition.value(); 1062 Position endPosition = rangeData->endPosition.value(); 1063 auto* startRenderer = startPosition.deprecatedNode()->renderer(); 1064 unsigned startOffset = startPosition.deprecatedEditingOffset(); 1065 auto* endRenderer = endPosition.deprecatedNode()->renderer(); 1066 unsigned endOffset = endPosition.deprecatedEditingOffset(); 1067 if (!startRenderer || !endRenderer) 1068 continue; 1069 1070 auto highlightData = HighlightData(renderer().view()); 1071 highlightData.setRenderRange({ startRenderer, endRenderer, startOffset, endOffset }); 1072 auto [highlightStart, highlightEnd] = highlightStartEnd(highlightData); 1073 if (highlightStart < highlightEnd) 1074 markedTexts.append({ highlightStart, highlightEnd, MarkedText::Highlight, nullptr, highlight.key }); 1075 } 1061 if (!highlightData.setRenderRange(rangeData)) 1062 continue; 1063 1064 auto [highlightStart, highlightEnd] = highlightStartEnd(highlightData); 1065 if (highlightStart < highlightEnd) 1066 markedTexts.append({ highlightStart, highlightEnd, MarkedText::Highlight, nullptr, highlight.key }); 1076 1067 } 1077 1068 } -
trunk/Source/WebCore/rendering/RenderReplaced.cpp
r268436 r268484 153 153 Color RenderReplaced::calculateHighlightColor() const 154 154 { 155 auto highlightData = HighlightData(view());155 HighlightData highlightData; 156 156 for (auto& highlight : document().highlightMap().map()) { 157 157 for (auto& rangeData : highlight.value->rangesData()) { -
trunk/Source/WebCore/rendering/RenderView.h
r260415 r268484 23 23 24 24 #include "FrameView.h" 25 #include "HighlightData.h"26 25 #include "Region.h" 27 26 #include "RenderBlockFlow.h" 28 27 #include "RenderWidget.h" 28 #include "SelectionRangeData.h" 29 29 #include <memory> 30 30 #include <wtf/HashSet.h> … … 85 85 RenderElement* rendererForRootBackground() const; 86 86 87 HighlightData& selection() { return m_selection; }87 SelectionRangeData& selection() { return m_selection; } 88 88 89 89 bool printing() const; … … 225 225 226 226 mutable std::unique_ptr<Region> m_accumulatedRepaintRegion; 227 HighlightData m_selection;227 SelectionRangeData m_selection; 228 228 229 229 WeakPtr<RenderLayer> m_styleChangeLayerMutationRoot; -
trunk/Source/WebCore/rendering/SelectionRangeData.cpp
r268483 r268484 1 1 /* 2 * Copyright (C) 2014 Igalia S.L. 3 * Copyright (C) 2015-2017 Apple Inc. All rights reserved. 2 * Copyright (C) 2020 Apple Inc. All rights reserved. 4 3 * 5 4 * Redistribution and use in source and binary forms, with or without … … 30 29 31 30 #include "config.h" 32 #include " HighlightData.h"31 #include "SelectionRangeData.h" 33 32 34 33 #include "Document.h" … … 39 38 #include "Range.h" 40 39 #include "RenderLayer.h" 41 #include "RenderMultiColumnSpannerPlaceholder.h"42 40 #include "RenderObject.h" 43 41 #include "RenderView.h" … … 47 45 namespace WebCore { 48 46 49 namespace { // See bug #177808. 50 51 struct SelectionData { 47 namespace { 48 49 struct SelectionContext { 50 52 51 using RendererMap = HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>>; 53 52 using RenderBlockMap = HashMap<const RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>>; 54 53 55 Optional<unsigned>startOffset;56 Optional<unsigned>endOffset;54 unsigned startOffset; 55 unsigned endOffset; 57 56 RendererMap renderers; 58 57 RenderBlockMap blocks; 59 58 }; 60 59 61 class HighlightIterator { 62 public: 63 HighlightIterator(RenderObject* start) 64 : m_current(start) 65 { 66 checkForSpanner(); 67 } 68 69 RenderObject* current() const 70 { 71 return m_current; 72 } 73 74 RenderObject* next() 75 { 76 RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner(); 77 m_current = m_current->nextInPreOrder(currentSpan); 78 checkForSpanner(); 79 if (!m_current && currentSpan) { 80 RenderObject* placeholder = m_spannerStack.last(); 81 m_spannerStack.removeLast(); 82 m_current = placeholder->nextInPreOrder(); 83 checkForSpanner(); 84 } 85 return m_current; 86 } 87 88 private: 89 void checkForSpanner() 90 { 91 if (!is<RenderMultiColumnSpannerPlaceholder>(m_current)) 92 return; 93 auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current); 94 m_spannerStack.append(&placeholder); 95 m_current = placeholder.spanner(); 96 } 97 98 RenderObject* m_current { nullptr }; 99 Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack; 100 }; 101 102 } // anonymous namespace 60 } 103 61 104 62 static RenderObject* rendererAfterOffset(const RenderObject& renderer, unsigned offset) … … 108 66 } 109 67 110 static bool isValidRendererForSelection(const RenderObject& renderer, const HighlightData::RenderRange& selection)68 static bool isValidRendererForSelection(const RenderObject& renderer, const RenderRange& selection) 111 69 { 112 70 return (renderer.canBeSelectionLeaf() || &renderer == selection.start() || &renderer == selection.end()) 113 114 71 && renderer.selectionState() != RenderObject::HighlightState::None 72 && renderer.containingBlock(); 115 73 } 116 74 … … 121 79 } 122 80 123 static Selection Data collectSelectionData(const HighlightData::RenderRange& selection, bool repaintDifference)124 { 125 Selection DataoldSelectionData { selection.startOffset(), selection.endOffset(), { }, { } };81 static SelectionContext collectSelectionData(const RenderRange& selection, bool repaintDifference) 82 { 83 SelectionContext oldSelectionData { selection.startOffset(), selection.endOffset(), { }, { } }; 126 84 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks. 127 85 // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise … … 130 88 RenderObject* stop = nullptr; 131 89 if (selection.end()) 132 stop = rendererAfterOffset(*selection.end(), selection.endOffset() .value());133 HighlightIterator selectionIterator(start);90 stop = rendererAfterOffset(*selection.end(), selection.endOffset()); 91 RenderRangeIterator selectionIterator(start); 134 92 while (start && start != stop) { 135 93 if (isValidRendererForSelection(*start, selection)) { … … 150 108 } 151 109 152 HighlightData::HighlightData(RenderView& view)110 SelectionRangeData::SelectionRangeData(RenderView& view) 153 111 : m_renderView(view) 154 112 #if ENABLE(SERVICE_CONTROLS) … … 158 116 } 159 117 160 void HighlightData::setRenderRange(const RenderRange& renderRange) 161 { 162 ASSERT(renderRange.start() && renderRange.end()); 163 m_renderRange = renderRange; 164 } 165 166 bool HighlightData::setRenderRange(const HighlightRangeData& rangeData) 167 { 168 if (!rangeData.startPosition || !rangeData.endPosition) 169 return false; 170 171 auto startPosition = rangeData.startPosition.value(); 172 auto endPosition = rangeData.endPosition.value(); 173 174 if (!startPosition.containerNode() || !endPosition.containerNode()) 175 return false; 176 177 auto* startRenderer = startPosition.containerNode()->renderer(); 178 auto* endRenderer = endPosition.containerNode()->renderer(); 179 180 if (!startRenderer || !endRenderer) 181 return false; 182 183 unsigned startOffset = startPosition.computeOffsetInContainerNode(); 184 unsigned endOffset = endPosition.computeOffsetInContainerNode(); 185 186 setRenderRange({ startRenderer, endRenderer, startOffset, endOffset }); 187 return true; 188 } 189 190 RenderObject::HighlightState HighlightData::highlightStateForRenderer(const RenderObject& renderer) 191 { 192 if (&renderer == m_renderRange.start()) { 193 if (m_renderRange.start() && m_renderRange.end() && m_renderRange.start() == m_renderRange.end()) 194 return RenderObject::HighlightState::Both; 195 if (m_renderRange.start()) 196 return RenderObject::HighlightState::Start; 197 } 198 if (&renderer == m_renderRange.end()) 199 return RenderObject::HighlightState::End; 200 201 auto* highlightEnd = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value()); 202 203 HighlightIterator highlightIterator(m_renderRange.start()); 204 for (auto* currentRenderer = m_renderRange.start(); currentRenderer && currentRenderer != highlightEnd; currentRenderer = highlightIterator.next()) { 205 if (currentRenderer == m_renderRange.start()) 206 continue; 207 if (!currentRenderer->canBeSelectionLeaf()) 208 continue; 209 if (&renderer == currentRenderer) 210 return RenderObject::HighlightState::Inside; 211 } 212 return RenderObject::HighlightState::None; 213 } 214 215 void HighlightData::setSelection(const RenderRange& selection, RepaintMode blockRepaintMode) 118 void SelectionRangeData::set(const RenderRange& selection, RepaintMode blockRepaintMode) 216 119 { 217 120 if ((selection.start() && !selection.end()) || (selection.end() && !selection.start())) … … 227 130 #endif 228 131 m_selectionWasCaret = isCaret; 229 apply Selection(selection, blockRepaintMode);230 } 231 232 void HighlightData::clearSelection()132 apply(selection, blockRepaintMode); 133 } 134 135 void SelectionRangeData::clear() 233 136 { 234 137 m_renderView.layer()->repaintBlockSelectionGaps(); 235 set Selection({ }, HighlightData::RepaintMode::NewMinusOld);236 } 237 238 void HighlightData::repaintSelection() const138 set({ }, SelectionRangeData::RepaintMode::NewMinusOld); 139 } 140 141 void SelectionRangeData::repaint() const 239 142 { 240 143 HashSet<RenderBlock*> processedBlocks; 241 144 RenderObject* end = nullptr; 242 145 if (m_renderRange.end()) 243 end = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset() .value());244 HighlightIterator highlightIterator(m_renderRange.start());146 end = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset()); 147 RenderRangeIterator highlightIterator(m_renderRange.start()); 245 148 for (auto* renderer = highlightIterator.current(); renderer && renderer != end; renderer = highlightIterator.next()) { 246 149 if (!renderer->canBeSelectionLeaf() && renderer != m_renderRange.start() && renderer != m_renderRange.end()) … … 258 161 } 259 162 260 IntRect HighlightData::collectBounds(ClipToVisibleContent clipToVisibleContent) const261 { 262 LOG_WITH_STREAM(Selection, stream << " HighlightData::collectBounds (clip to visible " << (clipToVisibleContent == ClipToVisibleContent::Yes ? "yes" : "no"));263 264 Selection Data::RendererMap renderers;163 IntRect SelectionRangeData::collectBounds(ClipToVisibleContent clipToVisibleContent) const 164 { 165 LOG_WITH_STREAM(Selection, stream << "SelectionData::collectBounds (clip to visible " << (clipToVisibleContent == ClipToVisibleContent::Yes ? "yes" : "no")); 166 167 SelectionContext::RendererMap renderers; 265 168 auto* start = m_renderRange.start(); 266 169 RenderObject* stop = nullptr; 267 170 if (m_renderRange.end()) 268 stop = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset() .value());269 270 HighlightIterator highlightIterator(start);171 stop = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset()); 172 173 RenderRangeIterator selectionIterator(start); 271 174 while (start && start != stop) { 272 175 if ((start->canBeSelectionLeaf() || start == m_renderRange.start() || start == m_renderRange.end()) … … 275 178 renderers.set(start, makeUnique<RenderSelectionInfo>(*start, clipToVisibleContent == ClipToVisibleContent::Yes)); 276 179 LOG_WITH_STREAM(Selection, stream << " added start " << *start << " with rect " << renderers.get(start)->rect()); 277 180 278 181 auto* block = start->containingBlock(); 279 182 while (block && !is<RenderView>(*block)) { … … 287 190 } 288 191 } 289 start = highlightIterator.next();290 } 291 192 start = selectionIterator.next(); 193 } 194 292 195 // Now create a single bounding box rect that encloses the whole selection. 293 196 LayoutRect selectionRect; … … 297 200 if (currentRect.isEmpty()) 298 201 continue; 299 202 300 203 if (auto* repaintContainer = info->repaintContainer()) { 301 204 FloatRect localRect = currentRect; … … 306 209 selectionRect.unite(currentRect); 307 210 } 308 211 309 212 LOG_WITH_STREAM(Selection, stream << " final rect " << selectionRect); 310 213 return snappedIntRect(selectionRect); 311 214 } 312 215 313 void HighlightData::applySelection(const RenderRange& newSelection, RepaintMode blockRepaintMode)216 void SelectionRangeData::apply(const RenderRange& newSelection, RepaintMode blockRepaintMode) 314 217 { 315 218 auto oldSelectionData = collectSelectionData(m_renderRange, blockRepaintMode == RepaintMode::NewXOROld); … … 328 231 end->setSelectionStateIfNeeded(RenderObject::HighlightState::End); 329 232 } 330 233 331 234 RenderObject* selectionEnd = nullptr; 332 235 auto* selectionDataEnd = m_renderRange.end(); 333 236 if (selectionDataEnd) 334 selectionEnd = rendererAfterOffset(*selectionDataEnd, m_renderRange.endOffset() .value());335 HighlightIterator selectionIterator(selectionStart);237 selectionEnd = rendererAfterOffset(*selectionDataEnd, m_renderRange.endOffset()); 238 RenderRangeIterator selectionIterator(selectionStart); 336 239 for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) { 337 240 if (currentRenderer == selectionStart || currentRenderer == m_renderRange.end()) … … 341 244 currentRenderer->setSelectionStateIfNeeded(RenderObject::HighlightState::Inside); 342 245 } 343 246 344 247 if (blockRepaintMode != RepaintMode::Nothing) 345 248 m_renderView.layer()->clearBlockSelectionGapsBounds(); 346 249 347 250 // Now that the selection state has been updated for the new objects, walk them again and 348 251 // put them in the new objects list. 349 Selection Data::RendererMap newSelectedRenderers;350 Selection Data::RenderBlockMap newSelectedBlocks;351 selectionIterator = HighlightIterator(selectionStart);252 SelectionContext::RendererMap newSelectedRenderers; 253 SelectionContext::RenderBlockMap newSelectedBlocks; 254 selectionIterator = RenderRangeIterator(selectionStart); 352 255 for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) { 353 256 if (isValidRendererForSelection(*currentRenderer, m_renderRange)) { … … 373 276 } 374 277 } 375 278 376 279 if (blockRepaintMode == RepaintMode::Nothing) 377 280 return; 378 281 379 282 // Have any of the old selected objects changed compared to the new selection? 380 283 for (auto& selectedRendererInfo : oldSelectionData.renderers) { … … 392 295 } 393 296 } 394 297 395 298 // Any new objects that remain were not found in the old objects dict, and so they need to be updated. 396 299 for (auto& selectedRendererInfo : newSelectedRenderers) 397 300 selectedRendererInfo.value->repaint(); 398 301 399 302 // Have any of the old blocks changed? 400 303 for (auto& selectedBlockInfo : oldSelectionData.blocks) { … … 410 313 } 411 314 } 412 315 413 316 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated. 414 317 for (auto& selectedBlockInfo : newSelectedBlocks)
Note: See TracChangeset
for help on using the changeset viewer.