Changeset 222697 in webkit
- Timestamp:
- Oct 1, 2017 9:46:32 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 2 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r222692 r222697 2750 2750 rendering/RootInlineBox.cpp 2751 2751 rendering/ScrollAlignment.cpp 2752 rendering/Selection SubtreeRoot.cpp2752 rendering/SelectionRangeData.cpp 2753 2753 rendering/SimpleLineLayout.cpp 2754 2754 rendering/SimpleLineLayoutCoverage.cpp -
trunk/Source/WebCore/ChangeLog
r222695 r222697 1 2017-10-01 Zalan Bujtas <zalan@apple.com> 2 3 RenderView does not need to be a SelectionSubtreeRoot 4 https://bugs.webkit.org/show_bug.cgi?id=177713 5 6 Reviewed by Darin Adler and Antti Koivisto. 7 8 1. SelectionSubtreeRoot -> SelectionRangeData 9 2. Move all selection logic from RenderView to SelectionRangeData 10 3. class RenderView : public SelectionSubtreeRoot -> SelectionRangeData m_selection; 11 4. Remove redundant code 12 5. General modernization 13 14 No change in functionality. 15 16 * editing/FrameSelection.cpp: 17 (WebCore::FrameSelection::setNeedsSelectionUpdate): 18 (WebCore::DragCaretController::nodeWillBeRemoved): 19 (WebCore::FrameSelection::respondToNodeModification): 20 (WebCore::FrameSelection::prepareForDestruction): 21 (WebCore::FrameSelection::focusedOrActiveStateChanged): 22 (WebCore::FrameSelection::updateAppearance): 23 (WebCore::FrameSelection::selectionBounds const): 24 * page/FrameView.cpp: 25 (WebCore::FrameView::paintContentsForSnapshot): 26 * platform/DragImage.cpp: 27 (WebCore::ScopedFrameSelectionState::ScopedFrameSelectionState): 28 (WebCore::ScopedFrameSelectionState::~ScopedFrameSelectionState): 29 (WebCore::createDragImageForRange): 30 * rendering/InlineTextBox.cpp: 31 (WebCore::InlineTextBox::selectionState): 32 (WebCore::InlineTextBox::selectionStartEnd const): 33 * rendering/RenderBlock.cpp: 34 (WebCore::RenderBlock::isSelectionRoot const): 35 * rendering/RenderObject.cpp: 36 (WebCore::RenderObject::isSelectionBorder const): 37 * rendering/RenderObject.h: 38 * rendering/RenderReplaced.cpp: 39 (WebCore::RenderReplaced::isSelected const): 40 * rendering/RenderText.cpp: 41 (WebCore::RenderText::collectSelectionRectsForLineBoxes): 42 * rendering/RenderTextLineBoxes.cpp: 43 (WebCore::RenderTextLineBoxes::setSelectionState): 44 * rendering/RenderView.cpp: 45 (WebCore::RenderView::RenderView): 46 (WebCore::SelectionIterator::SelectionIterator): Deleted. 47 (WebCore::SelectionIterator::current const): Deleted. 48 (WebCore::SelectionIterator::next): Deleted. 49 (WebCore::SelectionIterator::checkForSpanner): Deleted. 50 (WebCore::rendererAfterPosition): Deleted. 51 (WebCore::RenderView::selectionBounds const): Deleted. 52 (WebCore::RenderView::subtreeSelectionBounds const): Deleted. 53 (WebCore::RenderView::repaintSelection const): Deleted. 54 (WebCore::RenderView::repaintSubtreeSelection const): Deleted. 55 (WebCore::RenderView::setSelection): Deleted. 56 (WebCore::isValidObjectForNewSelection): Deleted. 57 (WebCore::RenderView::clearSubtreeSelection const): Deleted. 58 (WebCore::RenderView::applySubtreeSelection): Deleted. 59 (WebCore::RenderView::getSelection const): Deleted. 60 (WebCore::RenderView::clearSelection): Deleted. 61 * rendering/RenderView.h: 62 * rendering/SelectionSubtreeRoot.cpp: 63 (WebCore::rendererAfterPosition): 64 (WebCore::SelectionIterator::SelectionIterator): 65 (WebCore::SelectionIterator::current const): 66 (WebCore::SelectionIterator::next): 67 (WebCore::SelectionIterator::checkForSpanner): 68 (WebCore::SelectionRangeData::SelectionRangeData): 69 (WebCore::SelectionRangeData::set): 70 (WebCore::SelectionRangeData::clear): 71 (WebCore::SelectionRangeData::repaint const): 72 (WebCore::SelectionRangeData::bounds const): 73 (WebCore::SelectionRangeData::collectAndClear const): 74 (WebCore::SelectionRangeData::apply): 75 (WebCore::SelectionRangeData::isValidRendererForNewSelection const): 76 (WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot): Deleted. 77 * rendering/SelectionSubtreeRoot.h: 78 (WebCore::SelectionRangeData::Context::operator== const): 79 (WebCore::SelectionRangeData::get const): 80 (WebCore::SelectionRangeData::start const): 81 (WebCore::SelectionRangeData::end const): 82 (WebCore::SelectionRangeData::startPosition const): 83 (WebCore::SelectionRangeData::endPosition const): 84 (WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData): Deleted. 85 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::SelectionSubtreeData): Deleted. 86 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStart const): Deleted. 87 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartPos const): Deleted. 88 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEnd const): Deleted. 89 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEndPos const): Deleted. 90 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartEndPositions const): Deleted. 91 (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::clearSelection): Deleted. 92 (WebCore::SelectionSubtreeRoot::selectionData): Deleted. 93 (WebCore::SelectionSubtreeRoot::selectionData const): Deleted. 94 (WebCore::SelectionSubtreeRoot::setSelectionData): Deleted. 95 1 96 2017-10-01 Sam Weinig <sam@webkit.org> 2 97 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r222692 r222697 6433 6433 CDCD41E71C3DDB0900965D99 /* ParsedContentRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */; }; 6434 6434 CDCD41E81C3DDB0A00965D99 /* ParsedContentRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6435 CDCFABBD18C0AF78006F8450 /* Selection SubtreeRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */; settings = {ATTRIBUTES = (Private, ); }; };6436 CDCFABBE18C0AF84006F8450 /* Selection SubtreeRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */; };6435 CDCFABBD18C0AF78006F8450 /* SelectionRangeData.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCFABBB18C0AE31006F8450 /* SelectionRangeData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 6436 CDCFABBE18C0AF84006F8450 /* SelectionRangeData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFABBC18C0AF19006F8450 /* SelectionRangeData.cpp */; }; 6437 6437 CDD7089618359F6F002B3DC6 /* SampleMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDD7089418359F6E002B3DC6 /* SampleMap.cpp */; }; 6438 6438 CDD7089718359F6F002B3DC6 /* SampleMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CDD7089518359F6F002B3DC6 /* SampleMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 15215 15215 CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParsedContentRange.h; sourceTree = "<group>"; }; 15216 15216 CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetFactory.in; sourceTree = "<group>"; }; 15217 CDCFABBB18C0AE31006F8450 /* Selection SubtreeRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionSubtreeRoot.h; sourceTree = "<group>"; };15218 CDCFABBC18C0AF19006F8450 /* Selection SubtreeRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionSubtreeRoot.cpp; sourceTree = "<group>"; };15217 CDCFABBB18C0AE31006F8450 /* SelectionRangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionRangeData.h; sourceTree = "<group>"; }; 15218 CDCFABBC18C0AF19006F8450 /* SelectionRangeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionRangeData.cpp; sourceTree = "<group>"; }; 15219 15219 CDD1E525167BA56400CE820B /* TextTrackRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTrackRepresentation.h; sourceTree = "<group>"; }; 15220 15220 CDD7089418359F6E002B3DC6 /* SampleMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleMap.cpp; sourceTree = "<group>"; }; … … 26129 26129 5D925B650F64D4DD00B847F0 /* ScrollAlignment.cpp */, 26130 26130 5D925B660F64D4DD00B847F0 /* ScrollAlignment.h */, 26131 CDCFABBC18C0AF19006F8450 /* Selection SubtreeRoot.cpp */,26132 CDCFABBB18C0AE31006F8450 /* Selection SubtreeRoot.h */,26131 CDCFABBC18C0AF19006F8450 /* SelectionRangeData.cpp */, 26132 CDCFABBB18C0AE31006F8450 /* SelectionRangeData.h */, 26133 26133 E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */, 26134 26134 E48944A1180B57D800F165D8 /* SimpleLineLayout.h */, … … 30041 30041 2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */, 30042 30042 B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */, 30043 CDCFABBD18C0AF78006F8450 /* SelectionRangeData.h in Headers */, 30043 30044 BEA807C90F714A0300524199 /* SelectionRect.h in Headers */, 30044 30045 51405C89190B014400754F94 /* SelectionRectGatherer.h in Headers */, 30045 CDCFABBD18C0AF78006F8450 /* SelectionSubtreeRoot.h in Headers */,30046 30046 E44B4BB4141650D7002B1D8B /* SelectorChecker.h in Headers */, 30047 30047 432D3FE818A8658400D7DC03 /* SelectorCheckerTestFunctions.h in Headers */, … … 33966 33966 974D2DA4146A535D00D51F8B /* SecurityPolicy.cpp in Sources */, 33967 33967 B2C3DA2E0D006C1D00EF6F26 /* SegmentedString.cpp in Sources */, 33968 CDCFABBE18C0AF84006F8450 /* SelectionRangeData.cpp in Sources */, 33968 33969 BEA807C80F714A0300524199 /* SelectionRect.cpp in Sources */, 33969 33970 51405C88190B014400754F94 /* SelectionRectGatherer.cpp in Sources */, 33970 CDCFABBE18C0AF84006F8450 /* SelectionSubtreeRoot.cpp in Sources */,33971 33971 E44B4BB3141650D7002B1D8B /* SelectorChecker.cpp in Sources */, 33972 33972 26B999961804D54200D01121 /* SelectorCompiler.cpp in Sources */, -
trunk/Source/WebCore/editing/FrameSelection.cpp
r221064 r222697 388 388 m_pendingSelectionUpdate = true; 389 389 if (RenderView* view = m_frame->contentRenderer()) 390 view-> clearSelection();390 view->selection().clear(); 391 391 } 392 392 … … 444 444 445 445 if (RenderView* view = node.document().renderView()) 446 view-> clearSelection();446 view->selection().clear(); 447 447 448 448 clear(); … … 507 507 if (clearRenderTreeSelection) { 508 508 if (auto* renderView = node.document().renderView()) { 509 renderView-> clearSelection();509 renderView->selection().clear(); 510 510 511 511 // Trigger a selection update so the selection will be set again. … … 1518 1518 #endif 1519 1519 1520 RenderView* view = m_frame->contentRenderer(); 1521 if (view) 1522 view->clearSelection(); 1520 if (auto* view = m_frame->contentRenderer()) 1521 view->selection().clear(); 1523 1522 1524 1523 setSelectionWithoutUpdatingAppearance(VisibleSelection(), defaultSetSelectionOptions(), AlignCursorOnScrollIfNeeded, CharacterGranularity); … … 1996 1995 // we have to update places those colors were painted. 1997 1996 if (RenderView* view = document->renderView()) 1998 view-> repaintSelection();1997 view->selection().repaint(); 1999 1998 2000 1999 // Caret appears in the active frame. … … 2091 2090 2092 2091 if (!selection.isRange()) { 2093 view-> clearSelection();2092 view->selection().clear(); 2094 2093 return; 2095 2094 } … … 2116 2115 int endOffset = endPos.deprecatedEditingOffset(); 2117 2116 ASSERT(startOffset >= 0 && endOffset >= 0); 2118 view->se tSelection(startRenderer, startOffset, endRenderer, endOffset);2117 view->selection().set({ startRenderer, endRenderer, startOffset, endOffset }); 2119 2118 } 2120 2119 } … … 2233 2232 2234 2233 updateSelectionByUpdatingLayoutOrStyle(*m_frame); 2235 RenderView* root = m_frame->contentRenderer(); 2236 FrameView* view = m_frame->view(); 2237 if (!root || !view) 2234 auto* renderView = m_frame->contentRenderer(); 2235 if (!renderView) 2238 2236 return LayoutRect(); 2239 2237 2240 LayoutRect selectionRect = root->selectionBounds(clipToVisibleContent); 2241 return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect)) : selectionRect; 2238 auto& selection = renderView->selection(); 2239 auto selectionRect = clipToVisibleContent ? selection.boundsClippedToVisibleContent() : selection.bounds(); 2240 return clipToVisibleContent ? intersection(selectionRect, renderView->frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect)) : selectionRect; 2242 2241 } 2243 2242 -
trunk/Source/WebCore/page/FrameView.cpp
r222682 r222697 4523 4523 if (shouldPaintSelection == ExcludeSelection) { 4524 4524 for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) { 4525 if ( RenderView* root= frame->contentRenderer())4526 r oot->clearSelection();4525 if (auto* renderView = frame->contentRenderer()) 4526 renderView->selection().clear(); 4527 4527 } 4528 4528 } -
trunk/Source/WebCore/platform/DragImage.cpp
r219998 r222697 136 136 : frame(frame) 137 137 { 138 if ( RenderView* root= frame.contentRenderer())139 root->getSelection(startRenderer, startOffset, endRenderer, endOffset);138 if (auto* renderView = frame.contentRenderer()) 139 selection = renderView->selection().get(); 140 140 } 141 141 142 142 ~ScopedFrameSelectionState() 143 143 { 144 if (RenderView* root = frame.contentRenderer()) 145 root->setSelection(startRenderer, startOffset, endRenderer, endOffset, RenderView::RepaintNothing); 144 if (auto* renderView = frame.contentRenderer()) { 145 ASSERT(selection); 146 renderView->selection().set(selection.value(), SelectionRangeData::RepaintMode::Nothing); 147 } 146 148 } 147 149 148 150 const Frame& frame; 149 RenderObject* startRenderer; 150 RenderObject* endRenderer; 151 std::optional<unsigned> startOffset; 152 std::optional<unsigned> endOffset; 151 std::optional<SelectionRangeData::Context> selection; 153 152 }; 154 153 … … 187 186 int endOffset = end.deprecatedEditingOffset(); 188 187 ASSERT(startOffset >= 0 && endOffset >= 0); 189 view->se tSelection(startRenderer, startOffset, endRenderer, endOffset, RenderView::RepaintNothing);188 view->selection().set({ startRenderer, endRenderer, startOffset, endOffset }, SelectionRangeData::RepaintMode::Nothing); 190 189 // We capture using snapshotFrameRect() because we fake up the selection using 191 190 // FrameView but snapshotSelection() uses the selection from the Frame itself. 192 return createDragImageFromSnapshot(snapshotFrameRect(frame, view->selection Bounds(), options), nullptr);191 return createDragImageFromSnapshot(snapshotFrameRect(frame, view->selection().boundsClippedToVisibleContent(), options), nullptr); 193 192 } 194 193 -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r222677 r222697 145 145 RenderObject::SelectionState state = renderer().selectionState(); 146 146 if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) { 147 unsigned startPos, endPos; 148 renderer().view().getSelectionStartEnd(startPos, endPos); 147 auto& selection = renderer().view().selection(); 148 auto startPos = selection.startPosition(); 149 auto endPos = selection.endPosition(); 149 150 // The position after a hard line break is considered to be past its end. 150 151 ASSERT(start() + len() >= (isLineBreak() ? 1 : 0)); … … 640 641 return { 0, m_len }; 641 642 642 unsigned start; 643 unsigned end; 644 renderer().view().getSelectionStartEnd(start, end); 643 auto start = renderer().view().selection().startPosition(); 644 auto end = renderer().view().selection().endPosition(); 645 645 if (selectionState == RenderObject::SelectionStart) 646 646 end = renderer().textLength(); -
trunk/Source/WebCore/rendering/RenderBlock.cpp
r222679 r222697 1866 1866 return true; 1867 1867 1868 if (view().selection UnsplitStart()) {1869 Node* startElement = view().selection UnsplitStart()->node();1868 if (view().selection().start()) { 1869 Node* startElement = view().selection().start()->node(); 1870 1870 if (startElement && startElement->rootEditableElement() == element()) 1871 1871 return true; -
trunk/Source/WebCore/rendering/RenderObject.cpp
r222679 r222697 1418 1418 || st == SelectionEnd 1419 1419 || st == SelectionBoth 1420 || view().selection UnsplitStart() == this1421 || view().selection UnsplitEnd() == this;1420 || view().selection().start() == this 1421 || view().selection().end() == this; 1422 1422 } 1423 1423 -
trunk/Source/WebCore/rendering/RenderObject.h
r222682 r222697 63 63 class RenderFragmentContainer; 64 64 class RenderTheme; 65 class Selection SubtreeRoot;65 class SelectionRangeData; 66 66 class TransformState; 67 67 class VisiblePosition; -
trunk/Source/WebCore/rendering/RenderReplaced.cpp
r222677 r222697 645 645 bool RenderReplaced::isSelected() const 646 646 { 647 SelectionState s = selectionState();648 if (s == SelectionNone)649 return false; 650 if (s == SelectionInside)647 SelectionState state = selectionState(); 648 if (state == SelectionNone) 649 return false; 650 if (state == SelectionInside) 651 651 return true; 652 652 653 unsigned selectionStart, selectionEnd;654 view().getSelectionStartEnd(selectionStart, selectionEnd);655 if (s == SelectionStart)656 return selectionStart == 0;657 653 auto selectionStart = view().selection().startPosition(); 654 auto selectionEnd = view().selection().endPosition(); 655 if (state == SelectionStart) 656 return !selectionStart; 657 658 658 unsigned end = element()->hasChildNodes() ? element()->countChildNodes() : 1; 659 if (s == SelectionEnd)659 if (state == SelectionEnd) 660 660 return selectionEnd == end; 661 if (s == SelectionBoth) 662 return selectionStart == 0 && selectionEnd == end; 663 661 if (state == SelectionBoth) 662 return !selectionStart && selectionEnd == end; 664 663 ASSERT_NOT_REACHED(); 665 664 return false; -
trunk/Source/WebCore/rendering/RenderText.cpp
r222677 r222697 1442 1442 // Now calculate startPos and endPos for painting selection. 1443 1443 // We include a selection while endPos > 0 1444 unsigned startPos, endPos; 1444 unsigned startPos; 1445 unsigned endPos; 1445 1446 if (selectionState() == SelectionInside) { 1446 1447 // We are fully selected. … … 1448 1449 endPos = textLength(); 1449 1450 } else { 1450 view().getSelectionStartEnd(startPos, endPos); 1451 startPos = view().selection().startPosition(); 1452 endPos = view().selection().endPosition(); 1451 1453 if (selectionState() == SelectionStart) 1452 1454 endPos = textLength(); -
trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp
r222677 r222697 447 447 } 448 448 449 unsigned start, end;450 renderer.view().getSelectionStartEnd(start, end);449 auto start = renderer.view().selection().startPosition(); 450 auto end = renderer.view().selection().endPosition(); 451 451 if (state == RenderObject::SelectionStart) { 452 452 end = renderer.textLength(); 453 454 453 // to handle selection from end of text to end of line 455 454 if (start && start == end) -
trunk/Source/WebCore/rendering/RenderView.cpp
r222682 r222697 27 27 #include "FloatingObjects.h" 28 28 #include "Frame.h" 29 #include "FrameSelection.h"30 29 #include "FrameView.h" 31 30 #include "GraphicsContext.h" … … 48 47 #include "RenderMultiColumnSpannerPlaceholder.h" 49 48 #include "RenderQuote.h" 50 #include "RenderSelectionInfo.h"51 49 #include "RenderWidget.h" 52 50 #include "ScrollbarTheme.h" … … 79 77 }; 80 78 81 struct SelectionIterator {82 SelectionIterator(RenderObject* start)83 : m_current(start)84 {85 checkForSpanner();86 }87 88 RenderObject* current() const89 {90 return m_current;91 }92 93 RenderObject* next()94 {95 RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();96 m_current = m_current->nextInPreOrder(currentSpan);97 checkForSpanner();98 if (!m_current && currentSpan) {99 RenderObject* placeholder = m_spannerStack.last();100 m_spannerStack.removeLast();101 m_current = placeholder->nextInPreOrder();102 checkForSpanner();103 }104 return m_current;105 }106 107 private:108 void checkForSpanner()109 {110 if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))111 return;112 auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);113 m_spannerStack.append(&placeholder);114 m_current = placeholder.spanner();115 }116 117 RenderObject* m_current { nullptr };118 Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;119 };120 121 79 RenderView::RenderView(Document& document, RenderStyle&& style) 122 80 : RenderBlockFlow(document, WTFMove(style)) 123 81 , m_frameView(*document.view()) 82 , m_selection(*this) 124 83 , m_lazyRepaintTimer(*this, &RenderView::lazyRepaintTimerFired) 125 #if ENABLE(SERVICE_CONTROLS)126 , m_selectionRectGatherer(*this)127 #endif128 84 { 129 85 setIsRenderView(); … … 698 654 } 699 655 700 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)701 {702 if (!object)703 return nullptr;704 705 RenderObject* child = object->childAt(offset);706 return child ? child : object->nextInPreOrderAfterChildren();707 }708 709 IntRect RenderView::selectionBounds(bool clipToVisibleContent) const710 {711 LayoutRect selRect = subtreeSelectionBounds(clipToVisibleContent);712 return snappedIntRect(selRect);713 }714 715 LayoutRect RenderView::subtreeSelectionBounds(bool clipToVisibleContent) const716 {717 typedef HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>> SelectionMap;718 SelectionMap selectedObjects;719 720 RenderObject* os = selectionData().selectionStart();721 auto* selectionEnd = selectionData().selectionEnd();722 RenderObject* stop = nullptr;723 if (selectionEnd)724 stop = rendererAfterPosition(selectionEnd, selectionData().selectionEndPos().value());725 SelectionIterator selectionIterator(os);726 while (os && os != stop) {727 if ((os->canBeSelectionLeaf() || os == selectionData().selectionStart() || os == selectionData().selectionEnd()) && os->selectionState() != SelectionNone) {728 // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.729 selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(*os, clipToVisibleContent));730 RenderBlock* cb = os->containingBlock();731 while (cb && !is<RenderView>(*cb)) {732 std::unique_ptr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value;733 if (blockInfo)734 break;735 blockInfo = std::make_unique<RenderSelectionInfo>(*cb, clipToVisibleContent);736 cb = cb->containingBlock();737 }738 }739 740 os = selectionIterator.next();741 }742 743 // Now create a single bounding box rect that encloses the whole selection.744 LayoutRect selRect;745 SelectionMap::iterator end = selectedObjects.end();746 for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {747 RenderSelectionInfo* info = i->value.get();748 // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.749 LayoutRect currRect = info->rect();750 if (RenderLayerModelObject* repaintContainer = info->repaintContainer()) {751 FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));752 currRect = absQuad.enclosingBoundingBox();753 }754 selRect.unite(currRect);755 }756 return selRect;757 }758 759 void RenderView::repaintSelection() const760 {761 repaintSubtreeSelection();762 }763 764 void RenderView::repaintSubtreeSelection() const765 {766 HashSet<RenderBlock*> processedBlocks;767 768 auto* selectionEnd = selectionData().selectionEnd();769 RenderObject* end = nullptr;770 if (selectionEnd)771 end = rendererAfterPosition(selectionEnd, selectionData().selectionEndPos().value());772 SelectionIterator selectionIterator(selectionData().selectionStart());773 for (RenderObject* o = selectionIterator.current(); o && o != end; o = selectionIterator.next()) {774 if (!o->canBeSelectionLeaf() && o != selectionData().selectionStart() && o != selectionData().selectionEnd())775 continue;776 if (o->selectionState() == SelectionNone)777 continue;778 779 RenderSelectionInfo(*o, true).repaint();780 781 // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.782 for (RenderBlock* block = o->containingBlock(); block && !is<RenderView>(*block); block = block->containingBlock()) {783 if (!processedBlocks.add(block).isNewEntry)784 break;785 RenderSelectionInfo(*block, true).repaint();786 }787 }788 }789 790 void RenderView::setSelection(RenderObject* start, std::optional<unsigned> startPos, RenderObject* end, std::optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode)791 {792 // Make sure both our start and end objects are defined.793 // Check www.msnbc.com and try clicking around to find the case where this happened.794 if ((start && !end) || (end && !start))795 return;796 797 bool caretChanged = m_selectionWasCaret != frame().selection().isCaret();798 m_selectionWasCaret = frame().selection().isCaret();799 // Just return if the selection hasn't changed.800 if (m_selectionUnsplitStart == start && m_selectionUnsplitStartPos == startPos801 && m_selectionUnsplitEnd == end && m_selectionUnsplitEndPos == endPos && !caretChanged) {802 return;803 }804 805 #if ENABLE(SERVICE_CONTROLS)806 // Clear the current rects and create a notifier for the new rects we are about to gather.807 // The Notifier updates the Editor when it goes out of scope and is destroyed.808 std::unique_ptr<SelectionRectGatherer::Notifier> rectNotifier = m_selectionRectGatherer.clearAndCreateNotifier();809 #endif // ENABLE(SERVICE_CONTROLS)810 // Set global positions for new selection.811 m_selectionUnsplitStart = start;812 m_selectionUnsplitStartPos = startPos;813 m_selectionUnsplitEnd = end;814 m_selectionUnsplitEndPos = endPos;815 auto oldSelectionData = std::make_unique<OldSelectionData>();816 clearSubtreeSelection(blockRepaintMode, *oldSelectionData);817 setSelectionData(SelectionSubtreeData(start, startPos, end, endPos));818 applySubtreeSelection(blockRepaintMode, *oldSelectionData);819 }820 821 static inline bool isValidObjectForNewSelection(const RenderView& view, const RenderObject& object)822 {823 return (object.canBeSelectionLeaf() || &object == view.selectionData().selectionStart() || &object == view.selectionData().selectionEnd()) && object.selectionState() != RenderObject::SelectionNone && object.containingBlock();824 }825 826 void RenderView::clearSubtreeSelection(SelectionRepaintMode blockRepaintMode, OldSelectionData& oldSelectionData) const827 {828 // Record the old selected objects. These will be used later829 // when we compare against the new selected objects.830 oldSelectionData.selectionStartPos = selectionData().selectionStartPos();831 oldSelectionData.selectionEndPos = selectionData().selectionEndPos();832 833 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.834 // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise835 // the union of those rects might remain the same even when changes have occurred.836 837 RenderObject* os = selectionData().selectionStart();838 auto* selectionEnd = selectionData().selectionEnd();839 RenderObject* stop = nullptr;840 if (selectionEnd)841 stop = rendererAfterPosition(selectionEnd, selectionData().selectionEndPos().value());842 SelectionIterator selectionIterator(os);843 while (os && os != stop) {844 if (isValidObjectForNewSelection(*this, *os)) {845 // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.846 oldSelectionData.selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(*os, true));847 if (blockRepaintMode == RepaintNewXOROld) {848 RenderBlock* cb = os->containingBlock();849 while (cb && !is<RenderView>(*cb)) {850 std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = oldSelectionData.selectedBlocks.add(cb, nullptr).iterator->value;851 if (blockInfo)852 break;853 blockInfo = std::make_unique<RenderBlockSelectionInfo>(*cb);854 cb = cb->containingBlock();855 }856 }857 }858 859 os = selectionIterator.next();860 }861 862 for (auto* selectedObject : oldSelectionData.selectedObjects.keys())863 selectedObject->setSelectionStateIfNeeded(SelectionNone);864 }865 866 void RenderView::applySubtreeSelection(SelectionRepaintMode blockRepaintMode, const OldSelectionData& oldSelectionData)867 {868 // Update the selection status of all objects between selectionStart and selectionEnd869 if (selectionData().selectionStart() && selectionData().selectionStart() == selectionData().selectionEnd())870 selectionData().selectionStart()->setSelectionStateIfNeeded(SelectionBoth);871 else {872 if (selectionData().selectionStart())873 selectionData().selectionStart()->setSelectionStateIfNeeded(SelectionStart);874 if (selectionData().selectionEnd())875 selectionData().selectionEnd()->setSelectionStateIfNeeded(SelectionEnd);876 }877 878 RenderObject* selectionStart = selectionData().selectionStart();879 auto* selectionDataEnd = selectionData().selectionEnd();880 RenderObject* selectionEnd = nullptr;881 if (selectionDataEnd)882 selectionEnd = rendererAfterPosition(selectionDataEnd, selectionData().selectionEndPos().value());883 SelectionIterator selectionIterator(selectionStart);884 for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {885 if (currentRenderer == selectionData().selectionStart() || currentRenderer == selectionData().selectionEnd())886 continue;887 if (!currentRenderer->canBeSelectionLeaf())888 continue;889 currentRenderer->setSelectionStateIfNeeded(SelectionInside);890 }891 892 if (blockRepaintMode != RepaintNothing)893 layer()->clearBlockSelectionGapsBounds();894 895 // Now that the selection state has been updated for the new objects, walk them again and896 // put them in the new objects list.897 SelectedObjectMap newSelectedObjects;898 SelectedBlockMap newSelectedBlocks;899 selectionIterator = SelectionIterator(selectionStart);900 for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {901 if (isValidObjectForNewSelection(*this, *currentRenderer)) {902 std::unique_ptr<RenderSelectionInfo> selectionInfo = std::make_unique<RenderSelectionInfo>(*currentRenderer, true);903 904 #if ENABLE(SERVICE_CONTROLS)905 for (auto& rect : selectionInfo->collectedSelectionRects())906 m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);907 if (!currentRenderer->isTextOrLineBreak())908 m_selectionRectGatherer.setTextOnly(false);909 #endif910 911 newSelectedObjects.set(currentRenderer, WTFMove(selectionInfo));912 913 RenderBlock* containingBlock = currentRenderer->containingBlock();914 while (containingBlock && !is<RenderView>(*containingBlock)) {915 std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;916 if (blockInfo)917 break;918 blockInfo = std::make_unique<RenderBlockSelectionInfo>(*containingBlock);919 containingBlock = containingBlock->containingBlock();920 921 #if ENABLE(SERVICE_CONTROLS)922 m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());923 #endif924 }925 }926 }927 928 if (blockRepaintMode == RepaintNothing)929 return;930 931 // Have any of the old selected objects changed compared to the new selection?932 for (const auto& selectedObjectInfo : oldSelectionData.selectedObjects) {933 RenderObject* obj = selectedObjectInfo.key;934 RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);935 RenderSelectionInfo* oldInfo = selectedObjectInfo.value.get();936 if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()937 || (selectionData().selectionStart() == obj && oldSelectionData.selectionStartPos != selectionData().selectionStartPos())938 || (selectionData().selectionEnd() == obj && oldSelectionData.selectionEndPos != selectionData().selectionEndPos())) {939 oldInfo->repaint();940 if (newInfo) {941 newInfo->repaint();942 newSelectedObjects.remove(obj);943 }944 }945 }946 947 // Any new objects that remain were not found in the old objects dict, and so they need to be updated.948 for (const auto& selectedObjectInfo : newSelectedObjects)949 selectedObjectInfo.value->repaint();950 951 // Have any of the old blocks changed?952 for (const auto& selectedBlockInfo : oldSelectionData.selectedBlocks) {953 const RenderBlock* block = selectedBlockInfo.key;954 RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);955 RenderBlockSelectionInfo* oldInfo = selectedBlockInfo.value.get();956 if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {957 oldInfo->repaint();958 if (newInfo) {959 newInfo->repaint();960 newSelectedBlocks.remove(block);961 }962 }963 }964 965 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.966 for (const auto& selectedBlockInfo : newSelectedBlocks)967 selectedBlockInfo.value->repaint();968 }969 970 void RenderView::getSelection(RenderObject*& startRenderer, std::optional<unsigned>& startOffset, RenderObject*& endRenderer, std::optional<unsigned>& endOffset) const971 {972 startRenderer = m_selectionUnsplitStart;973 startOffset = m_selectionUnsplitStartPos;974 endRenderer = m_selectionUnsplitEnd;975 endOffset = m_selectionUnsplitEndPos;976 }977 978 void RenderView::clearSelection()979 {980 layer()->repaintBlockSelectionGaps();981 setSelection(nullptr, std::nullopt, nullptr, std::nullopt, RepaintNewMinusOld);982 }983 984 656 bool RenderView::printing() const 985 657 { -
trunk/Source/WebCore/rendering/RenderView.h
r222677 r222697 27 27 #include "RenderBlockFlow.h" 28 28 #include "RenderWidget.h" 29 #include "Selection SubtreeRoot.h"29 #include "SelectionRangeData.h" 30 30 #include <memory> 31 31 #include <wtf/HashSet.h> 32 32 #include <wtf/ListHashSet.h> 33 33 34 #if ENABLE(SERVICE_CONTROLS)35 #include "SelectionRectGatherer.h"36 #endif37 38 34 namespace WebCore { 39 35 … … 42 38 class RenderQuote; 43 39 44 class RenderView final : public RenderBlockFlow , public SelectionSubtreeRoot{40 class RenderView final : public RenderBlockFlow { 45 41 public: 46 42 RenderView(Document&, RenderStyle&&); … … 86 82 RenderElement* rendererForRootBackground() const; 87 83 88 enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing }; 89 void setSelection(RenderObject* start, std::optional<unsigned> startPos, RenderObject* endObject, std::optional<unsigned> endPos, SelectionRepaintMode = RepaintNewXOROld); 90 void getSelection(RenderObject*& startRenderer, std::optional<unsigned>& startOffset, RenderObject*& endRenderer, std::optional<unsigned>& endOffset) const; 91 void clearSelection(); 92 RenderObject* selectionUnsplitStart() const { return m_selectionUnsplitStart; } 93 RenderObject* selectionUnsplitEnd() const { return m_selectionUnsplitEnd; } 94 IntRect selectionBounds(bool clipToVisibleContent = true) const; 95 void repaintSelection() const; 96 void getSelectionStartEnd(unsigned& start, unsigned& end) const { selectionData().selectionStartEndPositions(start, end); } 84 SelectionRangeData& selection() { return m_selection; } 97 85 98 86 bool printing() const; … … 313 301 bool isScrollableOrRubberbandableBox() const override; 314 302 315 void clearSubtreeSelection(SelectionRepaintMode blockRepaintMode, OldSelectionData&) const;316 void applySubtreeSelection(SelectionRepaintMode, const OldSelectionData&);317 LayoutRect subtreeSelectionBounds(bool clipToVisibleContent = true) const;318 void repaintSubtreeSelection() const;319 320 303 private: 321 304 FrameView& m_frameView; 322 305 323 RenderObject* m_selectionUnsplitStart { nullptr };324 RenderObject* m_selectionUnsplitEnd { nullptr };325 std::optional<unsigned> m_selectionUnsplitStartPos;326 std::optional<unsigned> m_selectionUnsplitEndPos;327 328 306 // Include this RenderView. 329 307 uint64_t m_rendererCount { 1 }; 330 308 331 309 mutable std::unique_ptr<Region> m_accumulatedRepaintRegion; 310 SelectionRangeData m_selection; 332 311 333 312 // FIXME: Only used by embedded WebViews inside AppKit NSViews. Find a way to remove. … … 361 340 unsigned m_renderTreeInternalMutationCounter { 0 }; 362 341 363 bool m_selectionWasCaret { false };364 342 bool m_hasSoftwareFilters { false }; 365 343 bool m_usesFirstLineRules { false }; … … 373 351 Vector<RefPtr<RenderWidget>> m_protectedRenderWidgets; 374 352 375 #if ENABLE(SERVICE_CONTROLS)376 SelectionRectGatherer m_selectionRectGatherer;377 #endif378 353 #if ENABLE(CSS_SCROLL_SNAP) 379 354 HashSet<const RenderBox*> m_boxesWithScrollSnapPositions; -
trunk/Source/WebCore/rendering/RenderingAllInOne.cpp
r222575 r222697 134 134 #include "RootInlineBox.cpp" 135 135 #include "ScrollAlignment.cpp" 136 #include "Selection SubtreeRoot.cpp"136 #include "SelectionRangeData.cpp" 137 137 #include "SimpleLineLayout.cpp" 138 138 #include "SimpleLineLayoutCoverage.cpp"
Note: See TracChangeset
for help on using the changeset viewer.