1 // Copyright 2014 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.
5 #include "content/browser/renderer_host/input/touch_selection_controller.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/events/test/mock_motion_event.h"
10 using ui::test::MockMotionEvent;
15 class MockTouchHandleDrawable : public TouchHandleDrawable {
17 explicit MockTouchHandleDrawable(bool* contains_point)
18 : intersects_rect_(contains_point) {}
19 virtual ~MockTouchHandleDrawable() {}
20 virtual void SetEnabled(bool enabled) OVERRIDE {}
21 virtual void SetOrientation(TouchHandleOrientation orientation) OVERRIDE {}
22 virtual void SetAlpha(float alpha) OVERRIDE {}
23 virtual void SetFocus(const gfx::PointF& position) OVERRIDE {}
24 virtual void SetVisible(bool visible) OVERRIDE {}
25 virtual bool IntersectsWith(const gfx::RectF& rect) const OVERRIDE {
26 return *intersects_rect_;
30 bool* intersects_rect_;
35 class TouchSelectionControllerTest : public testing::Test,
36 public TouchSelectionControllerClient {
38 TouchSelectionControllerTest()
39 : last_event_(SELECTION_CLEARED),
41 selection_moved_(false),
42 needs_animate_(false),
43 animation_enabled_(true),
44 dragging_enabled_(false) {}
46 virtual ~TouchSelectionControllerTest() {}
48 // testing::Test implementation.
49 virtual void SetUp() OVERRIDE {
50 controller_.reset(new TouchSelectionController(this));
53 virtual void TearDown() OVERRIDE { controller_.reset(); }
55 // TouchSelectionControllerClient implementation.
57 virtual bool SupportsAnimation() const OVERRIDE { return animation_enabled_; }
59 virtual void SetNeedsAnimate() OVERRIDE { needs_animate_ = true; }
61 virtual void MoveCaret(const gfx::PointF& position) OVERRIDE {
63 caret_position_ = position;
66 virtual void SelectBetweenCoordinates(const gfx::PointF& start,
67 const gfx::PointF& end) OVERRIDE {
68 selection_moved_ = true;
69 selection_start_ = start;
73 virtual void OnSelectionEvent(SelectionEventType event,
74 const gfx::PointF& end_position) OVERRIDE {
76 last_event_start_ = end_position;
79 virtual scoped_ptr<TouchHandleDrawable> CreateDrawable() OVERRIDE {
80 return scoped_ptr<TouchHandleDrawable>(
81 new MockTouchHandleDrawable(&dragging_enabled_));
84 void SetAnimationEnabled(bool enabled) { animation_enabled_ = enabled; }
85 void SetDraggingEnabled(bool enabled) { dragging_enabled_ = enabled; }
87 void ClearSelection() {
88 controller_->OnSelectionBoundsChanged(gfx::RectF(),
89 TOUCH_HANDLE_ORIENTATION_UNDEFINED,
92 TOUCH_HANDLE_ORIENTATION_UNDEFINED,
96 void ClearInsertion() { ClearSelection(); }
98 void ChangeInsertion(const gfx::RectF& rect,
99 TouchHandleOrientation orientation,
101 controller_->OnSelectionBoundsChanged(
102 rect, orientation, visible, rect, orientation, visible);
105 void ChangeInsertion(const gfx::RectF& rect, bool visible) {
106 ChangeInsertion(rect, TOUCH_HANDLE_CENTER, visible);
109 void ChangeSelection(const gfx::RectF& start_rect,
110 TouchHandleOrientation start_orientation,
112 const gfx::RectF& end_rect,
113 TouchHandleOrientation end_orientation,
115 controller_->OnSelectionBoundsChanged(start_rect,
123 void ChangeSelection(const gfx::RectF& start_rect,
125 const gfx::RectF& end_rect,
127 ChangeSelection(start_rect,
136 base::TimeTicks now = base::TimeTicks::Now();
137 while (needs_animate_) {
138 needs_animate_ = controller_->Animate(now);
139 now += base::TimeDelta::FromMilliseconds(16);
143 bool GetAndResetNeedsAnimate() {
144 bool needs_animate = needs_animate_;
146 return needs_animate;
149 bool GetAndResetCaretMoved() {
150 bool moved = caret_moved_;
151 caret_moved_ = false;
155 bool GetAndResetSelectionMoved() {
156 bool moved = selection_moved_;
157 selection_moved_ = false;
161 const gfx::PointF& GetLastCaretPosition() const { return caret_position_; }
162 const gfx::PointF& GetLastSelectionStart() const { return selection_start_; }
163 const gfx::PointF& GetLastSelectionEnd() const { return selection_end_; }
164 SelectionEventType GetLastEventType() const { return last_event_; }
165 const gfx::PointF& GetLastEventAnchor() const { return last_event_start_; }
167 TouchSelectionController& controller() { return *controller_; }
170 gfx::PointF last_event_start_;
171 gfx::PointF caret_position_;
172 gfx::PointF selection_start_;
173 gfx::PointF selection_end_;
174 SelectionEventType last_event_;
176 bool selection_moved_;
178 bool animation_enabled_;
179 bool dragging_enabled_;
180 scoped_ptr<TouchSelectionController> controller_;
183 TEST_F(TouchSelectionControllerTest, InsertionBasic) {
184 gfx::RectF insertion_rect(5, 5, 0, 10);
187 // Insertion events are ignored until automatic showing is enabled.
188 ChangeInsertion(insertion_rect, visible);
189 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
190 controller().OnTapEvent();
192 // Insertion events are ignored until the selection region is marked editable.
193 ChangeInsertion(insertion_rect, visible);
194 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
196 controller().OnTapEvent();
197 controller().OnSelectionEditable(true);
198 ChangeInsertion(insertion_rect, visible);
199 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
200 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
202 insertion_rect.Offset(1, 0);
203 ChangeInsertion(insertion_rect, visible);
204 EXPECT_EQ(INSERTION_MOVED, GetLastEventType());
205 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
207 insertion_rect.Offset(0, 1);
208 ChangeInsertion(insertion_rect, visible);
209 EXPECT_EQ(INSERTION_MOVED, GetLastEventType());
210 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
213 EXPECT_EQ(INSERTION_CLEARED, GetLastEventType());
216 TEST_F(TouchSelectionControllerTest, InsertionClearedWhenNoLongerEditable) {
217 gfx::RectF insertion_rect(5, 5, 0, 10);
219 controller().OnTapEvent();
220 controller().OnSelectionEditable(true);
222 ChangeInsertion(insertion_rect, visible);
223 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
224 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
226 controller().OnSelectionEditable(false);
227 EXPECT_EQ(INSERTION_CLEARED, GetLastEventType());
230 TEST_F(TouchSelectionControllerTest, InsertionStaysHiddenIfEmptyRegionTapped) {
231 gfx::RectF insertion_rect(5, 5, 0, 10);
233 controller().OnSelectionEditable(true);
235 // Taps should be ignored if they're in an empty editable region.
236 controller().OnTapEvent();
237 controller().OnSelectionEmpty(true);
238 ChangeInsertion(insertion_rect, visible);
239 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
241 // Once the region becomes editable, taps should show the insertion handle.
242 controller().OnTapEvent();
243 controller().OnSelectionEmpty(false);
244 ChangeInsertion(insertion_rect, visible);
245 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
246 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
248 // Reset the selection.
249 controller().HideAndDisallowShowingAutomatically();
250 EXPECT_EQ(INSERTION_CLEARED, GetLastEventType());
252 // Long-pressing should show the handle even if the editable region is empty.
253 insertion_rect.Offset(2, -2);
254 controller().OnLongPressEvent();
255 controller().OnSelectionEmpty(true);
256 ChangeInsertion(insertion_rect, visible);
257 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
258 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
261 TEST_F(TouchSelectionControllerTest, InsertionAppearsAfterTapFollowingTyping) {
262 gfx::RectF insertion_rect(5, 5, 0, 10);
265 // Simulate the user tapping an empty text field.
266 controller().OnTapEvent();
267 controller().OnSelectionEditable(true);
268 controller().OnSelectionEmpty(true);
269 ChangeInsertion(insertion_rect, visible);
270 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
272 // Simulate the cursor moving while a user is typing.
273 insertion_rect.Offset(10, 0);
274 controller().OnSelectionEmpty(false);
275 ChangeInsertion(insertion_rect, visible);
276 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
278 // If the user taps the *same* position as the cursor at the end of the text
279 // entry, the handle should appear.
280 controller().OnTapEvent();
281 ChangeInsertion(insertion_rect, visible);
282 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
283 EXPECT_EQ(insertion_rect.bottom_left(), GetLastEventAnchor());
286 TEST_F(TouchSelectionControllerTest, InsertionToSelectionTransition) {
287 controller().OnLongPressEvent();
288 controller().OnSelectionEditable(true);
290 gfx::RectF start_rect(5, 5, 0, 10);
291 gfx::RectF end_rect(50, 5, 0, 10);
294 ChangeInsertion(start_rect, visible);
295 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
296 EXPECT_EQ(start_rect.bottom_left(), GetLastEventAnchor());
298 ChangeSelection(start_rect, visible, end_rect, visible);
299 EXPECT_EQ(SELECTION_SHOWN, GetLastEventType());
300 EXPECT_EQ(start_rect.bottom_left(), GetLastEventAnchor());
302 ChangeInsertion(end_rect, visible);
303 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
304 EXPECT_EQ(end_rect.bottom_left(), GetLastEventAnchor());
306 controller().HideAndDisallowShowingAutomatically();
307 EXPECT_EQ(INSERTION_CLEARED, GetLastEventType());
309 controller().OnTapEvent();
310 ChangeInsertion(end_rect, visible);
311 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
312 EXPECT_EQ(end_rect.bottom_left(), GetLastEventAnchor());
315 TEST_F(TouchSelectionControllerTest, InsertionDragged) {
316 base::TimeTicks event_time = base::TimeTicks::Now();
317 controller().OnTapEvent();
318 controller().OnSelectionEditable(true);
320 // The touch sequence should not be handled if insertion is not active.
321 MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
322 EXPECT_FALSE(controller().WillHandleTouchEvent(event));
324 float line_height = 10.f;
325 gfx::RectF start_rect(10, 0, 0, line_height);
327 ChangeInsertion(start_rect, visible);
328 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
329 EXPECT_EQ(start_rect.bottom_left(), GetLastEventAnchor());
331 // The touch sequence should be handled only if the drawable reports a hit.
332 EXPECT_FALSE(controller().WillHandleTouchEvent(event));
333 SetDraggingEnabled(true);
334 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
335 EXPECT_FALSE(GetAndResetCaretMoved());
337 // The MoveCaret() result should reflect the movement.
338 // The reported position is offset from the center of |start_rect|.
339 gfx::PointF start_offset = start_rect.CenterPoint();
340 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 5);
341 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
342 EXPECT_TRUE(GetAndResetCaretMoved());
343 EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
345 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 5, 5);
346 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
347 EXPECT_TRUE(GetAndResetCaretMoved());
348 EXPECT_EQ(start_offset + gfx::Vector2dF(5, 5), GetLastCaretPosition());
350 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 10, 10);
351 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
352 EXPECT_TRUE(GetAndResetCaretMoved());
353 EXPECT_EQ(start_offset + gfx::Vector2dF(10, 10), GetLastCaretPosition());
355 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
356 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
357 EXPECT_FALSE(GetAndResetCaretMoved());
359 // Once the drag is complete, no more touch events should be consumed until
360 // the next ACTION_DOWN.
361 EXPECT_FALSE(controller().WillHandleTouchEvent(event));
364 TEST_F(TouchSelectionControllerTest, InsertionTapped) {
365 base::TimeTicks event_time = base::TimeTicks::Now();
366 controller().OnTapEvent();
367 controller().OnSelectionEditable(true);
368 SetDraggingEnabled(true);
370 gfx::RectF start_rect(10, 0, 0, 10);
372 ChangeInsertion(start_rect, visible);
373 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
375 MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
376 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
377 //TODO(AKV): this test case has to be modified once crbug.com/394093 is fixed.
378 EXPECT_EQ(INSERTION_DRAG_STARTED, GetLastEventType());
380 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
381 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
382 EXPECT_EQ(INSERTION_TAPPED, GetLastEventType());
384 // Reset the insertion.
386 controller().OnTapEvent();
387 ChangeInsertion(start_rect, visible);
388 ASSERT_EQ(INSERTION_SHOWN, GetLastEventType());
390 // No tap should be signalled if the time between DOWN and UP was too long.
391 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
392 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
393 event = MockMotionEvent(MockMotionEvent::ACTION_UP,
394 event_time + base::TimeDelta::FromSeconds(1),
397 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
398 EXPECT_EQ(INSERTION_DRAG_STARTED, GetLastEventType());
400 // Reset the insertion.
402 controller().OnTapEvent();
403 ChangeInsertion(start_rect, visible);
404 ASSERT_EQ(INSERTION_SHOWN, GetLastEventType());
406 // No tap should be signalled if the touch sequence is cancelled.
407 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
408 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
409 event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL, event_time, 0, 0);
410 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
411 EXPECT_EQ(INSERTION_DRAG_STARTED, GetLastEventType());
414 TEST_F(TouchSelectionControllerTest, InsertionNotResetByRepeatedTapOrPress) {
415 base::TimeTicks event_time = base::TimeTicks::Now();
416 controller().OnTapEvent();
417 controller().OnSelectionEditable(true);
418 SetDraggingEnabled(true);
420 gfx::RectF anchor_rect(10, 0, 0, 10);
422 ChangeInsertion(anchor_rect, visible);
423 EXPECT_EQ(INSERTION_SHOWN, GetLastEventType());
424 EXPECT_EQ(anchor_rect.bottom_left(), GetLastEventAnchor());
426 // Tapping again shouldn't reset the active insertion point.
427 controller().OnTapEvent();
428 MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
429 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
430 EXPECT_EQ(INSERTION_DRAG_STARTED, GetLastEventType());
431 EXPECT_EQ(anchor_rect.bottom_left(), GetLastEventAnchor());
433 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
434 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
435 EXPECT_EQ(INSERTION_TAPPED, GetLastEventType());
436 EXPECT_EQ(anchor_rect.bottom_left(), GetLastEventAnchor());
438 anchor_rect.Offset(5, 15);
439 ChangeInsertion(anchor_rect, visible);
440 EXPECT_EQ(INSERTION_MOVED, GetLastEventType());
441 EXPECT_EQ(anchor_rect.bottom_left(), GetLastEventAnchor());
443 // Pressing shouldn't reset the active insertion point.
444 controller().OnLongPressEvent();
445 controller().OnSelectionEmpty(true);
446 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
447 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
448 EXPECT_EQ(INSERTION_DRAG_STARTED, GetLastEventType());
449 EXPECT_EQ(anchor_rect.bottom_left(), GetLastEventAnchor());
451 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
452 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
453 EXPECT_EQ(INSERTION_TAPPED, GetLastEventType());
454 EXPECT_EQ(anchor_rect.bottom_left(), GetLastEventAnchor());
457 TEST_F(TouchSelectionControllerTest, SelectionBasic) {
458 gfx::RectF start_rect(5, 5, 0, 10);
459 gfx::RectF end_rect(50, 5, 0, 10);
462 // Selection events are ignored until automatic showing is enabled.
463 ChangeSelection(start_rect, visible, end_rect, visible);
464 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
466 controller().OnLongPressEvent();
467 ChangeSelection(start_rect, visible, end_rect, visible);
468 EXPECT_EQ(SELECTION_SHOWN, GetLastEventType());
469 EXPECT_EQ(start_rect.bottom_left(), GetLastEventAnchor());
471 start_rect.Offset(1, 0);
472 ChangeSelection(start_rect, visible, end_rect, visible);
473 // Selection movement does not currently trigger a separate event.
474 EXPECT_EQ(SELECTION_SHOWN, GetLastEventType());
477 EXPECT_EQ(SELECTION_CLEARED, GetLastEventType());
478 EXPECT_EQ(gfx::PointF(), GetLastEventAnchor());
481 TEST_F(TouchSelectionControllerTest, SelectionDragged) {
482 base::TimeTicks event_time = base::TimeTicks::Now();
483 controller().OnLongPressEvent();
485 // The touch sequence should not be handled if selection is not active.
486 MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
487 EXPECT_FALSE(controller().WillHandleTouchEvent(event));
489 float line_height = 10.f;
490 gfx::RectF start_rect(0, 0, 0, line_height);
491 gfx::RectF end_rect(50, 0, 0, line_height);
493 ChangeSelection(start_rect, visible, end_rect, visible);
494 EXPECT_EQ(SELECTION_SHOWN, GetLastEventType());
495 EXPECT_EQ(start_rect.bottom_left(), GetLastEventAnchor());
497 // The touch sequence should be handled only if the drawable reports a hit.
498 EXPECT_FALSE(controller().WillHandleTouchEvent(event));
499 SetDraggingEnabled(true);
500 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
501 EXPECT_FALSE(GetAndResetSelectionMoved());
503 // The SelectBetweenCoordinates() result should reflect the movement. Note
504 // that the start coordinate will always reflect the "fixed" handle's
505 // position, in this case the position from |end_rect|.
506 // Note that the reported position is offset from the center of the
507 // input rects (i.e., the middle of the corresponding text line).
508 gfx::PointF fixed_offset = end_rect.CenterPoint();
509 gfx::PointF start_offset = start_rect.CenterPoint();
510 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 5);
511 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
512 EXPECT_EQ(SELECTION_DRAG_STARTED, GetLastEventType());
513 EXPECT_TRUE(GetAndResetSelectionMoved());
514 EXPECT_EQ(fixed_offset, GetLastSelectionStart());
515 EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
517 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 5, 5);
518 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
519 EXPECT_TRUE(GetAndResetSelectionMoved());
520 EXPECT_EQ(fixed_offset, GetLastSelectionStart());
521 EXPECT_EQ(start_offset + gfx::Vector2dF(5, 5), GetLastSelectionEnd());
523 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 10, 5);
524 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
525 EXPECT_TRUE(GetAndResetSelectionMoved());
526 EXPECT_EQ(fixed_offset, GetLastSelectionStart());
527 EXPECT_EQ(start_offset + gfx::Vector2dF(10, 5), GetLastSelectionEnd());
529 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
530 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
531 EXPECT_EQ(SELECTION_DRAG_STOPPED, GetLastEventType());
532 EXPECT_FALSE(GetAndResetSelectionMoved());
534 // Once the drag is complete, no more touch events should be consumed until
535 // the next ACTION_DOWN.
536 EXPECT_FALSE(controller().WillHandleTouchEvent(event));
539 TEST_F(TouchSelectionControllerTest, SelectionDraggedWithOverlap) {
540 base::TimeTicks event_time = base::TimeTicks::Now();
541 controller().OnLongPressEvent();
543 float line_height = 10.f;
544 gfx::RectF start_rect(0, 0, 0, line_height);
545 gfx::RectF end_rect(50, 0, 0, line_height);
547 ChangeSelection(start_rect, visible, end_rect, visible);
548 EXPECT_EQ(SELECTION_SHOWN, GetLastEventType());
549 EXPECT_EQ(start_rect.bottom_left(), GetLastEventAnchor());
551 // The ACTION_DOWN should lock to the closest handle.
552 gfx::PointF end_offset = end_rect.CenterPoint();
553 gfx::PointF fixed_offset = start_rect.CenterPoint();
554 float touch_down_x = (end_offset.x() + fixed_offset.x()) / 2 + 1.f;
555 MockMotionEvent event(
556 MockMotionEvent::ACTION_DOWN, event_time, touch_down_x, 0);
557 SetDraggingEnabled(true);
558 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
559 EXPECT_EQ(SELECTION_DRAG_STARTED, GetLastEventType());
560 EXPECT_FALSE(GetAndResetSelectionMoved());
562 // Even though the ACTION_MOVE is over the start handle, it should continue
563 // targetting the end handle that consumed the ACTION_DOWN.
564 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 0);
565 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
566 EXPECT_TRUE(GetAndResetSelectionMoved());
567 EXPECT_EQ(fixed_offset, GetLastSelectionStart());
568 EXPECT_EQ(end_offset - gfx::Vector2dF(touch_down_x, 0),
569 GetLastSelectionEnd());
571 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
572 EXPECT_TRUE(controller().WillHandleTouchEvent(event));
573 EXPECT_EQ(SELECTION_DRAG_STOPPED, GetLastEventType());
574 EXPECT_FALSE(GetAndResetSelectionMoved());
577 TEST_F(TouchSelectionControllerTest, Animation) {
578 controller().OnTapEvent();
579 controller().OnSelectionEditable(true);
581 gfx::RectF insertion_rect(5, 5, 0, 10);
584 ChangeInsertion(insertion_rect, visible);
585 EXPECT_FALSE(GetAndResetNeedsAnimate());
588 ChangeInsertion(insertion_rect, visible);
589 EXPECT_TRUE(GetAndResetNeedsAnimate());
592 ChangeInsertion(insertion_rect, visible);
593 EXPECT_TRUE(GetAndResetNeedsAnimate());
595 // If the handles are explicity hidden, no animation should be triggered.
596 controller().HideAndDisallowShowingAutomatically();
597 EXPECT_FALSE(GetAndResetNeedsAnimate());
599 // If the client doesn't support animation, no animation should be triggered.
600 SetAnimationEnabled(false);
601 controller().OnTapEvent();
603 ChangeInsertion(insertion_rect, visible);
604 EXPECT_FALSE(GetAndResetNeedsAnimate());
607 TEST_F(TouchSelectionControllerTest, TemporarilyHidden) {
608 controller().OnTapEvent();
609 controller().OnSelectionEditable(true);
611 gfx::RectF insertion_rect(5, 5, 0, 10);
614 ChangeInsertion(insertion_rect, visible);
615 EXPECT_FALSE(GetAndResetNeedsAnimate());
617 controller().SetTemporarilyHidden(true);
618 EXPECT_TRUE(GetAndResetNeedsAnimate());
621 ChangeInsertion(insertion_rect, visible);
622 EXPECT_FALSE(GetAndResetNeedsAnimate());
625 ChangeInsertion(insertion_rect, visible);
626 EXPECT_FALSE(GetAndResetNeedsAnimate());
628 controller().SetTemporarilyHidden(false);
629 EXPECT_TRUE(GetAndResetNeedsAnimate());
632 } // namespace content