Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1049)

Side by Side Diff: ui/views/controls/textfield/native_textfield_views_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698