| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop_proxy.h" | 8 #include "base/message_loop_proxy.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "chrome/common/render_messages.h" | 10 #include "chrome/common/render_messages.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 string16 text_; // Text to be checked in this task. | 39 string16 text_; // Text to be checked in this task. |
| 40 int offset_; // The text offset from the beginning. | 40 int offset_; // The text offset from the beginning. |
| 41 | 41 |
| 42 // The interface to send the misspelled ranges to WebKit. | 42 // The interface to send the misspelled ranges to WebKit. |
| 43 WebKit::WebTextCheckingCompletion* completion_; | 43 WebKit::WebTextCheckingCompletion* completion_; |
| 44 | 44 |
| 45 DISALLOW_COPY_AND_ASSIGN(SpellcheckRequest); | 45 DISALLOW_COPY_AND_ASSIGN(SpellcheckRequest); |
| 46 }; | 46 }; |
| 47 | 47 |
| 48 SpellCheck::SpellCheck() : auto_spell_correct_turned_on_(false) { | 48 SpellCheck::SpellCheck() : auto_spell_correct_turned_on_(false) { |
| 49 platform_spelling_engine_.reset(CreateNativeSpellingEngine()); |
| 49 } | 50 } |
| 50 | 51 |
| 51 SpellCheck::~SpellCheck() { | 52 SpellCheck::~SpellCheck() { |
| 52 } | 53 } |
| 53 | 54 |
| 54 bool SpellCheck::OnControlMessageReceived(const IPC::Message& message) { | 55 bool SpellCheck::OnControlMessageReceived(const IPC::Message& message) { |
| 55 bool handled = true; | 56 bool handled = true; |
| 56 IPC_BEGIN_MESSAGE_MAP(SpellCheck, message) | 57 IPC_BEGIN_MESSAGE_MAP(SpellCheck, message) |
| 57 IPC_MESSAGE_HANDLER(SpellCheckMsg_Init, OnInit) | 58 IPC_MESSAGE_HANDLER(SpellCheckMsg_Init, OnInit) |
| 58 IPC_MESSAGE_HANDLER(SpellCheckMsg_WordAdded, OnWordAdded) | 59 IPC_MESSAGE_HANDLER(SpellCheckMsg_WordAdded, OnWordAdded) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 83 | 84 |
| 84 void SpellCheck::OnEnableAutoSpellCorrect(bool enable) { | 85 void SpellCheck::OnEnableAutoSpellCorrect(bool enable) { |
| 85 auto_spell_correct_turned_on_ = enable; | 86 auto_spell_correct_turned_on_ = enable; |
| 86 } | 87 } |
| 87 | 88 |
| 88 // TODO(groby): Make sure we always have a spelling engine, even before Init() | 89 // TODO(groby): Make sure we always have a spelling engine, even before Init() |
| 89 // is called. | 90 // is called. |
| 90 void SpellCheck::Init(base::PlatformFile file, | 91 void SpellCheck::Init(base::PlatformFile file, |
| 91 const std::vector<std::string>& custom_words, | 92 const std::vector<std::string>& custom_words, |
| 92 const std::string& language) { | 93 const std::string& language) { |
| 93 bool use_platform_spelling_engine = | 94 platform_spelling_engine_->Init(file, custom_words); |
| 94 file == base::kInvalidPlatformFileValue && !language.empty(); | |
| 95 | 95 |
| 96 // Some tests under OSX still exercise hunspell. Only init native engine | |
| 97 // when no dictionary was specified. | |
| 98 // TODO(groby): Figure out if we can kill the hunspell dependency for OSX. | |
| 99 if (use_platform_spelling_engine) { | |
| 100 platform_spelling_engine_.reset(CreateNativeSpellingEngine()); | |
| 101 } else { | |
| 102 HunspellEngine* engine = new HunspellEngine; | |
| 103 engine->Init(file, custom_words); | |
| 104 platform_spelling_engine_.reset(engine); | |
| 105 } | |
| 106 character_attributes_.SetDefaultLanguage(language); | 96 character_attributes_.SetDefaultLanguage(language); |
| 107 text_iterator_.Reset(); | 97 text_iterator_.Reset(); |
| 108 contraction_iterator_.Reset(); | 98 contraction_iterator_.Reset(); |
| 109 } | 99 } |
| 110 | 100 |
| 111 bool SpellCheck::SpellCheckWord( | 101 bool SpellCheck::SpellCheckWord( |
| 112 const char16* in_word, | 102 const char16* in_word, |
| 113 int in_word_len, | 103 int in_word_len, |
| 114 int tag, | 104 int tag, |
| 115 int* misspelling_start, | 105 int* misspelling_start, |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 pending_request_param_.reset(new SpellcheckRequest( | 264 pending_request_param_.reset(new SpellcheckRequest( |
| 275 text, offset, completion)); | 265 text, offset, completion)); |
| 276 // We will check this text after we finish loading the hunspell dictionary. | 266 // We will check this text after we finish loading the hunspell dictionary. |
| 277 if (InitializeIfNeeded()) | 267 if (InitializeIfNeeded()) |
| 278 return; | 268 return; |
| 279 | 269 |
| 280 PostDelayedSpellCheckTask(pending_request_param_.release()); | 270 PostDelayedSpellCheckTask(pending_request_param_.release()); |
| 281 } | 271 } |
| 282 #endif | 272 #endif |
| 283 | 273 |
| 284 | |
| 285 bool SpellCheck::InitializeIfNeeded() { | 274 bool SpellCheck::InitializeIfNeeded() { |
| 286 // TODO(groby): OSX creates a hunspell engine here, too. That seems | 275 DCHECK(platform_spelling_engine_.get()); |
| 287 // wrong, but is (AFAICT) the existing flow. Fix that. | |
| 288 if (!platform_spelling_engine_.get()) | |
| 289 platform_spelling_engine_.reset(new HunspellEngine); | |
| 290 | |
| 291 return platform_spelling_engine_->InitializeIfNeeded(); | 276 return platform_spelling_engine_->InitializeIfNeeded(); |
| 292 } | 277 } |
| 293 | 278 |
| 294 // When called, relays the request to check the spelling to the proper | 279 // When called, relays the request to check the spelling to the proper |
| 295 // backend, either hunspell or a platform-specific backend. | 280 // backend, either hunspell or a platform-specific backend. |
| 296 bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { | 281 bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { |
| 297 if (platform_spelling_engine_.get()) | 282 if (platform_spelling_engine_.get()) |
| 298 return platform_spelling_engine_->CheckSpelling(word_to_check, tag); | 283 return platform_spelling_engine_->CheckSpelling(word_to_check, tag); |
| 299 else | 284 else |
| 300 return true; | 285 return true; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 string16 word; | 337 string16 word; |
| 353 int word_start; | 338 int word_start; |
| 354 int word_length; | 339 int word_length; |
| 355 while (contraction_iterator_.GetNextWord(&word, &word_start, &word_length)) { | 340 while (contraction_iterator_.GetNextWord(&word, &word_start, &word_length)) { |
| 356 if (!CheckSpelling(word, tag)) | 341 if (!CheckSpelling(word, tag)) |
| 357 return false; | 342 return false; |
| 358 } | 343 } |
| 359 return true; | 344 return true; |
| 360 } | 345 } |
| 361 | 346 |
| 362 #if !defined(OS_MACOSX) | |
| 363 void SpellCheck::CreateTextCheckingResults( | 347 void SpellCheck::CreateTextCheckingResults( |
| 348 ResultFilter filter, |
| 364 int line_offset, | 349 int line_offset, |
| 365 const string16& line_text, | 350 const string16& line_text, |
| 366 const std::vector<SpellCheckResult>& spellcheck_results, | 351 const std::vector<SpellCheckResult>& spellcheck_results, |
| 367 WebVector<WebTextCheckingResult>* textcheck_results) { | 352 WebVector<WebTextCheckingResult>* textcheck_results) { |
| 368 // Double-check misspelled words with our spellchecker and attach grammar | 353 // Double-check misspelled words with our spellchecker and attach grammar |
| 369 // markers to them if our spellchecker tells they are correct words, i.e. they | 354 // markers to them if our spellchecker tells they are correct words, i.e. they |
| 370 // are probably contextually-misspelled words. | 355 // are probably contextually-misspelled words. |
| 371 const char16* text = line_text.c_str(); | 356 const char16* text = line_text.c_str(); |
| 372 WebVector<WebTextCheckingResult> list(spellcheck_results.size()); | 357 WebVector<WebTextCheckingResult> list(spellcheck_results.size()); |
| 373 for (size_t i = 0; i < spellcheck_results.size(); ++i) { | 358 for (size_t i = 0; i < spellcheck_results.size(); ++i) { |
| 374 WebTextCheckingType type = | 359 WebTextCheckingType type = |
| 375 static_cast<WebTextCheckingType>(spellcheck_results[i].type); | 360 static_cast<WebTextCheckingType>(spellcheck_results[i].type); |
| 376 int word_location = spellcheck_results[i].location; | 361 int word_location = spellcheck_results[i].location; |
| 377 int word_length = spellcheck_results[i].length; | 362 int word_length = spellcheck_results[i].length; |
| 378 if (type == WebKit::WebTextCheckingTypeSpelling) { | 363 if (type == WebKit::WebTextCheckingTypeSpelling && |
| 364 filter == USE_NATIVE_CHECKER) { |
| 379 int misspelling_start = 0; | 365 int misspelling_start = 0; |
| 380 int misspelling_length = 0; | 366 int misspelling_length = 0; |
| 381 if (SpellCheckWord(text + word_location, word_length, 0, | 367 if (SpellCheckWord(text + word_location, word_length, 0, |
| 382 &misspelling_start, &misspelling_length, NULL)) { | 368 &misspelling_start, &misspelling_length, NULL)) { |
| 383 type = WebKit::WebTextCheckingTypeGrammar; | 369 type = WebKit::WebTextCheckingTypeGrammar; |
| 384 } | 370 } |
| 385 } | 371 } |
| 386 list[i] = WebKit::WebTextCheckingResult(type, | 372 list[i] = WebKit::WebTextCheckingResult(type, |
| 387 word_location + line_offset, | 373 word_location + line_offset, |
| 388 word_length, | 374 word_length, |
| 389 spellcheck_results[i].replacement); | 375 spellcheck_results[i].replacement); |
| 390 } | 376 } |
| 391 textcheck_results->swap(list); | 377 textcheck_results->swap(list); |
| 392 } | 378 } |
| 393 #endif | |
| OLD | NEW |