summaryrefslogtreecommitdiff
path: root/Source/WebCore/editing/AlternativeTextController.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/editing/AlternativeTextController.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/editing/AlternativeTextController.cpp')
-rw-r--r--Source/WebCore/editing/AlternativeTextController.cpp227
1 files changed, 109 insertions, 118 deletions
diff --git a/Source/WebCore/editing/AlternativeTextController.cpp b/Source/WebCore/editing/AlternativeTextController.cpp
index 31ca46ff2..15312a541 100644
--- a/Source/WebCore/editing/AlternativeTextController.cpp
+++ b/Source/WebCore/editing/AlternativeTextController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
@@ -11,10 +11,10 @@
* 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 APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS 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
@@ -32,26 +32,28 @@
#include "Editor.h"
#include "Element.h"
#include "Event.h"
-#include "ExceptionCodePlaceholder.h"
#include "FloatQuad.h"
#include "Frame.h"
#include "FrameView.h"
#include "Page.h"
+#include "RenderedDocumentMarker.h"
#include "SpellingCorrectionCommand.h"
#include "TextCheckerClient.h"
#include "TextCheckingHelper.h"
#include "TextEvent.h"
+#include "TextIterator.h"
#include "VisibleUnits.h"
#include "htmlediting.h"
#include "markup.h"
+#include <wtf/NeverDestroyed.h>
namespace WebCore {
class AutocorrectionAlternativeDetails : public AlternativeTextDetails {
public:
- static PassRefPtr<AutocorrectionAlternativeDetails> create(const String& replacementString)
+ static Ref<AutocorrectionAlternativeDetails> create(const String& replacementString)
{
- return adoptRef(new AutocorrectionAlternativeDetails(replacementString));
+ return adoptRef(*new AutocorrectionAlternativeDetails(replacementString));
}
const String& replacementString() const { return m_replacementString; }
@@ -65,9 +67,9 @@ private:
class DictationAlternativeDetails : public AlternativeTextDetails {
public:
- static PassRefPtr<DictationAlternativeDetails> create(uint64_t dictationContext)
+ static Ref<DictationAlternativeDetails> create(uint64_t dictationContext)
{
- return adoptRef(new DictationAlternativeDetails(dictationContext));
+ return adoptRef(*new DictationAlternativeDetails(dictationContext));
}
uint64_t dictationContext() const { return m_dictationContext; }
@@ -84,35 +86,35 @@ private:
static const Vector<DocumentMarker::MarkerType>& markerTypesForAutocorrection()
{
- DEFINE_STATIC_LOCAL(Vector<DocumentMarker::MarkerType>, markerTypesForAutoCorrection, ());
- if (markerTypesForAutoCorrection.isEmpty()) {
- markerTypesForAutoCorrection.append(DocumentMarker::Replacement);
- markerTypesForAutoCorrection.append(DocumentMarker::CorrectionIndicator);
- markerTypesForAutoCorrection.append(DocumentMarker::SpellCheckingExemption);
- markerTypesForAutoCorrection.append(DocumentMarker::Autocorrected);
+ static NeverDestroyed<Vector<DocumentMarker::MarkerType>> markerTypesForAutoCorrection;
+ if (markerTypesForAutoCorrection.get().isEmpty()) {
+ markerTypesForAutoCorrection.get().append(DocumentMarker::Replacement);
+ markerTypesForAutoCorrection.get().append(DocumentMarker::CorrectionIndicator);
+ markerTypesForAutoCorrection.get().append(DocumentMarker::SpellCheckingExemption);
+ markerTypesForAutoCorrection.get().append(DocumentMarker::Autocorrected);
}
return markerTypesForAutoCorrection;
}
static const Vector<DocumentMarker::MarkerType>& markerTypesForReplacement()
{
- DEFINE_STATIC_LOCAL(Vector<DocumentMarker::MarkerType>, markerTypesForReplacement, ());
- if (markerTypesForReplacement.isEmpty()) {
- markerTypesForReplacement.append(DocumentMarker::Replacement);
- markerTypesForReplacement.append(DocumentMarker::SpellCheckingExemption);
+ static NeverDestroyed<Vector<DocumentMarker::MarkerType>> markerTypesForReplacement;
+ if (markerTypesForReplacement.get().isEmpty()) {
+ markerTypesForReplacement.get().append(DocumentMarker::Replacement);
+ markerTypesForReplacement.get().append(DocumentMarker::SpellCheckingExemption);
}
return markerTypesForReplacement;
}
static const Vector<DocumentMarker::MarkerType>& markerTypesForAppliedDictationAlternative()
{
- DEFINE_STATIC_LOCAL(Vector<DocumentMarker::MarkerType>, markerTypesForAppliedDictationAlternative, ());
- if (markerTypesForAppliedDictationAlternative.isEmpty())
- markerTypesForAppliedDictationAlternative.append(DocumentMarker::SpellCheckingExemption);
+ static NeverDestroyed<Vector<DocumentMarker::MarkerType>> markerTypesForAppliedDictationAlternative;
+ if (markerTypesForAppliedDictationAlternative.get().isEmpty())
+ markerTypesForAppliedDictationAlternative.get().append(DocumentMarker::SpellCheckingExemption);
return markerTypesForAppliedDictationAlternative;
}
-static bool markersHaveIdenticalDescription(const Vector<DocumentMarker*>& markers)
+static bool markersHaveIdenticalDescription(const Vector<RenderedDocumentMarker*>& markers)
{
if (markers.isEmpty())
return true;
@@ -126,7 +128,7 @@ static bool markersHaveIdenticalDescription(const Vector<DocumentMarker*>& marke
}
AlternativeTextController::AlternativeTextController(Frame& frame)
- : m_timer(this, &AlternativeTextController::timerFired)
+ : m_timer(*this, &AlternativeTextController::timerFired)
, m_frame(frame)
{
}
@@ -144,7 +146,7 @@ void AlternativeTextController::startAlternativeTextUITimer(AlternativeTextType
// If type is PanelTypeReversion, then the new range has been set. So we shouldn't clear it.
if (type == AlternativeTextTypeCorrection)
- m_alternativeTextInfo.rangeWithAlternative.clear();
+ m_alternativeTextInfo.rangeWithAlternative = nullptr;
m_alternativeTextInfo.type = type;
m_timer.startOneShot(correctionPanelTimerInterval);
}
@@ -152,7 +154,7 @@ void AlternativeTextController::startAlternativeTextUITimer(AlternativeTextType
void AlternativeTextController::stopAlternativeTextUITimer()
{
m_timer.stop();
- m_alternativeTextInfo.rangeWithAlternative.clear();
+ m_alternativeTextInfo.rangeWithAlternative = nullptr;
}
void AlternativeTextController::stopPendingCorrection(const VisibleSelection& oldSelection)
@@ -180,7 +182,7 @@ void AlternativeTextController::applyPendingCorrection(const VisibleSelection& s
if (doApplyCorrection)
handleAlternativeTextUIResult(dismissSoon(ReasonForDismissingAlternativeTextAccepted));
else
- m_alternativeTextInfo.rangeWithAlternative.clear();
+ m_alternativeTextInfo.rangeWithAlternative = nullptr;
}
bool AlternativeTextController::hasPendingCorrection() const
@@ -240,10 +242,7 @@ void AlternativeTextController::applyAlternativeTextToRange(const Range* range,
if (!range)
return;
- ExceptionCode ec = 0;
- RefPtr<Range> paragraphRangeContainingCorrection = range->cloneRange(ec);
- if (ec)
- return;
+ RefPtr<Range> paragraphRangeContainingCorrection = range->cloneRange();
setStart(paragraphRangeContainingCorrection.get(), startOfParagraph(range->startPosition()));
setEnd(paragraphRangeContainingCorrection.get(), endOfParagraph(range->endPosition()));
@@ -254,25 +253,28 @@ void AlternativeTextController::applyAlternativeTextToRange(const Range* range,
// relative to the start position of the containing paragraph. We use correctionStartOffsetInParagraph
// to store this value. In order to obtain this offset, we need to first create a range
// which spans from the start of paragraph to the start position of rangeWithAlternative.
- RefPtr<Range> correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer(ec)->document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition());
- if (ec)
- return;
+ RefPtr<Range> correctionStartOffsetInParagraphAsRange = Range::create(paragraphRangeContainingCorrection->startContainer().document(), paragraphRangeContainingCorrection->startPosition(), paragraphRangeContainingCorrection->startPosition());
- Position startPositionOfrangeWithAlternative = range->startPosition();
- correctionStartOffsetInParagraphAsRange->setEnd(startPositionOfrangeWithAlternative.containerNode(), startPositionOfrangeWithAlternative.computeOffsetInContainerNode(), ec);
- if (ec)
+ Position startPositionOfRangeWithAlternative = range->startPosition();
+ if (!startPositionOfRangeWithAlternative.containerNode())
+ return;
+ auto setEndResult = correctionStartOffsetInParagraphAsRange->setEnd(*startPositionOfRangeWithAlternative.containerNode(), startPositionOfRangeWithAlternative.computeOffsetInContainerNode());
+ if (setEndResult.hasException())
return;
// Take note of the location of autocorrection so that we can add marker after the replacement took place.
int correctionStartOffsetInParagraph = TextIterator::rangeLength(correctionStartOffsetInParagraphAsRange.get());
// Clone the range, since the caller of this method may want to keep the original range around.
- RefPtr<Range> rangeWithAlternative = range->cloneRange(ec);
-
- int paragraphStartIndex = TextIterator::rangeLength(Range::create(*m_frame.document(), m_frame.document(), 0, paragraphRangeContainingCorrection.get()->startContainer(), paragraphRangeContainingCorrection.get()->startOffset()).get());
- applyCommand(SpellingCorrectionCommand::create(rangeWithAlternative, alternative));
+ Ref<Range> rangeWithAlternative = range->cloneRange();
+
+ ContainerNode& rootNode = paragraphRangeContainingCorrection.get()->startContainer().treeScope().rootNode();
+ int paragraphStartIndex = TextIterator::rangeLength(Range::create(rootNode.document(), &rootNode, 0, &paragraphRangeContainingCorrection->startContainer(), paragraphRangeContainingCorrection->startOffset()).ptr());
+ applyCommand(SpellingCorrectionCommand::create(rangeWithAlternative.ptr(), alternative));
// Recalculate pragraphRangeContainingCorrection, since SpellingCorrectionCommand modified the DOM, such that the original paragraphRangeContainingCorrection is no longer valid. Radar: 10305315 Bugzilla: 89526
- paragraphRangeContainingCorrection = TextIterator::rangeFromLocationAndLength(m_frame.document(), paragraphStartIndex, correctionStartOffsetInParagraph + alternative.length());
+ paragraphRangeContainingCorrection = TextIterator::rangeFromLocationAndLength(&rootNode, paragraphStartIndex, correctionStartOffsetInParagraph + alternative.length());
+ if (!paragraphRangeContainingCorrection)
+ return;
setEnd(paragraphRangeContainingCorrection.get(), m_frame.selection().selection().start());
RefPtr<Range> replacementRange = TextIterator::subrange(paragraphRangeContainingCorrection.get(), correctionStartOffsetInParagraph, alternative.length());
@@ -282,10 +284,10 @@ void AlternativeTextController::applyAlternativeTextToRange(const Range* range,
if (newText != alternative)
return;
- DocumentMarkerController& markers = replacementRange->startContainer()->document().markers();
- size_t size = markerTypesToAdd.size();
- for (size_t i = 0; i < size; ++i)
- markers.addMarker(replacementRange.get(), markerTypesToAdd[i], markerDescriptionForAppliedAlternativeText(alternativeType, markerTypesToAdd[i]));
+ DocumentMarkerController& markers = replacementRange->startContainer().document().markers();
+
+ for (auto& markerType : markerTypesToAdd)
+ markers.addMarker(replacementRange.get(), markerType, markerDescriptionForAppliedAlternativeText(alternativeType, markerType));
}
bool AlternativeTextController::applyAutocorrectionBeforeTypingIfAppropriate()
@@ -312,9 +314,11 @@ bool AlternativeTextController::applyAutocorrectionBeforeTypingIfAppropriate()
void AlternativeTextController::respondToUnappliedSpellCorrection(const VisibleSelection& selectionOfCorrected, const String& corrected, const String& correction)
{
if (AlternativeTextClient* client = alternativeTextClient())
- client->recordAutocorrectionResponse(AutocorrectionReverted, corrected, correction);
+ client->recordAutocorrectionResponse(AutocorrectionResponse::Reverted, corrected, correction);
+
+ Ref<Frame> protector(m_frame);
m_frame.document()->updateLayout();
- m_frame.selection().setSelection(selectionOfCorrected, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | FrameSelection::SpellCorrectionTriggered);
+ m_frame.selection().setSelection(selectionOfCorrected, FrameSelection::defaultSetSelectionOptions() | FrameSelection::SpellCorrectionTriggered);
RefPtr<Range> range = Range::create(*m_frame.document(), m_frame.selection().selection().start(), m_frame.selection().selection().end());
DocumentMarkerController& markers = m_frame.document()->markers();
@@ -323,7 +327,7 @@ void AlternativeTextController::respondToUnappliedSpellCorrection(const VisibleS
markers.addMarker(range.get(), DocumentMarker::SpellCheckingExemption);
}
-void AlternativeTextController::timerFired(Timer<AlternativeTextController>&)
+void AlternativeTextController::timerFired()
{
m_isDismissedByEditing = false;
switch (m_alternativeTextInfo.type) {
@@ -336,13 +340,13 @@ void AlternativeTextController::timerFired(Timer<AlternativeTextController>&)
}
break;
case AlternativeTextTypeReversion: {
- if (!m_alternativeTextInfo.rangeWithAlternative)
+ auto* details = static_cast<const AutocorrectionAlternativeDetails*>(m_alternativeTextInfo.details.get());
+ if (!m_alternativeTextInfo.rangeWithAlternative || !details || details->replacementString().isEmpty())
break;
m_alternativeTextInfo.isActive = true;
m_alternativeTextInfo.originalText = plainText(m_alternativeTextInfo.rangeWithAlternative.get());
FloatRect boundingBox = rootViewRectForRange(m_alternativeTextInfo.rangeWithAlternative.get());
if (!boundingBox.isEmpty()) {
- const AutocorrectionAlternativeDetails* details = static_cast<const AutocorrectionAlternativeDetails*>(m_alternativeTextInfo.details.get());
if (AlternativeTextClient* client = alternativeTextClient())
client->showCorrectionAlternative(m_alternativeTextInfo.type, boundingBox, m_alternativeTextInfo.originalText, details->replacementString(), Vector<String>());
}
@@ -353,9 +357,9 @@ void AlternativeTextController::timerFired(Timer<AlternativeTextController>&)
break;
String paragraphText = plainText(TextCheckingParagraph(m_alternativeTextInfo.rangeWithAlternative).paragraphRange().get());
Vector<String> suggestions;
- textChecker()->getGuessesForWord(m_alternativeTextInfo.originalText, paragraphText, suggestions);
+ textChecker()->getGuessesForWord(m_alternativeTextInfo.originalText, paragraphText, m_frame.selection().selection(), suggestions);
if (suggestions.isEmpty()) {
- m_alternativeTextInfo.rangeWithAlternative.clear();
+ m_alternativeTextInfo.rangeWithAlternative = nullptr;
break;
}
String topSuggestion = suggestions.first();
@@ -405,7 +409,7 @@ void AlternativeTextController::handleAlternativeTextUIResult(const String& resu
if (result.length())
applyAlternativeTextToRange(rangeWithAlternative, result, m_alternativeTextInfo.type, markerTypesForAutocorrection());
else if (!m_isDismissedByEditing)
- rangeWithAlternative->startContainer()->document().markers().addMarker(rangeWithAlternative, DocumentMarker::RejectedCorrection, m_alternativeTextInfo.originalText);
+ rangeWithAlternative->startContainer().document().markers().addMarker(rangeWithAlternative, DocumentMarker::RejectedCorrection, m_alternativeTextInfo.originalText);
break;
case AlternativeTextTypeReversion:
case AlternativeTextTypeSpellingSuggestions:
@@ -418,7 +422,7 @@ void AlternativeTextController::handleAlternativeTextUIResult(const String& resu
break;
}
- m_alternativeTextInfo.rangeWithAlternative.clear();
+ m_alternativeTextInfo.rangeWithAlternative = nullptr;
}
bool AlternativeTextController::isAutomaticSpellingCorrectionEnabled()
@@ -432,15 +436,14 @@ FloatRect AlternativeTextController::rootViewRectForRange(const Range* range) co
if (!view)
return FloatRect();
Vector<FloatQuad> textQuads;
- range->textQuads(textQuads);
+ range->absoluteTextQuads(textQuads);
FloatRect boundingRect;
- size_t size = textQuads.size();
- for (size_t i = 0; i < size; ++i)
- boundingRect.unite(textQuads[i].boundingBox());
+ for (auto& textQuad : textQuads)
+ boundingRect.unite(textQuad.boundingBox());
return view->contentsToRootView(IntRect(boundingRect));
}
-void AlternativeTextController::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
+void AlternativeTextController::respondToChangedSelection(const VisibleSelection& oldSelection)
{
VisibleSelection currentSelection(m_frame.selection().selection());
// When user moves caret to the end of autocorrected word and pauses, we show the panel
@@ -466,14 +469,9 @@ void AlternativeTextController::respondToChangedSelection(const VisibleSelection
return;
Node* node = position.containerNode();
- Vector<DocumentMarker*> markers = node->document().markers().markersFor(node);
- size_t markerCount = markers.size();
- for (size_t i = 0; i < markerCount; ++i) {
- const DocumentMarker* marker = markers[i];
- if (!marker)
- continue;
-
- if (respondToMarkerAtEndOfWord(*marker, position, options))
+ for (auto* marker : node->document().markers().markersFor(node)) {
+ ASSERT(marker);
+ if (respondToMarkerAtEndOfWord(*marker, position))
break;
}
}
@@ -485,6 +483,8 @@ void AlternativeTextController::respondToAppliedEditing(CompositeEditCommand* co
markPrecedingWhitespaceForDeletedAutocorrectionAfterCommand(command);
m_originalStringForLastDeletedAutocorrection = String();
+
+ dismiss(ReasonForDismissingAlternativeTextIgnored);
}
void AlternativeTextController::respondToUnappliedEditing(EditCommandComposition* command)
@@ -506,39 +506,32 @@ AlternativeTextClient* AlternativeTextController::alternativeTextClient()
EditorClient* AlternativeTextController::editorClient()
{
- return m_frame.page() ? m_frame.page()->editorClient() : 0;
+ return m_frame.page() ? &m_frame.page()->editorClient() : nullptr;
}
TextCheckerClient* AlternativeTextController::textChecker()
{
if (EditorClient* owner = editorClient())
return owner->textChecker();
- return 0;
+ return nullptr;
}
-void AlternativeTextController::recordAutocorrectionResponseReversed(const String& replacedString, const String& replacementString)
+void AlternativeTextController::recordAutocorrectionResponse(AutocorrectionResponse response, const String& replacedString, PassRefPtr<Range> replacementRange)
{
- if (AlternativeTextClient* client = alternativeTextClient())
- client->recordAutocorrectionResponse(AutocorrectionReverted, replacedString, replacementString);
-}
-
-void AlternativeTextController::recordAutocorrectionResponseReversed(const String& replacedString, PassRefPtr<Range> replacementRange)
-{
- recordAutocorrectionResponseReversed(replacedString, plainText(replacementRange.get()));
+ if (auto client = alternativeTextClient())
+ client->recordAutocorrectionResponse(response, replacedString, plainText(replacementRange.get()));
}
void AlternativeTextController::markReversed(PassRefPtr<Range> changedRange)
{
- changedRange->startContainer()->document().markers().removeMarkers(changedRange.get(), DocumentMarker::Autocorrected, DocumentMarkerController::RemovePartiallyOverlappingMarker);
- changedRange->startContainer()->document().markers().addMarker(changedRange.get(), DocumentMarker::SpellCheckingExemption);
+ changedRange->startContainer().document().markers().removeMarkers(changedRange.get(), DocumentMarker::Autocorrected, DocumentMarkerController::RemovePartiallyOverlappingMarker);
+ changedRange->startContainer().document().markers().addMarker(changedRange.get(), DocumentMarker::SpellCheckingExemption);
}
void AlternativeTextController::markCorrection(PassRefPtr<Range> replacedRange, const String& replacedString)
{
- Vector<DocumentMarker::MarkerType> markerTypesToAdd = markerTypesForAutocorrection();
- DocumentMarkerController& markers = replacedRange->startContainer()->document().markers();
- for (size_t i = 0; i < markerTypesToAdd.size(); ++i) {
- DocumentMarker::MarkerType markerType = markerTypesToAdd[i];
+ DocumentMarkerController& markers = replacedRange->startContainer().document().markers();
+ for (auto& markerType : markerTypesForAutocorrection()) {
if (markerType == DocumentMarker::Replacement || markerType == DocumentMarker::Autocorrected)
markers.addMarker(replacedRange.get(), markerType, replacedString);
else
@@ -550,8 +543,8 @@ void AlternativeTextController::recordSpellcheckerResponseForModifiedCorrection(
{
if (!rangeOfCorrection)
return;
- DocumentMarkerController& markers = rangeOfCorrection->startContainer()->document().markers();
- Vector<DocumentMarker*> correctedOnceMarkers = markers.markersInRange(rangeOfCorrection, DocumentMarker::Autocorrected);
+ DocumentMarkerController& markers = rangeOfCorrection->startContainer().document().markers();
+ Vector<RenderedDocumentMarker*> correctedOnceMarkers = markers.markersInRange(rangeOfCorrection, DocumentMarker::Autocorrected);
if (correctedOnceMarkers.isEmpty())
return;
@@ -559,9 +552,9 @@ void AlternativeTextController::recordSpellcheckerResponseForModifiedCorrection(
// Spelling corrected text has been edited. We need to determine whether user has reverted it to original text or
// edited it to something else, and notify spellchecker accordingly.
if (markersHaveIdenticalDescription(correctedOnceMarkers) && correctedOnceMarkers[0]->description() == corrected)
- client->recordAutocorrectionResponse(AutocorrectionReverted, corrected, correction);
+ client->recordAutocorrectionResponse(AutocorrectionResponse::Reverted, corrected, correction);
else
- client->recordAutocorrectionResponse(AutocorrectionEdited, corrected, correction);
+ client->recordAutocorrectionResponse(AutocorrectionResponse::Edited, corrected, correction);
}
markers.removeMarkers(rangeOfCorrection, DocumentMarker::Autocorrected, DocumentMarkerController::RemovePartiallyOverlappingMarker);
@@ -585,7 +578,7 @@ void AlternativeTextController::markPrecedingWhitespaceForDeletedAutocorrectionA
RefPtr<Range> precedingCharacterRange = Range::create(*m_frame.document(), precedingCharacterPosition, endOfSelection);
String string = plainText(precedingCharacterRange.get());
- if (string.isEmpty() || !isWhitespace(string[string.length() - 1]))
+ if (string.isEmpty() || !deprecatedIsEditingWhitespace(string[string.length() - 1]))
return;
// Mark this whitespace to indicate we have deleted an autocorrection following this
@@ -606,14 +599,16 @@ bool AlternativeTextController::processMarkersOnTextToBeReplacedByResult(const T
if (markerController.hasMarkers(rangeWithAlternative, DocumentMarker::RejectedCorrection))
return false;
+ if (markerController.hasMarkers(rangeWithAlternative, DocumentMarker::AcceptedCandidate))
+ return false;
+
Position beginningOfRange = rangeWithAlternative->startPosition();
Position precedingCharacterPosition = beginningOfRange.previous();
RefPtr<Range> precedingCharacterRange = Range::create(*m_frame.document(), precedingCharacterPosition, beginningOfRange);
- Vector<DocumentMarker*> markers = markerController.markersInRange(precedingCharacterRange.get(), DocumentMarker::DeletedAutocorrection);
-
- for (size_t i = 0; i < markers.size(); ++i) {
- if (markers[i]->description() == stringToBeReplaced)
+ Vector<RenderedDocumentMarker*> markers = markerController.markersInRange(precedingCharacterRange.get(), DocumentMarker::DeletedAutocorrection);
+ for (const auto* marker : markers) {
+ if (marker->description() == stringToBeReplaced)
return false;
}
@@ -625,10 +620,8 @@ bool AlternativeTextController::shouldStartTimerFor(const WebCore::DocumentMarke
return (((marker.type() == DocumentMarker::Replacement && !marker.description().isNull()) || marker.type() == DocumentMarker::Spelling || marker.type() == DocumentMarker::DictationAlternatives) && static_cast<int>(marker.endOffset()) == endOffset);
}
-bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker& marker, const Position& endOfWordPosition, FrameSelection::SetSelectionOptions options)
+bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker& marker, const Position& endOfWordPosition)
{
- if (options & FrameSelection::DictationTriggered)
- return false;
if (!shouldStartTimerFor(marker, endOfWordPosition.offsetInContainerNode()))
return false;
Node* node = endOfWordPosition.containerNode();
@@ -642,7 +635,7 @@ bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker&
switch (marker.type()) {
case DocumentMarker::Spelling:
m_alternativeTextInfo.rangeWithAlternative = wordRange;
- m_alternativeTextInfo.details = AutocorrectionAlternativeDetails::create("");
+ m_alternativeTextInfo.details = AutocorrectionAlternativeDetails::create(emptyString());
startAlternativeTextUITimer(AlternativeTextTypeSpellingSuggestions);
break;
case DocumentMarker::Replacement:
@@ -651,13 +644,13 @@ bool AlternativeTextController::respondToMarkerAtEndOfWord(const DocumentMarker&
startAlternativeTextUITimer(AlternativeTextTypeReversion);
break;
case DocumentMarker::DictationAlternatives: {
- const DictationMarkerDetails* markerDetails = static_cast<const DictationMarkerDetails*>(marker.details());
- if (!markerDetails)
+ if (!WTF::holds_alternative<DocumentMarker::DictationData>(marker.data()))
return false;
- if (currentWord != markerDetails->originalText())
+ auto& markerData = WTF::get<DocumentMarker::DictationData>(marker.data());
+ if (currentWord != markerData.originalText)
return false;
m_alternativeTextInfo.rangeWithAlternative = wordRange;
- m_alternativeTextInfo.details = DictationAlternativeDetails::create(markerDetails->dictationContext());
+ m_alternativeTextInfo.details = DictationAlternativeDetails::create(markerData.context);
startAlternativeTextUITimer(AlternativeTextTypeDictationAlternatives);
}
break;
@@ -673,7 +666,7 @@ String AlternativeTextController::markerDescriptionForAppliedAlternativeText(Alt
if (alternativeTextType != AlternativeTextTypeReversion && alternativeTextType != AlternativeTextTypeDictationAlternatives && (markerType == DocumentMarker::Replacement || markerType == DocumentMarker::Autocorrected))
return m_alternativeTextInfo.originalText;
- return "";
+ return emptyString();
}
#endif
@@ -691,32 +684,30 @@ bool AlternativeTextController::insertDictatedText(const String& text, const Vec
if (FrameView* view = m_frame.view())
view->disableLayerFlushThrottlingTemporarilyForInteraction();
- RefPtr<TextEvent> event = TextEvent::createForDictation(m_frame.document()->domWindow(), text, dictationAlternatives);
+ Ref<TextEvent> event = TextEvent::createForDictation(m_frame.document()->domWindow(), text, dictationAlternatives);
event->setUnderlyingEvent(triggeringEvent);
- target->dispatchEvent(event, IGNORE_EXCEPTION);
+ target->dispatchEvent(event);
return event->defaultHandled();
}
-void AlternativeTextController::removeDictationAlternativesForMarker(const DocumentMarker* marker)
+void AlternativeTextController::removeDictationAlternativesForMarker(const DocumentMarker& marker)
{
#if USE(DICTATION_ALTERNATIVES)
- DictationMarkerDetails* details = static_cast<DictationMarkerDetails*>(marker->details());
- if (AlternativeTextClient* client = alternativeTextClient())
- client->removeDictationAlternatives(details->dictationContext());
+ ASSERT(WTF::holds_alternative<DocumentMarker::DictationData>(marker.data()));
+ if (auto* client = alternativeTextClient())
+ client->removeDictationAlternatives(WTF::get<DocumentMarker::DictationData>(marker.data()).context);
#else
UNUSED_PARAM(marker);
#endif
}
-Vector<String> AlternativeTextController::dictationAlternativesForMarker(const DocumentMarker* marker)
+Vector<String> AlternativeTextController::dictationAlternativesForMarker(const DocumentMarker& marker)
{
#if USE(DICTATION_ALTERNATIVES)
- ASSERT(marker->type() == DocumentMarker::DictationAlternatives);
- if (AlternativeTextClient* client = alternativeTextClient()) {
- DictationMarkerDetails* details = static_cast<DictationMarkerDetails*>(marker->details());
- return client->dictationAlternatives(details->dictationContext());
- }
+ ASSERT(marker.type() == DocumentMarker::DictationAlternatives);
+ if (auto* client = alternativeTextClient())
+ return client->dictationAlternatives(WTF::get<DocumentMarker::DictationData>(marker.data()).context);
return Vector<String>();
#else
UNUSED_PARAM(marker);
@@ -729,12 +720,12 @@ void AlternativeTextController::applyDictationAlternative(const String& alternat
#if USE(DICTATION_ALTERNATIVES)
Editor& editor = m_frame.editor();
RefPtr<Range> selection = editor.selectedRange();
- if (!selection || !editor.shouldInsertText(alternativeString, selection.get(), EditorInsertActionPasted))
+ if (!selection || !editor.shouldInsertText(alternativeString, selection.get(), EditorInsertAction::Pasted))
return;
- DocumentMarkerController& markers = selection->startContainer()->document().markers();
- Vector<DocumentMarker*> dictationAlternativesMarkers = markers.markersInRange(selection.get(), DocumentMarker::DictationAlternatives);
- for (size_t i = 0; i < dictationAlternativesMarkers.size(); ++i)
- removeDictationAlternativesForMarker(dictationAlternativesMarkers[i]);
+ DocumentMarkerController& markers = selection->startContainer().document().markers();
+ Vector<RenderedDocumentMarker*> dictationAlternativesMarkers = markers.markersInRange(selection.get(), DocumentMarker::DictationAlternatives);
+ for (auto* marker : dictationAlternativesMarkers)
+ removeDictationAlternativesForMarker(*marker);
applyAlternativeTextToRange(selection.get(), alternativeString, AlternativeTextTypeDictationAlternatives, markerTypesForAppliedDictationAlternative());
#else