diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/editing/AlternativeTextController.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/editing/AlternativeTextController.cpp')
-rw-r--r-- | Source/WebCore/editing/AlternativeTextController.cpp | 227 |
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, ¶graphRangeContainingCorrection->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 |