| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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. | |
| 4 | |
| 5 #include "components/test_runner/spell_check_client.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/macros.h" | |
| 13 #include "components/test_runner/mock_grammar_check.h" | |
| 14 #include "components/test_runner/test_runner.h" | |
| 15 #include "components/test_runner/web_test_delegate.h" | |
| 16 #include "third_party/WebKit/public/web/WebFrame.h" | |
| 17 #include "third_party/WebKit/public/web/WebKit.h" | |
| 18 #include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" | |
| 19 #include "third_party/WebKit/public/web/WebTextCheckingResult.h" | |
| 20 | |
| 21 namespace test_runner { | |
| 22 | |
| 23 SpellCheckClient::SpellCheckClient(TestRunner* test_runner) | |
| 24 : last_requested_text_checking_completion_(nullptr), | |
| 25 test_runner_(test_runner), | |
| 26 weak_factory_(this) { | |
| 27 DCHECK(test_runner); | |
| 28 } | |
| 29 | |
| 30 SpellCheckClient::~SpellCheckClient() { | |
| 31 } | |
| 32 | |
| 33 void SpellCheckClient::SetDelegate(WebTestDelegate* delegate) { | |
| 34 delegate_ = delegate; | |
| 35 } | |
| 36 | |
| 37 void SpellCheckClient::SetEnabled(bool enabled) { | |
| 38 enabled_ = enabled; | |
| 39 } | |
| 40 | |
| 41 void SpellCheckClient::Reset() { | |
| 42 enabled_ = false; | |
| 43 resolved_callback_.Reset(); | |
| 44 } | |
| 45 | |
| 46 // blink::WebSpellCheckClient | |
| 47 void SpellCheckClient::checkSpelling( | |
| 48 const blink::WebString& text, | |
| 49 int& misspelled_offset, | |
| 50 int& misspelled_length, | |
| 51 blink::WebVector<blink::WebString>* optional_suggestions) { | |
| 52 if (!enabled_) { | |
| 53 misspelled_offset = 0; | |
| 54 misspelled_length = 0; | |
| 55 return; | |
| 56 } | |
| 57 | |
| 58 // Check the spelling of the given text. | |
| 59 spell_check_.SpellCheckWord(text, &misspelled_offset, &misspelled_length); | |
| 60 } | |
| 61 | |
| 62 void SpellCheckClient::requestCheckingOfText( | |
| 63 const blink::WebString& text, | |
| 64 const blink::WebVector<uint32_t>& markers, | |
| 65 const blink::WebVector<unsigned>& marker_offsets, | |
| 66 blink::WebTextCheckingCompletion* completion) { | |
| 67 if (!enabled_ || text.isEmpty()) { | |
| 68 if (completion) { | |
| 69 completion->didCancelCheckingText(); | |
| 70 RequestResolved(); | |
| 71 } | |
| 72 return; | |
| 73 } | |
| 74 | |
| 75 if (last_requested_text_checking_completion_) { | |
| 76 last_requested_text_checking_completion_->didCancelCheckingText(); | |
| 77 RequestResolved(); | |
| 78 } | |
| 79 | |
| 80 last_requested_text_checking_completion_ = completion; | |
| 81 last_requested_text_check_string_ = text; | |
| 82 if (spell_check_.HasInCache(text)) | |
| 83 FinishLastTextCheck(); | |
| 84 else | |
| 85 delegate_->PostDelayedTask( | |
| 86 base::Bind(&SpellCheckClient::FinishLastTextCheck, | |
| 87 weak_factory_.GetWeakPtr()), | |
| 88 0); | |
| 89 } | |
| 90 | |
| 91 void SpellCheckClient::cancelAllPendingRequests() { | |
| 92 if (!last_requested_text_checking_completion_) | |
| 93 return; | |
| 94 last_requested_text_checking_completion_->didCancelCheckingText(); | |
| 95 last_requested_text_checking_completion_ = nullptr; | |
| 96 } | |
| 97 | |
| 98 void SpellCheckClient::FinishLastTextCheck() { | |
| 99 if (!last_requested_text_checking_completion_) | |
| 100 return; | |
| 101 std::vector<blink::WebTextCheckingResult> results; | |
| 102 int offset = 0; | |
| 103 if (!spell_check_.IsMultiWordMisspelling(last_requested_text_check_string_, | |
| 104 &results)) { | |
| 105 base::string16 text = last_requested_text_check_string_.utf16(); | |
| 106 while (text.length()) { | |
| 107 int misspelled_position = 0; | |
| 108 int misspelled_length = 0; | |
| 109 spell_check_.SpellCheckWord(blink::WebString::fromUTF16(text), | |
| 110 &misspelled_position, &misspelled_length); | |
| 111 if (!misspelled_length) | |
| 112 break; | |
| 113 blink::WebVector<blink::WebString> suggestions; | |
| 114 spell_check_.FillSuggestionList( | |
| 115 blink::WebString::fromUTF16( | |
| 116 text.substr(misspelled_position, misspelled_length)), | |
| 117 &suggestions); | |
| 118 results.push_back(blink::WebTextCheckingResult( | |
| 119 blink::WebTextDecorationTypeSpelling, | |
| 120 offset + misspelled_position, | |
| 121 misspelled_length, | |
| 122 suggestions.isEmpty() ? blink::WebString() : suggestions[0])); | |
| 123 text = text.substr(misspelled_position + misspelled_length); | |
| 124 offset += misspelled_position + misspelled_length; | |
| 125 } | |
| 126 MockGrammarCheck::CheckGrammarOfString(last_requested_text_check_string_, | |
| 127 &results); | |
| 128 } | |
| 129 last_requested_text_checking_completion_->didFinishCheckingText(results); | |
| 130 last_requested_text_checking_completion_ = 0; | |
| 131 RequestResolved(); | |
| 132 | |
| 133 if (test_runner_->shouldDumpSpellCheckCallbacks()) | |
| 134 delegate_->PrintMessage("SpellCheckEvent: FinishLastTextCheck\n"); | |
| 135 } | |
| 136 | |
| 137 void SpellCheckClient::SetSpellCheckResolvedCallback( | |
| 138 v8::Local<v8::Function> callback) { | |
| 139 resolved_callback_.Reset(blink::mainThreadIsolate(), callback); | |
| 140 } | |
| 141 | |
| 142 void SpellCheckClient::RemoveSpellCheckResolvedCallback() { | |
| 143 resolved_callback_.Reset(); | |
| 144 } | |
| 145 | |
| 146 void SpellCheckClient::RequestResolved() { | |
| 147 if (resolved_callback_.IsEmpty()) | |
| 148 return; | |
| 149 | |
| 150 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
| 151 v8::HandleScope handle_scope(isolate); | |
| 152 | |
| 153 blink::WebFrame* frame = test_runner_->mainFrame(); | |
| 154 if (!frame || frame->isWebRemoteFrame()) | |
| 155 return; | |
| 156 | |
| 157 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | |
| 158 if (context.IsEmpty()) | |
| 159 return; | |
| 160 | |
| 161 v8::Context::Scope context_scope(context); | |
| 162 | |
| 163 frame->callFunctionEvenIfScriptDisabled( | |
| 164 v8::Local<v8::Function>::New(isolate, resolved_callback_), | |
| 165 context->Global(), 0, nullptr); | |
| 166 } | |
| 167 | |
| 168 } // namespace test_runner | |
| OLD | NEW |