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