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

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

Issue 2201853002: Blink handle selection handle visibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed incorrect rebase Created 3 years, 11 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(); }
29 30
30 void setHtmlInnerHTML(const char* htmlContent); 31 void setHtmlInnerHTML(const char* htmlContent);
31 32
32 private: 33 private:
33 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; 34 std::unique_ptr<DummyPageHolder> m_dummyPageHolder;
34 }; 35 };
35 36
36 class TapEventBuilder : public WebGestureEvent { 37 class TapEventBuilder : public WebGestureEvent {
37 public: 38 public:
38 TapEventBuilder(IntPoint position, int tapCount) 39 TapEventBuilder(IntPoint position, int tapCount)
39 : WebGestureEvent(WebInputEvent::GestureTap, 40 : WebGestureEvent(WebInputEvent::GestureTap,
40 WebInputEvent::NoModifiers, 41 WebInputEvent::NoModifiers,
41 TimeTicks::Now().InSeconds()) { 42 TimeTicks::Now().InSeconds()) {
42 x = globalX = position.x(); 43 x = globalX = position.x();
43 y = globalY = position.y(); 44 y = globalY = position.y();
44 sourceDevice = WebGestureDeviceTouchscreen; 45 sourceDevice = WebGestureDeviceTouchscreen;
45 data.tap.tapCount = tapCount; 46 data.tap.tapCount = tapCount;
46 data.tap.width = 5; 47 data.tap.width = 5;
47 data.tap.height = 5; 48 data.tap.height = 5;
48 m_frameScale = 1; 49 m_frameScale = 1;
49 } 50 }
50 }; 51 };
51 52
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
52 void EventHandlerTest::SetUp() { 80 void EventHandlerTest::SetUp() {
53 m_dummyPageHolder = DummyPageHolder::create(IntSize(300, 400)); 81 m_dummyPageHolder = DummyPageHolder::create(IntSize(300, 400));
54 } 82 }
55 83
56 void EventHandlerTest::setHtmlInnerHTML(const char* htmlContent) { 84 void EventHandlerTest::setHtmlInnerHTML(const char* htmlContent) {
57 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent)); 85 document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent));
58 document().view()->updateAllLifecyclePhases(); 86 document().view()->updateAllLifecyclePhases();
59 } 87 }
60 88
61 TEST_F(EventHandlerTest, dragSelectionAfterScroll) { 89 TEST_F(EventHandlerTest, dragSelectionAfterScroll) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 page().autoscrollController().animate(WTF::monotonicallyIncreasingTime()); 121 page().autoscrollController().animate(WTF::monotonicallyIncreasingTime());
94 page().animator().serviceScriptedAnimations( 122 page().animator().serviceScriptedAnimations(
95 WTF::monotonicallyIncreasingTime()); 123 WTF::monotonicallyIncreasingTime());
96 124
97 PlatformMouseEvent mouseUpEvent( 125 PlatformMouseEvent mouseUpEvent(
98 IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left, 126 IntPoint(100, 50), IntPoint(200, 250), WebPointerProperties::Button::Left,
99 PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0), 127 PlatformEvent::MouseReleased, 1, static_cast<PlatformEvent::Modifiers>(0),
100 TimeTicks::Now()); 128 TimeTicks::Now());
101 document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent); 129 document().frame()->eventHandler().handleMouseReleaseEvent(mouseUpEvent);
102 130
103 FrameSelection& selection = document().frame()->selection(); 131 ASSERT_TRUE(selection().isRange());
104 ASSERT_TRUE(selection.isRange());
105 Range* range = 132 Range* range =
106 createRange(selection.selection().toNormalizedEphemeralRange()); 133 createRange(selection().selection().toNormalizedEphemeralRange());
107 ASSERT_TRUE(range); 134 ASSERT_TRUE(range);
108 EXPECT_EQ("Line 1\nLine 2", range->text()); 135 EXPECT_EQ("Line 1\nLine 2", range->text());
109 } 136 }
110 137
111 TEST_F(EventHandlerTest, multiClickSelectionFromTap) { 138 TEST_F(EventHandlerTest, multiClickSelectionFromTap) {
112 setHtmlInnerHTML( 139 setHtmlInnerHTML(
113 "<style> body { margin: 0px; } .line { display: block; width: 300px; " 140 "<style> body { margin: 0px; } .line { display: block; width: 300px; "
114 "height: 30px; } </style>" 141 "height: 30px; } </style>"
115 "<body contenteditable='true'><span class='line' id='line'>One Two " 142 "<body contenteditable='true'><span class='line' id='line'>One Two "
116 "Three</span></body>"); 143 "Three</span></body>");
117 144
118 FrameSelection& selection = document().frame()->selection();
119 Node* line = document().getElementById("line")->firstChild(); 145 Node* line = document().getElementById("line")->firstChild();
120 146
121 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1); 147 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1);
122 document().frame()->eventHandler().handleGestureEvent(singleTapEvent); 148 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
123 ASSERT_TRUE(selection.isCaret()); 149 ASSERT_TRUE(selection().isCaret());
124 EXPECT_EQ(Position(line, 0), selection.start()); 150 EXPECT_EQ(Position(line, 0), selection().start());
125 151
126 // Multi-tap events on editable elements should trigger selection, just 152 // Multi-tap events on editable elements should trigger selection, just
127 // like multi-click events. 153 // like multi-click events.
128 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2); 154 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2);
129 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent); 155 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent);
130 ASSERT_TRUE(selection.isRange()); 156 ASSERT_TRUE(selection().isRange());
131 EXPECT_EQ(Position(line, 0), selection.start()); 157 EXPECT_EQ(Position(line, 0), selection().start());
132 if (document().frame()->editor().isSelectTrailingWhitespaceEnabled()) { 158 if (document().frame()->editor().isSelectTrailingWhitespaceEnabled()) {
133 EXPECT_EQ(Position(line, 4), selection.end()); 159 EXPECT_EQ(Position(line, 4), selection().end());
134 EXPECT_EQ("One ", WebString(selection.selectedText()).utf8()); 160 EXPECT_EQ("One ", WebString(selection().selectedText()).utf8());
135 } else { 161 } else {
136 EXPECT_EQ(Position(line, 3), selection.end()); 162 EXPECT_EQ(Position(line, 3), selection().end());
137 EXPECT_EQ("One", WebString(selection.selectedText()).utf8()); 163 EXPECT_EQ("One", WebString(selection().selectedText()).utf8());
138 } 164 }
139 165
140 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3); 166 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3);
141 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent); 167 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent);
142 ASSERT_TRUE(selection.isRange()); 168 ASSERT_TRUE(selection().isRange());
143 EXPECT_EQ(Position(line, 0), selection.start()); 169 EXPECT_EQ(Position(line, 0), selection().start());
144 EXPECT_EQ(Position(line, 13), selection.end()); 170 EXPECT_EQ(Position(line, 13), selection().end());
145 EXPECT_EQ("One Two Three", WebString(selection.selectedText()).utf8()); 171 EXPECT_EQ("One Two Three", WebString(selection().selectedText()).utf8());
146 } 172 }
147 173
148 TEST_F(EventHandlerTest, multiClickSelectionFromTapDisabledIfNotEditable) { 174 TEST_F(EventHandlerTest, multiClickSelectionFromTapDisabledIfNotEditable) {
149 setHtmlInnerHTML( 175 setHtmlInnerHTML(
150 "<style> body { margin: 0px; } .line { display: block; width: 300px; " 176 "<style> body { margin: 0px; } .line { display: block; width: 300px; "
151 "height: 30px; } </style>" 177 "height: 30px; } </style>"
152 "<span class='line' id='line'>One Two Three</span>"); 178 "<span class='line' id='line'>One Two Three</span>");
153 179
154 FrameSelection& selection = document().frame()->selection();
155 Node* line = document().getElementById("line")->firstChild(); 180 Node* line = document().getElementById("line")->firstChild();
156 181
157 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1); 182 TapEventBuilder singleTapEvent(IntPoint(0, 0), 1);
158 document().frame()->eventHandler().handleGestureEvent(singleTapEvent); 183 document().frame()->eventHandler().handleGestureEvent(singleTapEvent);
159 ASSERT_TRUE(selection.isCaret()); 184 ASSERT_TRUE(selection().isCaret());
160 EXPECT_EQ(Position(line, 0), selection.start()); 185 EXPECT_EQ(Position(line, 0), selection().start());
161 186
162 // As the text is readonly, multi-tap events should not trigger selection. 187 // As the text is readonly, multi-tap events should not trigger selection.
163 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2); 188 TapEventBuilder doubleTapEvent(IntPoint(0, 0), 2);
164 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent); 189 document().frame()->eventHandler().handleGestureEvent(doubleTapEvent);
165 ASSERT_TRUE(selection.isCaret()); 190 ASSERT_TRUE(selection().isCaret());
166 EXPECT_EQ(Position(line, 0), selection.start()); 191 EXPECT_EQ(Position(line, 0), selection().start());
167 192
168 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3); 193 TapEventBuilder tripleTapEvent(IntPoint(0, 0), 3);
169 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent); 194 document().frame()->eventHandler().handleGestureEvent(tripleTapEvent);
170 ASSERT_TRUE(selection.isCaret()); 195 ASSERT_TRUE(selection().isCaret());
171 EXPECT_EQ(Position(line, 0), selection.start()); 196 EXPECT_EQ(Position(line, 0), selection().start());
172 } 197 }
173 198
174 TEST_F(EventHandlerTest, draggedInlinePositionTest) { 199 TEST_F(EventHandlerTest, draggedInlinePositionTest) {
175 setHtmlInnerHTML( 200 setHtmlInnerHTML(
176 "<style>" 201 "<style>"
177 "body { margin: 0px; }" 202 "body { margin: 0px; }"
178 ".line { font-family: sans-serif; background: blue; width: 300px; " 203 ".line { font-family: sans-serif; background: blue; width: 300px; "
179 "height: 30px; font-size: 40px; margin-left: 250px; }" 204 "height: 30px; font-size: 40px; margin-left: 250px; }"
180 "</style>" 205 "</style>"
181 "<div style='width: 300px; height: 100px;'>" 206 "<div style='width: 300px; height: 100px;'>"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 .build()); 275 .build());
251 PlatformMouseEvent mouseDownEvent( 276 PlatformMouseEvent mouseDownEvent(
252 IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Right, 277 IntPoint(0, 0), IntPoint(100, 200), WebPointerProperties::Button::Right,
253 PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::RightButtonDown, 278 PlatformEvent::MousePressed, 1, PlatformEvent::Modifiers::RightButtonDown,
254 TimeTicks::Now()); 279 TimeTicks::Now());
255 EXPECT_EQ( 280 EXPECT_EQ(
256 WebInputEventResult::HandledApplication, 281 WebInputEventResult::HandledApplication,
257 document().frame()->eventHandler().sendContextMenuEvent(mouseDownEvent)); 282 document().frame()->eventHandler().sendContextMenuEvent(mouseDownEvent));
258 } 283 }
259 284
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
260 } // namespace blink 385 } // 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