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

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

Issue 2247003005: Eliminate class TextCheckingHelper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@CleanupUnifiedTextChecker
Patch Set: Created 4 years, 4 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 931a12f679b2e71586a9b4ad451789373405eaff..50e206051aa131a19b52ac058dc9e6e3e5f5bae3 100644
--- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
+++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -39,7 +39,7 @@
#include "core/editing/iterators/CharacterIterator.h"
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/editing/spellcheck/SpellCheckRequester.h"
-#include "core/editing/spellcheck/TextCheckingHelper.h"
+#include "core/editing/spellcheck/TextCheckingParagraph.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/html/HTMLInputElement.h"
@@ -47,6 +47,7 @@
#include "core/loader/EmptyClients.h"
#include "core/page/Page.h"
#include "core/page/SpellCheckerClient.h"
+#include "platform/text/TextBreakIterator.h"
#include "platform/text/TextCheckerClient.h"
namespace blink {
@@ -157,6 +158,114 @@ void SpellChecker::ignoreSpelling()
removeMarkers(frame().selection().selection(), DocumentMarker::Spelling);
}
+void SpellChecker::findMisspellings(const String& text, Vector<TextCheckingResult>* results)
yosin_UTC9 2016/08/16 06:04:06 Since WTF::Vector is now movable[1], let's return
Xiaocheng 2016/08/16 06:21:35 Didn't know that. Done.
+{
+ Vector<UChar> characters;
+ text.appendTo(characters);
+ unsigned length = text.length();
+
+ TextBreakIterator* iterator = wordBreakIterator(characters.data(), length);
+ if (!iterator)
+ return;
+
+ int wordStart = iterator->current();
+ while (0 <= wordStart) {
+ int wordEnd = iterator->next();
+ if (wordEnd < 0)
+ break;
+ int wordLength = wordEnd - wordStart;
+ int misspellingLocation = -1;
+ int misspellingLength = 0;
+ textChecker().checkSpellingOfString(String(characters.data() + wordStart, wordLength), &misspellingLocation, &misspellingLength);
+ if (0 < misspellingLength) {
yosin_UTC9 2016/08/16 06:04:06 I prefer |misspellingLength > 0|
Xiaocheng 2016/08/16 06:21:36 Done.
+ DCHECK_LE(0, misspellingLocation);
yosin_UTC9 2016/08/16 06:04:06 I prefer DCHECK_GE(misspellingLocation, 0);
Xiaocheng 2016/08/16 06:21:35 Done.
+ DCHECK_LE(misspellingLocation, wordLength);
+ DCHECK_LT(0, misspellingLength);
yosin_UTC9 2016/08/16 06:04:06 I prefer DCHECK_GT(misspellingLength, 0)
Xiaocheng 2016/08/16 06:21:35 Done.
+ DCHECK_LE(misspellingLocation + misspellingLength, wordLength);
+ TextCheckingResult misspelling;
+ misspelling.decoration = TextDecorationTypeSpelling;
+ misspelling.location = wordStart + misspellingLocation;
+ misspelling.length = misspellingLength;
+ results->append(misspelling);
+ }
+
yosin_UTC9 2016/08/16 06:04:06 nit: Please remove an extra blank line.
Xiaocheng 2016/08/16 06:21:36 Done.
+ wordStart = wordEnd;
+ }
+}
+
+std::pair<String, int> SpellChecker::findFirstMisspelling(const Position& start, const Position& end)
+{
+ String misspelledWord;
+
+ // Initialize out parameter; it will be updated if we find something to return.
+ String firstFoundItem;
+ int firstFoundOffset = 0;
+
+ // Expand the search range to encompass entire paragraphs, since text checking needs that much context.
+ // Determine the character offset from the start of the paragraph to the start of the original search range,
+ // since we will want to ignore results in this area.
+ Position paragraphStart = startOfParagraph(createVisiblePosition(start)).toParentAnchoredPosition();
+ Position paragraphEnd = end;
+ int totalRangeLength = TextIterator::rangeLength(paragraphStart, paragraphEnd);
+ paragraphEnd = endOfParagraph(createVisiblePosition(start)).toParentAnchoredPosition();
+
+ int rangeStartOffset = TextIterator::rangeLength(paragraphStart, start);
+ int totalLengthProcessed = 0;
+
+ bool firstIteration = true;
+ bool lastIteration = false;
+ while (totalLengthProcessed < totalRangeLength) {
+ // Iterate through the search range by paragraphs, checking each one for spelling.
+ int currentLength = TextIterator::rangeLength(paragraphStart, paragraphEnd);
+ int currentStartOffset = firstIteration ? rangeStartOffset : 0;
+ int currentEndOffset = currentLength;
+ if (inSameParagraph(createVisiblePosition(paragraphStart), createVisiblePosition(end))) {
+ // Determine the character offset from the end of the original search range to the end of the paragraph,
+ // since we will want to ignore results in this area.
+ currentEndOffset = TextIterator::rangeLength(paragraphStart, end);
+ lastIteration = true;
+ }
+ if (currentStartOffset < currentEndOffset) {
+ String paragraphString = plainText(EphemeralRange(paragraphStart, paragraphEnd));
+ if (paragraphString.length() > 0) {
+ int spellingLocation = 0;
+
+ Vector<TextCheckingResult> results;
+ findMisspellings(paragraphString, &results);
+
+ for (unsigned i = 0; i < results.size(); i++) {
+ const TextCheckingResult* result = &results[i];
+ if (result->decoration == TextDecorationTypeSpelling && result->location >= currentStartOffset && result->location + result->length <= currentEndOffset) {
+ DCHECK_GT(result->length, 0);
+ DCHECK_GE(result->location, 0);
+ spellingLocation = result->location;
+ misspelledWord = paragraphString.substring(result->location, result->length);
+ DCHECK(misspelledWord.length());
+ break;
+ }
+ }
+
+ if (!misspelledWord.isEmpty()) {
+ int spellingOffset = spellingLocation - currentStartOffset;
+ if (!firstIteration)
+ spellingOffset += TextIterator::rangeLength(start, paragraphStart);
+ firstFoundOffset = spellingOffset;
+ firstFoundItem = misspelledWord;
+ break;
+ }
+ }
+ }
+ if (lastIteration || totalLengthProcessed + currentLength >= totalRangeLength)
+ break;
+ VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePosition(paragraphEnd));
+ paragraphStart = newParagraphStart.toParentAnchoredPosition();
+ paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPosition();
+ firstIteration = false;
+ totalLengthProcessed += currentLength;
+ }
+ return std::make_pair(firstFoundItem, firstFoundOffset);
+}
+
void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
{
DocumentLifecycle::DisallowTransitionScope(frame().document()->lifecycle());
@@ -226,8 +335,10 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode();
int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode();
- int misspellingOffset = 0;
- String misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset);
+ std::pair<String, int> misspelledItem("", 0);
+ String& misspelledWord = misspelledItem.first;
+ int& misspellingOffset = misspelledItem.second;
+ misspelledItem = findFirstMisspelling(spellingSearchStart, spellingSearchEnd);
// 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).
@@ -235,7 +346,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
spellingSearchStart = Position::editingPositionOf(topNode, 0);
// going until the end of the very first chunk we tested is far enough
spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap, searchEndOffsetAfterWrap);
- misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset);
+ misspelledItem = findFirstMisspelling(spellingSearchStart, spellingSearchEnd);
}
if (!misspelledWord.isEmpty()) {

Powered by Google App Engine
This is Rietveld 408576698