Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / renderer / spellchecker / spellcheck_language.cc
blobe9d101509e85af921f86cd33300e0c2dd0eb9bf0
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
3 // found in the LICENSE file.
5 #include "chrome/renderer/spellchecker/spellcheck_language.h"
7 #include "base/logging.h"
8 #include "chrome/renderer/spellchecker/spellcheck_worditerator.h"
9 #include "chrome/renderer/spellchecker/spelling_engine.h"
12 SpellcheckLanguage::SpellcheckLanguage()
13 : platform_spelling_engine_(CreateNativeSpellingEngine()) {
16 SpellcheckLanguage::~SpellcheckLanguage() {
19 void SpellcheckLanguage::Init(
20 base::PlatformFile file,
21 const std::string& language) {
22 DCHECK(platform_spelling_engine_.get());
23 platform_spelling_engine_->Init(file);
25 character_attributes_.SetDefaultLanguage(language);
26 text_iterator_.Reset();
27 contraction_iterator_.Reset();
30 bool SpellcheckLanguage::InitializeIfNeeded() {
31 DCHECK(platform_spelling_engine_.get());
32 return platform_spelling_engine_->InitializeIfNeeded();
35 bool SpellcheckLanguage::SpellCheckWord(
36 const base::char16* in_word,
37 int in_word_len,
38 int tag,
39 int* misspelling_start,
40 int* misspelling_len,
41 std::vector<base::string16>* optional_suggestions) {
42 DCHECK(in_word_len >= 0);
43 DCHECK(misspelling_start && misspelling_len) << "Out vars must be given.";
45 // Do nothing if we need to delay initialization. (Rather than blocking,
46 // report the word as correctly spelled.)
47 if (InitializeIfNeeded())
48 return true;
50 // Do nothing if spell checking is disabled.
51 if (!platform_spelling_engine_.get() ||
52 !platform_spelling_engine_->IsEnabled())
53 return true;
55 *misspelling_start = 0;
56 *misspelling_len = 0;
57 if (in_word_len == 0)
58 return true; // No input means always spelled correctly.
60 base::string16 word;
61 int word_start;
62 int word_length;
63 if (!text_iterator_.IsInitialized() &&
64 !text_iterator_.Initialize(&character_attributes_, true)) {
65 // We failed to initialize text_iterator_, return as spelled correctly.
66 VLOG(1) << "Failed to initialize SpellcheckWordIterator";
67 return true;
70 text_iterator_.SetText(in_word, in_word_len);
71 DCHECK(platform_spelling_engine_.get());
72 while (text_iterator_.GetNextWord(&word, &word_start, &word_length)) {
73 // Found a word (or a contraction) that the spellchecker can check the
74 // spelling of.
75 if (platform_spelling_engine_->CheckSpelling(word, tag))
76 continue;
78 // If the given word is a concatenated word of two or more valid words
79 // (e.g. "hello:hello"), we should treat it as a valid word.
80 if (IsValidContraction(word, tag))
81 continue;
83 *misspelling_start = word_start;
84 *misspelling_len = word_length;
86 // Get the list of suggested words.
87 if (optional_suggestions) {
88 platform_spelling_engine_->FillSuggestionList(word,
89 optional_suggestions);
91 return false;
94 return true;
97 // Returns whether or not the given string is a valid contraction.
98 // This function is a fall-back when the SpellcheckWordIterator class
99 // returns a concatenated word which is not in the selected dictionary
100 // (e.g. "in'n'out") but each word is valid.
101 bool SpellcheckLanguage::IsValidContraction(const base::string16& contraction,
102 int tag) {
103 if (!contraction_iterator_.IsInitialized() &&
104 !contraction_iterator_.Initialize(&character_attributes_, false)) {
105 // We failed to initialize the word iterator, return as spelled correctly.
106 VLOG(1) << "Failed to initialize contraction_iterator_";
107 return true;
110 contraction_iterator_.SetText(contraction.c_str(), contraction.length());
112 base::string16 word;
113 int word_start;
114 int word_length;
116 DCHECK(platform_spelling_engine_.get());
117 while (contraction_iterator_.GetNextWord(&word, &word_start, &word_length)) {
118 if (!platform_spelling_engine_->CheckSpelling(word, tag))
119 return false;
121 return true;
124 bool SpellcheckLanguage::IsEnabled() {
125 DCHECK(platform_spelling_engine_.get());
126 return platform_spelling_engine_->IsEnabled();