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 |