Home | History | Annotate | Download | only in touchui
      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 "base/command_line.h"
      6 #include "base/strings/utf_string_conversions.h"
      7 #include "grit/ui_resources.h"
      8 #include "ui/base/resource/resource_bundle.h"
      9 #include "ui/base/touch/touch_editing_controller.h"
     10 #include "ui/base/ui_base_switches.h"
     11 #include "ui/gfx/point.h"
     12 #include "ui/gfx/rect.h"
     13 #include "ui/gfx/render_text.h"
     14 #include "ui/views/controls/textfield/native_textfield_views.h"
     15 #include "ui/views/controls/textfield/textfield.h"
     16 #include "ui/views/test/views_test_base.h"
     17 #include "ui/views/touchui/touch_selection_controller_impl.h"
     18 #include "ui/views/widget/widget.h"
     19 
     20 #if defined(USE_AURA)
     21 #include "ui/aura/test/event_generator.h"
     22 #include "ui/aura/window.h"
     23 #endif
     24 
     25 namespace {
     26 // Should match kSelectionHandlePadding in touch_selection_controller.
     27 const int kPadding = 10;
     28 
     29 gfx::Image* GetHandleImage() {
     30   static gfx::Image* handle_image = NULL;
     31   if (!handle_image) {
     32     handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
     33         IDR_TEXT_SELECTION_HANDLE);
     34   }
     35   return handle_image;
     36 }
     37 
     38 gfx::Size GetHandleImageSize() {
     39   return GetHandleImage()->Size();
     40 }
     41 }  // namespace
     42 
     43 namespace views {
     44 
     45 class TouchSelectionControllerImplTest : public ViewsTestBase {
     46  public:
     47   TouchSelectionControllerImplTest()
     48       : widget_(NULL),
     49         textfield_(NULL),
     50         textfield_view_(NULL),
     51         views_tsc_factory_(new ViewsTouchSelectionControllerFactory) {
     52     CommandLine::ForCurrentProcess()->AppendSwitch(
     53         switches::kEnableTouchEditing);
     54     ui::TouchSelectionControllerFactory::SetInstance(views_tsc_factory_.get());
     55   }
     56 
     57   virtual ~TouchSelectionControllerImplTest() {
     58     ui::TouchSelectionControllerFactory::SetInstance(NULL);
     59   }
     60 
     61   virtual void TearDown() {
     62     if (widget_)
     63       widget_->Close();
     64     ViewsTestBase::TearDown();
     65   }
     66 
     67   void CreateTextfield() {
     68     textfield_ = new Textfield();
     69     widget_ = new Widget;
     70     Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
     71     params.bounds = gfx::Rect(0, 0, 200, 200);
     72     widget_->Init(params);
     73     View* container = new View();
     74     widget_->SetContentsView(container);
     75     container->AddChildView(textfield_);
     76 
     77     textfield_view_ = static_cast<NativeTextfieldViews*>(
     78         textfield_->GetNativeWrapperForTesting());
     79     textfield_->SetBoundsRect(params.bounds);
     80     textfield_view_->SetBoundsRect(params.bounds);
     81     textfield_->set_id(1);
     82     widget_->Show();
     83 
     84     DCHECK(textfield_view_);
     85     textfield_->RequestFocus();
     86   }
     87 
     88  protected:
     89   gfx::Point GetCursorPosition(const gfx::SelectionModel& sel) {
     90     gfx::RenderText* render_text = textfield_view_->GetRenderText();
     91     gfx::Rect cursor_bounds = render_text->GetCursorBounds(sel, true);
     92     return gfx::Point(cursor_bounds.x(), cursor_bounds.y());
     93   }
     94 
     95   TouchSelectionControllerImpl* GetSelectionController() {
     96     return static_cast<TouchSelectionControllerImpl*>(
     97         textfield_view_->touch_selection_controller_.get());
     98   }
     99 
    100   void SimulateSelectionHandleDrag(gfx::Point p, int selection_handle) {
    101     TouchSelectionControllerImpl* controller = GetSelectionController();
    102     // Do the work of OnMousePressed().
    103     if (selection_handle == 1)
    104       controller->SetDraggingHandle(controller->selection_handle_1_.get());
    105     else
    106       controller->SetDraggingHandle(controller->selection_handle_2_.get());
    107 
    108     // Offset the drag position by the selection handle radius since it is
    109     // supposed to be in the coordinate system of the handle.
    110     p.Offset(GetHandleImageSize().width() / 2 + kPadding, 0);
    111     controller->SelectionHandleDragged(p);
    112 
    113     // Do the work of OnMouseReleased().
    114     controller->dragging_handle_ = NULL;
    115   }
    116 
    117   gfx::Point GetSelectionHandle1Position() {
    118     return GetSelectionController()->GetSelectionHandle1Position();
    119   }
    120 
    121   gfx::Point GetSelectionHandle2Position() {
    122     return GetSelectionController()->GetSelectionHandle2Position();
    123   }
    124 
    125   gfx::Point GetCursorHandlePosition() {
    126     return GetSelectionController()->GetCursorHandlePosition();
    127   }
    128 
    129   bool IsSelectionHandle1Visible() {
    130     return GetSelectionController()->IsSelectionHandle1Visible();
    131   }
    132 
    133   bool IsSelectionHandle2Visible() {
    134     return GetSelectionController()->IsSelectionHandle2Visible();
    135   }
    136 
    137   bool IsCursorHandleVisible() {
    138     return GetSelectionController()->IsCursorHandleVisible();
    139   }
    140 
    141   gfx::RenderText* GetRenderText() {
    142     return textfield_view_->GetRenderText();
    143   }
    144 
    145   Widget* widget_;
    146 
    147   Textfield* textfield_;
    148   NativeTextfieldViews* textfield_view_;
    149   scoped_ptr<ViewsTouchSelectionControllerFactory> views_tsc_factory_;
    150 
    151  private:
    152   DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest);
    153 };
    154 
    155 // If textfield has selection, this macro verifies that the selection handles
    156 // are visible and at the correct positions (at the end points of selection).
    157 // |cursor_at_selection_handle_1| is used to decide whether selection
    158 // handle 1's position is matched against the start of selection or the end.
    159 #define VERIFY_HANDLE_POSITIONS(cursor_at_selection_handle_1)                  \
    160 {                                                                              \
    161     gfx::SelectionModel sel = textfield_view_->GetSelectionModel();            \
    162     if (textfield_->HasSelection()) {                                          \
    163       EXPECT_TRUE(IsSelectionHandle1Visible());                                \
    164       EXPECT_TRUE(IsSelectionHandle2Visible());                                \
    165       EXPECT_FALSE(IsCursorHandleVisible());                                   \
    166       gfx::SelectionModel sel_start = GetRenderText()->                        \
    167                                       GetSelectionModelForSelectionStart();    \
    168       gfx::Point selection_start = GetCursorPosition(sel_start);               \
    169       gfx::Point selection_end = GetCursorPosition(sel);                       \
    170       gfx::Point sh1 = GetSelectionHandle1Position();                          \
    171       gfx::Point sh2 = GetSelectionHandle2Position();                          \
    172       sh1.Offset(GetHandleImageSize().width() / 2 + kPadding, 0);              \
    173       sh2.Offset(GetHandleImageSize().width() / 2 + kPadding, 0);              \
    174       if (cursor_at_selection_handle_1) {                                      \
    175         EXPECT_EQ(sh1, selection_end);                                         \
    176         EXPECT_EQ(sh2, selection_start);                                       \
    177       } else {                                                                 \
    178         EXPECT_EQ(sh1, selection_start);                                       \
    179         EXPECT_EQ(sh2, selection_end);                                         \
    180       }                                                                        \
    181     } else {                                                                   \
    182       EXPECT_FALSE(IsSelectionHandle1Visible());                               \
    183       EXPECT_FALSE(IsSelectionHandle2Visible());                               \
    184       EXPECT_TRUE(IsCursorHandleVisible());                                    \
    185       gfx::Point cursor_pos = GetCursorPosition(sel);                          \
    186       gfx::Point ch_pos = GetCursorHandlePosition();                           \
    187       ch_pos.Offset(GetHandleImageSize().width() / 2 + kPadding, 0);           \
    188       EXPECT_EQ(ch_pos, cursor_pos);                                           \
    189     }                                                                          \
    190 }
    191 
    192 // Tests that the selection handles are placed appropriately when selection in
    193 // a Textfield changes.
    194 TEST_F(TouchSelectionControllerImplTest, SelectionInTextfieldTest) {
    195   CreateTextfield();
    196   textfield_->SetText(ASCIIToUTF16("some text"));
    197   // Tap the textfield to invoke touch selection.
    198   ui::GestureEvent tap(ui::ET_GESTURE_TAP, 0, 0, 0, base::TimeDelta(),
    199       ui::GestureEventDetails(ui::ET_GESTURE_TAP, 1.0f, 0.0f), 0);
    200   textfield_view_->OnGestureEvent(&tap);
    201 
    202   // Test selecting a range.
    203   textfield_->SelectRange(gfx::Range(3, 7));
    204   VERIFY_HANDLE_POSITIONS(false);
    205 
    206   // Test selecting everything.
    207   textfield_->SelectAll(false);
    208   VERIFY_HANDLE_POSITIONS(false);
    209 
    210   // Test with no selection.
    211   textfield_->ClearSelection();
    212   VERIFY_HANDLE_POSITIONS(false);
    213 
    214   // Test with lost focus.
    215   widget_->GetFocusManager()->ClearFocus();
    216   EXPECT_FALSE(GetSelectionController());
    217 
    218   // Test with focus re-gained.
    219   widget_->GetFocusManager()->SetFocusedView(textfield_);
    220   EXPECT_FALSE(GetSelectionController());
    221   textfield_view_->OnGestureEvent(&tap);
    222   VERIFY_HANDLE_POSITIONS(false);
    223 }
    224 
    225 // Tests that the selection handles are placed appropriately in bidi text.
    226 TEST_F(TouchSelectionControllerImplTest, SelectionInBidiTextfieldTest) {
    227   CreateTextfield();
    228   textfield_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2"));
    229   // Tap the textfield to invoke touch selection.
    230   ui::GestureEvent tap(ui::ET_GESTURE_TAP, 0, 0, 0, base::TimeDelta(),
    231       ui::GestureEventDetails(ui::ET_GESTURE_TAP, 1.0f, 0.0f), 0);
    232   textfield_view_->OnGestureEvent(&tap);
    233 
    234   // Test cursor at run boundary and with empty selection.
    235   textfield_->SelectSelectionModel(
    236       gfx::SelectionModel(3, gfx::CURSOR_BACKWARD));
    237   VERIFY_HANDLE_POSITIONS(false);
    238 
    239   // Test selection range inside one run and starts or ends at run boundary.
    240   textfield_->SelectRange(gfx::Range(2, 3));
    241   VERIFY_HANDLE_POSITIONS(false);
    242 
    243   textfield_->SelectRange(gfx::Range(3, 2));
    244   VERIFY_HANDLE_POSITIONS(false);
    245 
    246   textfield_->SelectRange(gfx::Range(3, 4));
    247   VERIFY_HANDLE_POSITIONS(false);
    248 
    249   textfield_->SelectRange(gfx::Range(4, 3));
    250   VERIFY_HANDLE_POSITIONS(false);
    251 
    252   textfield_->SelectRange(gfx::Range(3, 6));
    253   VERIFY_HANDLE_POSITIONS(false);
    254 
    255   textfield_->SelectRange(gfx::Range(6, 3));
    256   VERIFY_HANDLE_POSITIONS(false);
    257 
    258   // Test selection range accross runs.
    259   textfield_->SelectRange(gfx::Range(0, 6));
    260   VERIFY_HANDLE_POSITIONS(false);
    261 
    262   textfield_->SelectRange(gfx::Range(6, 0));
    263   VERIFY_HANDLE_POSITIONS(false);
    264 
    265   textfield_->SelectRange(gfx::Range(1, 4));
    266   VERIFY_HANDLE_POSITIONS(false);
    267 
    268   textfield_->SelectRange(gfx::Range(4, 1));
    269   VERIFY_HANDLE_POSITIONS(false);
    270 }
    271 
    272 // Tests if the SelectRect callback is called appropriately when selection
    273 // handles are moved.
    274 TEST_F(TouchSelectionControllerImplTest, SelectRectCallbackTest) {
    275   CreateTextfield();
    276   textfield_->SetText(ASCIIToUTF16("textfield with selected text"));
    277   // Tap the textfield to invoke touch selection.
    278   ui::GestureEvent tap(ui::ET_GESTURE_TAP, 0, 0, 0, base::TimeDelta(),
    279       ui::GestureEventDetails(ui::ET_GESTURE_TAP, 1.0f, 0.0f), 0);
    280   textfield_view_->OnGestureEvent(&tap);
    281   textfield_->SelectRange(gfx::Range(3, 7));
    282 
    283   EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfie");
    284   VERIFY_HANDLE_POSITIONS(false);
    285 
    286   // Drag selection handle 2 to right by 3 chars.
    287   const gfx::Font& font = textfield_->GetPrimaryFont();
    288   int x = font.GetStringWidth(ASCIIToUTF16("ld "));
    289   SimulateSelectionHandleDrag(gfx::Point(x, 0), 2);
    290   EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfield ");
    291   VERIFY_HANDLE_POSITIONS(false);
    292 
    293   // Drag selection handle 1 to the left by a large amount (selection should
    294   // just stick to the beginning of the textfield).
    295   SimulateSelectionHandleDrag(gfx::Point(-50, 0), 1);
    296   EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "textfield ");
    297   VERIFY_HANDLE_POSITIONS(true);
    298 
    299   // Drag selection handle 1 across selection handle 2.
    300   x = font.GetStringWidth(ASCIIToUTF16("textfield with "));
    301   SimulateSelectionHandleDrag(gfx::Point(x, 0), 1);
    302   EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "with ");
    303   VERIFY_HANDLE_POSITIONS(true);
    304 
    305   // Drag selection handle 2 across selection handle 1.
    306   x = font.GetStringWidth(ASCIIToUTF16("with selected "));
    307   SimulateSelectionHandleDrag(gfx::Point(x, 0), 2);
    308   EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "selected ");
    309   VERIFY_HANDLE_POSITIONS(false);
    310 }
    311 
    312 TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) {
    313   CreateTextfield();
    314   textfield_->SetText(WideToUTF16(L"abc\x05e1\x05e2\x05e3" L"def"));
    315   // Tap the textfield to invoke touch selection.
    316   ui::GestureEvent tap(ui::ET_GESTURE_TAP, 0, 0, 0, base::TimeDelta(),
    317       ui::GestureEventDetails(ui::ET_GESTURE_TAP, 1.0f, 0.0f), 0);
    318   textfield_view_->OnGestureEvent(&tap);
    319 
    320   // Select [c] from left to right.
    321   textfield_->SelectRange(gfx::Range(2, 3));
    322   EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
    323   VERIFY_HANDLE_POSITIONS(false);
    324 
    325   // Drag selection handle 2 to right by 1 char.
    326   const gfx::Font& font = textfield_->GetPrimaryFont();
    327   int x = font.GetStringWidth(WideToUTF16(L"\x05e3"));
    328   SimulateSelectionHandleDrag(gfx::Point(x, 0), 2);
    329   EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
    330   VERIFY_HANDLE_POSITIONS(false);
    331 
    332   // Drag selection handle 1 to left by 1 char.
    333   x = font.GetStringWidth(WideToUTF16(L"b"));
    334   SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1);
    335   EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText());
    336   VERIFY_HANDLE_POSITIONS(true);
    337 
    338   // Select [c] from right to left.
    339   textfield_->SelectRange(gfx::Range(3, 2));
    340   EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
    341   VERIFY_HANDLE_POSITIONS(false);
    342 
    343   // Drag selection handle 1 to right by 1 char.
    344   x = font.GetStringWidth(WideToUTF16(L"\x05e3"));
    345   SimulateSelectionHandleDrag(gfx::Point(x, 0), 1);
    346   EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
    347   VERIFY_HANDLE_POSITIONS(true);
    348 
    349   // Drag selection handle 2 to left by 1 char.
    350   x = font.GetStringWidth(WideToUTF16(L"b"));
    351   SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2);
    352   EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText());
    353   VERIFY_HANDLE_POSITIONS(false);
    354 
    355   // Select [\x5e1] from right to left.
    356   textfield_->SelectRange(gfx::Range(3, 4));
    357   EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
    358   VERIFY_HANDLE_POSITIONS(false);
    359 
    360   /* TODO(xji): for bidi text "abcDEF" whose display is "abcFEDhij", when click
    361      right of 'D' and select [D] then move the left selection handle to left
    362      by one character, it should select [ED], instead it selects [F].
    363      Reason: click right of 'D' and left of 'h' return the same x-axis position,
    364      pass this position to FindCursorPosition() returns index of 'h'. which
    365      means the selection start changed from 3 to 6.
    366      Need further investigation on whether this is a bug in Pango and how to
    367      work around it.
    368   // Drag selection handle 2 to left by 1 char.
    369   x = font.GetStringWidth(WideToUTF16(L"\x05e2"));
    370   SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2);
    371   EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText());
    372   VERIFY_HANDLE_POSITIONS(false);
    373   */
    374 
    375   // Drag selection handle 1 to right by 1 char.
    376   x = font.GetStringWidth(WideToUTF16(L"d"));
    377   SimulateSelectionHandleDrag(gfx::Point(x, 0), 1);
    378   EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText());
    379   VERIFY_HANDLE_POSITIONS(true);
    380 
    381   // Select [\x5e1] from left to right.
    382   textfield_->SelectRange(gfx::Range(4, 3));
    383   EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
    384   VERIFY_HANDLE_POSITIONS(false);
    385 
    386   /* TODO(xji): see detail of above commented out test case.
    387   // Drag selection handle 1 to left by 1 char.
    388   x = font.GetStringWidth(WideToUTF16(L"\x05e2"));
    389   SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1);
    390   EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText());
    391   VERIFY_HANDLE_POSITIONS(true);
    392   */
    393 
    394   // Drag selection handle 2 to right by 1 char.
    395   x = font.GetStringWidth(WideToUTF16(L"d"));
    396   SimulateSelectionHandleDrag(gfx::Point(x, 0), 2);
    397   EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText());
    398   VERIFY_HANDLE_POSITIONS(false);
    399 
    400   // Select [\x05r3] from right to left.
    401   textfield_->SelectRange(gfx::Range(5, 6));
    402   EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
    403   VERIFY_HANDLE_POSITIONS(false);
    404 
    405   // Drag selection handle 2 to left by 1 char.
    406   x = font.GetStringWidth(WideToUTF16(L"c"));
    407   SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2);
    408   EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
    409   VERIFY_HANDLE_POSITIONS(false);
    410 
    411   // Drag selection handle 1 to right by 1 char.
    412   x = font.GetStringWidth(WideToUTF16(L"\x05e2"));
    413   SimulateSelectionHandleDrag(gfx::Point(x, 0), 1);
    414   EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
    415   VERIFY_HANDLE_POSITIONS(true);
    416 
    417   // Select [\x05r3] from left to right.
    418   textfield_->SelectRange(gfx::Range(6, 5));
    419   EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
    420   VERIFY_HANDLE_POSITIONS(false);
    421 
    422   // Drag selection handle 1 to left by 1 char.
    423   x = font.GetStringWidth(WideToUTF16(L"c"));
    424   SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1);
    425   EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
    426   VERIFY_HANDLE_POSITIONS(true);
    427 
    428   // Drag selection handle 2 to right by 1 char.
    429   x = font.GetStringWidth(WideToUTF16(L"\x05e2"));
    430   SimulateSelectionHandleDrag(gfx::Point(x, 0), 2);
    431   EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
    432   VERIFY_HANDLE_POSITIONS(false);
    433 }
    434 
    435 TEST_F(TouchSelectionControllerImplTest,
    436        HiddenSelectionHandleRetainsCursorPosition) {
    437   // Create a textfield with lots of text in it.
    438   CreateTextfield();
    439   std::string textfield_text("some text");
    440   for (int i = 0; i < 10; ++i)
    441     textfield_text += textfield_text;
    442   textfield_->SetText(ASCIIToUTF16(textfield_text));
    443 
    444   // Tap the textfield to invoke selection.
    445   ui::GestureEvent tap(ui::ET_GESTURE_TAP, 0, 0, 0, base::TimeDelta(),
    446       ui::GestureEventDetails(ui::ET_GESTURE_TAP, 1.0f, 0.0f), 0);
    447   textfield_view_->OnGestureEvent(&tap);
    448 
    449   // Select some text such that one handle is hidden.
    450   textfield_->SelectRange(gfx::Range(10, textfield_text.length()));
    451 
    452   // Check that one selection handle is hidden.
    453   EXPECT_FALSE(IsSelectionHandle1Visible());
    454   EXPECT_TRUE(IsSelectionHandle2Visible());
    455   EXPECT_EQ(gfx::Range(10, textfield_text.length()),
    456             textfield_->GetSelectedRange());
    457 
    458   // Drag the visible handle around and make sure the selection end point of the
    459   // invisible handle does not change.
    460   size_t visible_handle_position = textfield_->GetSelectedRange().end();
    461   for (int i = 0; i < 10; ++i) {
    462     SimulateSelectionHandleDrag(gfx::Point(-10, 0), 2);
    463     // Make sure that the visible handle is being dragged.
    464     EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end());
    465     visible_handle_position = textfield_->GetSelectedRange().end();
    466     EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start());
    467   }
    468 }
    469 
    470 #if defined(USE_AURA)
    471 TEST_F(TouchSelectionControllerImplTest,
    472        DoubleTapInTextfieldWithCursorHandleShouldSelectWord) {
    473   CreateTextfield();
    474   textfield_->SetText(ASCIIToUTF16("some text"));
    475   aura::test::EventGenerator generator(
    476       textfield_->GetWidget()->GetNativeView()->GetRootWindow());
    477 
    478   // Tap the textfield to invoke touch selection.
    479   generator.GestureTapAt(gfx::Point(10, 10));
    480 
    481   // Cursor handle should be visible.
    482   EXPECT_FALSE(textfield_->HasSelection());
    483   VERIFY_HANDLE_POSITIONS(false);
    484 
    485   // Double tap on the cursor handle position. We want to check that the cursor
    486   // handle is not eating the event and that the event is falling through to the
    487   // textfield.
    488   gfx::Point cursor_pos = GetCursorHandlePosition();
    489   cursor_pos.Offset(GetHandleImageSize().width() / 2 + kPadding, 0);
    490   generator.GestureTapAt(cursor_pos);
    491   generator.GestureTapAt(cursor_pos);
    492   EXPECT_TRUE(textfield_->HasSelection());
    493   VERIFY_HANDLE_POSITIONS(false);
    494 }
    495 #endif
    496 
    497 }  // namespace views
    498