RenderView does not need to be a SelectionSubtreeRoot
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Oct 2017 04:46:32 +0000 (04:46 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 2 Oct 2017 04:46:32 +0000 (04:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177713

Reviewed by Darin Adler and Antti Koivisto.

1. SelectionSubtreeRoot -> SelectionRangeData
2. Move all selection logic from RenderView to SelectionRangeData
3. class RenderView : public SelectionSubtreeRoot -> SelectionRangeData m_selection;
4. Remove redundant code
5. General modernization

No change in functionality.

* editing/FrameSelection.cpp:
(WebCore::FrameSelection::setNeedsSelectionUpdate):
(WebCore::DragCaretController::nodeWillBeRemoved):
(WebCore::FrameSelection::respondToNodeModification):
(WebCore::FrameSelection::prepareForDestruction):
(WebCore::FrameSelection::focusedOrActiveStateChanged):
(WebCore::FrameSelection::updateAppearance):
(WebCore::FrameSelection::selectionBounds const):
* page/FrameView.cpp:
(WebCore::FrameView::paintContentsForSnapshot):
* platform/DragImage.cpp:
(WebCore::ScopedFrameSelectionState::ScopedFrameSelectionState):
(WebCore::ScopedFrameSelectionState::~ScopedFrameSelectionState):
(WebCore::createDragImageForRange):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::selectionState):
(WebCore::InlineTextBox::selectionStartEnd const):
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::isSelectionRoot const):
* rendering/RenderObject.cpp:
(WebCore::RenderObject::isSelectionBorder const):
* rendering/RenderObject.h:
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::isSelected const):
* rendering/RenderText.cpp:
(WebCore::RenderText::collectSelectionRectsForLineBoxes):
* rendering/RenderTextLineBoxes.cpp:
(WebCore::RenderTextLineBoxes::setSelectionState):
* rendering/RenderView.cpp:
(WebCore::RenderView::RenderView):
(WebCore::SelectionIterator::SelectionIterator): Deleted.
(WebCore::SelectionIterator::current const): Deleted.
(WebCore::SelectionIterator::next): Deleted.
(WebCore::SelectionIterator::checkForSpanner): Deleted.
(WebCore::rendererAfterPosition): Deleted.
(WebCore::RenderView::selectionBounds const): Deleted.
(WebCore::RenderView::subtreeSelectionBounds const): Deleted.
(WebCore::RenderView::repaintSelection const): Deleted.
(WebCore::RenderView::repaintSubtreeSelection const): Deleted.
(WebCore::RenderView::setSelection): Deleted.
(WebCore::isValidObjectForNewSelection): Deleted.
(WebCore::RenderView::clearSubtreeSelection const): Deleted.
(WebCore::RenderView::applySubtreeSelection): Deleted.
(WebCore::RenderView::getSelection const): Deleted.
(WebCore::RenderView::clearSelection): Deleted.
* rendering/RenderView.h:
* rendering/SelectionSubtreeRoot.cpp:
(WebCore::rendererAfterPosition):
(WebCore::SelectionIterator::SelectionIterator):
(WebCore::SelectionIterator::current const):
(WebCore::SelectionIterator::next):
(WebCore::SelectionIterator::checkForSpanner):
(WebCore::SelectionRangeData::SelectionRangeData):
(WebCore::SelectionRangeData::set):
(WebCore::SelectionRangeData::clear):
(WebCore::SelectionRangeData::repaint const):
(WebCore::SelectionRangeData::bounds const):
(WebCore::SelectionRangeData::collectAndClear const):
(WebCore::SelectionRangeData::apply):
(WebCore::SelectionRangeData::isValidRendererForNewSelection const):
(WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot): Deleted.
* rendering/SelectionSubtreeRoot.h:
(WebCore::SelectionRangeData::Context::operator== const):
(WebCore::SelectionRangeData::get const):
(WebCore::SelectionRangeData::start const):
(WebCore::SelectionRangeData::end const):
(WebCore::SelectionRangeData::startPosition const):
(WebCore::SelectionRangeData::endPosition const):
(WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::SelectionSubtreeData): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStart const): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartPos const): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEnd const): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEndPos const): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartEndPositions const): Deleted.
(WebCore::SelectionSubtreeRoot::SelectionSubtreeData::clearSelection): Deleted.
(WebCore::SelectionSubtreeRoot::selectionData): Deleted.
(WebCore::SelectionSubtreeRoot::selectionData const): Deleted.
(WebCore::SelectionSubtreeRoot::setSelectionData): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222697 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/editing/FrameSelection.cpp
Source/WebCore/page/FrameView.cpp
Source/WebCore/platform/DragImage.cpp
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderObject.cpp
Source/WebCore/rendering/RenderObject.h
Source/WebCore/rendering/RenderReplaced.cpp
Source/WebCore/rendering/RenderText.cpp
Source/WebCore/rendering/RenderTextLineBoxes.cpp
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/RenderView.h
Source/WebCore/rendering/RenderingAllInOne.cpp
Source/WebCore/rendering/SelectionRangeData.cpp [new file with mode: 0644]
Source/WebCore/rendering/SelectionRangeData.h [new file with mode: 0644]
Source/WebCore/rendering/SelectionSubtreeRoot.cpp [deleted file]
Source/WebCore/rendering/SelectionSubtreeRoot.h [deleted file]

index 5738f7b..0053aef 100644 (file)
@@ -2749,7 +2749,7 @@ set(WebCore_SOURCES
     rendering/RenderWidget.cpp
     rendering/RootInlineBox.cpp
     rendering/ScrollAlignment.cpp
-    rendering/SelectionSubtreeRoot.cpp
+    rendering/SelectionRangeData.cpp
     rendering/SimpleLineLayout.cpp
     rendering/SimpleLineLayoutCoverage.cpp
     rendering/SimpleLineLayoutFlowContents.cpp
index 942efce..e6b142e 100644 (file)
@@ -1,3 +1,98 @@
+2017-10-01  Zalan Bujtas  <zalan@apple.com>
+
+        RenderView does not need to be a SelectionSubtreeRoot
+        https://bugs.webkit.org/show_bug.cgi?id=177713
+
+        Reviewed by Darin Adler and Antti Koivisto.
+
+        1. SelectionSubtreeRoot -> SelectionRangeData 
+        2. Move all selection logic from RenderView to SelectionRangeData
+        3. class RenderView : public SelectionSubtreeRoot -> SelectionRangeData m_selection;
+        4. Remove redundant code
+        5. General modernization
+        No change in functionality.
+
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::setNeedsSelectionUpdate):
+        (WebCore::DragCaretController::nodeWillBeRemoved):
+        (WebCore::FrameSelection::respondToNodeModification):
+        (WebCore::FrameSelection::prepareForDestruction):
+        (WebCore::FrameSelection::focusedOrActiveStateChanged):
+        (WebCore::FrameSelection::updateAppearance):
+        (WebCore::FrameSelection::selectionBounds const):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::paintContentsForSnapshot):
+        * platform/DragImage.cpp:
+        (WebCore::ScopedFrameSelectionState::ScopedFrameSelectionState):
+        (WebCore::ScopedFrameSelectionState::~ScopedFrameSelectionState):
+        (WebCore::createDragImageForRange):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::selectionState):
+        (WebCore::InlineTextBox::selectionStartEnd const):
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::isSelectionRoot const):
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::isSelectionBorder const):
+        * rendering/RenderObject.h:
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::isSelected const):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::collectSelectionRectsForLineBoxes):
+        * rendering/RenderTextLineBoxes.cpp:
+        (WebCore::RenderTextLineBoxes::setSelectionState):
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::RenderView):
+        (WebCore::SelectionIterator::SelectionIterator): Deleted.
+        (WebCore::SelectionIterator::current const): Deleted.
+        (WebCore::SelectionIterator::next): Deleted.
+        (WebCore::SelectionIterator::checkForSpanner): Deleted.
+        (WebCore::rendererAfterPosition): Deleted.
+        (WebCore::RenderView::selectionBounds const): Deleted.
+        (WebCore::RenderView::subtreeSelectionBounds const): Deleted.
+        (WebCore::RenderView::repaintSelection const): Deleted.
+        (WebCore::RenderView::repaintSubtreeSelection const): Deleted.
+        (WebCore::RenderView::setSelection): Deleted.
+        (WebCore::isValidObjectForNewSelection): Deleted.
+        (WebCore::RenderView::clearSubtreeSelection const): Deleted.
+        (WebCore::RenderView::applySubtreeSelection): Deleted.
+        (WebCore::RenderView::getSelection const): Deleted.
+        (WebCore::RenderView::clearSelection): Deleted.
+        * rendering/RenderView.h:
+        * rendering/SelectionSubtreeRoot.cpp:
+        (WebCore::rendererAfterPosition):
+        (WebCore::SelectionIterator::SelectionIterator):
+        (WebCore::SelectionIterator::current const):
+        (WebCore::SelectionIterator::next):
+        (WebCore::SelectionIterator::checkForSpanner):
+        (WebCore::SelectionRangeData::SelectionRangeData):
+        (WebCore::SelectionRangeData::set):
+        (WebCore::SelectionRangeData::clear):
+        (WebCore::SelectionRangeData::repaint const):
+        (WebCore::SelectionRangeData::bounds const):
+        (WebCore::SelectionRangeData::collectAndClear const):
+        (WebCore::SelectionRangeData::apply):
+        (WebCore::SelectionRangeData::isValidRendererForNewSelection const):
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot): Deleted.
+        * rendering/SelectionSubtreeRoot.h:
+        (WebCore::SelectionRangeData::Context::operator== const):
+        (WebCore::SelectionRangeData::get const):
+        (WebCore::SelectionRangeData::start const):
+        (WebCore::SelectionRangeData::end const):
+        (WebCore::SelectionRangeData::startPosition const):
+        (WebCore::SelectionRangeData::endPosition const):
+        (WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::SelectionSubtreeData): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStart const): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartPos const): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEnd const): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionEndPos const): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::selectionStartEndPositions const): Deleted.
+        (WebCore::SelectionSubtreeRoot::SelectionSubtreeData::clearSelection): Deleted.
+        (WebCore::SelectionSubtreeRoot::selectionData): Deleted.
+        (WebCore::SelectionSubtreeRoot::selectionData const): Deleted.
+        (WebCore::SelectionSubtreeRoot::setSelectionData): Deleted.
+
 2017-10-01  Sam Weinig  <sam@webkit.org>
 
         [Settings] Enums should not be passed by const reference
index 7e42d31..a60c780 100644 (file)
                CDCA98EB18B2C8EB00C12FF9 /* LegacyCDMPrivateMediaPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCA98EA18B2C8EB00C12FF9 /* LegacyCDMPrivateMediaPlayer.cpp */; };
                CDCD41E71C3DDB0900965D99 /* ParsedContentRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */; };
                CDCD41E81C3DDB0A00965D99 /* ParsedContentRange.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               CDCFABBD18C0AF78006F8450 /* SelectionSubtreeRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               CDCFABBE18C0AF84006F8450 /* SelectionSubtreeRoot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */; };
+               CDCFABBD18C0AF78006F8450 /* SelectionRangeData.h in Headers */ = {isa = PBXBuildFile; fileRef = CDCFABBB18C0AE31006F8450 /* SelectionRangeData.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               CDCFABBE18C0AF84006F8450 /* SelectionRangeData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDCFABBC18C0AF19006F8450 /* SelectionRangeData.cpp */; };
                CDD7089618359F6F002B3DC6 /* SampleMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CDD7089418359F6E002B3DC6 /* SampleMap.cpp */; };
                CDD7089718359F6F002B3DC6 /* SampleMap.h in Headers */ = {isa = PBXBuildFile; fileRef = CDD7089518359F6F002B3DC6 /* SampleMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
                CDDC1E7A18A952F30027A9D4 /* MediaSourcePrivateClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDC1E7918A952F30027A9D4 /* MediaSourcePrivateClient.h */; };
                CDCD41E51C3DDB0900965D99 /* ParsedContentRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParsedContentRange.cpp; sourceTree = "<group>"; };
                CDCD41E61C3DDB0900965D99 /* ParsedContentRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParsedContentRange.h; sourceTree = "<group>"; };
                CDCE5CD014633BC900D47CCA /* EventTargetFactory.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EventTargetFactory.in; sourceTree = "<group>"; };
-               CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionSubtreeRoot.h; sourceTree = "<group>"; };
-               CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionSubtreeRoot.cpp; sourceTree = "<group>"; };
+               CDCFABBB18C0AE31006F8450 /* SelectionRangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionRangeData.h; sourceTree = "<group>"; };
+               CDCFABBC18C0AF19006F8450 /* SelectionRangeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionRangeData.cpp; sourceTree = "<group>"; };
                CDD1E525167BA56400CE820B /* TextTrackRepresentation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextTrackRepresentation.h; sourceTree = "<group>"; };
                CDD7089418359F6E002B3DC6 /* SampleMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SampleMap.cpp; sourceTree = "<group>"; };
                CDD7089518359F6F002B3DC6 /* SampleMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SampleMap.h; sourceTree = "<group>"; };
                                A8CFF5DA0A155A05000A4234 /* RootInlineBox.h */,
                                5D925B650F64D4DD00B847F0 /* ScrollAlignment.cpp */,
                                5D925B660F64D4DD00B847F0 /* ScrollAlignment.h */,
-                               CDCFABBC18C0AF19006F8450 /* SelectionSubtreeRoot.cpp */,
-                               CDCFABBB18C0AE31006F8450 /* SelectionSubtreeRoot.h */,
+                               CDCFABBC18C0AF19006F8450 /* SelectionRangeData.cpp */,
+                               CDCFABBB18C0AE31006F8450 /* SelectionRangeData.h */,
                                E48944A0180B57D800F165D8 /* SimpleLineLayout.cpp */,
                                E48944A1180B57D800F165D8 /* SimpleLineLayout.h */,
                                11E067EB1E62461300162D16 /* SimpleLineLayoutCoverage.cpp */,
                                974D2DA5146A535D00D51F8B /* SecurityPolicy.h in Headers */,
                                2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */,
                                B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */,
+                               CDCFABBD18C0AF78006F8450 /* SelectionRangeData.h in Headers */,
                                BEA807C90F714A0300524199 /* SelectionRect.h in Headers */,
                                51405C89190B014400754F94 /* SelectionRectGatherer.h in Headers */,
-                               CDCFABBD18C0AF78006F8450 /* SelectionSubtreeRoot.h in Headers */,
                                E44B4BB4141650D7002B1D8B /* SelectorChecker.h in Headers */,
                                432D3FE818A8658400D7DC03 /* SelectorCheckerTestFunctions.h in Headers */,
                                26B999971804D54200D01121 /* SelectorCompiler.h in Headers */,
                                1AF7AFC71A48A8BC00C8E4E7 /* SecurityOriginPolicy.cpp in Sources */,
                                974D2DA4146A535D00D51F8B /* SecurityPolicy.cpp in Sources */,
                                B2C3DA2E0D006C1D00EF6F26 /* SegmentedString.cpp in Sources */,
+                               CDCFABBE18C0AF84006F8450 /* SelectionRangeData.cpp in Sources */,
                                BEA807C80F714A0300524199 /* SelectionRect.cpp in Sources */,
                                51405C88190B014400754F94 /* SelectionRectGatherer.cpp in Sources */,
-                               CDCFABBE18C0AF84006F8450 /* SelectionSubtreeRoot.cpp in Sources */,
                                E44B4BB3141650D7002B1D8B /* SelectorChecker.cpp in Sources */,
                                26B999961804D54200D01121 /* SelectorCompiler.cpp in Sources */,
                                415071571685067300C3C7B3 /* SelectorFilter.cpp in Sources */,
index a857ede..4adc0a8 100644 (file)
@@ -387,7 +387,7 @@ void FrameSelection::setNeedsSelectionUpdate()
 {
     m_pendingSelectionUpdate = true;
     if (RenderView* view = m_frame->contentRenderer())
-        view->clearSelection();
+        view->selection().clear();
 }
 
 void FrameSelection::updateAndRevealSelection(const AXTextStateChangeIntent& intent)
@@ -443,7 +443,7 @@ void DragCaretController::nodeWillBeRemoved(Node& node)
         return;
 
     if (RenderView* view = node.document().renderView())
-        view->clearSelection();
+        view->selection().clear();
 
     clear();
 }
@@ -506,7 +506,7 @@ void FrameSelection::respondToNodeModification(Node& node, bool baseRemoved, boo
 
     if (clearRenderTreeSelection) {
         if (auto* renderView = node.document().renderView()) {
-            renderView->clearSelection();
+            renderView->selection().clear();
 
             // Trigger a selection update so the selection will be set again.
             m_pendingSelectionUpdate = true;
@@ -1517,9 +1517,8 @@ void FrameSelection::prepareForDestruction()
     m_caretBlinkTimer.stop();
 #endif
 
-    RenderView* view = m_frame->contentRenderer();
-    if (view)
-        view->clearSelection();
+    if (auto* view = m_frame->contentRenderer())
+        view->selection().clear();
 
     setSelectionWithoutUpdatingAppearance(VisibleSelection(), defaultSetSelectionOptions(), AlignCursorOnScrollIfNeeded, CharacterGranularity);
     m_previousCaretNode = nullptr;
@@ -1995,7 +1994,7 @@ void FrameSelection::focusedOrActiveStateChanged()
     // RenderObject::selectionForegroundColor() check if the frame is active,
     // we have to update places those colors were painted.
     if (RenderView* view = document->renderView())
-        view->repaintSelection();
+        view->selection().repaint();
 
     // Caret appears in the active frame.
     if (activeAndFocused)
@@ -2090,7 +2089,7 @@ void FrameSelection::updateAppearance()
 #endif
 
     if (!selection.isRange()) {
-        view->clearSelection();
+        view->selection().clear();
         return;
     }
 
@@ -2115,7 +2114,7 @@ void FrameSelection::updateAppearance()
         RenderObject* endRenderer = endPos.deprecatedNode()->renderer();
         int endOffset = endPos.deprecatedEditingOffset();
         ASSERT(startOffset >= 0 && endOffset >= 0);
-        view->setSelection(startRenderer, startOffset, endRenderer, endOffset);
+        view->selection().set({ startRenderer, endRenderer, startOffset, endOffset });
     }
 }
 
@@ -2232,13 +2231,13 @@ FloatRect FrameSelection::selectionBounds(bool clipToVisibleContent) const
         return LayoutRect();
 
     updateSelectionByUpdatingLayoutOrStyle(*m_frame);
-    RenderView* root = m_frame->contentRenderer();
-    FrameView* view = m_frame->view();
-    if (!root || !view)
+    auto* renderView = m_frame->contentRenderer();
+    if (!renderView)
         return LayoutRect();
 
-    LayoutRect selectionRect = root->selectionBounds(clipToVisibleContent);
-    return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect)) : selectionRect;
+    auto& selection = renderView->selection();
+    auto selectionRect = clipToVisibleContent ? selection.boundsClippedToVisibleContent() : selection.bounds();
+    return clipToVisibleContent ? intersection(selectionRect, renderView->frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect)) : selectionRect;
 }
 
 void FrameSelection::getClippedVisibleTextRectangles(Vector<FloatRect>& rectangles, TextRectangleHeight textRectHeight) const
index ccef4b2..279d2ee 100644 (file)
@@ -4522,8 +4522,8 @@ void FrameView::paintContentsForSnapshot(GraphicsContext& context, const IntRect
     // after we paint the snapshot.
     if (shouldPaintSelection == ExcludeSelection) {
         for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
-            if (RenderView* root = frame->contentRenderer())
-                root->clearSelection();
+            if (auto* renderView = frame->contentRenderer())
+                renderView->selection().clear();
         }
     }
 
index cd2bd43..211c965 100644 (file)
@@ -135,21 +135,20 @@ struct ScopedFrameSelectionState {
     ScopedFrameSelectionState(Frame& frame)
         : frame(frame)
     {
-        if (RenderView* root = frame.contentRenderer())
-            root->getSelection(startRenderer, startOffset, endRenderer, endOffset);
+        if (auto* renderView = frame.contentRenderer())
+            selection = renderView->selection().get();
     }
 
     ~ScopedFrameSelectionState()
     {
-        if (RenderView* root = frame.contentRenderer())
-            root->setSelection(startRenderer, startOffset, endRenderer, endOffset, RenderView::RepaintNothing);
+        if (auto* renderView = frame.contentRenderer()) {
+            ASSERT(selection);
+            renderView->selection().set(selection.value(), SelectionRangeData::RepaintMode::Nothing);
+        }
     }
 
     const Frame& frame;
-    RenderObject* startRenderer;
-    RenderObject* endRenderer;
-    std::optional<unsigned> startOffset;
-    std::optional<unsigned> endOffset;
+    std::optional<SelectionRangeData::Context> selection;
 };
 
 #if !PLATFORM(IOS)
@@ -186,10 +185,10 @@ DragImageRef createDragImageForRange(Frame& frame, Range& range, bool forceBlack
     int startOffset = start.deprecatedEditingOffset();
     int endOffset = end.deprecatedEditingOffset();
     ASSERT(startOffset >= 0 && endOffset >= 0);
-    view->setSelection(startRenderer, startOffset, endRenderer, endOffset, RenderView::RepaintNothing);
+    view->selection().set({ startRenderer, endRenderer, startOffset, endOffset }, SelectionRangeData::RepaintMode::Nothing);
     // We capture using snapshotFrameRect() because we fake up the selection using
     // FrameView but snapshotSelection() uses the selection from the Frame itself.
-    return createDragImageFromSnapshot(snapshotFrameRect(frame, view->selectionBounds(), options), nullptr);
+    return createDragImageFromSnapshot(snapshotFrameRect(frame, view->selection().boundsClippedToVisibleContent(), options), nullptr);
 }
 
 #endif
index b64fceb..9ddd187 100644 (file)
@@ -144,8 +144,9 @@ RenderObject::SelectionState InlineTextBox::selectionState()
 {
     RenderObject::SelectionState state = renderer().selectionState();
     if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
-        unsigned startPos, endPos;
-        renderer().view().getSelectionStartEnd(startPos, endPos);
+        auto& selection = renderer().view().selection();
+        auto startPos = selection.startPosition();
+        auto endPos = selection.endPosition();
         // The position after a hard line break is considered to be past its end.
         ASSERT(start() + len() >= (isLineBreak() ? 1 : 0));
         unsigned lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
@@ -639,9 +640,8 @@ std::pair<unsigned, unsigned> InlineTextBox::selectionStartEnd() const
     if (selectionState == RenderObject::SelectionInside)
         return { 0, m_len };
     
-    unsigned start;
-    unsigned end;
-    renderer().view().getSelectionStartEnd(start, end);
+    auto start = renderer().view().selection().startPosition();
+    auto end = renderer().view().selection().endPosition();
     if (selectionState == RenderObject::SelectionStart)
         end = renderer().textLength();
     else if (selectionState == RenderObject::SelectionEnd)
index 5ab1332..bac5569 100644 (file)
@@ -1865,8 +1865,8 @@ bool RenderBlock::isSelectionRoot() const
         || isRenderFragmentedFlow() || style().columnSpan() == ColumnSpanAll)
         return true;
     
-    if (view().selectionUnsplitStart()) {
-        Node* startElement = view().selectionUnsplitStart()->node();
+    if (view().selection().start()) {
+        Node* startElement = view().selection().start()->node();
         if (startElement && startElement->rootEditableElement() == element())
             return true;
     }
index 8bbc289..d56129f 100644 (file)
@@ -1417,8 +1417,8 @@ bool RenderObject::isSelectionBorder() const
     return st == SelectionStart
         || st == SelectionEnd
         || st == SelectionBoth
-        || view().selectionUnsplitStart() == this
-        || view().selectionUnsplitEnd() == this;
+        || view().selection().start() == this
+        || view().selection().end() == this;
 }
 
 void RenderObject::willBeDestroyed()
index baa1f65..b4810ec 100644 (file)
@@ -62,7 +62,7 @@ class RenderLayer;
 class RenderLayerModelObject;
 class RenderFragmentContainer;
 class RenderTheme;
-class SelectionSubtreeRoot;
+class SelectionRangeData;
 class TransformState;
 class VisiblePosition;
 
index 640a7ba..2818c64 100644 (file)
@@ -644,23 +644,22 @@ void RenderReplaced::setSelectionState(SelectionState state)
 
 bool RenderReplaced::isSelected() const
 {
-    SelectionState s = selectionState();
-    if (s == SelectionNone)
+    SelectionState state = selectionState();
+    if (state == SelectionNone)
         return false;
-    if (s == SelectionInside)
+    if (state == SelectionInside)
         return true;
 
-    unsigned selectionStart, selectionEnd;
-    view().getSelectionStartEnd(selectionStart, selectionEnd);
-    if (s == SelectionStart)
-        return selectionStart == 0;
-        
+    auto selectionStart = view().selection().startPosition();
+    auto selectionEnd = view().selection().endPosition();
+    if (state == SelectionStart)
+        return !selectionStart;
+
     unsigned end = element()->hasChildNodes() ? element()->countChildNodes() : 1;
-    if (s == SelectionEnd)
+    if (state == SelectionEnd)
         return selectionEnd == end;
-    if (s == SelectionBoth)
-        return selectionStart == 0 && selectionEnd == end;
-        
+    if (state == SelectionBoth)
+        return !selectionStart && selectionEnd == end;
     ASSERT_NOT_REACHED();
     return false;
 }
index df13319..3d9ffcb 100644 (file)
@@ -1441,13 +1441,15 @@ LayoutRect RenderText::collectSelectionRectsForLineBoxes(const RenderLayerModelO
 
     // Now calculate startPos and endPos for painting selection.
     // We include a selection while endPos > 0
-    unsigned startPos, endPos;
+    unsigned startPos;
+    unsigned endPos;
     if (selectionState() == SelectionInside) {
         // We are fully selected.
         startPos = 0;
         endPos = textLength();
     } else {
-        view().getSelectionStartEnd(startPos, endPos);
+        startPos = view().selection().startPosition();
+        endPos = view().selection().endPosition();
         if (selectionState() == SelectionStart)
             endPos = textLength();
         else if (selectionState() == SelectionEnd)
index c250a4d..75e21c5 100644 (file)
@@ -446,11 +446,10 @@ void RenderTextLineBoxes::setSelectionState(RenderText& renderer, RenderObject::
         return;
     }
 
-    unsigned start, end;
-    renderer.view().getSelectionStartEnd(start, end);
+    auto start = renderer.view().selection().startPosition();
+    auto end = renderer.view().selection().endPosition();
     if (state == RenderObject::SelectionStart) {
         end = renderer.textLength();
-
         // to handle selection from end of text to end of line
         if (start && start == end)
             start = end - 1;
index 88ce834..6fcb599 100644 (file)
@@ -26,7 +26,6 @@
 #include "FloatQuad.h"
 #include "FloatingObjects.h"
 #include "Frame.h"
-#include "FrameSelection.h"
 #include "FrameView.h"
 #include "GraphicsContext.h"
 #include "HTMLBodyElement.h"
@@ -47,7 +46,6 @@
 #include "RenderMultiColumnSet.h"
 #include "RenderMultiColumnSpannerPlaceholder.h"
 #include "RenderQuote.h"
-#include "RenderSelectionInfo.h"
 #include "RenderWidget.h"
 #include "ScrollbarTheme.h"
 #include "Settings.h"
@@ -78,53 +76,11 @@ private:
     bool m_disallowLayout { false };
 };
 
-struct SelectionIterator {
-    SelectionIterator(RenderObject* start)
-        : m_current(start)
-    {
-        checkForSpanner();
-    }
-    
-    RenderObject* current() const
-    {
-        return m_current;
-    }
-    
-    RenderObject* next()
-    {
-        RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();
-        m_current = m_current->nextInPreOrder(currentSpan);
-        checkForSpanner();
-        if (!m_current && currentSpan) {
-            RenderObject* placeholder = m_spannerStack.last();
-            m_spannerStack.removeLast();
-            m_current = placeholder->nextInPreOrder();
-            checkForSpanner();
-        }
-        return m_current;
-    }
-
-private:
-    void checkForSpanner()
-    {
-        if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
-            return;
-        auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
-        m_spannerStack.append(&placeholder);
-        m_current = placeholder.spanner();
-    }
-
-    RenderObject* m_current { nullptr };
-    Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
-};
-
 RenderView::RenderView(Document& document, RenderStyle&& style)
     : RenderBlockFlow(document, WTFMove(style))
     , m_frameView(*document.view())
+    , m_selection(*this)
     , m_lazyRepaintTimer(*this, &RenderView::lazyRepaintTimerFired)
-#if ENABLE(SERVICE_CONTROLS)
-    , m_selectionRectGatherer(*this)
-#endif
 {
     setIsRenderView();
 
@@ -697,290 +653,6 @@ void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
     quads.append(FloatRect(FloatPoint(), layer()->size()));
 }
 
-static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset)
-{
-    if (!object)
-        return nullptr;
-
-    RenderObject* child = object->childAt(offset);
-    return child ? child : object->nextInPreOrderAfterChildren();
-}
-
-IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
-{
-    LayoutRect selRect = subtreeSelectionBounds(clipToVisibleContent);
-    return snappedIntRect(selRect);
-}
-
-LayoutRect RenderView::subtreeSelectionBounds(bool clipToVisibleContent) const
-{
-    typedef HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>> SelectionMap;
-    SelectionMap selectedObjects;
-
-    RenderObject* os = selectionData().selectionStart();
-    auto* selectionEnd = selectionData().selectionEnd();
-    RenderObject* stop = nullptr;
-    if (selectionEnd)
-        stop = rendererAfterPosition(selectionEnd, selectionData().selectionEndPos().value());
-    SelectionIterator selectionIterator(os);
-    while (os && os != stop) {
-        if ((os->canBeSelectionLeaf() || os == selectionData().selectionStart() || os == selectionData().selectionEnd()) && os->selectionState() != SelectionNone) {
-            // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
-            selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(*os, clipToVisibleContent));
-            RenderBlock* cb = os->containingBlock();
-            while (cb && !is<RenderView>(*cb)) {
-                std::unique_ptr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value;
-                if (blockInfo)
-                    break;
-                blockInfo = std::make_unique<RenderSelectionInfo>(*cb, clipToVisibleContent);
-                cb = cb->containingBlock();
-            }
-        }
-
-        os = selectionIterator.next();
-    }
-
-    // Now create a single bounding box rect that encloses the whole selection.
-    LayoutRect selRect;
-    SelectionMap::iterator end = selectedObjects.end();
-    for (SelectionMap::iterator i = selectedObjects.begin(); i != end; ++i) {
-        RenderSelectionInfo* info = i->value.get();
-        // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
-        LayoutRect currRect = info->rect();
-        if (RenderLayerModelObject* repaintContainer = info->repaintContainer()) {
-            FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
-            currRect = absQuad.enclosingBoundingBox(); 
-        }
-        selRect.unite(currRect);
-    }
-    return selRect;
-}
-
-void RenderView::repaintSelection() const
-{
-    repaintSubtreeSelection();
-}
-
-void RenderView::repaintSubtreeSelection() const
-{
-    HashSet<RenderBlock*> processedBlocks;
-
-    auto* selectionEnd = selectionData().selectionEnd();
-    RenderObject* end = nullptr;
-    if (selectionEnd)
-        end = rendererAfterPosition(selectionEnd, selectionData().selectionEndPos().value());
-    SelectionIterator selectionIterator(selectionData().selectionStart());
-    for (RenderObject* o = selectionIterator.current(); o && o != end; o = selectionIterator.next()) {
-        if (!o->canBeSelectionLeaf() && o != selectionData().selectionStart() && o != selectionData().selectionEnd())
-            continue;
-        if (o->selectionState() == SelectionNone)
-            continue;
-
-        RenderSelectionInfo(*o, true).repaint();
-
-        // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
-        for (RenderBlock* block = o->containingBlock(); block && !is<RenderView>(*block); block = block->containingBlock()) {
-            if (!processedBlocks.add(block).isNewEntry)
-                break;
-            RenderSelectionInfo(*block, true).repaint();
-        }
-    }
-}
-
-void RenderView::setSelection(RenderObject* start, std::optional<unsigned> startPos, RenderObject* end, std::optional<unsigned> endPos, SelectionRepaintMode blockRepaintMode)
-{
-    // Make sure both our start and end objects are defined.
-    // Check www.msnbc.com and try clicking around to find the case where this happened.
-    if ((start && !end) || (end && !start))
-        return;
-
-    bool caretChanged = m_selectionWasCaret != frame().selection().isCaret();
-    m_selectionWasCaret = frame().selection().isCaret();
-    // Just return if the selection hasn't changed.
-    if (m_selectionUnsplitStart == start && m_selectionUnsplitStartPos == startPos
-        && m_selectionUnsplitEnd == end && m_selectionUnsplitEndPos == endPos && !caretChanged) {
-        return;
-    }
-
-#if ENABLE(SERVICE_CONTROLS)
-    // Clear the current rects and create a notifier for the new rects we are about to gather.
-    // The Notifier updates the Editor when it goes out of scope and is destroyed.
-    std::unique_ptr<SelectionRectGatherer::Notifier> rectNotifier = m_selectionRectGatherer.clearAndCreateNotifier();
-#endif // ENABLE(SERVICE_CONTROLS)
-    // Set global positions for new selection.
-    m_selectionUnsplitStart = start;
-    m_selectionUnsplitStartPos = startPos;
-    m_selectionUnsplitEnd = end;
-    m_selectionUnsplitEndPos = endPos;
-    auto oldSelectionData = std::make_unique<OldSelectionData>();
-    clearSubtreeSelection(blockRepaintMode, *oldSelectionData);
-    setSelectionData(SelectionSubtreeData(start, startPos, end, endPos));
-    applySubtreeSelection(blockRepaintMode, *oldSelectionData);
-}
-
-static inline bool isValidObjectForNewSelection(const RenderView& view, const RenderObject& object)
-{
-    return (object.canBeSelectionLeaf() || &object == view.selectionData().selectionStart() || &object == view.selectionData().selectionEnd()) && object.selectionState() != RenderObject::SelectionNone && object.containingBlock();
-}
-
-void RenderView::clearSubtreeSelection(SelectionRepaintMode blockRepaintMode, OldSelectionData& oldSelectionData) const
-{
-    // Record the old selected objects.  These will be used later
-    // when we compare against the new selected objects.
-    oldSelectionData.selectionStartPos = selectionData().selectionStartPos();
-    oldSelectionData.selectionEndPos = selectionData().selectionEndPos();
-    
-    // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
-    // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
-    // the union of those rects might remain the same even when changes have occurred.
-
-    RenderObject* os = selectionData().selectionStart();
-    auto* selectionEnd = selectionData().selectionEnd();
-    RenderObject* stop = nullptr;
-    if (selectionEnd)
-        stop = rendererAfterPosition(selectionEnd, selectionData().selectionEndPos().value());
-    SelectionIterator selectionIterator(os);
-    while (os && os != stop) {
-        if (isValidObjectForNewSelection(*this, *os)) {
-            // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
-            oldSelectionData.selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(*os, true));
-            if (blockRepaintMode == RepaintNewXOROld) {
-                RenderBlock* cb = os->containingBlock();
-                while (cb && !is<RenderView>(*cb)) {
-                    std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = oldSelectionData.selectedBlocks.add(cb, nullptr).iterator->value;
-                    if (blockInfo)
-                        break;
-                    blockInfo = std::make_unique<RenderBlockSelectionInfo>(*cb);
-                    cb = cb->containingBlock();
-                }
-            }
-        }
-
-        os = selectionIterator.next();
-    }
-
-    for (auto* selectedObject : oldSelectionData.selectedObjects.keys())
-        selectedObject->setSelectionStateIfNeeded(SelectionNone);
-}
-
-void RenderView::applySubtreeSelection(SelectionRepaintMode blockRepaintMode, const OldSelectionData& oldSelectionData)
-{
-    // Update the selection status of all objects between selectionStart and selectionEnd
-    if (selectionData().selectionStart() && selectionData().selectionStart() == selectionData().selectionEnd())
-        selectionData().selectionStart()->setSelectionStateIfNeeded(SelectionBoth);
-    else {
-        if (selectionData().selectionStart())
-            selectionData().selectionStart()->setSelectionStateIfNeeded(SelectionStart);
-        if (selectionData().selectionEnd())
-            selectionData().selectionEnd()->setSelectionStateIfNeeded(SelectionEnd);
-    }
-
-    RenderObject* selectionStart = selectionData().selectionStart();
-    auto* selectionDataEnd = selectionData().selectionEnd();
-    RenderObject* selectionEnd = nullptr;
-    if (selectionDataEnd)
-        selectionEnd = rendererAfterPosition(selectionDataEnd, selectionData().selectionEndPos().value());
-    SelectionIterator selectionIterator(selectionStart);
-    for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
-        if (currentRenderer == selectionData().selectionStart() || currentRenderer == selectionData().selectionEnd())
-            continue;
-        if (!currentRenderer->canBeSelectionLeaf())
-            continue;
-        currentRenderer->setSelectionStateIfNeeded(SelectionInside);
-    }
-
-    if (blockRepaintMode != RepaintNothing)
-        layer()->clearBlockSelectionGapsBounds();
-
-    // Now that the selection state has been updated for the new objects, walk them again and
-    // put them in the new objects list.
-    SelectedObjectMap newSelectedObjects;
-    SelectedBlockMap newSelectedBlocks;
-    selectionIterator = SelectionIterator(selectionStart);
-    for (RenderObject* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
-        if (isValidObjectForNewSelection(*this, *currentRenderer)) {
-            std::unique_ptr<RenderSelectionInfo> selectionInfo = std::make_unique<RenderSelectionInfo>(*currentRenderer, true);
-
-#if ENABLE(SERVICE_CONTROLS)
-            for (auto& rect : selectionInfo->collectedSelectionRects())
-                m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);
-            if (!currentRenderer->isTextOrLineBreak())
-                m_selectionRectGatherer.setTextOnly(false);
-#endif
-
-            newSelectedObjects.set(currentRenderer, WTFMove(selectionInfo));
-
-            RenderBlock* containingBlock = currentRenderer->containingBlock();
-            while (containingBlock && !is<RenderView>(*containingBlock)) {
-                std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;
-                if (blockInfo)
-                    break;
-                blockInfo = std::make_unique<RenderBlockSelectionInfo>(*containingBlock);
-                containingBlock = containingBlock->containingBlock();
-
-#if ENABLE(SERVICE_CONTROLS)
-                m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());
-#endif
-            }
-        }
-    }
-
-    if (blockRepaintMode == RepaintNothing)
-        return;
-
-    // Have any of the old selected objects changed compared to the new selection?
-    for (const auto& selectedObjectInfo : oldSelectionData.selectedObjects) {
-        RenderObject* obj = selectedObjectInfo.key;
-        RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
-        RenderSelectionInfo* oldInfo = selectedObjectInfo.value.get();
-        if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()
-            || (selectionData().selectionStart() == obj && oldSelectionData.selectionStartPos != selectionData().selectionStartPos())
-            || (selectionData().selectionEnd() == obj && oldSelectionData.selectionEndPos != selectionData().selectionEndPos())) {
-            oldInfo->repaint();
-            if (newInfo) {
-                newInfo->repaint();
-                newSelectedObjects.remove(obj);
-            }
-        }
-    }
-
-    // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
-    for (const auto& selectedObjectInfo : newSelectedObjects)
-        selectedObjectInfo.value->repaint();
-
-    // Have any of the old blocks changed?
-    for (const auto& selectedBlockInfo : oldSelectionData.selectedBlocks) {
-        const RenderBlock* block = selectedBlockInfo.key;
-        RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
-        RenderBlockSelectionInfo* oldInfo = selectedBlockInfo.value.get();
-        if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
-            oldInfo->repaint();
-            if (newInfo) {
-                newInfo->repaint();
-                newSelectedBlocks.remove(block);
-            }
-        }
-    }
-
-    // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
-    for (const auto& selectedBlockInfo : newSelectedBlocks)
-        selectedBlockInfo.value->repaint();
-}
-
-void RenderView::getSelection(RenderObject*& startRenderer, std::optional<unsigned>& startOffset, RenderObject*& endRenderer, std::optional<unsigned>& endOffset) const
-{
-    startRenderer = m_selectionUnsplitStart;
-    startOffset = m_selectionUnsplitStartPos;
-    endRenderer = m_selectionUnsplitEnd;
-    endOffset = m_selectionUnsplitEndPos;
-}
-
-void RenderView::clearSelection()
-{
-    layer()->repaintBlockSelectionGaps();
-    setSelection(nullptr, std::nullopt, nullptr, std::nullopt, RepaintNewMinusOld);
-}
-
 bool RenderView::printing() const
 {
     return document().printing();
index 581888d..c37ebbf 100644 (file)
 #include "Region.h"
 #include "RenderBlockFlow.h"
 #include "RenderWidget.h"
-#include "SelectionSubtreeRoot.h"
+#include "SelectionRangeData.h"
 #include <memory>
 #include <wtf/HashSet.h>
 #include <wtf/ListHashSet.h>
 
-#if ENABLE(SERVICE_CONTROLS)
-#include "SelectionRectGatherer.h"
-#endif
-
 namespace WebCore {
 
 class ImageQualityController;
 class RenderLayerCompositor;
 class RenderQuote;
 
-class RenderView final : public RenderBlockFlow, public SelectionSubtreeRoot {
+class RenderView final : public RenderBlockFlow {
 public:
     RenderView(Document&, RenderStyle&&);
     virtual ~RenderView();
@@ -85,15 +81,7 @@ public:
     // Return the renderer whose background style is used to paint the root background.
     RenderElement* rendererForRootBackground() const;
 
-    enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing };
-    void setSelection(RenderObject* start, std::optional<unsigned> startPos, RenderObject* endObject, std::optional<unsigned> endPos, SelectionRepaintMode = RepaintNewXOROld);
-    void getSelection(RenderObject*& startRenderer, std::optional<unsigned>& startOffset, RenderObject*& endRenderer, std::optional<unsigned>& endOffset) const;
-    void clearSelection();
-    RenderObject* selectionUnsplitStart() const { return m_selectionUnsplitStart; }
-    RenderObject* selectionUnsplitEnd() const { return m_selectionUnsplitEnd; }
-    IntRect selectionBounds(bool clipToVisibleContent = true) const;
-    void repaintSelection() const;
-    void getSelectionStartEnd(unsigned& start, unsigned& end) const { selectionData().selectionStartEndPositions(start, end); }
+    SelectionRangeData& selection() { return m_selection; }
 
     bool printing() const;
 
@@ -312,23 +300,14 @@ private:
 
     bool isScrollableOrRubberbandableBox() const override;
 
-    void clearSubtreeSelection(SelectionRepaintMode blockRepaintMode, OldSelectionData&) const;
-    void applySubtreeSelection(SelectionRepaintMode, const OldSelectionData&);
-    LayoutRect subtreeSelectionBounds(bool clipToVisibleContent = true) const;
-    void repaintSubtreeSelection() const;
-
 private:
     FrameView& m_frameView;
 
-    RenderObject* m_selectionUnsplitStart { nullptr };
-    RenderObject* m_selectionUnsplitEnd { nullptr };
-    std::optional<unsigned> m_selectionUnsplitStartPos;
-    std::optional<unsigned> m_selectionUnsplitEndPos;
-
     // Include this RenderView.
     uint64_t m_rendererCount { 1 };
 
     mutable std::unique_ptr<Region> m_accumulatedRepaintRegion;
+    SelectionRangeData m_selection;
 
     // FIXME: Only used by embedded WebViews inside AppKit NSViews.  Find a way to remove.
     struct LegacyPrinting {
@@ -360,7 +339,6 @@ private:
     unsigned m_renderCounterCount { 0 };
     unsigned m_renderTreeInternalMutationCounter { 0 };
 
-    bool m_selectionWasCaret { false };
     bool m_hasSoftwareFilters { false };
     bool m_usesFirstLineRules { false };
     bool m_usesFirstLetterRules { false };
@@ -372,9 +350,6 @@ private:
     HashSet<RenderElement*> m_visibleInViewportRenderers;
     Vector<RefPtr<RenderWidget>> m_protectedRenderWidgets;
 
-#if ENABLE(SERVICE_CONTROLS)
-    SelectionRectGatherer m_selectionRectGatherer;
-#endif
 #if ENABLE(CSS_SCROLL_SNAP)
     HashSet<const RenderBox*> m_boxesWithScrollSnapPositions;
 #endif
index dec6dfa..ecec027 100644 (file)
 #include "RenderWidget.cpp"
 #include "RootInlineBox.cpp"
 #include "ScrollAlignment.cpp"
-#include "SelectionSubtreeRoot.cpp"
+#include "SelectionRangeData.cpp"
 #include "SimpleLineLayout.cpp"
 #include "SimpleLineLayoutCoverage.cpp"
 #include "SimpleLineLayoutFlowContents.cpp"
diff --git a/Source/WebCore/rendering/SelectionRangeData.cpp b/Source/WebCore/rendering/SelectionRangeData.cpp
new file mode 100644 (file)
index 0000000..fcc6979
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2014 Igalia S.L.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "SelectionRangeData.h"
+
+#include "Document.h"
+#include "FrameSelection.h"
+#include "Position.h"
+#include "Range.h"
+#include "RenderLayer.h"
+#include "RenderMultiColumnSpannerPlaceholder.h"
+#include "RenderObject.h"
+#include "RenderView.h"
+#include "VisibleSelection.h"
+
+namespace WebCore {
+    
+struct SelectionData {
+    using RendererMap = HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>>;
+    using RenderBlockMap = HashMap<const RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>>;
+
+    std::optional<unsigned> startPosition;
+    std::optional<unsigned> endPosition;
+    RendererMap renderers;
+    RenderBlockMap blocks;
+};
+
+class SelectionIterator {
+public:
+    SelectionIterator(RenderObject* start)
+        : m_current(start)
+    {
+        checkForSpanner();
+    }
+    
+    RenderObject* current() const
+    {
+        return m_current;
+    }
+    
+    RenderObject* next()
+    {
+        RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();
+        m_current = m_current->nextInPreOrder(currentSpan);
+        checkForSpanner();
+        if (!m_current && currentSpan) {
+            RenderObject* placeholder = m_spannerStack.last();
+            m_spannerStack.removeLast();
+            m_current = placeholder->nextInPreOrder();
+            checkForSpanner();
+        }
+        return m_current;
+    }
+
+private:
+    void checkForSpanner()
+    {
+        if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
+            return;
+        auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
+        m_spannerStack.append(&placeholder);
+        m_current = placeholder.spanner();
+    }
+
+    RenderObject* m_current { nullptr };
+    Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
+};
+
+static RenderObject* rendererAfterPosition(const RenderObject& renderer, unsigned offset)
+{
+    auto* child = renderer.childAt(offset);
+    return child ? child : renderer.nextInPreOrderAfterChildren();
+}
+
+static bool isValidRendererForSelection(const RenderObject& renderer, const SelectionRangeData::Context& selection)
+{
+    return (renderer.canBeSelectionLeaf() || &renderer == selection.start || &renderer == selection.end)
+        && renderer.selectionState() != RenderObject::SelectionNone
+        && renderer.containingBlock();
+}
+
+static RenderBlock* containingBlockBelowView(const RenderObject& renderer)
+{
+    auto* containingBlock = renderer.containingBlock();
+    return is<RenderView>(containingBlock) ? nullptr : containingBlock;
+}
+
+static SelectionData collect(const SelectionRangeData::Context& selection, bool repaintDifference)
+{
+    SelectionData oldSelectionData { selection.startPosition, selection.endPosition, { }, { } };
+    // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
+    // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
+    // the union of those rects might remain the same even when changes have occurred.
+    RenderObject* start = selection.start;
+    RenderObject* stop = nullptr;
+    if (selection.end)
+        stop = rendererAfterPosition(*selection.end, selection.endPosition.value());
+    SelectionIterator selectionIterator(start);
+    while (start && start != stop) {
+        if (isValidRendererForSelection(*start, selection)) {
+            // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
+            oldSelectionData.renderers.set(start, std::make_unique<RenderSelectionInfo>(*start, true));
+            if (repaintDifference) {
+                for (auto* block = containingBlockBelowView(*start); block; block = containingBlockBelowView(*block)) {
+                    auto& blockInfo = oldSelectionData.blocks.add(block, nullptr).iterator->value;
+                    if (blockInfo)
+                        break;
+                    blockInfo = std::make_unique<RenderBlockSelectionInfo>(*block);
+                }
+            }
+        }
+        start = selectionIterator.next();
+    }
+    return oldSelectionData;
+}
+
+SelectionRangeData::SelectionRangeData(RenderView& view)
+    : m_renderView(view)
+#if ENABLE(SERVICE_CONTROLS)
+    , m_selectionRectGatherer(view)
+#endif
+{
+}
+
+void SelectionRangeData::set(const Context& selection, RepaintMode blockRepaintMode)
+{
+    // Make sure both our start and end objects are defined.
+    // Check www.msnbc.com and try clicking around to find the case where this happened.
+    if ((selection.start && !selection.end) || (selection.end && !selection.start))
+        return;
+    // Just return if the selection hasn't changed.
+    auto isCaret = m_renderView.frame().selection().isCaret();
+    if (selection == m_selectionContext && m_selectionWasCaret == isCaret)
+        return;
+#if ENABLE(SERVICE_CONTROLS)
+    // Clear the current rects and create a notifier for the new rects we are about to gather.
+    // The Notifier updates the Editor when it goes out of scope and is destroyed.
+    auto rectNotifier = m_selectionRectGatherer.clearAndCreateNotifier();
+#endif
+    m_selectionWasCaret = isCaret;
+    apply(selection, blockRepaintMode);
+}
+
+void SelectionRangeData::clear()
+{
+    m_renderView.layer()->repaintBlockSelectionGaps();
+    set({nullptr, nullptr, std::nullopt, std::nullopt}, SelectionRangeData::RepaintMode::NewMinusOld);
+}
+
+void SelectionRangeData::repaint() const
+{
+    HashSet<RenderBlock*> processedBlocks;
+    RenderObject* end = nullptr;
+    if (m_selectionContext.end)
+        end = rendererAfterPosition(*m_selectionContext.end, m_selectionContext.endPosition.value());
+    SelectionIterator selectionIterator(m_selectionContext.start);
+    for (auto* renderer = selectionIterator.current(); renderer && renderer != end; renderer = selectionIterator.next()) {
+        if (!renderer->canBeSelectionLeaf() && renderer != m_selectionContext.start && renderer != m_selectionContext.end)
+            continue;
+        if (renderer->selectionState() == RenderObject::SelectionNone)
+            continue;
+        RenderSelectionInfo(*renderer, true).repaint();
+        // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
+        for (auto* block = containingBlockBelowView(*renderer); block; block = containingBlockBelowView(*block)) {
+            if (!processedBlocks.add(block).isNewEntry)
+                break;
+            RenderSelectionInfo(*block, true).repaint();
+        }
+    }
+}
+
+IntRect SelectionRangeData::collectBounds(ClipToVisibleContent clipToVisibleContent) const
+{
+    SelectionData::RendererMap renderers;
+    RenderObject* start = m_selectionContext.start;
+    RenderObject* stop = nullptr;
+    if (m_selectionContext.end)
+        stop = rendererAfterPosition(*m_selectionContext.end, m_selectionContext.endPosition.value());
+    SelectionIterator selectionIterator(start);
+    while (start && start != stop) {
+        if ((start->canBeSelectionLeaf() || start == m_selectionContext.start || start == m_selectionContext.end)
+            && start->selectionState() != RenderObject::SelectionNone) {
+            // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
+            renderers.set(start, std::make_unique<RenderSelectionInfo>(*start, clipToVisibleContent == ClipToVisibleContent::Yes));
+            auto* block = start->containingBlock();
+            while (block && !is<RenderView>(*block)) {
+                std::unique_ptr<RenderSelectionInfo>& blockInfo = renderers.add(block, nullptr).iterator->value;
+                if (blockInfo)
+                    break;
+                blockInfo = std::make_unique<RenderSelectionInfo>(*block, clipToVisibleContent == ClipToVisibleContent::Yes);
+                block = block->containingBlock();
+            }
+        }
+        start = selectionIterator.next();
+    }
+
+    // Now create a single bounding box rect that encloses the whole selection.
+    LayoutRect selectionRect;
+    for (auto& info : renderers.values()) {
+        // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
+        LayoutRect currentRect = info->rect();
+        if (auto* repaintContainer = info->repaintContainer()) {
+            FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currentRect));
+            currentRect = absQuad.enclosingBoundingBox();
+        }
+        selectionRect.unite(currentRect);
+    }
+    return snappedIntRect(selectionRect);
+}
+
+void SelectionRangeData::apply(const Context& newSelection, RepaintMode blockRepaintMode)
+{
+    auto oldSelectionData = collect(m_selectionContext, blockRepaintMode == RepaintMode::NewXOROld);
+    // Remove current selection.
+    for (auto* renderer : oldSelectionData.renderers.keys())
+        renderer->setSelectionStateIfNeeded(RenderObject::SelectionNone);
+    m_selectionContext = newSelection;
+    // Update the selection status of all objects between selectionStart and selectionEnd
+    if (m_selectionContext.start && m_selectionContext.start == m_selectionContext.end)
+        m_selectionContext.start->setSelectionStateIfNeeded(RenderObject::SelectionBoth);
+    else {
+        if (m_selectionContext.start)
+            m_selectionContext.start->setSelectionStateIfNeeded(RenderObject::SelectionStart);
+        if (m_selectionContext.end)
+            m_selectionContext.end->setSelectionStateIfNeeded(RenderObject::SelectionEnd);
+    }
+
+    auto* selectionStart = m_selectionContext.start;
+    auto* selectionDataEnd = m_selectionContext.end;
+    RenderObject* selectionEnd = nullptr;
+    if (selectionDataEnd)
+        selectionEnd = rendererAfterPosition(*selectionDataEnd, m_selectionContext.endPosition.value());
+    SelectionIterator selectionIterator(selectionStart);
+    for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
+        if (currentRenderer == m_selectionContext.start || currentRenderer == m_selectionContext.end)
+            continue;
+        if (!currentRenderer->canBeSelectionLeaf())
+            continue;
+        currentRenderer->setSelectionStateIfNeeded(RenderObject::SelectionInside);
+    }
+
+    if (blockRepaintMode != RepaintMode::Nothing)
+        m_renderView.layer()->clearBlockSelectionGapsBounds();
+
+    // Now that the selection state has been updated for the new objects, walk them again and
+    // put them in the new objects list.
+    SelectionData::RendererMap newSelectedRenderers;
+    SelectionData::RenderBlockMap newSelectedBlocks;
+    selectionIterator = SelectionIterator(selectionStart);
+    for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
+        if (isValidRendererForSelection(*currentRenderer, m_selectionContext)) {
+            std::unique_ptr<RenderSelectionInfo> selectionInfo = std::make_unique<RenderSelectionInfo>(*currentRenderer, true);
+#if ENABLE(SERVICE_CONTROLS)
+            for (auto& rect : selectionInfo->collectedSelectionRects())
+                m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);
+            if (!currentRenderer->isTextOrLineBreak())
+                m_selectionRectGatherer.setTextOnly(false);
+#endif
+            newSelectedRenderers.set(currentRenderer, WTFMove(selectionInfo));
+            auto* containingBlock = currentRenderer->containingBlock();
+            while (containingBlock && !is<RenderView>(*containingBlock)) {
+                std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;
+                if (blockInfo)
+                    break;
+                blockInfo = std::make_unique<RenderBlockSelectionInfo>(*containingBlock);
+                containingBlock = containingBlock->containingBlock();
+#if ENABLE(SERVICE_CONTROLS)
+                m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());
+#endif
+            }
+        }
+    }
+
+    if (blockRepaintMode == RepaintMode::Nothing)
+        return;
+
+    // Have any of the old selected objects changed compared to the new selection?
+    for (auto& selectedRendererInfo : oldSelectionData.renderers) {
+        auto* renderer = selectedRendererInfo.key;
+        auto* newInfo = newSelectedRenderers.get(renderer);
+        auto* oldInfo = selectedRendererInfo.value.get();
+        if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()
+            || (m_selectionContext.start == renderer && oldSelectionData.startPosition != m_selectionContext.startPosition)
+            || (m_selectionContext.end == renderer && oldSelectionData.endPosition != m_selectionContext.endPosition)) {
+            oldInfo->repaint();
+            if (newInfo) {
+                newInfo->repaint();
+                newSelectedRenderers.remove(renderer);
+            }
+        }
+    }
+
+    // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
+    for (auto& selectedRendererInfo : newSelectedRenderers)
+        selectedRendererInfo.value->repaint();
+
+    // Have any of the old blocks changed?
+    for (auto& selectedBlockInfo : oldSelectionData.blocks) {
+        auto* block = selectedBlockInfo.key;
+        auto* newInfo = newSelectedBlocks.get(block);
+        auto* oldInfo = selectedBlockInfo.value.get();
+        if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
+            oldInfo->repaint();
+            if (newInfo) {
+                newInfo->repaint();
+                newSelectedBlocks.remove(block);
+            }
+        }
+    }
+
+    // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
+    for (auto& selectedBlockInfo : newSelectedBlocks)
+        selectedBlockInfo.value->repaint();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/SelectionRangeData.h b/Source/WebCore/rendering/SelectionRangeData.h
new file mode 100644 (file)
index 0000000..f4ff3db
--- /dev/null
@@ -0,0 +1,86 @@
+ /*
+ * Copyright (C) 2014 Igalia S.L.
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ *    copyright notice, this list of conditions and the following
+ *    disclaimer in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "RenderSelectionInfo.h"
+
+#if ENABLE(SERVICE_CONTROLS)
+#include "SelectionRectGatherer.h"
+#endif
+
+namespace WebCore {
+
+struct OldSelectionData;
+    
+class SelectionRangeData {
+public:
+    SelectionRangeData(RenderView&);
+    
+    struct Context {
+        RenderObject* start { nullptr };
+        RenderObject* end { nullptr };
+        std::optional<unsigned> startPosition;
+        std::optional<unsigned> endPosition;
+
+        bool operator==(const Context& other) const
+        {
+            return start == other.start && end == other.end && startPosition == other.startPosition && endPosition == other.endPosition;
+        }
+    };
+
+    enum class RepaintMode { NewXOROld, NewMinusOld, Nothing };
+    void set(const Context&, RepaintMode = RepaintMode::NewXOROld);
+    const Context& get() const { return m_selectionContext; }
+
+    RenderObject* start() const { return m_selectionContext.start; }
+    RenderObject* end() const { return m_selectionContext.end; }
+    unsigned startPosition() const { ASSERT(m_selectionContext.startPosition); return m_selectionContext.startPosition.value(); }
+    unsigned endPosition() const { ASSERT(m_selectionContext.endPosition); return m_selectionContext.endPosition.value(); }
+
+    void clear();
+    IntRect bounds() const { return collectBounds(ClipToVisibleContent::No); }
+    IntRect boundsClippedToVisibleContent() const { return collectBounds(ClipToVisibleContent::Yes); }
+    void repaint() const;
+
+private:
+    enum class ClipToVisibleContent { Yes, No };
+    IntRect collectBounds(ClipToVisibleContent) const;
+    void apply(const Context&, RepaintMode);
+
+    const RenderView& m_renderView;
+#if ENABLE(SERVICE_CONTROLS)
+    SelectionRectGatherer m_selectionRectGatherer;
+#endif
+    Context m_selectionContext;
+    bool m_selectionWasCaret { false };
+};
+
+} // namespace WebCore
diff --git a/Source/WebCore/rendering/SelectionSubtreeRoot.cpp b/Source/WebCore/rendering/SelectionSubtreeRoot.cpp
deleted file mode 100644 (file)
index 4189564..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2014 Igalia S.L.
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials
- *    provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "SelectionSubtreeRoot.h"
-
-#include "Document.h"
-#include "Position.h"
-#include "Range.h"
-#include "VisibleSelection.h"
-
-namespace WebCore {
-
-SelectionSubtreeRoot::SelectionSubtreeRoot()
-{
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/rendering/SelectionSubtreeRoot.h b/Source/WebCore/rendering/SelectionSubtreeRoot.h
deleted file mode 100644 (file)
index b9c68a7..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
- /*
- * Copyright (C) 2014 Igalia S.L.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials
- *    provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#pragma once
-
-#include "RenderObject.h"
-#include "RenderSelectionInfo.h"
-
-namespace WebCore {
-
-class Document;
-
-class SelectionSubtreeRoot {
-public:
-    
-    typedef HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>> SelectedObjectMap;
-    typedef HashMap<const RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>> SelectedBlockMap;
-
-    struct OldSelectionData {
-        OldSelectionData()
-        {
-        }
-
-        std::optional<unsigned> selectionStartPos;
-        std::optional<unsigned> selectionEndPos;
-        SelectedObjectMap selectedObjects;
-        SelectedBlockMap selectedBlocks;
-    };
-
-    class SelectionSubtreeData {
-    public:
-        SelectionSubtreeData() = default;
-
-        SelectionSubtreeData(RenderObject* selectionStart, std::optional<unsigned> selectionStartPos, RenderObject* selectionEnd, std::optional<unsigned> selectionEndPos)
-            : m_selectionStart(selectionStart)
-            , m_selectionEnd(selectionEnd)
-            , m_selectionStartPos(selectionStartPos)
-            , m_selectionEndPos(selectionEndPos)
-        {
-        }
-
-        RenderObject* selectionStart() const { return m_selectionStart; }
-        std::optional<unsigned> selectionStartPos() const { return m_selectionStartPos; }
-        RenderObject* selectionEnd() const { return m_selectionEnd; }
-        std::optional<unsigned> selectionEndPos() const { return m_selectionEndPos; }
-        void selectionStartEndPositions(unsigned& startPos, unsigned& endPos) const
-        {
-            startPos = m_selectionStartPos.value();
-            endPos = m_selectionEndPos.value();
-        }
-        void clearSelection()
-        {
-            m_selectionStart = nullptr;
-            m_selectionStartPos = std::nullopt;
-            m_selectionEnd = nullptr;
-            m_selectionEndPos = std::nullopt;
-        }
-
-    private:
-        RenderObject* m_selectionStart { nullptr };
-        RenderObject* m_selectionEnd { nullptr };
-        std::optional<unsigned> m_selectionStartPos;
-        std::optional<unsigned> m_selectionEndPos;
-    };
-
-    SelectionSubtreeRoot();
-
-    SelectionSubtreeData& selectionData() { return m_selectionSubtreeData; }
-    const SelectionSubtreeData& selectionData() const { return m_selectionSubtreeData; }
-
-    void setSelectionData(const SelectionSubtreeData& selectionSubtreeData) { m_selectionSubtreeData = selectionSubtreeData; }
-
-private:
-    SelectionSubtreeData m_selectionSubtreeData;
-};
-
-} // namespace WebCore