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

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

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

Powered by Google App Engine
This is Rietveld 408576698