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 21 matching lines...) Expand all Loading... |
80 platform_spelling_engine_->OnWordAdded(word); | 81 platform_spelling_engine_->OnWordAdded(word); |
81 } | 82 } |
82 | 83 |
83 void SpellCheck::OnEnableAutoSpellCorrect(bool enable) { | 84 void SpellCheck::OnEnableAutoSpellCorrect(bool enable) { |
84 auto_spell_correct_turned_on_ = enable; | 85 auto_spell_correct_turned_on_ = enable; |
85 } | 86 } |
86 | 87 |
87 void SpellCheck::Init(base::PlatformFile file, | 88 void SpellCheck::Init(base::PlatformFile file, |
88 const std::vector<std::string>& custom_words, | 89 const std::vector<std::string>& custom_words, |
89 const std::string& language) { | 90 const std::string& language) { |
90 bool use_platform_spelling_engine = | 91 platform_spelling_engine_->Init(file, custom_words); |
91 file == base::kInvalidPlatformFileValue && !language.empty(); | |
92 | 92 |
93 // Some tests under OSX still exercise hunspell. Only init native engine | |
94 // when no dictionary was specified. | |
95 // TODO(groby): Figure out if we can kill the hunspell dependency for OSX. | |
96 if (use_platform_spelling_engine) { | |
97 platform_spelling_engine_.reset(CreateNativeSpellingEngine()); | |
98 } else { | |
99 HunspellEngine* engine = new HunspellEngine; | |
100 engine->Init(file, custom_words); | |
101 platform_spelling_engine_.reset(engine); | |
102 } | |
103 character_attributes_.SetDefaultLanguage(language); | 93 character_attributes_.SetDefaultLanguage(language); |
104 text_iterator_.Reset(); | 94 text_iterator_.Reset(); |
105 contraction_iterator_.Reset(); | 95 contraction_iterator_.Reset(); |
106 } | 96 } |
107 | 97 |
108 bool SpellCheck::SpellCheckWord( | 98 bool SpellCheck::SpellCheckWord( |
109 const char16* in_word, | 99 const char16* in_word, |
110 int in_word_len, | 100 int in_word_len, |
111 int tag, | 101 int tag, |
112 int* misspelling_start, | 102 int* misspelling_start, |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 pending_request_param_.reset(new SpellcheckRequest( | 260 pending_request_param_.reset(new SpellcheckRequest( |
271 text, offset, completion)); | 261 text, offset, completion)); |
272 // We will check this text after we finish loading the hunspell dictionary. | 262 // We will check this text after we finish loading the hunspell dictionary. |
273 if (InitializeIfNeeded()) | 263 if (InitializeIfNeeded()) |
274 return; | 264 return; |
275 | 265 |
276 PostDelayedSpellCheckTask(pending_request_param_.release()); | 266 PostDelayedSpellCheckTask(pending_request_param_.release()); |
277 } | 267 } |
278 #endif | 268 #endif |
279 | 269 |
280 | |
281 bool SpellCheck::InitializeIfNeeded() { | 270 bool SpellCheck::InitializeIfNeeded() { |
282 // TODO(groby): OSX creates a hunspell engine here, too. That seems | 271 DCHECK(platform_spelling_engine_.get()); |
283 // wrong, but is (AFAICT) the existing flow. Fix that. | |
284 if (!platform_spelling_engine_.get()) | |
285 platform_spelling_engine_.reset(new HunspellEngine); | |
286 | |
287 return platform_spelling_engine_->InitializeIfNeeded(); | 272 return platform_spelling_engine_->InitializeIfNeeded(); |
288 } | 273 } |
289 | 274 |
290 // When called, relays the request to check the spelling to the proper | 275 // When called, relays the request to check the spelling to the proper |
291 // backend, either hunspell or a platform-specific backend. | 276 // backend, either hunspell or a platform-specific backend. |
292 bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { | 277 bool SpellCheck::CheckSpelling(const string16& word_to_check, int tag) { |
293 DCHECK(platform_spelling_engine_.get()); | 278 DCHECK(platform_spelling_engine_.get()); |
294 return platform_spelling_engine_->CheckSpelling(word_to_check, tag); | 279 return platform_spelling_engine_->CheckSpelling(word_to_check, tag); |
295 } | 280 } |
296 | 281 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 string16 word; | 330 string16 word; |
346 int word_start; | 331 int word_start; |
347 int word_length; | 332 int word_length; |
348 while (contraction_iterator_.GetNextWord(&word, &word_start, &word_length)) { | 333 while (contraction_iterator_.GetNextWord(&word, &word_start, &word_length)) { |
349 if (!CheckSpelling(word, tag)) | 334 if (!CheckSpelling(word, tag)) |
350 return false; | 335 return false; |
351 } | 336 } |
352 return true; | 337 return true; |
353 } | 338 } |
354 | 339 |
355 #if !defined(OS_MACOSX) | |
356 void SpellCheck::CreateTextCheckingResults( | 340 void SpellCheck::CreateTextCheckingResults( |
| 341 ResultFilter filter, |
357 int line_offset, | 342 int line_offset, |
358 const string16& line_text, | 343 const string16& line_text, |
359 const std::vector<SpellCheckResult>& spellcheck_results, | 344 const std::vector<SpellCheckResult>& spellcheck_results, |
360 WebVector<WebTextCheckingResult>* textcheck_results) { | 345 WebVector<WebTextCheckingResult>* textcheck_results) { |
361 // Double-check misspelled words with our spellchecker and attach grammar | 346 // Double-check misspelled words with our spellchecker and attach grammar |
362 // markers to them if our spellchecker tells they are correct words, i.e. they | 347 // markers to them if our spellchecker tells they are correct words, i.e. they |
363 // are probably contextually-misspelled words. | 348 // are probably contextually-misspelled words. |
364 const char16* text = line_text.c_str(); | 349 const char16* text = line_text.c_str(); |
365 WebVector<WebTextCheckingResult> list(spellcheck_results.size()); | 350 WebVector<WebTextCheckingResult> list(spellcheck_results.size()); |
366 for (size_t i = 0; i < spellcheck_results.size(); ++i) { | 351 for (size_t i = 0; i < spellcheck_results.size(); ++i) { |
367 WebTextCheckingType type = | 352 WebTextCheckingType type = |
368 static_cast<WebTextCheckingType>(spellcheck_results[i].type); | 353 static_cast<WebTextCheckingType>(spellcheck_results[i].type); |
369 int word_location = spellcheck_results[i].location; | 354 int word_location = spellcheck_results[i].location; |
370 int word_length = spellcheck_results[i].length; | 355 int word_length = spellcheck_results[i].length; |
371 if (type == WebKit::WebTextCheckingTypeSpelling) { | 356 if (type == WebKit::WebTextCheckingTypeSpelling && |
| 357 filter == USE_NATIVE_CHECKER) { |
372 int misspelling_start = 0; | 358 int misspelling_start = 0; |
373 int misspelling_length = 0; | 359 int misspelling_length = 0; |
374 if (SpellCheckWord(text + word_location, word_length, 0, | 360 if (SpellCheckWord(text + word_location, word_length, 0, |
375 &misspelling_start, &misspelling_length, NULL)) { | 361 &misspelling_start, &misspelling_length, NULL)) { |
376 type = WebKit::WebTextCheckingTypeGrammar; | 362 type = WebKit::WebTextCheckingTypeGrammar; |
377 } | 363 } |
378 } | 364 } |
379 list[i] = WebKit::WebTextCheckingResult(type, | 365 list[i] = WebKit::WebTextCheckingResult(type, |
380 word_location + line_offset, | 366 word_location + line_offset, |
381 word_length, | 367 word_length, |
382 spellcheck_results[i].replacement); | 368 spellcheck_results[i].replacement); |
383 } | 369 } |
384 textcheck_results->swap(list); | 370 textcheck_results->swap(list); |
385 } | 371 } |
386 #endif | |
OLD | NEW |