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