Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / ui / views / controls / textfield / textfield_unittest.cc
blob84da7d4e37f0473ee520dd9fd47c223d63990270
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"
7 #include <set>
8 #include <string>
9 #include <vector>
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"
35 #include "url/gurl.h"
37 #if defined(OS_WIN)
38 #include "base/win/windows_version.h"
39 #endif
41 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
42 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
43 #endif
45 #if defined(USE_X11)
46 #include "ui/events/event_utils.h"
47 #endif
49 using base::ASCIIToUTF16;
50 using base::UTF8ToUTF16;
51 using base::WideToUTF16;
53 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16)
55 namespace {
57 const base::char16 kHebrewLetterSamekh = 0x05E1;
59 // A Textfield wrapper to intercept OnKey[Pressed|Released]() ressults.
60 class TestTextfield : public views::Textfield {
61 public:
62 TestTextfield()
63 : Textfield(),
64 key_handled_(false),
65 key_received_(false),
66 weak_ptr_factory_(this) {}
68 bool OnKeyPressed(const ui::KeyEvent& e) override {
69 key_received_ = true;
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);
76 if (!textfield)
77 return key;
79 key_handled_ = key;
81 return key_handled_;
84 bool OnKeyReleased(const ui::KeyEvent& e) override {
85 key_received_ = true;
86 key_handled_ = views::Textfield::OnKeyReleased(e);
87 return key_handled_;
90 bool key_handled() const { return key_handled_; }
91 bool key_received() const { return key_received_; }
93 void clear() { key_received_ = key_handled_ = false; }
95 private:
96 bool key_handled_;
97 bool key_received_;
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 {
106 public:
107 GestureEventForTest(int x, int y, ui::GestureEventDetails details)
108 : GestureEvent(x, y, 0, base::TimeDelta(), details) {}
110 private:
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 {
117 public:
118 explicit TextfieldDestroyerController(views::Textfield* target)
119 : target_(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 {
128 target_.reset();
129 return false;
132 private:
133 scoped_ptr<views::Textfield> target_;
136 base::string16 GetClipboardText(ui::ClipboardType type) {
137 base::string16 text;
138 ui::Clipboard::GetForCurrentThread()->ReadText(type, &text);
139 return text;
142 void SetClipboardText(ui::ClipboardType type, const std::string& text) {
143 ui::ScopedClipboardWriter(type).WriteText(ASCIIToUTF16(text));
146 } // namespace
148 namespace views {
150 class TextfieldTest : public ViewsTestBase, public TextfieldController {
151 public:
152 TextfieldTest()
153 : widget_(NULL),
154 textfield_(NULL),
155 model_(NULL),
156 input_method_(NULL),
157 on_before_user_action_(0),
158 on_after_user_action_(0),
159 copied_to_clipboard_(ui::CLIPBOARD_TYPE_LAST) {
162 // ::testing::Test:
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 {
172 if (widget_)
173 widget_->Close();
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() {
205 InitTextfields(1);
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.
236 widget_->Activate();
237 textfield_->RequestFocus();
240 ui::MenuModel* GetContextMenuModel() {
241 test_api_->UpdateContextMenu();
242 return test_api_->context_menu_contents();
245 protected:
246 void SendKeyEvent(ui::KeyboardCode key_code,
247 bool alt,
248 bool shift,
249 bool control,
250 bool caps_lock) {
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) {
268 if (ch < 0x80) {
269 ui::KeyboardCode code =
270 ch == ' ' ? ui::VKEY_SPACE :
271 static_cast<ui::KeyboardCode>(ui::VKEY_A + ch - 'a');
272 SendKeyEvent(code);
273 } else {
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(
337 point.x(),
338 point.y(),
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,
353 bool can_undo,
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.
367 Widget* widget_;
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_;
385 private:
386 ui::ClipboardType copied_to_clipboard_;
387 wm::DefaultScreenPositionClient screen_position_client_;
389 DISALLOW_COPY_AND_ASSIGN(TextfieldTest);
392 TEST_F(TextfieldTest, ModelChangesTest) {
393 InitTextfield();
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) {
416 InitTextfield();
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.
431 InitTextfield();
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());
440 // Test word select.
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.
466 InitTextfield();
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());
496 #else
497 EXPECT_STR_EQ("one three ", textfield_->text());
498 #endif
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());
511 #else
512 EXPECT_STR_EQ(" two four", textfield_->text());
513 #endif
516 TEST_F(TextfieldTest, PasswordTest) {
517 InitTextfield();
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) {
555 InitTextfield();
557 // Defaults to TEXT
558 EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, textfield_->GetTextInputType());
560 // And can be set.
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) {
582 InitTextfield();
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());
588 textfield_->clear();
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());
594 textfield_->clear();
596 SendKeyEvent(ui::VKEY_RIGHT);
597 EXPECT_TRUE(textfield_->key_received());
598 EXPECT_TRUE(textfield_->key_handled());
599 textfield_->clear();
601 SendKeyEvent(ui::VKEY_HOME);
602 EXPECT_TRUE(textfield_->key_received());
603 EXPECT_TRUE(textfield_->key_handled());
604 textfield_->clear();
606 SendKeyEvent(ui::VKEY_END);
607 EXPECT_TRUE(textfield_->key_received());
608 EXPECT_TRUE(textfield_->key_handled());
609 textfield_->clear();
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());
615 textfield_->clear();
617 SendKeyEvent(ui::VKEY_UP);
618 EXPECT_TRUE(textfield_->key_received());
619 EXPECT_FALSE(textfield_->key_handled());
620 textfield_->clear();
622 SendKeyEvent(ui::VKEY_DOWN);
623 EXPECT_TRUE(textfield_->key_received());
624 EXPECT_FALSE(textfield_->key_handled());
625 textfield_->clear();
628 // Tests that default key bindings are handled even with a delegate installed.
629 TEST_F(TextfieldTest, OnKeyPressBinding) {
630 InitTextfield();
632 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
633 // Install a TextEditKeyBindingsDelegateAuraLinux that does nothing.
634 class TestDelegate : public ui::TextEditKeyBindingsDelegateAuraLinux {
635 public:
636 TestDelegate() {}
637 ~TestDelegate() override {}
639 bool MatchEvent(
640 const ui::Event& event,
641 std::vector<ui::TextEditCommandAuraLinux>* commands) override {
642 return false;
645 private:
646 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
649 TestDelegate delegate;
650 ui::SetTextEditKeyBindingsDelegate(&delegate);
651 #endif
653 SendKeyEvent(ui::VKEY_A, false, false);
654 EXPECT_STR_EQ("a", textfield_->text());
655 textfield_->clear();
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());
662 textfield_->clear();
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());
668 textfield_->clear();
670 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
671 ui::SetTextEditKeyBindingsDelegate(NULL);
672 #endif
675 TEST_F(TextfieldTest, CursorMovement) {
676 InitTextfield();
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
709 // first word.
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) {
726 InitTextfields(3);
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) {
762 InitTextfield();
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) {
785 InitTextfield();
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) {
816 InitTextfield();
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());
852 #if defined(OS_WIN)
853 TEST_F(TextfieldTest, DragAndDrop_AcceptDrop) {
854 InitTextfield();
855 textfield_->SetText(ASCIIToUTF16("hello world"));
857 ui::OSExchangeData data;
858 base::string16 string(ASCIIToUTF16("string "));
859 data.SetString(string);
860 int formats = 0;
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));
903 #endif
905 TEST_F(TextfieldTest, DragAndDrop_InitiateDrag) {
906 InitTextfield();
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(),
942 gfx::Point()));
943 EXPECT_EQ(ui::DragDropTypes::DRAG_COPY,
944 textfield_->GetDragOperationsForView(NULL, kStringPoint));
945 EXPECT_TRUE(textfield_->CanStartDragForView(NULL, kStringPoint,
946 gfx::Point()));
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) {
953 InitTextfield();
954 textfield_->SetText(ASCIIToUTF16("hello world"));
956 base::string16 string;
957 ui::OSExchangeData data;
958 int formats = 0;
959 int operations = 0;
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(),
969 gfx::Point()));
970 operations = textfield_->GetDragOperationsForView(textfield_,
971 click_a.location());
972 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
973 operations);
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) {
1006 InitTextfield();
1007 textfield_->SetText(ASCIIToUTF16("hello world"));
1009 base::string16 string;
1010 ui::OSExchangeData data;
1011 int formats = 0;
1012 int operations = 0;
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(),
1022 gfx::Point()));
1023 operations = textfield_->GetDragOperationsForView(textfield_,
1024 click_a.location());
1025 EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
1026 operations);
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) {
1059 InitTextfield();
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) {
1089 InitTextfield();
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) {
1155 InitTextfield();
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"));
1161 gfx::Range range;
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) {
1254 InitTextfield();
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());
1266 // AppendText
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());
1275 // SetText
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());
1322 // Delete/Backspace
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) {
1348 InitTextfield();
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) {
1428 InitTextfield();
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) {
1438 InitTextfield();
1439 // LTR-RTL string in LTR context.
1440 SendKeyEvent('a');
1441 EXPECT_STR_EQ("a", textfield_->text());
1442 int x = GetCursorBounds().x();
1443 int prev_x = x;
1445 SendKeyEvent('b');
1446 EXPECT_STR_EQ("ab", textfield_->text());
1447 x = GetCursorBounds().x();
1448 EXPECT_LT(prev_x, x);
1449 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);
1461 // Clear text.
1462 SendKeyEvent(ui::VKEY_A, false, true);
1463 SendKeyEvent('\n');
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);
1470 prev_x = x;
1472 SendKeyEvent(0x05E2);
1473 EXPECT_EQ(WideToUTF16(L"\x05E1\x05E2"), textfield_->text());
1474 x = GetCursorBounds().x();
1475 EXPECT_EQ(prev_x, x);
1477 SendKeyEvent('a');
1478 EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"a"), textfield_->text());
1479 x = GetCursorBounds().x();
1480 EXPECT_LT(prev_x, x);
1481 prev_x = x;
1483 SendKeyEvent('b');
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");
1493 InitTextfield();
1494 // LTR-RTL string in RTL context.
1495 SendKeyEvent('a');
1496 EXPECT_STR_EQ("a", textfield_->text());
1497 int x = GetCursorBounds().x();
1498 EXPECT_EQ(GetDisplayRect().right() - 1, x);
1499 int prev_x = x;
1501 SendKeyEvent('b');
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);
1510 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);
1518 SendKeyEvent('\n');
1520 // RTL-LTR string in RTL context.
1521 SendKeyEvent(0x05E1);
1522 EXPECT_EQ(WideToUTF16(L"\x05E1"), textfield_->text());
1523 x = GetCursorBounds().x();
1524 prev_x = x;
1526 SendKeyEvent(0x05E2);
1527 EXPECT_EQ(WideToUTF16(L"\x05E1\x05E2"), textfield_->text());
1528 x = GetCursorBounds().x();
1529 EXPECT_GT(prev_x, x);
1530 prev_x = x;
1532 SendKeyEvent('a');
1533 EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"a"), textfield_->text());
1534 x = GetCursorBounds().x();
1535 EXPECT_EQ(prev_x, x);
1536 prev_x = x;
1538 SendKeyEvent('b');
1539 EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"ab"), textfield_->text());
1540 x = GetCursorBounds().x();
1541 EXPECT_EQ(prev_x, x);
1543 // Reset locale.
1544 base::i18n::SetICUDefaultLocale(locale);
1547 TEST_F(TextfieldTest, HitInsideTextAreaTest) {
1548 InitTextfield();
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};
1585 int index = 0;
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) {
1603 InitTextfield();
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");
1638 InitTextfield();
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());
1666 // Reset locale.
1667 base::i18n::SetICUDefaultLocale(locale);
1670 TEST_F(TextfieldTest, OverflowTest) {
1671 InitTextfield();
1673 base::string16 str;
1674 for (int i = 0; i < 500; ++i)
1675 SendKeyEvent('a');
1676 SendKeyEvent(kHebrewLetterSamekh);
1677 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1679 // Test mouse pointing.
1680 MouseClick(GetCursorBounds(), -1);
1681 EXPECT_EQ(500U, textfield_->GetCursorPosition());
1683 // Clear text.
1684 SendKeyEvent(ui::VKEY_A, false, true);
1685 SendKeyEvent('\n');
1687 for (int i = 0; i < 500; ++i)
1688 SendKeyEvent(kHebrewLetterSamekh);
1689 SendKeyEvent('a');
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");
1700 InitTextfield();
1702 base::string16 str;
1703 for (int i = 0; i < 500; ++i)
1704 SendKeyEvent('a');
1705 SendKeyEvent(kHebrewLetterSamekh);
1706 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1708 MouseClick(GetCursorBounds(), 1);
1709 EXPECT_EQ(501U, textfield_->GetCursorPosition());
1711 // Clear text.
1712 SendKeyEvent(ui::VKEY_A, false, true);
1713 SendKeyEvent('\n');
1715 for (int i = 0; i < 500; ++i)
1716 SendKeyEvent(kHebrewLetterSamekh);
1717 SendKeyEvent('a');
1718 EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1720 MouseClick(GetCursorBounds(), 1);
1721 EXPECT_EQ(500U, textfield_->GetCursorPosition());
1723 // Reset locale.
1724 base::i18n::SetICUDefaultLocale(locale);
1727 TEST_F(TextfieldTest, GetCompositionCharacterBoundsTest) {
1728 InitTextfield();
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.
1753 gfx::Rect rect;
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) {
1760 InitTextfield();
1762 const base::char16 kUtf16Chars[] = {
1763 // U+0020 SPACE
1764 0x0020,
1765 // U+1F408 (CAT) as surrogate pair
1766 0xd83d, 0xdc08,
1767 // U+5642 as Ideographic Variation Sequences
1768 0x5642, 0xDB40, 0xDD00,
1769 // U+260E (BLACK TELEPHONE) as Emoji Variation Sequences
1770 0x260E, 0xFE0F,
1771 // U+0020 SPACE
1772 0x0020,
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) {
1797 InitTextfield();
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) {
1826 InitTextfield();
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);
1859 #endif
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());
1948 #endif
1950 // Touch selection and dragging currently only works for chromeos.
1951 #if defined(OS_CHROMEOS)
1952 TEST_F(TextfieldTest, TouchSelectionAndDraggingTest) {
1953 InitTextfield();
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());
2002 #endif
2004 TEST_F(TextfieldTest, TouchSelectionInUnfocusableTextfield) {
2005 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing);
2007 InitTextfield();
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
2012 // activated.
2013 textfield_->SetEnabled(false);
2014 Tap(touch_point);
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
2019 // get activated.
2020 textfield_->SetFocusable(false);
2021 Tap(touch_point);
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) {
2029 InitTextfield();
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(
2042 kStringPoint.x(),
2043 kStringPoint.y(),
2044 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
2045 textfield_->OnGestureEvent(&long_press);
2046 EXPECT_TRUE(textfield_->CanStartDragForView(NULL, kStringPoint,
2047 kStringPoint));
2050 TEST_F(TextfieldTest, GetTextfieldBaseline_FontFallbackTest) {
2051 InitTextfield();
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) {
2067 InitTextfield();
2069 // The controller assumes ownership of the textfield.
2070 TextfieldDestroyerController controller(textfield_);
2071 EXPECT_TRUE(controller.target());
2073 // Send a key to trigger OnKeyEvent().
2074 SendKeyEvent('X');
2076 EXPECT_FALSE(controller.target());
2079 } // namespace views