• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/views/controls/textfield/textfield.h"
6 
7 #include <set>
8 #include <string>
9 #include <vector>
10 
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 "url/gurl.h"
35 
36 #if defined(OS_WIN)
37 #include "base/win/windows_version.h"
38 #endif
39 
40 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
41 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h"
42 #endif
43 
44 #if defined(USE_X11)
45 #include "ui/events/event_utils.h"
46 #endif
47 
48 using base::ASCIIToUTF16;
49 using base::UTF8ToUTF16;
50 using base::WideToUTF16;
51 
52 #define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16)
53 
54 namespace {
55 
56 const base::char16 kHebrewLetterSamekh = 0x05E1;
57 
58 // A Textfield wrapper to intercept OnKey[Pressed|Released]() ressults.
59 class TestTextfield : public views::Textfield {
60  public:
TestTextfield()61   TestTextfield()
62      : Textfield(),
63        key_handled_(false),
64        key_received_(false),
65        weak_ptr_factory_(this) {}
66 
OnKeyPressed(const ui::KeyEvent & e)67   virtual bool OnKeyPressed(const ui::KeyEvent& e) OVERRIDE {
68     key_received_ = true;
69 
70     // Since OnKeyPressed() might destroy |this|, get a weak pointer and
71     // verify it isn't null before writing the bool value to key_handled_.
72     base::WeakPtr<TestTextfield> textfield(weak_ptr_factory_.GetWeakPtr());
73     bool key = views::Textfield::OnKeyPressed(e);
74 
75     if (!textfield)
76       return key;
77 
78     key_handled_ = key;
79 
80     return key_handled_;
81   }
82 
OnKeyReleased(const ui::KeyEvent & e)83   virtual bool OnKeyReleased(const ui::KeyEvent& e) OVERRIDE {
84     key_received_ = true;
85     key_handled_ = views::Textfield::OnKeyReleased(e);
86     return key_handled_;
87   }
88 
key_handled() const89   bool key_handled() const { return key_handled_; }
key_received() const90   bool key_received() const { return key_received_; }
91 
clear()92   void clear() { key_received_ = key_handled_ = false; }
93 
94  private:
95   bool key_handled_;
96   bool key_received_;
97 
98   base::WeakPtrFactory<TestTextfield> weak_ptr_factory_;
99 
100   DISALLOW_COPY_AND_ASSIGN(TestTextfield);
101 };
102 
103 // Convenience to make constructing a GestureEvent simpler.
104 class GestureEventForTest : public ui::GestureEvent {
105  public:
GestureEventForTest(int x,int y,ui::GestureEventDetails details)106   GestureEventForTest(int x, int y, ui::GestureEventDetails details)
107       : GestureEvent(x, y, 0, base::TimeDelta(), details) {}
108 
109  private:
110   DISALLOW_COPY_AND_ASSIGN(GestureEventForTest);
111 };
112 
113 // This controller will happily destroy the target textfield passed on
114 // construction when a key event is triggered.
115 class TextfieldDestroyerController : public views::TextfieldController {
116  public:
TextfieldDestroyerController(views::Textfield * target)117   explicit TextfieldDestroyerController(views::Textfield* target)
118       : target_(target) {
119     target_->set_controller(this);
120   }
121 
target()122   views::Textfield* target() { return target_.get(); }
123 
124   // views::TextfieldController:
HandleKeyEvent(views::Textfield * sender,const ui::KeyEvent & key_event)125   virtual bool HandleKeyEvent(views::Textfield* sender,
126                               const ui::KeyEvent& key_event) OVERRIDE {
127     target_.reset();
128     return false;
129   }
130 
131  private:
132   scoped_ptr<views::Textfield> target_;
133 };
134 
GetClipboardText(ui::ClipboardType type)135 base::string16 GetClipboardText(ui::ClipboardType type) {
136   base::string16 text;
137   ui::Clipboard::GetForCurrentThread()->ReadText(type, &text);
138   return text;
139 }
140 
SetClipboardText(ui::ClipboardType type,const std::string & text)141 void SetClipboardText(ui::ClipboardType type, const std::string& text) {
142   ui::ScopedClipboardWriter(type).WriteText(ASCIIToUTF16(text));
143 }
144 
145 }  // namespace
146 
147 namespace views {
148 
149 class TextfieldTest : public ViewsTestBase, public TextfieldController {
150  public:
TextfieldTest()151   TextfieldTest()
152       : widget_(NULL),
153         textfield_(NULL),
154         model_(NULL),
155         input_method_(NULL),
156         on_before_user_action_(0),
157         on_after_user_action_(0),
158         copied_to_clipboard_(ui::CLIPBOARD_TYPE_LAST) {
159   }
160 
161   // ::testing::Test:
SetUp()162   virtual void SetUp() {
163     ViewsTestBase::SetUp();
164   }
165 
TearDown()166   virtual void TearDown() {
167     if (widget_)
168       widget_->Close();
169     ViewsTestBase::TearDown();
170   }
171 
GetAndResetCopiedToClipboard()172   ui::ClipboardType GetAndResetCopiedToClipboard() {
173     ui::ClipboardType clipboard_type = copied_to_clipboard_;
174     copied_to_clipboard_ = ui::CLIPBOARD_TYPE_LAST;
175     return clipboard_type;
176   }
177 
178   // TextfieldController:
ContentsChanged(Textfield * sender,const base::string16 & new_contents)179   virtual void ContentsChanged(Textfield* sender,
180                                const base::string16& new_contents) OVERRIDE {
181     // Paste calls TextfieldController::ContentsChanged() explicitly even if the
182     // paste action did not change the content. So |new_contents| may match
183     // |last_contents_|. For more info, see http://crbug.com/79002
184     last_contents_ = new_contents;
185   }
186 
OnBeforeUserAction(Textfield * sender)187   virtual void OnBeforeUserAction(Textfield* sender) OVERRIDE {
188     ++on_before_user_action_;
189   }
190 
OnAfterUserAction(Textfield * sender)191   virtual void OnAfterUserAction(Textfield* sender) OVERRIDE {
192     ++on_after_user_action_;
193   }
194 
OnAfterCutOrCopy(ui::ClipboardType clipboard_type)195   virtual void OnAfterCutOrCopy(ui::ClipboardType clipboard_type) OVERRIDE {
196     copied_to_clipboard_ = clipboard_type;
197   }
198 
InitTextfield()199   void InitTextfield() {
200     InitTextfields(1);
201   }
202 
InitTextfields(int count)203   void InitTextfields(int count) {
204     ASSERT_FALSE(textfield_);
205     textfield_ = new TestTextfield();
206     textfield_->set_controller(this);
207     widget_ = new Widget();
208     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
209     params.bounds = gfx::Rect(100, 100, 100, 100);
210     widget_->Init(params);
211     View* container = new View();
212     widget_->SetContentsView(container);
213     container->AddChildView(textfield_);
214     textfield_->SetBoundsRect(params.bounds);
215     textfield_->set_id(1);
216     test_api_.reset(new TextfieldTestApi(textfield_));
217 
218     for (int i = 1; i < count; i++) {
219       Textfield* textfield = new Textfield();
220       container->AddChildView(textfield);
221       textfield->set_id(i + 1);
222     }
223 
224     model_ = test_api_->model();
225     model_->ClearEditHistory();
226 
227     input_method_ = new MockInputMethod();
228     widget_->ReplaceInputMethod(input_method_);
229 
230     // Activate the widget and focus the textfield for input handling.
231     widget_->Activate();
232     textfield_->RequestFocus();
233   }
234 
GetContextMenuModel()235   ui::MenuModel* GetContextMenuModel() {
236     test_api_->UpdateContextMenu();
237     return test_api_->context_menu_contents();
238   }
239 
240  protected:
SendKeyEvent(ui::KeyboardCode key_code,bool alt,bool shift,bool control,bool caps_lock)241   void SendKeyEvent(ui::KeyboardCode key_code,
242                     bool alt,
243                     bool shift,
244                     bool control,
245                     bool caps_lock) {
246     int flags = (alt ? ui::EF_ALT_DOWN : 0) |
247                 (shift ? ui::EF_SHIFT_DOWN : 0) |
248                 (control ? ui::EF_CONTROL_DOWN : 0) |
249                 (caps_lock ? ui::EF_CAPS_LOCK_DOWN : 0);
250     ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, flags);
251     input_method_->DispatchKeyEvent(event);
252   }
253 
SendKeyEvent(ui::KeyboardCode key_code,bool shift,bool control)254   void SendKeyEvent(ui::KeyboardCode key_code, bool shift, bool control) {
255     SendKeyEvent(key_code, false, shift, control, false);
256   }
257 
SendKeyEvent(ui::KeyboardCode key_code)258   void SendKeyEvent(ui::KeyboardCode key_code) {
259     SendKeyEvent(key_code, false, false);
260   }
261 
SendKeyEvent(base::char16 ch)262   void SendKeyEvent(base::char16 ch) {
263     if (ch < 0x80) {
264       ui::KeyboardCode code =
265           ch == ' ' ? ui::VKEY_SPACE :
266           static_cast<ui::KeyboardCode>(ui::VKEY_A + ch - 'a');
267       SendKeyEvent(code);
268     } else {
269       ui::KeyEvent event(ch, ui::VKEY_UNKNOWN, ui::EF_NONE);
270       input_method_->DispatchKeyEvent(event);
271     }
272   }
273 
GetFocusedView()274   View* GetFocusedView() {
275     return widget_->GetFocusManager()->GetFocusedView();
276   }
277 
GetCursorPositionX(int cursor_pos)278   int GetCursorPositionX(int cursor_pos) {
279     return test_api_->GetRenderText()->GetCursorBounds(
280         gfx::SelectionModel(cursor_pos, gfx::CURSOR_FORWARD), false).x();
281   }
282 
283   // Get the current cursor bounds.
GetCursorBounds()284   gfx::Rect GetCursorBounds() {
285     return test_api_->GetRenderText()->GetUpdatedCursorBounds();
286   }
287 
288   // Get the cursor bounds of |sel|.
GetCursorBounds(const gfx::SelectionModel & sel)289   gfx::Rect GetCursorBounds(const gfx::SelectionModel& sel) {
290     return test_api_->GetRenderText()->GetCursorBounds(sel, true);
291   }
292 
GetDisplayRect()293   gfx::Rect GetDisplayRect() {
294     return test_api_->GetRenderText()->display_rect();
295   }
296 
297   // Mouse click on the point whose x-axis is |bound|'s x plus |x_offset| and
298   // y-axis is in the middle of |bound|'s vertical range.
MouseClick(const gfx::Rect bound,int x_offset)299   void MouseClick(const gfx::Rect bound, int x_offset) {
300     gfx::Point point(bound.x() + x_offset, bound.y() + bound.height() / 2);
301     ui::MouseEvent click(ui::ET_MOUSE_PRESSED, point, point,
302                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
303     textfield_->OnMousePressed(click);
304     ui::MouseEvent release(ui::ET_MOUSE_RELEASED, point, point,
305                            ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
306     textfield_->OnMouseReleased(release);
307   }
308 
309   // This is to avoid double/triple click.
NonClientMouseClick()310   void NonClientMouseClick() {
311     ui::MouseEvent click(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
312                          ui::EF_LEFT_MOUSE_BUTTON | ui::EF_IS_NON_CLIENT,
313                          ui::EF_LEFT_MOUSE_BUTTON);
314     textfield_->OnMousePressed(click);
315     ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
316                            ui::EF_LEFT_MOUSE_BUTTON | ui::EF_IS_NON_CLIENT,
317                            ui::EF_LEFT_MOUSE_BUTTON);
318     textfield_->OnMouseReleased(release);
319   }
320 
321   // Simulates a complete tap.
Tap(const gfx::Point & point)322   void Tap(const gfx::Point& point) {
323     GestureEventForTest begin(
324         point.x(), point.y(), ui::GestureEventDetails(ui::ET_GESTURE_BEGIN));
325     textfield_->OnGestureEvent(&begin);
326 
327     GestureEventForTest tap_down(
328         point.x(), point.y(), ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN));
329     textfield_->OnGestureEvent(&tap_down);
330 
331     GestureEventForTest show_press(
332         point.x(),
333         point.y(),
334         ui::GestureEventDetails(ui::ET_GESTURE_SHOW_PRESS));
335     textfield_->OnGestureEvent(&show_press);
336 
337     ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
338     tap_details.set_tap_count(1);
339     GestureEventForTest tap(point.x(), point.y(), tap_details);
340     textfield_->OnGestureEvent(&tap);
341 
342     GestureEventForTest end(
343         point.x(), point.y(), ui::GestureEventDetails(ui::ET_GESTURE_END));
344     textfield_->OnGestureEvent(&end);
345   }
346 
VerifyTextfieldContextMenuContents(bool textfield_has_selection,bool can_undo,ui::MenuModel * menu)347   void VerifyTextfieldContextMenuContents(bool textfield_has_selection,
348                                           bool can_undo,
349                                           ui::MenuModel* menu) {
350     EXPECT_EQ(can_undo, menu->IsEnabledAt(0 /* UNDO */));
351     EXPECT_TRUE(menu->IsEnabledAt(1 /* Separator */));
352     EXPECT_EQ(textfield_has_selection, menu->IsEnabledAt(2 /* CUT */));
353     EXPECT_EQ(textfield_has_selection, menu->IsEnabledAt(3 /* COPY */));
354     EXPECT_NE(GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE).empty(),
355               menu->IsEnabledAt(4 /* PASTE */));
356     EXPECT_EQ(textfield_has_selection, menu->IsEnabledAt(5 /* DELETE */));
357     EXPECT_TRUE(menu->IsEnabledAt(6 /* Separator */));
358     EXPECT_TRUE(menu->IsEnabledAt(7 /* SELECT ALL */));
359   }
360 
361   // We need widget to populate wrapper class.
362   Widget* widget_;
363 
364   TestTextfield* textfield_;
365   scoped_ptr<TextfieldTestApi> test_api_;
366   TextfieldModel* model_;
367 
368   // The string from Controller::ContentsChanged callback.
369   base::string16 last_contents_;
370 
371   // For testing input method related behaviors.
372   MockInputMethod* input_method_;
373 
374   // Indicates how many times OnBeforeUserAction() is called.
375   int on_before_user_action_;
376 
377   // Indicates how many times OnAfterUserAction() is called.
378   int on_after_user_action_;
379 
380  private:
381   ui::ClipboardType copied_to_clipboard_;
382 
383   DISALLOW_COPY_AND_ASSIGN(TextfieldTest);
384 };
385 
TEST_F(TextfieldTest,ModelChangesTest)386 TEST_F(TextfieldTest, ModelChangesTest) {
387   InitTextfield();
388 
389   // TextfieldController::ContentsChanged() shouldn't be called when changing
390   // text programmatically.
391   last_contents_.clear();
392   textfield_->SetText(ASCIIToUTF16("this is"));
393 
394   EXPECT_STR_EQ("this is", model_->text());
395   EXPECT_STR_EQ("this is", textfield_->text());
396   EXPECT_TRUE(last_contents_.empty());
397 
398   textfield_->AppendText(ASCIIToUTF16(" a test"));
399   EXPECT_STR_EQ("this is a test", model_->text());
400   EXPECT_STR_EQ("this is a test", textfield_->text());
401   EXPECT_TRUE(last_contents_.empty());
402 
403   EXPECT_EQ(base::string16(), textfield_->GetSelectedText());
404   textfield_->SelectAll(false);
405   EXPECT_STR_EQ("this is a test", textfield_->GetSelectedText());
406   EXPECT_TRUE(last_contents_.empty());
407 }
408 
TEST_F(TextfieldTest,KeyTest)409 TEST_F(TextfieldTest, KeyTest) {
410   InitTextfield();
411   // Event flags:  key,    alt,   shift, ctrl,  caps-lock.
412   SendKeyEvent(ui::VKEY_T, false, true,  false, false);
413   SendKeyEvent(ui::VKEY_E, false, false, false, false);
414   SendKeyEvent(ui::VKEY_X, false, true,  false, true);
415   SendKeyEvent(ui::VKEY_T, false, false, false, true);
416   SendKeyEvent(ui::VKEY_1, false, true,  false, false);
417   SendKeyEvent(ui::VKEY_1, false, false, false, false);
418   SendKeyEvent(ui::VKEY_1, false, true,  false, true);
419   SendKeyEvent(ui::VKEY_1, false, false, false, true);
420   EXPECT_STR_EQ("TexT!1!1", textfield_->text());
421 }
422 
TEST_F(TextfieldTest,ControlAndSelectTest)423 TEST_F(TextfieldTest, ControlAndSelectTest) {
424   // Insert a test string in a textfield.
425   InitTextfield();
426   textfield_->SetText(ASCIIToUTF16("one two three"));
427   SendKeyEvent(ui::VKEY_HOME,  false /* shift */, false /* control */);
428   SendKeyEvent(ui::VKEY_RIGHT, true, false);
429   SendKeyEvent(ui::VKEY_RIGHT, true, false);
430   SendKeyEvent(ui::VKEY_RIGHT, true, false);
431 
432   EXPECT_STR_EQ("one", textfield_->GetSelectedText());
433 
434   // Test word select.
435   SendKeyEvent(ui::VKEY_RIGHT, true, true);
436   EXPECT_STR_EQ("one two", textfield_->GetSelectedText());
437   SendKeyEvent(ui::VKEY_RIGHT, true, true);
438   EXPECT_STR_EQ("one two three", textfield_->GetSelectedText());
439   SendKeyEvent(ui::VKEY_LEFT, true, true);
440   EXPECT_STR_EQ("one two ", textfield_->GetSelectedText());
441   SendKeyEvent(ui::VKEY_LEFT, true, true);
442   EXPECT_STR_EQ("one ", textfield_->GetSelectedText());
443 
444   // Replace the selected text.
445   SendKeyEvent(ui::VKEY_Z, true, false);
446   SendKeyEvent(ui::VKEY_E, true, false);
447   SendKeyEvent(ui::VKEY_R, true, false);
448   SendKeyEvent(ui::VKEY_O, true, false);
449   SendKeyEvent(ui::VKEY_SPACE, false, false);
450   EXPECT_STR_EQ("ZERO two three", textfield_->text());
451 
452   SendKeyEvent(ui::VKEY_END, true, false);
453   EXPECT_STR_EQ("two three", textfield_->GetSelectedText());
454   SendKeyEvent(ui::VKEY_HOME, true, false);
455   EXPECT_STR_EQ("ZERO ", textfield_->GetSelectedText());
456 }
457 
TEST_F(TextfieldTest,InsertionDeletionTest)458 TEST_F(TextfieldTest, InsertionDeletionTest) {
459   // Insert a test string in a textfield.
460   InitTextfield();
461   for (size_t i = 0; i < 10; i++)
462     SendKeyEvent(static_cast<ui::KeyboardCode>(ui::VKEY_A + i));
463   EXPECT_STR_EQ("abcdefghij", textfield_->text());
464 
465   // Test the delete and backspace keys.
466   textfield_->SelectRange(gfx::Range(5));
467   for (int i = 0; i < 3; i++)
468     SendKeyEvent(ui::VKEY_BACK);
469   EXPECT_STR_EQ("abfghij", textfield_->text());
470   for (int i = 0; i < 3; i++)
471     SendKeyEvent(ui::VKEY_DELETE);
472   EXPECT_STR_EQ("abij", textfield_->text());
473 
474   // Select all and replace with "k".
475   textfield_->SelectAll(false);
476   SendKeyEvent(ui::VKEY_K);
477   EXPECT_STR_EQ("k", textfield_->text());
478 
479   // Delete the previous word from cursor.
480   textfield_->SetText(ASCIIToUTF16("one two three four"));
481   SendKeyEvent(ui::VKEY_END);
482   SendKeyEvent(ui::VKEY_BACK, false, false, true, false);
483   EXPECT_STR_EQ("one two three ", textfield_->text());
484 
485   // Delete to a line break on Linux and ChromeOS, to a word break on Windows.
486   SendKeyEvent(ui::VKEY_LEFT, false, false, true, false);
487   SendKeyEvent(ui::VKEY_BACK, false, true, true, false);
488 #if defined(OS_LINUX)
489   EXPECT_STR_EQ("three ", textfield_->text());
490 #else
491   EXPECT_STR_EQ("one three ", textfield_->text());
492 #endif
493 
494   // Delete the next word from cursor.
495   textfield_->SetText(ASCIIToUTF16("one two three four"));
496   SendKeyEvent(ui::VKEY_HOME);
497   SendKeyEvent(ui::VKEY_DELETE, false, false, true, false);
498   EXPECT_STR_EQ(" two three four", textfield_->text());
499 
500   // Delete to a line break on Linux and ChromeOS, to a word break on Windows.
501   SendKeyEvent(ui::VKEY_RIGHT, false, false, true, false);
502   SendKeyEvent(ui::VKEY_DELETE, false, true, true, false);
503 #if defined(OS_LINUX)
504   EXPECT_STR_EQ(" two", textfield_->text());
505 #else
506   EXPECT_STR_EQ(" two four", textfield_->text());
507 #endif
508 }
509 
TEST_F(TextfieldTest,PasswordTest)510 TEST_F(TextfieldTest, PasswordTest) {
511   InitTextfield();
512   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
513   EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, textfield_->GetTextInputType());
514   EXPECT_TRUE(textfield_->enabled());
515   EXPECT_TRUE(textfield_->IsFocusable());
516 
517   last_contents_.clear();
518   textfield_->SetText(ASCIIToUTF16("password"));
519   // Ensure text() and the callback returns the actual text instead of "*".
520   EXPECT_STR_EQ("password", textfield_->text());
521   EXPECT_TRUE(last_contents_.empty());
522   model_->SelectAll(false);
523   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "foo");
524 
525   // Cut and copy should be disabled.
526   EXPECT_FALSE(textfield_->IsCommandIdEnabled(IDS_APP_CUT));
527   textfield_->ExecuteCommand(IDS_APP_CUT, 0);
528   SendKeyEvent(ui::VKEY_X, false, true);
529   EXPECT_FALSE(textfield_->IsCommandIdEnabled(IDS_APP_COPY));
530   textfield_->ExecuteCommand(IDS_APP_COPY, 0);
531   SendKeyEvent(ui::VKEY_C, false, true);
532   SendKeyEvent(ui::VKEY_INSERT, false, true);
533   EXPECT_STR_EQ("foo", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
534   EXPECT_STR_EQ("password", textfield_->text());
535   // [Shift]+[Delete] should just delete without copying text to the clipboard.
536   textfield_->SelectAll(false);
537   SendKeyEvent(ui::VKEY_DELETE, true, false);
538 
539   // Paste should work normally.
540   EXPECT_TRUE(textfield_->IsCommandIdEnabled(IDS_APP_PASTE));
541   textfield_->ExecuteCommand(IDS_APP_PASTE, 0);
542   SendKeyEvent(ui::VKEY_V, false, true);
543   SendKeyEvent(ui::VKEY_INSERT, true, false);
544   EXPECT_STR_EQ("foo", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
545   EXPECT_STR_EQ("foofoofoo", textfield_->text());
546 }
547 
TEST_F(TextfieldTest,TextInputType)548 TEST_F(TextfieldTest, TextInputType) {
549   InitTextfield();
550 
551   // Defaults to TEXT
552   EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, textfield_->GetTextInputType());
553 
554   // And can be set.
555   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_URL);
556   EXPECT_EQ(ui::TEXT_INPUT_TYPE_URL, textfield_->GetTextInputType());
557   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
558   EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, textfield_->GetTextInputType());
559 
560   // Readonly textfields have type NONE
561   textfield_->SetReadOnly(true);
562   EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, textfield_->GetTextInputType());
563 
564   textfield_->SetReadOnly(false);
565   EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, textfield_->GetTextInputType());
566 
567   // As do disabled textfields
568   textfield_->SetEnabled(false);
569   EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, textfield_->GetTextInputType());
570 
571   textfield_->SetEnabled(true);
572   EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, textfield_->GetTextInputType());
573 }
574 
TEST_F(TextfieldTest,OnKeyPress)575 TEST_F(TextfieldTest, OnKeyPress) {
576   InitTextfield();
577 
578   // Character keys are handled by the input method.
579   SendKeyEvent(ui::VKEY_A);
580   EXPECT_TRUE(textfield_->key_received());
581   EXPECT_FALSE(textfield_->key_handled());
582   textfield_->clear();
583 
584   // Arrow keys and home/end are handled by the textfield.
585   SendKeyEvent(ui::VKEY_LEFT);
586   EXPECT_TRUE(textfield_->key_received());
587   EXPECT_TRUE(textfield_->key_handled());
588   textfield_->clear();
589 
590   SendKeyEvent(ui::VKEY_RIGHT);
591   EXPECT_TRUE(textfield_->key_received());
592   EXPECT_TRUE(textfield_->key_handled());
593   textfield_->clear();
594 
595   SendKeyEvent(ui::VKEY_HOME);
596   EXPECT_TRUE(textfield_->key_received());
597   EXPECT_TRUE(textfield_->key_handled());
598   textfield_->clear();
599 
600   SendKeyEvent(ui::VKEY_END);
601   EXPECT_TRUE(textfield_->key_received());
602   EXPECT_TRUE(textfield_->key_handled());
603   textfield_->clear();
604 
605   // F24, up/down key won't be handled.
606   SendKeyEvent(ui::VKEY_F24);
607   EXPECT_TRUE(textfield_->key_received());
608   EXPECT_FALSE(textfield_->key_handled());
609   textfield_->clear();
610 
611   SendKeyEvent(ui::VKEY_UP);
612   EXPECT_TRUE(textfield_->key_received());
613   EXPECT_FALSE(textfield_->key_handled());
614   textfield_->clear();
615 
616   SendKeyEvent(ui::VKEY_DOWN);
617   EXPECT_TRUE(textfield_->key_received());
618   EXPECT_FALSE(textfield_->key_handled());
619   textfield_->clear();
620 }
621 
622 // Tests that default key bindings are handled even with a delegate installed.
TEST_F(TextfieldTest,OnKeyPressBinding)623 TEST_F(TextfieldTest, OnKeyPressBinding) {
624   InitTextfield();
625 
626 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
627   // Install a TextEditKeyBindingsDelegateAuraLinux that does nothing.
628   class TestDelegate : public ui::TextEditKeyBindingsDelegateAuraLinux {
629    public:
630     TestDelegate() {}
631     virtual ~TestDelegate() {}
632 
633     virtual bool MatchEvent(
634         const ui::Event& event,
635         std::vector<ui::TextEditCommandAuraLinux>* commands) OVERRIDE {
636       return false;
637     }
638 
639    private:
640     DISALLOW_COPY_AND_ASSIGN(TestDelegate);
641   };
642 
643   TestDelegate delegate;
644   ui::SetTextEditKeyBindingsDelegate(&delegate);
645 #endif
646 
647   SendKeyEvent(ui::VKEY_A, false, false);
648   EXPECT_STR_EQ("a", textfield_->text());
649   textfield_->clear();
650 
651   // Undo/Redo command keys are handled by the textfield.
652   SendKeyEvent(ui::VKEY_Z, false, true);
653   EXPECT_TRUE(textfield_->key_received());
654   EXPECT_TRUE(textfield_->key_handled());
655   EXPECT_TRUE(textfield_->text().empty());
656   textfield_->clear();
657 
658   SendKeyEvent(ui::VKEY_Z, true, true);
659   EXPECT_TRUE(textfield_->key_received());
660   EXPECT_TRUE(textfield_->key_handled());
661   EXPECT_STR_EQ("a", textfield_->text());
662   textfield_->clear();
663 
664 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
665   ui::SetTextEditKeyBindingsDelegate(NULL);
666 #endif
667 }
668 
TEST_F(TextfieldTest,CursorMovement)669 TEST_F(TextfieldTest, CursorMovement) {
670   InitTextfield();
671 
672   // Test with trailing whitespace.
673   textfield_->SetText(ASCIIToUTF16("one two hre "));
674 
675   // Send the cursor at the end.
676   SendKeyEvent(ui::VKEY_END);
677 
678   // Ctrl+Left should move the cursor just before the last word.
679   SendKeyEvent(ui::VKEY_LEFT, false, true);
680   SendKeyEvent(ui::VKEY_T);
681   EXPECT_STR_EQ("one two thre ", textfield_->text());
682   EXPECT_STR_EQ("one two thre ", last_contents_);
683 
684   // Ctrl+Right should move the cursor to the end of the last word.
685   SendKeyEvent(ui::VKEY_RIGHT, false, true);
686   SendKeyEvent(ui::VKEY_E);
687   EXPECT_STR_EQ("one two three ", textfield_->text());
688   EXPECT_STR_EQ("one two three ", last_contents_);
689 
690   // Ctrl+Right again should move the cursor to the end.
691   SendKeyEvent(ui::VKEY_RIGHT, false, true);
692   SendKeyEvent(ui::VKEY_BACK);
693   EXPECT_STR_EQ("one two three", textfield_->text());
694   EXPECT_STR_EQ("one two three", last_contents_);
695 
696   // Test with leading whitespace.
697   textfield_->SetText(ASCIIToUTF16(" ne two"));
698 
699   // Send the cursor at the beginning.
700   SendKeyEvent(ui::VKEY_HOME);
701 
702   // Ctrl+Right, then Ctrl+Left should move the cursor to the beginning of the
703   // first word.
704   SendKeyEvent(ui::VKEY_RIGHT, false, true);
705   SendKeyEvent(ui::VKEY_LEFT, false, true);
706   SendKeyEvent(ui::VKEY_O);
707   EXPECT_STR_EQ(" one two", textfield_->text());
708   EXPECT_STR_EQ(" one two", last_contents_);
709 
710   // Ctrl+Left to move the cursor to the beginning of the first word.
711   SendKeyEvent(ui::VKEY_LEFT, false, true);
712   // Ctrl+Left again should move the cursor back to the very beginning.
713   SendKeyEvent(ui::VKEY_LEFT, false, true);
714   SendKeyEvent(ui::VKEY_DELETE);
715   EXPECT_STR_EQ("one two", textfield_->text());
716   EXPECT_STR_EQ("one two", last_contents_);
717 }
718 
TEST_F(TextfieldTest,FocusTraversalTest)719 TEST_F(TextfieldTest, FocusTraversalTest) {
720   InitTextfields(3);
721   textfield_->RequestFocus();
722 
723   EXPECT_EQ(1, GetFocusedView()->id());
724   widget_->GetFocusManager()->AdvanceFocus(false);
725   EXPECT_EQ(2, GetFocusedView()->id());
726   widget_->GetFocusManager()->AdvanceFocus(false);
727   EXPECT_EQ(3, GetFocusedView()->id());
728   // Cycle back to the first textfield.
729   widget_->GetFocusManager()->AdvanceFocus(false);
730   EXPECT_EQ(1, GetFocusedView()->id());
731 
732   widget_->GetFocusManager()->AdvanceFocus(true);
733   EXPECT_EQ(3, GetFocusedView()->id());
734   widget_->GetFocusManager()->AdvanceFocus(true);
735   EXPECT_EQ(2, GetFocusedView()->id());
736   widget_->GetFocusManager()->AdvanceFocus(true);
737   EXPECT_EQ(1, GetFocusedView()->id());
738   // Cycle back to the last textfield.
739   widget_->GetFocusManager()->AdvanceFocus(true);
740   EXPECT_EQ(3, GetFocusedView()->id());
741 
742   // Request focus should still work.
743   textfield_->RequestFocus();
744   EXPECT_EQ(1, GetFocusedView()->id());
745 
746   // Test if clicking on textfield view sets the focus.
747   widget_->GetFocusManager()->AdvanceFocus(true);
748   EXPECT_EQ(3, GetFocusedView()->id());
749   ui::MouseEvent click(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
750                        ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
751   textfield_->OnMousePressed(click);
752   EXPECT_EQ(1, GetFocusedView()->id());
753 }
754 
TEST_F(TextfieldTest,ContextMenuDisplayTest)755 TEST_F(TextfieldTest, ContextMenuDisplayTest) {
756   InitTextfield();
757   EXPECT_TRUE(textfield_->context_menu_controller());
758   textfield_->SetText(ASCIIToUTF16("hello world"));
759   ui::Clipboard::GetForCurrentThread()->Clear(ui::CLIPBOARD_TYPE_COPY_PASTE);
760   textfield_->ClearEditHistory();
761   EXPECT_TRUE(GetContextMenuModel());
762   VerifyTextfieldContextMenuContents(false, false, GetContextMenuModel());
763 
764   textfield_->SelectAll(false);
765   VerifyTextfieldContextMenuContents(true, false, GetContextMenuModel());
766 
767   SendKeyEvent(ui::VKEY_T);
768   VerifyTextfieldContextMenuContents(false, true, GetContextMenuModel());
769 
770   textfield_->SelectAll(false);
771   VerifyTextfieldContextMenuContents(true, true, GetContextMenuModel());
772 
773   // Exercise the "paste enabled?" check in the verifier.
774   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "Test");
775   VerifyTextfieldContextMenuContents(true, true, GetContextMenuModel());
776 }
777 
TEST_F(TextfieldTest,DoubleAndTripleClickTest)778 TEST_F(TextfieldTest, DoubleAndTripleClickTest) {
779   InitTextfield();
780   textfield_->SetText(ASCIIToUTF16("hello world"));
781   ui::MouseEvent click(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
782                        ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
783   ui::MouseEvent release(ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(),
784                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
785   ui::MouseEvent double_click(
786       ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
787       ui::EF_LEFT_MOUSE_BUTTON | ui::EF_IS_DOUBLE_CLICK,
788       ui::EF_LEFT_MOUSE_BUTTON);
789 
790   // Test for double click.
791   textfield_->OnMousePressed(click);
792   textfield_->OnMouseReleased(release);
793   EXPECT_TRUE(textfield_->GetSelectedText().empty());
794   textfield_->OnMousePressed(double_click);
795   textfield_->OnMouseReleased(release);
796   EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
797 
798   // Test for triple click.
799   textfield_->OnMousePressed(click);
800   textfield_->OnMouseReleased(release);
801   EXPECT_STR_EQ("hello world", textfield_->GetSelectedText());
802 
803   // Another click should reset back to double click.
804   textfield_->OnMousePressed(click);
805   textfield_->OnMouseReleased(release);
806   EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
807 }
808 
TEST_F(TextfieldTest,DragToSelect)809 TEST_F(TextfieldTest, DragToSelect) {
810   InitTextfield();
811   textfield_->SetText(ASCIIToUTF16("hello world"));
812   const int kStart = GetCursorPositionX(5);
813   const int kEnd = 500;
814   gfx::Point start_point(kStart, 0);
815   gfx::Point end_point(kEnd, 0);
816   ui::MouseEvent click_a(ui::ET_MOUSE_PRESSED, start_point, start_point,
817                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
818   ui::MouseEvent click_b(ui::ET_MOUSE_PRESSED, end_point, end_point,
819                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
820   ui::MouseEvent drag_left(ui::ET_MOUSE_DRAGGED, gfx::Point(), gfx::Point(),
821                            ui::EF_LEFT_MOUSE_BUTTON, 0);
822   ui::MouseEvent drag_right(ui::ET_MOUSE_DRAGGED, end_point, end_point,
823                             ui::EF_LEFT_MOUSE_BUTTON, 0);
824   ui::MouseEvent release(ui::ET_MOUSE_RELEASED, end_point, end_point,
825                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
826   textfield_->OnMousePressed(click_a);
827   EXPECT_TRUE(textfield_->GetSelectedText().empty());
828   // Check that dragging left selects the beginning of the string.
829   textfield_->OnMouseDragged(drag_left);
830   base::string16 text_left = textfield_->GetSelectedText();
831   EXPECT_STR_EQ("hello", text_left);
832   // Check that dragging right selects the rest of the string.
833   textfield_->OnMouseDragged(drag_right);
834   base::string16 text_right = textfield_->GetSelectedText();
835   EXPECT_STR_EQ(" world", text_right);
836   // Check that releasing in the same location does not alter the selection.
837   textfield_->OnMouseReleased(release);
838   EXPECT_EQ(text_right, textfield_->GetSelectedText());
839   // Check that dragging from beyond the text length works too.
840   textfield_->OnMousePressed(click_b);
841   textfield_->OnMouseDragged(drag_left);
842   textfield_->OnMouseReleased(release);
843   EXPECT_EQ(textfield_->text(), textfield_->GetSelectedText());
844 }
845 
846 #if defined(OS_WIN)
TEST_F(TextfieldTest,DragAndDrop_AcceptDrop)847 TEST_F(TextfieldTest, DragAndDrop_AcceptDrop) {
848   InitTextfield();
849   textfield_->SetText(ASCIIToUTF16("hello world"));
850 
851   ui::OSExchangeData data;
852   base::string16 string(ASCIIToUTF16("string "));
853   data.SetString(string);
854   int formats = 0;
855   std::set<OSExchangeData::CustomFormat> custom_formats;
856 
857   // Ensure that disabled textfields do not accept drops.
858   textfield_->SetEnabled(false);
859   EXPECT_FALSE(textfield_->GetDropFormats(&formats, &custom_formats));
860   EXPECT_EQ(0, formats);
861   EXPECT_TRUE(custom_formats.empty());
862   EXPECT_FALSE(textfield_->CanDrop(data));
863   textfield_->SetEnabled(true);
864 
865   // Ensure that read-only textfields do not accept drops.
866   textfield_->SetReadOnly(true);
867   EXPECT_FALSE(textfield_->GetDropFormats(&formats, &custom_formats));
868   EXPECT_EQ(0, formats);
869   EXPECT_TRUE(custom_formats.empty());
870   EXPECT_FALSE(textfield_->CanDrop(data));
871   textfield_->SetReadOnly(false);
872 
873   // Ensure that enabled and editable textfields do accept drops.
874   EXPECT_TRUE(textfield_->GetDropFormats(&formats, &custom_formats));
875   EXPECT_EQ(ui::OSExchangeData::STRING, formats);
876   EXPECT_TRUE(custom_formats.empty());
877   EXPECT_TRUE(textfield_->CanDrop(data));
878   gfx::Point drop_point(GetCursorPositionX(6), 0);
879   ui::DropTargetEvent drop(data, drop_point, drop_point,
880       ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE);
881   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE,
882             textfield_->OnDragUpdated(drop));
883   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, textfield_->OnPerformDrop(drop));
884   EXPECT_STR_EQ("hello string world", textfield_->text());
885 
886   // Ensure that textfields do not accept non-OSExchangeData::STRING types.
887   ui::OSExchangeData bad_data;
888   bad_data.SetFilename(base::FilePath(FILE_PATH_LITERAL("x")));
889   ui::OSExchangeData::CustomFormat fmt = ui::Clipboard::GetBitmapFormatType();
890   bad_data.SetPickledData(fmt, Pickle());
891   bad_data.SetFileContents(base::FilePath(L"x"), "x");
892   bad_data.SetHtml(base::string16(ASCIIToUTF16("x")), GURL("x.org"));
893   ui::OSExchangeData::DownloadFileInfo download(base::FilePath(), NULL);
894   bad_data.SetDownloadFileInfo(download);
895   EXPECT_FALSE(textfield_->CanDrop(bad_data));
896 }
897 #endif
898 
TEST_F(TextfieldTest,DragAndDrop_InitiateDrag)899 TEST_F(TextfieldTest, DragAndDrop_InitiateDrag) {
900   InitTextfield();
901   textfield_->SetText(ASCIIToUTF16("hello string world"));
902 
903   // Ensure the textfield will provide selected text for drag data.
904   base::string16 string;
905   ui::OSExchangeData data;
906   const gfx::Range kStringRange(6, 12);
907   textfield_->SelectRange(kStringRange);
908   const gfx::Point kStringPoint(GetCursorPositionX(9), 0);
909   textfield_->WriteDragDataForView(NULL, kStringPoint, &data);
910   EXPECT_TRUE(data.GetString(&string));
911   EXPECT_EQ(textfield_->GetSelectedText(), string);
912 
913   // Ensure that disabled textfields do not support drag operations.
914   textfield_->SetEnabled(false);
915   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
916             textfield_->GetDragOperationsForView(NULL, kStringPoint));
917   textfield_->SetEnabled(true);
918   // Ensure that textfields without selections do not support drag operations.
919   textfield_->ClearSelection();
920   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
921             textfield_->GetDragOperationsForView(NULL, kStringPoint));
922   textfield_->SelectRange(kStringRange);
923   // Ensure that password textfields do not support drag operations.
924   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
925   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
926             textfield_->GetDragOperationsForView(NULL, kStringPoint));
927   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
928   // Ensure that textfields only initiate drag operations inside the selection.
929   ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, kStringPoint, kStringPoint,
930                              ui::EF_LEFT_MOUSE_BUTTON,
931                              ui::EF_LEFT_MOUSE_BUTTON);
932   textfield_->OnMousePressed(press_event);
933   EXPECT_EQ(ui::DragDropTypes::DRAG_NONE,
934             textfield_->GetDragOperationsForView(NULL, gfx::Point()));
935   EXPECT_FALSE(textfield_->CanStartDragForView(NULL, gfx::Point(),
936                                                gfx::Point()));
937   EXPECT_EQ(ui::DragDropTypes::DRAG_COPY,
938             textfield_->GetDragOperationsForView(NULL, kStringPoint));
939   EXPECT_TRUE(textfield_->CanStartDragForView(NULL, kStringPoint,
940                                               gfx::Point()));
941   // Ensure that textfields support local moves.
942   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
943       textfield_->GetDragOperationsForView(textfield_, kStringPoint));
944 }
945 
TEST_F(TextfieldTest,DragAndDrop_ToTheRight)946 TEST_F(TextfieldTest, DragAndDrop_ToTheRight) {
947   InitTextfield();
948   textfield_->SetText(ASCIIToUTF16("hello world"));
949 
950   base::string16 string;
951   ui::OSExchangeData data;
952   int formats = 0;
953   int operations = 0;
954   std::set<OSExchangeData::CustomFormat> custom_formats;
955 
956   // Start dragging "ello".
957   textfield_->SelectRange(gfx::Range(1, 5));
958   gfx::Point point(GetCursorPositionX(3), 0);
959   ui::MouseEvent click_a(ui::ET_MOUSE_PRESSED, point, point,
960                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
961   textfield_->OnMousePressed(click_a);
962   EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, click_a.location(),
963                                               gfx::Point()));
964   operations = textfield_->GetDragOperationsForView(textfield_,
965                                                     click_a.location());
966   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
967             operations);
968   textfield_->WriteDragDataForView(NULL, click_a.location(), &data);
969   EXPECT_TRUE(data.GetString(&string));
970   EXPECT_EQ(textfield_->GetSelectedText(), string);
971   EXPECT_TRUE(textfield_->GetDropFormats(&formats, &custom_formats));
972   EXPECT_EQ(ui::OSExchangeData::STRING, formats);
973   EXPECT_TRUE(custom_formats.empty());
974 
975   // Drop "ello" after "w".
976   const gfx::Point kDropPoint(GetCursorPositionX(7), 0);
977   EXPECT_TRUE(textfield_->CanDrop(data));
978   ui::DropTargetEvent drop_a(data, kDropPoint, kDropPoint, operations);
979   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop_a));
980   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnPerformDrop(drop_a));
981   EXPECT_STR_EQ("h welloorld", textfield_->text());
982   textfield_->OnDragDone();
983 
984   // Undo/Redo the drag&drop change.
985   SendKeyEvent(ui::VKEY_Z, false, true);
986   EXPECT_STR_EQ("hello world", textfield_->text());
987   SendKeyEvent(ui::VKEY_Z, false, true);
988   EXPECT_STR_EQ("", textfield_->text());
989   SendKeyEvent(ui::VKEY_Z, false, true);
990   EXPECT_STR_EQ("", textfield_->text());
991   SendKeyEvent(ui::VKEY_Y, false, true);
992   EXPECT_STR_EQ("hello world", textfield_->text());
993   SendKeyEvent(ui::VKEY_Y, false, true);
994   EXPECT_STR_EQ("h welloorld", textfield_->text());
995   SendKeyEvent(ui::VKEY_Y, false, true);
996   EXPECT_STR_EQ("h welloorld", textfield_->text());
997 }
998 
TEST_F(TextfieldTest,DragAndDrop_ToTheLeft)999 TEST_F(TextfieldTest, DragAndDrop_ToTheLeft) {
1000   InitTextfield();
1001   textfield_->SetText(ASCIIToUTF16("hello world"));
1002 
1003   base::string16 string;
1004   ui::OSExchangeData data;
1005   int formats = 0;
1006   int operations = 0;
1007   std::set<OSExchangeData::CustomFormat> custom_formats;
1008 
1009   // Start dragging " worl".
1010   textfield_->SelectRange(gfx::Range(5, 10));
1011   gfx::Point point(GetCursorPositionX(7), 0);
1012   ui::MouseEvent click_a(ui::ET_MOUSE_PRESSED, point, point,
1013                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1014   textfield_->OnMousePressed(click_a);
1015   EXPECT_TRUE(textfield_->CanStartDragForView(textfield_, click_a.location(),
1016                                               gfx::Point()));
1017   operations = textfield_->GetDragOperationsForView(textfield_,
1018                                                     click_a.location());
1019   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY,
1020             operations);
1021   textfield_->WriteDragDataForView(NULL, click_a.location(), &data);
1022   EXPECT_TRUE(data.GetString(&string));
1023   EXPECT_EQ(textfield_->GetSelectedText(), string);
1024   EXPECT_TRUE(textfield_->GetDropFormats(&formats, &custom_formats));
1025   EXPECT_EQ(ui::OSExchangeData::STRING, formats);
1026   EXPECT_TRUE(custom_formats.empty());
1027 
1028   // Drop " worl" after "h".
1029   EXPECT_TRUE(textfield_->CanDrop(data));
1030   gfx::Point drop_point(GetCursorPositionX(1), 0);
1031   ui::DropTargetEvent drop_a(data, drop_point, drop_point, operations);
1032   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop_a));
1033   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnPerformDrop(drop_a));
1034   EXPECT_STR_EQ("h worlellod", textfield_->text());
1035   textfield_->OnDragDone();
1036 
1037   // Undo/Redo the drag&drop change.
1038   SendKeyEvent(ui::VKEY_Z, false, true);
1039   EXPECT_STR_EQ("hello world", textfield_->text());
1040   SendKeyEvent(ui::VKEY_Z, false, true);
1041   EXPECT_STR_EQ("", textfield_->text());
1042   SendKeyEvent(ui::VKEY_Z, false, true);
1043   EXPECT_STR_EQ("", textfield_->text());
1044   SendKeyEvent(ui::VKEY_Y, false, true);
1045   EXPECT_STR_EQ("hello world", textfield_->text());
1046   SendKeyEvent(ui::VKEY_Y, false, true);
1047   EXPECT_STR_EQ("h worlellod", textfield_->text());
1048   SendKeyEvent(ui::VKEY_Y, false, true);
1049   EXPECT_STR_EQ("h worlellod", textfield_->text());
1050 }
1051 
TEST_F(TextfieldTest,DragAndDrop_Canceled)1052 TEST_F(TextfieldTest, DragAndDrop_Canceled) {
1053   InitTextfield();
1054   textfield_->SetText(ASCIIToUTF16("hello world"));
1055 
1056   // Start dragging "worl".
1057   textfield_->SelectRange(gfx::Range(6, 10));
1058   gfx::Point point(GetCursorPositionX(8), 0);
1059   ui::MouseEvent click(ui::ET_MOUSE_PRESSED, point, point,
1060                        ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1061   textfield_->OnMousePressed(click);
1062   ui::OSExchangeData data;
1063   textfield_->WriteDragDataForView(NULL, click.location(), &data);
1064   EXPECT_TRUE(textfield_->CanDrop(data));
1065   // Drag the text over somewhere valid, outside the current selection.
1066   gfx::Point drop_point(GetCursorPositionX(2), 0);
1067   ui::DropTargetEvent drop(data, drop_point, drop_point,
1068                            ui::DragDropTypes::DRAG_MOVE);
1069   EXPECT_EQ(ui::DragDropTypes::DRAG_MOVE, textfield_->OnDragUpdated(drop));
1070   // "Cancel" the drag, via move and release over the selection, and OnDragDone.
1071   gfx::Point drag_point(GetCursorPositionX(9), 0);
1072   ui::MouseEvent drag(ui::ET_MOUSE_DRAGGED, drag_point, drag_point,
1073                       ui::EF_LEFT_MOUSE_BUTTON, 0);
1074   ui::MouseEvent release(ui::ET_MOUSE_RELEASED, drag_point, drag_point,
1075                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1076   textfield_->OnMouseDragged(drag);
1077   textfield_->OnMouseReleased(release);
1078   textfield_->OnDragDone();
1079   EXPECT_EQ(ASCIIToUTF16("hello world"), textfield_->text());
1080 }
1081 
TEST_F(TextfieldTest,ReadOnlyTest)1082 TEST_F(TextfieldTest, ReadOnlyTest) {
1083   InitTextfield();
1084   textfield_->SetText(ASCIIToUTF16("read only"));
1085   textfield_->SetReadOnly(true);
1086   EXPECT_TRUE(textfield_->enabled());
1087   EXPECT_TRUE(textfield_->IsFocusable());
1088 
1089   SendKeyEvent(ui::VKEY_HOME);
1090   EXPECT_EQ(0U, textfield_->GetCursorPosition());
1091   SendKeyEvent(ui::VKEY_END);
1092   EXPECT_EQ(9U, textfield_->GetCursorPosition());
1093 
1094   SendKeyEvent(ui::VKEY_LEFT, false, false);
1095   EXPECT_EQ(8U, textfield_->GetCursorPosition());
1096   SendKeyEvent(ui::VKEY_LEFT, false, true);
1097   EXPECT_EQ(5U, textfield_->GetCursorPosition());
1098   SendKeyEvent(ui::VKEY_LEFT, true, true);
1099   EXPECT_EQ(0U, textfield_->GetCursorPosition());
1100   EXPECT_STR_EQ("read ", textfield_->GetSelectedText());
1101   textfield_->SelectAll(false);
1102   EXPECT_STR_EQ("read only", textfield_->GetSelectedText());
1103 
1104   // Cut should be disabled.
1105   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "Test");
1106   EXPECT_FALSE(textfield_->IsCommandIdEnabled(IDS_APP_CUT));
1107   textfield_->ExecuteCommand(IDS_APP_CUT, 0);
1108   SendKeyEvent(ui::VKEY_X, false, true);
1109   SendKeyEvent(ui::VKEY_DELETE, true, false);
1110   EXPECT_STR_EQ("Test", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1111   EXPECT_STR_EQ("read only", textfield_->text());
1112 
1113   // Paste should be disabled.
1114   EXPECT_FALSE(textfield_->IsCommandIdEnabled(IDS_APP_PASTE));
1115   textfield_->ExecuteCommand(IDS_APP_PASTE, 0);
1116   SendKeyEvent(ui::VKEY_V, false, true);
1117   SendKeyEvent(ui::VKEY_INSERT, true, false);
1118   EXPECT_STR_EQ("read only", textfield_->text());
1119 
1120   // Copy should work normally.
1121   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "Test");
1122   EXPECT_TRUE(textfield_->IsCommandIdEnabled(IDS_APP_COPY));
1123   textfield_->ExecuteCommand(IDS_APP_COPY, 0);
1124   EXPECT_STR_EQ("read only", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1125   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "Test");
1126   SendKeyEvent(ui::VKEY_C, false, true);
1127   EXPECT_STR_EQ("read only", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1128   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "Test");
1129   SendKeyEvent(ui::VKEY_INSERT, false, true);
1130   EXPECT_STR_EQ("read only", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1131 
1132   // SetText should work even in read only mode.
1133   textfield_->SetText(ASCIIToUTF16(" four five six "));
1134   EXPECT_STR_EQ(" four five six ", textfield_->text());
1135 
1136   textfield_->SelectAll(false);
1137   EXPECT_STR_EQ(" four five six ", textfield_->GetSelectedText());
1138 
1139   // Text field is unmodifiable and selection shouldn't change.
1140   SendKeyEvent(ui::VKEY_DELETE);
1141   EXPECT_STR_EQ(" four five six ", textfield_->GetSelectedText());
1142   SendKeyEvent(ui::VKEY_BACK);
1143   EXPECT_STR_EQ(" four five six ", textfield_->GetSelectedText());
1144   SendKeyEvent(ui::VKEY_T);
1145   EXPECT_STR_EQ(" four five six ", textfield_->GetSelectedText());
1146 }
1147 
TEST_F(TextfieldTest,TextInputClientTest)1148 TEST_F(TextfieldTest, TextInputClientTest) {
1149   InitTextfield();
1150   ui::TextInputClient* client = textfield_->GetTextInputClient();
1151   EXPECT_TRUE(client);
1152   EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, client->GetTextInputType());
1153 
1154   textfield_->SetText(ASCIIToUTF16("0123456789"));
1155   gfx::Range range;
1156   EXPECT_TRUE(client->GetTextRange(&range));
1157   EXPECT_EQ(0U, range.start());
1158   EXPECT_EQ(10U, range.end());
1159 
1160   EXPECT_TRUE(client->SetSelectionRange(gfx::Range(1, 4)));
1161   EXPECT_TRUE(client->GetSelectionRange(&range));
1162   EXPECT_EQ(gfx::Range(1, 4), range);
1163 
1164   base::string16 substring;
1165   EXPECT_TRUE(client->GetTextFromRange(range, &substring));
1166   EXPECT_STR_EQ("123", substring);
1167 
1168   EXPECT_TRUE(client->DeleteRange(range));
1169   EXPECT_STR_EQ("0456789", textfield_->text());
1170 
1171   ui::CompositionText composition;
1172   composition.text = UTF8ToUTF16("321");
1173   // Set composition through input method.
1174   input_method_->Clear();
1175   input_method_->SetCompositionTextForNextKey(composition);
1176   textfield_->clear();
1177 
1178   on_before_user_action_ = on_after_user_action_ = 0;
1179   SendKeyEvent(ui::VKEY_A);
1180   EXPECT_TRUE(textfield_->key_received());
1181   EXPECT_FALSE(textfield_->key_handled());
1182   EXPECT_TRUE(client->HasCompositionText());
1183   EXPECT_TRUE(client->GetCompositionTextRange(&range));
1184   EXPECT_STR_EQ("0321456789", textfield_->text());
1185   EXPECT_EQ(gfx::Range(1, 4), range);
1186   EXPECT_EQ(1, on_before_user_action_);
1187   EXPECT_EQ(1, on_after_user_action_);
1188 
1189   input_method_->SetResultTextForNextKey(UTF8ToUTF16("123"));
1190   on_before_user_action_ = on_after_user_action_ = 0;
1191   textfield_->clear();
1192   SendKeyEvent(ui::VKEY_A);
1193   EXPECT_TRUE(textfield_->key_received());
1194   EXPECT_FALSE(textfield_->key_handled());
1195   EXPECT_FALSE(client->HasCompositionText());
1196   EXPECT_FALSE(input_method_->cancel_composition_called());
1197   EXPECT_STR_EQ("0123456789", textfield_->text());
1198   EXPECT_EQ(1, on_before_user_action_);
1199   EXPECT_EQ(1, on_after_user_action_);
1200 
1201   input_method_->Clear();
1202   input_method_->SetCompositionTextForNextKey(composition);
1203   textfield_->clear();
1204   SendKeyEvent(ui::VKEY_A);
1205   EXPECT_TRUE(client->HasCompositionText());
1206   EXPECT_STR_EQ("0123321456789", textfield_->text());
1207 
1208   on_before_user_action_ = on_after_user_action_ = 0;
1209   textfield_->clear();
1210   SendKeyEvent(ui::VKEY_RIGHT);
1211   EXPECT_FALSE(client->HasCompositionText());
1212   EXPECT_TRUE(input_method_->cancel_composition_called());
1213   EXPECT_TRUE(textfield_->key_received());
1214   EXPECT_TRUE(textfield_->key_handled());
1215   EXPECT_STR_EQ("0123321456789", textfield_->text());
1216   EXPECT_EQ(8U, textfield_->GetCursorPosition());
1217   EXPECT_EQ(1, on_before_user_action_);
1218   EXPECT_EQ(1, on_after_user_action_);
1219 
1220   textfield_->clear();
1221   textfield_->SetText(ASCIIToUTF16("0123456789"));
1222   EXPECT_TRUE(client->SetSelectionRange(gfx::Range(5, 5)));
1223   client->ExtendSelectionAndDelete(4, 2);
1224   EXPECT_STR_EQ("0789", textfield_->text());
1225 
1226   // On{Before,After}UserAction should be called by whatever user action
1227   // triggers clearing or setting a selection if appropriate.
1228   on_before_user_action_ = on_after_user_action_ = 0;
1229   textfield_->clear();
1230   textfield_->ClearSelection();
1231   textfield_->SelectAll(false);
1232   EXPECT_EQ(0, on_before_user_action_);
1233   EXPECT_EQ(0, on_after_user_action_);
1234 
1235   input_method_->Clear();
1236   textfield_->SetReadOnly(true);
1237   EXPECT_TRUE(input_method_->text_input_type_changed());
1238   EXPECT_FALSE(textfield_->GetTextInputClient());
1239 
1240   textfield_->SetReadOnly(false);
1241   input_method_->Clear();
1242   textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
1243   EXPECT_TRUE(input_method_->text_input_type_changed());
1244   EXPECT_TRUE(textfield_->GetTextInputClient());
1245 }
1246 
TEST_F(TextfieldTest,UndoRedoTest)1247 TEST_F(TextfieldTest, UndoRedoTest) {
1248   InitTextfield();
1249   SendKeyEvent(ui::VKEY_A);
1250   EXPECT_STR_EQ("a", textfield_->text());
1251   SendKeyEvent(ui::VKEY_Z, false, true);
1252   EXPECT_STR_EQ("", textfield_->text());
1253   SendKeyEvent(ui::VKEY_Z, false, true);
1254   EXPECT_STR_EQ("", textfield_->text());
1255   SendKeyEvent(ui::VKEY_Y, false, true);
1256   EXPECT_STR_EQ("a", textfield_->text());
1257   SendKeyEvent(ui::VKEY_Y, false, true);
1258   EXPECT_STR_EQ("a", textfield_->text());
1259 
1260   // AppendText
1261   textfield_->AppendText(ASCIIToUTF16("b"));
1262   last_contents_.clear();  // AppendText doesn't call ContentsChanged.
1263   EXPECT_STR_EQ("ab", textfield_->text());
1264   SendKeyEvent(ui::VKEY_Z, false, true);
1265   EXPECT_STR_EQ("a", textfield_->text());
1266   SendKeyEvent(ui::VKEY_Y, false, true);
1267   EXPECT_STR_EQ("ab", textfield_->text());
1268 
1269   // SetText
1270   SendKeyEvent(ui::VKEY_C);
1271   // Undo'ing append moves the cursor to the end for now.
1272   // A no-op SetText won't add a new edit; see TextfieldModel::SetText.
1273   EXPECT_STR_EQ("abc", textfield_->text());
1274   textfield_->SetText(ASCIIToUTF16("abc"));
1275   EXPECT_STR_EQ("abc", textfield_->text());
1276   SendKeyEvent(ui::VKEY_Z, false, true);
1277   EXPECT_STR_EQ("ab", textfield_->text());
1278   SendKeyEvent(ui::VKEY_Y, false, true);
1279   EXPECT_STR_EQ("abc", textfield_->text());
1280   SendKeyEvent(ui::VKEY_Y, false, true);
1281   EXPECT_STR_EQ("abc", textfield_->text());
1282   textfield_->SetText(ASCIIToUTF16("123"));
1283   textfield_->SetText(ASCIIToUTF16("123"));
1284   EXPECT_STR_EQ("123", textfield_->text());
1285   SendKeyEvent(ui::VKEY_END, false, false);
1286   SendKeyEvent(ui::VKEY_4, false, false);
1287   EXPECT_STR_EQ("1234", textfield_->text());
1288   last_contents_.clear();
1289   SendKeyEvent(ui::VKEY_Z, false, true);
1290   EXPECT_STR_EQ("123", textfield_->text());
1291   SendKeyEvent(ui::VKEY_Z, false, true);
1292   // the insert edit "c" and set edit "123" are merged to single edit,
1293   // so text becomes "ab" after undo.
1294   EXPECT_STR_EQ("ab", textfield_->text());
1295   SendKeyEvent(ui::VKEY_Z, false, true);
1296   EXPECT_STR_EQ("a", textfield_->text());
1297   SendKeyEvent(ui::VKEY_Y, false, true);
1298   EXPECT_STR_EQ("ab", textfield_->text());
1299   SendKeyEvent(ui::VKEY_Y, false, true);
1300   EXPECT_STR_EQ("123", textfield_->text());
1301   SendKeyEvent(ui::VKEY_Y, false, true);
1302   EXPECT_STR_EQ("1234", textfield_->text());
1303 
1304   // Undoing to the same text shouldn't call ContentsChanged.
1305   SendKeyEvent(ui::VKEY_A, false, true);  // select all
1306   SendKeyEvent(ui::VKEY_A);
1307   EXPECT_STR_EQ("a", textfield_->text());
1308   SendKeyEvent(ui::VKEY_B);
1309   SendKeyEvent(ui::VKEY_C);
1310   EXPECT_STR_EQ("abc", textfield_->text());
1311   SendKeyEvent(ui::VKEY_Z, false, true);
1312   EXPECT_STR_EQ("1234", textfield_->text());
1313   SendKeyEvent(ui::VKEY_Y, false, true);
1314   EXPECT_STR_EQ("abc", textfield_->text());
1315 
1316   // Delete/Backspace
1317   SendKeyEvent(ui::VKEY_BACK);
1318   EXPECT_STR_EQ("ab", textfield_->text());
1319   SendKeyEvent(ui::VKEY_HOME);
1320   SendKeyEvent(ui::VKEY_DELETE);
1321   EXPECT_STR_EQ("b", textfield_->text());
1322   SendKeyEvent(ui::VKEY_A, false, true);
1323   SendKeyEvent(ui::VKEY_DELETE);
1324   EXPECT_STR_EQ("", textfield_->text());
1325   SendKeyEvent(ui::VKEY_Z, false, true);
1326   EXPECT_STR_EQ("b", textfield_->text());
1327   SendKeyEvent(ui::VKEY_Z, false, true);
1328   EXPECT_STR_EQ("ab", textfield_->text());
1329   SendKeyEvent(ui::VKEY_Z, false, true);
1330   EXPECT_STR_EQ("abc", textfield_->text());
1331   SendKeyEvent(ui::VKEY_Y, false, true);
1332   EXPECT_STR_EQ("ab", textfield_->text());
1333   SendKeyEvent(ui::VKEY_Y, false, true);
1334   EXPECT_STR_EQ("b", textfield_->text());
1335   SendKeyEvent(ui::VKEY_Y, false, true);
1336   EXPECT_STR_EQ("", textfield_->text());
1337   SendKeyEvent(ui::VKEY_Y, false, true);
1338   EXPECT_STR_EQ("", textfield_->text());
1339 }
1340 
TEST_F(TextfieldTest,CutCopyPaste)1341 TEST_F(TextfieldTest, CutCopyPaste) {
1342   InitTextfield();
1343 
1344   // Ensure IDS_APP_CUT cuts.
1345   textfield_->SetText(ASCIIToUTF16("123"));
1346   textfield_->SelectAll(false);
1347   EXPECT_TRUE(textfield_->IsCommandIdEnabled(IDS_APP_CUT));
1348   textfield_->ExecuteCommand(IDS_APP_CUT, 0);
1349   EXPECT_STR_EQ("123", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1350   EXPECT_STR_EQ("", textfield_->text());
1351   EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
1352 
1353   // Ensure [Ctrl]+[x] cuts and [Ctrl]+[Alt][x] does nothing.
1354   textfield_->SetText(ASCIIToUTF16("456"));
1355   textfield_->SelectAll(false);
1356   SendKeyEvent(ui::VKEY_X, true, false, true, false);
1357   EXPECT_STR_EQ("123", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1358   EXPECT_STR_EQ("456", textfield_->text());
1359   EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
1360   SendKeyEvent(ui::VKEY_X, false, true);
1361   EXPECT_STR_EQ("456", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1362   EXPECT_STR_EQ("", textfield_->text());
1363   EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
1364 
1365   // Ensure [Shift]+[Delete] cuts.
1366   textfield_->SetText(ASCIIToUTF16("123"));
1367   textfield_->SelectAll(false);
1368   SendKeyEvent(ui::VKEY_DELETE, true, false);
1369   EXPECT_STR_EQ("123", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1370   EXPECT_STR_EQ("", textfield_->text());
1371   EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
1372 
1373   // Ensure IDS_APP_COPY copies.
1374   textfield_->SetText(ASCIIToUTF16("789"));
1375   textfield_->SelectAll(false);
1376   EXPECT_TRUE(textfield_->IsCommandIdEnabled(IDS_APP_COPY));
1377   textfield_->ExecuteCommand(IDS_APP_COPY, 0);
1378   EXPECT_STR_EQ("789", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1379   EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
1380 
1381   // Ensure [Ctrl]+[c] copies and [Ctrl]+[Alt][c] does nothing.
1382   textfield_->SetText(ASCIIToUTF16("012"));
1383   textfield_->SelectAll(false);
1384   SendKeyEvent(ui::VKEY_C, true, false, true, false);
1385   EXPECT_STR_EQ("789", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1386   EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
1387   SendKeyEvent(ui::VKEY_C, false, true);
1388   EXPECT_STR_EQ("012", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1389   EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
1390 
1391   // Ensure [Ctrl]+[Insert] copies.
1392   textfield_->SetText(ASCIIToUTF16("345"));
1393   textfield_->SelectAll(false);
1394   SendKeyEvent(ui::VKEY_INSERT, false, true);
1395   EXPECT_STR_EQ("345", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1396   EXPECT_STR_EQ("345", textfield_->text());
1397   EXPECT_EQ(ui::CLIPBOARD_TYPE_COPY_PASTE, GetAndResetCopiedToClipboard());
1398 
1399   // Ensure IDS_APP_PASTE, [Ctrl]+[V], and [Shift]+[Insert] pastes;
1400   // also ensure that [Ctrl]+[Alt]+[V] does nothing.
1401   SetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE, "abc");
1402   textfield_->SetText(base::string16());
1403   EXPECT_TRUE(textfield_->IsCommandIdEnabled(IDS_APP_PASTE));
1404   textfield_->ExecuteCommand(IDS_APP_PASTE, 0);
1405   EXPECT_STR_EQ("abc", textfield_->text());
1406   SendKeyEvent(ui::VKEY_V, false, true);
1407   EXPECT_STR_EQ("abcabc", textfield_->text());
1408   SendKeyEvent(ui::VKEY_INSERT, true, false);
1409   EXPECT_STR_EQ("abcabcabc", textfield_->text());
1410   SendKeyEvent(ui::VKEY_V, true, false, true, false);
1411   EXPECT_STR_EQ("abcabcabc", textfield_->text());
1412 
1413   // Ensure [Ctrl]+[Shift]+[Insert] is a no-op.
1414   textfield_->SelectAll(false);
1415   SendKeyEvent(ui::VKEY_INSERT, true, true);
1416   EXPECT_STR_EQ("abc", GetClipboardText(ui::CLIPBOARD_TYPE_COPY_PASTE));
1417   EXPECT_STR_EQ("abcabcabc", textfield_->text());
1418   EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
1419 }
1420 
TEST_F(TextfieldTest,OvertypeMode)1421 TEST_F(TextfieldTest, OvertypeMode) {
1422   InitTextfield();
1423   // Overtype mode should be disabled (no-op [Insert]).
1424   textfield_->SetText(ASCIIToUTF16("2"));
1425   SendKeyEvent(ui::VKEY_HOME);
1426   SendKeyEvent(ui::VKEY_INSERT);
1427   SendKeyEvent(ui::VKEY_1, false, false);
1428   EXPECT_STR_EQ("12", textfield_->text());
1429 }
1430 
TEST_F(TextfieldTest,TextCursorDisplayTest)1431 TEST_F(TextfieldTest, TextCursorDisplayTest) {
1432   InitTextfield();
1433   // LTR-RTL string in LTR context.
1434   SendKeyEvent('a');
1435   EXPECT_STR_EQ("a", textfield_->text());
1436   int x = GetCursorBounds().x();
1437   int prev_x = x;
1438 
1439   SendKeyEvent('b');
1440   EXPECT_STR_EQ("ab", textfield_->text());
1441   x = GetCursorBounds().x();
1442   EXPECT_LT(prev_x, x);
1443   prev_x = x;
1444 
1445   SendKeyEvent(0x05E1);
1446   EXPECT_EQ(WideToUTF16(L"ab\x05E1"), textfield_->text());
1447   x = GetCursorBounds().x();
1448   EXPECT_EQ(prev_x, x);
1449 
1450   SendKeyEvent(0x05E2);
1451   EXPECT_EQ(WideToUTF16(L"ab\x05E1\x5E2"), textfield_->text());
1452   x = GetCursorBounds().x();
1453   EXPECT_EQ(prev_x, x);
1454 
1455   // Clear text.
1456   SendKeyEvent(ui::VKEY_A, false, true);
1457   SendKeyEvent('\n');
1458 
1459   // RTL-LTR string in LTR context.
1460   SendKeyEvent(0x05E1);
1461   EXPECT_EQ(WideToUTF16(L"\x05E1"), textfield_->text());
1462   x = GetCursorBounds().x();
1463   EXPECT_EQ(GetDisplayRect().x(), x);
1464   prev_x = x;
1465 
1466   SendKeyEvent(0x05E2);
1467   EXPECT_EQ(WideToUTF16(L"\x05E1\x05E2"), textfield_->text());
1468   x = GetCursorBounds().x();
1469   EXPECT_EQ(prev_x, x);
1470 
1471   SendKeyEvent('a');
1472   EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"a"), textfield_->text());
1473   x = GetCursorBounds().x();
1474   EXPECT_LT(prev_x, x);
1475   prev_x = x;
1476 
1477   SendKeyEvent('b');
1478   EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"ab"), textfield_->text());
1479   x = GetCursorBounds().x();
1480   EXPECT_LT(prev_x, x);
1481 }
1482 
TEST_F(TextfieldTest,TextCursorDisplayInRTLTest)1483 TEST_F(TextfieldTest, TextCursorDisplayInRTLTest) {
1484   std::string locale = l10n_util::GetApplicationLocale("");
1485   base::i18n::SetICUDefaultLocale("he");
1486 
1487   InitTextfield();
1488   // LTR-RTL string in RTL context.
1489   SendKeyEvent('a');
1490   EXPECT_STR_EQ("a", textfield_->text());
1491   int x = GetCursorBounds().x();
1492   EXPECT_EQ(GetDisplayRect().right() - 1, x);
1493   int prev_x = x;
1494 
1495   SendKeyEvent('b');
1496   EXPECT_STR_EQ("ab", textfield_->text());
1497   x = GetCursorBounds().x();
1498   EXPECT_EQ(prev_x, x);
1499 
1500   SendKeyEvent(0x05E1);
1501   EXPECT_EQ(WideToUTF16(L"ab\x05E1"), textfield_->text());
1502   x = GetCursorBounds().x();
1503   EXPECT_GT(prev_x, x);
1504   prev_x = x;
1505 
1506   SendKeyEvent(0x05E2);
1507   EXPECT_EQ(WideToUTF16(L"ab\x05E1\x5E2"), textfield_->text());
1508   x = GetCursorBounds().x();
1509   EXPECT_GT(prev_x, x);
1510 
1511   SendKeyEvent(ui::VKEY_A, false, true);
1512   SendKeyEvent('\n');
1513 
1514   // RTL-LTR string in RTL context.
1515   SendKeyEvent(0x05E1);
1516   EXPECT_EQ(WideToUTF16(L"\x05E1"), textfield_->text());
1517   x = GetCursorBounds().x();
1518   prev_x = x;
1519 
1520   SendKeyEvent(0x05E2);
1521   EXPECT_EQ(WideToUTF16(L"\x05E1\x05E2"), textfield_->text());
1522   x = GetCursorBounds().x();
1523   EXPECT_GT(prev_x, x);
1524   prev_x = x;
1525 
1526   SendKeyEvent('a');
1527   EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"a"), textfield_->text());
1528   x = GetCursorBounds().x();
1529   EXPECT_EQ(prev_x, x);
1530   prev_x = x;
1531 
1532   SendKeyEvent('b');
1533   EXPECT_EQ(WideToUTF16(L"\x05E1\x5E2" L"ab"), textfield_->text());
1534   x = GetCursorBounds().x();
1535   EXPECT_EQ(prev_x, x);
1536 
1537   // Reset locale.
1538   base::i18n::SetICUDefaultLocale(locale);
1539 }
1540 
TEST_F(TextfieldTest,HitInsideTextAreaTest)1541 TEST_F(TextfieldTest, HitInsideTextAreaTest) {
1542   InitTextfield();
1543   textfield_->SetText(WideToUTF16(L"ab\x05E1\x5E2"));
1544   std::vector<gfx::Rect> cursor_bounds;
1545 
1546   // Save each cursor bound.
1547   gfx::SelectionModel sel(0, gfx::CURSOR_FORWARD);
1548   cursor_bounds.push_back(GetCursorBounds(sel));
1549 
1550   sel = gfx::SelectionModel(1, gfx::CURSOR_BACKWARD);
1551   gfx::Rect bound = GetCursorBounds(sel);
1552   sel = gfx::SelectionModel(1, gfx::CURSOR_FORWARD);
1553   EXPECT_EQ(bound.x(), GetCursorBounds(sel).x());
1554   cursor_bounds.push_back(bound);
1555 
1556   // Check that a cursor at the end of the Latin portion of the text is at the
1557   // same position as a cursor placed at the end of the RTL Hebrew portion.
1558   sel = gfx::SelectionModel(2, gfx::CURSOR_BACKWARD);
1559   bound = GetCursorBounds(sel);
1560   sel = gfx::SelectionModel(4, gfx::CURSOR_BACKWARD);
1561   EXPECT_EQ(bound.x(), GetCursorBounds(sel).x());
1562   cursor_bounds.push_back(bound);
1563 
1564   sel = gfx::SelectionModel(3, gfx::CURSOR_BACKWARD);
1565   bound = GetCursorBounds(sel);
1566   sel = gfx::SelectionModel(3, gfx::CURSOR_FORWARD);
1567   EXPECT_EQ(bound.x(), GetCursorBounds(sel).x());
1568   cursor_bounds.push_back(bound);
1569 
1570   sel = gfx::SelectionModel(2, gfx::CURSOR_FORWARD);
1571   bound = GetCursorBounds(sel);
1572   sel = gfx::SelectionModel(4, gfx::CURSOR_FORWARD);
1573   EXPECT_EQ(bound.x(), GetCursorBounds(sel).x());
1574   cursor_bounds.push_back(bound);
1575 
1576   // Expected cursor position when clicking left and right of each character.
1577   size_t cursor_pos_expected[] = {0, 1, 1, 2, 4, 3, 3, 2};
1578 
1579   int index = 0;
1580   for (int i = 0; i < static_cast<int>(cursor_bounds.size() - 1); ++i) {
1581     int half_width = (cursor_bounds[i + 1].x() - cursor_bounds[i].x()) / 2;
1582     MouseClick(cursor_bounds[i], half_width / 2);
1583     EXPECT_EQ(cursor_pos_expected[index++], textfield_->GetCursorPosition());
1584 
1585     // To avoid trigger double click. Not using sleep() since it takes longer
1586     // for the test to run if using sleep().
1587     NonClientMouseClick();
1588 
1589     MouseClick(cursor_bounds[i + 1], - (half_width / 2));
1590     EXPECT_EQ(cursor_pos_expected[index++], textfield_->GetCursorPosition());
1591 
1592     NonClientMouseClick();
1593   }
1594 }
1595 
TEST_F(TextfieldTest,HitOutsideTextAreaTest)1596 TEST_F(TextfieldTest, HitOutsideTextAreaTest) {
1597   InitTextfield();
1598 
1599   // LTR-RTL string in LTR context.
1600   textfield_->SetText(WideToUTF16(L"ab\x05E1\x5E2"));
1601 
1602   SendKeyEvent(ui::VKEY_HOME);
1603   gfx::Rect bound = GetCursorBounds();
1604   MouseClick(bound, -10);
1605   EXPECT_EQ(bound, GetCursorBounds());
1606 
1607   SendKeyEvent(ui::VKEY_END);
1608   bound = GetCursorBounds();
1609   MouseClick(bound, 10);
1610   EXPECT_EQ(bound, GetCursorBounds());
1611 
1612   NonClientMouseClick();
1613 
1614   // RTL-LTR string in LTR context.
1615   textfield_->SetText(WideToUTF16(L"\x05E1\x5E2" L"ab"));
1616 
1617   SendKeyEvent(ui::VKEY_HOME);
1618   bound = GetCursorBounds();
1619   MouseClick(bound, 10);
1620   EXPECT_EQ(bound, GetCursorBounds());
1621 
1622   SendKeyEvent(ui::VKEY_END);
1623   bound = GetCursorBounds();
1624   MouseClick(bound, -10);
1625   EXPECT_EQ(bound, GetCursorBounds());
1626 }
1627 
TEST_F(TextfieldTest,HitOutsideTextAreaInRTLTest)1628 TEST_F(TextfieldTest, HitOutsideTextAreaInRTLTest) {
1629   std::string locale = l10n_util::GetApplicationLocale("");
1630   base::i18n::SetICUDefaultLocale("he");
1631 
1632   InitTextfield();
1633 
1634   // RTL-LTR string in RTL context.
1635   textfield_->SetText(WideToUTF16(L"\x05E1\x5E2" L"ab"));
1636   SendKeyEvent(ui::VKEY_HOME);
1637   gfx::Rect bound = GetCursorBounds();
1638   MouseClick(bound, 10);
1639   EXPECT_EQ(bound, GetCursorBounds());
1640 
1641   SendKeyEvent(ui::VKEY_END);
1642   bound = GetCursorBounds();
1643   MouseClick(bound, -10);
1644   EXPECT_EQ(bound, GetCursorBounds());
1645 
1646   NonClientMouseClick();
1647 
1648   // LTR-RTL string in RTL context.
1649   textfield_->SetText(WideToUTF16(L"ab\x05E1\x5E2"));
1650   SendKeyEvent(ui::VKEY_HOME);
1651   bound = GetCursorBounds();
1652   MouseClick(bound, -10);
1653   EXPECT_EQ(bound, GetCursorBounds());
1654 
1655   SendKeyEvent(ui::VKEY_END);
1656   bound = GetCursorBounds();
1657   MouseClick(bound, 10);
1658   EXPECT_EQ(bound, GetCursorBounds());
1659 
1660   // Reset locale.
1661   base::i18n::SetICUDefaultLocale(locale);
1662 }
1663 
TEST_F(TextfieldTest,OverflowTest)1664 TEST_F(TextfieldTest, OverflowTest) {
1665   InitTextfield();
1666 
1667   base::string16 str;
1668   for (int i = 0; i < 500; ++i)
1669     SendKeyEvent('a');
1670   SendKeyEvent(kHebrewLetterSamekh);
1671   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1672 
1673   // Test mouse pointing.
1674   MouseClick(GetCursorBounds(), -1);
1675   EXPECT_EQ(500U, textfield_->GetCursorPosition());
1676 
1677   // Clear text.
1678   SendKeyEvent(ui::VKEY_A, false, true);
1679   SendKeyEvent('\n');
1680 
1681   for (int i = 0; i < 500; ++i)
1682     SendKeyEvent(kHebrewLetterSamekh);
1683   SendKeyEvent('a');
1684   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1685 
1686   MouseClick(GetCursorBounds(), -1);
1687   EXPECT_EQ(501U, textfield_->GetCursorPosition());
1688 }
1689 
TEST_F(TextfieldTest,OverflowInRTLTest)1690 TEST_F(TextfieldTest, OverflowInRTLTest) {
1691   std::string locale = l10n_util::GetApplicationLocale("");
1692   base::i18n::SetICUDefaultLocale("he");
1693 
1694   InitTextfield();
1695 
1696   base::string16 str;
1697   for (int i = 0; i < 500; ++i)
1698     SendKeyEvent('a');
1699   SendKeyEvent(kHebrewLetterSamekh);
1700   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1701 
1702   MouseClick(GetCursorBounds(), 1);
1703   EXPECT_EQ(501U, textfield_->GetCursorPosition());
1704 
1705   // Clear text.
1706   SendKeyEvent(ui::VKEY_A, false, true);
1707   SendKeyEvent('\n');
1708 
1709   for (int i = 0; i < 500; ++i)
1710     SendKeyEvent(kHebrewLetterSamekh);
1711   SendKeyEvent('a');
1712   EXPECT_TRUE(GetDisplayRect().Contains(GetCursorBounds()));
1713 
1714   MouseClick(GetCursorBounds(), 1);
1715   EXPECT_EQ(500U, textfield_->GetCursorPosition());
1716 
1717   // Reset locale.
1718   base::i18n::SetICUDefaultLocale(locale);
1719 }
1720 
TEST_F(TextfieldTest,GetCompositionCharacterBoundsTest)1721 TEST_F(TextfieldTest, GetCompositionCharacterBoundsTest) {
1722   InitTextfield();
1723   ui::CompositionText composition;
1724   composition.text = UTF8ToUTF16("abc123");
1725   const uint32 char_count = static_cast<uint32>(composition.text.length());
1726   ui::TextInputClient* client = textfield_->GetTextInputClient();
1727 
1728   // Compare the composition character bounds with surrounding cursor bounds.
1729   for (uint32 i = 0; i < char_count; ++i) {
1730     composition.selection = gfx::Range(i);
1731     client->SetCompositionText(composition);
1732     gfx::Point cursor_origin = GetCursorBounds().origin();
1733     views::View::ConvertPointToScreen(textfield_, &cursor_origin);
1734 
1735     composition.selection = gfx::Range(i + 1);
1736     client->SetCompositionText(composition);
1737     gfx::Point next_cursor_bottom_left = GetCursorBounds().bottom_left();
1738     views::View::ConvertPointToScreen(textfield_, &next_cursor_bottom_left);
1739 
1740     gfx::Rect character;
1741     EXPECT_TRUE(client->GetCompositionCharacterBounds(i, &character));
1742     EXPECT_EQ(character.origin(), cursor_origin) << " i=" << i;
1743     EXPECT_EQ(character.bottom_right(), next_cursor_bottom_left) << " i=" << i;
1744   }
1745 
1746   // Return false if the index is out of range.
1747   gfx::Rect rect;
1748   EXPECT_FALSE(client->GetCompositionCharacterBounds(char_count, &rect));
1749   EXPECT_FALSE(client->GetCompositionCharacterBounds(char_count + 1, &rect));
1750   EXPECT_FALSE(client->GetCompositionCharacterBounds(char_count + 100, &rect));
1751 }
1752 
TEST_F(TextfieldTest,GetCompositionCharacterBounds_ComplexText)1753 TEST_F(TextfieldTest, GetCompositionCharacterBounds_ComplexText) {
1754   InitTextfield();
1755 
1756   const base::char16 kUtf16Chars[] = {
1757     // U+0020 SPACE
1758     0x0020,
1759     // U+1F408 (CAT) as surrogate pair
1760     0xd83d, 0xdc08,
1761     // U+5642 as Ideographic Variation Sequences
1762     0x5642, 0xDB40, 0xDD00,
1763     // U+260E (BLACK TELEPHONE) as Emoji Variation Sequences
1764     0x260E, 0xFE0F,
1765     // U+0020 SPACE
1766     0x0020,
1767   };
1768   const size_t kUtf16CharsCount = arraysize(kUtf16Chars);
1769 
1770   ui::CompositionText composition;
1771   composition.text.assign(kUtf16Chars, kUtf16Chars + kUtf16CharsCount);
1772   ui::TextInputClient* client = textfield_->GetTextInputClient();
1773   client->SetCompositionText(composition);
1774 
1775   // Make sure GetCompositionCharacterBounds never fails for index.
1776   gfx::Rect rects[kUtf16CharsCount];
1777   gfx::Rect prev_cursor = GetCursorBounds();
1778   for (uint32 i = 0; i < kUtf16CharsCount; ++i)
1779     EXPECT_TRUE(client->GetCompositionCharacterBounds(i, &rects[i]));
1780 
1781   // Here we might expect the following results but it actually depends on how
1782   // Uniscribe or HarfBuzz treats them with given font.
1783   // - rects[1] == rects[2]
1784   // - rects[3] == rects[4] == rects[5]
1785   // - rects[6] == rects[7]
1786 }
1787 
1788 // The word we select by double clicking should remain selected regardless of
1789 // where we drag the mouse afterwards without releasing the left button.
TEST_F(TextfieldTest,KeepInitiallySelectedWord)1790 TEST_F(TextfieldTest, KeepInitiallySelectedWord) {
1791   InitTextfield();
1792 
1793   textfield_->SetText(ASCIIToUTF16("abc def ghi"));
1794 
1795   textfield_->SelectRange(gfx::Range(5, 5));
1796   const gfx::Rect middle_cursor = GetCursorBounds();
1797   textfield_->SelectRange(gfx::Range(0, 0));
1798   const gfx::Point beginning = GetCursorBounds().origin();
1799 
1800   // Double click, but do not release the left button.
1801   MouseClick(middle_cursor, 0);
1802   const gfx::Point middle(middle_cursor.x(),
1803                           middle_cursor.y() + middle_cursor.height() / 2);
1804   ui::MouseEvent press_event(ui::ET_MOUSE_PRESSED, middle, middle,
1805                              ui::EF_LEFT_MOUSE_BUTTON,
1806                              ui::EF_LEFT_MOUSE_BUTTON);
1807   textfield_->OnMousePressed(press_event);
1808   EXPECT_EQ(gfx::Range(4, 7), textfield_->GetSelectedRange());
1809 
1810   // Drag the mouse to the beginning of the textfield.
1811   ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, beginning, beginning,
1812                             ui::EF_LEFT_MOUSE_BUTTON, 0);
1813   textfield_->OnMouseDragged(drag_event);
1814   EXPECT_EQ(gfx::Range(7, 0), textfield_->GetSelectedRange());
1815 }
1816 
1817 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
1818 // flaky: http://crbug.com/396477
TEST_F(TextfieldTest,DISABLED_SelectionClipboard)1819 TEST_F(TextfieldTest, DISABLED_SelectionClipboard) {
1820   InitTextfield();
1821   textfield_->SetText(ASCIIToUTF16("0123"));
1822   gfx::Point point_1(GetCursorPositionX(1), 0);
1823   gfx::Point point_2(GetCursorPositionX(2), 0);
1824   gfx::Point point_3(GetCursorPositionX(3), 0);
1825   gfx::Point point_4(GetCursorPositionX(4), 0);
1826 
1827   // Text selected by the mouse should be placed on the selection clipboard.
1828   ui::MouseEvent press(ui::ET_MOUSE_PRESSED, point_1, point_1,
1829                        ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1830   textfield_->OnMousePressed(press);
1831   ui::MouseEvent drag(ui::ET_MOUSE_DRAGGED, point_3, point_3,
1832                       ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1833   textfield_->OnMouseDragged(drag);
1834   ui::MouseEvent release(ui::ET_MOUSE_RELEASED, point_3, point_3,
1835                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1836   textfield_->OnMouseReleased(release);
1837   EXPECT_EQ(gfx::Range(1, 3), textfield_->GetSelectedRange());
1838   EXPECT_STR_EQ("12", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1839 
1840   // Select-all should update the selection clipboard.
1841   SendKeyEvent(ui::VKEY_A, false, true);
1842   EXPECT_EQ(gfx::Range(0, 4), textfield_->GetSelectedRange());
1843   EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1844   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1845 
1846   // Shift-click selection modifications should update the clipboard.
1847   NonClientMouseClick();
1848   ui::MouseEvent press_2(ui::ET_MOUSE_PRESSED, point_2, point_2,
1849                          ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1850   press_2.set_flags(press_2.flags() | ui::EF_SHIFT_DOWN);
1851 #if defined(USE_X11)
1852   ui::UpdateX11EventForFlags(&press_2);
1853 #endif
1854   textfield_->OnMousePressed(press_2);
1855   ui::MouseEvent release_2(ui::ET_MOUSE_RELEASED, point_2, point_2,
1856                            ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1857   textfield_->OnMouseReleased(release_2);
1858   EXPECT_EQ(gfx::Range(0, 2), textfield_->GetSelectedRange());
1859   EXPECT_STR_EQ("01", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1860   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1861 
1862   // Shift-Left/Right should update the selection clipboard.
1863   SendKeyEvent(ui::VKEY_RIGHT, true, false);
1864   EXPECT_STR_EQ("012", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1865   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1866   SendKeyEvent(ui::VKEY_LEFT, true, false);
1867   EXPECT_STR_EQ("01", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1868   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1869   SendKeyEvent(ui::VKEY_RIGHT, true, true);
1870   EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1871   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1872 
1873   // Moving the cursor without a selection should not change the clipboard.
1874   SendKeyEvent(ui::VKEY_LEFT, false, false);
1875   EXPECT_EQ(gfx::Range(0, 0), textfield_->GetSelectedRange());
1876   EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1877   EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
1878 
1879   // Middle clicking should paste at the mouse (not cursor) location.
1880   ui::MouseEvent middle(ui::ET_MOUSE_PRESSED, point_4, point_4,
1881                         ui::EF_MIDDLE_MOUSE_BUTTON, ui::EF_MIDDLE_MOUSE_BUTTON);
1882   textfield_->OnMousePressed(middle);
1883   EXPECT_STR_EQ("01230123", textfield_->text());
1884   EXPECT_EQ(gfx::Range(0, 0), textfield_->GetSelectedRange());
1885   EXPECT_STR_EQ("0123", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1886 
1887   // Middle click pasting should adjust trailing cursors.
1888   textfield_->SelectRange(gfx::Range(5, 5));
1889   textfield_->OnMousePressed(middle);
1890   EXPECT_STR_EQ("012301230123", textfield_->text());
1891   EXPECT_EQ(gfx::Range(9, 9), textfield_->GetSelectedRange());
1892 
1893   // Middle click pasting should adjust trailing selections.
1894   textfield_->SelectRange(gfx::Range(7, 9));
1895   textfield_->OnMousePressed(middle);
1896   EXPECT_STR_EQ("0123012301230123", textfield_->text());
1897   EXPECT_EQ(gfx::Range(11, 13), textfield_->GetSelectedRange());
1898 
1899   // Middle clicking in the selection should clear the clipboard and selection.
1900   textfield_->SelectRange(gfx::Range(2, 6));
1901   textfield_->OnMousePressed(middle);
1902   EXPECT_STR_EQ("0123012301230123", textfield_->text());
1903   EXPECT_EQ(gfx::Range(6, 6), textfield_->GetSelectedRange());
1904   EXPECT_TRUE(GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION).empty());
1905 
1906   // Double and triple clicking should update the clipboard contents.
1907   textfield_->SetText(ASCIIToUTF16("ab cd ef"));
1908   gfx::Point word(GetCursorPositionX(4), 0);
1909   ui::MouseEvent press_word(ui::ET_MOUSE_PRESSED, word, word,
1910                             ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
1911   textfield_->OnMousePressed(press_word);
1912   ui::MouseEvent release_word(ui::ET_MOUSE_RELEASED, word, word,
1913                               ui::EF_LEFT_MOUSE_BUTTON,
1914                               ui::EF_LEFT_MOUSE_BUTTON);
1915   textfield_->OnMouseReleased(release_word);
1916   ui::MouseEvent double_click(ui::ET_MOUSE_PRESSED, word, word,
1917                               ui::EF_LEFT_MOUSE_BUTTON | ui::EF_IS_DOUBLE_CLICK,
1918                               ui::EF_LEFT_MOUSE_BUTTON);
1919   textfield_->OnMousePressed(double_click);
1920   textfield_->OnMouseReleased(release_word);
1921   EXPECT_EQ(gfx::Range(3, 5), textfield_->GetSelectedRange());
1922   EXPECT_STR_EQ("cd", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1923   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1924   textfield_->OnMousePressed(press_word);
1925   textfield_->OnMouseReleased(release_word);
1926   EXPECT_EQ(gfx::Range(0, 8), textfield_->GetSelectedRange());
1927   EXPECT_STR_EQ("ab cd ef", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1928   EXPECT_EQ(ui::CLIPBOARD_TYPE_SELECTION, GetAndResetCopiedToClipboard());
1929 
1930   // Selecting a range of text without any user interaction should not change
1931   // the clipboard content.
1932   textfield_->SelectRange(gfx::Range(0, 3));
1933   EXPECT_STR_EQ("ab ", textfield_->GetSelectedText());
1934   EXPECT_STR_EQ("ab cd ef", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1935   EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
1936 
1937   SetClipboardText(ui::CLIPBOARD_TYPE_SELECTION, "other");
1938   textfield_->SelectAll(false);
1939   EXPECT_STR_EQ("other", GetClipboardText(ui::CLIPBOARD_TYPE_SELECTION));
1940   EXPECT_EQ(ui::CLIPBOARD_TYPE_LAST, GetAndResetCopiedToClipboard());
1941 }
1942 #endif
1943 
1944 // Touch selection and dragging currently only works for chromeos.
1945 #if defined(OS_CHROMEOS)
TEST_F(TextfieldTest,TouchSelectionAndDraggingTest)1946 TEST_F(TextfieldTest, TouchSelectionAndDraggingTest) {
1947   InitTextfield();
1948   textfield_->SetText(ASCIIToUTF16("hello world"));
1949   EXPECT_FALSE(test_api_->touch_selection_controller());
1950   const int x = GetCursorPositionX(2);
1951   CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing);
1952 
1953   // Tapping on the textfield should turn on the TouchSelectionController.
1954   ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP);
1955   tap_details.set_tap_count(1);
1956   GestureEventForTest tap(x, 0, tap_details);
1957   textfield_->OnGestureEvent(&tap);
1958   EXPECT_TRUE(test_api_->touch_selection_controller());
1959 
1960   // Un-focusing the textfield should reset the TouchSelectionController
1961   textfield_->GetFocusManager()->ClearFocus();
1962   EXPECT_FALSE(test_api_->touch_selection_controller());
1963   textfield_->RequestFocus();
1964 
1965   // With touch editing enabled, long press should not show context menu.
1966   // Instead, select word and invoke TouchSelectionController.
1967   GestureEventForTest long_press_1(
1968       x, 0, ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
1969   textfield_->OnGestureEvent(&long_press_1);
1970   EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
1971   EXPECT_TRUE(test_api_->touch_selection_controller());
1972   EXPECT_TRUE(long_press_1.handled());
1973 
1974   // With touch drag drop enabled, long pressing in the selected region should
1975   // start a drag and remove TouchSelectionController.
1976   ASSERT_TRUE(switches::IsTouchDragDropEnabled());
1977   GestureEventForTest long_press_2(
1978       x, 0, ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
1979   textfield_->OnGestureEvent(&long_press_2);
1980   EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
1981   EXPECT_FALSE(test_api_->touch_selection_controller());
1982   EXPECT_FALSE(long_press_2.handled());
1983 
1984   // After disabling touch drag drop, long pressing again in the selection
1985   // region should not do anything.
1986   CommandLine::ForCurrentProcess()->AppendSwitch(
1987       switches::kDisableTouchDragDrop);
1988   ASSERT_FALSE(switches::IsTouchDragDropEnabled());
1989   GestureEventForTest long_press_3(
1990       x, 0, ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
1991   textfield_->OnGestureEvent(&long_press_3);
1992   EXPECT_STR_EQ("hello", textfield_->GetSelectedText());
1993   EXPECT_FALSE(test_api_->touch_selection_controller());
1994   EXPECT_FALSE(long_press_3.handled());
1995 }
1996 #endif
1997 
TEST_F(TextfieldTest,TouchSelectionInUnfocusableTextfield)1998 TEST_F(TextfieldTest, TouchSelectionInUnfocusableTextfield) {
1999   CommandLine::ForCurrentProcess()->AppendSwitch(switches::kEnableTouchEditing);
2000 
2001   InitTextfield();
2002   textfield_->SetText(ASCIIToUTF16("hello world"));
2003   gfx::Point touch_point(GetCursorPositionX(2), 0);
2004 
2005   // Disable textfield and tap on it. Touch text selection should not get
2006   // activated.
2007   textfield_->SetEnabled(false);
2008   Tap(touch_point);
2009   EXPECT_FALSE(test_api_->touch_selection_controller());
2010   textfield_->SetEnabled(true);
2011 
2012   // Make textfield unfocusable and tap on it. Touch text selection should not
2013   // get activated.
2014   textfield_->SetFocusable(false);
2015   Tap(touch_point);
2016   EXPECT_FALSE(textfield_->HasFocus());
2017   EXPECT_FALSE(test_api_->touch_selection_controller());
2018   textfield_->SetFocusable(true);
2019 }
2020 
2021 // Long_Press gesture in Textfield can initiate a drag and drop now.
TEST_F(TextfieldTest,TestLongPressInitiatesDragDrop)2022 TEST_F(TextfieldTest, TestLongPressInitiatesDragDrop) {
2023   InitTextfield();
2024   textfield_->SetText(ASCIIToUTF16("Hello string world"));
2025 
2026   // Ensure the textfield will provide selected text for drag data.
2027   textfield_->SelectRange(gfx::Range(6, 12));
2028   const gfx::Point kStringPoint(GetCursorPositionX(9), 0);
2029 
2030   // Enable touch-drag-drop to make long press effective.
2031   CommandLine::ForCurrentProcess()->AppendSwitch(
2032       switches::kEnableTouchDragDrop);
2033 
2034   // Create a long press event in the selected region should start a drag.
2035   GestureEventForTest long_press(
2036       kStringPoint.x(),
2037       kStringPoint.y(),
2038       ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS));
2039   textfield_->OnGestureEvent(&long_press);
2040   EXPECT_TRUE(textfield_->CanStartDragForView(NULL, kStringPoint,
2041                                               kStringPoint));
2042 }
2043 
TEST_F(TextfieldTest,GetTextfieldBaseline_FontFallbackTest)2044 TEST_F(TextfieldTest, GetTextfieldBaseline_FontFallbackTest) {
2045   InitTextfield();
2046   textfield_->SetText(UTF8ToUTF16("abc"));
2047   const int old_baseline = textfield_->GetBaseline();
2048 
2049   // Set text which may fall back to a font which has taller baseline than
2050   // the default font.
2051   textfield_->SetText(UTF8ToUTF16("\xE0\xB9\x91"));
2052   const int new_baseline = textfield_->GetBaseline();
2053 
2054   // Regardless of the text, the baseline must be the same.
2055   EXPECT_EQ(new_baseline, old_baseline);
2056 }
2057 
2058 // Tests that a textfield view can be destroyed from OnKeyEvent() on its
2059 // controller and it does not crash.
TEST_F(TextfieldTest,DestroyingTextfieldFromOnKeyEvent)2060 TEST_F(TextfieldTest, DestroyingTextfieldFromOnKeyEvent) {
2061   InitTextfield();
2062 
2063   // The controller assumes ownership of the textfield.
2064   TextfieldDestroyerController controller(textfield_);
2065   EXPECT_TRUE(controller.target());
2066 
2067   // Send a key to trigger OnKeyEvent().
2068   SendKeyEvent('X');
2069 
2070   EXPECT_FALSE(controller.target());
2071 }
2072 
2073 }  // namespace views
2074