OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/browser/web_contents/touch_editable_impl_aura.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "base/run_loop.h" | |
9 #include "base/strings/utf_string_conversions.h" | |
10 #include "base/test/test_timeouts.h" | |
11 #include "base/values.h" | |
12 #include "content/browser/web_contents/web_contents_impl.h" | |
13 #include "content/browser/web_contents/web_contents_view_aura.h" | |
14 #include "content/public/browser/render_frame_host.h" | |
15 #include "content/public/common/content_switches.h" | |
16 #include "content/public/test/browser_test_utils.h" | |
17 #include "content/public/test/content_browser_test.h" | |
18 #include "content/public/test/content_browser_test_utils.h" | |
19 #include "content/public/test/test_utils.h" | |
20 #include "content/shell/browser/shell.h" | |
21 #include "third_party/WebKit/public/web/WebInputEvent.h" | |
22 #include "ui/aura/window.h" | |
23 #include "ui/aura/window_tree_host.h" | |
24 #include "ui/base/ui_base_switches.h" | |
25 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | |
26 #include "ui/events/event_utils.h" | |
27 #include "ui/events/test/event_generator.h" | |
28 #include "ui/wm/core/default_screen_position_client.h" | |
29 | |
30 using blink::WebInputEvent; | |
31 | |
32 namespace content { | |
33 | |
34 class TestTouchEditableImplAura : public TouchEditableImplAura { | |
35 public: | |
36 TestTouchEditableImplAura() | |
37 : overscroll_started_callback_arrived_(false), | |
38 waiting_for_overscroll_started_callback_(false), | |
39 overscroll_completed_callback_arrived_(false), | |
40 waiting_for_overscroll_completed_callback_(false), | |
41 selection_changed_callback_arrived_(false), | |
42 waiting_for_selection_changed_callback_(false), | |
43 waiting_for_gesture_ack_type_(WebInputEvent::Undefined), | |
44 last_gesture_ack_type_(WebInputEvent::Undefined), | |
45 fling_stop_callback_arrived_(false), | |
46 waiting_for_fling_stop_callback_(false) {} | |
47 | |
48 virtual void Reset() { | |
49 overscroll_started_callback_arrived_ = false; | |
50 waiting_for_overscroll_started_callback_ = false; | |
51 overscroll_completed_callback_arrived_ = false; | |
52 waiting_for_overscroll_completed_callback_ = false; | |
53 selection_changed_callback_arrived_ = false; | |
54 waiting_for_selection_changed_callback_ = false; | |
55 waiting_for_gesture_ack_type_ = WebInputEvent::Undefined; | |
56 last_gesture_ack_type_ = WebInputEvent::Undefined; | |
57 fling_stop_callback_arrived_ = false; | |
58 waiting_for_fling_stop_callback_ = false; | |
59 } | |
60 | |
61 void OverscrollStarted() override { | |
62 overscroll_started_callback_arrived_ = true; | |
63 TouchEditableImplAura::OverscrollStarted(); | |
64 if (waiting_for_overscroll_started_callback_) | |
65 overscroll_started_wait_run_loop_->Quit(); | |
66 } | |
67 | |
68 void WaitForOverscrollStartedCallback() { | |
69 // Doesn't make sense to call more that once without resetting. | |
70 CHECK(!waiting_for_overscroll_started_callback_); | |
71 waiting_for_overscroll_started_callback_ = true; | |
72 if (overscroll_started_callback_arrived_) | |
73 return; | |
74 overscroll_started_wait_run_loop_.reset(new base::RunLoop()); | |
75 overscroll_started_wait_run_loop_->Run(); | |
76 } | |
77 | |
78 void OverscrollCompleted() override { | |
79 overscroll_completed_callback_arrived_ = true; | |
80 TouchEditableImplAura::OverscrollCompleted(); | |
81 if (waiting_for_overscroll_completed_callback_) | |
82 overscroll_completed_wait_run_loop_->Quit(); | |
83 } | |
84 | |
85 void WaitForOverscrollCompletedCallback() { | |
86 // Doesn't make sense to call more that once without resetting. | |
87 CHECK(!waiting_for_overscroll_completed_callback_); | |
88 waiting_for_overscroll_completed_callback_ = true; | |
89 if (overscroll_completed_callback_arrived_) | |
90 return; | |
91 overscroll_completed_wait_run_loop_.reset(new base::RunLoop()); | |
92 overscroll_completed_wait_run_loop_->Run(); | |
93 } | |
94 | |
95 void OnSelectionOrCursorChanged(const ui::SelectionBound& anchor, | |
96 const ui::SelectionBound& focus) override { | |
97 selection_changed_callback_arrived_ = true; | |
98 TouchEditableImplAura::OnSelectionOrCursorChanged(anchor, focus); | |
99 if (waiting_for_selection_changed_callback_) | |
100 selection_changed_wait_run_loop_->Quit(); | |
101 } | |
102 | |
103 void GestureEventAck(int gesture_event_type) override { | |
104 last_gesture_ack_type_ = | |
105 static_cast<WebInputEvent::Type>(gesture_event_type); | |
106 TouchEditableImplAura::GestureEventAck(gesture_event_type); | |
107 if (waiting_for_gesture_ack_type_ == gesture_event_type) | |
108 gesture_ack_wait_run_loop_->Quit(); | |
109 } | |
110 | |
111 void DidStopFlinging() override { | |
112 fling_stop_callback_arrived_ = true; | |
113 TouchEditableImplAura::DidStopFlinging(); | |
114 if (waiting_for_fling_stop_callback_) | |
115 fling_stop_wait_run_loop_->Quit(); | |
116 } | |
117 | |
118 void WaitForSelectionChangeCallback() { | |
119 // Doesn't make sense to call more that once without resetting. | |
120 CHECK(!waiting_for_selection_changed_callback_); | |
121 waiting_for_selection_changed_callback_ = true; | |
122 if (selection_changed_callback_arrived_) | |
123 return; | |
124 selection_changed_wait_run_loop_.reset(new base::RunLoop()); | |
125 selection_changed_wait_run_loop_->Run(); | |
126 } | |
127 | |
128 void WaitForGestureAck(WebInputEvent::Type gesture_event_type) { | |
129 // Doesn't make sense to call more that once without resetting. | |
130 CHECK_EQ(waiting_for_gesture_ack_type_, WebInputEvent::Undefined); | |
131 waiting_for_gesture_ack_type_ = gesture_event_type; | |
132 if (last_gesture_ack_type_ == gesture_event_type) | |
133 return; | |
134 gesture_ack_wait_run_loop_.reset(new base::RunLoop()); | |
135 gesture_ack_wait_run_loop_->Run(); | |
136 } | |
137 | |
138 void WaitForFlingStopCallback() { | |
139 // Doesn't make sense to call more that once without resetting. | |
140 CHECK(!waiting_for_fling_stop_callback_); | |
141 waiting_for_fling_stop_callback_ = true; | |
142 if (fling_stop_callback_arrived_) | |
143 return; | |
144 fling_stop_wait_run_loop_.reset(new base::RunLoop()); | |
145 fling_stop_wait_run_loop_->Run(); | |
146 } | |
147 | |
148 protected: | |
149 ~TestTouchEditableImplAura() override {} | |
150 | |
151 private: | |
152 bool overscroll_started_callback_arrived_; | |
153 bool waiting_for_overscroll_started_callback_; | |
154 bool overscroll_completed_callback_arrived_; | |
155 bool waiting_for_overscroll_completed_callback_; | |
156 bool selection_changed_callback_arrived_; | |
157 bool waiting_for_selection_changed_callback_; | |
158 WebInputEvent::Type waiting_for_gesture_ack_type_; | |
159 WebInputEvent::Type last_gesture_ack_type_; | |
160 bool fling_stop_callback_arrived_; | |
161 bool waiting_for_fling_stop_callback_; | |
162 scoped_ptr<base::RunLoop> overscroll_started_wait_run_loop_; | |
163 scoped_ptr<base::RunLoop> overscroll_completed_wait_run_loop_; | |
164 scoped_ptr<base::RunLoop> selection_changed_wait_run_loop_; | |
165 scoped_ptr<base::RunLoop> gesture_ack_wait_run_loop_; | |
166 scoped_ptr<base::RunLoop> fling_stop_wait_run_loop_; | |
167 | |
168 DISALLOW_COPY_AND_ASSIGN(TestTouchEditableImplAura); | |
169 }; | |
170 | |
171 class TouchEditableImplAuraTest : public ContentBrowserTest { | |
172 public: | |
173 TouchEditableImplAuraTest() {} | |
174 | |
175 protected: | |
176 void SetUpOnMainThread() override { | |
177 ContentBrowserTest::SetUpOnMainThread(); | |
178 aura::client::SetScreenPositionClient(shell()->window()->GetRootWindow(), | |
179 &screen_position_client_); | |
180 } | |
181 | |
182 void SetUpCommandLine(base::CommandLine* command_line) override { | |
183 command_line->AppendSwitch(switches::kEnableTouchEditing); | |
184 } | |
185 | |
186 // Executes the javascript synchronously and makes sure the returned value is | |
187 // freed properly. | |
188 void ExecuteSyncJSFunction(RenderFrameHost* rfh, const std::string& jscript) { | |
189 scoped_ptr<base::Value> value = | |
190 content::ExecuteScriptAndGetValue(rfh, jscript); | |
191 } | |
192 | |
193 // Starts the test server and navigates to the given url. Sets a large enough | |
194 // size to the root window. Returns after the navigation to the url is | |
195 // complete. | |
196 void StartTestWithPage(const std::string& url) { | |
197 ASSERT_TRUE(test_server()->Start()); | |
198 GURL test_url(test_server()->GetURL(url)); | |
199 NavigateToURL(shell(), test_url); | |
200 aura::Window* content = shell()->web_contents()->GetContentNativeView(); | |
201 content->GetHost()->SetBounds(gfx::Rect(800, 600)); | |
202 } | |
203 | |
204 RenderWidgetHostViewAura* GetRenderWidgetHostViewAura( | |
205 TouchEditableImplAura* touch_editable) { | |
206 return touch_editable->rwhva_; | |
207 } | |
208 | |
209 ui::TouchEditingControllerDeprecated* GetTouchSelectionController( | |
210 TouchEditableImplAura* touch_editable) { | |
211 return touch_editable->touch_selection_controller_.get(); | |
212 } | |
213 | |
214 ui::TextInputType GetTextInputType(TouchEditableImplAura* touch_editable) { | |
215 return touch_editable->text_input_type_; | |
216 } | |
217 | |
218 private: | |
219 wm::DefaultScreenPositionClient screen_position_client_; | |
220 | |
221 DISALLOW_COPY_AND_ASSIGN(TouchEditableImplAuraTest); | |
222 }; | |
223 | |
224 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
225 TouchSelectionOriginatingFromWebpageTest) { | |
226 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
227 WebContentsImpl* web_contents = | |
228 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
229 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
230 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>( | |
231 web_contents->GetView()); | |
232 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
233 view_aura->SetTouchEditableForTest(touch_editable); | |
234 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
235 web_contents->GetRenderWidgetHostView()); | |
236 aura::Window* content = web_contents->GetContentNativeView(); | |
237 ui::test::EventGenerator generator(content->GetRootWindow(), content); | |
238 gfx::Rect bounds = content->GetBoundsInRootWindow(); | |
239 | |
240 touch_editable->Reset(); | |
241 ExecuteSyncJSFunction(main_frame, "select_all_text()"); | |
242 touch_editable->WaitForSelectionChangeCallback(); | |
243 | |
244 // Tap inside selection to bring up selection handles. | |
245 generator.GestureTapAt(gfx::Point(bounds.x() + 10, bounds.y() + 10)); | |
246 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
247 | |
248 scoped_ptr<base::Value> value = | |
249 content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
250 std::string selection; | |
251 value->GetAsString(&selection); | |
252 | |
253 // Check if selection handles are showing. | |
254 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
255 EXPECT_STREQ("Some text we can select", selection.c_str()); | |
256 | |
257 // Lets move the handles a bit to modify the selection | |
258 touch_editable->Reset(); | |
259 ui::SelectionBound anchor, focus; | |
260 touch_editable->GetSelectionEndPoints(&anchor, &focus); | |
261 // The distance by which a handle image is offset from the bottom of the | |
262 // selection/text baseline. | |
263 const int kSelectionHandleVerticalVisualOffset = 2; | |
264 int handle_grab_x = bounds.x() + anchor.edge_bottom_rounded().x(); | |
265 int handle_grab_y = bounds.y() + anchor.edge_bottom_rounded().y() + | |
266 kSelectionHandleVerticalVisualOffset + 1; | |
267 generator.GestureScrollSequence( | |
268 gfx::Point(handle_grab_x, handle_grab_y), | |
269 gfx::Point(handle_grab_x + 20, handle_grab_y), | |
270 base::TimeDelta::FromMilliseconds(20), | |
271 5); | |
272 touch_editable->WaitForSelectionChangeCallback(); | |
273 | |
274 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
275 value = content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
276 value->GetAsString(&selection); | |
277 | |
278 // It is hard to tell what exactly the selection would be now. But it would | |
279 // definitely be less than whatever was selected before. | |
280 EXPECT_GT(std::strlen("Some text we can select"), selection.size()); | |
281 } | |
282 | |
283 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
284 TestTouchSelectionHiddenWhenScrolling) { | |
285 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
286 WebContentsImpl* web_contents = | |
287 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
288 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
289 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>( | |
290 web_contents->GetView()); | |
291 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
292 view_aura->SetTouchEditableForTest(touch_editable); | |
293 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
294 web_contents->GetRenderWidgetHostView()); | |
295 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
296 | |
297 // Long press to select word. | |
298 ui::GestureEvent long_press( | |
299 10, | |
300 10, | |
301 0, | |
302 ui::EventTimeForNow(), | |
303 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); | |
304 touch_editable->Reset(); | |
305 rwhva->OnGestureEvent(&long_press); | |
306 touch_editable->WaitForSelectionChangeCallback(); | |
307 | |
308 // Check if selection handles are showing. | |
309 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
310 | |
311 scoped_ptr<base::Value> value = | |
312 content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
313 std::string selection; | |
314 value->GetAsString(&selection); | |
315 EXPECT_STREQ("Some", selection.c_str()); | |
316 | |
317 // Start scrolling. Handles should get hidden. | |
318 ui::GestureEvent scroll_begin( | |
319 10, | |
320 10, | |
321 0, | |
322 ui::EventTimeForNow(), | |
323 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN)); | |
324 rwhva->OnGestureEvent(&scroll_begin); | |
325 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
326 | |
327 // Handles should come back after scroll ends. | |
328 ui::GestureEvent scroll_end( | |
329 10, | |
330 10, | |
331 0, | |
332 ui::EventTimeForNow(), | |
333 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); | |
334 rwhva->OnGestureEvent(&scroll_end); | |
335 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
336 } | |
337 | |
338 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
339 TestTouchSelectionReshownAfterFling) { | |
340 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
341 WebContentsImpl* web_contents = | |
342 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
343 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
344 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>( | |
345 web_contents->GetView()); | |
346 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
347 view_aura->SetTouchEditableForTest(touch_editable); | |
348 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
349 web_contents->GetRenderWidgetHostView()); | |
350 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
351 | |
352 // Long press to select word. | |
353 ui::GestureEvent long_press( | |
354 10, | |
355 10, | |
356 0, | |
357 ui::EventTimeForNow(), | |
358 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); | |
359 touch_editable->Reset(); | |
360 rwhva->OnGestureEvent(&long_press); | |
361 touch_editable->WaitForSelectionChangeCallback(); | |
362 | |
363 // Check if selection handles are showing. | |
364 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
365 | |
366 scoped_ptr<base::Value> value = | |
367 content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
368 std::string selection; | |
369 value->GetAsString(&selection); | |
370 EXPECT_STREQ("Some", selection.c_str()); | |
371 | |
372 // Start scrolling. Handles should get hidden. | |
373 ui::GestureEvent scroll_begin( | |
374 10, | |
375 10, | |
376 0, | |
377 ui::EventTimeForNow(), | |
378 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0)); | |
379 rwhva->OnGestureEvent(&scroll_begin); | |
380 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
381 | |
382 // Start a fling. Handles should come back after fling stops. | |
383 ui::GestureEvent fling_start( | |
384 10, | |
385 10, | |
386 0, | |
387 ui::EventTimeForNow(), | |
388 ui::GestureEventDetails(ui::ET_SCROLL_FLING_START, 1, 0)); | |
389 rwhva->OnGestureEvent(&fling_start); | |
390 touch_editable->WaitForFlingStopCallback(); | |
391 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
392 } | |
393 | |
394 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
395 TestTouchSelectionWhenOverscrolling) { | |
396 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
397 WebContentsImpl* web_contents = | |
398 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
399 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
400 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>( | |
401 web_contents->GetView()); | |
402 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
403 view_aura->SetTouchEditableForTest(touch_editable); | |
404 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
405 web_contents->GetRenderWidgetHostView()); | |
406 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
407 | |
408 // Long press to select word. | |
409 ui::GestureEvent long_press( | |
410 10, | |
411 10, | |
412 0, | |
413 ui::EventTimeForNow(), | |
414 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); | |
415 touch_editable->Reset(); | |
416 rwhva->OnGestureEvent(&long_press); | |
417 touch_editable->WaitForSelectionChangeCallback(); | |
418 | |
419 // Check if selection handles are showing. | |
420 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
421 | |
422 scoped_ptr<base::Value> value = | |
423 content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
424 std::string selection; | |
425 value->GetAsString(&selection); | |
426 EXPECT_STREQ("Some", selection.c_str()); | |
427 | |
428 ui::GestureEvent scroll_begin( | |
429 10, | |
430 10, | |
431 0, | |
432 ui::EventTimeForNow(), | |
433 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0)); | |
434 rwhva->OnGestureEvent(&scroll_begin); | |
435 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
436 | |
437 // Then overscroll starts. OverscrollStarted callback should be called and | |
438 // handles should remain hidden. | |
439 ui::GestureEvent scroll_update( | |
440 210, | |
441 10, | |
442 0, | |
443 ui::EventTimeForNow(), | |
444 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 200, 0)); | |
445 rwhva->OnGestureEvent(&scroll_update); | |
446 touch_editable->WaitForOverscrollStartedCallback(); | |
447 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
448 | |
449 // We might have multiple overscroll-starts in one overscroll session. Handles | |
450 // should still remain hidden. | |
451 touch_editable->OverscrollStarted(); | |
452 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
453 | |
454 // And, finally a scroll-end. An OverscrollCompleted callback should be | |
455 // called and handles should come back. | |
456 ui::GestureEvent scroll_end( | |
457 10, | |
458 210, | |
459 0, | |
460 ui::EventTimeForNow(), | |
461 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); | |
462 rwhva->OnGestureEvent(&scroll_end); | |
463 touch_editable->WaitForOverscrollCompletedCallback(); | |
464 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
465 | |
466 // Now repeat the same sequence, but abort the overscroll by scrolling back | |
467 // before ending the scroll. | |
468 touch_editable->Reset(); | |
469 scroll_begin = ui::GestureEvent( | |
470 10, | |
471 10, | |
472 0, | |
473 ui::EventTimeForNow(), | |
474 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0)); | |
475 rwhva->OnGestureEvent(&scroll_begin); | |
476 | |
477 scroll_update = ui::GestureEvent( | |
478 210, | |
479 10, | |
480 0, | |
481 ui::EventTimeForNow(), | |
482 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, 200, 0)); | |
483 rwhva->OnGestureEvent(&scroll_update); | |
484 touch_editable->WaitForOverscrollStartedCallback(); | |
485 | |
486 // Scroll back. | |
487 ui::GestureEvent scroll_update2( | |
488 10, | |
489 10, | |
490 0, | |
491 ui::EventTimeForNow(), | |
492 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE, -200, 0)); | |
493 rwhva->OnGestureEvent(&scroll_update2); | |
494 // Handles should remain hidden. | |
495 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
496 | |
497 // End the scroll - the overscroll should be cancelled, and we should still | |
498 // receive OverscrollCompleted callback | |
499 scroll_end = ui::GestureEvent( | |
500 10, | |
501 10, | |
502 0, | |
503 ui::EventTimeForNow(), | |
504 ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END)); | |
505 rwhva->OnGestureEvent(&scroll_end); | |
506 touch_editable->WaitForOverscrollCompletedCallback(); | |
507 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
508 } | |
509 | |
510 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
511 TouchSelectionOnLongPressTest) { | |
512 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
513 WebContentsImpl* web_contents = | |
514 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
515 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
516 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>( | |
517 web_contents->GetView()); | |
518 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
519 view_aura->SetTouchEditableForTest(touch_editable); | |
520 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
521 web_contents->GetRenderWidgetHostView()); | |
522 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
523 | |
524 // Long press to select word. | |
525 ui::GestureEvent long_press( | |
526 10, | |
527 10, | |
528 0, | |
529 ui::EventTimeForNow(), | |
530 ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS)); | |
531 touch_editable->Reset(); | |
532 rwhva->OnGestureEvent(&long_press); | |
533 touch_editable->WaitForSelectionChangeCallback(); | |
534 | |
535 // Check if selection handles are showing. | |
536 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
537 | |
538 scoped_ptr<base::Value> value = | |
539 content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
540 std::string selection; | |
541 value->GetAsString(&selection); | |
542 EXPECT_STREQ("Some", selection.c_str()); | |
543 } | |
544 | |
545 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
546 NoTouchSelectionOnDoubleTapTest) { | |
547 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
548 WebContentsImpl* web_contents = | |
549 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
550 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
551 WebContentsViewAura* view_aura = | |
552 static_cast<WebContentsViewAura*>(web_contents->GetView()); | |
553 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
554 view_aura->SetTouchEditableForTest(touch_editable); | |
555 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
556 web_contents->GetRenderWidgetHostView()); | |
557 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
558 | |
559 // Double-tap to select word. | |
560 ui::GestureEventDetails details(ui::ET_GESTURE_TAP); | |
561 details.set_tap_count(2); | |
562 ui::GestureEvent double_tap(10, 10, 0, ui::EventTimeForNow(), details); | |
563 touch_editable->Reset(); | |
564 rwhva->OnGestureEvent(&double_tap); | |
565 touch_editable->WaitForSelectionChangeCallback(); | |
566 | |
567 // Make sure touch selection handles are not showing. | |
568 EXPECT_FALSE(GetTouchSelectionController(touch_editable)); | |
569 | |
570 scoped_ptr<base::Value> value = | |
571 content::ExecuteScriptAndGetValue(main_frame, "get_selection()"); | |
572 std::string selection; | |
573 value->GetAsString(&selection); | |
574 EXPECT_STREQ("Some", selection.c_str()); | |
575 } | |
576 | |
577 #if defined(OS_CHROMEOS) | |
578 // http://crbug.com/396509 | |
579 #define MAYBE_TouchCursorInTextfieldTest DISABLED_TouchCursorInTextfieldTest | |
580 #else | |
581 #define MAYBE_TouchCursorInTextfieldTest TouchCursorInTextfieldTest | |
582 #endif | |
583 IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest, | |
584 MAYBE_TouchCursorInTextfieldTest) { | |
585 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html")); | |
586 WebContentsImpl* web_contents = | |
587 static_cast<WebContentsImpl*>(shell()->web_contents()); | |
588 RenderFrameHost* main_frame = web_contents->GetMainFrame(); | |
589 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>( | |
590 web_contents->GetView()); | |
591 TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura; | |
592 view_aura->SetTouchEditableForTest(touch_editable); | |
593 RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>( | |
594 web_contents->GetRenderWidgetHostView()); | |
595 aura::Window* content = web_contents->GetContentNativeView(); | |
596 ui::test::EventGenerator generator(content->GetRootWindow(), content); | |
597 gfx::Rect bounds = content->GetBoundsInRootWindow(); | |
598 EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva); | |
599 | |
600 ExecuteSyncJSFunction(main_frame, "focus_textfield()"); | |
601 touch_editable->WaitForSelectionChangeCallback(); | |
602 | |
603 // Tap textfield | |
604 touch_editable->Reset(); | |
605 generator.GestureTapAt(gfx::Point(bounds.x() + 50, bounds.y() + 40)); | |
606 // Tap Down acks are sent synchronously, while Tap acks are asynchronous. | |
607 touch_editable->WaitForGestureAck(WebInputEvent::GestureTap); | |
608 touch_editable->WaitForSelectionChangeCallback(); | |
609 touch_editable->Reset(); | |
610 | |
611 // Check if cursor handle is showing. | |
612 EXPECT_NE(ui::TEXT_INPUT_TYPE_NONE, GetTextInputType(touch_editable)); | |
613 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
614 | |
615 scoped_ptr<base::Value> value = | |
616 content::ExecuteScriptAndGetValue(main_frame, "get_cursor_position()"); | |
617 int cursor_pos = -1; | |
618 value->GetAsInteger(&cursor_pos); | |
619 EXPECT_NE(-1, cursor_pos); | |
620 | |
621 // Move the cursor handle. | |
622 generator.GestureScrollSequence( | |
623 gfx::Point(50, 59), | |
624 gfx::Point(10, 59), | |
625 base::TimeDelta::FromMilliseconds(20), | |
626 1); | |
627 touch_editable->WaitForSelectionChangeCallback(); | |
628 EXPECT_TRUE(GetTouchSelectionController(touch_editable)); | |
629 value = content::ExecuteScriptAndGetValue(main_frame, | |
630 "get_cursor_position()"); | |
631 int new_cursor_pos = -1; | |
632 value->GetAsInteger(&new_cursor_pos); | |
633 EXPECT_NE(-1, new_cursor_pos); | |
634 // Cursor should have moved. | |
635 EXPECT_NE(new_cursor_pos, cursor_pos); | |
636 } | |
637 | |
638 } // namespace content | |
OLD | NEW |