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