Remove live ranges from Editor.h and EditorClient.h
https://bugs.webkit.org/show_bug.cgi?id=214261
Reviewed by Sam Weinig.
Source/WebCore:
* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::misspellingRange const): Update since
rangeForTextCheckingResult no longer returns a live range.
(WebCore::AccessibilityObject::rangeOfStringClosestToRangeInDirection const):
Update since rangeOfString no longer returns a live range.
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(accessibilityTextOperationForParameterizedAttribute): Use makeSimpleRange.
* dom/Document.cpp:
(WebCore::acceptsEditingFocus): Use makeRangeSelectingNodeContents
since shouldBeginEditing no longer takes a live range.
* dom/Range.h: Exxported makeSimpleRange for use outside WebCore.
* dom/SimpleRange.cpp:
(WebCore::makeSimpleRange): Added. Takes two optional boundary points and
returns an optional range.
* dom/SimpleRange.h: Added the above.
* editing/AlternativeTextController.cpp:
(WebCore::AlternativeTextController::timerFired): Removed calls to
crateLiveRange since markAllMisspellingsAndBadGrammarInRanges no
longer takes live ranges.
(WebCore::AlternativeTextController::applyDictationAlternative):
Updates since shouldInsertText no longer takes a live range.
* editing/DeleteSelectionCommand.cpp:
(WebCore::DeleteSelectionCommand::mergeParagraphs): Updated since
shouldMoveRangeAfterDelete no longer takes live ranges.
* editing/Editor.cpp:
(WebCore::Editor::canDeleteRange const): Updated to not take a
live range.
(WebCore::Editor::deleteWithDirection): Updated since
addRangeToKillRing no longer takes a live range.
(WebCore::Editor::pasteAsPlainTextWithPasteboard): Updated since
shouldInsertText no longer takes a live range.
(WebCore::Editor::shouldInsertFragment): No longer take a live range.
(WebCore::Editor::replaceSelectionWithText): Updated since
selectedRange no longer returns a live range.
(WebCore::Editor::selectedRange): Do not return a live range.
(WebCore::Editor::shouldDeleteRange const): Do not take a live range.
(WebCore::Editor::shouldInsertText const): Ditto.
(WebCore::Editor::shouldApplyStyle): Ditto. Also take a const& to
the style instead of a non-const*.
(WebCore::Editor::applyStyleToSelection): Pass a style reference
and a non-live range.
(WebCore::Editor::applyParagraphStyleToSelection): Updated for
the change above.
(WebCore::Editor::insertTextWithoutSendingTextEvent): No need to
pass a live range any more.
(WebCore::Editor::insertLineBreak): Ditto.
(WebCore::Editor::insertParagraphSeparator): Ditto.
(WebCore::Editor::performCutOrCopy): Updated to not use live range.
(WebCore::Editor::performDelete): Ditto.
(WebCore::Editor::shouldEndEditing): Do not take a live range.
(WebCore::Editor::shouldBeginEditing): Ditto.
(WebCore::Editor::willWriteSelectionToPasteboard): Ditto.
(WebCore::Editor::selectComposition): Update since compositionRange
is not a live range.
(WebCore::Editor::markMisspellingsAfterTypingToWord): Update since
we don't need to pass live ranges to markAllMisspellingsAndBadGrammarInRanges.
(WebCore::Editor::markMisspellingsOrBadGrammar): Don't return a
live range in tthe out argument.
(WebCore::Editor::markMisspellings): Ditto.
(WebCore::Editor::markBadGrammar): Update for the above.
(WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Do not
take live ranges for the arguments.
(WebCore::Editor::replaceRangeForSpellChecking): Do not take a live range.
(WebCore::Editor::markAndReplaceFor): Update since shouldInsertText does
not take a live range any more.
(WebCore::Editor::changeBackToReplacedString): Update to not use live
ranges as much.
(WebCore::Editor::markMisspellingsAndBadGrammar): Updae since
we don't need to pass live ranges to markAllMisspellingsAndBadGrammarInRanges.
(WebCore::Editor::rangeForPoint): Don't return a live range.
(WebCore::Editor::compositionRange const): Ditto.
(WebCore::Editor::transpose): Updated since we don't pass a live range.
(WebCore::Editor::firstRectForRange const): Don't take a live range.
(WebCore::Editor::shouldChangeSelection const): Updated since we don't
need to pass a live range.
(WebCore::Editor::findString): Ditto.
(WebCore::start): Added. Helper to make rangeOfString easier to read.
(WebCore::end): Ditto.
(WebCore::makeBoundaryPointAfterNodeContents): Ditto.
(WebCore::makeBoundaryPointAfterNode): Ditto.
(WebCore::collapseIfRootsDiffer): Ditto.
(WebCore::Editor::rangeOfString): Updated to not take or return a
live range and not use it internally either.
(WebCore::isFrameInRange): Don't take a live range.
(WebCore::Editor::countMatchesForText): Don't take or return live ranges.
(WebCore::Editor::contextRangeForCandidateRequest const): Don't return
a live range.
(WebCore::Editor::rangeForTextCheckingResult const): Ditto.
(WebCore::Editor::handleAcceptedCandidate): Update for the above.
(WebCore::Editor::adjustedSelectionRange): Don't return a live range.
* editing/Editor.h: Updated for all the chagnes above.
* editing/EditorCommand.cpp:
(WebCore::expandSelectionToGranularity): Updated to reduce the use of
live ranges.
(WebCore::unionRanges): Updated to no longer take or return a live
range. Still uses live ranges in the algorithm for now.
(WebCore::executeDeleteToMark): Updated since selectedRange no longer
returns a live range.
(WebCore::executeSelectToMark): Update to use the new unionRanges.
* editing/FrameSelection.cpp:
(WebCore::FrameSelection::shouldDeleteSelection const): Updated
since shouldDeleteRange no longer requires a live range.
* editing/cocoa/EditorCocoa.mm:
(WebCore::Editor::getPasteboardTypesAndDataForAttachment): Updated
for changes to use fewer live ranges.
(WebCore::Editor::writeSelectionToPasteboard): Ditto.
(WebCore::Editor::writeSelection): Ditto.
(WebCore::Editor::replaceSelectionWithAttributedString): Ditto.
* editing/gtk/EditorGtk.cpp:
(WebCore::Editor::pasteWithPasteboard): Ditto.
* editing/ios/EditorIOS.mm:
(WebCore::Editor::writeImageToPasteboard): Ditto.
(WebCore::Editor::pasteWithPasteboard): Ditto.
* editing/libwpe/EditorLibWPE.cpp:
(WebCore::createFragmentFromPasteboardData): Ditto.
(WebCore::Editor::pasteWithPasteboard): Ditto.
* editing/mac/EditorMac.mm:
(WebCore::Editor::pasteWithPasteboard): Ditto.
(WebCore::Editor::replaceNodeFromPasteboard): Ditto.
(WebCore::Editor::dataSelectionForPasteboard): Ditto.
* editing/win/EditorWin.cpp:
(WebCore::Editor::pasteWithPasteboard): Ditto.
* html/FTPDirectoryDocument.cpp:
(WebCore::FTPDirectoryDocumentParser::createTDForFilename):
Removed a WTFMove that messes up the return value optimization.
Noticed while fixing errors caused by live range changes.
* loader/EmptyClients.cpp: Updated for changes to EditorClient.
* page/ContextMenuController.cpp:
(WebCore::insertUnicodeCharacter): Updated to use fewer live ranges.
(WebCore::ContextMenuController::contextMenuItemSelected): DItto.
* page/DragController.cpp:
(WebCore::DragController::concludeEditDrag): Ditto.
(WebCore::DragController::startDrag): Ditto.
* page/EditorClient.h: Don't take or return live ranges.
* page/EventHandler.cpp:
(WebCore::EventHandler::sendContextMenuEventForKey): Simplified
since we don't need to use a live range.
* page/FocusController.cpp:
(WebCore::relinquishesEditingFocus): Changed argument type to be
more specific, and changed to not use a live range.
(WebCore::FocusController::setFocusedElement): Updated for the above.
* page/Frame.cpp:
(WebCore::Frame::rangeForPoint): Updated to not use live ranges.
* page/Page.cpp:
(WebCore::Page::findStringMatchingRanges): Updated to not use
live ranges as much.
(WebCore::Page::rangeOfString): Ditto.
(WebCore::Page::findMatchesForText): Ditto.
* testing/Internals.cpp:
(WebCore::Internals::rangeOfString): Updated since return value
of the Editor member function is no longer a live range.
(WebCore::Internals::countMatchesForText): Ditto.
Source/WebKit:
* UIProcess/mac/WKPrintingView.mm:
(-[WKPrintingView rectForPage:]): Use NSZeroRect.
* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::shouldDeleteRange): Updated for live
range changes and also removed gratuitous call to notImplemented
since the function is implemented.
(WebKit::WebEditorClient::shouldBeginEditing): Ditto.
(WebKit::WebEditorClient::shouldEndEditing): Ditto.
(WebKit::WebEditorClient::shouldInsertNode): Ditto.
(WebKit::WebEditorClient::shouldInsertText): Ditto.
(WebKit::WebEditorClient::shouldChangeSelectedRange): Ditto.
(WebKit::WebEditorClient::shouldApplyStyle): Ditto.
(WebKit::WebEditorClient::shouldMoveRangeAfterDelete): Ditto.
(WebKit::WebEditorClient::didBeginEditing): Ditto.
(WebKit::WebEditorClient::didEndEditing): Ditto.
(WebKit::WebEditorClient::willWriteSelectionToPasteboard): Ditto.
(WebKit::WebEditorClient::getClientPasteboardData): Ditto.
(WebKit::WebEditorClient::performTwoStepDrop): Ditto.
(WebKit::WebEditorClient::overflowScrollPositionChanged): Ditto.
(WebKit::WebEditorClient::subFrameScrollPositionChanged): Ditto.
(WebKit::WebEditorClient::setInputMethodState): Ditto.
* WebProcess/WebCoreSupport/WebEditorClient.h: Updated
for changes to EditorClient.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::getMarkedRangeAsync): Updated to reduce
the use of local values and live ranges.
(WebKit::WebPage::getSelectedRangeAsync): Ditto.
(WebKit::WebPage::characterIndexForPointAsync): Ditto.
(WebKit::WebPage::firstRectForCharacterRangeAsync): Ditto.
(WebKit::WebPage::setCompositionAsync): Ditto.
* WebProcess/WebPage/glib/WebPageGLib.cpp:
(WebKit::WebPage::getPlatformEditorState const): Ditto.
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getPlatformEditorState const): Ditto.
(WebKit::WebPage::selectWithGesture): Ditto.
(WebKit::WebPage::autocorrectionContext): Ditto.
(WebKit::focusedElementPositionInformation): Ditto.
(WebKit::WebPage::requestDocumentEditingContext): Ditto.
Source/WebKitLegacy/ios:
* WebCoreSupport/WebFrameIOS.mm:
(-[WebFrame closestCaretRectInMarkedTextRangeForPoint:]):
Updated since compositionRange is no longer a live range.
Source/WebKitLegacy/mac:
* DOM/DOMRange.mm:
(kit): Added an overload to convert to a live range so we don't have
to touch every call site.
* DOM/DOMRangeInternal.h: Added the above.
* WebCoreSupport/WebEditorClient.h: Updated for changes to EditorClient.
* WebCoreSupport/WebEditorClient.mm:
(WebEditorClient::shouldDeleteRange): Changed types to not use live ranges.
(WebEditorClient::shouldApplyStyle): Ditto.
(WebEditorClient::shouldMoveRangeAfterDelete): Ditto.
(WebEditorClient::shouldBeginEditing): Ditto.
(WebEditorClient::shouldEndEditing): Ditto.
(WebEditorClient::shouldInsertText): Ditto.
(WebEditorClient::shouldChangeSelectedRange): Ditto.
(WebEditorClient::willWriteSelectionToPasteboard): Ditto.
(WebEditorClient::getClientPasteboardData): Ditto.
(WebEditorClient::shouldInsertNode): Ditto.
(WebEditorClient::performTwoStepDrop): Ditto.
* WebView/WebFrame.mm:
(-[WebFrame _firstRectForDOMRange:]): Update to not use live range.
(-[WebFrame _scrollDOMRangeToVisible:]): Ditto.
(-[WebFrame _rangeByAlteringCurrentSelection:direction:granularity:]): Ditto.
(-[WebFrame _markDOMRange]): Ditto.
(-[WebFrame _selectionRangeForFirstPoint:secondPoint:]): Ditto.
(-[WebFrame _selectionRangeForPoint:]): Ditto.
(-[WebFrame selectedDOMRange]): Ditto.
(-[WebFrame elementRangeContainingCaretSelection]): Ditto.
(-[WebFrame wordRangeContainingCaretSelection]): Ditto.
(-[WebFrame rangeByMovingCurrentSelection:]): Ditto.
(-[WebFrame rangeByExtendingCurrentSelection:]): Ditto.
(-[WebFrame markedTextDOMRange]): Ditto.
* WebView/WebHTMLView.mm:
(-[WebHTMLView _selectedRange]): Update to not use live range.
(-[WebHTMLView firstRectForCharacterRange:]): Use NSZeroRect.
(-[WebHTMLView countMatchesForText:inDOMRange:options:limit:markMatches:]):
Update to not use live range.
* WebView/WebTextCompletionController.mm:
(-[WebTextCompletionController doCompletion]): Ditto.
* WebView/WebTextIterator.mm:
(-[WebTextIterator currentRange]): Ditto.
* WebView/WebView.mm:
(-[WebView textIteratorForRect:]): Ditto.
(-[WebView editableDOMRangeForPoint:]): Ditto.
(-[WebView selectedDOMRange]): Ditto.
Source/WebKitLegacy/win:
* DOMCoreClasses.cpp:
(DOMWindow::DOMWindow): Added ref for underlying WebCore::DOMWindow.
(DOMWindow::~DOMWindow): Added deref for underlying WebCore::DOMWindow.
(DOMRange::DOMRange): Added ref for underlying live range.
(DOMRange::~DOMRange): Added deref for underlying live range.
(DOMRange::createInstance): Added overload for creating a DOMRange from
a SimpleRange that creates the live range.
(DOMNamedNodeMap::DOMNamedNodeMap): Added ref for underlying live range.
(DOMNamedNodeMap::~DOMNamedNodeMap): Added deref for underlying live range.
* DOMCoreClasses.h: Added createInstance overload as described above.
* WebCoreSupport/WebEditorClient.cpp:
(WebEditorClient::shouldBeginEditing): Updated for changes to not use
live ranges. Also removed unnecessary notImplemented calls.
(WebEditorClient::shouldEndEditing): Ditto.
(WebEditorClient::discardedComposition): Ditto.
(WebEditorClient::canceledComposition): Ditto.
(WebEditorClient::didWriteSelectionToPasteboard): Ditto.
(WebEditorClient::willWriteSelectionToPasteboard): Ditto.
(WebEditorClient::getClientPasteboardData): Ditto.
(WebEditorClient::shouldDeleteRange): Ditto.
(WebEditorClient::shouldInsertNode): Ditto.
(WebEditorClient::shouldInsertText): Ditto.
(WebEditorClient::shouldChangeSelectedRange): Ditto.
(WebEditorClient::shouldApplyStyle): Ditto.
(WebEditorClient::didApplyStyle): Ditto.
(WebEditorClient::shouldMoveRangeAfterDelete): Ditto.
* WebCoreSupport/WebEditorClient.h: Updated for changes to
EditorClient.
* WebView.cpp:
(WebView::prepareCandidateWindow): Updated to not use live ranges.
(WebView::onIMERequestCharPosition): Ditto.
(WebView::compositionRangeForTesting): Ditto.
(WebView::firstRectForCharacterRangeForTesting): Ditto.
(WebView::selectedRangeForTesting): Ditto.
Tools:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
Removed duplicate install of Ahem.ttf that was leading new versions
of Xcode to fail when trying to build this.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@264692 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/editing/AlternativeTextController.cpp b/Source/WebCore/editing/AlternativeTextController.cpp
index e2e894c..9ac2e9d 100644
--- a/Source/WebCore/editing/AlternativeTextController.cpp
+++ b/Source/WebCore/editing/AlternativeTextController.cpp
@@ -243,7 +243,7 @@
VisiblePosition p = startOfWord(start, LeftWordIfOnBoundary);
VisibleSelection adjacentWords = VisibleSelection(p, start);
auto adjacentWordRange = adjacentWords.toNormalizedRange();
- m_document.editor().markAllMisspellingsAndBadGrammarInRanges({ TextCheckingType::Spelling, TextCheckingType::Replacement, TextCheckingType::ShowCorrectionPanel }, createLiveRange(adjacentWordRange), createLiveRange(adjacentWordRange), nullptr);
+ m_document.editor().markAllMisspellingsAndBadGrammarInRanges({ TextCheckingType::Spelling, TextCheckingType::Replacement, TextCheckingType::ShowCorrectionPanel }, adjacentWordRange, adjacentWordRange, WTF::nullopt);
}
break;
case AlternativeTextTypeReversion: {
@@ -653,7 +653,7 @@
#if USE(DICTATION_ALTERNATIVES)
auto& editor = m_document.editor();
auto selection = editor.selectedRange();
- if (!selection || !editor.shouldInsertText(alternativeString, selection.get(), EditorInsertAction::Pasted))
+ if (!selection || !editor.shouldInsertText(alternativeString, *selection, EditorInsertAction::Pasted))
return;
for (auto* marker : selection->startContainer().document().markers().markersInRange(*selection, DocumentMarker::DictationAlternatives))
removeDictationAlternativesForMarker(*marker);
diff --git a/Source/WebCore/editing/DeleteSelectionCommand.cpp b/Source/WebCore/editing/DeleteSelectionCommand.cpp
index 112f97b..870c4db 100644
--- a/Source/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/Source/WebCore/editing/DeleteSelectionCommand.cpp
@@ -749,9 +749,9 @@
auto range = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), endOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent());
auto rangeToBeReplaced = Range::create(document(), mergeDestination.deepEquivalent().parentAnchoredEquivalent(), mergeDestination.deepEquivalent().parentAnchoredEquivalent());
- if (!document().editor().client()->shouldMoveRangeAfterDelete(range.ptr(), rangeToBeReplaced.ptr()))
+ if (!document().editor().client()->shouldMoveRangeAfterDelete(range, rangeToBeReplaced))
return;
-
+
// moveParagraphs will insert placeholders if it removes blocks that would require their use, don't let block
// removals that it does cause the insertion of *another* placeholder.
bool needPlaceholder = m_needPlaceholder;
diff --git a/Source/WebCore/editing/Editor.cpp b/Source/WebCore/editing/Editor.cpp
index db97d37..7b5e2ee 100644
--- a/Source/WebCore/editing/Editor.cpp
+++ b/Source/WebCore/editing/Editor.cpp
@@ -507,21 +507,18 @@
return selection.isRange() && selection.rootEditableElement();
}
-bool Editor::canDeleteRange(Range* range) const
+bool Editor::canDeleteRange(const SimpleRange& range) const
{
- Node& startContainer = range->startContainer();
- Node& endContainer = range->endContainer();
-
- if (!startContainer.hasEditableStyle() || !endContainer.hasEditableStyle())
+ if (!range.start.container->hasEditableStyle() || !range.end.container->hasEditableStyle())
return false;
- if (range->collapsed()) {
- VisiblePosition start(range->startPosition(), DOWNSTREAM);
- VisiblePosition previous = start.previous();
+ if (range.collapsed()) {
// FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.
- if (previous.isNull() || previous.deepEquivalent().deprecatedNode()->rootEditableElement() != startContainer.rootEditableElement())
+ auto previous = VisiblePosition { createLegacyEditingPosition(range.start), DOWNSTREAM }.previous();
+ if (previous.isNull() || previous.deepEquivalent().deprecatedNode()->rootEditableElement() != range.start.container->rootEditableElement())
return false;
}
+
return true;
}
@@ -558,7 +555,7 @@
revealSelectionAfterEditingOperation();
} else {
if (shouldAddToKillRing)
- addRangeToKillRing(*selectedRange().get(), KillRingInsertionMode::AppendText);
+ addRangeToKillRing(*selectedRange(), KillRingInsertionMode::AppendText);
deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
// Implicitly calls revealSelectionAfterEditingOperation().
}
@@ -627,7 +624,7 @@
void Editor::pasteAsPlainTextWithPasteboard(Pasteboard& pasteboard)
{
String text = readPlainTextFromPasteboard(pasteboard);
- if (client() && client()->shouldInsertText(text, selectedRange().get(), EditorInsertAction::Pasted))
+ if (client() && client()->shouldInsertText(text, selectedRange(), EditorInsertAction::Pasted))
pasteAsPlainText(text, canSmartReplaceWithPasteboard(pasteboard));
}
@@ -652,7 +649,7 @@
return client() && client()->smartInsertDeleteEnabled() && pasteboard.canSmartReplace();
}
-bool Editor::shouldInsertFragment(DocumentFragment& fragment, Range* replacingDOMRange, EditorInsertAction givenAction)
+bool Editor::shouldInsertFragment(DocumentFragment& fragment, const Optional<SimpleRange>& replacingDOMRange, EditorInsertAction givenAction)
{
if (!client())
return false;
@@ -661,7 +658,7 @@
if (is<CharacterData>(child) && fragment.lastChild() == child)
return client()->shouldInsertText(downcast<CharacterData>(*child).data(), replacingDOMRange, givenAction);
- return client()->shouldInsertNode(&fragment, replacingDOMRange, givenAction);
+ return client()->shouldInsertNode(fragment, replacingDOMRange, givenAction);
}
void Editor::replaceSelectionWithFragment(DocumentFragment& fragment, SelectReplacement selectReplacement, SmartReplace smartReplace, MatchStyle matchStyle, EditAction editingAction, MailBlockquoteHandling mailBlockquoteHandling)
@@ -724,27 +721,21 @@
void Editor::replaceSelectionWithText(const String& text, SelectReplacement selectReplacement, SmartReplace smartReplace, EditAction editingAction)
{
- RefPtr<Range> range = selectedRange();
+ auto range = selectedRange();
if (!range)
return;
- replaceSelectionWithFragment(createFragmentFromText(*range, text), selectReplacement, smartReplace, MatchStyle::Yes, editingAction);
+ replaceSelectionWithFragment(createFragmentFromText(createLiveRange(*range), text), selectReplacement, smartReplace, MatchStyle::Yes, editingAction);
}
-RefPtr<Range> Editor::selectedRange()
+Optional<SimpleRange> Editor::selectedRange()
{
- return createLiveRange(m_document.selection().selection().toNormalizedRange());
+ return m_document.selection().selection().toNormalizedRange();
}
-bool Editor::shouldDeleteRange(Range* range) const
+bool Editor::shouldDeleteRange(const Optional<SimpleRange>& range) const
{
- if (!range || range->collapsed())
- return false;
-
- if (!canDeleteRange(range))
- return false;
-
- return client() && client()->shouldDeleteRange(range);
+ return range && !range->collapsed() && canDeleteRange(*range) && client() && client()->shouldDeleteRange(*range);
}
bool Editor::tryDHTMLCopy()
@@ -763,7 +754,7 @@
return !dispatchClipboardEvent(findEventTargetFromSelection(), ClipboardEventKind::Cut);
}
-bool Editor::shouldInsertText(const String& text, Range* range, EditorInsertAction action) const
+bool Editor::shouldInsertText(const String& text, const Optional<SimpleRange>& range, EditorInsertAction action) const
{
if (m_document.frame()->mainFrame().loader().shouldSuppressTextInputFromEditing() && action == EditorInsertAction::Typed)
return false;
@@ -980,7 +971,7 @@
dispatchInputEvent(*element, inputTypeName, inputEventData);
}
-bool Editor::shouldApplyStyle(StyleProperties* style, Range* range)
+bool Editor::shouldApplyStyle(const StyleProperties& style, const SimpleRange& range)
{
return client()->shouldApplyStyle(style, range);
}
@@ -1011,7 +1002,7 @@
if (!style || style->isEmpty() || !canEditRichly())
return;
- if (!client() || !client()->shouldApplyStyle(style, createLiveRange(m_document.selection().selection().toNormalizedRange()).get()))
+ if (!client() || !client()->shouldApplyStyle(*style, m_document.selection().selection().toNormalizedRange()))
return;
applyStyle(style, editingAction);
}
@@ -1022,7 +1013,7 @@
return;
// FIXME: This is wrong for text decorations since m_mutableStyle is empty.
- if (!client() || !client()->shouldApplyStyle(style->styleWithResolvedTextDecorations().ptr(), createLiveRange(m_document.selection().selection().toNormalizedRange()).get()))
+ if (!client() || !client()->shouldApplyStyle(style->styleWithResolvedTextDecorations(), m_document.selection().selection().toNormalizedRange()))
return;
applyStyle(WTFMove(style), editingAction, colorFilterMode);
@@ -1033,7 +1024,7 @@
if (!style || style->isEmpty() || !canEditRichly())
return;
- if (client() && client()->shouldApplyStyle(style, createLiveRange(m_document.selection().selection().toNormalizedRange()).get()))
+ if (client() && client()->shouldApplyStyle(*style, m_document.selection().selection().toNormalizedRange()))
applyParagraphStyle(style, editingAction);
}
@@ -1273,7 +1264,7 @@
if (!selection.isContentEditable())
return false;
- if (!shouldInsertText(text, createLiveRange(selection.toNormalizedRange()).get(), EditorInsertAction::Typed))
+ if (!shouldInsertText(text, selection.toNormalizedRange(), EditorInsertAction::Typed))
return true;
// FIXME: Should pass false to updateMarkersForWordsAffectedByEditing() to not remove markers if
@@ -1332,7 +1323,7 @@
if (!canEdit())
return false;
- if (!shouldInsertText("\n", createLiveRange(m_document.selection().selection().toNormalizedRange()).get(), EditorInsertAction::Typed))
+ if (!shouldInsertText("\n"_s, m_document.selection().selection().toNormalizedRange(), EditorInsertAction::Typed))
return true;
VisiblePosition caret = m_document.selection().selection().visibleStart();
@@ -1352,7 +1343,7 @@
if (!canEditRichly())
return insertLineBreak();
- if (!shouldInsertText("\n", createLiveRange(m_document.selection().selection().toNormalizedRange()).get(), EditorInsertAction::Typed))
+ if (!shouldInsertText("\n"_s, m_document.selection().selection().toNormalizedRange(), EditorInsertAction::Typed))
return true;
VisiblePosition caret = m_document.selection().selection().visibleStart();
@@ -1412,10 +1403,10 @@
void Editor::performCutOrCopy(EditorActionSpecifier action)
{
- RefPtr<Range> selection = selectedRange();
- willWriteSelectionToPasteboard(selection.get());
+ auto selection = selectedRange();
+ willWriteSelectionToPasteboard(selection);
if (action == CutAction) {
- if (!shouldDeleteRange(selection.get()))
+ if (!shouldDeleteRange(selection))
return;
updateMarkersForWordsAffectedByEditing(true);
@@ -1440,7 +1431,7 @@
writeSelectionToPasteboard(*Pasteboard::createForCopyAndPaste());
#else
// FIXME: Delete after <http://webkit.org/b/177618> lands.
- Pasteboard::createForCopyAndPaste()->writeSelection(*selection, canSmartCopyOrDelete(), *m_document.frame(), IncludeImageAltTextForDataTransfer);
+ Pasteboard::createForCopyAndPaste()->writeSelection(createLiveRange(*selection).get(), canSmartCopyOrDelete(), *m_document.frame(), IncludeImageAltTextForDataTransfer);
#endif
}
}
@@ -1532,7 +1523,7 @@
return;
}
- addRangeToKillRing(*selectedRange().get(), KillRingInsertionMode::AppendText);
+ addRangeToKillRing(*selectedRange(), KillRingInsertionMode::AppendText);
deleteSelectionWithSmartDelete(canSmartCopyOrDelete());
// clear the "start new kill ring sequence" setting, because it was set to true
@@ -1790,12 +1781,12 @@
#endif
-bool Editor::shouldEndEditing(Range* range)
+bool Editor::shouldEndEditing(const SimpleRange& range)
{
return client() && client()->shouldEndEditing(range);
}
-bool Editor::shouldBeginEditing(Range* range)
+bool Editor::shouldBeginEditing(const SimpleRange& range)
{
return client() && client()->shouldBeginEditing(range);
}
@@ -1847,7 +1838,7 @@
client()->didEndEditing();
}
-void Editor::willWriteSelectionToPasteboard(Range* range)
+void Editor::willWriteSelectionToPasteboard(const Optional<SimpleRange>& range)
{
if (client())
client()->willWriteSelectionToPasteboard(range);
@@ -1930,14 +1921,14 @@
void Editor::selectComposition()
{
- RefPtr<Range> range = compositionRange();
+ auto range = compositionRange();
if (!range)
return;
// The composition can start inside a composed character sequence, so we have to override checks.
// See <http://bugs.webkit.org/show_bug.cgi?id=15781>
VisibleSelection selection;
- selection.setWithoutValidation(range->startPosition(), range->endPosition());
+ selection.setWithoutValidation(createLegacyEditingPosition(range->start), createLegacyEditingPosition(range->end));
m_document.selection().setSelection(selection, { });
}
@@ -2491,9 +2482,9 @@
if (!textCheckingOptions.contains(TextCheckingType::Spelling))
return;
- VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
+ auto adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
auto adjacentWordRange = adjacentWords.toNormalizedRange();
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, createLiveRange(adjacentWordRange), createLiveRange(adjacentWordRange), createLiveRange(adjacentWordRange));
+ markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWordRange, adjacentWordRange, adjacentWordRange);
#else
#if !USE(AUTOMATIC_TEXT_REPLACEMENT)
UNUSED_PARAM(doReplacement);
@@ -2578,7 +2569,7 @@
// full sentence as we can, respecting boundaries where spellchecking is disabled.
fullSentenceRange->start.document().markers().removeMarkers(*fullSentenceRange, DocumentMarker::Grammar);
spellCheckingRange->start.document().markers().removeMarkers(*spellCheckingRange, DocumentMarker::Spelling);
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, createLiveRange(spellCheckingRange), createLiveRange(adjacentWordRange), createLiveRange(fullSentenceRange));
+ markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellCheckingRange, adjacentWordRange, fullSentenceRange);
return;
}
@@ -2586,8 +2577,7 @@
return;
// Check spelling of one word
- RefPtr<Range> misspellingRange;
- markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange);
+ auto misspellingRange = markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)));
// Autocorrect the misspelled word.
if (!misspellingRange)
@@ -2605,7 +2595,7 @@
m_document.selection().setSelection(newSelection);
}
- if (!m_document.editor().shouldInsertText(autocorrectedString, misspellingRange.get(), EditorInsertAction::Typed))
+ if (!m_document.editor().shouldInsertText(autocorrectedString, misspellingRange, EditorInsertAction::Typed))
return;
m_document.editor().replaceSelectionWithText(autocorrectedString, SelectReplacement::No, SmartReplace::No, EditAction::Insert);
@@ -2622,7 +2612,7 @@
#endif
}
-void Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtr<Range>& firstMisspellingRange)
+Optional<SimpleRange> Editor::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling)
{
#if !PLATFORM(IOS_FAMILY)
// This function is called with a selection already expanded to word boundaries.
@@ -2631,33 +2621,37 @@
// This function is used only for as-you-type checking, so if that's off we do nothing. Note that
// grammar checking can only be on if spell checking is also on.
if (!isContinuousSpellCheckingEnabled())
- return;
+ return WTF::nullopt;
auto searchRange = selection.toNormalizedRange();
if (!searchRange)
- return;
+ return WTF::nullopt;
// If we're not in an editable node, bail.
Node& editableNode = searchRange->startContainer();
if (!editableNode.hasEditableStyle())
- return;
+ return WTF::nullopt;
if (!isSpellCheckingEnabledFor(&editableNode))
- return;
+ return WTF::nullopt;
// Get the spell checker if it is available
if (!client())
- return;
+ return WTF::nullopt;
TextCheckingHelper checker(*client(), *searchRange);
- if (checkSpelling)
- checker.markAllMisspellings(firstMisspellingRange);
- else if (isGrammarCheckingEnabled())
+ if (checkSpelling) {
+ RefPtr<Range> firstMisspellingLiveRange;
+ checker.markAllMisspellings(firstMisspellingLiveRange);
+ return makeSimpleRange(firstMisspellingLiveRange);
+ }
+ if (isGrammarCheckingEnabled())
checker.markAllBadGrammar();
+ return WTF::nullopt;
#else
UNUSED_PARAM(selection);
UNUSED_PARAM(checkSpelling);
- UNUSED_PARAM(firstMisspellingRange);
+ return WTF::nullopt;
#endif // !PLATFORM(IOS_FAMILY)
}
@@ -2680,18 +2674,17 @@
return isSpellCheckingEnabledFor(m_document.selection().selection().start().deprecatedNode());
}
-void Editor::markMisspellings(const VisibleSelection& selection, RefPtr<Range>& firstMisspellingRange)
+Optional<SimpleRange> Editor::markMisspellings(const VisibleSelection& selection)
{
- markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange);
+ return markMisspellingsOrBadGrammar(selection, true);
}
void Editor::markBadGrammar(const VisibleSelection& selection)
{
- RefPtr<Range> firstMisspellingRange;
- markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange);
+ markMisspellingsOrBadGrammar(selection, false);
}
-void Editor::markAllMisspellingsAndBadGrammarInRanges(OptionSet<TextCheckingType> textCheckingOptions, RefPtr<Range>&& spellingRange, RefPtr<Range>&& automaticReplacementRange, RefPtr<Range>&& grammarRange)
+void Editor::markAllMisspellingsAndBadGrammarInRanges(OptionSet<TextCheckingType> textCheckingOptions, const Optional<SimpleRange>& spellingRange, const Optional<SimpleRange>& automaticReplacementRange, const Optional<SimpleRange>& grammarRange)
{
if (platformDrivenTextCheckerEnabled())
return;
@@ -2716,8 +2709,8 @@
if (!isSpellCheckingEnabledFor(&editableNode))
return;
- auto rangeToCheck = shouldMarkGrammar ? grammarRange.releaseNonNull() : spellingRange.releaseNonNull();
- TextCheckingParagraph paragraphToCheck(rangeToCheck.get());
+ auto& rangeToCheck = shouldMarkGrammar ? *grammarRange : *spellingRange;
+ TextCheckingParagraph paragraphToCheck(createLiveRange(rangeToCheck));
if (paragraphToCheck.isEmpty())
return;
@@ -2725,8 +2718,8 @@
// In asynchronous mode, we intentionally check paragraph-wide sentence.
const auto resolvedOptions = resolveTextCheckingTypeMask(editableNode, textCheckingOptions);
- auto textReplacementRange = automaticReplacementRange ? makeRef(*automaticReplacementRange) : rangeToCheck.copyRef();
- auto request = SpellCheckRequest::create(resolvedOptions, TextCheckingProcessIncremental, asynchronous ? makeRef(paragraphToCheck.paragraphRange()) : WTFMove(rangeToCheck), WTFMove(textReplacementRange), paragraphToCheck.paragraphRange());
+ auto& textReplacementRange = automaticReplacementRange ? *automaticReplacementRange : rangeToCheck;
+ auto request = SpellCheckRequest::create(resolvedOptions, TextCheckingProcessIncremental, asynchronous ? Ref<Range> { paragraphToCheck.paragraphRange() } : createLiveRange(rangeToCheck), createLiveRange(textReplacementRange), paragraphToCheck.paragraphRange());
if (!request)
return;
@@ -2759,9 +2752,9 @@
return false;
}
-void Editor::replaceRangeForSpellChecking(Range& rangeToReplace, const String& replacement)
+void Editor::replaceRangeForSpellChecking(const SimpleRange& rangeToReplace, const String& replacement)
{
- SpellingCorrectionCommand::create(rangeToReplace, replacement)->apply();
+ SpellingCorrectionCommand::create(createLiveRange(rangeToReplace), replacement)->apply();
}
static void correctSpellcheckingPreservingTextCheckingParagraph(TextCheckingParagraph& paragraph, Range& rangeToReplace, const String& replacement, CharacterRange resultCharacterRange)
@@ -2901,7 +2894,7 @@
restoreSelectionAfterChange = false;
if (canEditRichly())
CreateLinkCommand::create(document(), replacement)->apply();
- } else if (canEdit() && shouldInsertText(replacement, rangeToReplace.ptr(), EditorInsertAction::Typed)) {
+ } else if (canEdit() && shouldInsertText(replacement, makeSimpleRange(rangeToReplace), EditorInsertAction::Typed)) {
correctSpellcheckingPreservingTextCheckingParagraph(paragraph, rangeToReplace, replacement, { resultLocation, resultLength });
if (AXObjectCache* cache = document().existingAXObjectCache()) {
@@ -2954,12 +2947,12 @@
if (replacedString.isEmpty())
return;
- RefPtr<Range> selection = selectedRange();
- if (!selection || !shouldInsertText(replacedString, selection.get(), EditorInsertAction::Pasted))
+ auto selection = selectedRange();
+ if (!selection || !shouldInsertText(replacedString, selection, EditorInsertAction::Pasted))
return;
m_alternativeTextController->recordAutocorrectionResponse(AutocorrectionResponse::Reverted, replacedString, *selection);
- TextCheckingParagraph paragraph(*selection);
+ TextCheckingParagraph paragraph(createLiveRange(*selection));
replaceSelectionWithText(replacedString, SelectReplacement::No, SmartReplace::No, EditAction::Insert);
auto changedRange = paragraph.subrange(CharacterRange(paragraph.checkingStart(), replacedString.length()));
changedRange->startContainer().document().markers().addMarker(changedRange, DocumentMarker::Replacement, String());
@@ -2985,12 +2978,11 @@
if (markGrammar && isGrammarCheckingEnabled())
textCheckingOptions.add(TextCheckingType::Grammar);
auto spellCheckingRange = spellingSelection.toNormalizedRange();
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, createLiveRange(spellCheckingRange), createLiveRange(spellCheckingRange), createLiveRange(grammarSelection.toNormalizedRange()));
+ markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellCheckingRange, spellCheckingRange, grammarSelection.toNormalizedRange());
return;
}
- RefPtr<Range> firstMisspellingRange;
- markMisspellings(spellingSelection, firstMisspellingRange);
+ markMisspellings(spellingSelection);
if (markGrammar)
markBadGrammar(grammarSelection);
}
@@ -3092,23 +3084,18 @@
m_alternativeTextController->deletedAutocorrectionAtPosition(position, originalString);
}
-RefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
+Optional<SimpleRange> Editor::rangeForPoint(const IntPoint& windowPoint)
{
auto document = m_document.frame()->documentAtPoint(windowPoint);
if (!document)
- return nullptr;
-
+ return WTF::nullopt;
auto frame = document->frame();
if (!frame)
- return nullptr;
-
+ return WTF::nullopt;
auto frameView = frame->view();
if (!frameView)
- return nullptr;
-
- auto framePoint = frameView->windowToContents(windowPoint);
- auto selection = VisibleSelection { frame->visiblePositionForPoint(framePoint) };
- return createLiveRange(selection.toNormalizedRange());
+ return WTF::nullopt;
+ return VisibleSelection { frame->visiblePositionForPoint(frameView->windowToContents(windowPoint)) }.toNormalizedRange();
}
void Editor::revealSelectionAfterEditingOperation(const ScrollAlignment& alignment, RevealExtentOption revealExtentOption)
@@ -3135,17 +3122,16 @@
revealSelectionAfterEditingOperation(ScrollAlignment::alignToEdgeIfNeeded, RevealExtent);
}
-RefPtr<Range> Editor::compositionRange() const
+Optional<SimpleRange> Editor::compositionRange() const
{
if (!m_compositionNode)
- return nullptr;
+ return WTF::nullopt;
unsigned length = m_compositionNode->length();
unsigned start = std::min(m_compositionStart, length);
- unsigned end = std::min(std::max(start, m_compositionEnd), length);
- // FIXME: Why is this early return neeed?
+ unsigned end = std::clamp(m_compositionEnd, start, length);
if (start >= end)
- return nullptr;
- return Range::create(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);
+ return WTF::nullopt;
+ return { { { *m_compositionNode, start }, { *m_compositionNode, end } } };
}
bool Editor::getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const
@@ -3207,7 +3193,7 @@
}
// Insert the transposed characters.
- if (!shouldInsertText(transposed, range.get(), EditorInsertAction::Typed))
+ if (!shouldInsertText(transposed, newSelection.firstRange(), EditorInsertAction::Typed))
return;
replaceSelectionWithText(transposed, SelectReplacement::No, SmartReplace::No, EditAction::Insert);
}
@@ -3366,13 +3352,13 @@
rect.setHeight(0);
}
-IntRect Editor::firstRectForRange(Range* range) const
+IntRect Editor::firstRectForRange(const SimpleRange& range) const
{
- range->ownerDocument().updateLayout();
+ range.start.document().updateLayout();
- VisiblePosition startVisiblePosition(range->startPosition(), DOWNSTREAM);
+ VisiblePosition startVisiblePosition(createLegacyEditingPosition(range.start), DOWNSTREAM);
- if (range->collapsed()) {
+ if (range.collapsed()) {
// FIXME: Getting caret rect and removing caret width is a very roundabout way to get collapsed range location.
// In particular, width adjustment doesn't work for rotated text.
IntRect startCaretRect = RenderedPosition(startVisiblePosition).absoluteRect();
@@ -3380,10 +3366,10 @@
return startCaretRect;
}
- VisiblePosition endVisiblePosition(range->endPosition(), UPSTREAM);
+ VisiblePosition endVisiblePosition(createLegacyEditingPosition(range.end), UPSTREAM);
if (inSameLine(startVisiblePosition, endVisiblePosition))
- return enclosingIntRect(unitedBoundingBoxes(RenderObject::absoluteTextQuads(*range)));
+ return enclosingIntRect(unitedBoundingBoxes(RenderObject::absoluteTextQuads(range)));
LayoutUnit extraWidthToEndOfLine;
IntRect startCaretRect = RenderedPosition(startVisiblePosition).absoluteRect(&extraWidthToEndOfLine);
@@ -3409,7 +3395,7 @@
if (m_document.frame() && m_document.frame()->selectionChangeCallbacksDisabled())
return true;
#endif
- return client() && client()->shouldChangeSelectedRange(createLiveRange(oldSelection.toNormalizedRange()).get(), createLiveRange(newSelection.toNormalizedRange()).get(), affinity, stillSelecting);
+ return client() && client()->shouldChangeSelectedRange(oldSelection.toNormalizedRange(), newSelection.toNormalizedRange(), affinity, stillSelecting);
}
void Editor::computeAndSetTypingStyle(EditingStyle& style, EditAction editingAction)
@@ -3496,7 +3482,7 @@
VisibleSelection selection = m_document.selection().selection();
- auto resultRange = rangeOfString(target, createLiveRange(selection.firstRange()).get(), options);
+ auto resultRange = rangeOfString(target, selection.firstRange(), options);
if (!resultRange)
return false;
@@ -3508,106 +3494,109 @@
return true;
}
-RefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
+template<typename T> static auto& start(T& range, FindOptions options)
+{
+ return options.contains(Backwards) ? range.end : range.start;
+}
+
+template<typename T> static auto& end(T& range, FindOptions options)
+{
+ return options.contains(Backwards) ? range.start : range.end;
+}
+
+static BoundaryPoint makeBoundaryPointAfterNodeContents(Node& node, FindOptions options)
+{
+ return options.contains(Backwards) ? makeBoundaryPointBeforeNodeContents(node) : makeBoundaryPointAfterNodeContents(node);
+}
+
+static Optional<BoundaryPoint> makeBoundaryPointAfterNode(Node& node, FindOptions options)
+{
+ return options.contains(Backwards) ? makeBoundaryPointBeforeNode(node) : makeBoundaryPointAfterNode(node);
+}
+
+static SimpleRange collapseIfRootsDiffer(SimpleRange&& range)
+{
+ // FIXME: This helps correct results in some cases involving shadow trees. But we can incorrectly find a string with middle characters in an input element and first and last characters outside it.
+ return &range.start.container->rootNode() == &range.end.container->rootNode()
+ ? WTFMove(range) : SimpleRange { range.start, range.start };
+}
+
+Optional<SimpleRange> Editor::rangeOfString(const String& target, const Optional<SimpleRange>& referenceRange, FindOptions options)
{
if (target.isEmpty())
- return nullptr;
+ return WTF::nullopt;
// Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge
// is used depends on whether we're searching forward or backward, and whether startInSelection is set.
- RefPtr<Range> searchRange(rangeOfContents(document()));
- bool forward = !options.contains(Backwards);
bool startInReferenceRange = referenceRange && options.contains(StartInSelection);
- if (referenceRange) {
- if (forward)
- searchRange->setStart(startInReferenceRange ? referenceRange->startPosition() : referenceRange->endPosition());
- else
- searchRange->setEnd(startInReferenceRange ? referenceRange->endPosition() : referenceRange->startPosition());
- }
+ auto shadowTreeRoot = referenceRange ? referenceRange->startContainer().containingShadowRoot() : nullptr;
- RefPtr<ShadowRoot> shadowTreeRoot = referenceRange ? referenceRange->startContainer().containingShadowRoot() : nullptr;
- if (shadowTreeRoot) {
- if (forward)
- searchRange->setEnd(*shadowTreeRoot, shadowTreeRoot->countChildNodes());
- else
- searchRange->setStart(*shadowTreeRoot, 0);
- }
+ auto searchRange = makeRangeSelectingNodeContents(document());
+ if (referenceRange)
+ start(searchRange, options) = startInReferenceRange ? start(*referenceRange, options) : end(*referenceRange, options);
+ if (shadowTreeRoot)
+ end(searchRange, options) = makeBoundaryPointAfterNodeContents(*shadowTreeRoot, options);
+ auto resultRange = collapseIfRootsDiffer(findPlainText(searchRange, target, options));
- RefPtr<Range> resultRange = createLiveRange(findPlainText(*searchRange, target, options));
// If we started in the reference range and the found range exactly matches the reference range, find again.
// Build a selection with the found range to remove collapsed whitespace.
// Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInReferenceRange && areRangesEqual(createLiveRange(VisibleSelection(*resultRange).toNormalizedRange()).get(), referenceRange)) {
- searchRange = rangeOfContents(document());
- if (forward)
- searchRange->setStart(referenceRange->endPosition());
- else
- searchRange->setEnd(referenceRange->startPosition());
-
- if (shadowTreeRoot) {
- if (forward)
- searchRange->setEnd(*shadowTreeRoot, shadowTreeRoot->countChildNodes());
- else
- searchRange->setStart(*shadowTreeRoot, 0);
- }
-
- resultRange = createLiveRange(findPlainText(*searchRange, target, options));
+ if (startInReferenceRange && VisibleSelection(resultRange).toNormalizedRange() == referenceRange) {
+ searchRange = makeRangeSelectingNodeContents(document());
+ start(searchRange, options) = end(*referenceRange, options);
+ if (shadowTreeRoot)
+ end(searchRange, options) = makeBoundaryPointAfterNodeContents(*shadowTreeRoot, options);
+ resultRange = collapseIfRootsDiffer(findPlainText(searchRange, target, options));
}
// If nothing was found in the shadow tree, search in main content following the shadow tree.
- if (resultRange->collapsed() && shadowTreeRoot) {
- searchRange = rangeOfContents(document());
- if (shadowTreeRoot->shadowHost()) {
- if (forward)
- searchRange->setStartAfter(*shadowTreeRoot->shadowHost());
- else
- searchRange->setEndBefore(*shadowTreeRoot->shadowHost());
- }
-
- resultRange = createLiveRange(findPlainText(*searchRange, target, options));
+ if (resultRange.collapsed() && shadowTreeRoot) {
+ searchRange = makeRangeSelectingNodeContents(document());
+ if (auto host = shadowTreeRoot->shadowHost())
+ start(searchRange, options) = *makeBoundaryPointAfterNode(*host, options);
+ resultRange = collapseIfRootsDiffer(findPlainText(searchRange, target, options));
}
// If we didn't find anything and we're wrapping, search again in the entire document (this will
// redundantly re-search the area already searched in some cases).
- if (resultRange->collapsed() && options.contains(WrapAround)) {
- resultRange = createLiveRange(findPlainText(rangeOfContents(document()), target, options));
+ if (resultRange.collapsed() && options.contains(WrapAround)) {
+ resultRange = collapseIfRootsDiffer(findPlainText(rangeOfContents(document()), target, options));
// We used to return false here if we ended up with the same range that we started with
// (e.g., the reference range was already the only instance of this text). But we decided that
// this should be a success case instead, so we'll just fall through in that case.
}
- return resultRange->collapsed() ? nullptr : resultRange;
+ return resultRange.collapsed() ? WTF::nullopt : makeOptional(resultRange);
}
-static bool isFrameInRange(Frame& frame, Range& range)
+static bool isFrameInRange(Frame& frame, const SimpleRange& range)
{
for (auto* ownerElement = frame.ownerElement(); ownerElement; ownerElement = ownerElement->document().ownerElement()) {
- if (&ownerElement->document() == &range.ownerDocument()) {
- auto result = range.intersectsNode(*ownerElement);
+ if (&ownerElement->document() == &range.start.document()) {
+ auto result = createLiveRange(range)->intersectsNode(*ownerElement);
return !result.hasException() && result.releaseReturnValue();
}
}
return false;
}
-unsigned Editor::countMatchesForText(const String& target, Range* range, FindOptions options, unsigned limit, bool markMatches, Vector<RefPtr<Range>>* matches)
+unsigned Editor::countMatchesForText(const String& target, const Optional<SimpleRange>& range, FindOptions options, unsigned limit, bool markMatches, Vector<SimpleRange>* matches)
{
if (target.isEmpty())
return 0;
- RefPtr<Range> searchRange;
+ Optional<SimpleRange> searchRange;
if (range) {
- if (&range->ownerDocument() == &document())
- searchRange = range;
+ if (&range->start.document() == &document())
+ searchRange = *range;
else if (!isFrameInRange(*m_document.frame(), *range))
return 0;
}
if (!searchRange)
- searchRange = rangeOfContents(document());
+ searchRange = makeRangeSelectingNodeContents(document());
- Node& originalEndContainer = searchRange->endContainer();
- int originalEndOffset = searchRange->endOffset();
+ auto originalEnd = searchRange->end;
unsigned matchCount = 0;
do {
@@ -3616,8 +3605,8 @@
if (!resultRange.start.container->isInShadowTree())
break;
- searchRange->setStartAfter(*resultRange.start.container->shadowHost());
- searchRange->setEnd(originalEndContainer, originalEndOffset);
+ searchRange->start = makeBoundaryPointAfterNodeContents(*resultRange.start.container->shadowHost());
+ searchRange->end = originalEnd;
continue;
}
@@ -3632,15 +3621,14 @@
if (limit > 0 && matchCount >= limit)
break;
- // Set the new start for the search range to be the end of the previous
- // result range. There is no need to use a VisiblePosition here,
- // since findPlainText will use a TextIterator to go over the visible
- // text nodes.
- searchRange->setStart(WTFMove(resultRange.end.container), resultRange.end.offset);
+ // Set the new start for the search range to be the end of the previous result range.
+ // There is no need to use VisiblePosition here: findPlainText will use TextIterator to go over visible text nodes.
+ searchRange->start = WTFMove(resultRange.end);
- Node* shadowTreeRoot = searchRange->shadowRoot();
- if (searchRange->collapsed() && shadowTreeRoot)
- searchRange->setEnd(*shadowTreeRoot, shadowTreeRoot->countChildNodes());
+ if (searchRange->collapsed()) {
+ if (auto shadowTreeRoot = searchRange->start.container->containingShadowRoot())
+ searchRange->end = makeBoundaryPointAfterNodeContents(*shadowTreeRoot);
+ }
} while (true);
return matchCount;
@@ -3949,22 +3937,24 @@
return plainText(*range);
}
-RefPtr<Range> Editor::contextRangeForCandidateRequest() const
+Optional<SimpleRange> Editor::contextRangeForCandidateRequest() const
{
- const VisibleSelection& selection = m_document.selection().selection();
- return makeRange(startOfParagraph(selection.visibleStart()), endOfParagraph(selection.visibleEnd()));
+ auto& selection = m_document.selection().selection();
+ auto start = makeBoundaryPoint(startOfParagraph(selection.visibleStart()));
+ auto end = makeBoundaryPoint(endOfParagraph(selection.visibleEnd()));
+ if (!start || !end)
+ return WTF::nullopt;
+ return { { *start, *end } };
}
-RefPtr<Range> Editor::rangeForTextCheckingResult(const TextCheckingResult& result) const
+Optional<SimpleRange> Editor::rangeForTextCheckingResult(const TextCheckingResult& result) const
{
if (!result.range.length)
- return nullptr;
-
- RefPtr<Range> contextRange = contextRangeForCandidateRequest();
+ return WTF::nullopt;
+ auto contextRange = contextRangeForCandidateRequest();
if (!contextRange)
- return nullptr;
-
- return createLiveRange(resolveCharacterRange(*contextRange, result.range));
+ return WTF::nullopt;
+ return resolveCharacterRange(*contextRange, result.range);
}
void Editor::scheduleEditorUIUpdate()
@@ -4234,8 +4224,8 @@
m_isHandlingAcceptedCandidate = true;
if (auto range = rangeForTextCheckingResult(acceptedCandidate)) {
- if (shouldInsertText(acceptedCandidate.replacement, range.get(), EditorInsertAction::Typed))
- ReplaceRangeWithTextCommand::create(range.get(), acceptedCandidate.replacement)->apply();
+ if (shouldInsertText(acceptedCandidate.replacement, range, EditorInsertAction::Typed))
+ ReplaceRangeWithTextCommand::create(createLiveRange(range), acceptedCandidate.replacement)->apply();
} else
insertText(acceptedCandidate.replacement, nullptr);
@@ -4267,16 +4257,16 @@
m_document.selection().setShouldShowBlockCursor(m_overwriteModeEnabled);
}
-RefPtr<Range> Editor::adjustedSelectionRange()
+Optional<SimpleRange> Editor::adjustedSelectionRange()
{
- // FIXME: Why do we need to adjust the selection to include the anchor tag it's in?
- // Whoever wrote this code originally forgot to leave us a comment explaining the rationale.
- RefPtr<Range> range = selectedRange();
- Node* commonAncestor = range->commonAncestorContainer();
- ASSERT(commonAncestor);
- auto* enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonAncestor), HTMLNames::aTag);
- if (enclosingAnchor && comparePositions(firstPositionInOrBeforeNode(range->startPosition().anchorNode()), range->startPosition()) >= 0)
- range->setStart(*enclosingAnchor, 0);
+ // FIXME: Why do we need to adjust the selection to include the anchor tag it's in? Whoever wrote this code originally forgot to leave us a comment explaining the rationale.
+ auto range = selectedRange();
+ if (range) {
+ if (auto enclosingAnchor = enclosingElementWithTag(firstPositionInNode(commonInclusiveAncestor(range->start.container, range->end.container).get()), HTMLNames::aTag)) {
+ if (comparePositions(firstPositionInOrBeforeNode(range->start.container.ptr()), createLegacyEditingPosition(range->start)) >= 0)
+ range->start = makeBoundaryPointBeforeNodeContents(*enclosingAnchor);
+ }
+ }
return range;
}
diff --git a/Source/WebCore/editing/Editor.h b/Source/WebCore/editing/Editor.h
index 111440c..a97cb42 100644
--- a/Source/WebCore/editing/Editor.h
+++ b/Source/WebCore/editing/Editor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -214,10 +214,10 @@
WEBCORE_EXPORT void outdent();
void transpose();
- bool shouldInsertFragment(DocumentFragment&, Range*, EditorInsertAction);
- bool shouldInsertText(const String&, Range*, EditorInsertAction) const;
- WEBCORE_EXPORT bool shouldDeleteRange(Range*) const;
- bool shouldApplyStyle(StyleProperties*, Range*);
+ bool shouldInsertFragment(DocumentFragment&, const Optional<SimpleRange>&, EditorInsertAction);
+ bool shouldInsertText(const String&, const Optional<SimpleRange>&, EditorInsertAction) const;
+ WEBCORE_EXPORT bool shouldDeleteRange(const Optional<SimpleRange>&) const;
+ bool shouldApplyStyle(const StyleProperties&, const SimpleRange&);
void respondToChangedContents(const VisibleSelection& endingSelection);
@@ -323,16 +323,16 @@
bool isSpellCheckingEnabledInFocusedNode() const;
bool isSpellCheckingEnabledFor(Node*) const;
WEBCORE_EXPORT void markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping, bool doReplacement);
- void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
+ Optional<SimpleRange> markMisspellings(const VisibleSelection&); // Returns first mispelling range.
void markBadGrammar(const VisibleSelection&);
void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
void markAndReplaceFor(const SpellCheckRequest&, const Vector<TextCheckingResult>&);
- WEBCORE_EXPORT void replaceRangeForSpellChecking(Range&, const String&);
+ WEBCORE_EXPORT void replaceRangeForSpellChecking(const SimpleRange&, const String&);
bool isOverwriteModeEnabled() const { return m_overwriteModeEnabled; }
WEBCORE_EXPORT void toggleOverwriteModeEnabled();
- void markAllMisspellingsAndBadGrammarInRanges(OptionSet<TextCheckingType>, RefPtr<Range>&& spellingRange, RefPtr<Range>&& automaticReplacementRange, RefPtr<Range>&& grammarRange);
+ void markAllMisspellingsAndBadGrammarInRanges(OptionSet<TextCheckingType>, const Optional<SimpleRange>& spellingRange, const Optional<SimpleRange>& automaticReplacementRange, const Optional<SimpleRange>& grammarRange);
#if PLATFORM(IOS_FAMILY)
NO_RETURN_DUE_TO_ASSERT
#endif
@@ -344,8 +344,8 @@
void showSpellingGuessPanel();
bool spellingPanelIsShowing();
- bool shouldBeginEditing(Range*);
- bool shouldEndEditing(Range*);
+ bool shouldBeginEditing(const SimpleRange&);
+ bool shouldEndEditing(const SimpleRange&);
void clearUndoRedoOperations();
bool canUndo() const;
@@ -357,7 +357,7 @@
void didBeginEditing();
void didEndEditing();
- void willWriteSelectionToPasteboard(Range*);
+ void willWriteSelectionToPasteboard(const Optional<SimpleRange>&);
void didWriteSelectionToPasteboard();
void showFontPanel();
@@ -381,7 +381,7 @@
WEBCORE_EXPORT void confirmComposition(const String&); // if no existing composition, replaces selection
WEBCORE_EXPORT void cancelComposition();
bool cancelCompositionIfSelectionIsInvalid();
- WEBCORE_EXPORT RefPtr<Range> compositionRange() const;
+ WEBCORE_EXPORT Optional<SimpleRange> compositionRange() const;
WEBCORE_EXPORT bool getCompositionSelection(unsigned& selectionStart, unsigned& selectionEnd) const;
// getting international text input composition state (for use by InlineTextBox)
@@ -401,7 +401,7 @@
WEBCORE_EXPORT void setIgnoreSelectionChanges(bool, RevealSelection shouldRevealExistingSelection = RevealSelection::Yes);
bool ignoreSelectionChanges() const { return m_ignoreSelectionChanges; }
- WEBCORE_EXPORT RefPtr<Range> rangeForPoint(const IntPoint& windowPoint);
+ WEBCORE_EXPORT Optional<SimpleRange> rangeForPoint(const IntPoint& windowPoint);
void clear();
@@ -412,7 +412,7 @@
EditingBehavior behavior() const;
- RefPtr<Range> selectedRange();
+ Optional<SimpleRange> selectedRange();
#if PLATFORM(IOS_FAMILY)
WEBCORE_EXPORT void confirmMarkedText();
@@ -447,7 +447,7 @@
String selectedTextForDataTransfer() const;
WEBCORE_EXPORT bool findString(const String&, FindOptions);
- WEBCORE_EXPORT RefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
+ WEBCORE_EXPORT Optional<SimpleRange> rangeOfString(const String&, const Optional<SimpleRange>& searchRange, FindOptions);
const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
void setMark(const VisibleSelection&);
@@ -456,13 +456,13 @@
WEBCORE_EXPORT void computeAndSetTypingStyle(StyleProperties& , EditAction = EditAction::Unspecified);
WEBCORE_EXPORT void applyEditingStyleToBodyElement() const;
- WEBCORE_EXPORT IntRect firstRectForRange(Range*) const;
+ WEBCORE_EXPORT IntRect firstRectForRange(const SimpleRange&) const;
void selectionWillChange();
void respondToChangedSelection(const VisibleSelection& oldSelection, OptionSet<FrameSelection::SetSelectionOption>);
WEBCORE_EXPORT void updateEditorUINowIfScheduled();
bool shouldChangeSelection(const VisibleSelection& oldSelection, const VisibleSelection& newSelection, EAffinity, bool stillSelecting) const;
- WEBCORE_EXPORT unsigned countMatchesForText(const String&, Range*, FindOptions, unsigned limit, bool markMatches, Vector<RefPtr<Range>>*);
+ WEBCORE_EXPORT unsigned countMatchesForText(const String&, const Optional<SimpleRange>&, FindOptions, unsigned limit, bool markMatches, Vector<SimpleRange>*);
bool markedTextMatchesAreHighlighted() const;
WEBCORE_EXPORT void setMarkedTextMatchesAreHighlighted(bool);
@@ -546,8 +546,8 @@
WEBCORE_EXPORT String stringForCandidateRequest() const;
WEBCORE_EXPORT void handleAcceptedCandidate(TextCheckingResult);
- WEBCORE_EXPORT RefPtr<Range> contextRangeForCandidateRequest() const;
- RefPtr<Range> rangeForTextCheckingResult(const TextCheckingResult&) const;
+ WEBCORE_EXPORT Optional<SimpleRange> contextRangeForCandidateRequest() const;
+ Optional<SimpleRange> rangeForTextCheckingResult(const TextCheckingResult&) const;
bool isHandlingAcceptedCandidate() const { return m_isHandlingAcceptedCandidate; }
void setIsGettingDictionaryPopupInfo(bool b) { m_isGettingDictionaryPopupInfo = b; }
@@ -580,7 +580,7 @@
private:
Document& document() const { return m_document; }
- bool canDeleteRange(Range*) const;
+ bool canDeleteRange(const SimpleRange&) const;
bool canSmartReplaceWithPasteboard(Pasteboard&);
void pasteAsPlainTextWithPasteboard(Pasteboard&);
void pasteWithPasteboard(Pasteboard*, OptionSet<PasteOption>);
@@ -589,7 +589,7 @@
void quoteFragmentForPasting(DocumentFragment&);
void revealSelectionAfterEditingOperation(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
- void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
+ Optional<SimpleRange> markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling);
OptionSet<TextCheckingType> resolveTextCheckingTypeMask(const Node& rootEditableElement, OptionSet<TextCheckingType>);
WEBCORE_EXPORT String selectedText(TextIteratorBehavior) const;
@@ -609,7 +609,7 @@
bool unifiedTextCheckerEnabled() const;
- RefPtr<Range> adjustedSelectionRange();
+ Optional<SimpleRange> adjustedSelectionRange();
#if PLATFORM(COCOA)
RefPtr<SharedBuffer> selectionInWebArchiveFormat();
diff --git a/Source/WebCore/editing/EditorCommand.cpp b/Source/WebCore/editing/EditorCommand.cpp
index d6ea426..440fcf6 100644
--- a/Source/WebCore/editing/EditorCommand.cpp
+++ b/Source/WebCore/editing/EditorCommand.cpp
@@ -176,15 +176,15 @@
static bool expandSelectionToGranularity(Frame& frame, TextGranularity granularity)
{
VisibleSelection selection = frame.selection().selection();
+ auto oldRange = selection.toNormalizedRange();
selection.expandUsingGranularity(granularity);
auto newRange = selection.toNormalizedRange();
if (!newRange || newRange->collapsed())
return false;
- auto oldRange = selection.toNormalizedRange();
auto affinity = selection.affinity();
- if (!frame.editor().client()->shouldChangeSelectedRange(createLiveRange(oldRange).get(), createLiveRange(newRange).get(), affinity, false))
+ if (!frame.editor().client()->shouldChangeSelectedRange(*oldRange, *newRange, affinity, false))
return false;
- frame.selection().setSelectedRange(createLiveRange(newRange).get(), affinity, FrameSelection::ShouldCloseTyping::Yes);
+ frame.selection().setSelectedRange(createLiveRange(*newRange).ptr(), affinity, FrameSelection::ShouldCloseTyping::Yes);
return true;
}
@@ -226,11 +226,11 @@
return static_cast<unsigned>(Scrollbar::pageStep(height));
}
-static RefPtr<Range> unionDOMRanges(Range& a, Range& b)
+static SimpleRange unionRanges(const SimpleRange& a, const SimpleRange& b)
{
- Range& start = a.compareBoundaryPoints(Range::START_TO_START, b).releaseReturnValue() <= 0 ? a : b;
- Range& end = a.compareBoundaryPoints(Range::END_TO_END, b).releaseReturnValue() <= 0 ? b : a;
- return Range::create(a.ownerDocument(), &start.startContainer(), start.startOffset(), &end.endContainer(), end.endOffset());
+ auto& start = createLiveRange(a)->compareBoundaryPoints(Range::START_TO_START, createLiveRange(b)).releaseReturnValue() <= 0 ? a : b;
+ auto& end = createLiveRange(a)->compareBoundaryPoints(Range::END_TO_END, createLiveRange(b)).releaseReturnValue() <= 0 ? b : a;
+ return { start.start, end.end };
}
// Execute command functions
@@ -354,7 +354,7 @@
auto mark = frame.editor().mark().toNormalizedRange();
auto& selection = frame.selection();
if (mark && frame.editor().selectedRange()) {
- bool selected = selection.setSelectedRange(unionDOMRanges(createLiveRange(*mark), *frame.editor().selectedRange()).get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes);
+ bool selected = selection.setSelectedRange(createLiveRange(unionRanges(*mark, *frame.editor().selectedRange())).ptr(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes);
ASSERT(selected);
if (!selected)
return false;
@@ -1056,7 +1056,7 @@
PAL::systemBeep();
return false;
}
- frame.selection().setSelectedRange(unionDOMRanges(createLiveRange(*mark), *selection).get(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes);
+ frame.selection().setSelectedRange(createLiveRange(unionRanges(*mark, *selection)).ptr(), DOWNSTREAM, FrameSelection::ShouldCloseTyping::Yes);
return true;
}
diff --git a/Source/WebCore/editing/FrameSelection.cpp b/Source/WebCore/editing/FrameSelection.cpp
index 1475fe5..52a67a8 100644
--- a/Source/WebCore/editing/FrameSelection.cpp
+++ b/Source/WebCore/editing/FrameSelection.cpp
@@ -2311,7 +2311,7 @@
if (m_document->frame() && m_document->frame()->selectionChangeCallbacksDisabled())
return true;
#endif
- return m_document->editor().client()->shouldDeleteRange(createLiveRange(selection.toNormalizedRange()).get());
+ return m_document->editor().client()->shouldDeleteRange(selection.toNormalizedRange());
}
FloatRect FrameSelection::selectionBounds(ClipToVisibleContent clipToVisibleContent) const
diff --git a/Source/WebCore/editing/cocoa/EditorCocoa.mm b/Source/WebCore/editing/cocoa/EditorCocoa.mm
index c5cbc3f..eefe8fd 100644
--- a/Source/WebCore/editing/cocoa/EditorCocoa.mm
+++ b/Source/WebCore/editing/cocoa/EditorCocoa.mm
@@ -88,14 +88,13 @@
void Editor::getPasteboardTypesAndDataForAttachment(Element& element, Vector<String>& outTypes, Vector<RefPtr<SharedBuffer>>& outData)
{
- auto& document = element.document();
- auto elementRange = Range::create(document, { &element, Position::PositionIsBeforeAnchor }, { &element, Position::PositionIsAfterAnchor });
- client()->getClientPasteboardDataForRange(elementRange.ptr(), outTypes, outData);
+ auto elementRange = makeRangeSelectingNode(element);
+ client()->getClientPasteboardData(elementRange, outTypes, outData);
outTypes.append(PasteboardCustomData::cocoaType());
- outData.append(PasteboardCustomData { document.originIdentifierForPasteboard(), { } }.createSharedBuffer());
+ outData.append(PasteboardCustomData { element.document().originIdentifierForPasteboard(), { } }.createSharedBuffer());
- if (auto archive = LegacyWebArchive::create(elementRange.ptr())) {
+ if (auto archive = LegacyWebArchive::create(createLiveRange(elementRange).get())) {
if (auto webArchiveData = archive->rawDataRepresentation()) {
outTypes.append(WebArchivePboardType);
outData.append(SharedBuffer::create(webArchiveData.get()));
@@ -123,7 +122,7 @@
content.dataInRTFDFormat = [string containsAttachments] ? dataInRTFDFormat(string.get()) : nullptr;
content.dataInRTFFormat = dataInRTFFormat(string.get());
content.dataInAttributedStringFormat = archivedDataForAttributedString(string.get());
- client()->getClientPasteboardDataForRange(selectedRange().get(), content.clientTypes, content.clientData);
+ client()->getClientPasteboardData(selectedRange(), content.clientTypes, content.clientData);
}
content.dataInHTMLFormat = selectionInHTMLFormat();
content.dataInStringFormat = stringSelectionForPasteboardWithImageAltText();
@@ -144,7 +143,7 @@
webContent.dataInAttributedStringFormat = archivedDataForAttributedString(string.get());
webContent.dataInHTMLFormat = selectionInHTMLFormat();
webContent.dataInStringFormat = stringSelectionForPasteboardWithImageAltText();
- client()->getClientPasteboardDataForRange(selectedRange().get(), webContent.clientTypes, webContent.clientData);
+ client()->getClientPasteboardData(selectedRange(), webContent.clientTypes, webContent.clientData);
pasteboardWriterData.setWebContent(WTFMove(webContent));
}
@@ -184,12 +183,12 @@
if (m_document.selection().selection().isContentRichlyEditable()) {
if (auto fragment = createFragmentAndAddResources(*m_document.frame(), attributedString)) {
- if (shouldInsertFragment(*fragment, selectedRange().get(), EditorInsertAction::Pasted))
+ if (shouldInsertFragment(*fragment, selectedRange(), EditorInsertAction::Pasted))
pasteAsFragment(fragment.releaseNonNull(), false, false, mailBlockquoteHandling);
}
} else {
String text = attributedString.string;
- if (shouldInsertText(text, selectedRange().get(), EditorInsertAction::Pasted))
+ if (shouldInsertText(text, selectedRange(), EditorInsertAction::Pasted))
pasteAsPlainText(text, false);
}
}
diff --git a/Source/WebCore/editing/gtk/EditorGtk.cpp b/Source/WebCore/editing/gtk/EditorGtk.cpp
index 99aa119..da7e941 100644
--- a/Source/WebCore/editing/gtk/EditorGtk.cpp
+++ b/Source/WebCore/editing/gtk/EditorGtk.cpp
@@ -50,17 +50,17 @@
void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
- RefPtr<Range> range = selectedRange();
+ auto range = selectedRange();
if (!range)
return;
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = webContentFromPasteboard(*pasteboard, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+ auto fragment = webContentFromPasteboard(*pasteboard, *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
if (fragment && options.contains(PasteOption::AsQuotation))
quoteFragmentForPasting(*fragment);
- if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
+ if (fragment && shouldInsertFragment(*fragment, *range, EditorInsertAction::Pasted))
pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
diff --git a/Source/WebCore/editing/ios/EditorIOS.mm b/Source/WebCore/editing/ios/EditorIOS.mm
index 312325f..6c25479 100644
--- a/Source/WebCore/editing/ios/EditorIOS.mm
+++ b/Source/WebCore/editing/ios/EditorIOS.mm
@@ -206,30 +206,26 @@
pasteboardImage.resourceMIMEType = pasteboard.resourceMIMEType(cachedImage->response().mimeType());
pasteboardImage.resourceData = cachedImage->resourceBuffer();
- if (!pasteboard.isStatic()) {
- Position beforeImagePosition(&imageElement, Position::PositionIsBeforeAnchor);
- Position afterImagePosition(&imageElement, Position::PositionIsAfterAnchor);
- auto imageRange = Range::create(imageElement.document(), beforeImagePosition, afterImagePosition);
- client()->getClientPasteboardDataForRange(imageRange.ptr(), pasteboardImage.clientTypes, pasteboardImage.clientData);
- }
+ if (!pasteboard.isStatic())
+ client()->getClientPasteboardData(makeRangeSelectingNode(imageElement), pasteboardImage.clientTypes, pasteboardImage.clientData);
pasteboard.write(pasteboardImage);
}
void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
- RefPtr<Range> range = selectedRange();
+ auto range = selectedRange();
bool allowPlainText = options.contains(PasteOption::AllowPlainText);
WebContentReader reader(*m_document.frame(), *range, allowPlainText);
int numberOfPasteboardItems = client()->getPasteboardItemsCount();
for (int i = 0; i < numberOfPasteboardItems; ++i) {
- RefPtr<DocumentFragment> fragment = client()->documentFragmentFromDelegate(i);
+ auto fragment = client()->documentFragmentFromDelegate(i);
if (!fragment)
continue;
reader.addFragment(fragment.releaseNonNull());
}
- RefPtr<DocumentFragment> fragment = reader.fragment;
+ auto fragment = WTFMove(reader.fragment);
if (!fragment) {
bool chosePlainTextIgnored;
fragment = webContentFromPasteboard(*pasteboard, *range, allowPlainText, chosePlainTextIgnored);
@@ -238,7 +234,7 @@
if (fragment && options.contains(PasteOption::AsQuotation))
quoteFragmentForPasting(*fragment);
- if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
+ if (fragment && shouldInsertFragment(*fragment, range, EditorInsertAction::Pasted))
pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), false, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
diff --git a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
index 12fd6a4..0b7c262 100644
--- a/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
+++ b/Source/WebCore/editing/libwpe/EditorLibWPE.cpp
@@ -37,7 +37,7 @@
namespace WebCore {
-static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, Range& range, bool allowPlainText, bool& chosePlainText)
+static RefPtr<DocumentFragment> createFragmentFromPasteboardData(Pasteboard& pasteboard, Frame& frame, const SimpleRange& range, bool allowPlainText, bool& chosePlainText)
{
chosePlainText = false;
@@ -47,8 +47,7 @@
if (types.contains("text/html;charset=utf-8") && frame.document()) {
String markup = pasteboard.readString("text/html;charset=utf-8");
- if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(*frame.document(), markup, emptyString(), DisallowScriptingAndPluginContent))
- return fragment;
+ return createFragmentFromMarkup(*frame.document(), markup, emptyString(), DisallowScriptingAndPluginContent);
}
if (!allowPlainText)
@@ -56,8 +55,7 @@
if (types.contains("text/plain;charset=utf-8")) {
chosePlainText = true;
- if (RefPtr<DocumentFragment> fragment = createFragmentFromText(range, pasteboard.readString("text/plain;charset=utf-8")))
- return fragment;
+ return createFragmentFromText(createLiveRange(range).get(), pasteboard.readString("text/plain;charset=utf-8"));
}
return nullptr;
@@ -79,17 +77,17 @@
void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
- RefPtr<Range> range = selectedRange();
+ auto range = selectedRange();
if (!range)
return;
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = createFragmentFromPasteboardData(*pasteboard, *m_document.frame(), *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+ auto fragment = createFragmentFromPasteboardData(*pasteboard, *m_document.frame(), *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
if (fragment && options.contains(PasteOption::AsQuotation))
quoteFragmentForPasting(*fragment);
- if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
+ if (fragment && shouldInsertFragment(*fragment, *range, EditorInsertAction::Pasted))
pasteAsFragment(*fragment, canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}
diff --git a/Source/WebCore/editing/mac/EditorMac.mm b/Source/WebCore/editing/mac/EditorMac.mm
index 1cd8c39..ba31c18 100644
--- a/Source/WebCore/editing/mac/EditorMac.mm
+++ b/Source/WebCore/editing/mac/EditorMac.mm
@@ -80,7 +80,7 @@
void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
- RefPtr<Range> range = selectedRange();
+ auto range = selectedRange();
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
// FIXME: How can this hard-coded pasteboard name be right, given that the passed-in pasteboard has a name?
@@ -93,7 +93,7 @@
if (fragment && options.contains(PasteOption::AsQuotation))
quoteFragmentForPasting(*fragment);
- if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
+ if (fragment && shouldInsertFragment(*fragment, range, EditorInsertAction::Pasted))
pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), false, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote );
client()->setInsertionPasteboard(String());
@@ -159,7 +159,7 @@
bool chosePlainText;
if (auto fragment = webContentFromPasteboard(pasteboard, range, true, chosePlainText)) {
maybeCopyNodeAttributesToFragment(*node, *fragment);
- if (shouldInsertFragment(*fragment, createLiveRange(range).ptr(), EditorInsertAction::Pasted))
+ if (shouldInsertFragment(*fragment, range, EditorInsertAction::Pasted))
pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(pasteboard), false, MailBlockquoteHandling::IgnoreBlockquote);
}
@@ -176,11 +176,9 @@
RefPtr<SharedBuffer> Editor::dataSelectionForPasteboard(const String& pasteboardType)
{
- // FIXME: The interface to this function is awkward. We'd probably be better off with three separate functions.
- // As of this writing, this is only used in WebKit2 to implement the method -[WKView writeSelectionToPasteboard:types:],
- // which is only used to support OS X services.
+ // FIXME: The interface to this function is awkward. We'd probably be better off with three separate functions. As of this writing, this is only used in WebKit2 to implement the method -[WKView writeSelectionToPasteboard:types:], which is only used to support OS X services.
- // FIXME: Does this function really need to use adjustedSelectionRange()? Because writeSelectionToPasteboard() just uses selectedRange().
+ // FIXME: Does this function really need to use adjustedSelectionRange()? Because writeSelectionToPasteboard() just uses selectedRange(). This is the only function in WebKit that uses adjustedSelectionRange.
if (!canCopy())
return nullptr;
diff --git a/Source/WebCore/editing/win/EditorWin.cpp b/Source/WebCore/editing/win/EditorWin.cpp
index c796bfa..93ddeaf 100644
--- a/Source/WebCore/editing/win/EditorWin.cpp
+++ b/Source/WebCore/editing/win/EditorWin.cpp
@@ -37,17 +37,17 @@
void Editor::pasteWithPasteboard(Pasteboard* pasteboard, OptionSet<PasteOption> options)
{
- RefPtr<Range> range = selectedRange();
+ auto range = selectedRange();
if (!range)
return;
bool chosePlainText;
- RefPtr<DocumentFragment> fragment = pasteboard->documentFragment(*m_document.frame(), *range, options.contains(PasteOption::AllowPlainText), chosePlainText);
+ auto fragment = pasteboard->documentFragment(*m_document.frame(), createLiveRange(*range), options.contains(PasteOption::AllowPlainText), chosePlainText);
if (fragment && options.contains(PasteOption::AsQuotation))
quoteFragmentForPasting(*fragment);
- if (fragment && shouldInsertFragment(*fragment, range.get(), EditorInsertAction::Pasted))
+ if (fragment && shouldInsertFragment(*fragment, *range, EditorInsertAction::Pasted))
pasteAsFragment(fragment.releaseNonNull(), canSmartReplaceWithPasteboard(*pasteboard), chosePlainText, options.contains(PasteOption::IgnoreMailBlockquote) ? MailBlockquoteHandling::IgnoreBlockquote : MailBlockquoteHandling::RespectBlockquote);
}