Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1769)

Unified Diff: third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp

Issue 2202463002: ALL-IN-ONE Stop SpellChecker from checking or marking grammar (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix layout test accessibility/misspellings.html Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
index 0c89d47e76816c3c67a2a0e6d7c469ff7da1069c..178de0e87616ea6bfc9d512f8f4c88eaa6a5b03b 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -226,89 +226,20 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode();
int misspellingOffset = 0;
- GrammarDetail grammarDetail;
- int grammarPhraseOffset = 0;
- Position grammarSearchStart, grammarSearchEnd;
- String badGrammarPhrase;
- String misspelledWord;
-
- bool isSpelling = true;
- int foundOffset = 0;
- String foundItem;
- if (unifiedTextCheckerEnabled()) {
- grammarSearchStart = spellingSearchStart;
- grammarSearchEnd = spellingSearchEnd;
- foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, grammarDetail);
- if (isSpelling) {
- misspelledWord = foundItem;
- misspellingOffset = foundOffset;
- } else {
- badGrammarPhrase = foundItem;
- grammarPhraseOffset = foundOffset;
- }
- } else {
- misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
- grammarSearchStart = spellingSearchStart;
- grammarSearchEnd = spellingSearchEnd;
- if (!misspelledWord.isEmpty()) {
- // Stop looking at start of next misspelled word
- CharacterIterator chars(grammarSearchStart, grammarSearchEnd);
- chars.advance(misspellingOffset);
- grammarSearchEnd = chars.startPosition();
- }
-
- badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false);
- }
+ String misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
- // If we found neither bad grammar nor a misspelled word, wrap and try again (but don't bother if we started at the beginning of the
+ // If we did not find a misspelled word, wrap and try again (but don't bother if we started at the beginning of the
// block rather than at a selection).
- if (startedWithSelection && !misspelledWord && !badGrammarPhrase) {
+ if (startedWithSelection && !misspelledWord) {
spellingSearchStart = Position::editingPositionOf(topNode, 0);
// going until the end of the very first chunk we tested is far enough
spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap, searchEndOffsetAfterWrap);
- if (unifiedTextCheckerEnabled()) {
- grammarSearchStart = spellingSearchStart;
- grammarSearchEnd = spellingSearchEnd;
- foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, grammarDetail);
- if (isSpelling) {
- misspelledWord = foundItem;
- misspellingOffset = foundOffset;
- } else {
- badGrammarPhrase = foundItem;
- grammarPhraseOffset = foundOffset;
- }
- } else {
- misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
- grammarSearchStart = spellingSearchStart;
- grammarSearchEnd = spellingSearchEnd;
- if (!misspelledWord.isEmpty()) {
- // Stop looking at start of next misspelled word
- CharacterIterator chars(grammarSearchStart, grammarSearchEnd);
- chars.advance(misspellingOffset);
- grammarSearchEnd = chars.startPosition();
- }
-
- badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false);
- }
+ misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false);
}
- if (!badGrammarPhrase.isEmpty()) {
- // We found bad grammar. Since we only searched for bad grammar up to the first misspelled word, the bad grammar
- // takes precedence and we ignore any potential misspelled word. Select the grammar detail, update the spelling
- // panel, and store a marker so we draw the green squiggle later.
-
- DCHECK_GT(badGrammarPhrase.length(), 0u);
- DCHECK_NE(grammarDetail.location, -1);
- DCHECK_GT(grammarDetail.length, 0);
-
- // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
- const EphemeralRange badGrammarRange = calculateCharacterSubrange(EphemeralRange(grammarSearchStart, grammarSearchEnd), grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
- frame().selection().setSelection(VisibleSelection(badGrammarRange));
- frame().selection().revealSelection();
- frame().document()->markers().addMarker(badGrammarRange.startPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, grammarDetail.userDescription);
- } else if (!misspelledWord.isEmpty()) {
- // We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store
+ if (!misspelledWord.isEmpty()) {
+ // We found a misspelling. Select the misspelling, update the spelling panel, and store
// a marker so we draw the red squiggle later.
const EphemeralRange misspellingRange = calculateCharacterSubrange(EphemeralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelledWord.length());
@@ -337,7 +268,16 @@ void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
{
- markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnabled(), movingSelection);
+ if (!unifiedTextCheckerEnabled()) {
+ markMisspellings(movingSelection);
+ return;
+ }
+
+ if (!isContinuousSpellCheckingEnabled())
+ return;
+
+ // markMisspellings() is triggered by selection change, in which case we check spelling, but don't autocorrect misspellings.
+ markAllMisspellingsInRange(movingSelection.toNormalizedEphemeralRange());
}
void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSelection)
@@ -349,88 +289,25 @@ void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSe
return;
}
- TextCheckingTypeMask textCheckingOptions = TextCheckingTypeGrammar;
-
if (isContinuousSpellCheckingEnabled())
- textCheckingOptions |= TextCheckingTypeSpelling;
-
- VisibleSelection wholeParagraph(
- startOfParagraph(wordSelection.visibleStart()),
- endOfParagraph(wordSelection.visibleEnd()));
-
- markAllMisspellingsAndBadGrammarInRanges(
- textCheckingOptions, wordSelection.toNormalizedEphemeralRange(),
- wholeParagraph.toNormalizedEphemeralRange());
+ markAllMisspellingsInRange(wordSelection.toNormalizedEphemeralRange());
}
void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping)
{
TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord");
- if (unifiedTextCheckerEnabled()) {
- TextCheckingTypeMask textCheckingOptions = 0;
-
- if (isContinuousSpellCheckingEnabled())
- textCheckingOptions |= TextCheckingTypeSpelling;
-
- if (!(textCheckingOptions & TextCheckingTypeSpelling))
- return;
-
- textCheckingOptions |= TextCheckingTypeGrammar;
+ if (!isContinuousSpellCheckingEnabled())
+ return;
+ if (unifiedTextCheckerEnabled()) {
VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary));
- if (textCheckingOptions & TextCheckingTypeGrammar) {
- VisibleSelection selectedSentence = VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart));
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedEphemeralRange(), selectedSentence.toNormalizedEphemeralRange());
- } else {
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjacentWords.toNormalizedEphemeralRange(), adjacentWords.toNormalizedEphemeralRange());
- }
+ markAllMisspellingsInRange(adjacentWords.toNormalizedEphemeralRange());
return;
}
- if (!isContinuousSpellCheckingEnabled())
- return;
-
// Check spelling of one word
- bool result = markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)));
-
- if (!result)
- return;
-
- // Check grammar of entire sentence
- markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart)));
-}
-
-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.
-
- // 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 false;
-
- TRACE_EVENT0("blink", "SpellChecker::markMisspellingsOrBadGrammar");
-
- const EphemeralRange range = selection.toNormalizedEphemeralRange();
- if (range.isNull())
- return false;
-
- // If we're not in an editable node, bail.
- Node* editableNode = range.startPosition().computeContainerNode();
- if (!editableNode || !hasEditableStyle(*editableNode))
- return false;
-
- if (!isSpellCheckingEnabledFor(editableNode))
- return false;
-
- TextCheckingHelper checker(spellCheckerClient(), range.startPosition(), range.endPosition());
- if (checkSpelling)
- return checker.markAllMisspellings();
-
- checker.markAllBadGrammar();
- return false;
+ markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)));
}
bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const
@@ -467,22 +344,37 @@ bool SpellChecker::isSpellCheckingEnabledFor(const VisibleSelection& selection)
bool SpellChecker::markMisspellings(const VisibleSelection& selection)
{
- return markMisspellingsOrBadGrammar(selection, true);
-}
+ // This function is called with a selection already expanded to word boundaries.
+ // Might be nice to assert that here.
-void SpellChecker::markBadGrammar(const VisibleSelection& selection)
-{
- markMisspellingsOrBadGrammar(selection, false);
+ // This function is used only for as-you-type checking, so if that's off we do nothing.
+ if (!isContinuousSpellCheckingEnabled())
+ return false;
+
+ TRACE_EVENT0("blink", "SpellChecker::markMisspellings");
+
+ const EphemeralRange range = selection.toNormalizedEphemeralRange();
+ if (range.isNull())
+ return false;
+
+ // If we're not in an editable node, bail.
+ Node* editableNode = range.startPosition().computeContainerNode();
+ if (!editableNode || !hasEditableStyle(*editableNode))
+ return false;
+
+ if (!isSpellCheckingEnabledFor(editableNode))
+ return false;
+
+ TextCheckingHelper checker(spellCheckerClient(), range.startPosition(), range.endPosition());
+ return checker.markAllMisspellings();
}
-void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, const EphemeralRange& spellingRange, const EphemeralRange& grammarRange)
+void SpellChecker::markAllMisspellingsInRange(const EphemeralRange& spellingRange)
{
DCHECK(unifiedTextCheckerEnabled());
- bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
-
// This function is called with selections already expanded to word boundaries.
- if (spellingRange.isNull() || (shouldMarkGrammar && grammarRange.isNull()))
+ if (spellingRange.isNull())
return;
// If we're not in an editable node, bail.
@@ -493,8 +385,8 @@ void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask
if (!isSpellCheckingEnabledFor(editableNode))
return;
- TextCheckingParagraph fullParagraphToCheck(shouldMarkGrammar ? grammarRange : spellingRange);
- chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphToCheck);
+ TextCheckingParagraph fullParagraphToCheck(spellingRange);
+ chunkAndMarkAllMisspellings(fullParagraphToCheck);
}
static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range)
@@ -522,10 +414,10 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node, const Ep
return;
EphemeralRange paragraphRange(Position::firstPositionInNode(node), Position::lastPositionInNode(node));
TextCheckingParagraph textToCheck(insertedRange, paragraphRange);
- chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextCheckingTypeSpelling | TextCheckingTypeGrammar), textToCheck);
+ chunkAndMarkAllMisspellings(textToCheck);
}
-void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck)
+void SpellChecker::chunkAndMarkAllMisspellings(const TextCheckingParagraph& fullParagraphToCheck)
{
if (fullParagraphToCheck.isEmpty())
return;
@@ -537,7 +429,7 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
// Check the full paragraph instead if the paragraph is short, which saves
// the cost on sentence boundary finding.
if (fullParagraphToCheck.rangeLength() <= kChunkSize) {
- SpellCheckRequest* request = SpellCheckRequest::create(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, paragraphRange, paragraphRange, 0);
+ SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingTypeSpelling, TextCheckingProcessBatch, paragraphRange, paragraphRange, 0);
if (request)
m_spellCheckRequester->requestCheckingFor(request);
return;
@@ -548,7 +440,7 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
EphemeralRange chunkRange = checkRangeIterator.calculateCharacterSubrange(0, kChunkSize);
EphemeralRange checkRange = requestNum ? expandEndToSentenceBoundary(chunkRange) : expandRangeToSentenceBoundary(chunkRange);
- SpellCheckRequest* request = SpellCheckRequest::create(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkRange, paragraphRange, requestNum);
+ SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingTypeSpelling, TextCheckingProcessBatch, checkRange, paragraphRange, requestNum);
if (request)
m_spellCheckRequester->requestCheckingFor(request);
@@ -582,7 +474,6 @@ void SpellChecker::markAndReplaceFor(SpellCheckRequest* request, const Vector<Te
TextCheckingParagraph paragraph(request->checkingRange(), request->paragraphRange());
bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
- bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
// Expand the range to encompass entire paragraphs, since text checking needs that much context.
int selectionOffset = 0;
@@ -628,18 +519,6 @@ void SpellChecker::markAndReplaceFor(SpellCheckRequest* request, const Vector<Te
DCHECK_GE(resultLocation, 0);
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)) {
- DCHECK_GT(resultLength, 0);
- DCHECK_GE(resultLocation, 0);
- for (unsigned j = 0; j < result->details.size(); j++) {
- const GrammarDetail* detail = &result->details[j];
- DCHECK_GT(detail->length, 0);
- DCHECK_GE(detail->location, 0);
- if (paragraph.checkingRangeCovers(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) {
DCHECK_GT(resultLength, 0);
DCHECK_GE(resultLocation, 0);
@@ -666,25 +545,6 @@ void SpellChecker::markAndReplaceFor(SpellCheckRequest* request, const Vector<Te
}
}
-void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection)
-{
- if (unifiedTextCheckerEnabled()) {
- if (!isContinuousSpellCheckingEnabled())
- return;
-
- // markMisspellingsAndBadGrammar() is triggered by selection change, in which case we check spelling and grammar, but don't autocorrect misspellings.
- TextCheckingTypeMask textCheckingOptions = TextCheckingTypeSpelling;
- if (markGrammar)
- textCheckingOptions |= TextCheckingTypeGrammar;
- markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellingSelection.toNormalizedEphemeralRange(), grammarSelection.toNormalizedEphemeralRange());
- return;
- }
-
- markMisspellings(spellingSelection);
- if (markGrammar)
- markBadGrammar(grammarSelection);
-}
-
void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSelectionAtWordBoundary)
{
DCHECK(frame().selection().isAvailable());
@@ -777,8 +637,6 @@ void SpellChecker::didEndEditingOnTextField(Element* e)
HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlElement(e);
HTMLElement* innerEditor = textFormControlElement->innerEditorElement();
DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling);
- if (unifiedTextCheckerEnabled())
- markerTypes.add(DocumentMarker::Grammar);
for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor))
frame().document()->markers().removeMarkers(&node, markerTypes);
}
@@ -819,7 +677,6 @@ void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelectio
// When continuous spell checking is off, existing markers disappear after the selection changes.
if (!isContinuousSpellCheckingEnabled()) {
frame().document()->markers().removeMarkers(DocumentMarker::Spelling);
- frame().document()->markers().removeMarkers(DocumentMarker::Grammar);
return;
}
@@ -886,12 +743,8 @@ void SpellChecker::spellCheckOldSelection(const VisibleSelection& oldSelection,
VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary));
if (oldAdjacentWords == newAdjacentWords)
return;
- if (isContinuousSpellCheckingEnabled()) {
- VisibleSelection selectedSentence = VisibleSelection(startOfSentence(oldStart), endOfSentence(oldStart));
- markMisspellingsAndBadGrammar(oldAdjacentWords, true, selectedSentence);
- return;
- }
- markMisspellingsAndBadGrammar(oldAdjacentWords, false, oldAdjacentWords);
+
+ markMisspellingsAndBadGrammar(oldAdjacentWords);
}
static Node* findFirstMarkable(Node* node)
@@ -935,20 +788,6 @@ bool SpellChecker::selectionStartHasSpellingMarkerFor(int from, int length) cons
return selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
}
-TextCheckingTypeMask SpellChecker::resolveTextCheckingTypeMask(TextCheckingTypeMask textCheckingOptions)
-{
- bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling;
- bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar;
-
- TextCheckingTypeMask checkingTypes = 0;
- if (shouldMarkSpelling)
- checkingTypes |= TextCheckingTypeSpelling;
- if (shouldMarkGrammar)
- checkingTypes |= TextCheckingTypeGrammar;
-
- return checkingTypes;
-}
-
void SpellChecker::removeMarkers(const VisibleSelection& selection, DocumentMarker::MarkerTypes markerTypes)
{
const EphemeralRange range = selection.toNormalizedEphemeralRange();
@@ -970,7 +809,7 @@ void SpellChecker::cancelCheck()
void SpellChecker::requestTextChecking(const Element& element)
{
const EphemeralRange rangeToCheck = EphemeralRange::rangeOfContents(element);
- m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextCheckingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToCheck, rangeToCheck));
+ m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextCheckingTypeSpelling, TextCheckingProcessBatch, rangeToCheck, rangeToCheck));
}
DEFINE_TRACE(SpellChecker)
« no previous file with comments | « third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.h ('k') | third_party/WebKit/Source/web/tests/WebFrameTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698