| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |