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
48using base::ASCIIToUTF16;
49using base::UTF8ToUTF16;
50using base::WideToUTF16;
51
52#define EXPECT_STR_EQ(ascii, utf16) EXPECT_EQ(ASCIIToUTF16(ascii), utf16)
53
54namespace {
55
56const base::char16 kHebrewLetterSamekh = 0x05E1;
57
58// A Textfield wrapper to intercept OnKey[Pressed|Released]() ressults.
59class TestTextfield : public views::Textfield {
60 public:
61  TestTextfield()
62     : Textfield(),
63       key_handled_(false),
64       key_received_(false),
65       weak_ptr_factory_(this) {}
66
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
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
89  bool key_handled() const { return key_handled_; }
90  bool key_received() const { return key_received_; }
91
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.
104class GestureEventForTest : public ui::GestureEvent {
105 public:
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.
115class TextfieldDestroyerController : public views::TextfieldController {
116 public:
117  explicit TextfieldDestroyerController(views::Textfield* target)
118      : target_(target) {
119    target_->set_controller(this);
120  }
121
122  views::Textfield* target() { return target_.get(); }
123
124  // views::TextfieldController:
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
135base::string16 GetClipboardText(ui::ClipboardType type) {
136  base::string16 text;
137  ui::Clipboard::GetForCurrentThread()->ReadText(type, &text);
138  return text;
139}
140
141void SetClipboardText(ui::ClipboardType type, const std::string& text) {
142  ui::ScopedClipboardWriter(type).WriteText(ASCIIToUTF16(text));
143}
144
145}  // namespace
146
147namespace views {
148
149class TextfieldTest : public ViewsTestBase, public TextfieldController {
150 public:
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:
162  virtual void SetUp() {
163    ViewsTestBase::SetUp();
164  }
165
166  virtual void TearDown() {
167    if (widget_)
168      widget_->Close();
169    ViewsTestBase::TearDown();
170  }
171
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:
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
187  virtual void OnBeforeUserAction(Textfield* sender) OVERRIDE {
188    ++on_before_user_action_;
189  }
190
191  virtual void OnAfterUserAction(Textfield* sender) OVERRIDE {
192    ++on_after_user_action_;
193  }
194
195  virtual void OnAfterCutOrCopy(ui::ClipboardType clipboard_type) OVERRIDE {
196    copied_to_clipboard_ = clipboard_type;
197  }
198
199  void InitTextfield() {
200    InitTextfields(1);
201  }
202
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
235  ui::MenuModel* GetContextMenuModel() {
236    test_api_->UpdateContextMenu();
237    return test_api_->context_menu_contents();
238  }
239
240 protected:
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
254  void SendKeyEvent(ui::KeyboardCode key_code, bool shift, bool control) {
255    SendKeyEvent(key_code, false, shift, control, false);
256  }
257
258  void SendKeyEvent(ui::KeyboardCode key_code) {
259    SendKeyEvent(key_code, false, false);
260  }
261
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
274  View* GetFocusedView() {
275    return widget_->GetFocusManager()->GetFocusedView();
276  }
277
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.
284  gfx::Rect GetCursorBounds() {
285    return test_api_->GetRenderText()->GetUpdatedCursorBounds();
286  }
287
288  // Get the cursor bounds of |sel|.
289  gfx::Rect GetCursorBounds(const gfx::SelectionModel& sel) {
290    return test_api_->GetRenderText()->GetCursorBounds(sel, true);
291  }
292
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.
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.
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.
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
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
386TEST_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
409TEST_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
423TEST_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
458TEST_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
510TEST_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
548TEST_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
575TEST_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.
623TEST_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
669TEST_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
719TEST_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
755TEST_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
778TEST_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
809TEST_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)
847TEST_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
899TEST_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
946TEST_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
999TEST_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
1052TEST_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
1082TEST_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
1148TEST_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
1247TEST_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
1341TEST_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
1421TEST_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
1431TEST_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
1483TEST_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
1541TEST_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
1596TEST_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
1628TEST_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
1664TEST_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
1690TEST_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
1721TEST_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
1753TEST_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.
1790TEST_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
1819TEST_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)
1946TEST_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
1998TEST_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.
2022TEST_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
2044TEST_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.
2060TEST_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