blob: 9bc1dfb627529534e18801995735c8cfbcc24124 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2020 The Chromium Authors
[email protected]f751653a92014-02-18 16:32:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakj89f47082020-09-02 17:53:435#include "content/web_test/renderer/text_input_controller.h"
[email protected]f751653a92014-02-18 16:32:556
Dave Tapuska13da016a2021-02-04 21:51:587#include "content/web_test/renderer/web_frame_test_proxy.h"
[email protected]f751653a92014-02-18 16:32:558#include "gin/arguments.h"
9#include "gin/handle.h"
10#include "gin/object_template_builder.h"
11#include "gin/wrappable.h"
Dave Tapuska0dd120b2020-05-08 17:06:5212#include "third_party/blink/public/common/input/web_coalesced_input_event.h"
Dave Tapuska129cef82019-12-19 16:36:4813#include "third_party/blink/public/common/input/web_keyboard_event.h"
Dave Tapuskad1aaf8a2023-09-12 14:50:3414#include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
Blink Reformata30d4232018-04-07 15:31:0615#include "third_party/blink/public/platform/web_input_event_result.h"
Blink Reformata30d4232018-04-07 15:31:0616#include "third_party/blink/public/web/web_frame_widget.h"
Blink Reformata30d4232018-04-07 15:31:0617#include "third_party/blink/public/web/web_input_method_controller.h"
18#include "third_party/blink/public/web/web_local_frame.h"
19#include "third_party/blink/public/web/web_range.h"
20#include "third_party/blink/public/web/web_view.h"
changwan9bdc18f02015-11-20 02:43:5221#include "third_party/skia/include/core/SkColor.h"
Dave Tapuska7fa75212020-06-04 17:46:1122#include "ui/base/ime/ime_text_span.h"
dtapuska899ac222017-01-03 18:09:1623#include "ui/events/base_event_utils.h"
[email protected]f751653a92014-02-18 16:32:5524#include "v8/include/v8.h"
25
danakj741848a2020-04-07 22:48:0626namespace content {
[email protected]f751653a92014-02-18 16:32:5527
28class TextInputControllerBindings
29 : public gin::Wrappable<TextInputControllerBindings> {
30 public:
31 static gin::WrapperInfo kWrapperInfo;
32
Peter Boström9b036532021-10-28 23:37:2833 TextInputControllerBindings(const TextInputControllerBindings&) = delete;
34 TextInputControllerBindings& operator=(const TextInputControllerBindings&) =
35 delete;
36
[email protected]f751653a92014-02-18 16:32:5537 static void Install(base::WeakPtr<TextInputController> controller,
lukasza8b6d5f32016-04-22 16:56:3138 blink::WebLocalFrame* frame);
[email protected]f751653a92014-02-18 16:32:5539
40 private:
41 explicit TextInputControllerBindings(
42 base::WeakPtr<TextInputController> controller);
dchenge933b3e2014-10-21 11:44:0943 ~TextInputControllerBindings() override;
[email protected]f751653a92014-02-18 16:32:5544
45 // gin::Wrappable:
dchenge933b3e2014-10-21 11:44:0946 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
anand.ratn449f39a42014-10-06 13:45:5747 v8::Isolate* isolate) override;
[email protected]f751653a92014-02-18 16:32:5548
49 void InsertText(const std::string& text);
50 void UnmarkText();
Ryan Landay7b5dbd52018-01-11 19:05:5951 void UnmarkAndUnselectText();
[email protected]f751653a92014-02-18 16:32:5552 void DoCommand(const std::string& text);
Ryan Landay9c6809422018-01-17 07:04:1553 void ExtendSelectionAndDelete(int before, int after);
Ryan Landay6d163ae2018-01-17 06:58:0654 void DeleteSurroundingText(int before, int after);
Peter Kastinge468f502023-11-06 19:22:5255 void SetMarkedText(const std::string& text, uint32_t start, uint32_t length);
56 void SetMarkedTextFromExistingText(uint32_t start, uint32_t end);
[email protected]f751653a92014-02-18 16:32:5557 bool HasMarkedText();
58 std::vector<int> MarkedRange();
59 std::vector<int> SelectedRange();
Peter Kasting7064abb2022-08-11 18:11:3860 std::vector<int> FirstRectForCharacterRange(uint32_t location,
61 uint32_t length);
[email protected]f751653a92014-02-18 16:32:5562 void SetComposition(const std::string& text);
Alex Kengd1e6590d2022-06-28 10:31:1263 void SetCompositionWithReplacementRange(const std::string& text,
64 int replacement_start,
65 int replacement_end);
ekaramad2daaf672016-11-10 20:29:0166 void ForceTextInputStateUpdate();
[email protected]f751653a92014-02-18 16:32:5567
68 base::WeakPtr<TextInputController> controller_;
[email protected]f751653a92014-02-18 16:32:5569};
70
71gin::WrapperInfo TextInputControllerBindings::kWrapperInfo = {
72 gin::kEmbedderNativeGin};
73
74// static
75void TextInputControllerBindings::Install(
76 base::WeakPtr<TextInputController> controller,
lukasza8b6d5f32016-04-22 16:56:3177 blink::WebLocalFrame* frame) {
Dave Tapuskad1aaf8a2023-09-12 14:50:3478 v8::Isolate* isolate = frame->GetAgentGroupScheduler()->Isolate();
[email protected]f751653a92014-02-18 16:32:5579 v8::HandleScope handle_scope(isolate);
Blink Reformat1c4d759e2017-04-09 16:34:5480 v8::Local<v8::Context> context = frame->MainWorldScriptContext();
[email protected]f751653a92014-02-18 16:32:5581 if (context.IsEmpty())
82 return;
83
84 v8::Context::Scope context_scope(context);
85
86 gin::Handle<TextInputControllerBindings> bindings =
87 gin::CreateHandle(isolate, new TextInputControllerBindings(controller));
[email protected]ad4d2032014-04-28 13:50:5988 if (bindings.IsEmpty())
89 return;
deepak.s750d68f2015-04-30 07:32:4190 v8::Local<v8::Object> global = context->Global();
Dan Elphicka83be512019-02-05 15:57:2391 global
92 ->Set(context, gin::StringToV8(isolate, "textInputController"),
93 bindings.ToV8())
94 .Check();
[email protected]f751653a92014-02-18 16:32:5595}
96
97TextInputControllerBindings::TextInputControllerBindings(
98 base::WeakPtr<TextInputController> controller)
99 : controller_(controller) {}
100
101TextInputControllerBindings::~TextInputControllerBindings() {}
102
103gin::ObjectTemplateBuilder
104TextInputControllerBindings::GetObjectTemplateBuilder(v8::Isolate* isolate) {
105 return gin::Wrappable<TextInputControllerBindings>::GetObjectTemplateBuilder(
106 isolate)
107 .SetMethod("insertText", &TextInputControllerBindings::InsertText)
108 .SetMethod("unmarkText", &TextInputControllerBindings::UnmarkText)
Ryan Landay7b5dbd52018-01-11 19:05:59109 .SetMethod("unmarkAndUnselectText",
110 &TextInputControllerBindings::UnmarkAndUnselectText)
[email protected]f751653a92014-02-18 16:32:55111 .SetMethod("doCommand", &TextInputControllerBindings::DoCommand)
Ryan Landay9c6809422018-01-17 07:04:15112 .SetMethod("extendSelectionAndDelete",
113 &TextInputControllerBindings::ExtendSelectionAndDelete)
Ryan Landay6d163ae2018-01-17 06:58:06114 .SetMethod("deleteSurroundingText",
115 &TextInputControllerBindings::DeleteSurroundingText)
[email protected]f751653a92014-02-18 16:32:55116 .SetMethod("setMarkedText", &TextInputControllerBindings::SetMarkedText)
Ryan Landayd2034672018-01-12 22:22:32117 .SetMethod("setMarkedTextFromExistingText",
118 &TextInputControllerBindings::SetMarkedTextFromExistingText)
[email protected]f751653a92014-02-18 16:32:55119 .SetMethod("hasMarkedText", &TextInputControllerBindings::HasMarkedText)
120 .SetMethod("markedRange", &TextInputControllerBindings::MarkedRange)
121 .SetMethod("selectedRange", &TextInputControllerBindings::SelectedRange)
122 .SetMethod("firstRectForCharacterRange",
123 &TextInputControllerBindings::FirstRectForCharacterRange)
ekaramad2daaf672016-11-10 20:29:01124 .SetMethod("setComposition", &TextInputControllerBindings::SetComposition)
Alex Kengd1e6590d2022-06-28 10:31:12125 .SetMethod(
126 "setCompositionWithReplacementRange",
127 &TextInputControllerBindings::SetCompositionWithReplacementRange)
ekaramad2daaf672016-11-10 20:29:01128 .SetMethod("forceTextInputStateUpdate",
129 &TextInputControllerBindings::ForceTextInputStateUpdate);
[email protected]f751653a92014-02-18 16:32:55130}
131
132void TextInputControllerBindings::InsertText(const std::string& text) {
133 if (controller_)
134 controller_->InsertText(text);
135}
136
137void TextInputControllerBindings::UnmarkText() {
138 if (controller_)
139 controller_->UnmarkText();
140}
141
Ryan Landay7b5dbd52018-01-11 19:05:59142void TextInputControllerBindings::UnmarkAndUnselectText() {
143 if (controller_)
144 controller_->UnmarkAndUnselectText();
145}
146
[email protected]f751653a92014-02-18 16:32:55147void TextInputControllerBindings::DoCommand(const std::string& text) {
148 if (controller_)
149 controller_->DoCommand(text);
150}
151
Ryan Landay9c6809422018-01-17 07:04:15152void TextInputControllerBindings::ExtendSelectionAndDelete(int before,
153 int after) {
154 if (controller_)
155 controller_->ExtendSelectionAndDelete(before, after);
156}
157
Ryan Landay6d163ae2018-01-17 06:58:06158void TextInputControllerBindings::DeleteSurroundingText(int before, int after) {
159 if (controller_)
160 controller_->DeleteSurroundingText(before, after);
161}
162
[email protected]f751653a92014-02-18 16:32:55163void TextInputControllerBindings::SetMarkedText(const std::string& text,
Peter Kastinge468f502023-11-06 19:22:52164 uint32_t start,
165 uint32_t length) {
[email protected]f751653a92014-02-18 16:32:55166 if (controller_)
167 controller_->SetMarkedText(text, start, length);
168}
169
Peter Kastinge468f502023-11-06 19:22:52170void TextInputControllerBindings::SetMarkedTextFromExistingText(uint32_t start,
171 uint32_t end) {
Ryan Landayd2034672018-01-12 22:22:32172 if (controller_)
173 controller_->SetMarkedTextFromExistingText(start, end);
174}
175
[email protected]f751653a92014-02-18 16:32:55176bool TextInputControllerBindings::HasMarkedText() {
177 return controller_ ? controller_->HasMarkedText() : false;
178}
179
180std::vector<int> TextInputControllerBindings::MarkedRange() {
181 return controller_ ? controller_->MarkedRange() : std::vector<int>();
182}
183
184std::vector<int> TextInputControllerBindings::SelectedRange() {
185 return controller_ ? controller_->SelectedRange() : std::vector<int>();
186}
187
188std::vector<int> TextInputControllerBindings::FirstRectForCharacterRange(
Peter Kasting7064abb2022-08-11 18:11:38189 uint32_t location,
190 uint32_t length) {
[email protected]f751653a92014-02-18 16:32:55191 return controller_ ? controller_->FirstRectForCharacterRange(location, length)
192 : std::vector<int>();
193}
194
195void TextInputControllerBindings::SetComposition(const std::string& text) {
196 if (controller_)
Alex Kengd1e6590d2022-06-28 10:31:12197 controller_->SetComposition(text, -1, -1);
198}
199void TextInputControllerBindings::SetCompositionWithReplacementRange(
200 const std::string& text,
201 int replacement_start,
202 int replacement_end) {
203 if (controller_)
204 controller_->SetComposition(text, replacement_start, replacement_end);
[email protected]f751653a92014-02-18 16:32:55205}
ekaramad2daaf672016-11-10 20:29:01206void TextInputControllerBindings::ForceTextInputStateUpdate() {
207 if (controller_)
208 controller_->ForceTextInputStateUpdate();
209}
[email protected]f751653a92014-02-18 16:32:55210// TextInputController ---------------------------------------------------------
211
Dave Tapuska13da016a2021-02-04 21:51:58212TextInputController::TextInputController(
213 WebFrameTestProxy* web_frame_test_proxy)
214 : web_frame_test_proxy_(web_frame_test_proxy) {}
[email protected]f751653a92014-02-18 16:32:55215
216TextInputController::~TextInputController() {}
217
lukasza8b6d5f32016-04-22 16:56:31218void TextInputController::Install(blink::WebLocalFrame* frame) {
[email protected]f751653a92014-02-18 16:32:55219 TextInputControllerBindings::Install(weak_factory_.GetWeakPtr(), frame);
220}
221
[email protected]f751653a92014-02-18 16:32:55222void TextInputController::InsertText(const std::string& text) {
ekaramadc75b1b3b32016-12-02 03:57:52223 if (auto* controller = GetInputMethodController()) {
Blink Reformat1c4d759e2017-04-09 16:34:54224 controller->CommitText(blink::WebString::FromUTF8(text),
Dave Tapuska7fa75212020-06-04 17:46:11225 std::vector<ui::ImeTextSpan>(), blink::WebRange(),
226 0);
ekaramadc75b1b3b32016-12-02 03:57:52227 }
[email protected]f751653a92014-02-18 16:32:55228}
229
230void TextInputController::UnmarkText() {
ekaramadc75b1b3b32016-12-02 03:57:52231 if (auto* controller = GetInputMethodController()) {
Blink Reformat1c4d759e2017-04-09 16:34:54232 controller->FinishComposingText(
233 blink::WebInputMethodController::kKeepSelection);
ekaramadc75b1b3b32016-12-02 03:57:52234 }
[email protected]f751653a92014-02-18 16:32:55235}
236
Ryan Landay7b5dbd52018-01-11 19:05:59237void TextInputController::UnmarkAndUnselectText() {
238 if (auto* controller = GetInputMethodController()) {
239 controller->FinishComposingText(
240 blink::WebInputMethodController::kDoNotKeepSelection);
241 }
242}
243
[email protected]f751653a92014-02-18 16:32:55244void TextInputController::DoCommand(const std::string& text) {
Blink Reformat1c4d759e2017-04-09 16:34:54245 if (view()->MainFrame()) {
Ryan Landayd2034672018-01-12 22:22:32246 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
247 "called if the main frame "
248 "is not a local frame.";
Blink Reformat1c4d759e2017-04-09 16:34:54249 view()->MainFrame()->ToWebLocalFrame()->ExecuteCommand(
250 blink::WebString::FromUTF8(text));
yabinh8204efc2016-07-08 13:58:57251 }
[email protected]f751653a92014-02-18 16:32:55252}
253
Ryan Landay9c6809422018-01-17 07:04:15254void TextInputController::ExtendSelectionAndDelete(int before, int after) {
255 if (view()->MainFrame()) {
256 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
257 "called if the main frame "
258 "is not a local frame.";
259 view()->MainFrame()->ToWebLocalFrame()->ExtendSelectionAndDelete(before,
260 after);
261 }
262}
263
Ryan Landay6d163ae2018-01-17 06:58:06264void TextInputController::DeleteSurroundingText(int before, int after) {
265 if (view()->MainFrame()) {
266 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
267 "called if the main frame "
268 "is not a local frame.";
269 view()->MainFrame()->ToWebLocalFrame()->DeleteSurroundingText(before,
270 after);
271 }
272}
273
[email protected]f751653a92014-02-18 16:32:55274void TextInputController::SetMarkedText(const std::string& text,
Peter Kastinge468f502023-11-06 19:22:52275 uint32_t start,
276 uint32_t length) {
Blink Reformat1c4d759e2017-04-09 16:34:54277 blink::WebString web_text(blink::WebString::FromUTF8(text));
[email protected]f751653a92014-02-18 16:32:55278
279 // Split underline into up to 3 elements (before, selection, and after).
Dave Tapuska7fa75212020-06-04 17:46:11280 std::vector<ui::ImeTextSpan> ime_text_spans;
Peter Kastinge468f502023-11-06 19:22:52281 ui::ImeTextSpan selection;
282 if (start) {
283 ui::ImeTextSpan before;
284 before.end_offset = start;
285 ime_text_spans.push_back(before);
286
287 selection.start_offset = start;
288 selection.end_offset = base::ClampedNumeric(start) + length;
[email protected]f751653a92014-02-18 16:32:55289 } else {
Peter Kastinge468f502023-11-06 19:22:52290 selection.end_offset = length;
[email protected]f751653a92014-02-18 16:32:55291 }
Peter Kastinge468f502023-11-06 19:22:52292 if (selection.end_offset != selection.start_offset) {
293 selection.thickness = ui::ImeTextSpan::Thickness::kThick;
294 selection.underline_style = ui::ImeTextSpan::UnderlineStyle::kSolid;
295 ime_text_spans.push_back(selection);
296 }
297 if (selection.end_offset < web_text.length()) {
298 ui::ImeTextSpan after;
299 after.start_offset = selection.end_offset;
300 after.end_offset = web_text.length();
301 ime_text_spans.push_back(after);
[email protected]f751653a92014-02-18 16:32:55302 }
303
ekaramadc75b1b3b32016-12-02 03:57:52304 if (auto* controller = GetInputMethodController()) {
Ryan Landay9e42fd742017-08-12 01:59:11305 controller->SetComposition(web_text, ime_text_spans, blink::WebRange(),
Peter Kastinge468f502023-11-06 19:22:52306 selection.start_offset, selection.end_offset);
ekaramadc75b1b3b32016-12-02 03:57:52307 }
[email protected]f751653a92014-02-18 16:32:55308}
309
Peter Kastinge468f502023-11-06 19:22:52310void TextInputController::SetMarkedTextFromExistingText(uint32_t start,
311 uint32_t end) {
Ryan Landayd2034672018-01-12 22:22:32312 if (!view()->MainFrame())
313 return;
314
315 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
316 "called if the main frame "
317 "is not a local frame.";
318
319 view()->MainFrame()->ToWebLocalFrame()->SetCompositionFromExistingText(
Dave Tapuska7fa75212020-06-04 17:46:11320 start, end, std::vector<ui::ImeTextSpan>());
Ryan Landayd2034672018-01-12 22:22:32321}
322
[email protected]f751653a92014-02-18 16:32:55323bool TextInputController::HasMarkedText() {
Blink Reformat1c4d759e2017-04-09 16:34:54324 if (!view()->MainFrame())
yabinh8204efc2016-07-08 13:58:57325 return false;
326
Ryan Landayd2034672018-01-12 22:22:32327 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
328 "called if the main frame "
329 "is not a local frame.";
yabinh8204efc2016-07-08 13:58:57330
Blink Reformat1c4d759e2017-04-09 16:34:54331 return view()->MainFrame()->ToWebLocalFrame()->HasMarkedText();
[email protected]f751653a92014-02-18 16:32:55332}
333
334std::vector<int> TextInputController::MarkedRange() {
Blink Reformat1c4d759e2017-04-09 16:34:54335 if (!view()->MainFrame())
[email protected]6f9397122014-02-25 09:30:50336 return std::vector<int>();
337
Ryan Landayd2034672018-01-12 22:22:32338 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
339 "called if the main frame "
340 "is not a local frame.";
yabinh8204efc2016-07-08 13:58:57341
Blink Reformat1c4d759e2017-04-09 16:34:54342 blink::WebRange range = view()->MainFrame()->ToWebLocalFrame()->MarkedRange();
[email protected]f751653a92014-02-18 16:32:55343 std::vector<int> int_array(2);
Blink Reformat1c4d759e2017-04-09 16:34:54344 int_array[0] = range.StartOffset();
345 int_array[1] = range.EndOffset();
[email protected]f751653a92014-02-18 16:32:55346
347 return int_array;
348}
349
350std::vector<int> TextInputController::SelectedRange() {
Blink Reformat1c4d759e2017-04-09 16:34:54351 if (!view()->MainFrame())
[email protected]6f9397122014-02-25 09:30:50352 return std::vector<int>();
353
Ryan Landayd2034672018-01-12 22:22:32354 CHECK(view()->MainFrame()->ToWebLocalFrame()) << "This function cannot be "
355 "called if the main frame "
356 "is not a local frame.";
yabinh8204efc2016-07-08 13:58:57357
358 blink::WebRange range =
Blink Reformat1c4d759e2017-04-09 16:34:54359 view()->MainFrame()->ToWebLocalFrame()->SelectionRange();
360 if (range.IsNull())
yosin702c78a32016-06-13 08:39:13361 return std::vector<int>();
[email protected]f751653a92014-02-18 16:32:55362 std::vector<int> int_array(2);
Blink Reformat1c4d759e2017-04-09 16:34:54363 int_array[0] = range.StartOffset();
364 int_array[1] = range.EndOffset();
[email protected]f751653a92014-02-18 16:32:55365
366 return int_array;
367}
368
369std::vector<int> TextInputController::FirstRectForCharacterRange(
Peter Kasting7064abb2022-08-11 18:11:38370 uint32_t location,
371 uint32_t length) {
Dave Tapuskae8fe9b22021-01-21 20:38:21372 gfx::Rect rect;
Blink Reformat1c4d759e2017-04-09 16:34:54373 if (!view()->FocusedFrame() ||
374 !view()->FocusedFrame()->FirstRectForCharacterRange(location, length,
lukasza8b6d5f32016-04-22 16:56:31375 rect)) {
[email protected]f751653a92014-02-18 16:32:55376 return std::vector<int>();
[email protected]6f9397122014-02-25 09:30:50377 }
[email protected]f751653a92014-02-18 16:32:55378
379 std::vector<int> int_array(4);
Dave Tapuskae8fe9b22021-01-21 20:38:21380 int_array[0] = rect.x();
381 int_array[1] = rect.y();
382 int_array[2] = rect.width();
383 int_array[3] = rect.height();
[email protected]f751653a92014-02-18 16:32:55384
385 return int_array;
386}
387
Alex Kengd1e6590d2022-06-28 10:31:12388void TextInputController::SetComposition(const std::string& text,
389 int replacement_range_start,
390 int replacement_range_end) {
[email protected]f751653a92014-02-18 16:32:55391 // Sends a keydown event with key code = 0xE5 to emulate input method
392 // behavior.
Dave Tapuska347d60a2020-04-21 23:55:47393 blink::WebKeyboardEvent key_down(blink::WebInputEvent::Type::kRawKeyDown,
Daniel Cheng224569ee2018-04-25 05:45:06394 blink::WebInputEvent::kNoModifiers,
395 ui::EventTimeForNow());
dtapuska899ac222017-01-03 18:09:16396
Blink Reformat1c4d759e2017-04-09 16:34:54397 key_down.windows_key_code = 0xE5; // VKEY_PROCESSKEY
danakj763c2402018-11-09 02:46:22398 view()->MainFrameWidget()->HandleInputEvent(
Dave Tapuskacc788dd2020-05-11 22:33:56399 blink::WebCoalescedInputEvent(key_down, ui::LatencyInfo()));
[email protected]f751653a92014-02-18 16:32:55400
yabinhdd6d1b62016-08-23 07:09:02401 // The value returned by std::string::length() may not correspond to the
402 // actual number of encoded characters in sequences of multi-byte or
403 // variable-length characters.
Blink Reformat1c4d759e2017-04-09 16:34:54404 blink::WebString newText = blink::WebString::FromUTF8(text);
yabinhdd6d1b62016-08-23 07:09:02405 size_t textLength = newText.length();
406
Dave Tapuska7fa75212020-06-04 17:46:11407 std::vector<ui::ImeTextSpan> ime_text_spans;
408 ime_text_spans.push_back(ui::ImeTextSpan(
409 ui::ImeTextSpan::Type::kComposition, 0, textLength,
410 ui::ImeTextSpan::Thickness::kThin,
411 ui::ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT));
Alex Kengd1e6590d2022-06-28 10:31:12412 blink::WebRange replacement_range =
413 (replacement_range_start == -1 && replacement_range_end == -1)
414 ? blink::WebRange()
415 : blink::WebRange(replacement_range_start,
416 replacement_range_end - replacement_range_start);
ekaramadc75b1b3b32016-12-02 03:57:52417 if (auto* controller = GetInputMethodController()) {
Blink Reformat1c4d759e2017-04-09 16:34:54418 controller->SetComposition(
Xianzhu Wangaece0d42025-01-29 01:57:12419 newText, std::vector<ui::ImeTextSpan>(std::move(ime_text_spans)),
Alex Kengd1e6590d2022-06-28 10:31:12420 replacement_range, textLength, textLength);
ekaramadc75b1b3b32016-12-02 03:57:52421 }
lukasza8b6d5f32016-04-22 16:56:31422}
423
ekaramad2daaf672016-11-10 20:29:01424void TextInputController::ForceTextInputStateUpdate() {
Dave Tapuskaa5c53485102020-12-01 21:31:02425 blink::WebFrameWidget* frame_widget =
Dave Tapuska13da016a2021-02-04 21:51:58426 web_frame_test_proxy_->GetLocalRootWebFrameWidget();
Dave Tapuskaa5c53485102020-12-01 21:31:02427 frame_widget->ShowVirtualKeyboard();
ekaramad2daaf672016-11-10 20:29:01428}
429
lukasza8b6d5f32016-04-22 16:56:31430blink::WebView* TextInputController::view() {
Dave Tapuska13da016a2021-02-04 21:51:58431 return web_frame_test_proxy_->GetWebFrame()->View();
[email protected]f751653a92014-02-18 16:32:55432}
433
ekaramadc75b1b3b32016-12-02 03:57:52434blink::WebInputMethodController*
435TextInputController::GetInputMethodController() {
Blink Reformat1c4d759e2017-04-09 16:34:54436 if (!view()->MainFrame())
ekaramadc75b1b3b32016-12-02 03:57:52437 return nullptr;
438
Kent Tamura21d1de62018-12-10 04:45:20439 // TODO(lukasza): Finish adding OOPIF support to the web tests harness.
Daniel Cheng3c829432017-06-19 03:42:31440 CHECK(view()->MainFrame()->IsWebLocalFrame())
441 << "WebView does not have a local main frame and"
442 " cannot handle input method controller tasks.";
443
danakje3e48d42020-05-01 23:47:33444 return view()->MainFrameWidget()->GetActiveWebInputMethodController();
ekaramad2daaf672016-11-10 20:29:01445}
446
danakj741848a2020-04-07 22:48:06447} // namespace content