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

Side by Side Diff: chrome/renderer/spellchecker/spellcheck.cc

Issue 1300213002: Offers suggestions for each language that marks a word misspelled. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@multi-spellcheck
Patch Set: Addressed comments. Created 5 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 unified diff | Download patch
OLDNEW
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
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;
270 // A vector to hold a language's misspelling suggestions between spellcheck
271 // calls.
272 std::vector<base::string16> language_suggestions;
267 273
268 // This loop only advances if all languages agree that a sequence of text is 274 // This loop only advances if all languages agree that a sequence of text is
269 // skippable. 275 // skippable.
270 for (; position_in_text <= text_length; 276 for (; position_in_text <= text_length;
271 position_in_text += agreed_skippable_len) { 277 position_in_text += agreed_skippable_len) {
272 // Reseting |agreed_skippable_len| to the worst-case length each time 278 // Reseting |agreed_skippable_len| to the worst-case length each time
273 // prevents some unnecessary iterations. 279 // prevents some unnecessary iterations.
274 agreed_skippable_len = text_length; 280 agreed_skippable_len = text_length;
275 *misspelling_start = 0; 281 *misspelling_start = 0;
276 *misspelling_len = 0; 282 *misspelling_len = 0;
277 283 suggestions_list.clear();
278 if (optional_suggestions)
279 optional_suggestions->clear();
280 284
281 for (ScopedVector<SpellcheckLanguage>::iterator language = 285 for (ScopedVector<SpellcheckLanguage>::iterator language =
282 languages_.begin(); 286 languages_.begin();
283 language != languages_.end();) { 287 language != languages_.end();) {
288 language_suggestions.clear();
284 SpellcheckLanguage::SpellcheckWordResult result = 289 SpellcheckLanguage::SpellcheckWordResult result =
285 (*language)->SpellCheckWord(text_begin, position_in_text, text_length, 290 (*language)->SpellCheckWord(
286 tag, &possible_misspelling_start, 291 text_begin, position_in_text, text_length, tag,
287 &possible_misspelling_len, 292 &possible_misspelling_start, &possible_misspelling_len,
288 optional_suggestions); 293 optional_suggestions ? &language_suggestions : nullptr);
289 294
290 switch (result) { 295 switch (result) {
291 case SpellcheckLanguage::SpellcheckWordResult::IS_CORRECT: 296 case SpellcheckLanguage::SpellcheckWordResult::IS_CORRECT:
292 *misspelling_start = 0; 297 *misspelling_start = 0;
293 *misspelling_len = 0; 298 *misspelling_len = 0;
294 return true; 299 return true;
295 case SpellcheckLanguage::SpellcheckWordResult::IS_SKIPPABLE: 300 case SpellcheckLanguage::SpellcheckWordResult::IS_SKIPPABLE:
296 agreed_skippable_len = 301 agreed_skippable_len =
297 std::min(agreed_skippable_len, possible_misspelling_len); 302 std::min(agreed_skippable_len, possible_misspelling_len);
298 // If true, this means the spellchecker moved past a word that was 303 // If true, this means the spellchecker moved past a word that was
299 // previously determined to be misspelled or skippable, which means 304 // previously determined to be misspelled or skippable, which means
300 // another spellcheck language marked it as correct. 305 // another spellcheck language marked it as correct.
301 if (position_in_text != possible_misspelling_start) { 306 if (position_in_text != possible_misspelling_start) {
302 *misspelling_len = 0; 307 *misspelling_len = 0;
303 position_in_text = possible_misspelling_start; 308 position_in_text = possible_misspelling_start;
309 suggestions_list.clear();
304 language = languages_.begin(); 310 language = languages_.begin();
305 } else { 311 } else {
306 language++; 312 language++;
307 } 313 }
308 break; 314 break;
309 case SpellcheckLanguage::SpellcheckWordResult::IS_MISSPELLED: 315 case SpellcheckLanguage::SpellcheckWordResult::IS_MISSPELLED:
310 *misspelling_start = possible_misspelling_start; 316 *misspelling_start = possible_misspelling_start;
311 *misspelling_len = possible_misspelling_len; 317 *misspelling_len = possible_misspelling_len;
312 // If true, this means the spellchecker moved past a word that was 318 // If true, this means the spellchecker moved past a word that was
313 // previously determined to be misspelled or skippable, which means 319 // previously determined to be misspelled or skippable, which means
314 // another spellcheck language marked it as correct. 320 // another spellcheck language marked it as correct.
315 language = position_in_text != *misspelling_start ? languages_.begin() 321 if (position_in_text != *misspelling_start) {
316 : language + 1; 322 suggestions_list.clear();
317 position_in_text = *misspelling_start; 323 language = languages_.begin();
324 position_in_text = *misspelling_start;
325 } else {
326 suggestions_list.push_back(language_suggestions);
327 language++;
328 }
318 break; 329 break;
319 } 330 }
320 } 331 }
321 332
322 // If |*misspelling_len| is non-zero, that means at least one language 333 // If |*misspelling_len| is non-zero, that means at least one language
323 // marked a word misspelled and no other language considered it correct. 334 // marked a word misspelled and no other language considered it correct.
324 if (*misspelling_len != 0) 335 if (*misspelling_len != 0) {
336 if (optional_suggestions)
337 FillSuggestions(suggestions_list, optional_suggestions);
325 return false; 338 return false;
339 }
326 } 340 }
327 341
328 NOTREACHED(); 342 NOTREACHED();
329 return true; 343 return true;
330 } 344 }
331 345
346 void SpellCheck::FillSuggestions(
please use gerrit instead 2015/08/20 22:14:27 Match the order of functions in the header and the
Julius 2015/08/21 00:39:19 Done.
347 const std::vector<std::vector<base::string16>>& suggestions_list,
348 std::vector<base::string16>* optional_suggestions) {
349 // A vector containing the indices of the current suggestion for each
350 // language's suggestion list.
351 std::vector<size_t> indices(suggestions_list.size(), 0);
352 // Take one suggestion at a time from each language's suggestions and add it
353 // to |optional_suggestions|.
354 for (size_t i = 0, num_empty = 0;
355 num_empty < suggestions_list.size() &&
356 optional_suggestions->size() <
357 chrome::spellcheck_common::kMaxSuggestions;
358 i = (i + 1) % suggestions_list.size()) {
359 if (indices[i] < suggestions_list[i].size()) {
360 const base::string16& suggestion = suggestions_list[i][indices[i]];
361 // Only add the suggestion if it's unique.
362 if (std::find(optional_suggestions->begin(), optional_suggestions->end(),
363 suggestion) == optional_suggestions->end()) {
364 optional_suggestions->push_back(suggestion);
365 }
366 if (++indices[i] == suggestions_list[i].size())
367 num_empty++;
368 }
369 }
370 }
371
332 bool SpellCheck::SpellCheckParagraph( 372 bool SpellCheck::SpellCheckParagraph(
333 const base::string16& text, 373 const base::string16& text,
334 WebVector<WebTextCheckingResult>* results) { 374 WebVector<WebTextCheckingResult>* results) {
335 #if !defined(USE_BROWSER_SPELLCHECKER) 375 #if !defined(USE_BROWSER_SPELLCHECKER)
336 // Mac and Android have their own spell checkers,so this method won't be used 376 // Mac and Android have their own spell checkers,so this method won't be used
337 DCHECK(results); 377 DCHECK(results);
338 std::vector<WebTextCheckingResult> textcheck_results; 378 std::vector<WebTextCheckingResult> textcheck_results;
339 size_t length = text.length(); 379 size_t length = text.length();
340 size_t position_in_text = 0; 380 size_t position_in_text = 0;
341 381
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 593
554 bool SpellCheck::IsSpellcheckEnabled() { 594 bool SpellCheck::IsSpellcheckEnabled() {
555 #if defined(OS_ANDROID) 595 #if defined(OS_ANDROID)
556 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( 596 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
557 switches::kEnableAndroidSpellChecker)) { 597 switches::kEnableAndroidSpellChecker)) {
558 return false; 598 return false;
559 } 599 }
560 #endif 600 #endif
561 return spellcheck_enabled_; 601 return spellcheck_enabled_;
562 } 602 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698