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

Side by Side Diff: third_party/WebKit/Source/core/input/EventHandlerTest.cpp

Issue 2664253002: Revert "Blink handle selection handle visibility" (Closed)
Patch Set: Created 3 years, 10 months 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "core/input/EventHandler.h" 5 #include "core/input/EventHandler.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/dom/Range.h" 8 #include "core/dom/Range.h"
9 #include "core/editing/Editor.h" 9 #include "core/editing/Editor.h"
10 #include "core/editing/FrameSelection.h" 10 #include "core/editing/FrameSelection.h"
11 #include "core/frame/FrameView.h" 11 #include "core/frame/FrameView.h"
12 #include "core/frame/LocalFrame.h" 12 #include "core/frame/LocalFrame.h"
13 #include "core/frame/Settings.h" 13 #include "core/frame/Settings.h"
14 #include "core/page/AutoscrollController.h" 14 #include "core/page/AutoscrollController.h"
15 #include "core/page/Page.h" 15 #include "core/page/Page.h"
16 #include "core/testing/DummyPageHolder.h" 16 #include "core/testing/DummyPageHolder.h"
17 #include "platform/PlatformMouseEvent.h" 17 #include "platform/PlatformMouseEvent.h"
18 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
19 #include <memory> 19 #include <memory>
20 20
21 namespace blink { 21 namespace blink {
22 22
23 class EventHandlerTest : public ::testing::Test { 23 class EventHandlerTest : public ::testing::Test {
24 protected: 24 protected:
25 void SetUp() override; 25 void SetUp() override;
26 26
27 Page& page() const { return m_dummyPageHolder->page(); } 27 Page& page() const { return m_dummyPageHolder->page(); }
28 Document& document() const { return m_dummyPageHolder->document(); } 28 Document& document() const { return m_dummyPageHolder->document(); }
29 FrameSelection& selection() const { return document().frame()->selection(); }
30 29
31 void setHtmlInnerHTML(const char* htmlContent); 30 void setHtmlInnerHTML(const char* htmlContent);
32 31
33 private: 32 private:
34 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; 33 std::unique_ptr<DummyPageHolder> m_dummyPageHolder;
35 }; 34 };
36 35
37 class TapEventBuilder : public WebGestureEvent { 36 class TapEventBuilder : public WebGestureEvent {
38 public: 37 public:
39 TapEventBuilder(IntPoint position, int tapCount) 38 TapEventBuilder(IntPoint position, int tapCount)
40 : WebGestureEvent(WebInputEvent::GestureTap, 39 : WebGestureEvent(WebInputEvent::GestureTap,
41 WebInputEvent::NoModifiers, 40 WebInputEvent::NoModifiers,
42 TimeTicks::Now().InSeconds()) { 41 TimeTicks::Now().InSeconds()) {
43 x = globalX = position.x(); 42 x = globalX = position.x();
44 y = globalY = position.y(); 43 y = globalY = position.y();
45 sourceDevice = WebGestureDeviceTouchscreen; 44 sourceDevice = WebGestureDeviceTouchscreen;
46 data.tap.tapCount = tapCount; 45 data.tap.tapCount = tapCount;
47 data.tap.width = 5; 46 data.tap.width = 5;
48 data.tap.height = 5; 47 data.tap.height = 5;
49 m_frameScale = 1; 48 m_frameScale = 1;
50 } 49 }
51 }; 50 };
52 51
53 class LongPressEventBuilder : public WebGestureEvent {
54 public:
55 LongPressEventBuilder(IntPoint position) : WebGestureEvent() {
56 m_type = WebInputEvent::GestureLongPress;
57 x = globalX = position.x();
58 y = globalY = position.y();
59 sourceDevice = WebGestureDeviceTouchscreen;
60 data.longPress.width = 5;
61 data.longPress.height = 5;
62 m_frameScale = 1;
63 }
64 };
65
66 class MousePressEventBuilder : public PlatformMouseEvent {
67 public:
68 MousePressEventBuilder(IntPoint position,
69 int clickCount,
70 WebMouseEvent::Button button)
71 : PlatformMouseEvent(position,
72 position,
73 button,
74 PlatformEvent::MousePressed,
75 clickCount,
76 static_cast<PlatformEvent::Modifiers>(0),
77 TimeTicks::Now()) {}
78 };
79
80 void EventHandlerTest::SetUp() { 52 void EventHandlerTest::SetUp() {
81 m_dummyPageHolder = DummyPageHolder::create(IntSize(300, 400)); 53 m_dummyPageHolder = DummyPageHolder::create(IntSize(300, 400));
82 } 54 }
83 55
84 void EventHandlerTest::setHtmlInnerHTML(const char* htmlContent) { 56 void EventHandlerTest::setHtmlInnerHTML(const char* htmlContent) {
85 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent)); 57 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent));
86 document().view()->updateAllLifecyclePhases(); 58 document().view()->updateAllLifecyclePhases();
87 } 59 }
88 60
89 TEST_F(EventHandlerTest, dragSelectionAfterScroll) { 61 TEST_F(EventHandlerTest, dragSelectionAfterScroll) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 page().autoscrollController().animate(WTF::monotonicallyIncreasingTime()); 93 page().autoscrollController().animate(WTF::monotonicallyIncreasingTime());
122 page().animator().serviceScriptedAnimations( 94 page().animator().serviceScriptedAnimations(
123 WTF::monotonicallyIncreasingTime()); 95 WTF::monotonicallyIncreasingTime());
124 96
125 PlatformMouseEvent mouseUpEvent( 97 PlatformMouseEvent mouseUpEvent(
126 IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left, 98 IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
127 PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0), 99 PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0),
128 TimeTicks::Now()); 100 TimeTicks::Now());
129 document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent); 101 document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent);
130 102
131 ASSERT_TRUE(selection().isRange()); 103 FrameSelection& selection = document().frame()->selection();
104 ASSERT_TRUE(selection.isRange());
132 Range* range = 105 Range* range =
133 createRange(selection().selection().toNormalizedEphemeralRange()); 106 createRange(selection.selection().toNormalizedEphemeralRange());
134 ASSERT_TRUE(range); 107 ASSERT_TRUE(range);
135 EXPECT_EQ("Line 1\nLine 2", range->text()); 108 EXPECT_EQ("Line 1\nLine 2", range->text());
136 } 109 }
137 110
138 TEST_F(EventHandlerTest, multiClickSelectionFromTap) { 111 TEST_F(EventHandlerTest, multiClickSelectionFromTap) {
139 setHtmlInnerHTML( 112 setHtmlInnerHTML(
140 "<style> body { margin: 0px; } .line { display: block; width: 300px; " 113 "<style> body { margin: 0px; } .line { display: block; width: 300px; "
141 "height: 30px; } </style>" 114 "height: 30px; } </style>"
142 "<body contenteditable='true'><span class='line' id='line'>One Two " 115 "<body contenteditable='true'><span class='line' id='line'>One Two "
143 "Three</span></body>"); 116 "Three</span></body>");
144 117
118 FrameSelection& selection = document().frame()->selection();
145 Node* line = document().getElementById("line")->firstChild(); 119 Node* line = document().getElementById("line")->firstChild();
146 120
147 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1); 121 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1);
148 document().frame()->eventHandler().handleGestureEvent(singleTapEvent); 122 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
149 ASSERT_TRUE(selection().isCaret()); 123 ASSERT_TRUE(selection.isCaret());
150 EXPECT_EQ(Position(line, 0), selection().start()); 124 EXPECT_EQ(Position(line, 0), selection.start());
151 125
152 // Multi-tap events on editable elements should trigger selection, just 126 // Multi-tap events on editable elements should trigger selection, just
153 // like multi-click events. 127 // like multi-click events.
154 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2); 128 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2);
155 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent); 129 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent);
156 ASSERT_TRUE(selection().isRange()); 130 ASSERT_TRUE(selection.isRange());
157 EXPECT_EQ(Position(line, 0), selection().start()); 131 EXPECT_EQ(Position(line, 0), selection.start());
158 if (document().frame()->editor().isSelectTrailingWhitespaceEnabled()) { 132 if (document().frame()->editor().isSelectTrailingWhitespaceEnabled()) {
159 EXPECT_EQ(Position(line, 4), selection().end()); 133 EXPECT_EQ(Position(line, 4), selection.end());
160 EXPECT_EQ("One ", WebString(selection().selectedText()).utf8()); 134 EXPECT_EQ("One ", WebString(selection.selectedText()).utf8());
161 } else { 135 } else {
162 EXPECT_EQ(Position(line, 3), selection().end()); 136 EXPECT_EQ(Position(line, 3), selection.end());
163 EXPECT_EQ("One", WebString(selection().selectedText()).utf8()); 137 EXPECT_EQ("One", WebString(selection.selectedText()).utf8());
164 } 138 }
165 139
166 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3); 140 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3);
167 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent); 141 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent);
168 ASSERT_TRUE(selection().isRange()); 142 ASSERT_TRUE(selection.isRange());
169 EXPECT_EQ(Position(line, 0), selection().start()); 143 EXPECT_EQ(Position(line, 0), selection.start());
170 EXPECT_EQ(Position(line, 13), selection().end()); 144 EXPECT_EQ(Position(line, 13), selection.end());
171 EXPECT_EQ("One Two Three", WebString(selection().selectedText()).utf8()); 145 EXPECT_EQ("One Two Three", WebString(selection.selectedText()).utf8());
172 } 146 }
173 147
174 TEST_F(EventHandlerTest, multiClickSelectionFromTapDisabledIfNotEditable) { 148 TEST_F(EventHandlerTest, multiClickSelectionFromTapDisabledIfNotEditable) {
175 setHtmlInnerHTML( 149 setHtmlInnerHTML(
176 "<style> body { margin: 0px; } .line { display: block; width: 300px; " 150 "<style> body { margin: 0px; } .line { display: block; width: 300px; "
177 "height: 30px; } </style>" 151 "height: 30px; } </style>"
178 "<span class='line' id='line'>One Two Three</span>"); 152 "<span class='line' id='line'>One Two Three</span>");
179 153
154 FrameSelection& selection = document().frame()->selection();
180 Node* line = document().getElementById("line")->firstChild(); 155 Node* line = document().getElementById("line")->firstChild();
181 156
182 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1); 157 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1);
183 document().frame()->eventHandler().handleGestureEvent(singleTapEvent); 158 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
184 ASSERT_TRUE(selection().isCaret()); 159 ASSERT_TRUE(selection.isCaret());
185 EXPECT_EQ(Position(line, 0), selection().start()); 160 EXPECT_EQ(Position(line, 0), selection.start());
186 161
187 // As the text is readonly, multi-tap events should not trigger selection. 162 // As the text is readonly, multi-tap events should not trigger selection.
188 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2); 163 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2);
189 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent); 164 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent);
190 ASSERT_TRUE(selection().isCaret()); 165 ASSERT_TRUE(selection.isCaret());
191 EXPECT_EQ(Position(line, 0), selection().start()); 166 EXPECT_EQ(Position(line, 0), selection.start());
192 167
193 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3); 168 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3);
194 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent); 169 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent);
195 ASSERT_TRUE(selection().isCaret()); 170 ASSERT_TRUE(selection.isCaret());
196 EXPECT_EQ(Position(line, 0), selection().start()); 171 EXPECT_EQ(Position(line, 0), selection.start());
197 } 172 }
198 173
199 TEST_F(EventHandlerTest, draggedInlinePositionTest) { 174 TEST_F(EventHandlerTest, draggedInlinePositionTest) {
200 setHtmlInnerHTML( 175 setHtmlInnerHTML(
201 "<style>" 176 "<style>"
202 "body { margin: 0px; }" 177 "body { margin: 0px; }"
203 ".line { font-family: sans-serif; background: blue; width: 300px; " 178 ".line { font-family: sans-serif; background: blue; width: 300px; "
204 "height: 30px; font-size: 40px; margin-left: 250px; }" 179 "height: 30px; font-size: 40px; margin-left: 250px; }"
205 "</style>" 180 "</style>"
206 "<div style='width: 300px; height: 100px;'>" 181 "<div style='width: 300px; height: 100px;'>"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 .build()); 250 .build());
276 PlatformMouseEvent mouseDownEvent( 251 PlatformMouseEvent mouseDownEvent(
277 IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Right, 252 IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Right,
278 PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::RightButtonDown, 253 PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::RightButtonDown,
279 TimeTicks::Now()); 254 TimeTicks::Now());
280 EXPECT_EQ( 255 EXPECT_EQ(
281 WebInputEventResult::HandledApplication, 256 WebInputEventResult::HandledApplication,
282 document().frame()->eventHandler().sendContextMenuEvent(mouseDownEvent)); 257 document().frame()->eventHandler().sendContextMenuEvent(mouseDownEvent));
283 } 258 }
284 259
285 TEST_F(EventHandlerTest, EmptyTextfieldInsertionOnTap) {
286 setHtmlInnerHTML("<textarea cols=50 rows=50></textarea>");
287
288 TapEventBuilder singleTapEvent(IntPoint(200, 200), 1);
289 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
290
291 ASSERT_TRUE(selection().isCaret());
292 ASSERT_FALSE(selection().isHandleVisible());
293 }
294
295 TEST_F(EventHandlerTest, NonEmptyTextfieldInsertionOnTap) {
296 setHtmlInnerHTML("<textarea cols=50 rows=50>Enter text</textarea>");
297
298 TapEventBuilder singleTapEvent(IntPoint(200, 200), 1);
299 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
300
301 ASSERT_TRUE(selection().isCaret());
302 ASSERT_TRUE(selection().isHandleVisible());
303 }
304
305 TEST_F(EventHandlerTest, EmptyTextfieldInsertionOnLongPress) {
306 setHtmlInnerHTML("<textarea cols=50 rows=50></textarea>");
307
308 LongPressEventBuilder longPressEvent(IntPoint(200, 200));
309 document().frame()->eventHandler().handleGestureEvent(longPressEvent);
310
311 ASSERT_TRUE(selection().isCaret());
312 ASSERT_TRUE(selection().isHandleVisible());
313
314 // Single Tap on an empty edit field should clear insertion handle
315 TapEventBuilder singleTapEvent(IntPoint(200, 200), 1);
316 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
317
318 ASSERT_TRUE(selection().isCaret());
319 ASSERT_FALSE(selection().isHandleVisible());
320 }
321
322 TEST_F(EventHandlerTest, NonEmptyTextfieldInsertionOnLongPress) {
323 setHtmlInnerHTML("<textarea cols=50 rows=50>Enter text</textarea>");
324
325 LongPressEventBuilder longPressEvent(IntPoint(200, 200));
326 document().frame()->eventHandler().handleGestureEvent(longPressEvent);
327
328 ASSERT_TRUE(selection().isCaret());
329 ASSERT_TRUE(selection().isHandleVisible());
330 }
331
332 TEST_F(EventHandlerTest, ClearHandleAfterTap) {
333 setHtmlInnerHTML("<textarea cols=50 rows=50>Enter text</textarea>");
334
335 // Show handle
336 LongPressEventBuilder longPressEvent(IntPoint(200, 200));
337 document().frame()->eventHandler().handleGestureEvent(longPressEvent);
338
339 ASSERT_TRUE(selection().isCaret());
340 ASSERT_TRUE(selection().isHandleVisible());
341
342 // Tap away from text area should clear handle
343 TapEventBuilder singleTapEvent(IntPoint(700, 700), 1);
344 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
345
346 ASSERT_TRUE(selection().isNone());
347 ASSERT_FALSE(selection().isHandleVisible());
348 }
349
350 TEST_F(EventHandlerTest, HandleNotShownOnMouseEvents) {
351 setHtmlInnerHTML("<textarea cols=50 rows=50>Enter text</textarea>");
352
353 MousePressEventBuilder leftMousePressEvent(
354 IntPoint(200, 200), 1, WebPointerProperties::Button::Left);
355 document().frame()->eventHandler().handleMousePressEvent(leftMousePressEvent);
356
357 ASSERT_TRUE(selection().isCaret());
358 ASSERT_FALSE(selection().isHandleVisible());
359
360 MousePressEventBuilder rightMousePressEvent(
361 IntPoint(200, 200), 1, WebPointerProperties::Button::Right);
362 document().frame()->eventHandler().handleMousePressEvent(
363 rightMousePressEvent);
364
365 ASSERT_TRUE(selection().isCaret());
366 ASSERT_FALSE(selection().isHandleVisible());
367
368 MousePressEventBuilder doubleClickMousePressEvent(
369 IntPoint(200, 200), 2, WebPointerProperties::Button::Left);
370 document().frame()->eventHandler().handleMousePressEvent(
371 doubleClickMousePressEvent);
372
373 ASSERT_TRUE(selection().isRange());
374 ASSERT_FALSE(selection().isHandleVisible());
375
376 MousePressEventBuilder tripleClickMousePressEvent(
377 IntPoint(200, 200), 3, WebPointerProperties::Button::Left);
378 document().frame()->eventHandler().handleMousePressEvent(
379 tripleClickMousePressEvent);
380
381 ASSERT_TRUE(selection().isRange());
382 ASSERT_FALSE(selection().isHandleVisible());
383 }
384
385 TEST_F(EventHandlerTest, dragEndInNewDrag) {
386 setHtmlInnerHTML(
387 "<style>.box { width: 100px; height: 100px; display: block; }</style>"
388 "<a class='box' href=''>Drag me</a>");
389
390 PlatformMouseEvent mouseDownEvent(
391 IntPoint(50, 50), IntPoint(50, 50), WebPointerProperties::Button::Left,
392 PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::LeftButtonDown,
393 TimeTicks::Now());
394 document().frame()->eventHandler().handleMousePressEvent(mouseDownEvent);
395
396 PlatformMouseEvent mouseMoveEvent(
397 IntPoint(51, 50), IntPoint(51, 50), WebPointerProperties::Button::Left,
398 PlatformEvent::MouseMoved, 1, PlatformEvent::Modifiers::LeftButtonDown,
399 TimeTicks::Now());
400 document().frame()->eventHandler().handleMouseMoveEvent(
401 mouseMoveEvent, Vector<PlatformMouseEvent>());
402
403 // This reproduces what might be the conditions of http://crbug.com/677916
404 //
405 // TODO(crbug.com/682047): The call sequence below should not occur outside
406 // this contrived test. Given the current code, it is unclear how the
407 // dragSourceEndedAt() call could occur before a drag operation is started.
408
409 PlatformMouseEvent mouseUpEvent(
410 IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
411 PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0),
412 TimeTicks::Now());
413 document().frame()->eventHandler().dragSourceEndedAt(mouseUpEvent,
414 DragOperationNone);
415
416 // This test passes if it doesn't crash.
417 }
418
419 } // namespace blink 260 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/FrameView.cpp ('k') | third_party/WebKit/Source/web/tests/WebFrameTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698