blob: d82c0d3e3730fc0a87debf2520c526ee747530a9 [file] [log] [blame]
[email protected]f751653a92014-02-18 16:32:551// 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
dcheng59826e32017-02-22 10:31:365#include "content/shell/test_runner/text_input_controller.h"
[email protected]f751653a92014-02-18 16:32:556
avi5dd91f82015-12-25 22:30:467#include "base/macros.h"
dcheng59826e32017-02-22 10:31:368#include "content/shell/test_runner/web_test_delegate.h"
9#include "content/shell/test_runner/web_view_test_proxy.h"
[email protected]f751653a92014-02-18 16:32:5510#include "gin/arguments.h"
11#include "gin/handle.h"
12#include "gin/object_template_builder.h"
13#include "gin/wrappable.h"
Blink Reformata30d4232018-04-07 15:31:0614#include "third_party/blink/public/platform/web_coalesced_input_event.h"
15#include "third_party/blink/public/platform/web_input_event_result.h"
16#include "third_party/blink/public/platform/web_keyboard_event.h"
17#include "third_party/blink/public/web/blink.h"
18#include "third_party/blink/public/web/web_frame_widget.h"
19#include "third_party/blink/public/web/web_ime_text_span.h"
20#include "third_party/blink/public/web/web_input_method_controller.h"
21#include "third_party/blink/public/web/web_local_frame.h"
22#include "third_party/blink/public/web/web_range.h"
23#include "third_party/blink/public/web/web_view.h"
changwan9bdc18f02015-11-20 02:43:5224#include "third_party/skia/include/core/SkColor.h"
dtapuska899ac222017-01-03 18:09:1625#include "ui/events/base_event_utils.h"
[email protected]f751653a92014-02-18 16:32:5526#include "v8/include/v8.h"
27
jochenf5f31752015-06-03 12:06:3428namespace test_runner {
[email protected]f751653a92014-02-18 16:32:5529
30class TextInputControllerBindings
31 : public gin::Wrappable<TextInputControllerBindings> {
32 public:
33 static gin::WrapperInfo kWrapperInfo;
34
35 static void Install(base::WeakPtr<TextInputController> controller,
lukasza8b6d5f32016-04-22 16:56:3136 blink::WebLocalFrame* frame);
[email protected]f751653a92014-02-18 16:32:5537
38 private:
39 explicit TextInputControllerBindings(
40 base::WeakPtr<TextInputController> controller);
dchenge933b3e2014-10-21 11:44:0941 ~TextInputControllerBindings() override;
[email protected]f751653a92014-02-18 16:32:5542
43 // gin::Wrappable:
dchenge933b3e2014-10-21 11:44:0944 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
anand.ratn449f39a42014-10-06 13:45:5745 v8::Isolate* isolate) override;
[email protected]f751653a92014-02-18 16:32:5546
47 void InsertText(const std::string& text);
48 void UnmarkText();
Ryan Landay7b5dbd52018-01-11 19:05:5949 void UnmarkAndUnselectText();
[email protected]f751653a92014-02-18 16:32:5550 void DoCommand(const std::string& text);
Ryan Landay9c6809422018-01-17 07:04:1551 void ExtendSelectionAndDelete(int before, int after);
Ryan Landay6d163ae2018-01-17 06:58:0652 void DeleteSurroundingText(int before, int after);
[email protected]f751653a92014-02-18 16:32:5553 void SetMarkedText(const std::string& text, int start, int length);
Ryan Landayd2034672018-01-12 22:22:3254 void SetMarkedTextFromExistingText(int start, int length);
[email protected]f751653a92014-02-18 16:32:5555 bool HasMarkedText();
56 std::vector<int> MarkedRange();
57 std::vector<int> SelectedRange();
58 std::vector<int> FirstRectForCharacterRange(unsigned location,
59 unsigned length);
60 void SetComposition(const std::string& text);
ekaramad2daaf672016-11-10 20:29:0161 void ForceTextInputStateUpdate();
[email protected]f751653a92014-02-18 16:32:5562
63 base::WeakPtr<TextInputController> controller_;
64
65 DISALLOW_COPY_AND_ASSIGN(TextInputControllerBindings);
66};
67
68gin::WrapperInfo TextInputControllerBindings::kWrapperInfo = {
69 gin::kEmbedderNativeGin};
70
71// static
72void TextInputControllerBindings::Install(
73 base::WeakPtr<TextInputController> controller,
lukasza8b6d5f32016-04-22 16:56:3174 blink::WebLocalFrame* frame) {
Blink Reformat1c4d759e2017-04-09 16:34:5475 v8::Isolate* isolate = blink::MainThreadIsolate();
[email protected]f751653a92014-02-18 16:32:5576 v8::HandleScope handle_scope(isolate);
Blink Reformat1c4d759e2017-04-09 16:34:5477 v8::Local<v8::Context> context = frame->MainWorldScriptContext();
[email protected]f751653a92014-02-18 16:32:5578 if (context.IsEmpty())
79 return;
80
81 v8::Context::Scope context_scope(context);
82
83 gin::Handle<TextInputControllerBindings> bindings =
84 gin::CreateHandle(isolate, new TextInputControllerBindings(controller));
[email protected]ad4d2032014-04-28 13:50:5985 if (bindings.IsEmpty())
86 return;
deepak.s750d68f2015-04-30 07:32:4187 v8::Local<v8::Object> global = context->Global();
[email protected]f751653a92014-02-18 16:32:5588 global->Set(gin::StringToV8(isolate, "textInputController"), bindings.ToV8());
89}
90
91TextInputControllerBindings::TextInputControllerBindings(
92 base::WeakPtr<TextInputController> controller)
93 : controller_(controller) {}
94
95TextInputControllerBindings::~TextInputControllerBindings() {}
96
97gin::ObjectTemplateBuilder
98TextInputControllerBindings::GetObjectTemplateBuilder(v8::Isolate* isolate) {
99 return gin::Wrappable<TextInputControllerBindings>::GetObjectTemplateBuilder(
100 isolate)
101 .SetMethod("insertText", &TextInputControllerBindings::InsertText)
102 .SetMethod("unmarkText", &TextInputControllerBindings::UnmarkText)
Ryan Landay7b5dbd52018-01-11 19:05:59103 .SetMethod("unmarkAndUnselectText",
104 &TextInputControllerBindings::UnmarkAndUnselectText)
[email protected]f751653a92014-02-18 16:32:55105 .SetMethod("doCommand", &TextInputControllerBindings::DoCommand)
Ryan Landay9c6809422018-01-17 07:04:15106 .SetMethod("extendSelectionAndDelete",
107 &TextInputControllerBindings::ExtendSelectionAndDelete)
Ryan Landay6d163ae2018-01-17 06:58:06108 .SetMethod("deleteSurroundingText",
109 &TextInputControllerBindings::DeleteSurroundingText)
[email protected]f751653a92014-02-18 16:32:55110 .SetMethod("setMarkedText", &TextInputControllerBindings::SetMarkedText)
Ryan Landayd2034672018-01-12 22:22:32111 .SetMethod("setMarkedTextFromExistingText",
112 &TextInputControllerBindings::SetMarkedTextFromExistingText)
[email protected]f751653a92014-02-18 16:32:55113 .SetMethod("hasMarkedText", &TextInputControllerBindings::HasMarkedText)
114 .SetMethod("markedRange", &TextInputControllerBindings::MarkedRange)
115 .SetMethod("selectedRange", &TextInputControllerBindings::SelectedRange)
116 .SetMethod("firstRectForCharacterRange",
117 &TextInputControllerBindings::FirstRectForCharacterRange)
ekaramad2daaf672016-11-10 20:29:01118 .SetMethod("setComposition", &TextInputControllerBindings::SetComposition)
119 .SetMethod("forceTextInputStateUpdate",
120 &TextInputControllerBindings::ForceTextInputStateUpdate);
[email protected]f751653a92014-02-18 16:32:55121}
122
123void TextInputControllerBindings::InsertText(const std::string& text) {
124 if (controller_)
125 controller_->InsertText(text);
126}
127
128void TextInputControllerBindings::UnmarkText() {
129 if (controller_)
130 controller_->UnmarkText();
131}
132
Ryan Landay7b5dbd52018-01-11 19:05:59133void TextInputControllerBindings::UnmarkAndUnselectText() {
134 if (controller_)
135 controller_->UnmarkAndUnselectText();
136}
137
[email protected]f751653a92014-02-18 16:32:55138void TextInputControllerBindings::DoCommand(const std::string& text) {
139 if (controller_)
140 controller_->DoCommand(text);
141}
142
Ryan Landay9c6809422018-01-17 07:04:15143void TextInputControllerBindings::ExtendSelectionAndDelete(int before,
144 int after) {
145 if (controller_)
146 controller_->ExtendSelectionAndDelete(before, after);
147}
148
Ryan Landay6d163ae2018-01-17 06:58:06149void TextInputControllerBindings::DeleteSurroundingText(int before, int after) {
150 if (controller_)
151 controller_->DeleteSurroundingText(before, after);
152}
153
[email protected]f751653a92014-02-18 16:32:55154void TextInputControllerBindings::SetMarkedText(const std::string& text,
155 int start,
156 int length) {
157 if (controller_)
158 controller_->SetMarkedText(text, start, length);
159}
160
Ryan Landayd2034672018-01-12 22:22:32161void TextInputControllerBindings::SetMarkedTextFromExistingText(int start,
162 int end) {
163 if (controller_)
164 controller_->SetMarkedTextFromExistingText(start, end);
165}
166
[email protected]f751653a92014-02-18 16:32:55167bool TextInputControllerBindings::HasMarkedText() {
168 return controller_ ? controller_->HasMarkedText() : false;
169}
170
171std::vector<int> TextInputControllerBindings::MarkedRange() {
172 return controller_ ? controller_->MarkedRange() : std::vector<int>();
173}
174
175std::vector<int> TextInputControllerBindings::SelectedRange() {
176 return controller_ ? controller_->SelectedRange() : std::vector<int>();
177}
178
179std::vector<int> TextInputControllerBindings::FirstRectForCharacterRange(
180 unsigned location,
181 unsigned length) {
182 return controller_ ? controller_->FirstRectForCharacterRange(location, length)
183 : std::vector<int>();
184}
185
186void TextInputControllerBindings::SetComposition(const std::string& text) {
187 if (controller_)
188 controller_->SetComposition(text);
189}
ekaramad2daaf672016-11-10 20:29:01190void TextInputControllerBindings::ForceTextInputStateUpdate() {
191 if (controller_)
192 controller_->ForceTextInputStateUpdate();
193}
[email protected]f751653a92014-02-18 16:32:55194// TextInputController ---------------------------------------------------------
195
lfg05e41372016-07-22 15:38:10196TextInputController::TextInputController(
197 WebViewTestProxyBase* web_view_test_proxy_base)
198 : web_view_test_proxy_base_(web_view_test_proxy_base),
199 weak_factory_(this) {}
[email protected]f751653a92014-02-18 16:32:55200
201TextInputController::~TextInputController() {}
202
lukasza8b6d5f32016-04-22 16:56:31203void TextInputController::Install(blink::WebLocalFrame* frame) {
[email protected]f751653a92014-02-18 16:32:55204 TextInputControllerBindings::Install(weak_factory_.GetWeakPtr(), frame);
205}
206
[email protected]f751653a92014-02-18 16:32:55207void TextInputController::InsertText(const std::string& text) {
ekaramadc75b1b3b32016-12-02 03:57:52208 if (auto* controller = GetInputMethodController()) {
Blink Reformat1c4d759e2017-04-09 16:34:54209 controller->CommitText(blink::WebString::FromUTF8(text),
Ryan Landay9e42fd742017-08-12 01:59:11210 std::vector<blink::WebImeTextSpan>(),
ekaramadce32ef9f2017-02-09 17:33:56211 blink::WebRange(), 0);
ekaramadc75b1b3b32016-12-02 03:57:52212 }
[email protected]f751653a92014-02-18 16:32:55213}
214
215void TextInputController::UnmarkText() {
ekaramadc75b1b3b32016-12-02 03:57:52216 if (auto* controller = GetInputMethodController()) {
Blink Reformat1c4d759e2017-04-09 16:34:54217 controller->FinishComposingText(
218 blink::WebInputMethodController::kKeepSelection);
ekaramadc75b1b3b32016-12-02 03:57:52219 }
[email protected]f751653a92014-02-18 16:32:55220}
221
Ryan Landay7b5dbd52018-01-11 19:05:59222void TextInputController::UnmarkAndUnselectText() {
223 if (auto* controller = GetInputMethodController()) {
224 controller->FinishComposingText(
225 blink::WebInputMethodController::kDoNotKeepSelection);
226 }
227}
228
[email protected]f751653a92014-02-18 16:32:55229void TextInputController::DoCommand(const std::string& text) {
Blink Reformat1c4d759e2017-04-09 16:34:54230 if (view()->MainFrame()) {
Ryan Landayd2034672018-01-12 22:22:32231 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
232 "called if the main frame "
233 "is not a local frame.";
Blink Reformat1c4d759e2017-04-09 16:34:54234 view()->MainFrame()->ToWebLocalFrame()->ExecuteCommand(
235 blink::WebString::FromUTF8(text));
yabinh8204efc2016-07-08 13:58:57236 }
[email protected]f751653a92014-02-18 16:32:55237}
238
Ryan Landay9c6809422018-01-17 07:04:15239void TextInputController::ExtendSelectionAndDelete(int before, int after) {
240 if (view()->MainFrame()) {
241 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
242 "called if the main frame "
243 "is not a local frame.";
244 view()->MainFrame()->ToWebLocalFrame()->ExtendSelectionAndDelete(before,
245 after);
246 }
247}
248
Ryan Landay6d163ae2018-01-17 06:58:06249void TextInputController::DeleteSurroundingText(int before, int after) {
250 if (view()->MainFrame()) {
251 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
252 "called if the main frame "
253 "is not a local frame.";
254 view()->MainFrame()->ToWebLocalFrame()->DeleteSurroundingText(before,
255 after);
256 }
257}
258
[email protected]f751653a92014-02-18 16:32:55259void TextInputController::SetMarkedText(const std::string& text,
260 int start,
261 int length) {
Blink Reformat1c4d759e2017-04-09 16:34:54262 blink::WebString web_text(blink::WebString::FromUTF8(text));
[email protected]f751653a92014-02-18 16:32:55263
264 // Split underline into up to 3 elements (before, selection, and after).
Ryan Landay9e42fd742017-08-12 01:59:11265 std::vector<blink::WebImeTextSpan> ime_text_spans;
266 blink::WebImeTextSpan ime_text_span;
[email protected]f751653a92014-02-18 16:32:55267 if (!start) {
Ryan Landay9e42fd742017-08-12 01:59:11268 ime_text_span.end_offset = length;
[email protected]f751653a92014-02-18 16:32:55269 } else {
Ryan Landay9e42fd742017-08-12 01:59:11270 ime_text_span.end_offset = start;
271 ime_text_spans.push_back(ime_text_span);
272 ime_text_span.start_offset = start;
273 ime_text_span.end_offset = start + length;
[email protected]f751653a92014-02-18 16:32:55274 }
Manuel Rego Casasnovas05eec2c2018-03-08 06:54:41275 ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThick;
Ryan Landay9e42fd742017-08-12 01:59:11276 ime_text_spans.push_back(ime_text_span);
[email protected]f751653a92014-02-18 16:32:55277 if (start + length < static_cast<int>(web_text.length())) {
Ryan Landay9e42fd742017-08-12 01:59:11278 ime_text_span.start_offset = ime_text_span.end_offset;
279 ime_text_span.end_offset = web_text.length();
Manuel Rego Casasnovas05eec2c2018-03-08 06:54:41280 ime_text_span.thickness = ui::mojom::ImeTextSpanThickness::kThin;
Ryan Landay9e42fd742017-08-12 01:59:11281 ime_text_spans.push_back(ime_text_span);
[email protected]f751653a92014-02-18 16:32:55282 }
283
ekaramadc75b1b3b32016-12-02 03:57:52284 if (auto* controller = GetInputMethodController()) {
Ryan Landay9e42fd742017-08-12 01:59:11285 controller->SetComposition(web_text, ime_text_spans, blink::WebRange(),
286 start, start + length);
ekaramadc75b1b3b32016-12-02 03:57:52287 }
[email protected]f751653a92014-02-18 16:32:55288}
289
Ryan Landayd2034672018-01-12 22:22:32290void TextInputController::SetMarkedTextFromExistingText(int start, int end) {
291 if (!view()->MainFrame())
292 return;
293
294 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
295 "called if the main frame "
296 "is not a local frame.";
297
298 view()->MainFrame()->ToWebLocalFrame()->SetCompositionFromExistingText(
299 start, end, std::vector<blink::WebImeTextSpan>());
300}
301
[email protected]f751653a92014-02-18 16:32:55302bool TextInputController::HasMarkedText() {
Blink Reformat1c4d759e2017-04-09 16:34:54303 if (!view()->MainFrame())
yabinh8204efc2016-07-08 13:58:57304 return false;
305
Ryan Landayd2034672018-01-12 22:22:32306 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
307 "called if the main frame "
308 "is not a local frame.";
yabinh8204efc2016-07-08 13:58:57309
Blink Reformat1c4d759e2017-04-09 16:34:54310 return view()->MainFrame()->ToWebLocalFrame()->HasMarkedText();
[email protected]f751653a92014-02-18 16:32:55311}
312
313std::vector<int> TextInputController::MarkedRange() {
Blink Reformat1c4d759e2017-04-09 16:34:54314 if (!view()->MainFrame())
[email protected]6f9397122014-02-25 09:30:50315 return std::vector<int>();
316
Ryan Landayd2034672018-01-12 22:22:32317 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
318 "called if the main frame "
319 "is not a local frame.";
yabinh8204efc2016-07-08 13:58:57320
Blink Reformat1c4d759e2017-04-09 16:34:54321 blink::WebRange range = view()->MainFrame()->ToWebLocalFrame()->MarkedRange();
[email protected]f751653a92014-02-18 16:32:55322 std::vector<int> int_array(2);
Blink Reformat1c4d759e2017-04-09 16:34:54323 int_array[0] = range.StartOffset();
324 int_array[1] = range.EndOffset();
[email protected]f751653a92014-02-18 16:32:55325
326 return int_array;
327}
328
329std::vector<int> TextInputController::SelectedRange() {
Blink Reformat1c4d759e2017-04-09 16:34:54330 if (!view()->MainFrame())
[email protected]6f9397122014-02-25 09:30:50331 return std::vector<int>();
332
Ryan Landayd2034672018-01-12 22:22:32333 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
334 "called if the main frame "
335 "is not a local frame.";
yabinh8204efc2016-07-08 13:58:57336
337 blink::WebRange range =
Blink Reformat1c4d759e2017-04-09 16:34:54338 view()->MainFrame()->ToWebLocalFrame()->SelectionRange();
339 if (range.IsNull())
yosin702c78a32016-06-13 08:39:13340 return std::vector<int>();
[email protected]f751653a92014-02-18 16:32:55341 std::vector<int> int_array(2);
Blink Reformat1c4d759e2017-04-09 16:34:54342 int_array[0] = range.StartOffset();
343 int_array[1] = range.EndOffset();
[email protected]f751653a92014-02-18 16:32:55344
345 return int_array;
346}
347
348std::vector<int> TextInputController::FirstRectForCharacterRange(
349 unsigned location,
350 unsigned length) {
351 blink::WebRect rect;
Blink Reformat1c4d759e2017-04-09 16:34:54352 if (!view()->FocusedFrame() ||
353 !view()->FocusedFrame()->FirstRectForCharacterRange(location, length,
lukasza8b6d5f32016-04-22 16:56:31354 rect)) {
[email protected]f751653a92014-02-18 16:32:55355 return std::vector<int>();
[email protected]6f9397122014-02-25 09:30:50356 }
[email protected]f751653a92014-02-18 16:32:55357
358 std::vector<int> int_array(4);
359 int_array[0] = rect.x;
360 int_array[1] = rect.y;
361 int_array[2] = rect.width;
362 int_array[3] = rect.height;
363
364 return int_array;
365}
366
367void TextInputController::SetComposition(const std::string& text) {
368 // Sends a keydown event with key code = 0xE5 to emulate input method
369 // behavior.
Daniel Cheng224569ee2018-04-25 05:45:06370 blink::WebKeyboardEvent key_down(blink::WebInputEvent::kRawKeyDown,
371 blink::WebInputEvent::kNoModifiers,
372 ui::EventTimeForNow());
dtapuska899ac222017-01-03 18:09:16373
Blink Reformat1c4d759e2017-04-09 16:34:54374 key_down.windows_key_code = 0xE5; // VKEY_PROCESSKEY
375 view()->HandleInputEvent(blink::WebCoalescedInputEvent(key_down));
[email protected]f751653a92014-02-18 16:32:55376
yabinhdd6d1b62016-08-23 07:09:02377 // The value returned by std::string::length() may not correspond to the
378 // actual number of encoded characters in sequences of multi-byte or
379 // variable-length characters.
Blink Reformat1c4d759e2017-04-09 16:34:54380 blink::WebString newText = blink::WebString::FromUTF8(text);
yabinhdd6d1b62016-08-23 07:09:02381 size_t textLength = newText.length();
382
Ryan Landay9e42fd742017-08-12 01:59:11383 std::vector<blink::WebImeTextSpan> ime_text_spans;
Ryan Landay9387aa92017-08-16 23:16:52384 ime_text_spans.push_back(blink::WebImeTextSpan(
Manuel Rego Casasnovas6743b452018-03-22 20:42:39385 blink::WebImeTextSpan::Type::kComposition, 0, textLength,
Manuel Rego Casasnovas05eec2c2018-03-08 06:54:41386 ui::mojom::ImeTextSpanThickness::kThin, SK_ColorTRANSPARENT));
ekaramadc75b1b3b32016-12-02 03:57:52387 if (auto* controller = GetInputMethodController()) {
Blink Reformat1c4d759e2017-04-09 16:34:54388 controller->SetComposition(
Ryan Landay9e42fd742017-08-12 01:59:11389 newText, blink::WebVector<blink::WebImeTextSpan>(ime_text_spans),
ekaramadce32ef9f2017-02-09 17:33:56390 blink::WebRange(), textLength, textLength);
ekaramadc75b1b3b32016-12-02 03:57:52391 }
lukasza8b6d5f32016-04-22 16:56:31392}
393
ekaramad2daaf672016-11-10 20:29:01394void TextInputController::ForceTextInputStateUpdate() {
lukaszabedb4b22017-06-23 00:00:13395 // TODO(lukasza): Finish adding OOPIF support to the layout tests harness.
Daniel Cheng3c829432017-06-19 03:42:31396 CHECK(view()->MainFrame()->IsWebLocalFrame())
397 << "WebView does not have a local main frame and"
398 " cannot handle input method controller tasks.";
ekaramad2daaf672016-11-10 20:29:01399 web_view_test_proxy_base_->delegate()->ForceTextInputStateUpdate(
Daniel Cheng3c829432017-06-19 03:42:31400 view()->MainFrame()->ToWebLocalFrame());
ekaramad2daaf672016-11-10 20:29:01401}
402
lukasza8b6d5f32016-04-22 16:56:31403blink::WebView* TextInputController::view() {
lfg05e41372016-07-22 15:38:10404 return web_view_test_proxy_base_->web_view();
[email protected]f751653a92014-02-18 16:32:55405}
406
ekaramadc75b1b3b32016-12-02 03:57:52407blink::WebInputMethodController*
408TextInputController::GetInputMethodController() {
Blink Reformat1c4d759e2017-04-09 16:34:54409 if (!view()->MainFrame())
ekaramadc75b1b3b32016-12-02 03:57:52410 return nullptr;
411
lukaszabedb4b22017-06-23 00:00:13412 // TODO(lukasza): Finish adding OOPIF support to the layout tests harness.
Daniel Cheng3c829432017-06-19 03:42:31413 CHECK(view()->MainFrame()->IsWebLocalFrame())
414 << "WebView does not have a local main frame and"
415 " cannot handle input method controller tasks.";
416
417 return view()
418 ->MainFrame()
419 ->ToWebLocalFrame()
420 ->FrameWidget()
421 ->GetActiveWebInputMethodController();
ekaramad2daaf672016-11-10 20:29:01422}
423
jochenf5f31752015-06-03 12:06:34424} // namespace test_runner