Index: Source/core/editing/spellcheck/SpellChecker.cpp |
diff --git a/Source/core/editing/spellcheck/SpellChecker.cpp b/Source/core/editing/spellcheck/SpellChecker.cpp |
index 2c3736e5cd4ba270de4214837341a31cb2e997e3..85b98f2e2b77a985b56d42fa20f6bc068866e108 100644 |
--- a/Source/core/editing/spellcheck/SpellChecker.cpp |
+++ b/Source/core/editing/spellcheck/SpellChecker.cpp |
@@ -237,7 +237,6 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) |
bool isSpelling = true; |
int foundOffset = 0; |
String foundItem; |
- RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr; |
if (unifiedTextCheckerEnabled()) { |
grammarSearchStart = spellingSearchStart; |
grammarSearchEnd = spellingSearchEnd; |
@@ -250,7 +249,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) |
grammarPhraseOffset = foundOffset; |
} |
} else { |
- misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange); |
+ misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); |
grammarSearchStart = spellingSearchStart; |
grammarSearchEnd = spellingSearchEnd; |
if (!misspelledWord.isEmpty()) { |
@@ -283,7 +282,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) |
grammarPhraseOffset = foundOffset; |
} |
} else { |
- misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange); |
+ misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); |
grammarSearchStart = spellingSearchStart; |
grammarSearchEnd = spellingSearchEnd; |
if (!misspelledWord.isEmpty()) { |
@@ -350,26 +349,26 @@ void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSe |
{ |
TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); |
- if (unifiedTextCheckerEnabled()) { |
- TextCheckingTypeMask textCheckingOptions = 0; |
+ if (!unifiedTextCheckerEnabled()) { |
+ markMisspellings(wordSelection); |
+ return; |
+ } |
- if (isContinuousSpellCheckingEnabled()) |
- textCheckingOptions |= TextCheckingTypeSpelling; |
+ TextCheckingTypeMask textCheckingOptions = 0; |
- if (isGrammarCheckingEnabled()) |
- textCheckingOptions |= TextCheckingTypeGrammar; |
+ if (isContinuousSpellCheckingEnabled()) |
+ textCheckingOptions |= TextCheckingTypeSpelling; |
- VisibleSelection wholeParagraph( |
- startOfParagraph(wordSelection.visibleStart()), |
- endOfParagraph(wordSelection.visibleEnd())); |
+ if (isGrammarCheckingEnabled()) |
+ textCheckingOptions |= TextCheckingTypeGrammar; |
- markAllMisspellingsAndBadGrammarInRanges( |
- textCheckingOptions, wordSelection.toNormalizedEphemeralRange(), |
- wholeParagraph.toNormalizedEphemeralRange()); |
- } else { |
- RefPtrWillBeRawPtr<Range> misspellingRange = nullptr; |
- markMisspellings(wordSelection, misspellingRange); |
- } |
+ VisibleSelection wholeParagraph( |
+ startOfParagraph(wordSelection.visibleStart()), |
+ endOfParagraph(wordSelection.visibleEnd())); |
+ |
+ markAllMisspellingsAndBadGrammarInRanges( |
+ textCheckingOptions, wordSelection.toNormalizedEphemeralRange(), |
+ wholeParagraph.toNormalizedEphemeralRange()); |
} |
void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping) |
@@ -402,17 +401,16 @@ void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word |
return; |
// Check spelling of one word |
- RefPtrWillBeRawPtr<Range> misspellingRange = nullptr; |
- markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange); |
+ bool result = markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary))); |
- if (!misspellingRange || !isGrammarCheckingEnabled()) |
+ if (!result || !isGrammarCheckingEnabled()) |
return; |
// Check grammar of entire sentence |
markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart))); |
} |
-void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtrWillBeRawPtr<Range>& firstMisspellingRange) |
+bool SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling) |
{ |
// This function is called with a selection already expanded to word boundaries. |
// Might be nice to assert that here. |
@@ -420,27 +418,29 @@ void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selectio |
// 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 false; |
TRACE_EVENT0("blink", "SpellChecker::markMisspellingsOrBadGrammar"); |
const EphemeralRange range = selection.toNormalizedEphemeralRange(); |
if (range.isNull()) |
- return; |
+ return false; |
// If we're not in an editable node, bail. |
Node* editableNode = range.startPosition().computeContainerNode(); |
if (!editableNode || !editableNode->hasEditableStyle()) |
- return; |
+ return false; |
if (!isSpellCheckingEnabledFor(editableNode)) |
- return; |
+ return false; |
TextCheckingHelper checker(spellCheckerClient(), range.startPosition(), range.endPosition()); |
if (checkSpelling) |
- checker.markAllMisspellings(firstMisspellingRange); |
- else if (isGrammarCheckingEnabled()) |
+ return checker.markAllMisspellings(); |
+ |
+ if (isGrammarCheckingEnabled()) |
checker.markAllBadGrammar(); |
+ return false; |
} |
bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const |
@@ -458,15 +458,14 @@ bool SpellChecker::isSpellCheckingEnabledInFocusedNode() const |
return isSpellCheckingEnabledFor(frame().selection().start().anchorNode()); |
} |
-void SpellChecker::markMisspellings(const VisibleSelection& selection, RefPtrWillBeRawPtr<Range>& firstMisspellingRange) |
+bool SpellChecker::markMisspellings(const VisibleSelection& selection) |
{ |
- markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange); |
+ return markMisspellingsOrBadGrammar(selection, true); |
} |
void SpellChecker::markBadGrammar(const VisibleSelection& selection) |
{ |
- RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr; |
- markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange); |
+ markMisspellingsOrBadGrammar(selection, false); |
} |
void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, const EphemeralRange& spellingRange, const EphemeralRange& grammarRange) |
@@ -487,8 +486,7 @@ void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask |
if (!isSpellCheckingEnabledFor(editableNode)) |
return; |
- RefPtrWillBeRawPtr<Range> rangeToCheck = createRange(shouldMarkGrammar ? grammarRange : spellingRange); |
- TextCheckingParagraph fullParagraphToCheck(rangeToCheck); |
+ TextCheckingParagraph fullParagraphToCheck(shouldMarkGrammar ? grammarRange : spellingRange); |
bool asynchronous = frame().settings() && frame().settings()->asynchronousSpellCheckingEnabled(); |
chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphToCheck, asynchronous); |
@@ -518,39 +516,39 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask |
end = std::max(start, end); |
const int kNumChunksToCheck = asynchronous ? (end - start + kChunkSize - 1) / (kChunkSize) : 1; |
int currentChunkStart = start; |
- RefPtrWillBeRawPtr<Range> checkRange = fullParagraphToCheck.checkingRange(); |
if (kNumChunksToCheck == 1 && asynchronous) { |
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange.get(), checkRange.get(), asynchronous, 0); |
+ EphemeralRange checkRange = fullParagraphToCheck.checkingRange(); |
+ markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange, checkRange, asynchronous, 0); |
return; |
} |
for (int iter = 0; iter < kNumChunksToCheck; ++iter) { |
- checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize); |
- expandRangeToSentenceBoundary(*checkRange); |
+ EphemeralRange checkRange = expandRangeToSentenceBoundary(fullParagraphToCheck.subrange(currentChunkStart, kChunkSize)); |
int checkingLength = 0; |
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange.get(), checkRange.get(), asynchronous, iter, &checkingLength); |
+ markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange, checkRange, asynchronous, iter, &checkingLength); |
currentChunkStart += checkingLength; |
} |
} |
-void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, Range* checkRange, Range* paragraphRange, bool asynchronous, int requestNumber, int* checkingLength) |
+void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, const EphemeralRange& checkRange, const EphemeralRange& paragraphRange, bool asynchronous, int requestNumber, int* checkingLength) |
{ |
TextCheckingParagraph sentenceToCheck(checkRange, paragraphRange); |
if (checkingLength) |
*checkingLength = sentenceToCheck.checkingLength(); |
- RefPtrWillBeRawPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkRange, paragraphRange, requestNumber); |
+ RefPtrWillBeRawPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, createRange(checkRange), createRange(paragraphRange), requestNumber); |
if (!request) |
return; |
if (asynchronous) { |
m_spellCheckRequester->requestCheckingFor(request); |
- } else { |
- Vector<TextCheckingResult> results; |
- checkTextOfParagraph(textChecker(), sentenceToCheck.text(), resolveTextCheckingTypeMask(textCheckingOptions), results); |
- markAndReplaceFor(request, results); |
+ return; |
} |
+ |
+ Vector<TextCheckingResult> results; |
+ checkTextOfParagraph(textChecker(), sentenceToCheck.text(), resolveTextCheckingTypeMask(textCheckingOptions), results); |
+ markAndReplaceFor(request, results); |
} |
void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> request, const Vector<TextCheckingResult>& results) |
@@ -575,7 +573,7 @@ void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> r |
if (frame().selection().isCaret()) { |
// Attempt to save the caret position so we can restore it later if needed |
Position caretPosition = frame().selection().end(); |
- selectionOffset = paragraph.offsetTo(caretPosition, ASSERT_NO_EXCEPTION); |
+ selectionOffset = paragraph.offsetTo(caretPosition); |
restoreSelectionAfterChange = true; |
if (selectionOffset > 0 && (static_cast<unsigned>(selectionOffset) > paragraph.text().length() || paragraph.textCharAt(selectionOffset - 1) == newlineCharacter)) |
adjustSelectionForParagraphBoundaries = true; |
@@ -598,7 +596,7 @@ void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> r |
// "wouldn'" as misspelled right after apostrophe is typed. |
if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelling && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { |
ASSERT(resultLength > 0 && resultLocation >= 0); |
- const EphemeralRange misspellingRange = calculateCharacterSubrange(EphemeralRange(paragraph.paragraphRange().get()), resultLocation, resultLength); |
+ const EphemeralRange misspellingRange = calculateCharacterSubrange(paragraph.paragraphRange(), resultLocation, resultLength); |
frame().document()->markers().addMarker(misspellingRange.startPosition(), misspellingRange.endPosition(), DocumentMarker::Spelling, result->replacement, result->hash); |
} else if (shouldMarkGrammar && result->decoration == TextDecorationTypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) { |
ASSERT(resultLength > 0 && resultLocation >= 0); |
@@ -606,13 +604,13 @@ void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> r |
const GrammarDetail* detail = &result->details[j]; |
ASSERT(detail->length > 0 && detail->location >= 0); |
if (paragraph.checkingRangeCovers(resultLocation + detail->location, detail->length)) { |
- const EphemeralRange badGrammarRange = calculateCharacterSubrange(EphemeralRange(paragraph.paragraphRange().get()), resultLocation + detail->location, detail->length); |
+ const EphemeralRange badGrammarRange = calculateCharacterSubrange(paragraph.paragraphRange(), resultLocation + detail->location, detail->length); |
frame().document()->markers().addMarker(badGrammarRange.startPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, detail->userDescription, result->hash); |
} |
} |
} else if (result->decoration == TextDecorationTypeInvisibleSpellcheck && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset) { |
ASSERT(resultLength > 0 && resultLocation >= 0); |
- const EphemeralRange invisibleSpellcheckRange = calculateCharacterSubrange(EphemeralRange(paragraph.paragraphRange().get()), resultLocation, resultLength); |
+ const EphemeralRange invisibleSpellcheckRange = calculateCharacterSubrange(paragraph.paragraphRange(), resultLocation, resultLength); |
frame().document()->markers().addMarker(invisibleSpellcheckRange.startPosition(), invisibleSpellcheckRange.endPosition(), DocumentMarker::InvisibleSpellcheck, result->replacement, result->hash); |
} |
} |
@@ -622,8 +620,8 @@ void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> r |
// Restore the caret position if we have made any replacements |
extendedParagraph.expandRangeToNextEnd(); |
if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffset <= extendedParagraph.rangeLength()) { |
- RefPtrWillBeRawPtr<Range> selectionRange = extendedParagraph.subrange(0, selectionOffset); |
- frame().selection().moveTo(selectionRange->endPosition(), TextAffinity::Downstream); |
+ EphemeralRange selectionRange = extendedParagraph.subrange(0, selectionOffset); |
+ frame().selection().moveTo(selectionRange.endPosition(), TextAffinity::Downstream); |
if (adjustSelectionForParagraphBoundaries) |
frame().selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity); |
} else { |
@@ -648,8 +646,7 @@ void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& spellin |
return; |
} |
- RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr; |
- markMisspellings(spellingSelection, firstMisspellingRange); |
+ markMisspellings(spellingSelection); |
if (markGrammar) |
markBadGrammar(grammarSelection); |
} |