Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 | 26 |
| 27 #include "core/editing/spellcheck/TextCheckingHelper.h" | 27 #include "core/editing/spellcheck/TextCheckingHelper.h" |
| 28 | 28 |
| 29 #include "core/dom/Document.h" | 29 #include "core/dom/Document.h" |
| 30 #include "core/dom/Range.h" | 30 #include "core/dom/Range.h" |
| 31 #include "core/editing/VisiblePosition.h" | 31 #include "core/editing/VisiblePosition.h" |
| 32 #include "core/editing/VisibleUnits.h" | 32 #include "core/editing/VisibleUnits.h" |
| 33 #include "core/editing/iterators/CharacterIterator.h" | 33 #include "core/editing/iterators/CharacterIterator.h" |
| 34 #include "core/editing/iterators/WordAwareIterator.h" | 34 #include "core/editing/iterators/WordAwareIterator.h" |
| 35 #include "core/editing/markers/DocumentMarkerController.h" | 35 #include "core/editing/markers/DocumentMarkerController.h" |
| 36 #include "core/editing/spellcheck/SpellChecker.h" | |
| 36 #include "core/frame/LocalFrame.h" | 37 #include "core/frame/LocalFrame.h" |
| 37 #include "core/frame/Settings.h" | 38 #include "core/frame/Settings.h" |
| 38 #include "core/page/SpellCheckerClient.h" | 39 #include "core/page/SpellCheckerClient.h" |
| 39 #include "platform/text/TextBreakIterator.h" | 40 #include "platform/text/TextBreakIterator.h" |
| 40 #include "platform/text/TextCheckerClient.h" | 41 #include "platform/text/TextCheckerClient.h" |
| 41 | 42 |
| 42 namespace blink { | 43 namespace blink { |
| 43 | 44 |
| 44 static void findMisspellings(TextCheckerClient& client, const String& text, Vect or<TextCheckingResult>& results) | 45 void SpellChecker::findMisspellings(const String& text, Vector<TextCheckingResul t>& results) |
|
yosin_UTC9
2016/08/16 08:30:32
Please add TODO comment that this function should
Xiaocheng
2016/08/16 08:32:25
Whoops, done.
| |
| 45 { | 46 { |
| 46 Vector<UChar> characters; | 47 Vector<UChar> characters; |
| 47 text.appendTo(characters); | 48 text.appendTo(characters); |
| 48 unsigned length = text.length(); | 49 unsigned length = text.length(); |
| 49 | 50 |
| 50 TextBreakIterator* iterator = wordBreakIterator(characters.data(), length); | 51 TextBreakIterator* iterator = wordBreakIterator(characters.data(), length); |
| 51 if (!iterator) | 52 if (!iterator) |
| 52 return; | 53 return; |
| 53 | 54 |
| 54 int wordStart = iterator->current(); | 55 int wordStart = iterator->current(); |
| 55 while (0 <= wordStart) { | 56 while (0 <= wordStart) { |
| 56 int wordEnd = iterator->next(); | 57 int wordEnd = iterator->next(); |
| 57 if (wordEnd < 0) | 58 if (wordEnd < 0) |
| 58 break; | 59 break; |
| 59 int wordLength = wordEnd - wordStart; | 60 int wordLength = wordEnd - wordStart; |
| 60 int misspellingLocation = -1; | 61 int misspellingLocation = -1; |
| 61 int misspellingLength = 0; | 62 int misspellingLength = 0; |
| 62 client.checkSpellingOfString(String(characters.data() + wordStart, wordL ength), &misspellingLocation, &misspellingLength); | 63 textChecker().checkSpellingOfString(String(characters.data() + wordStart , wordLength), &misspellingLocation, &misspellingLength); |
| 63 if (0 < misspellingLength) { | 64 if (0 < misspellingLength) { |
| 64 DCHECK_LE(0, misspellingLocation); | 65 DCHECK_LE(0, misspellingLocation); |
| 65 DCHECK_LE(misspellingLocation, wordLength); | 66 DCHECK_LE(misspellingLocation, wordLength); |
| 66 DCHECK_LT(0, misspellingLength); | 67 DCHECK_LT(0, misspellingLength); |
| 67 DCHECK_LE(misspellingLocation + misspellingLength, wordLength); | 68 DCHECK_LE(misspellingLocation + misspellingLength, wordLength); |
| 68 TextCheckingResult misspelling; | 69 TextCheckingResult misspelling; |
| 69 misspelling.decoration = TextDecorationTypeSpelling; | 70 misspelling.decoration = TextDecorationTypeSpelling; |
| 70 misspelling.location = wordStart + misspellingLocation; | 71 misspelling.location = wordStart + misspellingLocation; |
| 71 misspelling.length = misspellingLength; | 72 misspelling.length = misspellingLength; |
| 72 results.append(misspelling); | 73 results.append(misspelling); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 214 } | 215 } |
| 215 | 216 |
| 216 int TextCheckingParagraph::checkingLength() const | 217 int TextCheckingParagraph::checkingLength() const |
| 217 { | 218 { |
| 218 DCHECK(m_checkingRange.isNotNull()); | 219 DCHECK(m_checkingRange.isNotNull()); |
| 219 if (-1 == m_checkingLength) | 220 if (-1 == m_checkingLength) |
| 220 m_checkingLength = TextIterator::rangeLength(checkingRange().startPositi on(), checkingRange().endPosition()); | 221 m_checkingLength = TextIterator::rangeLength(checkingRange().startPositi on(), checkingRange().endPosition()); |
| 221 return m_checkingLength; | 222 return m_checkingLength; |
| 222 } | 223 } |
| 223 | 224 |
| 224 TextCheckingHelper::TextCheckingHelper(SpellCheckerClient& client, const Positio n& start, const Position& end) | 225 String SpellChecker::findFirstMisspellingOrBadGrammar(const Position& start, con st Position& end, int& outFirstFoundOffset) |
| 225 : m_client(&client) | |
| 226 , m_start(start) | |
| 227 , m_end(end) | |
| 228 { | |
| 229 } | |
| 230 | |
| 231 TextCheckingHelper::~TextCheckingHelper() | |
| 232 { | |
| 233 } | |
| 234 | |
| 235 String TextCheckingHelper::findFirstMisspellingOrBadGrammar(int& outFirstFoundOf fset) | |
| 236 { | 226 { |
| 237 String firstFoundItem; | 227 String firstFoundItem; |
| 238 String misspelledWord; | 228 String misspelledWord; |
| 239 | 229 |
| 240 // Initialize out parameter; it will be updated if we find something to retu rn. | 230 // Initialize out parameter; it will be updated if we find something to retu rn. |
| 241 outFirstFoundOffset = 0; | 231 outFirstFoundOffset = 0; |
| 242 | 232 |
| 243 // Expand the search range to encompass entire paragraphs, since text checki ng needs that much context. | 233 // Expand the search range to encompass entire paragraphs, since text checki ng needs that much context. |
| 244 // Determine the character offset from the start of the paragraph to the sta rt of the original search range, | 234 // Determine the character offset from the start of the paragraph to the sta rt of the original search range, |
| 245 // since we will want to ignore results in this area. | 235 // since we will want to ignore results in this area. |
| 246 Position paragraphStart = startOfParagraph(createVisiblePosition(m_start)).t oParentAnchoredPosition(); | 236 Position paragraphStart = startOfParagraph(createVisiblePosition(start)).toP arentAnchoredPosition(); |
| 247 Position paragraphEnd = m_end; | 237 Position paragraphEnd = end; |
| 248 int totalRangeLength = TextIterator::rangeLength(paragraphStart, paragraphEn d); | 238 int totalRangeLength = TextIterator::rangeLength(paragraphStart, paragraphEn d); |
| 249 paragraphEnd = endOfParagraph(createVisiblePosition(m_start)).toParentAnchor edPosition(); | 239 paragraphEnd = endOfParagraph(createVisiblePosition(start)).toParentAnchored Position(); |
| 250 | 240 |
| 251 int rangeStartOffset = TextIterator::rangeLength(paragraphStart, m_start); | 241 int rangeStartOffset = TextIterator::rangeLength(paragraphStart, start); |
| 252 int totalLengthProcessed = 0; | 242 int totalLengthProcessed = 0; |
| 253 | 243 |
| 254 bool firstIteration = true; | 244 bool firstIteration = true; |
| 255 bool lastIteration = false; | 245 bool lastIteration = false; |
| 256 while (totalLengthProcessed < totalRangeLength) { | 246 while (totalLengthProcessed < totalRangeLength) { |
| 257 // Iterate through the search range by paragraphs, checking each one for spelling. | 247 // Iterate through the search range by paragraphs, checking each one for spelling. |
| 258 int currentLength = TextIterator::rangeLength(paragraphStart, paragraphE nd); | 248 int currentLength = TextIterator::rangeLength(paragraphStart, paragraphE nd); |
| 259 int currentStartOffset = firstIteration ? rangeStartOffset : 0; | 249 int currentStartOffset = firstIteration ? rangeStartOffset : 0; |
| 260 int currentEndOffset = currentLength; | 250 int currentEndOffset = currentLength; |
| 261 if (inSameParagraph(createVisiblePosition(paragraphStart), createVisible Position(m_end))) { | 251 if (inSameParagraph(createVisiblePosition(paragraphStart), createVisible Position(end))) { |
| 262 // Determine the character offset from the end of the original searc h range to the end of the paragraph, | 252 // Determine the character offset from the end of the original searc h range to the end of the paragraph, |
| 263 // since we will want to ignore results in this area. | 253 // since we will want to ignore results in this area. |
| 264 currentEndOffset = TextIterator::rangeLength(paragraphStart, m_end); | 254 currentEndOffset = TextIterator::rangeLength(paragraphStart, end); |
| 265 lastIteration = true; | 255 lastIteration = true; |
| 266 } | 256 } |
| 267 if (currentStartOffset < currentEndOffset) { | 257 if (currentStartOffset < currentEndOffset) { |
| 268 String paragraphString = plainText(EphemeralRange(paragraphStart, pa ragraphEnd)); | 258 String paragraphString = plainText(EphemeralRange(paragraphStart, pa ragraphEnd)); |
| 269 if (paragraphString.length() > 0) { | 259 if (paragraphString.length() > 0) { |
| 270 int spellingLocation = 0; | 260 int spellingLocation = 0; |
| 271 | 261 |
| 272 Vector<TextCheckingResult> results; | 262 Vector<TextCheckingResult> results; |
| 273 findMisspellings(m_client->textChecker(), paragraphString, resul ts); | 263 findMisspellings(paragraphString, results); |
| 274 | 264 |
| 275 for (unsigned i = 0; i < results.size(); i++) { | 265 for (unsigned i = 0; i < results.size(); i++) { |
| 276 const TextCheckingResult* result = &results[i]; | 266 const TextCheckingResult* result = &results[i]; |
| 277 if (result->decoration == TextDecorationTypeSpelling && resu lt->location >= currentStartOffset && result->location + result->length <= curre ntEndOffset) { | 267 if (result->decoration == TextDecorationTypeSpelling && resu lt->location >= currentStartOffset && result->location + result->length <= curre ntEndOffset) { |
| 278 DCHECK_GT(result->length, 0); | 268 DCHECK_GT(result->length, 0); |
| 279 DCHECK_GE(result->location, 0); | 269 DCHECK_GE(result->location, 0); |
| 280 spellingLocation = result->location; | 270 spellingLocation = result->location; |
| 281 misspelledWord = paragraphString.substring(result->locat ion, result->length); | 271 misspelledWord = paragraphString.substring(result->locat ion, result->length); |
| 282 DCHECK(misspelledWord.length()); | 272 DCHECK(misspelledWord.length()); |
| 283 break; | 273 break; |
| 284 } | 274 } |
| 285 } | 275 } |
| 286 | 276 |
| 287 if (!misspelledWord.isEmpty()) { | 277 if (!misspelledWord.isEmpty()) { |
| 288 int spellingOffset = spellingLocation - currentStartOffset; | 278 int spellingOffset = spellingLocation - currentStartOffset; |
| 289 if (!firstIteration) | 279 if (!firstIteration) |
| 290 spellingOffset += TextIterator::rangeLength(m_start, par agraphStart); | 280 spellingOffset += TextIterator::rangeLength(start, parag raphStart); |
| 291 outFirstFoundOffset = spellingOffset; | 281 outFirstFoundOffset = spellingOffset; |
| 292 firstFoundItem = misspelledWord; | 282 firstFoundItem = misspelledWord; |
| 293 break; | 283 break; |
| 294 } | 284 } |
| 295 } | 285 } |
| 296 } | 286 } |
| 297 if (lastIteration || totalLengthProcessed + currentLength >= totalRangeL ength) | 287 if (lastIteration || totalLengthProcessed + currentLength >= totalRangeL ength) |
| 298 break; | 288 break; |
| 299 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo sition(paragraphEnd)); | 289 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo sition(paragraphEnd)); |
| 300 paragraphStart = newParagraphStart.toParentAnchoredPosition(); | 290 paragraphStart = newParagraphStart.toParentAnchoredPosition(); |
| 301 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio n(); | 291 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio n(); |
| 302 firstIteration = false; | 292 firstIteration = false; |
| 303 totalLengthProcessed += currentLength; | 293 totalLengthProcessed += currentLength; |
| 304 } | 294 } |
| 305 return firstFoundItem; | 295 return firstFoundItem; |
| 306 } | 296 } |
| 307 | 297 |
| 308 } // namespace blink | 298 } // namespace blink |
| OLD | NEW |