static void findMisspellings(TextCheckerClient& client, StringView text, Vector<TextCheckingResult>& results) { TextBreakIterator* iterator = wordBreakIterator(text); if (!iterator) return; for (int wordStart = textBreakCurrent(iterator); wordStart > 0; ) { int wordEnd = textBreakNext(iterator); if (wordEnd < 0) break; int wordLength = wordEnd - wordStart; int misspellingLocation = -1; int misspellingLength = 0; client.checkSpellingOfString(text.substring(wordStart, wordLength), &misspellingLocation, &misspellingLength); if (misspellingLength > 0) { ASSERT(misspellingLocation >= 0); ASSERT(misspellingLocation <= wordLength); ASSERT(misspellingLength > 0); ASSERT(misspellingLocation + misspellingLength <= wordLength); TextCheckingResult misspelling; misspelling.type = TextCheckingTypeSpelling; misspelling.location = wordStart + misspellingLocation; misspelling.length = misspellingLength; misspelling.replacement = client.getAutoCorrectSuggestionForMisspelledWord(text.substring(misspelling.location, misspelling.length).toStringWithoutCopying()); results.append(misspelling); } wordStart = wordEnd; } }
static void findMisspellings(TextCheckerClient& client, const UChar* text, int start, int length, Vector<TextCheckingResult>& results) { TextBreakIterator* iterator = wordBreakIterator(text + start, 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; client.checkSpellingOfString(String(text + start + wordStart, wordLength), &misspellingLocation, &misspellingLength); if (0 < misspellingLength) { ASSERT(0 <= misspellingLocation && misspellingLocation <= wordLength); ASSERT(0 < misspellingLength && misspellingLocation + misspellingLength <= wordLength); TextCheckingResult misspelling; misspelling.decoration = TextDecorationTypeSpelling; misspelling.location = start + wordStart + misspellingLocation; misspelling.length = misspellingLength; misspelling.replacement = client.getAutoCorrectSuggestionForMisspelledWord(String(text + misspelling.location, misspelling.length)); results.append(misspelling); } wordStart = wordEnd; } }
static void findBadGrammars(TextCheckerClient& client, const UChar* text, int start, int length, Vector<TextCheckingResult>& results) { int checkLocation = start; int checkLength = length; while (0 < checkLength) { int badGrammarLocation = -1; int badGrammarLength = 0; Vector<GrammarDetail> badGrammarDetails; client.checkGrammarOfString(String(text + checkLocation, checkLength), badGrammarDetails, &badGrammarLocation, &badGrammarLength); if (!badGrammarLength) break; ASSERT(0 <= badGrammarLocation && badGrammarLocation <= checkLength); ASSERT(0 < badGrammarLength && badGrammarLocation + badGrammarLength <= checkLength); TextCheckingResult badGrammar; badGrammar.decoration = TextDecorationTypeGrammar; badGrammar.location = checkLocation + badGrammarLocation; badGrammar.length = badGrammarLength; badGrammar.details.swap(badGrammarDetails); results.append(badGrammar); checkLocation += (badGrammarLocation + badGrammarLength); checkLength -= (badGrammarLocation + badGrammarLength); } }
void checkTextOfParagraph(TextCheckerClient& client, StringView text, TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results) { #if USE(UNIFIED_TEXT_CHECKING) results = client.checkTextOfParagraph(text, checkingTypes); #else Vector<TextCheckingResult> mispellings; if (checkingTypes & TextCheckingTypeSpelling) findMisspellings(client, text, mispellings); #if USE(GRAMMAR_CHECKING) // Look for grammatical errors that occur before the first misspelling. Vector<TextCheckingResult> grammaticalErrors; if (checkingTypes & TextCheckingTypeGrammar) { unsigned grammarCheckLength = text.length(); for (auto& mispelling : mispellings) grammarCheckLength = std::min<unsigned>(grammarCheckLength, mispelling.location); findGrammaticalErrors(client, text.substring(0, grammarCheckLength), grammaticalErrors); } results = std::move(grammaticalErrors); #endif if (results.isEmpty()) results = std::move(mispellings); else results.appendVector(mispellings); #endif // USE(UNIFIED_TEXT_CHECKING) }
static void findGrammaticalErrors(TextCheckerClient& client, StringView text, Vector<TextCheckingResult>& results) { for (unsigned checkLocation = 0; checkLocation < text.length(); ) { int badGrammarLocation = -1; int badGrammarLength = 0; Vector<GrammarDetail> badGrammarDetails; client.checkGrammarOfString(text.substring(checkLocation), badGrammarDetails, &badGrammarLocation, &badGrammarLength); if (!badGrammarLength) break; ASSERT(badGrammarLocation >= 0); ASSERT(static_cast<unsigned>(badGrammarLocation) <= text.length() - checkLocation); ASSERT(badGrammarLength > 0); ASSERT(static_cast<unsigned>(badGrammarLength) <= text.length() - checkLocation - badGrammarLocation); TextCheckingResult badGrammar; badGrammar.type = TextCheckingTypeGrammar; badGrammar.location = checkLocation + badGrammarLocation; badGrammar.length = badGrammarLength; badGrammar.details = std::move(badGrammarDetails); results.append(badGrammar); checkLocation += badGrammarLocation + badGrammarLength; } }
bool AccessibilityObject::hasMisspelling() const { if (!node()) return false; Document* document = node()->document(); if (!document) return false; Frame* frame = document->frame(); if (!frame) return false; Editor* editor = frame->editor(); if (!editor) return false; TextCheckerClient* textChecker = editor->textChecker(); if (!textChecker) return false; const UChar* chars = stringValue().characters(); int charsLength = stringValue().length(); bool isMisspelled = false; if (unifiedTextCheckerEnabled(frame)) { Vector<TextCheckingResult> results; checkTextOfParagraph(textChecker, chars, charsLength, TextCheckingTypeSpelling, results); if (!results.isEmpty()) isMisspelled = true; return isMisspelled; } int misspellingLength = 0; int misspellingLocation = -1; textChecker->checkSpellingOfString(chars, charsLength, &misspellingLocation, &misspellingLength); if (misspellingLength || misspellingLocation != -1) isMisspelled = true; return isMisspelled; }