Chromium Code Reviews| Index: chrome/renderer/spellchecker/spellcheck_provider.cc |
| =================================================================== |
| --- chrome/renderer/spellchecker/spellcheck_provider.cc (revision 141385) |
| +++ chrome/renderer/spellchecker/spellcheck_provider.cc (working copy) |
| @@ -103,22 +103,62 @@ |
| document_tag, |
| text)); |
| #else |
| - // Send this text to a browser. A browser checks the user profile and send |
| - // this text to the Spelling service only if a user enables this feature. |
| - // TODO(hbono) Implement a cache to avoid sending IPC messages. |
| - string16 line; |
| - int offset = -1; |
| - if (!GetRequestLine(text, &line, &offset)) { |
| + if (text.isEmpty() || !HasWordCharacters(text, 0)) { |
| completion->didCancelCheckingText(); |
| return; |
| } |
| - |
| - last_line_ = line; |
| + // Cancel this spellcheck request if the cached text is a substring of the |
| + // given text and the given text is the middle of a possible word. |
| + string16 request(text); |
|
Hajime Morrita
2012/06/11 06:53:21
I hope this early-return-with-cache part to be a m
Hironori Bono
2012/06/11 07:24:14
Unfortunately, this code is a temporary workaround
|
| + size_t text_length = request.length(); |
| + size_t last_length = last_request_.length(); |
| + if (text_length >= last_length && |
| + !request.compare(0, last_length, last_request_)) { |
| + if (text_length == last_length || !HasWordCharacters(text, last_length)) { |
| + completion->didCancelCheckingText(); |
|
Hajime Morrita
2012/06/11 06:53:21
This means that there should be no misspelling, ri
Hironori Bono
2012/06/11 07:24:14
This code means we should not change existing mark
|
| + return; |
| + } |
| + int code = 0; |
| + int length = static_cast<int>(text_length); |
| + U16_PREV(text.data(), 0, length, code); |
| + UErrorCode error = U_ZERO_ERROR; |
| + if (uscript_getScript(code, &error) != USCRIPT_COMMON) { |
| + completion->didCancelCheckingText(); |
| + return; |
| + } |
| + } |
| + // Create a subset of the cached results and return it if the given text is a |
| + // substring of the cached text. |
| + if (text_length < last_length && |
| + !last_request_.compare(0, text_length, request)) { |
| + size_t result_size = 0; |
| + for (size_t i = 0; i < last_results_.size(); ++i) { |
| + size_t start = last_results_[i].location; |
| + size_t end = start + last_results_[i].length; |
| + if (start <= text_length && end <= text_length) |
| + ++result_size; |
| + } |
| + if (result_size > 0) { |
| + WebKit::WebVector<WebKit::WebTextCheckingResult> results(result_size); |
| + for (size_t i = 0; i < result_size; ++i) { |
| + results[i].type = last_results_[i].type; |
| + results[i].location = last_results_[i].location; |
| + results[i].length = last_results_[i].length; |
| + results[i].replacement = last_results_[i].replacement; |
| + } |
| + completion->didFinishCheckingText(results); |
| + return; |
| + } |
| + } |
| + // Send this text to a browser. A browser checks the user profile and send |
| + // this text to the Spelling service only if a user enables this feature. |
| + last_request_.clear(); |
| + last_results_.assign(WebKit::WebVector<WebKit::WebTextCheckingResult>()); |
| Send(new SpellCheckHostMsg_CallSpellingService( |
| routing_id(), |
| text_check_completions_.Add(completion), |
| - offset, |
| - line)); |
| + 0, |
| + request)); |
| #endif // !OS_MACOSX |
| } |
| @@ -278,59 +318,26 @@ |
| CreateTextCheckingResults(offset, results, &textcheck_results); |
| } |
| completion->didFinishCheckingText(textcheck_results); |
| + |
| + // Cache the request and the converted results. |
| + last_request_ = line; |
| + last_results_.swap(textcheck_results); |
| } |
| -bool SpellCheckProvider::HasWordCharacters(const string16& text, |
| - int index) const { |
| - const char16* data = text.c_str(); |
| +bool SpellCheckProvider::HasWordCharacters( |
| + const WebKit::WebString& text, |
| + int index) const { |
| + const char16* data = text.data(); |
| int length = text.length(); |
| while (index < length) { |
| uint32 code = 0; |
| U16_NEXT(data, index, length, code); |
| - UErrorCode err = U_ZERO_ERROR; |
| - if (uscript_getScript(code, &err) == USCRIPT_LATIN) |
| + UErrorCode error = U_ZERO_ERROR; |
| + if (uscript_getScript(code, &error) == USCRIPT_LATIN) |
| return true; |
| } |
| return false; |
| } |
| - |
| -bool SpellCheckProvider::GetRequestLine(const string16& text, |
| - string16* line, |
| - int* offset) const { |
| - // WebKit sends the line being edited by a user to this class. (It also sends |
| - // the previous line when the user is typing its first word.) We send the line |
| - // being edited by a user when the input text satisfies all conditions listed |
| - // below. |
| - // * There is a non-word character at the end of of the input line so this |
| - // class can send a request only when a user finishes typing a word. |
| - // * There are word characters in the input line. |
| - // * There are word characters in the difference between the input line and |
| - // the previously-spellchecked line. |
| - if (text.empty()) |
| - return false; |
| - UErrorCode err = U_ZERO_ERROR; |
| - if (uscript_getScript(*(text.rbegin()), &err) != USCRIPT_COMMON) |
| - return false; |
| - size_t input_offset = text.find('\n'); |
| - string16 input_line; |
| - if (input_offset != string16::npos && HasWordCharacters(text, input_offset)) { |
| - ++input_offset; |
| - *offset = static_cast<int>(input_offset); |
| - input_line = text.substr(input_offset); |
| - } else { |
| - if (!HasWordCharacters(text, 0)) |
| - return false; |
| - *offset = 0; |
| - input_line = text; |
| - } |
| - size_t length = last_line_.length(); |
| - if (length > 0 && !input_line.compare(0, length, last_line_)) { |
| - if (!HasWordCharacters(input_line, static_cast<int>(length))) |
| - return false; |
| - } |
| - line->assign(input_line); |
| - return true; |
| -} |
| #endif |
| #if defined(OS_MACOSX) |