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

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

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