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

Side by Side Diff: ui/views/touchui/touch_selection_controller_impl_unittest.cc

Issue 700563002: Implementing directional text selection handles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@new_assets_text
Patch Set: Addressing review feedback. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/command_line.h" 5 #include "base/command_line.h"
6 #include "base/strings/utf_string_conversions.h" 6 #include "base/strings/utf_string_conversions.h"
7 #include "ui/aura/client/screen_position_client.h" 7 #include "ui/aura/client/screen_position_client.h"
8 #include "ui/aura/test/test_cursor_client.h"
8 #include "ui/aura/window.h" 9 #include "ui/aura/window.h"
9 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/base/touch/touch_editing_controller.h" 11 #include "ui/base/touch/touch_editing_controller.h"
11 #include "ui/base/ui_base_switches.h" 12 #include "ui/base/ui_base_switches.h"
12 #include "ui/events/test/event_generator.h" 13 #include "ui/events/test/event_generator.h"
13 #include "ui/gfx/canvas.h" 14 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/point.h" 15 #include "ui/gfx/point.h"
15 #include "ui/gfx/rect.h" 16 #include "ui/gfx/rect.h"
16 #include "ui/gfx/render_text.h" 17 #include "ui/gfx/render_text.h"
17 #include "ui/resources/grit/ui_resources.h" 18 #include "ui/resources/grit/ui_resources.h"
18 #include "ui/views/controls/textfield/textfield.h" 19 #include "ui/views/controls/textfield/textfield.h"
19 #include "ui/views/controls/textfield/textfield_test_api.h" 20 #include "ui/views/controls/textfield/textfield_test_api.h"
20 #include "ui/views/test/views_test_base.h" 21 #include "ui/views/test/views_test_base.h"
21 #include "ui/views/touchui/touch_selection_controller_impl.h" 22 #include "ui/views/touchui/touch_selection_controller_impl.h"
22 #include "ui/views/views_touch_selection_controller_factory.h" 23 #include "ui/views/views_touch_selection_controller_factory.h"
23 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
25 #include "ui/wm/core/default_screen_position_client.h"
24 26
25 using base::ASCIIToUTF16; 27 using base::ASCIIToUTF16;
26 using base::UTF16ToUTF8; 28 using base::UTF16ToUTF8;
27 using base::WideToUTF16; 29 using base::WideToUTF16;
28 30
29 namespace { 31 namespace {
30 // Should match kSelectionHandlePadding in touch_selection_controller.
31 const int kPadding = 10;
32
33 // Should match kSelectionHandleBarMinHeight in touch_selection_controller. 32 // Should match kSelectionHandleBarMinHeight in touch_selection_controller.
34 const int kBarMinHeight = 5; 33 const int kBarMinHeight = 5;
35 34
36 // Should match kSelectionHandleBarBottomAllowance in 35 // Should match kSelectionHandleBarBottomAllowance in
37 // touch_selection_controller. 36 // touch_selection_controller.
38 const int kBarBottomAllowance = 3; 37 const int kBarBottomAllowance = 3;
39 38
40 // Should match kMenuButtonWidth in touch_editing_menu. 39 // Should match kMenuButtonWidth in touch_editing_menu.
41 const int kMenuButtonWidth = 63; 40 const int kMenuButtonWidth = 63;
42 41
43 // Should match size of kMenuCommands array in touch_editing_menu. 42 // Should match size of kMenuCommands array in touch_editing_menu.
44 const int kMenuCommandCount = 3; 43 const int kMenuCommandCount = 3;
45 44
46 gfx::Image* GetHandleImage() {
47 static gfx::Image* handle_image = NULL;
48 if (!handle_image) {
49 handle_image = &ui::ResourceBundle::GetSharedInstance().GetImageNamed(
50 IDR_TEXT_SELECTION_HANDLE);
51 }
52 return handle_image;
53 }
54
55 gfx::Size GetHandleImageSize() {
56 return GetHandleImage()->Size();
57 }
58 } // namespace 45 } // namespace
59 46
60 namespace views { 47 namespace views {
61 48
62 class TouchSelectionControllerImplTest : public ViewsTestBase { 49 class TouchSelectionControllerImplTest : public ViewsTestBase {
63 public: 50 public:
64 TouchSelectionControllerImplTest() 51 TouchSelectionControllerImplTest()
65 : textfield_widget_(NULL), 52 : textfield_widget_(nullptr),
66 widget_(NULL), 53 widget_(nullptr),
67 textfield_(NULL), 54 textfield_(nullptr),
68 views_tsc_factory_(new ViewsTouchSelectionControllerFactory) { 55 views_tsc_factory_(new ViewsTouchSelectionControllerFactory) {
69 CommandLine::ForCurrentProcess()->AppendSwitch( 56 CommandLine::ForCurrentProcess()->AppendSwitch(
70 switches::kEnableTouchEditing); 57 switches::kEnableTouchEditing);
71 ui::TouchSelectionControllerFactory::SetInstance(views_tsc_factory_.get()); 58 ui::TouchSelectionControllerFactory::SetInstance(views_tsc_factory_.get());
72 } 59 }
73 60
74 ~TouchSelectionControllerImplTest() override { 61 ~TouchSelectionControllerImplTest() override {
75 ui::TouchSelectionControllerFactory::SetInstance(NULL); 62 ui::TouchSelectionControllerFactory::SetInstance(nullptr);
76 } 63 }
77 64
78 void TearDown() override { 65 void TearDown() override {
66 test_cursor_client_.reset();
79 if (textfield_widget_ && !textfield_widget_->IsClosed()) 67 if (textfield_widget_ && !textfield_widget_->IsClosed())
80 textfield_widget_->Close(); 68 textfield_widget_->Close();
81 if (widget_ && !widget_->IsClosed()) 69 if (widget_ && !widget_->IsClosed())
82 widget_->Close(); 70 widget_->Close();
83 ViewsTestBase::TearDown(); 71 ViewsTestBase::TearDown();
84 } 72 }
85 73
86 void CreateTextfield() { 74 void CreateTextfield() {
87 textfield_ = new Textfield(); 75 textfield_ = new Textfield();
88 textfield_widget_ = new Widget; 76 textfield_widget_ = new Widget;
89 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 77 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
90 params.bounds = gfx::Rect(0, 0, 200, 200); 78 params.bounds = gfx::Rect(0, 0, 200, 200);
91 textfield_widget_->Init(params); 79 textfield_widget_->Init(params);
92 View* container = new View(); 80 View* container = new View();
93 textfield_widget_->SetContentsView(container); 81 textfield_widget_->SetContentsView(container);
94 container->AddChildView(textfield_); 82 container->AddChildView(textfield_);
95 83
96 textfield_->SetBoundsRect(gfx::Rect(0, 0, 200, 20)); 84 textfield_->SetBoundsRect(gfx::Rect(0, 0, 200, 20));
97 textfield_->set_id(1); 85 textfield_->set_id(1);
98 textfield_widget_->Show(); 86 textfield_widget_->Show();
99 87
88 SetUpRootWindowClients(textfield_widget_->GetNativeView()->GetRootWindow());
mohsen 2014/11/10 22:26:00 Can be moved to SetUp()?
mfomitchev 2014/11/10 23:07:30 Same as in textfield_unittest.cc - don't think the
mohsen 2014/11/11 01:24:39 Same as my response to your comment in textfield_u
mfomitchev 2014/11/12 18:32:49 Done.
100 textfield_->RequestFocus(); 89 textfield_->RequestFocus();
101
102 textfield_test_api_.reset(new TextfieldTestApi(textfield_)); 90 textfield_test_api_.reset(new TextfieldTestApi(textfield_));
103 } 91 }
104 92
105 void CreateWidget() { 93 void CreateWidget() {
106 widget_ = new Widget; 94 widget_ = new Widget;
107 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP); 95 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
108 params.bounds = gfx::Rect(0, 0, 200, 200); 96 params.bounds = gfx::Rect(0, 0, 200, 200);
109 widget_->Init(params); 97 widget_->Init(params);
110 widget_->Show(); 98 widget_->Show();
111 } 99 SetUpRootWindowClients(widget_->GetNativeView()->GetRootWindow());
mohsen 2014/11/10 22:26:00 Can be moved to SetUp()?
mfomitchev 2014/11/10 23:07:30 Same as above
mfomitchev 2014/11/12 18:32:49 Done.
100 }
112 101
113 protected: 102 protected:
114 static bool IsCursorHandleVisibleFor( 103 static bool IsCursorHandleVisibleFor(
115 ui::TouchSelectionController* controller) { 104 ui::TouchSelectionController* controller) {
116 TouchSelectionControllerImpl* impl = 105 TouchSelectionControllerImpl* impl =
117 static_cast<TouchSelectionControllerImpl*>(controller); 106 static_cast<TouchSelectionControllerImpl*>(controller);
118 return impl->IsCursorHandleVisible(); 107 return impl->IsCursorHandleVisible();
119 } 108 }
120 109
121 gfx::Rect GetCursorRect(const gfx::SelectionModel& sel) { 110 gfx::Rect GetCursorRect(const gfx::SelectionModel& sel) {
(...skipping 11 matching lines...) Expand all
133 } 122 }
134 123
135 void StartTouchEditing() { 124 void StartTouchEditing() {
136 textfield_test_api_->CreateTouchSelectionControllerAndNotifyIt(); 125 textfield_test_api_->CreateTouchSelectionControllerAndNotifyIt();
137 } 126 }
138 127
139 void EndTouchEditing() { 128 void EndTouchEditing() {
140 textfield_test_api_->ResetTouchSelectionController(); 129 textfield_test_api_->ResetTouchSelectionController();
141 } 130 }
142 131
143 void SimulateSelectionHandleDrag(gfx::Point p, int selection_handle) { 132 void SimulateSelectionHandleDrag(gfx::Vector2d v, int selection_handle) {
144 TouchSelectionControllerImpl* controller = GetSelectionController(); 133 TouchSelectionControllerImpl* controller = GetSelectionController();
145 // Do the work of OnMousePressed(). 134 views::WidgetDelegateView* handle = nullptr;
146 if (selection_handle == 1) 135 if (selection_handle == 1)
147 controller->SetDraggingHandle(controller->selection_handle_1_.get()); 136 handle = controller->GetHandle1View();
148 else 137 else
149 controller->SetDraggingHandle(controller->selection_handle_2_.get()); 138 handle = controller->GetHandle2View();
150 139
151 // Offset the drag position by the selection handle radius since it is 140 gfx::Point grip_location = gfx::Point(handle->size().width() / 2,
152 // supposed to be in the coordinate system of the handle. 141 handle->size().height() / 2);
153 p.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); 142 base::TimeDelta time_stamp = base::TimeDelta();
154 controller->SelectionHandleDragged(p); 143 {
155 144 ui::GestureEventDetails details(ui::ET_GESTURE_SCROLL_BEGIN);
156 // Do the work of OnMouseReleased(). 145 ui::GestureEvent scroll_begin(
157 controller->dragging_handle_ = NULL; 146 grip_location.x(), grip_location.y(), 0, time_stamp, details);
147 handle->OnGestureEvent(&scroll_begin);
148 }
149 test_cursor_client_->DisableMouseEvents();
150 {
151 ui::GestureEventDetails details(ui::ET_GESTURE_SCROLL_UPDATE);
152 gfx::Point update_location = grip_location + v;
153 ui::GestureEvent scroll_update(
154 update_location.x(), update_location.y(), 0, time_stamp, details);
155 handle->OnGestureEvent(&scroll_update);
156 }
157 {
158 ui::GestureEventDetails details(ui::ET_GESTURE_SCROLL_END);
159 ui::GestureEvent scroll_end(
160 grip_location.x(), grip_location.y(), 0, time_stamp, details);
161 handle->OnGestureEvent(&scroll_end);
162 }
163 test_cursor_client_->EnableMouseEvents();
158 } 164 }
159 165
160 gfx::NativeView GetCursorHandleNativeView() { 166 gfx::NativeView GetCursorHandleNativeView() {
161 return GetSelectionController()->GetCursorHandleNativeView(); 167 return GetSelectionController()->GetCursorHandleNativeView();
162 } 168 }
163 169
164 gfx::Point GetSelectionHandle1Position() { 170 gfx::Rect GetSelectionHandle1Bounds() {
165 return GetSelectionController()->GetSelectionHandle1Position(); 171 return GetSelectionController()->GetSelectionHandle1Bounds();
166 } 172 }
167 173
168 gfx::Point GetSelectionHandle2Position() { 174 gfx::Rect GetSelectionHandle2Bounds() {
169 return GetSelectionController()->GetSelectionHandle2Position(); 175 return GetSelectionController()->GetSelectionHandle2Bounds();
170 } 176 }
171 177
172 gfx::Point GetCursorHandlePosition() { 178 gfx::Rect GetCursorHandleBounds() {
173 return GetSelectionController()->GetCursorHandlePosition(); 179 return GetSelectionController()->GetCursorHandleBounds();
180 }
181
182 gfx::Rect GetExpectedHandleBounds(const ui::SelectionBound& bound) {
183 return GetSelectionController()->GetExpectedHandleBounds(bound);
174 } 184 }
175 185
176 bool IsSelectionHandle1Visible() { 186 bool IsSelectionHandle1Visible() {
177 return GetSelectionController()->IsSelectionHandle1Visible(); 187 return GetSelectionController()->IsSelectionHandle1Visible();
178 } 188 }
179 189
180 bool IsSelectionHandle2Visible() { 190 bool IsSelectionHandle2Visible() {
181 return GetSelectionController()->IsSelectionHandle2Visible(); 191 return GetSelectionController()->IsSelectionHandle2Visible();
182 } 192 }
183 193
184 bool IsCursorHandleVisible() { 194 bool IsCursorHandleVisible() {
185 return GetSelectionController()->IsCursorHandleVisible(); 195 return GetSelectionController()->IsCursorHandleVisible();
186 } 196 }
187 197
188 gfx::RenderText* GetRenderText() { 198 gfx::RenderText* GetRenderText() {
189 return textfield_test_api_->GetRenderText(); 199 return textfield_test_api_->GetRenderText();
190 } 200 }
191 201
192 gfx::Point GetCursorHandleDragPoint() { 202 gfx::Point GetCursorHandleDragPoint() {
193 gfx::Point point = GetCursorHandlePosition(); 203 gfx::Rect rect = GetCursorHandleBounds();
194 const gfx::SelectionModel& sel = textfield_->GetSelectionModel(); 204 const gfx::SelectionModel& sel = textfield_->GetSelectionModel();
195 int cursor_height = GetCursorRect(sel).height(); 205 int cursor_height = GetCursorRect(sel).height();
196 point.Offset(GetHandleImageSize().width() / 2 + kPadding, 206 gfx::Point point = rect.origin();
197 GetHandleImageSize().height() / 2 + cursor_height); 207 point.Offset(rect.width() / 2, rect.height() / 2 + cursor_height);
198 return point; 208 return point;
199 } 209 }
200 210
201 Widget* textfield_widget_; 211 Widget* textfield_widget_;
202 Widget* widget_; 212 Widget* widget_;
203 213
204 Textfield* textfield_; 214 Textfield* textfield_;
205 scoped_ptr<TextfieldTestApi> textfield_test_api_; 215 scoped_ptr<TextfieldTestApi> textfield_test_api_;
206 scoped_ptr<ViewsTouchSelectionControllerFactory> views_tsc_factory_; 216 scoped_ptr<ViewsTouchSelectionControllerFactory> views_tsc_factory_;
217 scoped_ptr<wm::DefaultScreenPositionClient> screen_position_client_;
218 scoped_ptr<aura::test::TestCursorClient> test_cursor_client_;
207 219
208 private: 220 private:
221 void SetUpRootWindowClients(aura::Window* root_window) {
222 if (!screen_position_client_) {
223 screen_position_client_.reset(new wm::DefaultScreenPositionClient());
224 aura::client::SetScreenPositionClient(root_window,
225 screen_position_client_.get());
226 test_cursor_client_.reset(new aura::test::TestCursorClient(root_window));
227 }
228 }
229
209 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest); 230 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest);
210 }; 231 };
211 232
233 // For selection bounds |b1| and |b2| in a paragraph of text, returns -1 if |b1|
234 // is physically before |b2|, +1 if |b2| is before |b1|, and 0 if they are at
235 // the same location.
236 int CompareTextSelectionBounds(const ui::SelectionBound& b1,
237 const ui::SelectionBound& b2) {
238 if ((b1.edge_top.y() < b2.edge_top.y()) || b1.edge_top.x() < b2.edge_top.x())
239 return -1;
240 else if (b1 == b2)
241 return 0;
242 else
243 return 1;
244 }
245
212 // If textfield has selection, this macro verifies that the selection handles 246 // If textfield has selection, this macro verifies that the selection handles
213 // are visible and at the correct positions (at the end points of selection). 247 // are visible, at the correct positions (at the end points of selection), and
248 // (if |check_direction| is set to true), that they have the correct
249 // directionality.
214 // |cursor_at_selection_handle_1| is used to decide whether selection 250 // |cursor_at_selection_handle_1| is used to decide whether selection
215 // handle 1's position is matched against the start of selection or the end. 251 // handle 1's position is matched against the start of selection or the end.
216 #define VERIFY_HANDLE_POSITIONS(cursor_at_selection_handle_1) \ 252 #define VERIFY_HANDLE_POSITIONS(cursor_at_selection_handle_1, check_direction) \
217 { \ 253 { \
218 gfx::SelectionModel sel = textfield_->GetSelectionModel(); \ 254 ui::SelectionBound anchor, focus; \
255 textfield_->GetSelectionEndPoints(&anchor, &focus); \
219 if (textfield_->HasSelection()) { \ 256 if (textfield_->HasSelection()) { \
220 EXPECT_TRUE(IsSelectionHandle1Visible()); \ 257 EXPECT_TRUE(IsSelectionHandle1Visible()); \
221 EXPECT_TRUE(IsSelectionHandle2Visible()); \ 258 EXPECT_TRUE(IsSelectionHandle2Visible()); \
222 EXPECT_FALSE(IsCursorHandleVisible()); \ 259 EXPECT_FALSE(IsCursorHandleVisible()); \
223 gfx::SelectionModel sel_start = GetRenderText()-> \ 260 gfx::Rect sh1_bounds = GetSelectionHandle1Bounds(); \
224 GetSelectionModelForSelectionStart(); \ 261 gfx::Rect sh2_bounds = GetSelectionHandle2Bounds(); \
225 gfx::Point selection_start = GetCursorPosition(sel_start); \
226 gfx::Point selection_end = GetCursorPosition(sel); \
227 gfx::Point sh1 = GetSelectionHandle1Position(); \
228 gfx::Point sh2 = GetSelectionHandle2Position(); \
229 sh1.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); \
230 sh2.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); \
231 if (cursor_at_selection_handle_1) { \ 262 if (cursor_at_selection_handle_1) { \
232 EXPECT_EQ(sh1, selection_end); \ 263 EXPECT_EQ(sh1_bounds, GetExpectedHandleBounds(focus)); \
233 EXPECT_EQ(sh2, selection_start); \ 264 EXPECT_EQ(sh2_bounds, GetExpectedHandleBounds(anchor)); \
234 } else { \ 265 } else { \
235 EXPECT_EQ(sh1, selection_start); \ 266 EXPECT_EQ(sh1_bounds, GetExpectedHandleBounds(anchor)); \
236 EXPECT_EQ(sh2, selection_end); \ 267 EXPECT_EQ(sh2_bounds, GetExpectedHandleBounds(focus)); \
237 } \ 268 } \
238 } else { \ 269 } else { \
239 EXPECT_FALSE(IsSelectionHandle1Visible()); \ 270 EXPECT_FALSE(IsSelectionHandle1Visible()); \
240 EXPECT_FALSE(IsSelectionHandle2Visible()); \ 271 EXPECT_FALSE(IsSelectionHandle2Visible()); \
241 EXPECT_TRUE(IsCursorHandleVisible()); \ 272 EXPECT_TRUE(IsCursorHandleVisible()); \
242 gfx::Point cursor_pos = GetCursorPosition(sel); \ 273 gfx::Rect cursor_bounds = GetCursorHandleBounds(); \
243 gfx::Point ch_pos = GetCursorHandlePosition(); \ 274 DCHECK(anchor == focus); \
244 ch_pos.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); \ 275 EXPECT_EQ(cursor_bounds, GetExpectedHandleBounds(anchor)); \
245 EXPECT_EQ(ch_pos, cursor_pos); \ 276 } \
277 if (check_direction) { \
278 if (CompareTextSelectionBounds(anchor, focus) < 0) { \
279 EXPECT_EQ(ui::SelectionBound::LEFT, anchor.type); \
280 EXPECT_EQ(ui::SelectionBound::RIGHT, focus.type); \
281 } else if (CompareTextSelectionBounds(anchor, focus) > 0) { \
282 EXPECT_EQ(ui::SelectionBound::LEFT, focus.type); \
283 EXPECT_EQ(ui::SelectionBound::RIGHT, anchor.type); \
284 } else { \
285 EXPECT_EQ(ui::SelectionBound::CENTER, focus.type); \
286 EXPECT_EQ(ui::SelectionBound::CENTER, anchor.type); \
287 } \
246 } \ 288 } \
247 } 289 }
248 290
249 // Tests that the selection handles are placed appropriately when selection in 291 // Tests that the selection handles are placed appropriately when selection in
250 // a Textfield changes. 292 // a Textfield changes.
251 TEST_F(TouchSelectionControllerImplTest, SelectionInTextfieldTest) { 293 TEST_F(TouchSelectionControllerImplTest, SelectionInTextfieldTest) {
252 CreateTextfield(); 294 CreateTextfield();
253 textfield_->SetText(ASCIIToUTF16("some text")); 295 textfield_->SetText(ASCIIToUTF16("some text"));
254 // Tap the textfield to invoke touch selection. 296 // Tap the textfield to invoke touch selection.
255 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 297 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
256 details.set_tap_count(1); 298 details.set_tap_count(1);
257 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 299 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
258 textfield_->OnGestureEvent(&tap); 300 textfield_->OnGestureEvent(&tap);
259 301
260 // Test selecting a range. 302 // Test selecting a range.
261 textfield_->SelectRange(gfx::Range(3, 7)); 303 textfield_->SelectRange(gfx::Range(3, 7));
262 VERIFY_HANDLE_POSITIONS(false); 304 VERIFY_HANDLE_POSITIONS(false, true);
263 305
264 // Test selecting everything. 306 // Test selecting everything.
265 textfield_->SelectAll(false); 307 textfield_->SelectAll(false);
266 VERIFY_HANDLE_POSITIONS(false); 308 VERIFY_HANDLE_POSITIONS(false, true);
267 309
268 // Test with no selection. 310 // Test with no selection.
269 textfield_->ClearSelection(); 311 textfield_->ClearSelection();
270 VERIFY_HANDLE_POSITIONS(false); 312 VERIFY_HANDLE_POSITIONS(false, true);
271 313
272 // Test with lost focus. 314 // Test with lost focus.
273 textfield_widget_->GetFocusManager()->ClearFocus(); 315 textfield_widget_->GetFocusManager()->ClearFocus();
274 EXPECT_FALSE(GetSelectionController()); 316 EXPECT_FALSE(GetSelectionController());
275 317
276 // Test with focus re-gained. 318 // Test with focus re-gained.
277 textfield_widget_->GetFocusManager()->SetFocusedView(textfield_); 319 textfield_widget_->GetFocusManager()->SetFocusedView(textfield_);
278 EXPECT_FALSE(GetSelectionController()); 320 EXPECT_FALSE(GetSelectionController());
279 textfield_->OnGestureEvent(&tap); 321 textfield_->OnGestureEvent(&tap);
280 VERIFY_HANDLE_POSITIONS(false); 322 VERIFY_HANDLE_POSITIONS(false, true);
281 } 323 }
282 324
283 // Tests that the selection handles are placed appropriately in bidi text. 325 // Tests that the selection handles are placed appropriately in bidi text.
284 TEST_F(TouchSelectionControllerImplTest, SelectionInBidiTextfieldTest) { 326 TEST_F(TouchSelectionControllerImplTest, SelectionInBidiTextfieldTest) {
285 CreateTextfield(); 327 CreateTextfield();
286 textfield_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 328 textfield_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2"));
287 // Tap the textfield to invoke touch selection. 329 // Tap the textfield to invoke touch selection.
288 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 330 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
289 details.set_tap_count(1); 331 details.set_tap_count(1);
290 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 332 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
291 textfield_->OnGestureEvent(&tap); 333 textfield_->OnGestureEvent(&tap);
292 334
293 // Test cursor at run boundary and with empty selection. 335 // Test cursor at run boundary and with empty selection.
294 textfield_->SelectSelectionModel( 336 textfield_->SelectSelectionModel(
295 gfx::SelectionModel(3, gfx::CURSOR_BACKWARD)); 337 gfx::SelectionModel(3, gfx::CURSOR_BACKWARD));
296 VERIFY_HANDLE_POSITIONS(false); 338 VERIFY_HANDLE_POSITIONS(false, true);
297 339
298 // Test selection range inside one run and starts or ends at run boundary. 340 // Test selection range inside one run and starts or ends at run boundary.
299 textfield_->SelectRange(gfx::Range(2, 3)); 341 textfield_->SelectRange(gfx::Range(2, 3));
300 VERIFY_HANDLE_POSITIONS(false); 342 VERIFY_HANDLE_POSITIONS(false, true);
301 343
302 textfield_->SelectRange(gfx::Range(3, 2)); 344 textfield_->SelectRange(gfx::Range(3, 2));
303 VERIFY_HANDLE_POSITIONS(false); 345 VERIFY_HANDLE_POSITIONS(false, true);
304 346
347 // TODO(mfomitchev): crbug.com/429705
348 // Handles in mixed ltr/rtl text line may have incorrect directionality (e.g.
349 // if rtl text is selected in the ltr line), so passing false for
350 // |check_direction| in some of these tests.
305 textfield_->SelectRange(gfx::Range(3, 4)); 351 textfield_->SelectRange(gfx::Range(3, 4));
306 VERIFY_HANDLE_POSITIONS(false); 352 VERIFY_HANDLE_POSITIONS(false, false);
307 353
308 textfield_->SelectRange(gfx::Range(4, 3)); 354 textfield_->SelectRange(gfx::Range(4, 3));
309 VERIFY_HANDLE_POSITIONS(false); 355 VERIFY_HANDLE_POSITIONS(false, false);
310 356
311 textfield_->SelectRange(gfx::Range(3, 6)); 357 textfield_->SelectRange(gfx::Range(3, 6));
312 VERIFY_HANDLE_POSITIONS(false); 358 VERIFY_HANDLE_POSITIONS(false, false);
313 359
314 textfield_->SelectRange(gfx::Range(6, 3)); 360 textfield_->SelectRange(gfx::Range(6, 3));
315 VERIFY_HANDLE_POSITIONS(false); 361 VERIFY_HANDLE_POSITIONS(false, false);
316 362
317 // Test selection range accross runs. 363 // Test selection range accross runs.
318 textfield_->SelectRange(gfx::Range(0, 6)); 364 textfield_->SelectRange(gfx::Range(0, 6));
319 VERIFY_HANDLE_POSITIONS(false); 365 VERIFY_HANDLE_POSITIONS(false, true);
320 366
321 textfield_->SelectRange(gfx::Range(6, 0)); 367 textfield_->SelectRange(gfx::Range(6, 0));
322 VERIFY_HANDLE_POSITIONS(false); 368 VERIFY_HANDLE_POSITIONS(false, true);
323 369
324 textfield_->SelectRange(gfx::Range(1, 4)); 370 textfield_->SelectRange(gfx::Range(1, 4));
325 VERIFY_HANDLE_POSITIONS(false); 371 VERIFY_HANDLE_POSITIONS(false, true);
326 372
327 textfield_->SelectRange(gfx::Range(4, 1)); 373 textfield_->SelectRange(gfx::Range(4, 1));
328 VERIFY_HANDLE_POSITIONS(false); 374 VERIFY_HANDLE_POSITIONS(false, true);
329 } 375 }
330 376
331 // Tests if the SelectRect callback is called appropriately when selection 377 // Tests if the SelectRect callback is called appropriately when selection
332 // handles are moved. 378 // handles are moved.
333 TEST_F(TouchSelectionControllerImplTest, SelectRectCallbackTest) { 379 TEST_F(TouchSelectionControllerImplTest, SelectRectCallbackTest) {
334 CreateTextfield(); 380 CreateTextfield();
335 textfield_->SetText(ASCIIToUTF16("textfield with selected text")); 381 textfield_->SetText(ASCIIToUTF16("textfield with selected text"));
336 // Tap the textfield to invoke touch selection. 382 // Tap the textfield to invoke touch selection.
337 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 383 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
338 details.set_tap_count(1); 384 details.set_tap_count(1);
339 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 385 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
340 textfield_->OnGestureEvent(&tap); 386 textfield_->OnGestureEvent(&tap);
341 textfield_->SelectRange(gfx::Range(3, 7)); 387 textfield_->SelectRange(gfx::Range(3, 7));
342 388
343 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfie"); 389 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfie");
344 VERIFY_HANDLE_POSITIONS(false); 390 VERIFY_HANDLE_POSITIONS(false, true);
345 391
346 // Drag selection handle 2 to right by 3 chars. 392 // Drag selection handle 2 to right by 3 chars.
347 const gfx::FontList& font_list = textfield_->GetFontList(); 393 const gfx::FontList& font_list = textfield_->GetFontList();
348 int x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("ld "), font_list); 394 int x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("ld "), font_list);
349 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 395 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
350 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfield "); 396 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "tfield ");
351 VERIFY_HANDLE_POSITIONS(false); 397 VERIFY_HANDLE_POSITIONS(false, true);
352 398
353 // Drag selection handle 1 to the left by a large amount (selection should 399 // Drag selection handle 1 to the left by a large amount (selection should
354 // just stick to the beginning of the textfield). 400 // just stick to the beginning of the textfield).
355 SimulateSelectionHandleDrag(gfx::Point(-50, 0), 1); 401 SimulateSelectionHandleDrag(gfx::Vector2d(-50, 0), 1);
356 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "textfield "); 402 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "textfield ");
357 VERIFY_HANDLE_POSITIONS(true); 403 VERIFY_HANDLE_POSITIONS(true, true);
358 404
359 // Drag selection handle 1 across selection handle 2. 405 // Drag selection handle 1 across selection handle 2.
360 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("textfield with "), font_list); 406 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("textfield with "), font_list);
361 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 407 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
362 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "with "); 408 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "with ");
363 VERIFY_HANDLE_POSITIONS(true); 409 VERIFY_HANDLE_POSITIONS(true, true);
364 410
365 // Drag selection handle 2 across selection handle 1. 411 // Drag selection handle 2 across selection handle 1.
366 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("with selected "), font_list); 412 x = gfx::Canvas::GetStringWidth(ASCIIToUTF16("with selected "), font_list);
367 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 413 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
368 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "selected "); 414 EXPECT_EQ(UTF16ToUTF8(textfield_->GetSelectedText()), "selected ");
369 VERIFY_HANDLE_POSITIONS(false); 415 VERIFY_HANDLE_POSITIONS(false, true);
370 } 416 }
371 417
372 TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) { 418 TEST_F(TouchSelectionControllerImplTest, SelectRectInBidiCallbackTest) {
373 CreateTextfield(); 419 CreateTextfield();
374 textfield_->SetText(WideToUTF16(L"abc\x05e1\x05e2\x05e3" L"def")); 420 textfield_->SetText(WideToUTF16(L"abc\x05e1\x05e2\x05e3" L"def"));
375 // Tap the textfield to invoke touch selection. 421 // Tap the textfield to invoke touch selection.
376 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); 422 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
377 details.set_tap_count(1); 423 details.set_tap_count(1);
378 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details); 424 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
379 textfield_->OnGestureEvent(&tap); 425 textfield_->OnGestureEvent(&tap);
380 426
381 // Select [c] from left to right. 427 // Select [c] from left to right.
382 textfield_->SelectRange(gfx::Range(2, 3)); 428 textfield_->SelectRange(gfx::Range(2, 3));
383 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText()); 429 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
384 VERIFY_HANDLE_POSITIONS(false); 430 VERIFY_HANDLE_POSITIONS(false, true);
385 431
386 // Drag selection handle 2 to right by 1 char. 432 // Drag selection handle 2 to right by 1 char.
387 const gfx::FontList& font_list = textfield_->GetFontList(); 433 const gfx::FontList& font_list = textfield_->GetFontList();
388 int x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list); 434 int x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list);
389 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 435 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
390 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 436 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
391 VERIFY_HANDLE_POSITIONS(false); 437 VERIFY_HANDLE_POSITIONS(false, true);
392 438
393 // Drag selection handle 1 to left by 1 char. 439 // Drag selection handle 1 to left by 1 char.
394 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list); 440 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list);
395 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1); 441 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 1);
396 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText()); 442 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText());
397 VERIFY_HANDLE_POSITIONS(true); 443 VERIFY_HANDLE_POSITIONS(true, true);
398 444
399 // Select [c] from right to left. 445 // Select [c] from right to left.
400 textfield_->SelectRange(gfx::Range(3, 2)); 446 textfield_->SelectRange(gfx::Range(3, 2));
401 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText()); 447 EXPECT_EQ(WideToUTF16(L"c"), textfield_->GetSelectedText());
402 VERIFY_HANDLE_POSITIONS(false); 448 VERIFY_HANDLE_POSITIONS(false, true);
403 449
404 // Drag selection handle 1 to right by 1 char. 450 // Drag selection handle 1 to right by 1 char.
405 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list); 451 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e3"), font_list);
406 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 452 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
407 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 453 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
408 VERIFY_HANDLE_POSITIONS(true); 454 VERIFY_HANDLE_POSITIONS(true, true);
409 455
410 // Drag selection handle 2 to left by 1 char. 456 // Drag selection handle 2 to left by 1 char.
411 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list); 457 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"b"), font_list);
412 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2); 458 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 2);
413 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText()); 459 EXPECT_EQ(WideToUTF16(L"bc\x05e1\x05e2"), textfield_->GetSelectedText());
414 VERIFY_HANDLE_POSITIONS(false); 460 VERIFY_HANDLE_POSITIONS(false, true);
415 461
416 // Select [\x5e1] from right to left. 462 // Select [\x5e1] from right to left.
417 textfield_->SelectRange(gfx::Range(3, 4)); 463 textfield_->SelectRange(gfx::Range(3, 4));
418 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText()); 464 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
419 VERIFY_HANDLE_POSITIONS(false); 465 // TODO(mfomitchev): crbug.com/429705
466 // Handles in mixed ltr/rtl text line may have incorrect directionality (e.g.
467 // if rtl text is selected in the ltr line), so passing false for
468 // |check_direction| in some of these tests.
469 VERIFY_HANDLE_POSITIONS(false, false);
420 470
421 /* TODO(xji): for bidi text "abcDEF" whose display is "abcFEDhij", when click 471 /* TODO(xji): for bidi text "abcDEF" whose display is "abcFEDhij", when click
422 right of 'D' and select [D] then move the left selection handle to left 472 right of 'D' and select [D] then move the left selection handle to left
423 by one character, it should select [ED], instead it selects [F]. 473 by one character, it should select [ED], instead it selects [F].
424 Reason: click right of 'D' and left of 'h' return the same x-axis position, 474 Reason: click right of 'D' and left of 'h' return the same x-axis position,
425 pass this position to FindCursorPosition() returns index of 'h'. which 475 pass this position to FindCursorPosition() returns index of 'h'. which
426 means the selection start changed from 3 to 6. 476 means the selection start changed from 3 to 6.
427 Need further investigation on whether this is a bug in Pango and how to 477 Need further investigation on whether this is a bug in Pango and how to
428 work around it. 478 work around it.
429 // Drag selection handle 2 to left by 1 char. 479 // Drag selection handle 2 to left by 1 char.
430 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 480 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
431 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2); 481 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 2);
432 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText()); 482 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText());
433 VERIFY_HANDLE_POSITIONS(false); 483 VERIFY_HANDLE_POSITIONS(false);
434 */ 484 */
435 485
436 // Drag selection handle 1 to right by 1 char. 486 // Drag selection handle 1 to right by 1 char.
437 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list); 487 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list);
438 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 488 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
439 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText()); 489 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText());
440 VERIFY_HANDLE_POSITIONS(true); 490 VERIFY_HANDLE_POSITIONS(true, true);
441 491
442 // Select [\x5e1] from left to right. 492 // Select [\x5e1] from left to right.
443 textfield_->SelectRange(gfx::Range(4, 3)); 493 textfield_->SelectRange(gfx::Range(4, 3));
444 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText()); 494 EXPECT_EQ(WideToUTF16(L"\x05e1"), textfield_->GetSelectedText());
445 VERIFY_HANDLE_POSITIONS(false); 495 VERIFY_HANDLE_POSITIONS(false, false);
446 496
447 /* TODO(xji): see detail of above commented out test case. 497 /* TODO(xji): see detail of above commented out test case.
448 // Drag selection handle 1 to left by 1 char. 498 // Drag selection handle 1 to left by 1 char.
449 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 499 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
450 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1); 500 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 1);
451 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText()); 501 EXPECT_EQ(WideToUTF16(L"\x05e1\x05e2"), textfield_->GetSelectedText());
452 VERIFY_HANDLE_POSITIONS(true); 502 VERIFY_HANDLE_POSITIONS(true);
453 */ 503 */
454 504
455 // Drag selection handle 2 to right by 1 char. 505 // Drag selection handle 2 to right by 1 char.
456 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list); 506 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"d"), font_list);
457 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 507 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
458 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText()); 508 EXPECT_EQ(WideToUTF16(L"\x05e2\x05e3" L"d"), textfield_->GetSelectedText());
459 VERIFY_HANDLE_POSITIONS(false); 509 VERIFY_HANDLE_POSITIONS(false, true);
460 510
461 // Select [\x05r3] from right to left. 511 // Select [\x05r3] from right to left.
462 textfield_->SelectRange(gfx::Range(5, 6)); 512 textfield_->SelectRange(gfx::Range(5, 6));
463 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText()); 513 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
464 VERIFY_HANDLE_POSITIONS(false); 514 VERIFY_HANDLE_POSITIONS(false, false);
465 515
466 // Drag selection handle 2 to left by 1 char. 516 // Drag selection handle 2 to left by 1 char.
467 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list); 517 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list);
468 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 2); 518 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 2);
469 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 519 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
470 VERIFY_HANDLE_POSITIONS(false); 520 VERIFY_HANDLE_POSITIONS(false, true);
471 521
472 // Drag selection handle 1 to right by 1 char. 522 // Drag selection handle 1 to right by 1 char.
473 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 523 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
474 SimulateSelectionHandleDrag(gfx::Point(x, 0), 1); 524 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 1);
475 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText()); 525 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
476 VERIFY_HANDLE_POSITIONS(true); 526 VERIFY_HANDLE_POSITIONS(true, true);
477 527
478 // Select [\x05r3] from left to right. 528 // Select [\x05r3] from left to right.
479 textfield_->SelectRange(gfx::Range(6, 5)); 529 textfield_->SelectRange(gfx::Range(6, 5));
480 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText()); 530 EXPECT_EQ(WideToUTF16(L"\x05e3"), textfield_->GetSelectedText());
481 VERIFY_HANDLE_POSITIONS(false); 531 VERIFY_HANDLE_POSITIONS(false, false);
482 532
483 // Drag selection handle 1 to left by 1 char. 533 // Drag selection handle 1 to left by 1 char.
484 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list); 534 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"c"), font_list);
485 SimulateSelectionHandleDrag(gfx::Point(-x, 0), 1); 535 SimulateSelectionHandleDrag(gfx::Vector2d(-x, 0), 1);
486 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText()); 536 EXPECT_EQ(WideToUTF16(L"c\x05e1\x05e2"), textfield_->GetSelectedText());
487 VERIFY_HANDLE_POSITIONS(true); 537 VERIFY_HANDLE_POSITIONS(true, true);
488 538
489 // Drag selection handle 2 to right by 1 char. 539 // Drag selection handle 2 to right by 1 char.
490 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 540 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
491 SimulateSelectionHandleDrag(gfx::Point(x, 0), 2); 541 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
492 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText()); 542 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
493 VERIFY_HANDLE_POSITIONS(false); 543 VERIFY_HANDLE_POSITIONS(false, false);
494 } 544 }
495 545
496 TEST_F(TouchSelectionControllerImplTest, 546 TEST_F(TouchSelectionControllerImplTest,
497 HiddenSelectionHandleRetainsCursorPosition) { 547 HiddenSelectionHandleRetainsCursorPosition) {
498 // Create a textfield with lots of text in it. 548 // Create a textfield with lots of text in it.
499 CreateTextfield(); 549 CreateTextfield();
500 std::string textfield_text("some text"); 550 std::string textfield_text("some text");
501 for (int i = 0; i < 10; ++i) 551 for (int i = 0; i < 10; ++i)
502 textfield_text += textfield_text; 552 textfield_text += textfield_text;
503 textfield_->SetText(ASCIIToUTF16(textfield_text)); 553 textfield_->SetText(ASCIIToUTF16(textfield_text));
(...skipping 10 matching lines...) Expand all
514 // Check that one selection handle is hidden. 564 // Check that one selection handle is hidden.
515 EXPECT_FALSE(IsSelectionHandle1Visible()); 565 EXPECT_FALSE(IsSelectionHandle1Visible());
516 EXPECT_TRUE(IsSelectionHandle2Visible()); 566 EXPECT_TRUE(IsSelectionHandle2Visible());
517 EXPECT_EQ(gfx::Range(10, textfield_text.length()), 567 EXPECT_EQ(gfx::Range(10, textfield_text.length()),
518 textfield_->GetSelectedRange()); 568 textfield_->GetSelectedRange());
519 569
520 // Drag the visible handle around and make sure the selection end point of the 570 // Drag the visible handle around and make sure the selection end point of the
521 // invisible handle does not change. 571 // invisible handle does not change.
522 size_t visible_handle_position = textfield_->GetSelectedRange().end(); 572 size_t visible_handle_position = textfield_->GetSelectedRange().end();
523 for (int i = 0; i < 10; ++i) { 573 for (int i = 0; i < 10; ++i) {
524 SimulateSelectionHandleDrag(gfx::Point(-10, 0), 2); 574 static const int drag_diff = -10;
575 SimulateSelectionHandleDrag(gfx::Vector2d(drag_diff, 0), 2);
525 // Make sure that the visible handle is being dragged. 576 // Make sure that the visible handle is being dragged.
526 EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end()); 577 EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end());
527 visible_handle_position = textfield_->GetSelectedRange().end(); 578 visible_handle_position = textfield_->GetSelectedRange().end();
528 EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start()); 579 EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start());
529 } 580 }
530 } 581 }
531 582
532 TEST_F(TouchSelectionControllerImplTest, 583 TEST_F(TouchSelectionControllerImplTest,
533 DoubleTapInTextfieldWithCursorHandleShouldSelectText) { 584 DoubleTapInTextfieldWithCursorHandleShouldSelectText) {
534 CreateTextfield(); 585 CreateTextfield();
535 textfield_->SetText(ASCIIToUTF16("some text")); 586 textfield_->SetText(ASCIIToUTF16("some text"));
536 ui::test::EventGenerator generator( 587 ui::test::EventGenerator generator(
537 textfield_->GetWidget()->GetNativeView()->GetRootWindow()); 588 textfield_->GetWidget()->GetNativeView()->GetRootWindow());
538 589
539 // Tap the textfield to invoke touch selection. 590 // Tap the textfield to invoke touch selection.
540 generator.GestureTapAt(gfx::Point(10, 10)); 591 generator.GestureTapAt(gfx::Point(10, 10));
541 592
542 // Cursor handle should be visible. 593 // Cursor handle should be visible.
543 EXPECT_FALSE(textfield_->HasSelection()); 594 EXPECT_FALSE(textfield_->HasSelection());
544 VERIFY_HANDLE_POSITIONS(false); 595 VERIFY_HANDLE_POSITIONS(false, true);
545 596
546 // Double tap on the cursor handle position. We want to check that the cursor 597 // Double tap on the cursor handle position. We want to check that the cursor
547 // handle is not eating the event and that the event is falling through to the 598 // handle is not eating the event and that the event is falling through to the
548 // textfield. 599 // textfield.
549 gfx::Point cursor_pos = GetCursorHandlePosition(); 600 gfx::Point cursor_pos = GetCursorHandleBounds().origin();
550 cursor_pos.Offset(GetHandleImageSize().width() / 2 + kPadding, 0); 601 cursor_pos.Offset(GetCursorHandleBounds().width() / 2, 0);
551 generator.GestureTapAt(cursor_pos); 602 generator.GestureTapAt(cursor_pos);
552 generator.GestureTapAt(cursor_pos); 603 generator.GestureTapAt(cursor_pos);
553 EXPECT_TRUE(textfield_->HasSelection()); 604 EXPECT_TRUE(textfield_->HasSelection());
554 } 605 }
555 606
556 // A simple implementation of TouchEditable that allows faking cursor position 607 // A simple implementation of TouchEditable that allows faking cursor position
557 // inside its boundaries. 608 // inside its boundaries.
558 class TestTouchEditable : public ui::TouchEditable { 609 class TestTouchEditable : public ui::TouchEditable {
559 public: 610 public:
560 explicit TestTouchEditable(aura::Window* window) 611 explicit TestTouchEditable(aura::Window* window)
561 : window_(window) { 612 : window_(window) {
562 DCHECK(window); 613 DCHECK(window);
563 } 614 }
564 615
565 void set_bounds(const gfx::Rect& bounds) { 616 void set_bounds(const gfx::Rect& bounds) {
566 bounds_ = bounds; 617 bounds_ = bounds;
567 } 618 }
568 619
569 void set_cursor_rect(const gfx::Rect& cursor_rect) { 620 void set_cursor_rect(const gfx::Rect& cursor_rect) {
570 cursor_rect_ = cursor_rect; 621 cursor_bound_.edge_top = cursor_rect.origin();
622 cursor_bound_.edge_bottom = cursor_rect.bottom_left();
623 cursor_bound_.type = ui::SelectionBound::Type::CENTER;
571 } 624 }
572 625
573 ~TestTouchEditable() override {} 626 ~TestTouchEditable() override {}
574 627
575 private: 628 private:
576 // Overridden from ui::TouchEditable. 629 // Overridden from ui::TouchEditable.
577 void SelectRect(const gfx::Point& start, const gfx::Point& end) override { 630 void SelectRect(const gfx::Point& start, const gfx::Point& end) override {
578 NOTREACHED(); 631 NOTREACHED();
579 } 632 }
580 void MoveCaretTo(const gfx::Point& point) override { NOTREACHED(); } 633 void MoveCaretTo(const gfx::Point& point) override { NOTREACHED(); }
581 void GetSelectionEndPoints(gfx::Rect* p1, gfx::Rect* p2) override { 634 void GetSelectionEndPoints(ui::SelectionBound* anchor,
582 *p1 = *p2 = cursor_rect_; 635 ui::SelectionBound* focus) override {
636 *anchor = *focus = cursor_bound_;
583 } 637 }
584 gfx::Rect GetBounds() override { return gfx::Rect(bounds_.size()); } 638 gfx::Rect GetBounds() override { return gfx::Rect(bounds_.size()); }
585 gfx::NativeView GetNativeView() const override { return window_; } 639 gfx::NativeView GetNativeView() const override { return window_; }
586 void ConvertPointToScreen(gfx::Point* point) override { 640 void ConvertPointToScreen(gfx::Point* point) override {
587 aura::client::ScreenPositionClient* screen_position_client = 641 aura::client::ScreenPositionClient* screen_position_client =
588 aura::client::GetScreenPositionClient(window_->GetRootWindow()); 642 aura::client::GetScreenPositionClient(window_->GetRootWindow());
589 if (screen_position_client) 643 if (screen_position_client)
590 screen_position_client->ConvertPointToScreen(window_, point); 644 screen_position_client->ConvertPointToScreen(window_, point);
591 } 645 }
592 void ConvertPointFromScreen(gfx::Point* point) override { 646 void ConvertPointFromScreen(gfx::Point* point) override {
(...skipping 23 matching lines...) Expand all
616 void ExecuteCommand(int command_id, int event_flags) override { 670 void ExecuteCommand(int command_id, int event_flags) override {
617 NOTREACHED(); 671 NOTREACHED();
618 } 672 }
619 673
620 aura::Window* window_; 674 aura::Window* window_;
621 675
622 // Boundaries of the client view. 676 // Boundaries of the client view.
623 gfx::Rect bounds_; 677 gfx::Rect bounds_;
624 678
625 // Cursor position inside the client view. 679 // Cursor position inside the client view.
626 gfx::Rect cursor_rect_; 680 //gfx::Rect cursor_rect_;
681 ui::SelectionBound cursor_bound_;
627 682
628 DISALLOW_COPY_AND_ASSIGN(TestTouchEditable); 683 DISALLOW_COPY_AND_ASSIGN(TestTouchEditable);
629 }; 684 };
630 685
631 // Tests if the touch editing handle is shown or hidden properly according to 686 // Tests if the touch editing handle is shown or hidden properly according to
632 // the cursor position relative to the client boundaries. 687 // the cursor position relative to the client boundaries.
633 TEST_F(TouchSelectionControllerImplTest, 688 TEST_F(TouchSelectionControllerImplTest,
634 VisibilityOfHandleRegardingClientBounds) { 689 VisibilityOfHandleRegardingClientBounds) {
635 CreateWidget(); 690 CreateWidget();
636 691
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 // image width and check that anchor rect's height is not adjusted. 819 // image width and check that anchor rect's height is not adjusted.
765 anchor_rect = 820 anchor_rect =
766 gfx::Rect(0, 0, quick_menu_width + handle_image_size.width() + 10, 20); 821 gfx::Rect(0, 0, quick_menu_width + handle_image_size.width() + 10, 20);
767 quick_menu = TouchEditingMenuView::Create( 822 quick_menu = TouchEditingMenuView::Create(
768 quick_menu_controller.get(), anchor_rect, handle_image_size, window); 823 quick_menu_controller.get(), anchor_rect, handle_image_size, window);
769 EXPECT_EQ(anchor_rect.ToString(), quick_menu->GetAnchorRect().ToString()); 824 EXPECT_EQ(anchor_rect.ToString(), quick_menu->GetAnchorRect().ToString());
770 825
771 // Close the widget, hence quick menus, before quick menu controller goes out 826 // Close the widget, hence quick menus, before quick menu controller goes out
772 // of scope. 827 // of scope.
773 widget_->CloseNow(); 828 widget_->CloseNow();
774 widget_ = NULL; 829 widget_ = nullptr;
775 } 830 }
776 831
777 TEST_F(TouchSelectionControllerImplTest, MouseEventDeactivatesTouchSelection) { 832 TEST_F(TouchSelectionControllerImplTest, MouseEventDeactivatesTouchSelection) {
778 CreateTextfield(); 833 CreateTextfield();
779 EXPECT_FALSE(GetSelectionController()); 834 EXPECT_FALSE(GetSelectionController());
780 835
781 ui::test::EventGenerator generator( 836 ui::test::EventGenerator generator(
782 textfield_widget_->GetNativeView()->GetRootWindow()); 837 textfield_widget_->GetNativeView()->GetRootWindow());
783 838
784 generator.set_current_location(gfx::Point(5, 5)); 839 generator.set_current_location(gfx::Point(5, 5));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 // Start touch editing; then press a key and ensure it deactivates touch 882 // Start touch editing; then press a key and ensure it deactivates touch
828 // selection. 883 // selection.
829 StartTouchEditing(); 884 StartTouchEditing();
830 EXPECT_TRUE(GetSelectionController()); 885 EXPECT_TRUE(GetSelectionController());
831 generator.PressKey(ui::VKEY_A, 0); 886 generator.PressKey(ui::VKEY_A, 0);
832 RunPendingMessages(); 887 RunPendingMessages();
833 EXPECT_FALSE(GetSelectionController()); 888 EXPECT_FALSE(GetSelectionController());
834 } 889 }
835 890
836 } // namespace views 891 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698