OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/spellchecker/spellcheck.h" | 5 #include "chrome/renderer/spellchecker/spellcheck.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 // report the word as correctly spelled.) | 257 // report the word as correctly spelled.) |
258 if (InitializeIfNeeded()) | 258 if (InitializeIfNeeded()) |
259 return true; | 259 return true; |
260 | 260 |
261 // These are for holding misspelling or skippable word positions and lengths | 261 // These are for holding misspelling or skippable word positions and lengths |
262 // between calls to SpellcheckLanguage::SpellCheckWord. | 262 // between calls to SpellcheckLanguage::SpellCheckWord. |
263 int possible_misspelling_start; | 263 int possible_misspelling_start; |
264 int possible_misspelling_len; | 264 int possible_misspelling_len; |
265 // The longest sequence of text that all languages agree is skippable. | 265 // The longest sequence of text that all languages agree is skippable. |
266 int agreed_skippable_len; | 266 int agreed_skippable_len; |
267 // A vector of vectors containing spelling suggestions from different | |
268 // languages. | |
269 std::vector<std::vector<base::string16>> suggestions_list; | |
267 | 270 |
268 // This loop only advances if all languages agree that a sequence of text is | 271 // This loop only advances if all languages agree that a sequence of text is |
269 // skippable. | 272 // skippable. |
270 for (; position_in_text <= text_length; | 273 for (; position_in_text <= text_length; |
271 position_in_text += agreed_skippable_len) { | 274 position_in_text += agreed_skippable_len) { |
272 // Reseting |agreed_skippable_len| to the worst-case length each time | 275 // Reseting |agreed_skippable_len| to the worst-case length each time |
273 // prevents some unnecessary iterations. | 276 // prevents some unnecessary iterations. |
274 agreed_skippable_len = text_length; | 277 agreed_skippable_len = text_length; |
275 *misspelling_start = 0; | 278 *misspelling_start = 0; |
276 *misspelling_len = 0; | 279 *misspelling_len = 0; |
277 | 280 suggestions_list.clear(); |
278 if (optional_suggestions) | |
279 optional_suggestions->clear(); | |
280 | 281 |
281 for (ScopedVector<SpellcheckLanguage>::iterator language = | 282 for (ScopedVector<SpellcheckLanguage>::iterator language = |
282 languages_.begin(); | 283 languages_.begin(); |
283 language != languages_.end();) { | 284 language != languages_.end();) { |
285 std::vector<base::string16> language_suggestions; | |
284 SpellcheckLanguage::SpellcheckWordResult result = | 286 SpellcheckLanguage::SpellcheckWordResult result = |
285 (*language)->SpellCheckWord(text_begin, position_in_text, text_length, | 287 (*language)->SpellCheckWord( |
286 tag, &possible_misspelling_start, | 288 text_begin, position_in_text, text_length, tag, |
287 &possible_misspelling_len, | 289 &possible_misspelling_start, &possible_misspelling_len, |
288 optional_suggestions); | 290 optional_suggestions ? &language_suggestions : nullptr); |
289 | 291 |
290 switch (result) { | 292 switch (result) { |
291 case SpellcheckLanguage::SpellcheckWordResult::IS_CORRECT: | 293 case SpellcheckLanguage::SpellcheckWordResult::IS_CORRECT: |
292 *misspelling_start = 0; | 294 *misspelling_start = 0; |
293 *misspelling_len = 0; | 295 *misspelling_len = 0; |
294 return true; | 296 return true; |
295 case SpellcheckLanguage::SpellcheckWordResult::IS_SKIPPABLE: | 297 case SpellcheckLanguage::SpellcheckWordResult::IS_SKIPPABLE: |
296 agreed_skippable_len = | 298 agreed_skippable_len = |
297 std::min(agreed_skippable_len, possible_misspelling_len); | 299 std::min(agreed_skippable_len, possible_misspelling_len); |
298 // If true, this means the spellchecker moved past a word that was | 300 // If true, this means the spellchecker moved past a word that was |
299 // previously determined to be misspelled or skippable, which means | 301 // previously determined to be misspelled or skippable, which means |
300 // another spellcheck language marked it as correct. | 302 // another spellcheck language marked it as correct. |
301 if (position_in_text != possible_misspelling_start) { | 303 if (position_in_text != possible_misspelling_start) { |
302 *misspelling_len = 0; | 304 *misspelling_len = 0; |
303 position_in_text = possible_misspelling_start; | 305 position_in_text = possible_misspelling_start; |
306 if (optional_suggestions) | |
307 suggestions_list.clear(); | |
please use gerrit instead
2015/08/20 18:40:23
If optional_suggestions is null, then suggestions_
Julius
2015/08/20 21:52:50
Done.
| |
304 language = languages_.begin(); | 308 language = languages_.begin(); |
305 } else { | 309 } else { |
306 language++; | 310 language++; |
307 } | 311 } |
308 break; | 312 break; |
309 case SpellcheckLanguage::SpellcheckWordResult::IS_MISSPELLED: | 313 case SpellcheckLanguage::SpellcheckWordResult::IS_MISSPELLED: |
310 *misspelling_start = possible_misspelling_start; | 314 *misspelling_start = possible_misspelling_start; |
311 *misspelling_len = possible_misspelling_len; | 315 *misspelling_len = possible_misspelling_len; |
312 // If true, this means the spellchecker moved past a word that was | 316 // If true, this means the spellchecker moved past a word that was |
313 // previously determined to be misspelled or skippable, which means | 317 // previously determined to be misspelled or skippable, which means |
314 // another spellcheck language marked it as correct. | 318 // another spellcheck language marked it as correct. |
315 language = position_in_text != *misspelling_start ? languages_.begin() | 319 if (position_in_text != *misspelling_start) { |
316 : language + 1; | 320 suggestions_list.clear(); |
317 position_in_text = *misspelling_start; | 321 language = languages_.begin(); |
322 position_in_text = *misspelling_start; | |
323 } else { | |
324 // Only add the language's suggestions if this is not a newly | |
325 // determined misspelling. This prevents adding a list of | |
326 // suggestions twice. | |
please use gerrit instead
2015/08/20 18:40:23
I don't think this comment explains much, although
Julius
2015/08/20 21:52:50
Done.
| |
327 if (optional_suggestions) | |
please use gerrit instead
2015/08/20 18:40:23
Remove the if. Just push_back.
Julius
2015/08/20 21:52:50
Done.
| |
328 suggestions_list.push_back(language_suggestions); | |
329 language++; | |
330 } | |
318 break; | 331 break; |
319 } | 332 } |
320 } | 333 } |
321 | 334 |
322 // If |*misspelling_len| is non-zero, that means at least one language | 335 // If |*misspelling_len| is non-zero, that means at least one language |
323 // marked a word misspelled and no other language considered it correct. | 336 // marked a word misspelled and no other language considered it correct. |
324 if (*misspelling_len != 0) | 337 if (*misspelling_len != 0) { |
338 FillSuggestions(suggestions_list, optional_suggestions); | |
325 return false; | 339 return false; |
340 } | |
326 } | 341 } |
327 | 342 |
328 NOTREACHED(); | 343 NOTREACHED(); |
329 return true; | 344 return true; |
330 } | 345 } |
331 | 346 |
347 void SpellCheck::FillSuggestions( | |
please use gerrit instead
2015/08/20 18:40:23
Your function does nothing if |optional_suggestion
Julius
2015/08/20 21:52:51
Done.
| |
348 std::vector<std::vector<base::string16>>& suggestions_list, | |
349 std::vector<base::string16>* optional_suggestions) { | |
350 if (!optional_suggestions) | |
351 return; | |
352 | |
353 // A vector containing the indices of the current suggestion for each | |
354 // language's suggestion list. | |
355 std::vector<size_t> indices(suggestions_list.size(), 0); | |
356 // Take one suggestion at a time from each language's suggestions and add it | |
357 // to |optional_suggestions|. | |
358 for (size_t i = 0, num_empty = 0; | |
359 num_empty < suggestions_list.size() && | |
360 optional_suggestions->size() < | |
361 chrome::spellcheck_common::kMaxSuggestions; | |
362 i = (i + 1) % suggestions_list.size()) { | |
363 if (indices[i] < suggestions_list[i].size()) { | |
364 base::string16 suggestion = suggestions_list[i][indices[i]]; | |
please use gerrit instead
2015/08/20 18:40:23
Avoid copying |suggestion| by making it const-ref.
Julius
2015/08/20 21:52:51
Done.
| |
365 // Only add the suggestion if it's unique. | |
366 if (std::find_if(optional_suggestions->begin(), | |
please use gerrit instead
2015/08/20 18:40:23
You don't need a lambda and std::find_if. Use std:
Julius
2015/08/20 21:52:51
Wow, duh.
| |
367 optional_suggestions->end(), | |
368 [&suggestion](base::string16 word) { | |
369 return word == suggestion; | |
370 }) == optional_suggestions->end()) { | |
371 optional_suggestions->push_back(suggestion); | |
372 } | |
373 indices[i]++; | |
374 if (indices[i] == suggestions_list[i].size()) | |
please use gerrit instead
2015/08/20 18:40:23
You can reduce lines 373-374 into a single line:
Julius
2015/08/20 21:52:50
Done.
| |
375 num_empty++; | |
376 } | |
377 } | |
378 } | |
379 | |
332 bool SpellCheck::SpellCheckParagraph( | 380 bool SpellCheck::SpellCheckParagraph( |
333 const base::string16& text, | 381 const base::string16& text, |
334 WebVector<WebTextCheckingResult>* results) { | 382 WebVector<WebTextCheckingResult>* results) { |
335 #if !defined(USE_BROWSER_SPELLCHECKER) | 383 #if !defined(USE_BROWSER_SPELLCHECKER) |
336 // Mac and Android have their own spell checkers,so this method won't be used | 384 // Mac and Android have their own spell checkers,so this method won't be used |
337 DCHECK(results); | 385 DCHECK(results); |
338 std::vector<WebTextCheckingResult> textcheck_results; | 386 std::vector<WebTextCheckingResult> textcheck_results; |
339 size_t length = text.length(); | 387 size_t length = text.length(); |
340 size_t position_in_text = 0; | 388 size_t position_in_text = 0; |
341 | 389 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 | 601 |
554 bool SpellCheck::IsSpellcheckEnabled() { | 602 bool SpellCheck::IsSpellcheckEnabled() { |
555 #if defined(OS_ANDROID) | 603 #if defined(OS_ANDROID) |
556 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 604 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
557 switches::kEnableAndroidSpellChecker)) { | 605 switches::kEnableAndroidSpellChecker)) { |
558 return false; | 606 return false; |
559 } | 607 } |
560 #endif | 608 #endif |
561 return spellcheck_enabled_; | 609 return spellcheck_enabled_; |
562 } | 610 } |
OLD | NEW |