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.
5 #include "ui/views/controls/textfield/textfield.h"
11 #include "base/command_line.h"
12 #include "base/pickle.h"
13 #include "base/strings/string16.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "ui/base/clipboard/clipboard.h"
16 #include "ui/base/clipboard/scoped_clipboard_writer.h"
17 #include "ui/base/dragdrop/drag_drop_types.h"
18 #include "ui/base/ime/text_input_client.h"
19 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/ui_base_switches.h"
21 #include "ui/base/ui_base_switches_util.h"
22 #include "ui/events/event.h"
23 #include "ui/events/keycodes/keyboard_codes.h"
24 #include "ui/gfx/render_text.h"
25 #include "ui/strings/grit/ui_strings.h"
26 #include "ui/views/controls/textfield/textfield_controller.h"
27 #include "ui/views/controls/textfield/textfield_model.h"
28 #include "ui/views/controls/textfield/textfield_test_api.h"
29 #include "ui/views/focus/focus_manager.h"
30 #include "ui/views/ime/mock_input_method.h"
31 #include "ui/views/test/test_views_delegate.h"
32 #include "ui/views/test/views_test_base.h"
33 #include "ui/views/widget/widget.h"
34 #include "ui/wm/core/default_screen_position_client.h"
38 #include "base/win/windows_version.h"
41 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
42 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
46 #include "ui/events/event_utils.h"
49 using base::ASCIIToUTF16
;
50 using base::UTF8ToUTF16
;
51 using base::WideToUTF16
;
53 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16)
57 const base::char16 kHebrewLetterSamekh
= 0x05E1;
59 // A Textfield wrapper to intercept OnKey[Pressed|Released]() ressults.
60 class TestTextfield
: public views::Textfield
{
66 weak_ptr_factory_(this) {}
68 bool OnKeyPressed(const ui::KeyEvent
& e
) override
{
71 // Since OnKeyPressed() might destroy |this|, get a weak pointer and
72 // verify it isn't null before writing the bool value to key_handled_.
73 base::WeakPtr
<TestTextfield
> textfield(weak_ptr_factory_
.GetWeakPtr());
74 bool key
= views::Textfield::OnKeyPressed(e
);
84 bool OnKeyReleased(const ui::KeyEvent
& e
) override
{
86 key_handled_
= views::Textfield::OnKeyReleased(e
);
90 bool key_handled() const { return key_handled_
; }
91 bool key_received() const { return key_received_
; }
93 void clear() { key_received_
= key_handled_
= false; }
99 base::WeakPtrFactory
<TestTextfield
> weak_ptr_factory_
;
101 DISALLOW_COPY_AND_ASSIGN(TestTextfield
);
104 // Convenience to make constructing a GestureEvent simpler.
105 class GestureEventForTest
: public ui::GestureEvent
{
107 GestureEventForTest(int x
, int y
, ui::GestureEventDetails details
)
108 : GestureEvent(x
, y
, 0, base::TimeDelta(), details
) {}
111 DISALLOW_COPY_AND_ASSIGN(GestureEventForTest
);
114 // This controller will happily destroy the target textfield passed on
115 // construction when a key event is triggered.
116 class TextfieldDestroyerController
: public views::TextfieldController
{
118 explicit TextfieldDestroyerController(views::Textfield
* target
)
120 target_
->set_controller(this);
123 views::Textfield
* target() { return target_
.get(); }
125 // views::TextfieldController:
126 bool HandleKeyEvent(views::Textfield
* sender
,
127 const ui::KeyEvent
& key_event
) override
{
133 scoped_ptr
<views::Textfield
> target_
;
136 base::string16
GetClipboardText(ui::ClipboardType type
) {
138 ui::Clipboard::GetForCurrentThread()->ReadText(type
, &text
);
142 void SetClipboardText(ui::ClipboardType type
, const std::string
& text
) {
143 ui::ScopedClipboardWriter(type
).WriteText(ASCIIToUTF16(text
));
150 class TextfieldTest
: public ViewsTestBase
, public TextfieldController
{
157 on_before_user_action_(0),
158 on_after_user_action_(0),
159 copied_to_clipboard_(ui::CLIPBOARD_TYPE_LAST
) {
163 void SetUp() override
{
164 ViewsTestBase::SetUp();
165 #if defined(USE_AURA)
166 aura::client::SetScreenPositionClient(GetContext(),
167 &screen_position_client_
);
168 #endif // !defined(USE_AURA)
171 void TearDown() override
{
174 ViewsTestBase::TearDown();
177 ui::ClipboardType
GetAndResetCopiedToClipboard() {
178 ui::ClipboardType clipboard_type
= copied_to_clipboard_
;
179 copied_to_clipboard_
= ui::CLIPBOARD_TYPE_LAST
;
180 return clipboard_type
;
183 // TextfieldController:
184 void ContentsChanged(Textfield
* sender
,
185 const base::string16
& new_contents
) override
{
186 // Paste calls TextfieldController::ContentsChanged() explicitly even if the
187 // paste action did not change the content. So |new_contents| may match
188 // |last_contents_|. For more info, see http://crbug.com/79002
189 last_contents_
= new_contents
;
192 void OnBeforeUserAction(Textfield
* sender
) override
{
193 ++on_before_user_action_
;
196 void OnAfterUserAction(Textfield
* sender
) override
{
197 ++on_after_user_action_
;
200 void OnAfterCutOrCopy(ui::ClipboardType clipboard_type
) override
{
201 copied_to_clipboard_
= clipboard_type
;
204 void InitTextfield() {
208 void InitTextfields(int count
) {
209 ASSERT_FALSE(textfield_
);
210 textfield_
= new TestTextfield();
211 textfield_
->set_controller(this);
212 widget_
= new Widget();
213 Widget::InitParams params
= CreateParams(Widget::InitParams::TYPE_POPUP
);
214 params
.bounds
= gfx::Rect(100, 100, 100, 100);
215 widget_
->Init(params
);
216 View
* container
= new View();
217 widget_
->SetContentsView(container
);
218 container
->AddChildView(textfield_
);
219 textfield_
->SetBoundsRect(params
.bounds
);
220 textfield_
->set_id(1);
221 test_api_
.reset(new TextfieldTestApi(textfield_
));
223 for (int i
= 1; i
< count
; i
++) {
224 Textfield
* textfield
= new Textfield();
225 container
->AddChildView(textfield
);
226 textfield
->set_id(i
+ 1);
229 model_
= test_api_
->model();
230 model_
->ClearEditHistory();
232 input_method_
= new MockInputMethod();
233 widget_
->ReplaceInputMethod(input_method_
);
235 // Activate the widget and focus the textfield for input handling.
237 textfield_
->RequestFocus();
240 ui::MenuModel
* GetContextMenuModel() {
241 test_api_
->UpdateContextMenu();
242 return test_api_
->context_menu_contents();
246 void SendKeyEvent(ui::KeyboardCode key_code
,
251 int flags
= (alt
? ui::EF_ALT_DOWN
: 0) |
252 (shift
? ui::EF_SHIFT_DOWN
: 0) |
253 (control
? ui::EF_CONTROL_DOWN
: 0) |
254 (caps_lock
? ui::EF_CAPS_LOCK_DOWN
: 0);
255 ui::KeyEvent
event(ui::ET_KEY_PRESSED
, key_code
, flags
);
256 input_method_
->DispatchKeyEvent(event
);
259 void SendKeyEvent(ui::KeyboardCode key_code
, bool shift
, bool control
) {
260 SendKeyEvent(key_code
, false, shift
, control
, false);
263 void SendKeyEvent(ui::KeyboardCode key_code
) {
264 SendKeyEvent(key_code
, false, false);
267 void SendKeyEvent(base::char16 ch
) {
269 ui::KeyboardCode code
=
270 ch
== ' ' ? ui::VKEY_SPACE
:
271 static_cast<ui::KeyboardCode
>(ui::VKEY_A
+ ch
- 'a');
274 ui::KeyEvent
event(ch
, ui::VKEY_UNKNOWN
, ui::EF_NONE
);
275 input_method_
->DispatchKeyEvent(event
);
279 View
* GetFocusedView() {
280 return widget_
->GetFocusManager()->GetFocusedView();
283 int GetCursorPositionX(int cursor_pos
) {
284 return test_api_
->GetRenderText()->GetCursorBounds(
285 gfx::SelectionModel(cursor_pos
, gfx::CURSOR_FORWARD
), false).x();
288 // Get the current cursor bounds.
289 gfx::Rect
GetCursorBounds() {
290 return test_api_
->GetRenderText()->GetUpdatedCursorBounds();
293 // Get the cursor bounds of |sel|.
294 gfx::Rect
GetCursorBounds(const gfx::SelectionModel
& sel
) {
295 return test_api_
->GetRenderText()->GetCursorBounds(sel
, true);
298 gfx::Rect
GetDisplayRect() {
299 return test_api_
->GetRenderText()->display_rect();
302 // Mouse click on the point whose x-axis is |bound|'s x plus |x_offset| and
303 // y-axis is in the middle of |bound|'s vertical range.
304 void MouseClick(const gfx::Rect bound
, int x_offset
) {
305 gfx::Point
point(bound
.x() + x_offset
, bound
.y() + bound
.height() / 2);
306 ui::MouseEvent
click(ui::ET_MOUSE_PRESSED
, point
, point
,
307 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
308 textfield_
->OnMousePressed(click
);
309 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, point
, point
,
310 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
311 textfield_
->OnMouseReleased(release
);
314 // This is to avoid double/triple click.
315 void NonClientMouseClick() {
316 ui::MouseEvent
click(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
317 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_IS_NON_CLIENT
,
318 ui::EF_LEFT_MOUSE_BUTTON
);
319 textfield_
->OnMousePressed(click
);
320 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
321 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_IS_NON_CLIENT
,
322 ui::EF_LEFT_MOUSE_BUTTON
);
323 textfield_
->OnMouseReleased(release
);
326 // Simulates a complete tap.
327 void Tap(const gfx::Point
& point
) {
328 GestureEventForTest
begin(
329 point
.x(), point
.y(), ui::GestureEventDetails(ui::ET_GESTURE_BEGIN
));
330 textfield_
->OnGestureEvent(&begin
);
332 GestureEventForTest
tap_down(
333 point
.x(), point
.y(), ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN
));
334 textfield_
->OnGestureEvent(&tap_down
);
336 GestureEventForTest
show_press(
339 ui::GestureEventDetails(ui::ET_GESTURE_SHOW_PRESS
));
340 textfield_
->OnGestureEvent(&show_press
);
342 ui::GestureEventDetails
tap_details(ui::ET_GESTURE_TAP
);
343 tap_details
.set_tap_count(1);
344 GestureEventForTest
tap(point
.x(), point
.y(), tap_details
);
345 textfield_
->OnGestureEvent(&tap
);
347 GestureEventForTest
end(
348 point
.x(), point
.y(), ui::GestureEventDetails(ui::ET_GESTURE_END
));
349 textfield_
->OnGestureEvent(&end
);
352 void VerifyTextfieldContextMenuContents(bool textfield_has_selection
,
354 ui::MenuModel
* menu
) {
355 EXPECT_EQ(can_undo
, menu
->IsEnabledAt(0 /* UNDO */));
356 EXPECT_TRUE(menu
->IsEnabledAt(1 /* Separator */));
357 EXPECT_EQ(textfield_has_selection
, menu
->IsEnabledAt(2 /* CUT */));
358 EXPECT_EQ(textfield_has_selection
, menu
->IsEnabledAt(3 /* COPY */));
359 EXPECT_NE(GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
).empty(),
360 menu
->IsEnabledAt(4 /* PASTE */));
361 EXPECT_EQ(textfield_has_selection
, menu
->IsEnabledAt(5 /* DELETE */));
362 EXPECT_TRUE(menu
->IsEnabledAt(6 /* Separator */));
363 EXPECT_TRUE(menu
->IsEnabledAt(7 /* SELECT ALL */));
366 // We need widget to populate wrapper class.
369 TestTextfield
* textfield_
;
370 scoped_ptr
<TextfieldTestApi
> test_api_
;
371 TextfieldModel
* model_
;
373 // The string from Controller::ContentsChanged callback.
374 base::string16 last_contents_
;
376 // For testing input method related behaviors.
377 MockInputMethod
* input_method_
;
379 // Indicates how many times OnBeforeUserAction() is called.
380 int on_before_user_action_
;
382 // Indicates how many times OnAfterUserAction() is called.
383 int on_after_user_action_
;
386 ui::ClipboardType copied_to_clipboard_
;
387 wm::DefaultScreenPositionClient screen_position_client_
;
389 DISALLOW_COPY_AND_ASSIGN(TextfieldTest
);
392 TEST_F(TextfieldTest
, ModelChangesTest
) {
395 // TextfieldController::ContentsChanged() shouldn't be called when changing
396 // text programmatically.
397 last_contents_
.clear();
398 textfield_
->SetText(ASCIIToUTF16("this is"));
400 EXPECT_STR_EQ("this is", model_
->text());
401 EXPECT_STR_EQ("this is", textfield_
->text());
402 EXPECT_TRUE(last_contents_
.empty());
404 textfield_
->AppendText(ASCIIToUTF16(" a test"));
405 EXPECT_STR_EQ("this is a test", model_
->text());
406 EXPECT_STR_EQ("this is a test", textfield_
->text());
407 EXPECT_TRUE(last_contents_
.empty());
409 EXPECT_EQ(base::string16(), textfield_
->GetSelectedText());
410 textfield_
->SelectAll(false);
411 EXPECT_STR_EQ("this is a test", textfield_
->GetSelectedText());
412 EXPECT_TRUE(last_contents_
.empty());
415 TEST_F(TextfieldTest
, KeyTest
) {
417 // Event flags: key, alt, shift, ctrl, caps-lock.
418 SendKeyEvent(ui::VKEY_T
, false, true, false, false);
419 SendKeyEvent(ui::VKEY_E
, false, false, false, false);
420 SendKeyEvent(ui::VKEY_X
, false, true, false, true);
421 SendKeyEvent(ui::VKEY_T
, false, false, false, true);
422 SendKeyEvent(ui::VKEY_1
, false, true, false, false);
423 SendKeyEvent(ui::VKEY_1
, false, false, false, false);
424 SendKeyEvent(ui::VKEY_1
, false, true, false, true);
425 SendKeyEvent(ui::VKEY_1
, false, false, false, true);
426 EXPECT_STR_EQ("TexT!1!1", textfield_
->text());
429 TEST_F(TextfieldTest
, ControlAndSelectTest
) {
430 // Insert a test string in a textfield.
432 textfield_
->SetText(ASCIIToUTF16("one two three"));
433 SendKeyEvent(ui::VKEY_HOME
, false /* shift */, false /* control */);
434 SendKeyEvent(ui::VKEY_RIGHT
, true, false);
435 SendKeyEvent(ui::VKEY_RIGHT
, true, false);
436 SendKeyEvent(ui::VKEY_RIGHT
, true, false);
438 EXPECT_STR_EQ("one", textfield_
->GetSelectedText());
441 SendKeyEvent(ui::VKEY_RIGHT
, true, true);
442 EXPECT_STR_EQ("one two", textfield_
->GetSelectedText());
443 SendKeyEvent(ui::VKEY_RIGHT
, true, true);
444 EXPECT_STR_EQ("one two three", textfield_
->GetSelectedText());
445 SendKeyEvent(ui::VKEY_LEFT
, true, true);
446 EXPECT_STR_EQ("one two ", textfield_
->GetSelectedText());
447 SendKeyEvent(ui::VKEY_LEFT
, true, true);
448 EXPECT_STR_EQ("one ", textfield_
->GetSelectedText());
450 // Replace the selected text.
451 SendKeyEvent(ui::VKEY_Z
, true, false);
452 SendKeyEvent(ui::VKEY_E
, true, false);
453 SendKeyEvent(ui::VKEY_R
, true, false);
454 SendKeyEvent(ui::VKEY_O
, true, false);
455 SendKeyEvent(ui::VKEY_SPACE
, false, false);
456 EXPECT_STR_EQ("ZERO two three", textfield_
->text());
458 SendKeyEvent(ui::VKEY_END
, true, false);
459 EXPECT_STR_EQ("two three", textfield_
->GetSelectedText());
460 SendKeyEvent(ui::VKEY_HOME
, true, false);
461 EXPECT_STR_EQ("ZERO ", textfield_
->GetSelectedText());
464 TEST_F(TextfieldTest
, InsertionDeletionTest
) {
465 // Insert a test string in a textfield.
467 for (size_t i
= 0; i
< 10; i
++)
468 SendKeyEvent(static_cast<ui::KeyboardCode
>(ui::VKEY_A
+ i
));
469 EXPECT_STR_EQ("abcdefghij", textfield_
->text());
471 // Test the delete and backspace keys.
472 textfield_
->SelectRange(gfx::Range(5));
473 for (int i
= 0; i
< 3; i
++)
474 SendKeyEvent(ui::VKEY_BACK
);
475 EXPECT_STR_EQ("abfghij", textfield_
->text());
476 for (int i
= 0; i
< 3; i
++)
477 SendKeyEvent(ui::VKEY_DELETE
);
478 EXPECT_STR_EQ("abij", textfield_
->text());
480 // Select all and replace with "k".
481 textfield_
->SelectAll(false);
482 SendKeyEvent(ui::VKEY_K
);
483 EXPECT_STR_EQ("k", textfield_
->text());
485 // Delete the previous word from cursor.
486 textfield_
->SetText(ASCIIToUTF16("one two three four"));
487 SendKeyEvent(ui::VKEY_END
);
488 SendKeyEvent(ui::VKEY_BACK
, false, false, true, false);
489 EXPECT_STR_EQ("one two three ", textfield_
->text());
491 // Delete to a line break on Linux and ChromeOS, to a word break on Windows.
492 SendKeyEvent(ui::VKEY_LEFT
, false, false, true, false);
493 SendKeyEvent(ui::VKEY_BACK
, false, true, true, false);
494 #if defined(OS_LINUX)
495 EXPECT_STR_EQ("three ", textfield_
->text());
497 EXPECT_STR_EQ("one three ", textfield_
->text());
500 // Delete the next word from cursor.
501 textfield_
->SetText(ASCIIToUTF16("one two three four"));
502 SendKeyEvent(ui::VKEY_HOME
);
503 SendKeyEvent(ui::VKEY_DELETE
, false, false, true, false);
504 EXPECT_STR_EQ(" two three four", textfield_
->text());
506 // Delete to a line break on Linux and ChromeOS, to a word break on Windows.
507 SendKeyEvent(ui::VKEY_RIGHT
, false, false, true, false);
508 SendKeyEvent(ui::VKEY_DELETE
, false, true, true, false);
509 #if defined(OS_LINUX)
510 EXPECT_STR_EQ(" two", textfield_
->text());
512 EXPECT_STR_EQ(" two four", textfield_
->text());
516 TEST_F(TextfieldTest
, PasswordTest
) {
518 textfield_
->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD
);
519 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD
, textfield_
->GetTextInputType());
520 EXPECT_TRUE(textfield_
->enabled());
521 EXPECT_TRUE(textfield_
->IsFocusable());
523 last_contents_
.clear();
524 textfield_
->SetText(ASCIIToUTF16("password"));
525 // Ensure text() and the callback returns the actual text instead of "*".
526 EXPECT_STR_EQ("password", textfield_
->text());
527 EXPECT_TRUE(last_contents_
.empty());
528 model_
->SelectAll(false);
529 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "foo");
531 // Cut and copy should be disabled.
532 EXPECT_FALSE(textfield_
->IsCommandIdEnabled(IDS_APP_CUT
));
533 textfield_
->ExecuteCommand(IDS_APP_CUT
, 0);
534 SendKeyEvent(ui::VKEY_X
, false, true);
535 EXPECT_FALSE(textfield_
->IsCommandIdEnabled(IDS_APP_COPY
));
536 textfield_
->ExecuteCommand(IDS_APP_COPY
, 0);
537 SendKeyEvent(ui::VKEY_C
, false, true);
538 SendKeyEvent(ui::VKEY_INSERT
, false, true);
539 EXPECT_STR_EQ("foo", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
540 EXPECT_STR_EQ("password", textfield_
->text());
541 // [Shift]+[Delete] should just delete without copying text to the clipboard.
542 textfield_
->SelectAll(false);
543 SendKeyEvent(ui::VKEY_DELETE
, true, false);
545 // Paste should work normally.
546 EXPECT_TRUE(textfield_
->IsCommandIdEnabled(IDS_APP_PASTE
));
547 textfield_
->ExecuteCommand(IDS_APP_PASTE
, 0);
548 SendKeyEvent(ui::VKEY_V
, false, true);
549 SendKeyEvent(ui::VKEY_INSERT
, true, false);
550 EXPECT_STR_EQ("foo", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
551 EXPECT_STR_EQ("foofoofoo", textfield_
->text());
554 TEST_F(TextfieldTest
, TextInputType
) {
558 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT
, textfield_
->GetTextInputType());
561 textfield_
->SetTextInputType(ui::TEXT_INPUT_TYPE_URL
);
562 EXPECT_EQ(ui::TEXT_INPUT_TYPE_URL
, textfield_
->GetTextInputType());
563 textfield_
->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD
);
564 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD
, textfield_
->GetTextInputType());
566 // Readonly textfields have type NONE
567 textfield_
->SetReadOnly(true);
568 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE
, textfield_
->GetTextInputType());
570 textfield_
->SetReadOnly(false);
571 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD
, textfield_
->GetTextInputType());
573 // As do disabled textfields
574 textfield_
->SetEnabled(false);
575 EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE
, textfield_
->GetTextInputType());
577 textfield_
->SetEnabled(true);
578 EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD
, textfield_
->GetTextInputType());
581 TEST_F(TextfieldTest
, OnKeyPress
) {
584 // Character keys are handled by the input method.
585 SendKeyEvent(ui::VKEY_A
);
586 EXPECT_TRUE(textfield_
->key_received());
587 EXPECT_FALSE(textfield_
->key_handled());
590 // Arrow keys and home/end are handled by the textfield.
591 SendKeyEvent(ui::VKEY_LEFT
);
592 EXPECT_TRUE(textfield_
->key_received());
593 EXPECT_TRUE(textfield_
->key_handled());
596 SendKeyEvent(ui::VKEY_RIGHT
);
597 EXPECT_TRUE(textfield_
->key_received());
598 EXPECT_TRUE(textfield_
->key_handled());
601 SendKeyEvent(ui::VKEY_HOME
);
602 EXPECT_TRUE(textfield_
->key_received());
603 EXPECT_TRUE(textfield_
->key_handled());
606 SendKeyEvent(ui::VKEY_END
);
607 EXPECT_TRUE(textfield_
->key_received());
608 EXPECT_TRUE(textfield_
->key_handled());
611 // F24, up/down key won't be handled.
612 SendKeyEvent(ui::VKEY_F24
);
613 EXPECT_TRUE(textfield_
->key_received());
614 EXPECT_FALSE(textfield_
->key_handled());
617 SendKeyEvent(ui::VKEY_UP
);
618 EXPECT_TRUE(textfield_
->key_received());
619 EXPECT_FALSE(textfield_
->key_handled());
622 SendKeyEvent(ui::VKEY_DOWN
);
623 EXPECT_TRUE(textfield_
->key_received());
624 EXPECT_FALSE(textfield_
->key_handled());
628 // Tests that default key bindings are handled even with a delegate installed.
629 TEST_F(TextfieldTest
, OnKeyPressBinding
) {
632 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
633 // Install a TextEditKeyBindingsDelegateAuraLinux that does nothing.
634 class TestDelegate
: public ui::TextEditKeyBindingsDelegateAuraLinux
{
637 ~TestDelegate() override
{}
640 const ui::Event
& event
,
641 std::vector
<ui::TextEditCommandAuraLinux
>* commands
) override
{
646 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
649 TestDelegate delegate
;
650 ui::SetTextEditKeyBindingsDelegate(&delegate
);
653 SendKeyEvent(ui::VKEY_A
, false, false);
654 EXPECT_STR_EQ("a", textfield_
->text());
657 // Undo/Redo command keys are handled by the textfield.
658 SendKeyEvent(ui::VKEY_Z
, false, true);
659 EXPECT_TRUE(textfield_
->key_received());
660 EXPECT_TRUE(textfield_
->key_handled());
661 EXPECT_TRUE(textfield_
->text().empty());
664 SendKeyEvent(ui::VKEY_Z
, true, true);
665 EXPECT_TRUE(textfield_
->key_received());
666 EXPECT_TRUE(textfield_
->key_handled());
667 EXPECT_STR_EQ("a", textfield_
->text());
670 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
671 ui::SetTextEditKeyBindingsDelegate(NULL
);
675 TEST_F(TextfieldTest
, CursorMovement
) {
678 // Test with trailing whitespace.
679 textfield_
->SetText(ASCIIToUTF16("one two hre "));
681 // Send the cursor at the end.
682 SendKeyEvent(ui::VKEY_END
);
684 // Ctrl+Left should move the cursor just before the last word.
685 SendKeyEvent(ui::VKEY_LEFT
, false, true);
686 SendKeyEvent(ui::VKEY_T
);
687 EXPECT_STR_EQ("one two thre ", textfield_
->text());
688 EXPECT_STR_EQ("one two thre ", last_contents_
);
690 // Ctrl+Right should move the cursor to the end of the last word.
691 SendKeyEvent(ui::VKEY_RIGHT
, false, true);
692 SendKeyEvent(ui::VKEY_E
);
693 EXPECT_STR_EQ("one two three ", textfield_
->text());
694 EXPECT_STR_EQ("one two three ", last_contents_
);
696 // Ctrl+Right again should move the cursor to the end.
697 SendKeyEvent(ui::VKEY_RIGHT
, false, true);
698 SendKeyEvent(ui::VKEY_BACK
);
699 EXPECT_STR_EQ("one two three", textfield_
->text());
700 EXPECT_STR_EQ("one two three", last_contents_
);
702 // Test with leading whitespace.
703 textfield_
->SetText(ASCIIToUTF16(" ne two"));
705 // Send the cursor at the beginning.
706 SendKeyEvent(ui::VKEY_HOME
);
708 // Ctrl+Right, then Ctrl+Left should move the cursor to the beginning of the
710 SendKeyEvent(ui::VKEY_RIGHT
, false, true);
711 SendKeyEvent(ui::VKEY_LEFT
, false, true);
712 SendKeyEvent(ui::VKEY_O
);
713 EXPECT_STR_EQ(" one two", textfield_
->text());
714 EXPECT_STR_EQ(" one two", last_contents_
);
716 // Ctrl+Left to move the cursor to the beginning of the first word.
717 SendKeyEvent(ui::VKEY_LEFT
, false, true);
718 // Ctrl+Left again should move the cursor back to the very beginning.
719 SendKeyEvent(ui::VKEY_LEFT
, false, true);
720 SendKeyEvent(ui::VKEY_DELETE
);
721 EXPECT_STR_EQ("one two", textfield_
->text());
722 EXPECT_STR_EQ("one two", last_contents_
);
725 TEST_F(TextfieldTest
, FocusTraversalTest
) {
727 textfield_
->RequestFocus();
729 EXPECT_EQ(1, GetFocusedView()->id());
730 widget_
->GetFocusManager()->AdvanceFocus(false);
731 EXPECT_EQ(2, GetFocusedView()->id());
732 widget_
->GetFocusManager()->AdvanceFocus(false);
733 EXPECT_EQ(3, GetFocusedView()->id());
734 // Cycle back to the first textfield.
735 widget_
->GetFocusManager()->AdvanceFocus(false);
736 EXPECT_EQ(1, GetFocusedView()->id());
738 widget_
->GetFocusManager()->AdvanceFocus(true);
739 EXPECT_EQ(3, GetFocusedView()->id());
740 widget_
->GetFocusManager()->AdvanceFocus(true);
741 EXPECT_EQ(2, GetFocusedView()->id());
742 widget_
->GetFocusManager()->AdvanceFocus(true);
743 EXPECT_EQ(1, GetFocusedView()->id());
744 // Cycle back to the last textfield.
745 widget_
->GetFocusManager()->AdvanceFocus(true);
746 EXPECT_EQ(3, GetFocusedView()->id());
748 // Request focus should still work.
749 textfield_
->RequestFocus();
750 EXPECT_EQ(1, GetFocusedView()->id());
752 // Test if clicking on textfield view sets the focus.
753 widget_
->GetFocusManager()->AdvanceFocus(true);
754 EXPECT_EQ(3, GetFocusedView()->id());
755 ui::MouseEvent
click(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
756 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
757 textfield_
->OnMousePressed(click
);
758 EXPECT_EQ(1, GetFocusedView()->id());
761 TEST_F(TextfieldTest
, ContextMenuDisplayTest
) {
763 EXPECT_TRUE(textfield_
->context_menu_controller());
764 textfield_
->SetText(ASCIIToUTF16("hello world"));
765 ui::Clipboard::GetForCurrentThread()->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE
);
766 textfield_
->ClearEditHistory();
767 EXPECT_TRUE(GetContextMenuModel());
768 VerifyTextfieldContextMenuContents(false, false, GetContextMenuModel());
770 textfield_
->SelectAll(false);
771 VerifyTextfieldContextMenuContents(true, false, GetContextMenuModel());
773 SendKeyEvent(ui::VKEY_T
);
774 VerifyTextfieldContextMenuContents(false, true, GetContextMenuModel());
776 textfield_
->SelectAll(false);
777 VerifyTextfieldContextMenuContents(true, true, GetContextMenuModel());
779 // Exercise the "paste enabled?" check in the verifier.
780 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "Test");
781 VerifyTextfieldContextMenuContents(true, true, GetContextMenuModel());
784 TEST_F(TextfieldTest
, DoubleAndTripleClickTest
) {
786 textfield_
->SetText(ASCIIToUTF16("hello world"));
787 ui::MouseEvent
click(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
788 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
789 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, gfx::Point(), gfx::Point(),
790 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
791 ui::MouseEvent
double_click(
792 ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
793 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_IS_DOUBLE_CLICK
,
794 ui::EF_LEFT_MOUSE_BUTTON
);
796 // Test for double click.
797 textfield_
->OnMousePressed(click
);
798 textfield_
->OnMouseReleased(release
);
799 EXPECT_TRUE(textfield_
->GetSelectedText().empty());
800 textfield_
->OnMousePressed(double_click
);
801 textfield_
->OnMouseReleased(release
);
802 EXPECT_STR_EQ("hello", textfield_
->GetSelectedText());
804 // Test for triple click.
805 textfield_
->OnMousePressed(click
);
806 textfield_
->OnMouseReleased(release
);
807 EXPECT_STR_EQ("hello world", textfield_
->GetSelectedText());
809 // Another click should reset back to double click.
810 textfield_
->OnMousePressed(click
);
811 textfield_
->OnMouseReleased(release
);
812 EXPECT_STR_EQ("hello", textfield_
->GetSelectedText());
815 TEST_F(TextfieldTest
, DragToSelect
) {
817 textfield_
->SetText(ASCIIToUTF16("hello world"));
818 const int kStart
= GetCursorPositionX(5);
819 const int kEnd
= 500;
820 gfx::Point
start_point(kStart
, 0);
821 gfx::Point
end_point(kEnd
, 0);
822 ui::MouseEvent
click_a(ui::ET_MOUSE_PRESSED
, start_point
, start_point
,
823 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
824 ui::MouseEvent
click_b(ui::ET_MOUSE_PRESSED
, end_point
, end_point
,
825 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
826 ui::MouseEvent
drag_left(ui::ET_MOUSE_DRAGGED
, gfx::Point(), gfx::Point(),
827 ui::EF_LEFT_MOUSE_BUTTON
, 0);
828 ui::MouseEvent
drag_right(ui::ET_MOUSE_DRAGGED
, end_point
, end_point
,
829 ui::EF_LEFT_MOUSE_BUTTON
, 0);
830 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, end_point
, end_point
,
831 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
832 textfield_
->OnMousePressed(click_a
);
833 EXPECT_TRUE(textfield_
->GetSelectedText().empty());
834 // Check that dragging left selects the beginning of the string.
835 textfield_
->OnMouseDragged(drag_left
);
836 base::string16 text_left
= textfield_
->GetSelectedText();
837 EXPECT_STR_EQ("hello", text_left
);
838 // Check that dragging right selects the rest of the string.
839 textfield_
->OnMouseDragged(drag_right
);
840 base::string16 text_right
= textfield_
->GetSelectedText();
841 EXPECT_STR_EQ(" world", text_right
);
842 // Check that releasing in the same location does not alter the selection.
843 textfield_
->OnMouseReleased(release
);
844 EXPECT_EQ(text_right
, textfield_
->GetSelectedText());
845 // Check that dragging from beyond the text length works too.
846 textfield_
->OnMousePressed(click_b
);
847 textfield_
->OnMouseDragged(drag_left
);
848 textfield_
->OnMouseReleased(release
);
849 EXPECT_EQ(textfield_
->text(), textfield_
->GetSelectedText());
853 TEST_F(TextfieldTest
, DragAndDrop_AcceptDrop
) {
855 textfield_
->SetText(ASCIIToUTF16("hello world"));
857 ui::OSExchangeData data
;
858 base::string16
string(ASCIIToUTF16("string "));
859 data
.SetString(string
);
861 std::set
<OSExchangeData::CustomFormat
> custom_formats
;
863 // Ensure that disabled textfields do not accept drops.
864 textfield_
->SetEnabled(false);
865 EXPECT_FALSE(textfield_
->GetDropFormats(&formats
, &custom_formats
));
866 EXPECT_EQ(0, formats
);
867 EXPECT_TRUE(custom_formats
.empty());
868 EXPECT_FALSE(textfield_
->CanDrop(data
));
869 textfield_
->SetEnabled(true);
871 // Ensure that read-only textfields do not accept drops.
872 textfield_
->SetReadOnly(true);
873 EXPECT_FALSE(textfield_
->GetDropFormats(&formats
, &custom_formats
));
874 EXPECT_EQ(0, formats
);
875 EXPECT_TRUE(custom_formats
.empty());
876 EXPECT_FALSE(textfield_
->CanDrop(data
));
877 textfield_
->SetReadOnly(false);
879 // Ensure that enabled and editable textfields do accept drops.
880 EXPECT_TRUE(textfield_
->GetDropFormats(&formats
, &custom_formats
));
881 EXPECT_EQ(ui::OSExchangeData::STRING
, formats
);
882 EXPECT_TRUE(custom_formats
.empty());
883 EXPECT_TRUE(textfield_
->CanDrop(data
));
884 gfx::Point
drop_point(GetCursorPositionX(6), 0);
885 ui::DropTargetEvent
drop(data
, drop_point
, drop_point
,
886 ui::DragDropTypes::DRAG_COPY
| ui::DragDropTypes::DRAG_MOVE
);
887 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY
| ui::DragDropTypes::DRAG_MOVE
,
888 textfield_
->OnDragUpdated(drop
));
889 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY
, textfield_
->OnPerformDrop(drop
));
890 EXPECT_STR_EQ("hello string world", textfield_
->text());
892 // Ensure that textfields do not accept non-OSExchangeData::STRING types.
893 ui::OSExchangeData bad_data
;
894 bad_data
.SetFilename(base::FilePath(FILE_PATH_LITERAL("x")));
895 ui::OSExchangeData::CustomFormat fmt
= ui::Clipboard::GetBitmapFormatType();
896 bad_data
.SetPickledData(fmt
, Pickle());
897 bad_data
.SetFileContents(base::FilePath(L
"x"), "x");
898 bad_data
.SetHtml(base::string16(ASCIIToUTF16("x")), GURL("x.org"));
899 ui::OSExchangeData::DownloadFileInfo
download(base::FilePath(), NULL
);
900 bad_data
.SetDownloadFileInfo(download
);
901 EXPECT_FALSE(textfield_
->CanDrop(bad_data
));
905 TEST_F(TextfieldTest
, DragAndDrop_InitiateDrag
) {
907 textfield_
->SetText(ASCIIToUTF16("hello string world"));
909 // Ensure the textfield will provide selected text for drag data.
910 base::string16 string
;
911 ui::OSExchangeData data
;
912 const gfx::Range
kStringRange(6, 12);
913 textfield_
->SelectRange(kStringRange
);
914 const gfx::Point
kStringPoint(GetCursorPositionX(9), 0);
915 textfield_
->WriteDragDataForView(NULL
, kStringPoint
, &data
);
916 EXPECT_TRUE(data
.GetString(&string
));
917 EXPECT_EQ(textfield_
->GetSelectedText(), string
);
919 // Ensure that disabled textfields do not support drag operations.
920 textfield_
->SetEnabled(false);
921 EXPECT_EQ(ui::DragDropTypes::DRAG_NONE
,
922 textfield_
->GetDragOperationsForView(NULL
, kStringPoint
));
923 textfield_
->SetEnabled(true);
924 // Ensure that textfields without selections do not support drag operations.
925 textfield_
->ClearSelection();
926 EXPECT_EQ(ui::DragDropTypes::DRAG_NONE
,
927 textfield_
->GetDragOperationsForView(NULL
, kStringPoint
));
928 textfield_
->SelectRange(kStringRange
);
929 // Ensure that password textfields do not support drag operations.
930 textfield_
->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD
);
931 EXPECT_EQ(ui::DragDropTypes::DRAG_NONE
,
932 textfield_
->GetDragOperationsForView(NULL
, kStringPoint
));
933 textfield_
->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT
);
934 // Ensure that textfields only initiate drag operations inside the selection.
935 ui::MouseEvent
press_event(ui::ET_MOUSE_PRESSED
, kStringPoint
, kStringPoint
,
936 ui::EF_LEFT_MOUSE_BUTTON
,
937 ui::EF_LEFT_MOUSE_BUTTON
);
938 textfield_
->OnMousePressed(press_event
);
939 EXPECT_EQ(ui::DragDropTypes::DRAG_NONE
,
940 textfield_
->GetDragOperationsForView(NULL
, gfx::Point()));
941 EXPECT_FALSE(textfield_
->CanStartDragForView(NULL
, gfx::Point(),
943 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY
,
944 textfield_
->GetDragOperationsForView(NULL
, kStringPoint
));
945 EXPECT_TRUE(textfield_
->CanStartDragForView(NULL
, kStringPoint
,
947 // Ensure that textfields support local moves.
948 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
| ui::DragDropTypes::DRAG_COPY
,
949 textfield_
->GetDragOperationsForView(textfield_
, kStringPoint
));
952 TEST_F(TextfieldTest
, DragAndDrop_ToTheRight
) {
954 textfield_
->SetText(ASCIIToUTF16("hello world"));
956 base::string16 string
;
957 ui::OSExchangeData data
;
960 std::set
<OSExchangeData::CustomFormat
> custom_formats
;
962 // Start dragging "ello".
963 textfield_
->SelectRange(gfx::Range(1, 5));
964 gfx::Point
point(GetCursorPositionX(3), 0);
965 ui::MouseEvent
click_a(ui::ET_MOUSE_PRESSED
, point
, point
,
966 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
967 textfield_
->OnMousePressed(click_a
);
968 EXPECT_TRUE(textfield_
->CanStartDragForView(textfield_
, click_a
.location(),
970 operations
= textfield_
->GetDragOperationsForView(textfield_
,
972 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
| ui::DragDropTypes::DRAG_COPY
,
974 textfield_
->WriteDragDataForView(NULL
, click_a
.location(), &data
);
975 EXPECT_TRUE(data
.GetString(&string
));
976 EXPECT_EQ(textfield_
->GetSelectedText(), string
);
977 EXPECT_TRUE(textfield_
->GetDropFormats(&formats
, &custom_formats
));
978 EXPECT_EQ(ui::OSExchangeData::STRING
, formats
);
979 EXPECT_TRUE(custom_formats
.empty());
981 // Drop "ello" after "w".
982 const gfx::Point
kDropPoint(GetCursorPositionX(7), 0);
983 EXPECT_TRUE(textfield_
->CanDrop(data
));
984 ui::DropTargetEvent
drop_a(data
, kDropPoint
, kDropPoint
, operations
);
985 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
, textfield_
->OnDragUpdated(drop_a
));
986 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
, textfield_
->OnPerformDrop(drop_a
));
987 EXPECT_STR_EQ("h welloorld", textfield_
->text());
988 textfield_
->OnDragDone();
990 // Undo/Redo the drag&drop change.
991 SendKeyEvent(ui::VKEY_Z
, false, true);
992 EXPECT_STR_EQ("hello world", textfield_
->text());
993 SendKeyEvent(ui::VKEY_Z
, false, true);
994 EXPECT_STR_EQ("", textfield_
->text());
995 SendKeyEvent(ui::VKEY_Z
, false, true);
996 EXPECT_STR_EQ("", textfield_
->text());
997 SendKeyEvent(ui::VKEY_Y
, false, true);
998 EXPECT_STR_EQ("hello world", textfield_
->text());
999 SendKeyEvent(ui::VKEY_Y
, false, true);
1000 EXPECT_STR_EQ("h welloorld", textfield_
->text());
1001 SendKeyEvent(ui::VKEY_Y
, false, true);
1002 EXPECT_STR_EQ("h welloorld", textfield_
->text());
1005 TEST_F(TextfieldTest
, DragAndDrop_ToTheLeft
) {
1007 textfield_
->SetText(ASCIIToUTF16("hello world"));
1009 base::string16 string
;
1010 ui::OSExchangeData data
;
1013 std::set
<OSExchangeData::CustomFormat
> custom_formats
;
1015 // Start dragging " worl".
1016 textfield_
->SelectRange(gfx::Range(5, 10));
1017 gfx::Point
point(GetCursorPositionX(7), 0);
1018 ui::MouseEvent
click_a(ui::ET_MOUSE_PRESSED
, point
, point
,
1019 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1020 textfield_
->OnMousePressed(click_a
);
1021 EXPECT_TRUE(textfield_
->CanStartDragForView(textfield_
, click_a
.location(),
1023 operations
= textfield_
->GetDragOperationsForView(textfield_
,
1024 click_a
.location());
1025 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
| ui::DragDropTypes::DRAG_COPY
,
1027 textfield_
->WriteDragDataForView(NULL
, click_a
.location(), &data
);
1028 EXPECT_TRUE(data
.GetString(&string
));
1029 EXPECT_EQ(textfield_
->GetSelectedText(), string
);
1030 EXPECT_TRUE(textfield_
->GetDropFormats(&formats
, &custom_formats
));
1031 EXPECT_EQ(ui::OSExchangeData::STRING
, formats
);
1032 EXPECT_TRUE(custom_formats
.empty());
1034 // Drop " worl" after "h".
1035 EXPECT_TRUE(textfield_
->CanDrop(data
));
1036 gfx::Point
drop_point(GetCursorPositionX(1), 0);
1037 ui::DropTargetEvent
drop_a(data
, drop_point
, drop_point
, operations
);
1038 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
, textfield_
->OnDragUpdated(drop_a
));
1039 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
, textfield_
->OnPerformDrop(drop_a
));
1040 EXPECT_STR_EQ("h worlellod", textfield_
->text());
1041 textfield_
->OnDragDone();
1043 // Undo/Redo the drag&drop change.
1044 SendKeyEvent(ui::VKEY_Z
, false, true);
1045 EXPECT_STR_EQ("hello world", textfield_
->text());
1046 SendKeyEvent(ui::VKEY_Z
, false, true);
1047 EXPECT_STR_EQ("", textfield_
->text());
1048 SendKeyEvent(ui::VKEY_Z
, false, true);
1049 EXPECT_STR_EQ("", textfield_
->text());
1050 SendKeyEvent(ui::VKEY_Y
, false, true);
1051 EXPECT_STR_EQ("hello world", textfield_
->text());
1052 SendKeyEvent(ui::VKEY_Y
, false, true);
1053 EXPECT_STR_EQ("h worlellod", textfield_
->text());
1054 SendKeyEvent(ui::VKEY_Y
, false, true);
1055 EXPECT_STR_EQ("h worlellod", textfield_
->text());
1058 TEST_F(TextfieldTest
, DragAndDrop_Canceled
) {
1060 textfield_
->SetText(ASCIIToUTF16("hello world"));
1062 // Start dragging "worl".
1063 textfield_
->SelectRange(gfx::Range(6, 10));
1064 gfx::Point
point(GetCursorPositionX(8), 0);
1065 ui::MouseEvent
click(ui::ET_MOUSE_PRESSED
, point
, point
,
1066 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1067 textfield_
->OnMousePressed(click
);
1068 ui::OSExchangeData data
;
1069 textfield_
->WriteDragDataForView(NULL
, click
.location(), &data
);
1070 EXPECT_TRUE(textfield_
->CanDrop(data
));
1071 // Drag the text over somewhere valid, outside the current selection.
1072 gfx::Point
drop_point(GetCursorPositionX(2), 0);
1073 ui::DropTargetEvent
drop(data
, drop_point
, drop_point
,
1074 ui::DragDropTypes::DRAG_MOVE
);
1075 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE
, textfield_
->OnDragUpdated(drop
));
1076 // "Cancel" the drag, via move and release over the selection, and OnDragDone.
1077 gfx::Point
drag_point(GetCursorPositionX(9), 0);
1078 ui::MouseEvent
drag(ui::ET_MOUSE_DRAGGED
, drag_point
, drag_point
,
1079 ui::EF_LEFT_MOUSE_BUTTON
, 0);
1080 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, drag_point
, drag_point
,
1081 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1082 textfield_
->OnMouseDragged(drag
);
1083 textfield_
->OnMouseReleased(release
);
1084 textfield_
->OnDragDone();
1085 EXPECT_EQ(ASCIIToUTF16("hello world"), textfield_
->text());
1088 TEST_F(TextfieldTest
, ReadOnlyTest
) {
1090 textfield_
->SetText(ASCIIToUTF16("read only"));
1091 textfield_
->SetReadOnly(true);
1092 EXPECT_TRUE(textfield_
->enabled());
1093 EXPECT_TRUE(textfield_
->IsFocusable());
1095 SendKeyEvent(ui::VKEY_HOME
);
1096 EXPECT_EQ(0U, textfield_
->GetCursorPosition());
1097 SendKeyEvent(ui::VKEY_END
);
1098 EXPECT_EQ(9U, textfield_
->GetCursorPosition());
1100 SendKeyEvent(ui::VKEY_LEFT
, false, false);
1101 EXPECT_EQ(8U, textfield_
->GetCursorPosition());
1102 SendKeyEvent(ui::VKEY_LEFT
, false, true);
1103 EXPECT_EQ(5U, textfield_
->GetCursorPosition());
1104 SendKeyEvent(ui::VKEY_LEFT
, true, true);
1105 EXPECT_EQ(0U, textfield_
->GetCursorPosition());
1106 EXPECT_STR_EQ("read ", textfield_
->GetSelectedText());
1107 textfield_
->SelectAll(false);
1108 EXPECT_STR_EQ("read only", textfield_
->GetSelectedText());
1110 // Cut should be disabled.
1111 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "Test");
1112 EXPECT_FALSE(textfield_
->IsCommandIdEnabled(IDS_APP_CUT
));
1113 textfield_
->ExecuteCommand(IDS_APP_CUT
, 0);
1114 SendKeyEvent(ui::VKEY_X
, false, true);
1115 SendKeyEvent(ui::VKEY_DELETE
, true, false);
1116 EXPECT_STR_EQ("Test", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1117 EXPECT_STR_EQ("read only", textfield_
->text());
1119 // Paste should be disabled.
1120 EXPECT_FALSE(textfield_
->IsCommandIdEnabled(IDS_APP_PASTE
));
1121 textfield_
->ExecuteCommand(IDS_APP_PASTE
, 0);
1122 SendKeyEvent(ui::VKEY_V
, false, true);
1123 SendKeyEvent(ui::VKEY_INSERT
, true, false);
1124 EXPECT_STR_EQ("read only", textfield_
->text());
1126 // Copy should work normally.
1127 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "Test");
1128 EXPECT_TRUE(textfield_
->IsCommandIdEnabled(IDS_APP_COPY
));
1129 textfield_
->ExecuteCommand(IDS_APP_COPY
, 0);
1130 EXPECT_STR_EQ("read only", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1131 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "Test");
1132 SendKeyEvent(ui::VKEY_C
, false, true);
1133 EXPECT_STR_EQ("read only", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1134 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "Test");
1135 SendKeyEvent(ui::VKEY_INSERT
, false, true);
1136 EXPECT_STR_EQ("read only", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1138 // SetText should work even in read only mode.
1139 textfield_
->SetText(ASCIIToUTF16(" four five six "));
1140 EXPECT_STR_EQ(" four five six ", textfield_
->text());
1142 textfield_
->SelectAll(false);
1143 EXPECT_STR_EQ(" four five six ", textfield_
->GetSelectedText());
1145 // Text field is unmodifiable and selection shouldn't change.
1146 SendKeyEvent(ui::VKEY_DELETE
);
1147 EXPECT_STR_EQ(" four five six ", textfield_
->GetSelectedText());
1148 SendKeyEvent(ui::VKEY_BACK
);
1149 EXPECT_STR_EQ(" four five six ", textfield_
->GetSelectedText());
1150 SendKeyEvent(ui::VKEY_T
);
1151 EXPECT_STR_EQ(" four five six ", textfield_
->GetSelectedText());
1154 TEST_F(TextfieldTest
, TextInputClientTest
) {
1156 ui::TextInputClient
* client
= textfield_
->GetTextInputClient();
1157 EXPECT_TRUE(client
);
1158 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT
, client
->GetTextInputType());
1160 textfield_
->SetText(ASCIIToUTF16("0123456789"));
1162 EXPECT_TRUE(client
->GetTextRange(&range
));
1163 EXPECT_EQ(0U, range
.start());
1164 EXPECT_EQ(10U, range
.end());
1166 EXPECT_TRUE(client
->SetSelectionRange(gfx::Range(1, 4)));
1167 EXPECT_TRUE(client
->GetSelectionRange(&range
));
1168 EXPECT_EQ(gfx::Range(1, 4), range
);
1170 base::string16 substring
;
1171 EXPECT_TRUE(client
->GetTextFromRange(range
, &substring
));
1172 EXPECT_STR_EQ("123", substring
);
1174 EXPECT_TRUE(client
->DeleteRange(range
));
1175 EXPECT_STR_EQ("0456789", textfield_
->text());
1177 ui::CompositionText composition
;
1178 composition
.text
= UTF8ToUTF16("321");
1179 // Set composition through input method.
1180 input_method_
->Clear();
1181 input_method_
->SetCompositionTextForNextKey(composition
);
1182 textfield_
->clear();
1184 on_before_user_action_
= on_after_user_action_
= 0;
1185 SendKeyEvent(ui::VKEY_A
);
1186 EXPECT_TRUE(textfield_
->key_received());
1187 EXPECT_FALSE(textfield_
->key_handled());
1188 EXPECT_TRUE(client
->HasCompositionText());
1189 EXPECT_TRUE(client
->GetCompositionTextRange(&range
));
1190 EXPECT_STR_EQ("0321456789", textfield_
->text());
1191 EXPECT_EQ(gfx::Range(1, 4), range
);
1192 EXPECT_EQ(1, on_before_user_action_
);
1193 EXPECT_EQ(1, on_after_user_action_
);
1195 input_method_
->SetResultTextForNextKey(UTF8ToUTF16("123"));
1196 on_before_user_action_
= on_after_user_action_
= 0;
1197 textfield_
->clear();
1198 SendKeyEvent(ui::VKEY_A
);
1199 EXPECT_TRUE(textfield_
->key_received());
1200 EXPECT_FALSE(textfield_
->key_handled());
1201 EXPECT_FALSE(client
->HasCompositionText());
1202 EXPECT_FALSE(input_method_
->cancel_composition_called());
1203 EXPECT_STR_EQ("0123456789", textfield_
->text());
1204 EXPECT_EQ(1, on_before_user_action_
);
1205 EXPECT_EQ(1, on_after_user_action_
);
1207 input_method_
->Clear();
1208 input_method_
->SetCompositionTextForNextKey(composition
);
1209 textfield_
->clear();
1210 SendKeyEvent(ui::VKEY_A
);
1211 EXPECT_TRUE(client
->HasCompositionText());
1212 EXPECT_STR_EQ("0123321456789", textfield_
->text());
1214 on_before_user_action_
= on_after_user_action_
= 0;
1215 textfield_
->clear();
1216 SendKeyEvent(ui::VKEY_RIGHT
);
1217 EXPECT_FALSE(client
->HasCompositionText());
1218 EXPECT_TRUE(input_method_
->cancel_composition_called());
1219 EXPECT_TRUE(textfield_
->key_received());
1220 EXPECT_TRUE(textfield_
->key_handled());
1221 EXPECT_STR_EQ("0123321456789", textfield_
->text());
1222 EXPECT_EQ(8U, textfield_
->GetCursorPosition());
1223 EXPECT_EQ(1, on_before_user_action_
);
1224 EXPECT_EQ(1, on_after_user_action_
);
1226 textfield_
->clear();
1227 textfield_
->SetText(ASCIIToUTF16("0123456789"));
1228 EXPECT_TRUE(client
->SetSelectionRange(gfx::Range(5, 5)));
1229 client
->ExtendSelectionAndDelete(4, 2);
1230 EXPECT_STR_EQ("0789", textfield_
->text());
1232 // On{Before,After}UserAction should be called by whatever user action
1233 // triggers clearing or setting a selection if appropriate.
1234 on_before_user_action_
= on_after_user_action_
= 0;
1235 textfield_
->clear();
1236 textfield_
->ClearSelection();
1237 textfield_
->SelectAll(false);
1238 EXPECT_EQ(0, on_before_user_action_
);
1239 EXPECT_EQ(0, on_after_user_action_
);
1241 input_method_
->Clear();
1242 textfield_
->SetReadOnly(true);
1243 EXPECT_TRUE(input_method_
->text_input_type_changed());
1244 EXPECT_FALSE(textfield_
->GetTextInputClient());
1246 textfield_
->SetReadOnly(false);
1247 input_method_
->Clear();
1248 textfield_
->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD
);
1249 EXPECT_TRUE(input_method_
->text_input_type_changed());
1250 EXPECT_TRUE(textfield_
->GetTextInputClient());
1253 TEST_F(TextfieldTest
, UndoRedoTest
) {
1255 SendKeyEvent(ui::VKEY_A
);
1256 EXPECT_STR_EQ("a", textfield_
->text());
1257 SendKeyEvent(ui::VKEY_Z
, false, true);
1258 EXPECT_STR_EQ("", textfield_
->text());
1259 SendKeyEvent(ui::VKEY_Z
, false, true);
1260 EXPECT_STR_EQ("", textfield_
->text());
1261 SendKeyEvent(ui::VKEY_Y
, false, true);
1262 EXPECT_STR_EQ("a", textfield_
->text());
1263 SendKeyEvent(ui::VKEY_Y
, false, true);
1264 EXPECT_STR_EQ("a", textfield_
->text());
1267 textfield_
->AppendText(ASCIIToUTF16("b"));
1268 last_contents_
.clear(); // AppendText doesn't call ContentsChanged.
1269 EXPECT_STR_EQ("ab", textfield_
->text());
1270 SendKeyEvent(ui::VKEY_Z
, false, true);
1271 EXPECT_STR_EQ("a", textfield_
->text());
1272 SendKeyEvent(ui::VKEY_Y
, false, true);
1273 EXPECT_STR_EQ("ab", textfield_
->text());
1276 SendKeyEvent(ui::VKEY_C
);
1277 // Undo'ing append moves the cursor to the end for now.
1278 // A no-op SetText won't add a new edit; see TextfieldModel::SetText.
1279 EXPECT_STR_EQ("abc", textfield_
->text());
1280 textfield_
->SetText(ASCIIToUTF16("abc"));
1281 EXPECT_STR_EQ("abc", textfield_
->text());
1282 SendKeyEvent(ui::VKEY_Z
, false, true);
1283 EXPECT_STR_EQ("ab", textfield_
->text());
1284 SendKeyEvent(ui::VKEY_Y
, false, true);
1285 EXPECT_STR_EQ("abc", textfield_
->text());
1286 SendKeyEvent(ui::VKEY_Y
, false, true);
1287 EXPECT_STR_EQ("abc", textfield_
->text());
1288 textfield_
->SetText(ASCIIToUTF16("123"));
1289 textfield_
->SetText(ASCIIToUTF16("123"));
1290 EXPECT_STR_EQ("123", textfield_
->text());
1291 SendKeyEvent(ui::VKEY_END
, false, false);
1292 SendKeyEvent(ui::VKEY_4
, false, false);
1293 EXPECT_STR_EQ("1234", textfield_
->text());
1294 last_contents_
.clear();
1295 SendKeyEvent(ui::VKEY_Z
, false, true);
1296 EXPECT_STR_EQ("123", textfield_
->text());
1297 SendKeyEvent(ui::VKEY_Z
, false, true);
1298 // the insert edit "c" and set edit "123" are merged to single edit,
1299 // so text becomes "ab" after undo.
1300 EXPECT_STR_EQ("ab", textfield_
->text());
1301 SendKeyEvent(ui::VKEY_Z
, false, true);
1302 EXPECT_STR_EQ("a", textfield_
->text());
1303 SendKeyEvent(ui::VKEY_Y
, false, true);
1304 EXPECT_STR_EQ("ab", textfield_
->text());
1305 SendKeyEvent(ui::VKEY_Y
, false, true);
1306 EXPECT_STR_EQ("123", textfield_
->text());
1307 SendKeyEvent(ui::VKEY_Y
, false, true);
1308 EXPECT_STR_EQ("1234", textfield_
->text());
1310 // Undoing to the same text shouldn't call ContentsChanged.
1311 SendKeyEvent(ui::VKEY_A
, false, true); // select all
1312 SendKeyEvent(ui::VKEY_A
);
1313 EXPECT_STR_EQ("a", textfield_
->text());
1314 SendKeyEvent(ui::VKEY_B
);
1315 SendKeyEvent(ui::VKEY_C
);
1316 EXPECT_STR_EQ("abc", textfield_
->text());
1317 SendKeyEvent(ui::VKEY_Z
, false, true);
1318 EXPECT_STR_EQ("1234", textfield_
->text());
1319 SendKeyEvent(ui::VKEY_Y
, false, true);
1320 EXPECT_STR_EQ("abc", textfield_
->text());
1323 SendKeyEvent(ui::VKEY_BACK
);
1324 EXPECT_STR_EQ("ab", textfield_
->text());
1325 SendKeyEvent(ui::VKEY_HOME
);
1326 SendKeyEvent(ui::VKEY_DELETE
);
1327 EXPECT_STR_EQ("b", textfield_
->text());
1328 SendKeyEvent(ui::VKEY_A
, false, true);
1329 SendKeyEvent(ui::VKEY_DELETE
);
1330 EXPECT_STR_EQ("", textfield_
->text());
1331 SendKeyEvent(ui::VKEY_Z
, false, true);
1332 EXPECT_STR_EQ("b", textfield_
->text());
1333 SendKeyEvent(ui::VKEY_Z
, false, true);
1334 EXPECT_STR_EQ("ab", textfield_
->text());
1335 SendKeyEvent(ui::VKEY_Z
, false, true);
1336 EXPECT_STR_EQ("abc", textfield_
->text());
1337 SendKeyEvent(ui::VKEY_Y
, false, true);
1338 EXPECT_STR_EQ("ab", textfield_
->text());
1339 SendKeyEvent(ui::VKEY_Y
, false, true);
1340 EXPECT_STR_EQ("b", textfield_
->text());
1341 SendKeyEvent(ui::VKEY_Y
, false, true);
1342 EXPECT_STR_EQ("", textfield_
->text());
1343 SendKeyEvent(ui::VKEY_Y
, false, true);
1344 EXPECT_STR_EQ("", textfield_
->text());
1347 TEST_F(TextfieldTest
, CutCopyPaste
) {
1350 // Ensure IDS_APP_CUT cuts.
1351 textfield_
->SetText(ASCIIToUTF16("123"));
1352 textfield_
->SelectAll(false);
1353 EXPECT_TRUE(textfield_
->IsCommandIdEnabled(IDS_APP_CUT
));
1354 textfield_
->ExecuteCommand(IDS_APP_CUT
, 0);
1355 EXPECT_STR_EQ("123", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1356 EXPECT_STR_EQ("", textfield_
->text());
1357 EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE
, GetAndResetCopiedToClipboard());
1359 // Ensure [Ctrl]+[x] cuts and [Ctrl]+[Alt][x] does nothing.
1360 textfield_
->SetText(ASCIIToUTF16("456"));
1361 textfield_
->SelectAll(false);
1362 SendKeyEvent(ui::VKEY_X
, true, false, true, false);
1363 EXPECT_STR_EQ("123", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1364 EXPECT_STR_EQ("456", textfield_
->text());
1365 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST
, GetAndResetCopiedToClipboard());
1366 SendKeyEvent(ui::VKEY_X
, false, true);
1367 EXPECT_STR_EQ("456", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1368 EXPECT_STR_EQ("", textfield_
->text());
1369 EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE
, GetAndResetCopiedToClipboard());
1371 // Ensure [Shift]+[Delete] cuts.
1372 textfield_
->SetText(ASCIIToUTF16("123"));
1373 textfield_
->SelectAll(false);
1374 SendKeyEvent(ui::VKEY_DELETE
, true, false);
1375 EXPECT_STR_EQ("123", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1376 EXPECT_STR_EQ("", textfield_
->text());
1377 EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE
, GetAndResetCopiedToClipboard());
1379 // Ensure IDS_APP_COPY copies.
1380 textfield_
->SetText(ASCIIToUTF16("789"));
1381 textfield_
->SelectAll(false);
1382 EXPECT_TRUE(textfield_
->IsCommandIdEnabled(IDS_APP_COPY
));
1383 textfield_
->ExecuteCommand(IDS_APP_COPY
, 0);
1384 EXPECT_STR_EQ("789", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1385 EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE
, GetAndResetCopiedToClipboard());
1387 // Ensure [Ctrl]+[c] copies and [Ctrl]+[Alt][c] does nothing.
1388 textfield_
->SetText(ASCIIToUTF16("012"));
1389 textfield_
->SelectAll(false);
1390 SendKeyEvent(ui::VKEY_C
, true, false, true, false);
1391 EXPECT_STR_EQ("789", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1392 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST
, GetAndResetCopiedToClipboard());
1393 SendKeyEvent(ui::VKEY_C
, false, true);
1394 EXPECT_STR_EQ("012", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1395 EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE
, GetAndResetCopiedToClipboard());
1397 // Ensure [Ctrl]+[Insert] copies.
1398 textfield_
->SetText(ASCIIToUTF16("345"));
1399 textfield_
->SelectAll(false);
1400 SendKeyEvent(ui::VKEY_INSERT
, false, true);
1401 EXPECT_STR_EQ("345", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1402 EXPECT_STR_EQ("345", textfield_
->text());
1403 EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE
, GetAndResetCopiedToClipboard());
1405 // Ensure IDS_APP_PASTE, [Ctrl]+[V], and [Shift]+[Insert] pastes;
1406 // also ensure that [Ctrl]+[Alt]+[V] does nothing.
1407 SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
, "abc");
1408 textfield_
->SetText(base::string16());
1409 EXPECT_TRUE(textfield_
->IsCommandIdEnabled(IDS_APP_PASTE
));
1410 textfield_
->ExecuteCommand(IDS_APP_PASTE
, 0);
1411 EXPECT_STR_EQ("abc", textfield_
->text());
1412 SendKeyEvent(ui::VKEY_V
, false, true);
1413 EXPECT_STR_EQ("abcabc", textfield_
->text());
1414 SendKeyEvent(ui::VKEY_INSERT
, true, false);
1415 EXPECT_STR_EQ("abcabcabc", textfield_
->text());
1416 SendKeyEvent(ui::VKEY_V
, true, false, true, false);
1417 EXPECT_STR_EQ("abcabcabc", textfield_
->text());
1419 // Ensure [Ctrl]+[Shift]+[Insert] is a no-op.
1420 textfield_
->SelectAll(false);
1421 SendKeyEvent(ui::VKEY_INSERT
, true, true);
1422 EXPECT_STR_EQ("abc", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE
));
1423 EXPECT_STR_EQ("abcabcabc", textfield_
->text());
1424 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST
, GetAndResetCopiedToClipboard());
1427 TEST_F(TextfieldTest
, OvertypeMode
) {
1429 // Overtype mode should be disabled (no-op [Insert]).
1430 textfield_
->SetText(ASCIIToUTF16("2"));
1431 SendKeyEvent(ui::VKEY_HOME
);
1432 SendKeyEvent(ui::VKEY_INSERT
);
1433 SendKeyEvent(ui::VKEY_1
, false, false);
1434 EXPECT_STR_EQ("12", textfield_
->text());
1437 TEST_F(TextfieldTest
, TextCursorDisplayTest
) {
1439 // LTR-RTL string in LTR context.
1441 EXPECT_STR_EQ("a", textfield_
->text());
1442 int x
= GetCursorBounds().x();
1446 EXPECT_STR_EQ("ab", textfield_
->text());
1447 x
= GetCursorBounds().x();
1448 EXPECT_LT(prev_x
, x
);
1451 SendKeyEvent(0x05E1);
1452 EXPECT_EQ(WideToUTF16(L
"ab\x05E1"), textfield_
->text());
1453 x
= GetCursorBounds().x();
1454 EXPECT_EQ(prev_x
, x
);
1456 SendKeyEvent(0x05E2);
1457 EXPECT_EQ(WideToUTF16(L
"ab\x05E1\x5E2"), textfield_
->text());
1458 x
= GetCursorBounds().x();
1459 EXPECT_EQ(prev_x
, x
);
1462 SendKeyEvent(ui::VKEY_A
, false, true);
1465 // RTL-LTR string in LTR context.
1466 SendKeyEvent(0x05E1);
1467 EXPECT_EQ(WideToUTF16(L
"\x05E1"), textfield_
->text());
1468 x
= GetCursorBounds().x();
1469 EXPECT_EQ(GetDisplayRect().x(), x
);
1472 SendKeyEvent(0x05E2);
1473 EXPECT_EQ(WideToUTF16(L
"\x05E1\x05E2"), textfield_
->text());
1474 x
= GetCursorBounds().x();
1475 EXPECT_EQ(prev_x
, x
);
1478 EXPECT_EQ(WideToUTF16(L
"\x05E1\x5E2" L
"a"), textfield_
->text());
1479 x
= GetCursorBounds().x();
1480 EXPECT_LT(prev_x
, x
);
1484 EXPECT_EQ(WideToUTF16(L
"\x05E1\x5E2" L
"ab"), textfield_
->text());
1485 x
= GetCursorBounds().x();
1486 EXPECT_LT(prev_x
, x
);
1489 TEST_F(TextfieldTest
, TextCursorDisplayInRTLTest
) {
1490 std::string locale
= l10n_util::GetApplicationLocale("");
1491 base::i18n::SetICUDefaultLocale("he");
1494 // LTR-RTL string in RTL context.
1496 EXPECT_STR_EQ("a", textfield_
->text());
1497 int x
= GetCursorBounds().x();
1498 EXPECT_EQ(GetDisplayRect().right() - 1, x
);
1502 EXPECT_STR_EQ("ab", textfield_
->text());
1503 x
= GetCursorBounds().x();
1504 EXPECT_EQ(prev_x
, x
);
1506 SendKeyEvent(0x05E1);
1507 EXPECT_EQ(WideToUTF16(L
"ab\x05E1"), textfield_
->text());
1508 x
= GetCursorBounds().x();
1509 EXPECT_GT(prev_x
, x
);
1512 SendKeyEvent(0x05E2);
1513 EXPECT_EQ(WideToUTF16(L
"ab\x05E1\x5E2"), textfield_
->text());
1514 x
= GetCursorBounds().x();
1515 EXPECT_GT(prev_x
, x
);
1517 SendKeyEvent(ui::VKEY_A
, false, true);
1520 // RTL-LTR string in RTL context.
1521 SendKeyEvent(0x05E1);
1522 EXPECT_EQ(WideToUTF16(L
"\x05E1"), textfield_
->text());
1523 x
= GetCursorBounds().x();
1526 SendKeyEvent(0x05E2);
1527 EXPECT_EQ(WideToUTF16(L
"\x05E1\x05E2"), textfield_
->text());
1528 x
= GetCursorBounds().x();
1529 EXPECT_GT(prev_x
, x
);
1533 EXPECT_EQ(WideToUTF16(L
"\x05E1\x5E2" L
"a"), textfield_
->text());
1534 x
= GetCursorBounds().x();
1535 EXPECT_EQ(prev_x
, x
);
1539 EXPECT_EQ(WideToUTF16(L
"\x05E1\x5E2" L
"ab"), textfield_
->text());
1540 x
= GetCursorBounds().x();
1541 EXPECT_EQ(prev_x
, x
);
1544 base::i18n::SetICUDefaultLocale(locale
);
1547 TEST_F(TextfieldTest
, HitInsideTextAreaTest
) {
1549 textfield_
->SetText(WideToUTF16(L
"ab\x05E1\x5E2"));
1550 std::vector
<gfx::Rect
> cursor_bounds
;
1552 // Save each cursor bound.
1553 gfx::SelectionModel
sel(0, gfx::CURSOR_FORWARD
);
1554 cursor_bounds
.push_back(GetCursorBounds(sel
));
1556 sel
= gfx::SelectionModel(1, gfx::CURSOR_BACKWARD
);
1557 gfx::Rect bound
= GetCursorBounds(sel
);
1558 sel
= gfx::SelectionModel(1, gfx::CURSOR_FORWARD
);
1559 EXPECT_EQ(bound
.x(), GetCursorBounds(sel
).x());
1560 cursor_bounds
.push_back(bound
);
1562 // Check that a cursor at the end of the Latin portion of the text is at the
1563 // same position as a cursor placed at the end of the RTL Hebrew portion.
1564 sel
= gfx::SelectionModel(2, gfx::CURSOR_BACKWARD
);
1565 bound
= GetCursorBounds(sel
);
1566 sel
= gfx::SelectionModel(4, gfx::CURSOR_BACKWARD
);
1567 EXPECT_EQ(bound
.x(), GetCursorBounds(sel
).x());
1568 cursor_bounds
.push_back(bound
);
1570 sel
= gfx::SelectionModel(3, gfx::CURSOR_BACKWARD
);
1571 bound
= GetCursorBounds(sel
);
1572 sel
= gfx::SelectionModel(3, gfx::CURSOR_FORWARD
);
1573 EXPECT_EQ(bound
.x(), GetCursorBounds(sel
).x());
1574 cursor_bounds
.push_back(bound
);
1576 sel
= gfx::SelectionModel(2, gfx::CURSOR_FORWARD
);
1577 bound
= GetCursorBounds(sel
);
1578 sel
= gfx::SelectionModel(4, gfx::CURSOR_FORWARD
);
1579 EXPECT_EQ(bound
.x(), GetCursorBounds(sel
).x());
1580 cursor_bounds
.push_back(bound
);
1582 // Expected cursor position when clicking left and right of each character.
1583 size_t cursor_pos_expected
[] = {0, 1, 1, 2, 4, 3, 3, 2};
1586 for (int i
= 0; i
< static_cast<int>(cursor_bounds
.size() - 1); ++i
) {
1587 int half_width
= (cursor_bounds
[i
+ 1].x() - cursor_bounds
[i
].x()) / 2;
1588 MouseClick(cursor_bounds
[i
], half_width
/ 2);
1589 EXPECT_EQ(cursor_pos_expected
[index
++], textfield_
->GetCursorPosition());
1591 // To avoid trigger double click. Not using sleep() since it takes longer
1592 // for the test to run if using sleep().
1593 NonClientMouseClick();
1595 MouseClick(cursor_bounds
[i
+ 1], - (half_width
/ 2));
1596 EXPECT_EQ(cursor_pos_expected
[index
++], textfield_
->GetCursorPosition());
1598 NonClientMouseClick();
1602 TEST_F(TextfieldTest
, HitOutsideTextAreaTest
) {
1605 // LTR-RTL string in LTR context.
1606 textfield_
->SetText(WideToUTF16(L
"ab\x05E1\x5E2"));
1608 SendKeyEvent(ui::VKEY_HOME
);
1609 gfx::Rect bound
= GetCursorBounds();
1610 MouseClick(bound
, -10);
1611 EXPECT_EQ(bound
, GetCursorBounds());
1613 SendKeyEvent(ui::VKEY_END
);
1614 bound
= GetCursorBounds();
1615 MouseClick(bound
, 10);
1616 EXPECT_EQ(bound
, GetCursorBounds());
1618 NonClientMouseClick();
1620 // RTL-LTR string in LTR context.
1621 textfield_
->SetText(WideToUTF16(L
"\x05E1\x5E2" L
"ab"));
1623 SendKeyEvent(ui::VKEY_HOME
);
1624 bound
= GetCursorBounds();
1625 MouseClick(bound
, 10);
1626 EXPECT_EQ(bound
, GetCursorBounds());
1628 SendKeyEvent(ui::VKEY_END
);
1629 bound
= GetCursorBounds();
1630 MouseClick(bound
, -10);
1631 EXPECT_EQ(bound
, GetCursorBounds());
1634 TEST_F(TextfieldTest
, HitOutsideTextAreaInRTLTest
) {
1635 std::string locale
= l10n_util::GetApplicationLocale("");
1636 base::i18n::SetICUDefaultLocale("he");
1640 // RTL-LTR string in RTL context.
1641 textfield_
->SetText(WideToUTF16(L
"\x05E1\x5E2" L
"ab"));
1642 SendKeyEvent(ui::VKEY_HOME
);
1643 gfx::Rect bound
= GetCursorBounds();
1644 MouseClick(bound
, 10);
1645 EXPECT_EQ(bound
, GetCursorBounds());
1647 SendKeyEvent(ui::VKEY_END
);
1648 bound
= GetCursorBounds();
1649 MouseClick(bound
, -10);
1650 EXPECT_EQ(bound
, GetCursorBounds());
1652 NonClientMouseClick();
1654 // LTR-RTL string in RTL context.
1655 textfield_
->SetText(WideToUTF16(L
"ab\x05E1\x5E2"));
1656 SendKeyEvent(ui::VKEY_HOME
);
1657 bound
= GetCursorBounds();
1658 MouseClick(bound
, -10);
1659 EXPECT_EQ(bound
, GetCursorBounds());
1661 SendKeyEvent(ui::VKEY_END
);
1662 bound
= GetCursorBounds();
1663 MouseClick(bound
, 10);
1664 EXPECT_EQ(bound
, GetCursorBounds());
1667 base::i18n::SetICUDefaultLocale(locale
);
1670 TEST_F(TextfieldTest
, OverflowTest
) {
1674 for (int i
= 0; i
< 500; ++i
)
1676 SendKeyEvent(kHebrewLetterSamekh
);
1677 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1679 // Test mouse pointing.
1680 MouseClick(GetCursorBounds(), -1);
1681 EXPECT_EQ(500U, textfield_
->GetCursorPosition());
1684 SendKeyEvent(ui::VKEY_A
, false, true);
1687 for (int i
= 0; i
< 500; ++i
)
1688 SendKeyEvent(kHebrewLetterSamekh
);
1690 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1692 MouseClick(GetCursorBounds(), -1);
1693 EXPECT_EQ(501U, textfield_
->GetCursorPosition());
1696 TEST_F(TextfieldTest
, OverflowInRTLTest
) {
1697 std::string locale
= l10n_util::GetApplicationLocale("");
1698 base::i18n::SetICUDefaultLocale("he");
1703 for (int i
= 0; i
< 500; ++i
)
1705 SendKeyEvent(kHebrewLetterSamekh
);
1706 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1708 MouseClick(GetCursorBounds(), 1);
1709 EXPECT_EQ(501U, textfield_
->GetCursorPosition());
1712 SendKeyEvent(ui::VKEY_A
, false, true);
1715 for (int i
= 0; i
< 500; ++i
)
1716 SendKeyEvent(kHebrewLetterSamekh
);
1718 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1720 MouseClick(GetCursorBounds(), 1);
1721 EXPECT_EQ(500U, textfield_
->GetCursorPosition());
1724 base::i18n::SetICUDefaultLocale(locale
);
1727 TEST_F(TextfieldTest
, GetCompositionCharacterBoundsTest
) {
1729 ui::CompositionText composition
;
1730 composition
.text
= UTF8ToUTF16("abc123");
1731 const uint32 char_count
= static_cast<uint32
>(composition
.text
.length());
1732 ui::TextInputClient
* client
= textfield_
->GetTextInputClient();
1734 // Compare the composition character bounds with surrounding cursor bounds.
1735 for (uint32 i
= 0; i
< char_count
; ++i
) {
1736 composition
.selection
= gfx::Range(i
);
1737 client
->SetCompositionText(composition
);
1738 gfx::Point cursor_origin
= GetCursorBounds().origin();
1739 views::View::ConvertPointToScreen(textfield_
, &cursor_origin
);
1741 composition
.selection
= gfx::Range(i
+ 1);
1742 client
->SetCompositionText(composition
);
1743 gfx::Point next_cursor_bottom_left
= GetCursorBounds().bottom_left();
1744 views::View::ConvertPointToScreen(textfield_
, &next_cursor_bottom_left
);
1746 gfx::Rect character
;
1747 EXPECT_TRUE(client
->GetCompositionCharacterBounds(i
, &character
));
1748 EXPECT_EQ(character
.origin(), cursor_origin
) << " i=" << i
;
1749 EXPECT_EQ(character
.bottom_right(), next_cursor_bottom_left
) << " i=" << i
;
1752 // Return false if the index is out of range.
1754 EXPECT_FALSE(client
->GetCompositionCharacterBounds(char_count
, &rect
));
1755 EXPECT_FALSE(client
->GetCompositionCharacterBounds(char_count
+ 1, &rect
));
1756 EXPECT_FALSE(client
->GetCompositionCharacterBounds(char_count
+ 100, &rect
));
1759 TEST_F(TextfieldTest
, GetCompositionCharacterBounds_ComplexText
) {
1762 const base::char16 kUtf16Chars
[] = {
1765 // U+1F408 (CAT) as surrogate pair
1767 // U+5642 as Ideographic Variation Sequences
1768 0x5642, 0xDB40, 0xDD00,
1769 // U+260E (BLACK TELEPHONE) as Emoji Variation Sequences
1774 const size_t kUtf16CharsCount
= arraysize(kUtf16Chars
);
1776 ui::CompositionText composition
;
1777 composition
.text
.assign(kUtf16Chars
, kUtf16Chars
+ kUtf16CharsCount
);
1778 ui::TextInputClient
* client
= textfield_
->GetTextInputClient();
1779 client
->SetCompositionText(composition
);
1781 // Make sure GetCompositionCharacterBounds never fails for index.
1782 gfx::Rect rects
[kUtf16CharsCount
];
1783 gfx::Rect prev_cursor
= GetCursorBounds();
1784 for (uint32 i
= 0; i
< kUtf16CharsCount
; ++i
)
1785 EXPECT_TRUE(client
->GetCompositionCharacterBounds(i
, &rects
[i
]));
1787 // Here we might expect the following results but it actually depends on how
1788 // Uniscribe or HarfBuzz treats them with given font.
1789 // - rects[1] == rects[2]
1790 // - rects[3] == rects[4] == rects[5]
1791 // - rects[6] == rects[7]
1794 // The word we select by double clicking should remain selected regardless of
1795 // where we drag the mouse afterwards without releasing the left button.
1796 TEST_F(TextfieldTest
, KeepInitiallySelectedWord
) {
1799 textfield_
->SetText(ASCIIToUTF16("abc def ghi"));
1801 textfield_
->SelectRange(gfx::Range(5, 5));
1802 const gfx::Rect middle_cursor
= GetCursorBounds();
1803 textfield_
->SelectRange(gfx::Range(0, 0));
1804 const gfx::Point beginning
= GetCursorBounds().origin();
1806 // Double click, but do not release the left button.
1807 MouseClick(middle_cursor
, 0);
1808 const gfx::Point
middle(middle_cursor
.x(),
1809 middle_cursor
.y() + middle_cursor
.height() / 2);
1810 ui::MouseEvent
press_event(ui::ET_MOUSE_PRESSED
, middle
, middle
,
1811 ui::EF_LEFT_MOUSE_BUTTON
,
1812 ui::EF_LEFT_MOUSE_BUTTON
);
1813 textfield_
->OnMousePressed(press_event
);
1814 EXPECT_EQ(gfx::Range(4, 7), textfield_
->GetSelectedRange());
1816 // Drag the mouse to the beginning of the textfield.
1817 ui::MouseEvent
drag_event(ui::ET_MOUSE_DRAGGED
, beginning
, beginning
,
1818 ui::EF_LEFT_MOUSE_BUTTON
, 0);
1819 textfield_
->OnMouseDragged(drag_event
);
1820 EXPECT_EQ(gfx::Range(7, 0), textfield_
->GetSelectedRange());
1823 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1824 // flaky: http://crbug.com/396477
1825 TEST_F(TextfieldTest
, DISABLED_SelectionClipboard
) {
1827 textfield_
->SetText(ASCIIToUTF16("0123"));
1828 gfx::Point
point_1(GetCursorPositionX(1), 0);
1829 gfx::Point
point_2(GetCursorPositionX(2), 0);
1830 gfx::Point
point_3(GetCursorPositionX(3), 0);
1831 gfx::Point
point_4(GetCursorPositionX(4), 0);
1833 // Text selected by the mouse should be placed on the selection clipboard.
1834 ui::MouseEvent
press(ui::ET_MOUSE_PRESSED
, point_1
, point_1
,
1835 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1836 textfield_
->OnMousePressed(press
);
1837 ui::MouseEvent
drag(ui::ET_MOUSE_DRAGGED
, point_3
, point_3
,
1838 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1839 textfield_
->OnMouseDragged(drag
);
1840 ui::MouseEvent
release(ui::ET_MOUSE_RELEASED
, point_3
, point_3
,
1841 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1842 textfield_
->OnMouseReleased(release
);
1843 EXPECT_EQ(gfx::Range(1, 3), textfield_
->GetSelectedRange());
1844 EXPECT_STR_EQ("12", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1846 // Select-all should update the selection clipboard.
1847 SendKeyEvent(ui::VKEY_A
, false, true);
1848 EXPECT_EQ(gfx::Range(0, 4), textfield_
->GetSelectedRange());
1849 EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1850 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1852 // Shift-click selection modifications should update the clipboard.
1853 NonClientMouseClick();
1854 ui::MouseEvent
press_2(ui::ET_MOUSE_PRESSED
, point_2
, point_2
,
1855 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1856 press_2
.set_flags(press_2
.flags() | ui::EF_SHIFT_DOWN
);
1857 #if defined(USE_X11)
1858 ui::UpdateX11EventForFlags(&press_2
);
1860 textfield_
->OnMousePressed(press_2
);
1861 ui::MouseEvent
release_2(ui::ET_MOUSE_RELEASED
, point_2
, point_2
,
1862 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1863 textfield_
->OnMouseReleased(release_2
);
1864 EXPECT_EQ(gfx::Range(0, 2), textfield_
->GetSelectedRange());
1865 EXPECT_STR_EQ("01", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1866 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1868 // Shift-Left/Right should update the selection clipboard.
1869 SendKeyEvent(ui::VKEY_RIGHT
, true, false);
1870 EXPECT_STR_EQ("012", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1871 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1872 SendKeyEvent(ui::VKEY_LEFT
, true, false);
1873 EXPECT_STR_EQ("01", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1874 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1875 SendKeyEvent(ui::VKEY_RIGHT
, true, true);
1876 EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1877 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1879 // Moving the cursor without a selection should not change the clipboard.
1880 SendKeyEvent(ui::VKEY_LEFT
, false, false);
1881 EXPECT_EQ(gfx::Range(0, 0), textfield_
->GetSelectedRange());
1882 EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1883 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST
, GetAndResetCopiedToClipboard());
1885 // Middle clicking should paste at the mouse (not cursor) location.
1886 ui::MouseEvent
middle(ui::ET_MOUSE_PRESSED
, point_4
, point_4
,
1887 ui::EF_MIDDLE_MOUSE_BUTTON
, ui::EF_MIDDLE_MOUSE_BUTTON
);
1888 textfield_
->OnMousePressed(middle
);
1889 EXPECT_STR_EQ("01230123", textfield_
->text());
1890 EXPECT_EQ(gfx::Range(0, 0), textfield_
->GetSelectedRange());
1891 EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1893 // Middle click pasting should adjust trailing cursors.
1894 textfield_
->SelectRange(gfx::Range(5, 5));
1895 textfield_
->OnMousePressed(middle
);
1896 EXPECT_STR_EQ("012301230123", textfield_
->text());
1897 EXPECT_EQ(gfx::Range(9, 9), textfield_
->GetSelectedRange());
1899 // Middle click pasting should adjust trailing selections.
1900 textfield_
->SelectRange(gfx::Range(7, 9));
1901 textfield_
->OnMousePressed(middle
);
1902 EXPECT_STR_EQ("0123012301230123", textfield_
->text());
1903 EXPECT_EQ(gfx::Range(11, 13), textfield_
->GetSelectedRange());
1905 // Middle clicking in the selection should clear the clipboard and selection.
1906 textfield_
->SelectRange(gfx::Range(2, 6));
1907 textfield_
->OnMousePressed(middle
);
1908 EXPECT_STR_EQ("0123012301230123", textfield_
->text());
1909 EXPECT_EQ(gfx::Range(6, 6), textfield_
->GetSelectedRange());
1910 EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
).empty());
1912 // Double and triple clicking should update the clipboard contents.
1913 textfield_
->SetText(ASCIIToUTF16("ab cd ef"));
1914 gfx::Point
word(GetCursorPositionX(4), 0);
1915 ui::MouseEvent
press_word(ui::ET_MOUSE_PRESSED
, word
, word
,
1916 ui::EF_LEFT_MOUSE_BUTTON
, ui::EF_LEFT_MOUSE_BUTTON
);
1917 textfield_
->OnMousePressed(press_word
);
1918 ui::MouseEvent
release_word(ui::ET_MOUSE_RELEASED
, word
, word
,
1919 ui::EF_LEFT_MOUSE_BUTTON
,
1920 ui::EF_LEFT_MOUSE_BUTTON
);
1921 textfield_
->OnMouseReleased(release_word
);
1922 ui::MouseEvent
double_click(ui::ET_MOUSE_PRESSED
, word
, word
,
1923 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_IS_DOUBLE_CLICK
,
1924 ui::EF_LEFT_MOUSE_BUTTON
);
1925 textfield_
->OnMousePressed(double_click
);
1926 textfield_
->OnMouseReleased(release_word
);
1927 EXPECT_EQ(gfx::Range(3, 5), textfield_
->GetSelectedRange());
1928 EXPECT_STR_EQ("cd", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1929 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1930 textfield_
->OnMousePressed(press_word
);
1931 textfield_
->OnMouseReleased(release_word
);
1932 EXPECT_EQ(gfx::Range(0, 8), textfield_
->GetSelectedRange());
1933 EXPECT_STR_EQ("ab cd ef", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1934 EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION
, GetAndResetCopiedToClipboard());
1936 // Selecting a range of text without any user interaction should not change
1937 // the clipboard content.
1938 textfield_
->SelectRange(gfx::Range(0, 3));
1939 EXPECT_STR_EQ("ab ", textfield_
->GetSelectedText());
1940 EXPECT_STR_EQ("ab cd ef", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1941 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST
, GetAndResetCopiedToClipboard());
1943 SetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
, "other");
1944 textfield_
->SelectAll(false);
1945 EXPECT_STR_EQ("other", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION
));
1946 EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST
, GetAndResetCopiedToClipboard());
1950 // Touch selection and dragging currently only works for chromeos.
1951 #if defined(OS_CHROMEOS)
1952 TEST_F(TextfieldTest
, TouchSelectionAndDraggingTest
) {
1954 textfield_
->SetText(ASCIIToUTF16("hello world"));
1955 EXPECT_FALSE(test_api_
->touch_selection_controller());
1956 const int x
= GetCursorPositionX(2);
1957 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing
);
1959 // Tapping on the textfield should turn on the TouchSelectionController.
1960 ui::GestureEventDetails
tap_details(ui::ET_GESTURE_TAP
);
1961 tap_details
.set_tap_count(1);
1962 GestureEventForTest
tap(x
, 0, tap_details
);
1963 textfield_
->OnGestureEvent(&tap
);
1964 EXPECT_TRUE(test_api_
->touch_selection_controller());
1966 // Un-focusing the textfield should reset the TouchSelectionController
1967 textfield_
->GetFocusManager()->ClearFocus();
1968 EXPECT_FALSE(test_api_
->touch_selection_controller());
1969 textfield_
->RequestFocus();
1971 // With touch editing enabled, long press should not show context menu.
1972 // Instead, select word and invoke TouchSelectionController.
1973 GestureEventForTest
long_press_1(
1974 x
, 0, ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
1975 textfield_
->OnGestureEvent(&long_press_1
);
1976 EXPECT_STR_EQ("hello", textfield_
->GetSelectedText());
1977 EXPECT_TRUE(test_api_
->touch_selection_controller());
1978 EXPECT_TRUE(long_press_1
.handled());
1980 // With touch drag drop enabled, long pressing in the selected region should
1981 // start a drag and remove TouchSelectionController.
1982 ASSERT_TRUE(switches::IsTouchDragDropEnabled());
1983 GestureEventForTest
long_press_2(
1984 x
, 0, ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
1985 textfield_
->OnGestureEvent(&long_press_2
);
1986 EXPECT_STR_EQ("hello", textfield_
->GetSelectedText());
1987 EXPECT_FALSE(test_api_
->touch_selection_controller());
1988 EXPECT_FALSE(long_press_2
.handled());
1990 // After disabling touch drag drop, long pressing again in the selection
1991 // region should not do anything.
1992 CommandLine::ForCurrentProcess()->AppendSwitch(
1993 switches::kDisableTouchDragDrop
);
1994 ASSERT_FALSE(switches::IsTouchDragDropEnabled());
1995 GestureEventForTest
long_press_3(
1996 x
, 0, ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
1997 textfield_
->OnGestureEvent(&long_press_3
);
1998 EXPECT_STR_EQ("hello", textfield_
->GetSelectedText());
1999 EXPECT_FALSE(test_api_
->touch_selection_controller());
2000 EXPECT_FALSE(long_press_3
.handled());
2004 TEST_F(TextfieldTest
, TouchSelectionInUnfocusableTextfield
) {
2005 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing
);
2008 textfield_
->SetText(ASCIIToUTF16("hello world"));
2009 gfx::Point
touch_point(GetCursorPositionX(2), 0);
2011 // Disable textfield and tap on it. Touch text selection should not get
2013 textfield_
->SetEnabled(false);
2015 EXPECT_FALSE(test_api_
->touch_selection_controller());
2016 textfield_
->SetEnabled(true);
2018 // Make textfield unfocusable and tap on it. Touch text selection should not
2020 textfield_
->SetFocusable(false);
2022 EXPECT_FALSE(textfield_
->HasFocus());
2023 EXPECT_FALSE(test_api_
->touch_selection_controller());
2024 textfield_
->SetFocusable(true);
2027 // Long_Press gesture in Textfield can initiate a drag and drop now.
2028 TEST_F(TextfieldTest
, TestLongPressInitiatesDragDrop
) {
2030 textfield_
->SetText(ASCIIToUTF16("Hello string world"));
2032 // Ensure the textfield will provide selected text for drag data.
2033 textfield_
->SelectRange(gfx::Range(6, 12));
2034 const gfx::Point
kStringPoint(GetCursorPositionX(9), 0);
2036 // Enable touch-drag-drop to make long press effective.
2037 CommandLine::ForCurrentProcess()->AppendSwitch(
2038 switches::kEnableTouchDragDrop
);
2040 // Create a long press event in the selected region should start a drag.
2041 GestureEventForTest
long_press(
2044 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS
));
2045 textfield_
->OnGestureEvent(&long_press
);
2046 EXPECT_TRUE(textfield_
->CanStartDragForView(NULL
, kStringPoint
,
2050 TEST_F(TextfieldTest
, GetTextfieldBaseline_FontFallbackTest
) {
2052 textfield_
->SetText(UTF8ToUTF16("abc"));
2053 const int old_baseline
= textfield_
->GetBaseline();
2055 // Set text which may fall back to a font which has taller baseline than
2056 // the default font.
2057 textfield_
->SetText(UTF8ToUTF16("\xE0\xB9\x91"));
2058 const int new_baseline
= textfield_
->GetBaseline();
2060 // Regardless of the text, the baseline must be the same.
2061 EXPECT_EQ(new_baseline
, old_baseline
);
2064 // Tests that a textfield view can be destroyed from OnKeyEvent() on its
2065 // controller and it does not crash.
2066 TEST_F(TextfieldTest
, DestroyingTextfieldFromOnKeyEvent
) {
2069 // The controller assumes ownership of the textfield.
2070 TextfieldDestroyerController
controller(textfield_
);
2071 EXPECT_TRUE(controller
.target());
2073 // Send a key to trigger OnKeyEvent().
2076 EXPECT_FALSE(controller
.target());
2079 } // namespace views