| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserv
ed. |
| 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 3 * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
| 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) | 4 * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies) |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 | 27 |
| 28 #include "core/input/EventHandler.h" | 28 #include "core/input/EventHandler.h" |
| 29 | 29 |
| 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
| 31 #include "core/HTMLNames.h" | 31 #include "core/HTMLNames.h" |
| 32 #include "core/InputTypeNames.h" | 32 #include "core/InputTypeNames.h" |
| 33 #include "core/clipboard/DataObject.h" | |
| 34 #include "core/clipboard/DataTransfer.h" | 33 #include "core/clipboard/DataTransfer.h" |
| 35 #include "core/dom/DOMNodeIds.h" | 34 #include "core/dom/DOMNodeIds.h" |
| 36 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
| 37 #include "core/dom/TouchList.h" | 36 #include "core/dom/TouchList.h" |
| 38 #include "core/dom/shadow/FlatTreeTraversal.h" | 37 #include "core/dom/shadow/FlatTreeTraversal.h" |
| 39 #include "core/dom/shadow/ShadowRoot.h" | 38 #include "core/dom/shadow/ShadowRoot.h" |
| 40 #include "core/editing/EditingUtilities.h" | 39 #include "core/editing/EditingUtilities.h" |
| 41 #include "core/editing/Editor.h" | 40 #include "core/editing/Editor.h" |
| 42 #include "core/editing/FrameSelection.h" | 41 #include "core/editing/FrameSelection.h" |
| 43 #include "core/editing/SelectionController.h" | 42 #include "core/editing/SelectionController.h" |
| 44 #include "core/events/DragEvent.h" | |
| 45 #include "core/events/EventPath.h" | 43 #include "core/events/EventPath.h" |
| 46 #include "core/events/GestureEvent.h" | 44 #include "core/events/GestureEvent.h" |
| 47 #include "core/events/KeyboardEvent.h" | 45 #include "core/events/KeyboardEvent.h" |
| 48 #include "core/events/MouseEvent.h" | 46 #include "core/events/MouseEvent.h" |
| 49 #include "core/events/PointerEvent.h" | 47 #include "core/events/PointerEvent.h" |
| 50 #include "core/events/TextEvent.h" | 48 #include "core/events/TextEvent.h" |
| 51 #include "core/events/TouchEvent.h" | 49 #include "core/events/TouchEvent.h" |
| 52 #include "core/events/WheelEvent.h" | 50 #include "core/events/WheelEvent.h" |
| 53 #include "core/fetch/ImageResource.h" | 51 #include "core/fetch/ImageResource.h" |
| 54 #include "core/frame/Deprecation.h" | 52 #include "core/frame/Deprecation.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 70 #include "core/layout/HitTestResult.h" | 68 #include "core/layout/HitTestResult.h" |
| 71 #include "core/layout/LayoutPart.h" | 69 #include "core/layout/LayoutPart.h" |
| 72 #include "core/layout/LayoutTextControlSingleLine.h" | 70 #include "core/layout/LayoutTextControlSingleLine.h" |
| 73 #include "core/layout/LayoutView.h" | 71 #include "core/layout/LayoutView.h" |
| 74 #include "core/layout/api/LayoutViewItem.h" | 72 #include "core/layout/api/LayoutViewItem.h" |
| 75 #include "core/loader/DocumentLoader.h" | 73 #include "core/loader/DocumentLoader.h" |
| 76 #include "core/loader/FrameLoader.h" | 74 #include "core/loader/FrameLoader.h" |
| 77 #include "core/loader/FrameLoaderClient.h" | 75 #include "core/loader/FrameLoaderClient.h" |
| 78 #include "core/page/AutoscrollController.h" | 76 #include "core/page/AutoscrollController.h" |
| 79 #include "core/page/ChromeClient.h" | 77 #include "core/page/ChromeClient.h" |
| 80 #include "core/page/DragController.h" | |
| 81 #include "core/page/DragState.h" | 78 #include "core/page/DragState.h" |
| 82 #include "core/page/FocusController.h" | 79 #include "core/page/FocusController.h" |
| 83 #include "core/page/FrameTree.h" | 80 #include "core/page/FrameTree.h" |
| 84 #include "core/page/Page.h" | 81 #include "core/page/Page.h" |
| 85 #include "core/page/TouchAdjustment.h" | 82 #include "core/page/TouchAdjustment.h" |
| 86 #include "core/page/scrolling/ScrollState.h" | 83 #include "core/page/scrolling/ScrollState.h" |
| 87 #include "core/paint/PaintLayer.h" | 84 #include "core/paint/PaintLayer.h" |
| 88 #include "core/style/ComputedStyle.h" | 85 #include "core/style/ComputedStyle.h" |
| 89 #include "core/style/CursorData.h" | 86 #include "core/style/CursorData.h" |
| 90 #include "core/svg/SVGDocumentExtensions.h" | 87 #include "core/svg/SVGDocumentExtensions.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 119 if (!targetNode || !targetNode->parentNode()) | 116 if (!targetNode || !targetNode->parentNode()) |
| 120 return true; | 117 return true; |
| 121 return targetNode->isShadowRoot() && | 118 return targetNode->isShadowRoot() && |
| 122 isHTMLInputElement(toShadowRoot(targetNode)->host()); | 119 isHTMLInputElement(toShadowRoot(targetNode)->host()); |
| 123 } | 120 } |
| 124 | 121 |
| 125 } // namespace | 122 } // namespace |
| 126 | 123 |
| 127 using namespace HTMLNames; | 124 using namespace HTMLNames; |
| 128 | 125 |
| 129 // The link drag hysteresis is much larger than the others because there | |
| 130 // needs to be enough space to cancel the link press without starting a link dra
g, | |
| 131 // and because dragging links is rare. | |
| 132 static const int LinkDragHysteresis = 40; | |
| 133 static const int ImageDragHysteresis = 5; | |
| 134 static const int TextDragHysteresis = 3; | |
| 135 static const int GeneralDragHysteresis = 3; | |
| 136 | |
| 137 // The amount of time to wait before sending a fake mouse event triggered | |
| 138 // during a scroll. | |
| 139 static const double fakeMouseMoveInterval = 0.1; | |
| 140 | |
| 141 // The amount of time to wait for a cursor update on style and layout changes | 126 // The amount of time to wait for a cursor update on style and layout changes |
| 142 // Set to 50Hz, no need to be faster than common screen refresh rate | 127 // Set to 50Hz, no need to be faster than common screen refresh rate |
| 143 static const double cursorUpdateInterval = 0.02; | 128 static const double cursorUpdateInterval = 0.02; |
| 144 | 129 |
| 145 static const int maximumCursorSize = 128; | 130 static const int maximumCursorSize = 128; |
| 146 | 131 |
| 147 // It's pretty unlikely that a scale of less than one would ever be used. But al
l we really | 132 // It's pretty unlikely that a scale of less than one would ever be used. But al
l we really |
| 148 // need to ensure here is that the scale isn't so small that integer overflow ca
n occur when | 133 // need to ensure here is that the scale isn't so small that integer overflow ca
n occur when |
| 149 // dividing cursor sizes (limited above) by the scale. | 134 // dividing cursor sizes (limited above) by the scale. |
| 150 static const double minimumCursorScale = 0.001; | 135 static const double minimumCursorScale = 0.001; |
| 151 | 136 |
| 152 // The minimum amount of time an element stays active after a ShowPress | 137 // The minimum amount of time an element stays active after a ShowPress |
| 153 // This is roughly 9 frames, which should be long enough to be noticeable. | 138 // This is roughly 9 frames, which should be long enough to be noticeable. |
| 154 static const double minimumActiveInterval = 0.15; | 139 static const double minimumActiveInterval = 0.15; |
| 155 | 140 |
| 156 #if OS(MACOSX) | |
| 157 static const double TextDragDelay = 0.15; | |
| 158 #else | |
| 159 static const double TextDragDelay = 0.0; | |
| 160 #endif | |
| 161 | |
| 162 enum NoCursorChangeType { NoCursorChange }; | 141 enum NoCursorChangeType { NoCursorChange }; |
| 163 | 142 |
| 164 enum class DragInitiator { Mouse, Touch }; | |
| 165 | |
| 166 class OptionalCursor { | 143 class OptionalCursor { |
| 167 public: | 144 public: |
| 168 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) {} | 145 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) {} |
| 169 OptionalCursor(const Cursor& cursor) | 146 OptionalCursor(const Cursor& cursor) |
| 170 : m_isCursorChange(true), m_cursor(cursor) {} | 147 : m_isCursorChange(true), m_cursor(cursor) {} |
| 171 | 148 |
| 172 bool isCursorChange() const { return m_isCursorChange; } | 149 bool isCursorChange() const { return m_isCursorChange; } |
| 173 const Cursor& cursor() const { | 150 const Cursor& cursor() const { |
| 174 ASSERT(m_isCursorChange); | 151 ASSERT(m_isCursorChange); |
| 175 return m_cursor; | 152 return m_cursor; |
| 176 } | 153 } |
| 177 | 154 |
| 178 private: | 155 private: |
| 179 bool m_isCursorChange; | 156 bool m_isCursorChange; |
| 180 Cursor m_cursor; | 157 Cursor m_cursor; |
| 181 }; | 158 }; |
| 182 | 159 |
| 183 EventHandler::EventHandler(LocalFrame* frame) | 160 EventHandler::EventHandler(LocalFrame* frame) |
| 184 : m_frame(frame), | 161 : m_frame(frame), |
| 185 m_mousePressed(false), | |
| 186 m_capturesDragging(false), | |
| 187 m_mouseDownMayStartDrag(false), | |
| 188 m_selectionController(SelectionController::create(*frame)), | 162 m_selectionController(SelectionController::create(*frame)), |
| 189 m_hoverTimer(this, &EventHandler::hoverTimerFired), | 163 m_hoverTimer(this, &EventHandler::hoverTimerFired), |
| 190 m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired), | 164 m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired), |
| 191 m_mouseDownMayStartAutoscroll(false), | |
| 192 m_fakeMouseMoveEventTimer(this, | |
| 193 &EventHandler::fakeMouseMoveEventTimerFired), | |
| 194 m_svgPan(false), | |
| 195 m_eventHandlerWillResetCapturingMouseEventsNode(0), | 165 m_eventHandlerWillResetCapturingMouseEventsNode(0), |
| 196 m_clickCount(0), | |
| 197 m_shouldOnlyFireDragOverEvent(false), | 166 m_shouldOnlyFireDragOverEvent(false), |
| 198 m_mousePositionIsUnknown(true), | |
| 199 m_mouseDownTimestamp(0), | |
| 200 m_scrollManager(new ScrollManager(frame)), | 167 m_scrollManager(new ScrollManager(frame)), |
| 201 m_mouseEventManager(new MouseEventManager(frame)), | 168 m_mouseEventManager(new MouseEventManager(frame, m_scrollManager)), |
| 202 m_keyboardEventManager(new KeyboardEventManager(frame, m_scrollManager)), | 169 m_keyboardEventManager(new KeyboardEventManager(frame, m_scrollManager)), |
| 203 m_pointerEventManager( | 170 m_pointerEventManager( |
| 204 new PointerEventManager(frame, m_mouseEventManager)), | 171 new PointerEventManager(frame, m_mouseEventManager)), |
| 205 m_gestureManager(new GestureManager(frame, | 172 m_gestureManager(new GestureManager(frame, |
| 206 m_scrollManager, | 173 m_scrollManager, |
| 174 m_mouseEventManager, |
| 207 m_pointerEventManager, | 175 m_pointerEventManager, |
| 208 m_selectionController)), | 176 m_selectionController)), |
| 209 m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) {} | 177 m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) {} |
| 210 | 178 |
| 211 EventHandler::~EventHandler() { | |
| 212 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); | |
| 213 } | |
| 214 | |
| 215 DEFINE_TRACE(EventHandler) { | 179 DEFINE_TRACE(EventHandler) { |
| 216 visitor->trace(m_frame); | 180 visitor->trace(m_frame); |
| 217 visitor->trace(m_mousePressNode); | |
| 218 visitor->trace(m_selectionController); | 181 visitor->trace(m_selectionController); |
| 219 visitor->trace(m_capturingMouseEventsNode); | 182 visitor->trace(m_capturingMouseEventsNode); |
| 220 visitor->trace(m_nodeUnderMouse); | |
| 221 visitor->trace(m_lastMouseMoveEventSubframe); | 183 visitor->trace(m_lastMouseMoveEventSubframe); |
| 222 visitor->trace(m_lastScrollbarUnderMouse); | 184 visitor->trace(m_lastScrollbarUnderMouse); |
| 223 visitor->trace(m_clickNode); | |
| 224 visitor->trace(m_dragTarget); | 185 visitor->trace(m_dragTarget); |
| 225 visitor->trace(m_frameSetBeingResized); | 186 visitor->trace(m_frameSetBeingResized); |
| 226 visitor->trace(m_scrollManager); | 187 visitor->trace(m_scrollManager); |
| 227 visitor->trace(m_mouseEventManager); | 188 visitor->trace(m_mouseEventManager); |
| 228 visitor->trace(m_keyboardEventManager); | 189 visitor->trace(m_keyboardEventManager); |
| 229 visitor->trace(m_pointerEventManager); | 190 visitor->trace(m_pointerEventManager); |
| 230 visitor->trace(m_gestureManager); | 191 visitor->trace(m_gestureManager); |
| 231 visitor->trace(m_lastDeferredTapElement); | 192 visitor->trace(m_lastDeferredTapElement); |
| 232 } | 193 } |
| 233 | 194 |
| 234 DragState& EventHandler::dragState() { | |
| 235 DEFINE_STATIC_LOCAL(DragState, state, (new DragState)); | |
| 236 return state; | |
| 237 } | |
| 238 | |
| 239 void EventHandler::clear() { | 195 void EventHandler::clear() { |
| 240 m_hoverTimer.stop(); | 196 m_hoverTimer.stop(); |
| 241 m_cursorUpdateTimer.stop(); | 197 m_cursorUpdateTimer.stop(); |
| 242 m_fakeMouseMoveEventTimer.stop(); | |
| 243 m_activeIntervalTimer.stop(); | 198 m_activeIntervalTimer.stop(); |
| 244 m_nodeUnderMouse = nullptr; | |
| 245 m_lastMouseMoveEventSubframe = nullptr; | 199 m_lastMouseMoveEventSubframe = nullptr; |
| 246 m_lastScrollbarUnderMouse = nullptr; | 200 m_lastScrollbarUnderMouse = nullptr; |
| 247 m_clickCount = 0; | |
| 248 m_clickNode = nullptr; | |
| 249 m_frameSetBeingResized = nullptr; | 201 m_frameSetBeingResized = nullptr; |
| 250 m_dragTarget = nullptr; | 202 m_dragTarget = nullptr; |
| 251 m_shouldOnlyFireDragOverEvent = false; | 203 m_shouldOnlyFireDragOverEvent = false; |
| 252 m_mousePositionIsUnknown = true; | |
| 253 m_lastKnownMousePosition = IntPoint(); | |
| 254 m_lastKnownMouseGlobalPosition = IntPoint(); | |
| 255 m_lastMouseDownUserGestureToken.clear(); | 204 m_lastMouseDownUserGestureToken.clear(); |
| 256 m_mousePressNode = nullptr; | |
| 257 m_mousePressed = false; | |
| 258 m_capturesDragging = false; | |
| 259 m_capturingMouseEventsNode = nullptr; | 205 m_capturingMouseEventsNode = nullptr; |
| 260 m_pointerEventManager->clear(); | 206 m_pointerEventManager->clear(); |
| 261 m_scrollManager->clear(); | 207 m_scrollManager->clear(); |
| 262 m_gestureManager->clear(); | 208 m_gestureManager->clear(); |
| 263 m_mouseEventManager->clear(); | 209 m_mouseEventManager->clear(); |
| 264 m_mouseDownMayStartDrag = false; | |
| 265 m_lastDeferredTapElement = nullptr; | 210 m_lastDeferredTapElement = nullptr; |
| 266 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 211 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
| 267 m_mouseDownMayStartAutoscroll = false; | |
| 268 m_svgPan = false; | |
| 269 m_mouseDownPos = IntPoint(); | |
| 270 m_mouseDownTimestamp = 0; | |
| 271 m_dragStartPos = LayoutPoint(); | |
| 272 m_mouseDown = PlatformMouseEvent(); | |
| 273 } | 212 } |
| 274 | 213 |
| 275 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) { | 214 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) { |
| 276 if (nodeToBeRemoved.isShadowIncludingInclusiveAncestorOf(m_clickNode.get())) { | 215 m_mouseEventManager->nodeWillBeRemoved(nodeToBeRemoved); |
| 277 // We don't dispatch click events if the mousedown node is removed | |
| 278 // before a mouseup event. It is compatible with IE and Firefox. | |
| 279 m_clickNode = nullptr; | |
| 280 } | |
| 281 } | |
| 282 | |
| 283 WebInputEventResult EventHandler::handleMousePressEvent( | |
| 284 const MouseEventWithHitTestResults& event) { | |
| 285 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); | |
| 286 | |
| 287 // Reset drag state. | |
| 288 dragState().m_dragSrc = nullptr; | |
| 289 | |
| 290 cancelFakeMouseMoveEvent(); | |
| 291 | |
| 292 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 293 | |
| 294 if (FrameView* frameView = m_frame->view()) { | |
| 295 if (frameView->isPointInScrollbarCorner(event.event().position())) | |
| 296 return WebInputEventResult::NotHandled; | |
| 297 } | |
| 298 | |
| 299 bool singleClick = event.event().clickCount() <= 1; | |
| 300 | |
| 301 m_mouseDownMayStartDrag = | |
| 302 singleClick && !isLinkSelection(event) && !isExtendingSelection(event); | |
| 303 | |
| 304 selectionController().handleMousePressEvent(event); | |
| 305 | |
| 306 m_mouseDown = event.event(); | |
| 307 | |
| 308 if (m_frame->document()->isSVGDocument() && | |
| 309 m_frame->document()->accessSVGExtensions().zoomAndPanEnabled()) { | |
| 310 if (event.event().shiftKey() && singleClick) { | |
| 311 m_svgPan = true; | |
| 312 m_frame->document()->accessSVGExtensions().startPan( | |
| 313 m_frame->view()->rootFrameToContents(event.event().position())); | |
| 314 return WebInputEventResult::HandledSystem; | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 // We don't do this at the start of mouse down handling, | |
| 319 // because we don't want to do it until we know we didn't hit a widget. | |
| 320 if (singleClick) | |
| 321 focusDocumentView(); | |
| 322 | |
| 323 Node* innerNode = event.innerNode(); | |
| 324 | |
| 325 m_mousePressNode = innerNode; | |
| 326 m_frame->document()->setSequentialFocusNavigationStartingPoint(innerNode); | |
| 327 m_dragStartPos = event.event().position(); | |
| 328 | |
| 329 bool swallowEvent = false; | |
| 330 m_mousePressed = true; | |
| 331 | |
| 332 if (event.event().clickCount() == 2) | |
| 333 swallowEvent = | |
| 334 selectionController().handleMousePressEventDoubleClick(event); | |
| 335 else if (event.event().clickCount() >= 3) | |
| 336 swallowEvent = | |
| 337 selectionController().handleMousePressEventTripleClick(event); | |
| 338 else | |
| 339 swallowEvent = | |
| 340 selectionController().handleMousePressEventSingleClick(event); | |
| 341 | |
| 342 m_mouseDownMayStartAutoscroll = | |
| 343 selectionController().mouseDownMayStartSelect() || | |
| 344 (m_mousePressNode && m_mousePressNode->layoutBox() && | |
| 345 m_mousePressNode->layoutBox()->canBeProgramaticallyScrolled()); | |
| 346 | |
| 347 return swallowEvent ? WebInputEventResult::HandledSystem | |
| 348 : WebInputEventResult::NotHandled; | |
| 349 } | |
| 350 | |
| 351 WebInputEventResult EventHandler::handleMouseDraggedEvent( | |
| 352 const MouseEventWithHitTestResults& event) { | |
| 353 TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent"); | |
| 354 | |
| 355 // While resetting m_mousePressed here may seem out of place, it turns out | |
| 356 // to be needed to handle some bugs^Wfeatures in Blink mouse event handling: | |
| 357 // 1. Certain elements, such as <embed>, capture mouse events. They do not | |
| 358 // bubble back up. One way for a <embed> to start capturing mouse events | |
| 359 // is on a mouse press. The problem is the <embed> node only starts | |
| 360 // capturing mouse events *after* m_mousePressed for the containing frame | |
| 361 // has already been set to true. As a result, the frame's EventHandler | |
| 362 // never sees the mouse release event, which is supposed to reset | |
| 363 // m_mousePressed... so m_mousePressed ends up remaining true until the | |
| 364 // event handler finally gets another mouse released event. Oops. | |
| 365 // 2. Dragging doesn't start until after a mouse press event, but a drag | |
| 366 // that ends as a result of a mouse release does not send a mouse release | |
| 367 // event. As a result, m_mousePressed also ends up remaining true until | |
| 368 // the next mouse release event seen by the EventHandler. | |
| 369 if (event.event().pointerProperties().button != | |
| 370 WebPointerProperties::Button::Left) | |
| 371 m_mousePressed = false; | |
| 372 | |
| 373 if (!m_mousePressed) | |
| 374 return WebInputEventResult::NotHandled; | |
| 375 | |
| 376 if (handleDrag(event, DragInitiator::Mouse)) | |
| 377 return WebInputEventResult::HandledSystem; | |
| 378 | |
| 379 Node* targetNode = event.innerNode(); | |
| 380 if (!targetNode) | |
| 381 return WebInputEventResult::NotHandled; | |
| 382 | |
| 383 LayoutObject* layoutObject = targetNode->layoutObject(); | |
| 384 if (!layoutObject) { | |
| 385 Node* parent = FlatTreeTraversal::parent(*targetNode); | |
| 386 if (!parent) | |
| 387 return WebInputEventResult::NotHandled; | |
| 388 | |
| 389 layoutObject = parent->layoutObject(); | |
| 390 if (!layoutObject || !layoutObject->isListBox()) | |
| 391 return WebInputEventResult::NotHandled; | |
| 392 } | |
| 393 | |
| 394 m_mouseDownMayStartDrag = false; | |
| 395 | |
| 396 if (m_mouseDownMayStartAutoscroll && | |
| 397 !m_scrollManager->middleClickAutoscrollInProgress()) { | |
| 398 if (AutoscrollController* controller = | |
| 399 m_scrollManager->autoscrollController()) { | |
| 400 controller->startAutoscrollForSelection(layoutObject); | |
| 401 m_mouseDownMayStartAutoscroll = false; | |
| 402 } | |
| 403 } | |
| 404 | |
| 405 selectionController().handleMouseDraggedEvent( | |
| 406 event, m_mouseDownPos, m_dragStartPos, m_mousePressNode.get(), | |
| 407 m_lastKnownMousePosition); | |
| 408 return WebInputEventResult::HandledSystem; | |
| 409 } | 216 } |
| 410 | 217 |
| 411 void EventHandler::updateSelectionForMouseDrag() { | 218 void EventHandler::updateSelectionForMouseDrag() { |
| 412 selectionController().updateSelectionForMouseDrag( | 219 m_mouseEventManager->updateSelectionForMouseDrag(); |
| 413 m_mousePressNode.get(), m_dragStartPos, m_lastKnownMousePosition); | |
| 414 } | |
| 415 | |
| 416 // TODO(nzolghadr): Refactor the mouse related functions to MouseEventManager. | |
| 417 WebInputEventResult EventHandler::handleMouseReleaseEvent( | |
| 418 const MouseEventWithHitTestResults& event) { | |
| 419 AutoscrollController* controller = m_scrollManager->autoscrollController(); | |
| 420 if (controller && controller->autoscrollInProgress()) | |
| 421 m_scrollManager->stopAutoscroll(); | |
| 422 | |
| 423 return selectionController().handleMouseReleaseEvent(event, m_dragStartPos) | |
| 424 ? WebInputEventResult::HandledSystem | |
| 425 : WebInputEventResult::NotHandled; | |
| 426 } | 220 } |
| 427 | 221 |
| 428 void EventHandler::startMiddleClickAutoscroll(LayoutObject* layoutObject) { | 222 void EventHandler::startMiddleClickAutoscroll(LayoutObject* layoutObject) { |
| 429 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); | 223 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); |
| 430 if (!layoutObject->isBox()) | 224 if (!layoutObject->isBox()) |
| 431 return; | 225 return; |
| 432 AutoscrollController* controller = m_scrollManager->autoscrollController(); | 226 AutoscrollController* controller = m_scrollManager->autoscrollController(); |
| 433 if (!controller) | 227 if (!controller) |
| 434 return; | 228 return; |
| 435 controller->startMiddleClickAutoscroll(toLayoutBox(layoutObject), | 229 controller->startMiddleClickAutoscroll( |
| 436 lastKnownMousePosition()); | 230 toLayoutBox(layoutObject), m_mouseEventManager->lastKnownMousePosition()); |
| 437 invalidateClick(); | 231 m_mouseEventManager->invalidateClick(); |
| 438 } | 232 } |
| 439 | 233 |
| 440 HitTestResult EventHandler::hitTestResultAtPoint( | 234 HitTestResult EventHandler::hitTestResultAtPoint( |
| 441 const LayoutPoint& point, | 235 const LayoutPoint& point, |
| 442 HitTestRequest::HitTestRequestType hitType, | 236 HitTestRequest::HitTestRequestType hitType, |
| 443 const LayoutSize& padding) { | 237 const LayoutSize& padding) { |
| 444 TRACE_EVENT0("blink", "EventHandler::hitTestResultAtPoint"); | 238 TRACE_EVENT0("blink", "EventHandler::hitTestResultAtPoint"); |
| 445 | 239 |
| 446 ASSERT((hitType & HitTestRequest::ListBased) || padding.isEmpty()); | 240 ASSERT((hitType & HitTestRequest::ListBased) || padding.isEmpty()); |
| 447 | 241 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 466 HitTestResult result(request, point, padding.height().toUnsigned(), | 260 HitTestResult result(request, point, padding.height().toUnsigned(), |
| 467 padding.width().toUnsigned(), | 261 padding.width().toUnsigned(), |
| 468 padding.height().toUnsigned(), | 262 padding.height().toUnsigned(), |
| 469 padding.width().toUnsigned()); | 263 padding.width().toUnsigned()); |
| 470 | 264 |
| 471 // LayoutView::hitTest causes a layout, and we don't want to hit that until th
e first | 265 // LayoutView::hitTest causes a layout, and we don't want to hit that until th
e first |
| 472 // layout because until then, there is nothing shown on the screen - the user
can't | 266 // layout because until then, there is nothing shown on the screen - the user
can't |
| 473 // have intentionally clicked on something belonging to this page. Furthermore
, | 267 // have intentionally clicked on something belonging to this page. Furthermore
, |
| 474 // mousemove events before the first layout should not lead to a premature lay
out() | 268 // mousemove events before the first layout should not lead to a premature lay
out() |
| 475 // happening, which could show a flash of white. | 269 // happening, which could show a flash of white. |
| 476 // See also the similar code in Document::prepareMouseEvent. | 270 // See also the similar code in Document::performMouseEventHitTest. |
| 477 if (m_frame->contentLayoutItem().isNull() || !m_frame->view() || | 271 if (m_frame->contentLayoutItem().isNull() || !m_frame->view() || |
| 478 !m_frame->view()->didFirstLayout()) | 272 !m_frame->view()->didFirstLayout()) |
| 479 return result; | 273 return result; |
| 480 | 274 |
| 481 m_frame->contentLayoutItem().hitTest(result); | 275 m_frame->contentLayoutItem().hitTest(result); |
| 482 if (!request.readOnly()) | 276 if (!request.readOnly()) |
| 483 m_frame->document()->updateHoverActiveState(request, result.innerElement()); | 277 m_frame->document()->updateHoverActiveState(request, result.innerElement()); |
| 484 | 278 |
| 485 return result; | 279 return result; |
| 486 } | 280 } |
| 487 | 281 |
| 488 void EventHandler::stopAutoscroll() { | 282 void EventHandler::stopAutoscroll() { |
| 489 m_scrollManager->stopAutoscroll(); | 283 m_scrollManager->stopAutoscroll(); |
| 490 } | 284 } |
| 491 | 285 |
| 492 // TODO(bokan): This should be merged with logicalScroll assuming | 286 // TODO(bokan): This should be merged with logicalScroll assuming |
| 493 // defaultSpaceEventHandler's chaining scroll can be done crossing frames. | 287 // defaultSpaceEventHandler's chaining scroll can be done crossing frames. |
| 494 bool EventHandler::bubblingScroll(ScrollDirection direction, | 288 bool EventHandler::bubblingScroll(ScrollDirection direction, |
| 495 ScrollGranularity granularity, | 289 ScrollGranularity granularity, |
| 496 Node* startingNode) { | 290 Node* startingNode) { |
| 497 return m_scrollManager->bubblingScroll(direction, granularity, startingNode, | 291 return m_scrollManager->bubblingScroll(direction, granularity, startingNode, |
| 498 m_mousePressNode); | 292 m_mouseEventManager->mousePressNode()); |
| 499 } | 293 } |
| 500 | 294 |
| 501 IntPoint EventHandler::lastKnownMousePosition() const { | 295 IntPoint EventHandler::lastKnownMousePosition() const { |
| 502 return m_lastKnownMousePosition; | 296 return m_mouseEventManager->lastKnownMousePosition(); |
| 503 } | 297 } |
| 504 | 298 |
| 505 IntPoint EventHandler::dragDataTransferLocationForTesting() { | 299 IntPoint EventHandler::dragDataTransferLocationForTesting() { |
| 506 if (dragState().m_dragDataTransfer) | 300 if (m_mouseEventManager->dragState().m_dragDataTransfer) |
| 507 return dragState().m_dragDataTransfer->dragLocation(); | 301 return m_mouseEventManager->dragState().m_dragDataTransfer->dragLocation(); |
| 508 | 302 |
| 509 return IntPoint(); | 303 return IntPoint(); |
| 510 } | 304 } |
| 511 | 305 |
| 512 static LocalFrame* subframeForTargetNode(Node* node) { | 306 static LocalFrame* subframeForTargetNode(Node* node) { |
| 513 if (!node) | 307 if (!node) |
| 514 return nullptr; | 308 return nullptr; |
| 515 | 309 |
| 516 LayoutObject* layoutObject = node->layoutObject(); | 310 LayoutObject* layoutObject = node->layoutObject(); |
| 517 if (!layoutObject || !layoutObject->isLayoutPart()) | 311 if (!layoutObject || !layoutObject->isLayoutPart()) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 updateCursor(); | 344 updateCursor(); |
| 551 } | 345 } |
| 552 | 346 |
| 553 void EventHandler::updateCursor() { | 347 void EventHandler::updateCursor() { |
| 554 TRACE_EVENT0("input", "EventHandler::updateCursor"); | 348 TRACE_EVENT0("input", "EventHandler::updateCursor"); |
| 555 | 349 |
| 556 // We must do a cross-frame hit test because the frame that triggered the curs
or | 350 // We must do a cross-frame hit test because the frame that triggered the curs
or |
| 557 // update could be occluded by a different frame. | 351 // update could be occluded by a different frame. |
| 558 ASSERT(m_frame == m_frame->localFrameRoot()); | 352 ASSERT(m_frame == m_frame->localFrameRoot()); |
| 559 | 353 |
| 560 if (m_mousePositionIsUnknown) | 354 if (m_mouseEventManager->isMousePositionUnknown()) |
| 561 return; | 355 return; |
| 562 | 356 |
| 563 FrameView* view = m_frame->view(); | 357 FrameView* view = m_frame->view(); |
| 564 if (!view || !view->shouldSetCursor()) | 358 if (!view || !view->shouldSetCursor()) |
| 565 return; | 359 return; |
| 566 | 360 |
| 567 LayoutViewItem layoutViewItem = view->layoutViewItem(); | 361 LayoutViewItem layoutViewItem = view->layoutViewItem(); |
| 568 if (layoutViewItem.isNull()) | 362 if (layoutViewItem.isNull()) |
| 569 return; | 363 return; |
| 570 | 364 |
| 571 m_frame->document()->updateStyleAndLayout(); | 365 m_frame->document()->updateStyleAndLayout(); |
| 572 | 366 |
| 573 HitTestRequest request(HitTestRequest::ReadOnly | | 367 HitTestRequest request(HitTestRequest::ReadOnly | |
| 574 HitTestRequest::AllowChildFrameContent); | 368 HitTestRequest::AllowChildFrameContent); |
| 575 HitTestResult result(request, | 369 HitTestResult result( |
| 576 view->rootFrameToContents(m_lastKnownMousePosition)); | 370 request, |
| 371 view->rootFrameToContents(m_mouseEventManager->lastKnownMousePosition())); |
| 577 layoutViewItem.hitTest(result); | 372 layoutViewItem.hitTest(result); |
| 578 | 373 |
| 579 if (LocalFrame* frame = result.innerNodeFrame()) { | 374 if (LocalFrame* frame = result.innerNodeFrame()) { |
| 580 OptionalCursor optionalCursor = frame->eventHandler().selectCursor(result); | 375 OptionalCursor optionalCursor = frame->eventHandler().selectCursor(result); |
| 581 if (optionalCursor.isCursorChange()) { | 376 if (optionalCursor.isCursorChange()) { |
| 582 view->setCursor(optionalCursor.cursor()); | 377 view->setCursor(optionalCursor.cursor()); |
| 583 } | 378 } |
| 584 } | 379 } |
| 585 } | 380 } |
| 586 | 381 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; | 535 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; |
| 741 if (layoutObject && m_frame->view()) { | 536 if (layoutObject && m_frame->view()) { |
| 742 PaintLayer* layer = layoutObject->enclosingLayer(); | 537 PaintLayer* layer = layoutObject->enclosingLayer(); |
| 743 inResizer = layer->getScrollableArea() && | 538 inResizer = layer->getScrollableArea() && |
| 744 layer->getScrollableArea()->isPointInResizeControl( | 539 layer->getScrollableArea()->isPointInResizeControl( |
| 745 result.roundedPointInMainFrame(), ResizerForPointer); | 540 result.roundedPointInMainFrame(), ResizerForPointer); |
| 746 } | 541 } |
| 747 | 542 |
| 748 // During selection, use an I-beam no matter what we're over. | 543 // During selection, use an I-beam no matter what we're over. |
| 749 // If a drag may be starting or we're capturing mouse events for a particular
node, don't treat this as a selection. | 544 // If a drag may be starting or we're capturing mouse events for a particular
node, don't treat this as a selection. |
| 750 if (m_mousePressed && selectionController().mouseDownMayStartSelect() && | 545 if (m_mouseEventManager->mousePressed() && |
| 751 !m_mouseDownMayStartDrag && !m_frame->selection().isNone() && | 546 selectionController().mouseDownMayStartSelect() && |
| 752 !m_capturingMouseEventsNode) { | 547 !m_mouseEventManager->mouseDownMayStartDrag() && |
| 548 !m_frame->selection().isNone() && !m_capturingMouseEventsNode) { |
| 753 return iBeam; | 549 return iBeam; |
| 754 } | 550 } |
| 755 | 551 |
| 756 if ((editable || | 552 if ((editable || |
| 757 (layoutObject && layoutObject->isText() && node->canStartSelection())) && | 553 (layoutObject && layoutObject->isText() && node->canStartSelection())) && |
| 758 !inResizer && !result.scrollbar()) | 554 !inResizer && !result.scrollbar()) |
| 759 return iBeam; | 555 return iBeam; |
| 760 return pointerCursor(); | 556 return pointerCursor(); |
| 761 } | 557 } |
| 762 | 558 |
| 763 static LayoutPoint contentPointFromRootFrame(LocalFrame* frame, | |
| 764 const IntPoint& pointInRootFrame) { | |
| 765 FrameView* view = frame->view(); | |
| 766 // FIXME: Is it really OK to use the wrong coordinates here when view is 0? | |
| 767 // Historically the code would just crash; this is clearly no worse than that. | |
| 768 return view ? view->rootFrameToContents(pointInRootFrame) : pointInRootFrame; | |
| 769 } | |
| 770 | |
| 771 WebInputEventResult EventHandler::handleMousePressEvent( | 559 WebInputEventResult EventHandler::handleMousePressEvent( |
| 772 const PlatformMouseEvent& mouseEvent) { | 560 const PlatformMouseEvent& mouseEvent) { |
| 773 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); | 561 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); |
| 774 | 562 |
| 775 // For 4th/5th button in the mouse since Chrome does not yet send | 563 // For 4th/5th button in the mouse since Chrome does not yet send |
| 776 // button value to Blink but in some cases it does send the event. | 564 // button value to Blink but in some cases it does send the event. |
| 777 // This check is needed to suppress such an event (crbug.com/574959) | 565 // This check is needed to suppress such an event (crbug.com/574959) |
| 778 if (mouseEvent.pointerProperties().button == | 566 if (mouseEvent.pointerProperties().button == |
| 779 WebPointerProperties::Button::NoButton) | 567 WebPointerProperties::Button::NoButton) |
| 780 return WebInputEventResult::HandledSuppressed; | 568 return WebInputEventResult::HandledSuppressed; |
| 781 | 569 |
| 782 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); | 570 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); |
| 783 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = | 571 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = |
| 784 UserGestureIndicator::currentToken(); | 572 UserGestureIndicator::currentToken(); |
| 785 | 573 |
| 786 cancelFakeMouseMoveEvent(); | |
| 787 if (m_eventHandlerWillResetCapturingMouseEventsNode) | 574 if (m_eventHandlerWillResetCapturingMouseEventsNode) |
| 788 m_capturingMouseEventsNode = nullptr; | 575 m_capturingMouseEventsNode = nullptr; |
| 789 m_mousePressed = true; | 576 m_mouseEventManager->handleMousePressEventUpdateStates(mouseEvent); |
| 790 m_capturesDragging = true; | |
| 791 setLastKnownMousePosition(mouseEvent); | |
| 792 m_mouseDownTimestamp = mouseEvent.timestamp(); | |
| 793 m_mouseDownMayStartDrag = false; | |
| 794 selectionController().setMouseDownMayStartSelect(false); | 577 selectionController().setMouseDownMayStartSelect(false); |
| 795 m_mouseDownMayStartAutoscroll = false; | 578 if (!m_frame->view()) |
| 796 if (FrameView* view = m_frame->view()) { | |
| 797 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position()); | |
| 798 } else { | |
| 799 invalidateClick(); | |
| 800 return WebInputEventResult::NotHandled; | 579 return WebInputEventResult::NotHandled; |
| 801 } | |
| 802 | 580 |
| 803 HitTestRequest request(HitTestRequest::Active); | 581 HitTestRequest request(HitTestRequest::Active); |
| 804 // Save the document point we generate in case the window coordinate is invali
dated by what happens | 582 // Save the document point we generate in case the window coordinate is invali
dated by what happens |
| 805 // when we dispatch the event. | 583 // when we dispatch the event. |
| 806 LayoutPoint documentPoint = | 584 LayoutPoint documentPoint = |
| 807 contentPointFromRootFrame(m_frame, mouseEvent.position()); | 585 m_frame->view()->rootFrameToContents(mouseEvent.position()); |
| 808 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent( | 586 MouseEventWithHitTestResults mev = |
| 809 request, documentPoint, mouseEvent); | 587 m_frame->document()->performMouseEventHitTest(request, documentPoint, |
| 588 mouseEvent); |
| 810 | 589 |
| 811 if (!mev.innerNode()) { | 590 if (!mev.innerNode()) { |
| 812 invalidateClick(); | 591 m_mouseEventManager->invalidateClick(); |
| 813 return WebInputEventResult::NotHandled; | 592 return WebInputEventResult::NotHandled; |
| 814 } | 593 } |
| 815 | 594 |
| 816 m_mousePressNode = mev.innerNode(); | 595 m_mouseEventManager->setMousePressNode(mev.innerNode()); |
| 817 m_frame->document()->setSequentialFocusNavigationStartingPoint( | 596 m_frame->document()->setSequentialFocusNavigationStartingPoint( |
| 818 mev.innerNode()); | 597 mev.innerNode()); |
| 819 | 598 |
| 820 LocalFrame* subframe = subframeForHitTestResult(mev); | 599 LocalFrame* subframe = subframeForHitTestResult(mev); |
| 821 if (subframe) { | 600 if (subframe) { |
| 822 WebInputEventResult result = passMousePressEventToSubframe(mev, subframe); | 601 WebInputEventResult result = passMousePressEventToSubframe(mev, subframe); |
| 823 // Start capturing future events for this frame. We only do this if we didn
't clear | 602 // Start capturing future events for this frame. We only do this if we didn
't clear |
| 824 // the m_mousePressed flag, which may happen if an AppKit widget entered a m
odal event loop. | 603 // the m_mousePressed flag, which may happen if an AppKit widget entered a m
odal event loop. |
| 825 // The capturing should be done only when the result indicates it | 604 // The capturing should be done only when the result indicates it |
| 826 // has been handled. See crbug.com/269917 | 605 // has been handled. See crbug.com/269917 |
| 827 m_capturesDragging = subframe->eventHandler().capturesDragging(); | 606 m_mouseEventManager->setCapturesDragging( |
| 828 if (m_mousePressed && m_capturesDragging) { | 607 subframe->eventHandler().m_mouseEventManager->capturesDragging()); |
| 608 if (m_mouseEventManager->mousePressed() && |
| 609 m_mouseEventManager->capturesDragging()) { |
| 829 m_capturingMouseEventsNode = mev.innerNode(); | 610 m_capturingMouseEventsNode = mev.innerNode(); |
| 830 m_eventHandlerWillResetCapturingMouseEventsNode = true; | 611 m_eventHandlerWillResetCapturingMouseEventsNode = true; |
| 831 } | 612 } |
| 832 invalidateClick(); | 613 m_mouseEventManager->invalidateClick(); |
| 833 return result; | 614 return result; |
| 834 } | 615 } |
| 835 | 616 |
| 836 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { | 617 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { |
| 837 // We store whether middle click autoscroll is in progress before calling st
opAutoscroll() | 618 // We store whether middle click autoscroll is in progress before calling st
opAutoscroll() |
| 838 // because it will set m_autoscrollType to NoAutoscroll on return. | 619 // because it will set m_autoscrollType to NoAutoscroll on return. |
| 839 bool isMiddleClickAutoscrollInProgress = | 620 bool isMiddleClickAutoscrollInProgress = |
| 840 m_scrollManager->middleClickAutoscrollInProgress(); | 621 m_scrollManager->middleClickAutoscrollInProgress(); |
| 841 m_scrollManager->stopAutoscroll(); | 622 m_scrollManager->stopAutoscroll(); |
| 842 if (isMiddleClickAutoscrollInProgress) { | 623 if (isMiddleClickAutoscrollInProgress) { |
| 843 // We invalidate the click when exiting middle click auto scroll so that w
e don't inadvertently navigate | 624 // We invalidate the click when exiting middle click auto scroll so that w
e don't inadvertently navigate |
| 844 // away from the current page (e.g. the click was on a hyperlink). See <rd
ar://problem/6095023>. | 625 // away from the current page (e.g. the click was on a hyperlink). See <rd
ar://problem/6095023>. |
| 845 invalidateClick(); | 626 m_mouseEventManager->invalidateClick(); |
| 846 return WebInputEventResult::HandledSuppressed; | 627 return WebInputEventResult::HandledSuppressed; |
| 847 } | 628 } |
| 848 } | 629 } |
| 849 | 630 |
| 850 m_clickCount = mouseEvent.clickCount(); | 631 m_mouseEventManager->setClickCount(mouseEvent.clickCount()); |
| 851 m_clickNode = mev.innerNode()->isTextNode() | 632 m_mouseEventManager->setClickNode( |
| 852 ? FlatTreeTraversal::parent(*mev.innerNode()) | 633 mev.innerNode()->isTextNode() |
| 853 : mev.innerNode(); | 634 ? FlatTreeTraversal::parent(*mev.innerNode()) |
| 635 : mev.innerNode()); |
| 854 | 636 |
| 855 if (!mouseEvent.fromTouch()) | 637 if (!mouseEvent.fromTouch()) |
| 856 m_frame->selection().setCaretBlinkingSuspended(true); | 638 m_frame->selection().setCaretBlinkingSuspended(true); |
| 857 | 639 |
| 858 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents( | 640 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents( |
| 859 EventTypeNames::mousedown, mev.innerNode(), m_clickCount, mev.event()); | 641 EventTypeNames::mousedown, mev.innerNode(), mev.event()); |
| 860 | 642 |
| 861 if (eventResult == WebInputEventResult::NotHandled && m_frame->view()) { | 643 if (eventResult == WebInputEventResult::NotHandled && m_frame->view()) { |
| 862 FrameView* view = m_frame->view(); | 644 FrameView* view = m_frame->view(); |
| 863 PaintLayer* layer = mev.innerNode()->layoutObject() | 645 PaintLayer* layer = mev.innerNode()->layoutObject() |
| 864 ? mev.innerNode()->layoutObject()->enclosingLayer() | 646 ? mev.innerNode()->layoutObject()->enclosingLayer() |
| 865 : nullptr; | 647 : nullptr; |
| 866 IntPoint p = view->rootFrameToContents(mouseEvent.position()); | 648 IntPoint p = view->rootFrameToContents(mouseEvent.position()); |
| 867 if (layer && layer->getScrollableArea() && | 649 if (layer && layer->getScrollableArea() && |
| 868 layer->getScrollableArea()->isPointInResizeControl(p, | 650 layer->getScrollableArea()->isPointInResizeControl(p, |
| 869 ResizerForPointer)) { | 651 ResizerForPointer)) { |
| 870 m_scrollManager->setResizeScrollableArea(layer, p); | 652 m_scrollManager->setResizeScrollableArea(layer, p); |
| 871 return WebInputEventResult::HandledSystem; | 653 return WebInputEventResult::HandledSystem; |
| 872 } | 654 } |
| 873 } | 655 } |
| 874 | 656 |
| 875 // m_selectionInitiationState is initialized after dispatching mousedown | 657 // m_selectionInitiationState is initialized after dispatching mousedown |
| 876 // event in order not to keep the selection by DOM APIs because we can't | 658 // event in order not to keep the selection by DOM APIs because we can't |
| 877 // give the user the chance to handle the selection by user action like | 659 // give the user the chance to handle the selection by user action like |
| 878 // dragging if we keep the selection in case of mousedown. FireFox also has | 660 // dragging if we keep the selection in case of mousedown. FireFox also has |
| 879 // the same behavior and it's more compatible with other browsers. | 661 // the same behavior and it's more compatible with other browsers. |
| 880 selectionController().initializeSelectionState(); | 662 selectionController().initializeSelectionState(); |
| 881 HitTestResult hitTestResult = EventHandlingUtil::hitTestResultInFrame( | 663 HitTestResult hitTestResult = EventHandlingUtil::hitTestResultInFrame( |
| 882 m_frame, documentPoint, HitTestRequest::ReadOnly); | 664 m_frame, documentPoint, HitTestRequest::ReadOnly); |
| 883 InputDeviceCapabilities* sourceCapabilities = | 665 InputDeviceCapabilities* sourceCapabilities = |
| 884 mouseEvent.getSyntheticEventType() == PlatformMouseEvent::FromTouch | 666 mouseEvent.getSyntheticEventType() == PlatformMouseEvent::FromTouch |
| 885 ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities() | 667 ? InputDeviceCapabilities::firesTouchEventsSourceCapabilities() |
| 886 : InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities(); | 668 : InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities(); |
| 887 if (eventResult == WebInputEventResult::NotHandled) | 669 if (eventResult == WebInputEventResult::NotHandled) { |
| 888 eventResult = handleMouseFocus(hitTestResult, sourceCapabilities); | 670 eventResult = m_mouseEventManager->handleMouseFocus(hitTestResult, |
| 889 m_capturesDragging = | 671 sourceCapabilities); |
| 890 eventResult == WebInputEventResult::NotHandled || mev.scrollbar(); | 672 } |
| 673 m_mouseEventManager->setCapturesDragging( |
| 674 eventResult == WebInputEventResult::NotHandled || mev.scrollbar()); |
| 891 | 675 |
| 892 // If the hit testing originally determined the event was in a scrollbar, refe
tch the MouseEventWithHitTestResults | 676 // If the hit testing originally determined the event was in a scrollbar, refe
tch the MouseEventWithHitTestResults |
| 893 // in case the scrollbar widget was destroyed when the mouse event was handled
. | 677 // in case the scrollbar widget was destroyed when the mouse event was handled
. |
| 894 if (mev.scrollbar()) { | 678 if (mev.scrollbar()) { |
| 895 const bool wasLastScrollBar = | 679 const bool wasLastScrollBar = |
| 896 mev.scrollbar() == m_lastScrollbarUnderMouse.get(); | 680 mev.scrollbar() == m_lastScrollbarUnderMouse.get(); |
| 897 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); | 681 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); |
| 898 mev = m_frame->document()->prepareMouseEvent(request, documentPoint, | 682 mev = m_frame->document()->performMouseEventHitTest(request, documentPoint, |
| 899 mouseEvent); | 683 mouseEvent); |
| 900 if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get()) | 684 if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get()) |
| 901 m_lastScrollbarUnderMouse = nullptr; | 685 m_lastScrollbarUnderMouse = nullptr; |
| 902 } | 686 } |
| 903 | 687 |
| 904 if (eventResult != WebInputEventResult::NotHandled) { | 688 if (eventResult != WebInputEventResult::NotHandled) { |
| 905 // scrollbars should get events anyway, even disabled controls might be scro
llable | 689 // scrollbars should get events anyway, even disabled controls might be scro
llable |
| 906 passMousePressEventToScrollbar(mev); | 690 passMousePressEventToScrollbar(mev); |
| 907 } else { | 691 } else { |
| 908 if (shouldRefetchEventTarget(mev)) { | 692 if (shouldRefetchEventTarget(mev)) { |
| 909 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); | 693 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); |
| 910 mev = m_frame->document()->prepareMouseEvent(request, documentPoint, | 694 mev = m_frame->document()->performMouseEventHitTest( |
| 911 mouseEvent); | 695 request, documentPoint, mouseEvent); |
| 912 } | 696 } |
| 913 | 697 |
| 914 if (passMousePressEventToScrollbar(mev)) | 698 if (passMousePressEventToScrollbar(mev)) |
| 915 eventResult = WebInputEventResult::HandledSystem; | 699 eventResult = WebInputEventResult::HandledSystem; |
| 916 else | 700 else |
| 917 eventResult = handleMousePressEvent(mev); | 701 eventResult = m_mouseEventManager->handleMousePressEvent(mev); |
| 918 } | 702 } |
| 919 | 703 |
| 920 if (mev.hitTestResult().innerNode() && | 704 if (mev.hitTestResult().innerNode() && |
| 921 mouseEvent.pointerProperties().button == | 705 mouseEvent.pointerProperties().button == |
| 922 WebPointerProperties::Button::Left) { | 706 WebPointerProperties::Button::Left) { |
| 923 ASSERT(mouseEvent.type() == PlatformEvent::MousePressed); | 707 ASSERT(mouseEvent.type() == PlatformEvent::MousePressed); |
| 924 HitTestResult result = mev.hitTestResult(); | 708 HitTestResult result = mev.hitTestResult(); |
| 925 result.setToShadowHostIfInUserAgentShadowRoot(); | 709 result.setToShadowHostIfInUserAgentShadowRoot(); |
| 926 m_frame->chromeClient().onMouseDown(result.innerNode()); | 710 m_frame->chromeClient().onMouseDown(result.innerNode()); |
| 927 } | 711 } |
| 928 | 712 |
| 929 return eventResult; | 713 return eventResult; |
| 930 } | 714 } |
| 931 | 715 |
| 932 static PaintLayer* layerForNode(Node* node) { | |
| 933 if (!node) | |
| 934 return nullptr; | |
| 935 | |
| 936 LayoutObject* layoutObject = node->layoutObject(); | |
| 937 if (!layoutObject) | |
| 938 return nullptr; | |
| 939 | |
| 940 PaintLayer* layer = layoutObject->enclosingLayer(); | |
| 941 if (!layer) | |
| 942 return nullptr; | |
| 943 | |
| 944 return layer; | |
| 945 } | |
| 946 | |
| 947 ScrollableArea* EventHandler::associatedScrollableArea( | |
| 948 const PaintLayer* layer) const { | |
| 949 if (PaintLayerScrollableArea* scrollableArea = layer->getScrollableArea()) { | |
| 950 if (scrollableArea->scrollsOverflow()) | |
| 951 return scrollableArea; | |
| 952 } | |
| 953 | |
| 954 return nullptr; | |
| 955 } | |
| 956 | |
| 957 WebInputEventResult EventHandler::handleMouseMoveEvent( | 716 WebInputEventResult EventHandler::handleMouseMoveEvent( |
| 958 const PlatformMouseEvent& event) { | 717 const PlatformMouseEvent& event) { |
| 959 TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent"); | 718 TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent"); |
| 960 | 719 |
| 961 HitTestResult hoveredNode = HitTestResult(); | 720 HitTestResult hoveredNode = HitTestResult(); |
| 962 WebInputEventResult result = handleMouseMoveOrLeaveEvent(event, &hoveredNode); | 721 WebInputEventResult result = handleMouseMoveOrLeaveEvent(event, &hoveredNode); |
| 963 | 722 |
| 964 Page* page = m_frame->page(); | 723 Page* page = m_frame->page(); |
| 965 if (!page) | 724 if (!page) |
| 966 return result; | 725 return result; |
| 967 | 726 |
| 968 if (PaintLayer* layer = layerForNode(hoveredNode.innerNode())) { | 727 if (PaintLayer* layer = |
| 969 if (ScrollableArea* layerScrollableArea = associatedScrollableArea(layer)) | 728 EventHandlingUtil::layerForNode(hoveredNode.innerNode())) { |
| 729 if (ScrollableArea* layerScrollableArea = |
| 730 EventHandlingUtil::associatedScrollableArea(layer)) |
| 970 layerScrollableArea->mouseMovedInContentArea(); | 731 layerScrollableArea->mouseMovedInContentArea(); |
| 971 } | 732 } |
| 972 | 733 |
| 973 if (FrameView* frameView = m_frame->view()) | 734 if (FrameView* frameView = m_frame->view()) |
| 974 frameView->mouseMovedInContentArea(); | 735 frameView->mouseMovedInContentArea(); |
| 975 | 736 |
| 976 hoveredNode.setToShadowHostIfInUserAgentShadowRoot(); | 737 hoveredNode.setToShadowHostIfInUserAgentShadowRoot(); |
| 977 page->chromeClient().mouseDidMoveOverElement(*m_frame, hoveredNode); | 738 page->chromeClient().mouseDidMoveOverElement(*m_frame, hoveredNode); |
| 978 | 739 |
| 979 return result; | 740 return result; |
| 980 } | 741 } |
| 981 | 742 |
| 982 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) { | 743 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) { |
| 983 TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent"); | 744 TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent"); |
| 984 | 745 |
| 985 handleMouseMoveOrLeaveEvent(event, 0, false, true); | 746 handleMouseMoveOrLeaveEvent(event, 0, false, true); |
| 986 } | 747 } |
| 987 | 748 |
| 988 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent( | 749 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent( |
| 989 const PlatformMouseEvent& mouseEvent, | 750 const PlatformMouseEvent& mouseEvent, |
| 990 HitTestResult* hoveredNode, | 751 HitTestResult* hoveredNode, |
| 991 bool onlyUpdateScrollbars, | 752 bool onlyUpdateScrollbars, |
| 992 bool forceLeave) { | 753 bool forceLeave) { |
| 993 ASSERT(m_frame); | 754 ASSERT(m_frame); |
| 994 ASSERT(m_frame->view()); | 755 ASSERT(m_frame->view()); |
| 995 | 756 |
| 996 setLastKnownMousePosition(mouseEvent); | 757 m_mouseEventManager->setLastKnownMousePosition(mouseEvent); |
| 997 | 758 |
| 998 if (m_hoverTimer.isActive()) | 759 if (m_hoverTimer.isActive()) |
| 999 m_hoverTimer.stop(); | 760 m_hoverTimer.stop(); |
| 1000 | 761 |
| 1001 m_cursorUpdateTimer.stop(); | 762 m_cursorUpdateTimer.stop(); |
| 1002 | 763 |
| 1003 cancelFakeMouseMoveEvent(); | 764 m_mouseEventManager->cancelFakeMouseMoveEvent(); |
| 1004 | 765 |
| 1005 if (m_svgPan) { | 766 m_mouseEventManager->handleSvgPanIfNeeded(false); |
| 1006 m_frame->document()->accessSVGExtensions().updatePan( | 767 |
| 1007 m_frame->view()->rootFrameToContents(m_lastKnownMousePosition)); | 768 if (m_frameSetBeingResized) { |
| 1008 return WebInputEventResult::HandledSuppressed; | 769 return updatePointerTargetAndDispatchEvents( |
| 770 EventTypeNames::mousemove, m_frameSetBeingResized.get(), mouseEvent); |
| 1009 } | 771 } |
| 1010 | 772 |
| 1011 if (m_frameSetBeingResized) | |
| 1012 return updatePointerTargetAndDispatchEvents( | |
| 1013 EventTypeNames::mousemove, m_frameSetBeingResized.get(), 0, mouseEvent); | |
| 1014 | |
| 1015 // Send events right to a scrollbar if the mouse is pressed. | 773 // Send events right to a scrollbar if the mouse is pressed. |
| 1016 if (m_lastScrollbarUnderMouse && m_mousePressed) { | 774 if (m_lastScrollbarUnderMouse && m_mouseEventManager->mousePressed()) { |
| 1017 m_lastScrollbarUnderMouse->mouseMoved(mouseEvent); | 775 m_lastScrollbarUnderMouse->mouseMoved(mouseEvent); |
| 1018 return WebInputEventResult::HandledSystem; | 776 return WebInputEventResult::HandledSystem; |
| 1019 } | 777 } |
| 1020 | 778 |
| 1021 // Mouse events simulated from touch should not hit-test again. | 779 // Mouse events simulated from touch should not hit-test again. |
| 1022 ASSERT(!mouseEvent.fromTouch()); | 780 ASSERT(!mouseEvent.fromTouch()); |
| 1023 | 781 |
| 1024 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; | 782 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; |
| 1025 if (m_mousePressed) { | 783 if (m_mouseEventManager->mousePressed()) { |
| 1026 hitType |= HitTestRequest::Active; | 784 hitType |= HitTestRequest::Active; |
| 1027 } else if (onlyUpdateScrollbars) { | 785 } else if (onlyUpdateScrollbars) { |
| 1028 // Mouse events should be treated as "read-only" if we're updating only scro
llbars. This | 786 // Mouse events should be treated as "read-only" if we're updating only scro
llbars. This |
| 1029 // means that :hover and :active freeze in the state they were in, rather th
an updating | 787 // means that :hover and :active freeze in the state they were in, rather th
an updating |
| 1030 // for nodes the mouse moves while the window is not key (which will be the
case if | 788 // for nodes the mouse moves while the window is not key (which will be the
case if |
| 1031 // onlyUpdateScrollbars is true). | 789 // onlyUpdateScrollbars is true). |
| 1032 hitType |= HitTestRequest::ReadOnly; | 790 hitType |= HitTestRequest::ReadOnly; |
| 1033 } | 791 } |
| 1034 | 792 |
| 1035 // Treat any mouse move events as readonly if the user is currently touching t
he screen. | 793 // Treat any mouse move events as readonly if the user is currently touching t
he screen. |
| 1036 if (m_pointerEventManager->isAnyTouchActive()) | 794 if (m_pointerEventManager->isAnyTouchActive()) |
| 1037 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; | 795 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; |
| 1038 HitTestRequest request(hitType); | 796 HitTestRequest request(hitType); |
| 1039 MouseEventWithHitTestResults mev = MouseEventWithHitTestResults( | 797 MouseEventWithHitTestResults mev = MouseEventWithHitTestResults( |
| 1040 mouseEvent, HitTestResult(request, LayoutPoint())); | 798 mouseEvent, HitTestResult(request, LayoutPoint())); |
| 1041 | 799 |
| 1042 // We don't want to do a hit-test in forceLeave scenarios because there might
actually be some other frame above this one at the specified co-ordinate. | 800 // We don't want to do a hit-test in forceLeave scenarios because there might
actually be some other frame above this one at the specified co-ordinate. |
| 1043 // So we must force the hit-test to fail, while still clearing hover/active st
ate. | 801 // So we must force the hit-test to fail, while still clearing hover/active st
ate. |
| 1044 if (forceLeave) | 802 if (forceLeave) { |
| 1045 m_frame->document()->updateHoverActiveState(request, 0); | 803 m_frame->document()->updateHoverActiveState(request, 0); |
| 1046 else | 804 } else { |
| 1047 mev = prepareMouseEvent(request, mouseEvent); | 805 mev = EventHandlingUtil::performMouseEventHitTest(m_frame, request, |
| 806 mouseEvent); |
| 807 } |
| 1048 | 808 |
| 1049 if (hoveredNode) | 809 if (hoveredNode) |
| 1050 *hoveredNode = mev.hitTestResult(); | 810 *hoveredNode = mev.hitTestResult(); |
| 1051 | 811 |
| 1052 Scrollbar* scrollbar = nullptr; | 812 Scrollbar* scrollbar = nullptr; |
| 1053 | 813 |
| 1054 if (m_scrollManager->inResizeMode()) { | 814 if (m_scrollManager->inResizeMode()) { |
| 1055 m_scrollManager->resize(mev.event()); | 815 m_scrollManager->resize(mev.event()); |
| 1056 } else { | 816 } else { |
| 1057 if (!scrollbar) | 817 if (!scrollbar) |
| 1058 scrollbar = mev.scrollbar(); | 818 scrollbar = mev.scrollbar(); |
| 1059 | 819 |
| 1060 updateLastScrollbarUnderMouse(scrollbar, !m_mousePressed); | 820 updateLastScrollbarUnderMouse(scrollbar, |
| 821 !m_mouseEventManager->mousePressed()); |
| 1061 if (onlyUpdateScrollbars) | 822 if (onlyUpdateScrollbars) |
| 1062 return WebInputEventResult::HandledSuppressed; | 823 return WebInputEventResult::HandledSuppressed; |
| 1063 } | 824 } |
| 1064 | 825 |
| 1065 WebInputEventResult eventResult = WebInputEventResult::NotHandled; | 826 WebInputEventResult eventResult = WebInputEventResult::NotHandled; |
| 1066 LocalFrame* newSubframe = | 827 LocalFrame* newSubframe = |
| 1067 m_capturingMouseEventsNode.get() | 828 m_capturingMouseEventsNode.get() |
| 1068 ? subframeForTargetNode(m_capturingMouseEventsNode.get()) | 829 ? subframeForTargetNode(m_capturingMouseEventsNode.get()) |
| 1069 : subframeForHitTestResult(mev); | 830 : subframeForHitTestResult(mev); |
| 1070 | 831 |
| 1071 // We want mouseouts to happen first, from the inside out. First send a move
event to the last subframe so that it will fire mouseouts. | 832 // We want mouseouts to happen first, from the inside out. First send a move
event to the last subframe so that it will fire mouseouts. |
| 1072 if (m_lastMouseMoveEventSubframe && | 833 if (m_lastMouseMoveEventSubframe && |
| 1073 m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && | 834 m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && |
| 1074 m_lastMouseMoveEventSubframe != newSubframe) | 835 m_lastMouseMoveEventSubframe != newSubframe) |
| 1075 m_lastMouseMoveEventSubframe->eventHandler().handleMouseLeaveEvent( | 836 m_lastMouseMoveEventSubframe->eventHandler().handleMouseLeaveEvent( |
| 1076 mev.event()); | 837 mev.event()); |
| 1077 | 838 |
| 1078 if (newSubframe) { | 839 if (newSubframe) { |
| 1079 // Update over/out state before passing the event to the subframe. | 840 // Update over/out state before passing the event to the subframe. |
| 1080 updateMouseEventTargetNodeAndSendEvents(mev.innerNode(), mev.event(), true); | 841 m_pointerEventManager->sendMouseAndPointerBoundaryEvents( |
| 842 updateMouseEventTargetNode(mev.innerNode()), mev.event()); |
| 1081 | 843 |
| 1082 // Event dispatch in updateMouseEventTargetNodeAndSendEvents may have caused
the subframe of the target | 844 // Event dispatch in sendMouseAndPointerBoundaryEvents may have caused the s
ubframe of the target |
| 1083 // node to be detached from its FrameView, in which case the event should no
t be passed. | 845 // node to be detached from its FrameView, in which case the event should no
t be passed. |
| 1084 if (newSubframe->view()) | 846 if (newSubframe->view()) |
| 1085 eventResult = passMouseMoveEventToSubframe(mev, newSubframe, hoveredNode); | 847 eventResult = passMouseMoveEventToSubframe(mev, newSubframe, hoveredNode); |
| 1086 } else { | 848 } else { |
| 1087 if (scrollbar && !m_mousePressed) | 849 if (scrollbar && !m_mouseEventManager->mousePressed()) |
| 1088 scrollbar->mouseMoved( | 850 scrollbar->mouseMoved( |
| 1089 mev.event()); // Handle hover effects on platforms that support visua
l feedback on scrollbar hovering. | 851 mev.event()); // Handle hover effects on platforms that support visua
l feedback on scrollbar hovering. |
| 1090 if (FrameView* view = m_frame->view()) { | 852 if (FrameView* view = m_frame->view()) { |
| 1091 OptionalCursor optionalCursor = selectCursor(mev.hitTestResult()); | 853 OptionalCursor optionalCursor = selectCursor(mev.hitTestResult()); |
| 1092 if (optionalCursor.isCursorChange()) { | 854 if (optionalCursor.isCursorChange()) { |
| 1093 view->setCursor(optionalCursor.cursor()); | 855 view->setCursor(optionalCursor.cursor()); |
| 1094 } | 856 } |
| 1095 } | 857 } |
| 1096 } | 858 } |
| 1097 | 859 |
| 1098 m_lastMouseMoveEventSubframe = newSubframe; | 860 m_lastMouseMoveEventSubframe = newSubframe; |
| 1099 | 861 |
| 1100 if (eventResult != WebInputEventResult::NotHandled) | 862 if (eventResult != WebInputEventResult::NotHandled) |
| 1101 return eventResult; | 863 return eventResult; |
| 1102 | 864 |
| 1103 eventResult = updatePointerTargetAndDispatchEvents( | 865 eventResult = updatePointerTargetAndDispatchEvents( |
| 1104 EventTypeNames::mousemove, mev.innerNode(), 0, mev.event()); | 866 EventTypeNames::mousemove, mev.innerNode(), mev.event()); |
| 1105 if (eventResult != WebInputEventResult::NotHandled) | 867 if (eventResult != WebInputEventResult::NotHandled) |
| 1106 return eventResult; | 868 return eventResult; |
| 1107 | 869 |
| 1108 return handleMouseDraggedEvent(mev); | 870 return m_mouseEventManager->handleMouseDraggedEvent(mev); |
| 1109 } | |
| 1110 | |
| 1111 void EventHandler::invalidateClick() { | |
| 1112 m_clickCount = 0; | |
| 1113 m_clickNode = nullptr; | |
| 1114 } | |
| 1115 | |
| 1116 ContainerNode* EventHandler::parentForClickEvent(const Node& node) { | |
| 1117 // IE doesn't dispatch click events for mousedown/mouseup events across form | |
| 1118 // controls. | |
| 1119 if (node.isHTMLElement() && toHTMLElement(node).isInteractiveContent()) | |
| 1120 return nullptr; | |
| 1121 | |
| 1122 return FlatTreeTraversal::parent(node); | |
| 1123 } | 871 } |
| 1124 | 872 |
| 1125 WebInputEventResult EventHandler::handleMouseReleaseEvent( | 873 WebInputEventResult EventHandler::handleMouseReleaseEvent( |
| 1126 const PlatformMouseEvent& mouseEvent) { | 874 const PlatformMouseEvent& mouseEvent) { |
| 1127 TRACE_EVENT0("blink", "EventHandler::handleMouseReleaseEvent"); | 875 TRACE_EVENT0("blink", "EventHandler::handleMouseReleaseEvent"); |
| 1128 | 876 |
| 1129 // For 4th/5th button in the mouse since Chrome does not yet send | 877 // For 4th/5th button in the mouse since Chrome does not yet send |
| 1130 // button value to Blink but in some cases it does send the event. | 878 // button value to Blink but in some cases it does send the event. |
| 1131 // This check is needed to suppress such an event (crbug.com/574959) | 879 // This check is needed to suppress such an event (crbug.com/574959) |
| 1132 if (mouseEvent.pointerProperties().button == | 880 if (mouseEvent.pointerProperties().button == |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1146 else | 894 else |
| 1147 gestureIndicator = | 895 gestureIndicator = |
| 1148 wrapUnique(new UserGestureIndicator(DefinitelyProcessingUserGesture)); | 896 wrapUnique(new UserGestureIndicator(DefinitelyProcessingUserGesture)); |
| 1149 | 897 |
| 1150 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { | 898 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { |
| 1151 if (Page* page = m_frame->page()) | 899 if (Page* page = m_frame->page()) |
| 1152 page->autoscrollController().handleMouseReleaseForMiddleClickAutoscroll( | 900 page->autoscrollController().handleMouseReleaseForMiddleClickAutoscroll( |
| 1153 m_frame, mouseEvent); | 901 m_frame, mouseEvent); |
| 1154 } | 902 } |
| 1155 | 903 |
| 1156 m_mousePressed = false; | 904 m_mouseEventManager->setMousePressed(false); |
| 1157 setLastKnownMousePosition(mouseEvent); | 905 m_mouseEventManager->setLastKnownMousePosition(mouseEvent); |
| 906 m_mouseEventManager->handleSvgPanIfNeeded(true); |
| 1158 | 907 |
| 1159 if (m_svgPan) { | 908 if (m_frameSetBeingResized) { |
| 1160 m_svgPan = false; | 909 return m_mouseEventManager->setMousePositionAndDispatchMouseEvent( |
| 1161 m_frame->document()->accessSVGExtensions().updatePan( | 910 updateMouseEventTargetNode(m_frameSetBeingResized.get()), |
| 1162 m_frame->view()->rootFrameToContents(m_lastKnownMousePosition)); | 911 EventTypeNames::mouseup, mouseEvent); |
| 1163 return WebInputEventResult::HandledSuppressed; | |
| 1164 } | 912 } |
| 1165 | 913 |
| 1166 if (m_frameSetBeingResized) | |
| 1167 return dispatchMouseEvent(EventTypeNames::mouseup, | |
| 1168 m_frameSetBeingResized.get(), m_clickCount, | |
| 1169 mouseEvent); | |
| 1170 | |
| 1171 if (m_lastScrollbarUnderMouse) { | 914 if (m_lastScrollbarUnderMouse) { |
| 1172 invalidateClick(); | 915 m_mouseEventManager->invalidateClick(); |
| 1173 m_lastScrollbarUnderMouse->mouseUp(mouseEvent); | 916 m_lastScrollbarUnderMouse->mouseUp(mouseEvent); |
| 1174 return updatePointerTargetAndDispatchEvents(EventTypeNames::mouseup, | 917 return updatePointerTargetAndDispatchEvents( |
| 1175 m_nodeUnderMouse.get(), | 918 EventTypeNames::mouseup, m_mouseEventManager->getNodeUnderMouse(), |
| 1176 m_clickCount, mouseEvent); | 919 mouseEvent); |
| 1177 } | 920 } |
| 1178 | 921 |
| 1179 // Mouse events simulated from touch should not hit-test again. | 922 // Mouse events simulated from touch should not hit-test again. |
| 1180 ASSERT(!mouseEvent.fromTouch()); | 923 ASSERT(!mouseEvent.fromTouch()); |
| 1181 | 924 |
| 1182 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release; | 925 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release; |
| 1183 HitTestRequest request(hitType); | 926 HitTestRequest request(hitType); |
| 1184 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); | 927 MouseEventWithHitTestResults mev = |
| 928 EventHandlingUtil::performMouseEventHitTest(m_frame, request, mouseEvent); |
| 1185 LocalFrame* subframe = | 929 LocalFrame* subframe = |
| 1186 m_capturingMouseEventsNode.get() | 930 m_capturingMouseEventsNode.get() |
| 1187 ? subframeForTargetNode(m_capturingMouseEventsNode.get()) | 931 ? subframeForTargetNode(m_capturingMouseEventsNode.get()) |
| 1188 : subframeForHitTestResult(mev); | 932 : subframeForHitTestResult(mev); |
| 1189 if (m_eventHandlerWillResetCapturingMouseEventsNode) | 933 if (m_eventHandlerWillResetCapturingMouseEventsNode) |
| 1190 m_capturingMouseEventsNode = nullptr; | 934 m_capturingMouseEventsNode = nullptr; |
| 1191 if (subframe) | 935 if (subframe) |
| 1192 return passMouseReleaseEventToSubframe(mev, subframe); | 936 return passMouseReleaseEventToSubframe(mev, subframe); |
| 1193 | 937 |
| 1194 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents( | 938 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents( |
| 1195 EventTypeNames::mouseup, mev.innerNode(), m_clickCount, mev.event()); | 939 EventTypeNames::mouseup, mev.innerNode(), mev.event()); |
| 1196 | 940 |
| 1197 // We only prevent click event when the click may cause contextmenu to popup. | 941 WebInputEventResult clickEventResult = |
| 1198 // However, we always send auxclick. | 942 m_mouseEventManager->dispatchMouseClickIfNeeded(mev); |
| 1199 bool contextMenuEvent = !RuntimeEnabledFeatures::auxclickEnabled() && | |
| 1200 mouseEvent.pointerProperties().button == | |
| 1201 WebPointerProperties::Button::Right; | |
| 1202 #if OS(MACOSX) | |
| 1203 // FIXME: The Mac port achieves the same behavior by checking whether the cont
ext menu is currently open in WebPage::mouseEvent(). Consider merging the implem
entations. | |
| 1204 if (mouseEvent.pointerProperties().button == | |
| 1205 WebPointerProperties::Button::Left && | |
| 1206 mouseEvent.getModifiers() & PlatformEvent::CtrlKey) | |
| 1207 contextMenuEvent = true; | |
| 1208 #endif | |
| 1209 | |
| 1210 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; | |
| 1211 const bool shouldDispatchClickEvent = | |
| 1212 m_clickCount > 0 && !contextMenuEvent && mev.innerNode() && m_clickNode && | |
| 1213 mev.innerNode()->canParticipateInFlatTree() && | |
| 1214 m_clickNode->canParticipateInFlatTree() && | |
| 1215 !(selectionController().hasExtendedSelection() && isLinkSelection(mev)); | |
| 1216 if (shouldDispatchClickEvent) { | |
| 1217 Node* clickTargetNode = nullptr; | |
| 1218 // Updates distribution because a 'mouseup' event listener can make the | |
| 1219 // tree dirty at dispatchMouseEvent() invocation above. | |
| 1220 // Unless distribution is updated, commonAncestor would hit ASSERT. | |
| 1221 if (m_clickNode == mev.innerNode()) { | |
| 1222 clickTargetNode = m_clickNode; | |
| 1223 clickTargetNode->updateDistribution(); | |
| 1224 } else if (m_clickNode->document() == mev.innerNode()->document()) { | |
| 1225 m_clickNode->updateDistribution(); | |
| 1226 mev.innerNode()->updateDistribution(); | |
| 1227 clickTargetNode = | |
| 1228 mev.innerNode()->commonAncestor(*m_clickNode, parentForClickEvent); | |
| 1229 } | |
| 1230 if (clickTargetNode) { | |
| 1231 // Dispatch mouseup directly w/o calling updateMouseEventTargetNodeAndSend
Events | |
| 1232 // because the mouseup dispatch above has already updated it | |
| 1233 // correctly. Moreover, clickTargetNode is different from | |
| 1234 // mev.innerNode at drag-release. | |
| 1235 clickEventResult = EventHandlingUtil::toWebInputEventResult( | |
| 1236 clickTargetNode->dispatchMouseEvent( | |
| 1237 mev.event(), !RuntimeEnabledFeatures::auxclickEnabled() || | |
| 1238 (mev.event().pointerProperties().button == | |
| 1239 WebPointerProperties::Button::Left) | |
| 1240 ? EventTypeNames::click | |
| 1241 : EventTypeNames::auxclick, | |
| 1242 m_clickCount)); | |
| 1243 } | |
| 1244 } | |
| 1245 | 943 |
| 1246 m_scrollManager->clearResizeScrollableArea(false); | 944 m_scrollManager->clearResizeScrollableArea(false); |
| 1247 | 945 |
| 1248 if (eventResult == WebInputEventResult::NotHandled) | 946 if (eventResult == WebInputEventResult::NotHandled) |
| 1249 eventResult = handleMouseReleaseEvent(mev); | 947 eventResult = m_mouseEventManager->handleMouseReleaseEvent(mev); |
| 1250 clearDragHeuristicState(); | 948 m_mouseEventManager->clearDragHeuristicState(); |
| 1251 | 949 |
| 1252 invalidateClick(); | 950 m_mouseEventManager->invalidateClick(); |
| 1253 | 951 |
| 1254 return EventHandlingUtil::mergeEventResult(clickEventResult, eventResult); | 952 return EventHandlingUtil::mergeEventResult(clickEventResult, eventResult); |
| 1255 } | 953 } |
| 1256 | 954 |
| 1257 WebInputEventResult EventHandler::dispatchDragEvent( | |
| 1258 const AtomicString& eventType, | |
| 1259 Node* dragTarget, | |
| 1260 const PlatformMouseEvent& event, | |
| 1261 DataTransfer* dataTransfer) { | |
| 1262 FrameView* view = m_frame->view(); | |
| 1263 | |
| 1264 // FIXME: We might want to dispatch a dragleave even if the view is gone. | |
| 1265 if (!view) | |
| 1266 return WebInputEventResult::NotHandled; | |
| 1267 | |
| 1268 DragEvent* me = DragEvent::create( | |
| 1269 eventType, true, true, m_frame->document()->domWindow(), 0, | |
| 1270 event.globalPosition().x(), event.globalPosition().y(), | |
| 1271 event.position().x(), event.position().y(), event.movementDelta().x(), | |
| 1272 event.movementDelta().y(), event.getModifiers(), 0, | |
| 1273 MouseEvent::platformModifiersToButtons(event.getModifiers()), nullptr, | |
| 1274 event.timestamp(), dataTransfer, event.getSyntheticEventType()); | |
| 1275 | |
| 1276 return EventHandlingUtil::toWebInputEventResult( | |
| 1277 dragTarget->dispatchEvent(me)); | |
| 1278 } | |
| 1279 | |
| 1280 static bool targetIsFrame(Node* target, LocalFrame*& frame) { | 955 static bool targetIsFrame(Node* target, LocalFrame*& frame) { |
| 1281 if (!isHTMLFrameElementBase(target)) | 956 if (!isHTMLFrameElementBase(target)) |
| 1282 return false; | 957 return false; |
| 1283 | 958 |
| 1284 // Cross-process drag and drop is not yet supported. | 959 // Cross-process drag and drop is not yet supported. |
| 1285 if (toHTMLFrameElementBase(target)->contentFrame() && | 960 if (toHTMLFrameElementBase(target)->contentFrame() && |
| 1286 !toHTMLFrameElementBase(target)->contentFrame()->isLocalFrame()) | 961 !toHTMLFrameElementBase(target)->contentFrame()->isLocalFrame()) |
| 1287 return false; | 962 return false; |
| 1288 | 963 |
| 1289 frame = toLocalFrame(toHTMLFrameElementBase(target)->contentFrame()); | 964 frame = toLocalFrame(toHTMLFrameElementBase(target)->contentFrame()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 | 1009 |
| 1335 WebInputEventResult EventHandler::updateDragAndDrop( | 1010 WebInputEventResult EventHandler::updateDragAndDrop( |
| 1336 const PlatformMouseEvent& event, | 1011 const PlatformMouseEvent& event, |
| 1337 DataTransfer* dataTransfer) { | 1012 DataTransfer* dataTransfer) { |
| 1338 WebInputEventResult eventResult = WebInputEventResult::NotHandled; | 1013 WebInputEventResult eventResult = WebInputEventResult::NotHandled; |
| 1339 | 1014 |
| 1340 if (!m_frame->view()) | 1015 if (!m_frame->view()) |
| 1341 return eventResult; | 1016 return eventResult; |
| 1342 | 1017 |
| 1343 HitTestRequest request(HitTestRequest::ReadOnly); | 1018 HitTestRequest request(HitTestRequest::ReadOnly); |
| 1344 MouseEventWithHitTestResults mev = prepareMouseEvent(request, event); | 1019 MouseEventWithHitTestResults mev = |
| 1020 EventHandlingUtil::performMouseEventHitTest(m_frame, request, event); |
| 1345 | 1021 |
| 1346 // Drag events should never go to text nodes (following IE, and proper mouseov
er/out dispatch) | 1022 // Drag events should never go to text nodes (following IE, and proper mouseov
er/out dispatch) |
| 1347 Node* newTarget = mev.innerNode(); | 1023 Node* newTarget = mev.innerNode(); |
| 1348 if (newTarget && newTarget->isTextNode()) | 1024 if (newTarget && newTarget->isTextNode()) |
| 1349 newTarget = FlatTreeTraversal::parent(*newTarget); | 1025 newTarget = FlatTreeTraversal::parent(*newTarget); |
| 1350 | 1026 |
| 1351 if (AutoscrollController* controller = | 1027 if (AutoscrollController* controller = |
| 1352 m_scrollManager->autoscrollController()) | 1028 m_scrollManager->autoscrollController()) |
| 1353 controller->updateDragAndDrop(newTarget, event.position(), | 1029 controller->updateDragAndDrop(newTarget, event.position(), |
| 1354 event.timestamp()); | 1030 event.timestamp()); |
| 1355 | 1031 |
| 1356 if (m_dragTarget != newTarget) { | 1032 if (m_dragTarget != newTarget) { |
| 1357 // FIXME: this ordering was explicitly chosen to match WinIE. However, | 1033 // FIXME: this ordering was explicitly chosen to match WinIE. However, |
| 1358 // it is sometimes incorrect when dragging within subframes, as seen with | 1034 // it is sometimes incorrect when dragging within subframes, as seen with |
| 1359 // LayoutTests/fast/events/drag-in-frames.html. | 1035 // LayoutTests/fast/events/drag-in-frames.html. |
| 1360 // | 1036 // |
| 1361 // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <ht
tp://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. | 1037 // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <ht
tp://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. |
| 1362 LocalFrame* targetFrame; | 1038 LocalFrame* targetFrame; |
| 1363 if (targetIsFrame(newTarget, targetFrame)) { | 1039 if (targetIsFrame(newTarget, targetFrame)) { |
| 1364 if (targetFrame) | 1040 if (targetFrame) |
| 1365 eventResult = | 1041 eventResult = |
| 1366 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); | 1042 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); |
| 1367 } else if (newTarget) { | 1043 } else if (newTarget) { |
| 1368 // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag ev
ent before firing a dragenter, dragleave, or dragover event. | 1044 // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag ev
ent before firing a dragenter, dragleave, or dragover event. |
| 1369 if (dragState().m_dragSrc) { | 1045 if (m_mouseEventManager->dragState().m_dragSrc) { |
| 1370 // for now we don't care if event handler cancels default behavior, sinc
e there is none | 1046 // for now we don't care if event handler cancels default behavior, sinc
e there is none |
| 1371 dispatchDragSrcEvent(EventTypeNames::drag, event); | 1047 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
| 1372 } | 1048 } |
| 1373 eventResult = dispatchDragEvent(EventTypeNames::dragenter, newTarget, | 1049 eventResult = m_mouseEventManager->dispatchDragEvent( |
| 1374 event, dataTransfer); | 1050 EventTypeNames::dragenter, newTarget, event, dataTransfer); |
| 1375 if (eventResult == WebInputEventResult::NotHandled && | 1051 if (eventResult == WebInputEventResult::NotHandled && |
| 1376 findDropZone(newTarget, dataTransfer)) | 1052 findDropZone(newTarget, dataTransfer)) |
| 1377 eventResult = WebInputEventResult::HandledSystem; | 1053 eventResult = WebInputEventResult::HandledSystem; |
| 1378 } | 1054 } |
| 1379 | 1055 |
| 1380 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 1056 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
| 1381 if (targetFrame) | 1057 if (targetFrame) |
| 1382 eventResult = | 1058 eventResult = |
| 1383 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); | 1059 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); |
| 1384 } else if (m_dragTarget) { | 1060 } else if (m_dragTarget) { |
| 1385 dispatchDragEvent(EventTypeNames::dragleave, m_dragTarget.get(), event, | 1061 m_mouseEventManager->dispatchDragEvent( |
| 1386 dataTransfer); | 1062 EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer); |
| 1387 } | 1063 } |
| 1388 | 1064 |
| 1389 if (newTarget) { | 1065 if (newTarget) { |
| 1390 // We do not explicitly call dispatchDragEvent here because it could ultim
ately result in the appearance that | 1066 // We do not explicitly call m_mouseEventManager->dispatchDragEvent here b
ecause it could ultimately result in the appearance that |
| 1391 // two dragover events fired. So, we mark that we should only fire a drago
ver event on the next call to this function. | 1067 // two dragover events fired. So, we mark that we should only fire a drago
ver event on the next call to this function. |
| 1392 m_shouldOnlyFireDragOverEvent = true; | 1068 m_shouldOnlyFireDragOverEvent = true; |
| 1393 } | 1069 } |
| 1394 } else { | 1070 } else { |
| 1395 LocalFrame* targetFrame; | 1071 LocalFrame* targetFrame; |
| 1396 if (targetIsFrame(newTarget, targetFrame)) { | 1072 if (targetIsFrame(newTarget, targetFrame)) { |
| 1397 if (targetFrame) | 1073 if (targetFrame) |
| 1398 eventResult = | 1074 eventResult = |
| 1399 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); | 1075 targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer); |
| 1400 } else if (newTarget) { | 1076 } else if (newTarget) { |
| 1401 // Note, when dealing with sub-frames, we may need to fire only a dragover
event as a drag event may have been fired earlier. | 1077 // Note, when dealing with sub-frames, we may need to fire only a dragover
event as a drag event may have been fired earlier. |
| 1402 if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc) { | 1078 if (!m_shouldOnlyFireDragOverEvent && |
| 1079 m_mouseEventManager->dragState().m_dragSrc) { |
| 1403 // for now we don't care if event handler cancels default behavior, sinc
e there is none | 1080 // for now we don't care if event handler cancels default behavior, sinc
e there is none |
| 1404 dispatchDragSrcEvent(EventTypeNames::drag, event); | 1081 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
| 1405 } | 1082 } |
| 1406 eventResult = dispatchDragEvent(EventTypeNames::dragover, newTarget, | 1083 eventResult = m_mouseEventManager->dispatchDragEvent( |
| 1407 event, dataTransfer); | 1084 EventTypeNames::dragover, newTarget, event, dataTransfer); |
| 1408 if (eventResult == WebInputEventResult::NotHandled && | 1085 if (eventResult == WebInputEventResult::NotHandled && |
| 1409 findDropZone(newTarget, dataTransfer)) | 1086 findDropZone(newTarget, dataTransfer)) |
| 1410 eventResult = WebInputEventResult::HandledSystem; | 1087 eventResult = WebInputEventResult::HandledSystem; |
| 1411 m_shouldOnlyFireDragOverEvent = false; | 1088 m_shouldOnlyFireDragOverEvent = false; |
| 1412 } | 1089 } |
| 1413 } | 1090 } |
| 1414 m_dragTarget = newTarget; | 1091 m_dragTarget = newTarget; |
| 1415 | 1092 |
| 1416 return eventResult; | 1093 return eventResult; |
| 1417 } | 1094 } |
| 1418 | 1095 |
| 1419 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, | 1096 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, |
| 1420 DataTransfer* dataTransfer) { | 1097 DataTransfer* dataTransfer) { |
| 1421 LocalFrame* targetFrame; | 1098 LocalFrame* targetFrame; |
| 1422 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 1099 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
| 1423 if (targetFrame) | 1100 if (targetFrame) |
| 1424 targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer); | 1101 targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer); |
| 1425 } else if (m_dragTarget.get()) { | 1102 } else if (m_dragTarget.get()) { |
| 1426 if (dragState().m_dragSrc) | 1103 if (m_mouseEventManager->dragState().m_dragSrc) |
| 1427 dispatchDragSrcEvent(EventTypeNames::drag, event); | 1104 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
| 1428 dispatchDragEvent(EventTypeNames::dragleave, m_dragTarget.get(), event, | 1105 m_mouseEventManager->dispatchDragEvent( |
| 1429 dataTransfer); | 1106 EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer); |
| 1430 } | 1107 } |
| 1431 clearDragState(); | 1108 clearDragState(); |
| 1432 } | 1109 } |
| 1433 | 1110 |
| 1434 WebInputEventResult EventHandler::performDragAndDrop( | 1111 WebInputEventResult EventHandler::performDragAndDrop( |
| 1435 const PlatformMouseEvent& event, | 1112 const PlatformMouseEvent& event, |
| 1436 DataTransfer* dataTransfer) { | 1113 DataTransfer* dataTransfer) { |
| 1437 LocalFrame* targetFrame; | 1114 LocalFrame* targetFrame; |
| 1438 WebInputEventResult result = WebInputEventResult::NotHandled; | 1115 WebInputEventResult result = WebInputEventResult::NotHandled; |
| 1439 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 1116 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
| 1440 if (targetFrame) | 1117 if (targetFrame) |
| 1441 result = | 1118 result = |
| 1442 targetFrame->eventHandler().performDragAndDrop(event, dataTransfer); | 1119 targetFrame->eventHandler().performDragAndDrop(event, dataTransfer); |
| 1443 } else if (m_dragTarget.get()) { | 1120 } else if (m_dragTarget.get()) { |
| 1444 result = dispatchDragEvent(EventTypeNames::drop, m_dragTarget.get(), event, | 1121 result = m_mouseEventManager->dispatchDragEvent( |
| 1445 dataTransfer); | 1122 EventTypeNames::drop, m_dragTarget.get(), event, dataTransfer); |
| 1446 } | 1123 } |
| 1447 clearDragState(); | 1124 clearDragState(); |
| 1448 return result; | 1125 return result; |
| 1449 } | 1126 } |
| 1450 | 1127 |
| 1451 void EventHandler::clearDragHeuristicState() { | |
| 1452 // Used to prevent mouseMoveEvent from initiating a drag before | |
| 1453 // the mouse is pressed again. | |
| 1454 m_mousePressed = false; | |
| 1455 m_capturesDragging = false; | |
| 1456 m_mouseDownMayStartDrag = false; | |
| 1457 m_mouseDownMayStartAutoscroll = false; | |
| 1458 } | |
| 1459 | |
| 1460 void EventHandler::clearDragState() { | 1128 void EventHandler::clearDragState() { |
| 1461 m_scrollManager->stopAutoscroll(); | 1129 m_scrollManager->stopAutoscroll(); |
| 1462 m_dragTarget = nullptr; | 1130 m_dragTarget = nullptr; |
| 1463 m_capturingMouseEventsNode = nullptr; | 1131 m_capturingMouseEventsNode = nullptr; |
| 1464 m_shouldOnlyFireDragOverEvent = false; | 1132 m_shouldOnlyFireDragOverEvent = false; |
| 1465 } | 1133 } |
| 1466 | 1134 |
| 1467 void EventHandler::setCapturingMouseEventsNode(Node* n) { | 1135 void EventHandler::setCapturingMouseEventsNode(Node* n) { |
| 1468 m_capturingMouseEventsNode = n; | 1136 m_capturingMouseEventsNode = n; |
| 1469 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 1137 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
| 1470 } | 1138 } |
| 1471 | 1139 |
| 1472 MouseEventWithHitTestResults EventHandler::prepareMouseEvent( | 1140 Node* EventHandler::updateMouseEventTargetNode(Node* targetNode) { |
| 1473 const HitTestRequest& request, | |
| 1474 const PlatformMouseEvent& mev) { | |
| 1475 ASSERT(m_frame); | |
| 1476 ASSERT(m_frame->document()); | |
| 1477 | |
| 1478 return m_frame->document()->prepareMouseEvent( | |
| 1479 request, contentPointFromRootFrame(m_frame, mev.position()), mev); | |
| 1480 } | |
| 1481 | |
| 1482 Node* EventHandler::updateMouseEventTargetNode( | |
| 1483 Node* targetNode, | |
| 1484 const PlatformMouseEvent& mouseEvent) { | |
| 1485 Node* newNodeUnderMouse = targetNode; | 1141 Node* newNodeUnderMouse = targetNode; |
| 1486 | 1142 |
| 1487 // If we're capturing, we always go right to that node. | 1143 // If we're capturing, we always go right to that node. |
| 1488 EventTarget* mousePointerCapturingNode = | 1144 EventTarget* mousePointerCapturingNode = |
| 1489 m_pointerEventManager->getMouseCapturingNode(); | 1145 m_pointerEventManager->getMouseCapturingNode(); |
| 1490 if (mousePointerCapturingNode && | 1146 if (mousePointerCapturingNode && |
| 1491 !RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { | 1147 !RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { |
| 1492 newNodeUnderMouse = mousePointerCapturingNode->toNode(); | 1148 newNodeUnderMouse = mousePointerCapturingNode->toNode(); |
| 1493 DCHECK(newNodeUnderMouse); | 1149 DCHECK(newNodeUnderMouse); |
| 1494 } else if (m_capturingMouseEventsNode) { | 1150 } else if (m_capturingMouseEventsNode) { |
| 1495 newNodeUnderMouse = m_capturingMouseEventsNode.get(); | 1151 newNodeUnderMouse = m_capturingMouseEventsNode.get(); |
| 1496 } else { | 1152 } else { |
| 1497 // If the target node is a text node, dispatch on the parent node - rdar://4
196646 | 1153 // If the target node is a text node, dispatch on the parent node - rdar://4
196646 |
| 1498 if (newNodeUnderMouse && newNodeUnderMouse->isTextNode()) | 1154 if (newNodeUnderMouse && newNodeUnderMouse->isTextNode()) |
| 1499 newNodeUnderMouse = FlatTreeTraversal::parent(*newNodeUnderMouse); | 1155 newNodeUnderMouse = FlatTreeTraversal::parent(*newNodeUnderMouse); |
| 1500 } | 1156 } |
| 1501 Node* lastNodeUnderMouse = m_nodeUnderMouse; | 1157 return newNodeUnderMouse; |
| 1502 m_nodeUnderMouse = newNodeUnderMouse; | |
| 1503 | |
| 1504 PaintLayer* layerForLastNode = layerForNode(lastNodeUnderMouse); | |
| 1505 PaintLayer* layerForNodeUnderMouse = layerForNode(m_nodeUnderMouse.get()); | |
| 1506 Page* page = m_frame->page(); | |
| 1507 | |
| 1508 if (lastNodeUnderMouse && | |
| 1509 (!m_nodeUnderMouse || | |
| 1510 m_nodeUnderMouse->document() != m_frame->document())) { | |
| 1511 // The mouse has moved between frames. | |
| 1512 if (LocalFrame* frame = lastNodeUnderMouse->document().frame()) { | |
| 1513 if (FrameView* frameView = frame->view()) | |
| 1514 frameView->mouseExitedContentArea(); | |
| 1515 } | |
| 1516 } else if (page && (layerForLastNode && | |
| 1517 (!layerForNodeUnderMouse || | |
| 1518 layerForNodeUnderMouse != layerForLastNode))) { | |
| 1519 // The mouse has moved between layers. | |
| 1520 if (ScrollableArea* scrollableAreaForLastNode = | |
| 1521 associatedScrollableArea(layerForLastNode)) | |
| 1522 scrollableAreaForLastNode->mouseExitedContentArea(); | |
| 1523 } | |
| 1524 | |
| 1525 if (m_nodeUnderMouse && | |
| 1526 (!lastNodeUnderMouse || | |
| 1527 lastNodeUnderMouse->document() != m_frame->document())) { | |
| 1528 // The mouse has moved between frames. | |
| 1529 if (LocalFrame* frame = m_nodeUnderMouse->document().frame()) { | |
| 1530 if (FrameView* frameView = frame->view()) | |
| 1531 frameView->mouseEnteredContentArea(); | |
| 1532 } | |
| 1533 } else if (page && (layerForNodeUnderMouse && | |
| 1534 (!layerForLastNode || | |
| 1535 layerForNodeUnderMouse != layerForLastNode))) { | |
| 1536 // The mouse has moved between layers. | |
| 1537 if (ScrollableArea* scrollableAreaForNodeUnderMouse = | |
| 1538 associatedScrollableArea(layerForNodeUnderMouse)) | |
| 1539 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea(); | |
| 1540 } | |
| 1541 | |
| 1542 if (lastNodeUnderMouse && | |
| 1543 lastNodeUnderMouse->document() != m_frame->document()) { | |
| 1544 lastNodeUnderMouse = nullptr; | |
| 1545 m_lastScrollbarUnderMouse = nullptr; | |
| 1546 } | |
| 1547 | |
| 1548 return lastNodeUnderMouse; | |
| 1549 } | |
| 1550 | |
| 1551 void EventHandler::updateMouseEventTargetNodeAndSendEvents( | |
| 1552 Node* targetNode, | |
| 1553 const PlatformMouseEvent& mouseEvent, | |
| 1554 bool isFrameBoundaryTransition) { | |
| 1555 Node* lastNodeUnderMouse = updateMouseEventTargetNode(targetNode, mouseEvent); | |
| 1556 m_pointerEventManager->sendMouseAndPossiblyPointerBoundaryEvents( | |
| 1557 lastNodeUnderMouse, m_nodeUnderMouse, mouseEvent, | |
| 1558 isFrameBoundaryTransition); | |
| 1559 } | |
| 1560 | |
| 1561 WebInputEventResult EventHandler::dispatchMouseEvent( | |
| 1562 const AtomicString& eventType, | |
| 1563 Node* targetNode, | |
| 1564 int clickCount, | |
| 1565 const PlatformMouseEvent& mouseEvent) { | |
| 1566 updateMouseEventTargetNodeAndSendEvents(targetNode, mouseEvent); | |
| 1567 | |
| 1568 return m_mouseEventManager->dispatchMouseEvent( | |
| 1569 m_nodeUnderMouse, eventType, mouseEvent, nullptr, clickCount); | |
| 1570 } | 1158 } |
| 1571 | 1159 |
| 1572 bool EventHandler::isPointerEventActive(int pointerId) { | 1160 bool EventHandler::isPointerEventActive(int pointerId) { |
| 1573 return m_pointerEventManager->isActive(pointerId); | 1161 return m_pointerEventManager->isActive(pointerId); |
| 1574 } | 1162 } |
| 1575 | 1163 |
| 1576 void EventHandler::setPointerCapture(int pointerId, EventTarget* target) { | 1164 void EventHandler::setPointerCapture(int pointerId, EventTarget* target) { |
| 1577 // TODO(crbug.com/591387): This functionality should be per page not per frame
. | 1165 // TODO(crbug.com/591387): This functionality should be per page not per frame
. |
| 1578 m_pointerEventManager->setPointerCapture(pointerId, target); | 1166 m_pointerEventManager->setPointerCapture(pointerId, target); |
| 1579 } | 1167 } |
| 1580 | 1168 |
| 1581 void EventHandler::releasePointerCapture(int pointerId, EventTarget* target) { | 1169 void EventHandler::releasePointerCapture(int pointerId, EventTarget* target) { |
| 1582 m_pointerEventManager->releasePointerCapture(pointerId, target); | 1170 m_pointerEventManager->releasePointerCapture(pointerId, target); |
| 1583 } | 1171 } |
| 1584 | 1172 |
| 1585 bool EventHandler::hasPointerCapture(int pointerId, | 1173 bool EventHandler::hasPointerCapture(int pointerId, |
| 1586 const EventTarget* target) const { | 1174 const EventTarget* target) const { |
| 1587 return m_pointerEventManager->hasPointerCapture(pointerId, target); | 1175 return m_pointerEventManager->hasPointerCapture(pointerId, target); |
| 1588 } | 1176 } |
| 1589 | 1177 |
| 1590 bool EventHandler::hasProcessedPointerCapture(int pointerId, | 1178 bool EventHandler::hasProcessedPointerCapture(int pointerId, |
| 1591 const EventTarget* target) const { | 1179 const EventTarget* target) const { |
| 1592 return m_pointerEventManager->hasProcessedPointerCapture(pointerId, target); | 1180 return m_pointerEventManager->hasProcessedPointerCapture(pointerId, target); |
| 1593 } | 1181 } |
| 1594 | 1182 |
| 1595 void EventHandler::elementRemoved(EventTarget* target) { | 1183 void EventHandler::elementRemoved(EventTarget* target) { |
| 1596 m_pointerEventManager->elementRemoved(target); | 1184 m_pointerEventManager->elementRemoved(target); |
| 1597 } | 1185 } |
| 1598 | 1186 |
| 1599 // TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler. | |
| 1600 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents( | 1187 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents( |
| 1601 const AtomicString& mouseEventType, | 1188 const AtomicString& mouseEventType, |
| 1602 Node* targetNode, | 1189 Node* targetNode, |
| 1603 int clickCount, | |
| 1604 const PlatformMouseEvent& mouseEvent) { | 1190 const PlatformMouseEvent& mouseEvent) { |
| 1605 ASSERT(mouseEventType == EventTypeNames::mousedown || | 1191 ASSERT(mouseEventType == EventTypeNames::mousedown || |
| 1606 mouseEventType == EventTypeNames::mousemove || | 1192 mouseEventType == EventTypeNames::mousemove || |
| 1607 mouseEventType == EventTypeNames::mouseup); | 1193 mouseEventType == EventTypeNames::mouseup); |
| 1608 | 1194 |
| 1609 Node* lastNodeUnderMouse = updateMouseEventTargetNode(targetNode, mouseEvent); | |
| 1610 | |
| 1611 Node* newNodeUnderMouse = nullptr; | |
| 1612 const auto& eventResult = m_pointerEventManager->sendMousePointerEvent( | 1195 const auto& eventResult = m_pointerEventManager->sendMousePointerEvent( |
| 1613 m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, | 1196 updateMouseEventTargetNode(targetNode), mouseEventType, mouseEvent); |
| 1614 lastNodeUnderMouse, &newNodeUnderMouse); | |
| 1615 m_nodeUnderMouse = newNodeUnderMouse; | |
| 1616 return eventResult; | 1197 return eventResult; |
| 1617 } | 1198 } |
| 1618 | 1199 |
| 1619 void EventHandler::setClickNode(Node* node) { | |
| 1620 m_clickNode = node; | |
| 1621 } | |
| 1622 | |
| 1623 WebInputEventResult EventHandler::handleMouseFocus( | |
| 1624 const HitTestResult& hitTestResult, | |
| 1625 InputDeviceCapabilities* sourceCapabilities) { | |
| 1626 // If clicking on a frame scrollbar, do not mess up with content focus. | |
| 1627 if (hitTestResult.scrollbar() && !m_frame->contentLayoutItem().isNull()) { | |
| 1628 if (hitTestResult.scrollbar()->getScrollableArea() == | |
| 1629 m_frame->contentLayoutItem().getScrollableArea()) | |
| 1630 return WebInputEventResult::NotHandled; | |
| 1631 } | |
| 1632 | |
| 1633 // The layout needs to be up to date to determine if an element is focusable. | |
| 1634 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 1635 | |
| 1636 Element* element = nullptr; | |
| 1637 if (m_nodeUnderMouse) | |
| 1638 element = m_nodeUnderMouse->isElementNode() | |
| 1639 ? toElement(m_nodeUnderMouse) | |
| 1640 : m_nodeUnderMouse->parentOrShadowHostElement(); | |
| 1641 for (; element; element = element->parentOrShadowHostElement()) { | |
| 1642 if (element->isFocusable() && element->isFocusedElementInDocument()) | |
| 1643 return WebInputEventResult::NotHandled; | |
| 1644 if (element->isMouseFocusable()) | |
| 1645 break; | |
| 1646 } | |
| 1647 ASSERT(!element || element->isMouseFocusable()); | |
| 1648 | |
| 1649 // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus | |
| 1650 // a node on mouse down if it's selected and inside a focused node. It will | |
| 1651 // be focused if the user does a mouseup over it, however, because the | |
| 1652 // mouseup will set a selection inside it, which will call | |
| 1653 // FrameSelection::setFocusedNodeIfNeeded. | |
| 1654 if (element && m_frame->selection().isRange()) { | |
| 1655 // TODO(yosin) We should not create |Range| object for calling | |
| 1656 // |isNodeFullyContained()|. | |
| 1657 if (createRange( | |
| 1658 m_frame->selection().selection().toNormalizedEphemeralRange()) | |
| 1659 ->isNodeFullyContained(*element) && | |
| 1660 element->isDescendantOf(m_frame->document()->focusedElement())) | |
| 1661 return WebInputEventResult::NotHandled; | |
| 1662 } | |
| 1663 | |
| 1664 // Only change the focus when clicking scrollbars if it can transfered to a | |
| 1665 // mouse focusable node. | |
| 1666 if (!element && hitTestResult.scrollbar()) | |
| 1667 return WebInputEventResult::HandledSystem; | |
| 1668 | |
| 1669 if (Page* page = m_frame->page()) { | |
| 1670 // If focus shift is blocked, we eat the event. Note we should never | |
| 1671 // clear swallowEvent if the page already set it (e.g., by canceling | |
| 1672 // default behavior). | |
| 1673 if (element) { | |
| 1674 if (slideFocusOnShadowHostIfNecessary(*element)) | |
| 1675 return WebInputEventResult::HandledSystem; | |
| 1676 if (!page->focusController().setFocusedElement( | |
| 1677 element, m_frame, | |
| 1678 FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeMouse, | |
| 1679 sourceCapabilities))) | |
| 1680 return WebInputEventResult::HandledSystem; | |
| 1681 } else { | |
| 1682 // We call setFocusedElement even with !element in order to blur | |
| 1683 // current focus element when a link is clicked; this is expected by | |
| 1684 // some sites that rely on onChange handlers running from form | |
| 1685 // fields before the button click is processed. | |
| 1686 if (!page->focusController().setFocusedElement( | |
| 1687 nullptr, m_frame, | |
| 1688 FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, | |
| 1689 sourceCapabilities))) | |
| 1690 return WebInputEventResult::HandledSystem; | |
| 1691 } | |
| 1692 } | |
| 1693 | |
| 1694 return WebInputEventResult::NotHandled; | |
| 1695 } | |
| 1696 | |
| 1697 bool EventHandler::slideFocusOnShadowHostIfNecessary(const Element& element) { | |
| 1698 if (element.authorShadowRoot() && | |
| 1699 element.authorShadowRoot()->delegatesFocus()) { | |
| 1700 Document* doc = m_frame->document(); | |
| 1701 if (element.isShadowIncludingInclusiveAncestorOf(doc->focusedElement())) { | |
| 1702 // If the inner element is already focused, do nothing. | |
| 1703 return true; | |
| 1704 } | |
| 1705 | |
| 1706 // If the host has a focusable inner element, focus it. Otherwise, the host
takes focus. | |
| 1707 Page* page = m_frame->page(); | |
| 1708 ASSERT(page); | |
| 1709 Element* found = | |
| 1710 page->focusController().findFocusableElementInShadowHost(element); | |
| 1711 if (found && element.isShadowIncludingInclusiveAncestorOf(found)) { | |
| 1712 // Use WebFocusTypeForward instead of WebFocusTypeMouse here to mean the f
ocus has slided. | |
| 1713 found->focus(FocusParams(SelectionBehaviorOnFocus::Reset, | |
| 1714 WebFocusTypeForward, nullptr)); | |
| 1715 return true; | |
| 1716 } | |
| 1717 } | |
| 1718 return false; | |
| 1719 } | |
| 1720 | |
| 1721 WebInputEventResult EventHandler::handleWheelEvent( | 1200 WebInputEventResult EventHandler::handleWheelEvent( |
| 1722 const PlatformWheelEvent& event) { | 1201 const PlatformWheelEvent& event) { |
| 1723 #if OS(MACOSX) | 1202 #if OS(MACOSX) |
| 1724 // Filter Mac OS specific phases, usually with a zero-delta. | 1203 // Filter Mac OS specific phases, usually with a zero-delta. |
| 1725 // https://crbug.com/553732 | 1204 // https://crbug.com/553732 |
| 1726 // TODO(chongz): EventSender sends events with |PlatformWheelEventPhaseNone|,
but it shouldn't. | 1205 // TODO(chongz): EventSender sends events with |PlatformWheelEventPhaseNone|,
but it shouldn't. |
| 1727 const int kPlatformWheelEventPhaseNoEventMask = | 1206 const int kPlatformWheelEventPhaseNoEventMask = |
| 1728 PlatformWheelEventPhaseEnded | PlatformWheelEventPhaseCancelled | | 1207 PlatformWheelEventPhaseEnded | PlatformWheelEventPhaseCancelled | |
| 1729 PlatformWheelEventPhaseMayBegin; | 1208 PlatformWheelEventPhaseMayBegin; |
| 1730 if ((event.phase() & kPlatformWheelEventPhaseNoEventMask) || | 1209 if ((event.phase() & kPlatformWheelEventPhaseNoEventMask) || |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent"); | 1305 TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent"); |
| 1827 | 1306 |
| 1828 return m_scrollManager->handleGestureScrollEvent(gestureEvent); | 1307 return m_scrollManager->handleGestureScrollEvent(gestureEvent); |
| 1829 } | 1308 } |
| 1830 | 1309 |
| 1831 WebInputEventResult EventHandler::handleGestureScrollEnd( | 1310 WebInputEventResult EventHandler::handleGestureScrollEnd( |
| 1832 const PlatformGestureEvent& gestureEvent) { | 1311 const PlatformGestureEvent& gestureEvent) { |
| 1833 return m_scrollManager->handleGestureScrollEnd(gestureEvent); | 1312 return m_scrollManager->handleGestureScrollEnd(gestureEvent); |
| 1834 } | 1313 } |
| 1835 | 1314 |
| 1315 void EventHandler::setMouseDownMayStartAutoscroll() { |
| 1316 m_mouseEventManager->setMouseDownMayStartAutoscroll(); |
| 1317 } |
| 1318 |
| 1836 bool EventHandler::isScrollbarHandlingGestures() const { | 1319 bool EventHandler::isScrollbarHandlingGestures() const { |
| 1837 return m_scrollManager->isScrollbarHandlingGestures(); | 1320 return m_scrollManager->isScrollbarHandlingGestures(); |
| 1838 } | 1321 } |
| 1839 | 1322 |
| 1840 bool EventHandler::shouldApplyTouchAdjustment( | 1323 bool EventHandler::shouldApplyTouchAdjustment( |
| 1841 const PlatformGestureEvent& event) const { | 1324 const PlatformGestureEvent& event) const { |
| 1842 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) | 1325 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) |
| 1843 return false; | 1326 return false; |
| 1844 return !event.area().isEmpty(); | 1327 return !event.area().isEmpty(); |
| 1845 } | 1328 } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1997 enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() | 1480 enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() |
| 1998 ? toLocalFrame(parentFrame) | 1481 ? toLocalFrame(parentFrame) |
| 1999 : nullptr; | 1482 : nullptr; |
| 2000 } | 1483 } |
| 2001 | 1484 |
| 2002 size_t indexEnteredFrameChain = enteredFrameChain.size(); | 1485 size_t indexEnteredFrameChain = enteredFrameChain.size(); |
| 2003 LocalFrame* exitedFrameInDocument = m_frame; | 1486 LocalFrame* exitedFrameInDocument = m_frame; |
| 2004 HeapVector<Member<LocalFrame>> exitedFrameChain; | 1487 HeapVector<Member<LocalFrame>> exitedFrameChain; |
| 2005 // Insert the frame from the disagreement between last frames and entered fram
es | 1488 // Insert the frame from the disagreement between last frames and entered fram
es |
| 2006 while (exitedFrameInDocument) { | 1489 while (exitedFrameInDocument) { |
| 2007 Node* lastNodeUnderTap = | 1490 Node* lastNodeUnderTap = exitedFrameInDocument->eventHandler() |
| 2008 exitedFrameInDocument->eventHandler().m_nodeUnderMouse.get(); | 1491 .m_mouseEventManager->getNodeUnderMouse(); |
| 2009 if (!lastNodeUnderTap) | 1492 if (!lastNodeUnderTap) |
| 2010 break; | 1493 break; |
| 2011 | 1494 |
| 2012 LocalFrame* nextExitedFrameInDocument = nullptr; | 1495 LocalFrame* nextExitedFrameInDocument = nullptr; |
| 2013 if (lastNodeUnderTap->isFrameOwnerElement()) { | 1496 if (lastNodeUnderTap->isFrameOwnerElement()) { |
| 2014 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnderTap); | 1497 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnderTap); |
| 2015 if (owner->contentFrame() && owner->contentFrame()->isLocalFrame()) | 1498 if (owner->contentFrame() && owner->contentFrame()->isLocalFrame()) |
| 2016 nextExitedFrameInDocument = toLocalFrame(owner->contentFrame()); | 1499 nextExitedFrameInDocument = toLocalFrame(owner->contentFrame()); |
| 2017 } | 1500 } |
| 2018 | 1501 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2036 gestureEvent.position(), gestureEvent.globalPosition(), | 1519 gestureEvent.position(), gestureEvent.globalPosition(), |
| 2037 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, | 1520 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, |
| 2038 /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers), | 1521 /* clickCount */ 0, static_cast<PlatformEvent::Modifiers>(modifiers), |
| 2039 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), | 1522 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), |
| 2040 WebPointerProperties::PointerType::Mouse); | 1523 WebPointerProperties::PointerType::Mouse); |
| 2041 | 1524 |
| 2042 // Update the mouseout/mouseleave event | 1525 // Update the mouseout/mouseleave event |
| 2043 size_t indexExitedFrameChain = exitedFrameChain.size(); | 1526 size_t indexExitedFrameChain = exitedFrameChain.size(); |
| 2044 while (indexExitedFrameChain) { | 1527 while (indexExitedFrameChain) { |
| 2045 LocalFrame* leaveFrame = exitedFrameChain[--indexExitedFrameChain]; | 1528 LocalFrame* leaveFrame = exitedFrameChain[--indexExitedFrameChain]; |
| 2046 leaveFrame->eventHandler().updateMouseEventTargetNodeAndSendEvents( | 1529 leaveFrame->eventHandler().m_mouseEventManager->setNodeUnderMouse( |
| 2047 nullptr, fakeMouseMove); | 1530 updateMouseEventTargetNode(nullptr), fakeMouseMove); |
| 2048 } | 1531 } |
| 2049 | 1532 |
| 2050 // update the mouseover/mouseenter event | 1533 // update the mouseover/mouseenter event |
| 2051 while (indexEnteredFrameChain) { | 1534 while (indexEnteredFrameChain) { |
| 2052 Frame* parentFrame = | 1535 Frame* parentFrame = |
| 2053 enteredFrameChain[--indexEnteredFrameChain]->tree().parent(); | 1536 enteredFrameChain[--indexEnteredFrameChain]->tree().parent(); |
| 2054 if (parentFrame && parentFrame->isLocalFrame()) | 1537 if (parentFrame && parentFrame->isLocalFrame()) |
| 2055 toLocalFrame(parentFrame) | 1538 toLocalFrame(parentFrame) |
| 2056 ->eventHandler() | 1539 ->eventHandler() |
| 2057 .updateMouseEventTargetNodeAndSendEvents( | 1540 .m_mouseEventManager->setNodeUnderMouse( |
| 2058 toHTMLFrameOwnerElement( | 1541 updateMouseEventTargetNode(toHTMLFrameOwnerElement( |
| 2059 enteredFrameChain[indexEnteredFrameChain]->owner()), | 1542 enteredFrameChain[indexEnteredFrameChain]->owner())), |
| 2060 fakeMouseMove); | 1543 fakeMouseMove); |
| 2061 } | 1544 } |
| 2062 } | 1545 } |
| 2063 | 1546 |
| 2064 GestureEventWithHitTestResults EventHandler::targetGestureEvent( | 1547 GestureEventWithHitTestResults EventHandler::targetGestureEvent( |
| 2065 const PlatformGestureEvent& gestureEvent, | 1548 const PlatformGestureEvent& gestureEvent, |
| 2066 bool readOnly) { | 1549 bool readOnly) { |
| 2067 TRACE_EVENT0("input", "EventHandler::targetGestureEvent"); | 1550 TRACE_EVENT0("input", "EventHandler::targetGestureEvent"); |
| 2068 | 1551 |
| 2069 ASSERT(m_frame == m_frame->localFrameRoot()); | 1552 ASSERT(m_frame == m_frame->localFrameRoot()); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2188 } | 1671 } |
| 2189 | 1672 |
| 2190 WebInputEventResult EventHandler::sendContextMenuEvent( | 1673 WebInputEventResult EventHandler::sendContextMenuEvent( |
| 2191 const PlatformMouseEvent& event, | 1674 const PlatformMouseEvent& event, |
| 2192 Node* overrideTargetNode) { | 1675 Node* overrideTargetNode) { |
| 2193 FrameView* v = m_frame->view(); | 1676 FrameView* v = m_frame->view(); |
| 2194 if (!v) | 1677 if (!v) |
| 2195 return WebInputEventResult::NotHandled; | 1678 return WebInputEventResult::NotHandled; |
| 2196 | 1679 |
| 2197 // Clear mouse press state to avoid initiating a drag while context menu is up
. | 1680 // Clear mouse press state to avoid initiating a drag while context menu is up
. |
| 2198 m_mousePressed = false; | 1681 m_mouseEventManager->setMousePressed(false); |
| 2199 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); | 1682 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); |
| 2200 HitTestRequest request(HitTestRequest::Active); | 1683 HitTestRequest request(HitTestRequest::Active); |
| 2201 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent( | 1684 MouseEventWithHitTestResults mev = |
| 2202 request, positionInContents, event); | 1685 m_frame->document()->performMouseEventHitTest(request, positionInContents, |
| 2203 // Since |Document::prepareMouseEvent()| modifies layout tree for setting | 1686 event); |
| 1687 // Since |Document::performMouseEventHitTest()| modifies layout tree for setti
ng |
| 2204 // hover element, we need to update layout tree for requirement of | 1688 // hover element, we need to update layout tree for requirement of |
| 2205 // |SelectionController::sendContextMenuEvent()|. | 1689 // |SelectionController::sendContextMenuEvent()|. |
| 2206 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1690 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 2207 | 1691 |
| 2208 selectionController().sendContextMenuEvent(mev, positionInContents); | 1692 selectionController().sendContextMenuEvent(mev, positionInContents); |
| 2209 | 1693 |
| 2210 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode(); | 1694 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode(); |
| 2211 return dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event); | 1695 return m_mouseEventManager->dispatchMouseEvent( |
| 1696 updateMouseEventTargetNode(targetNode), EventTypeNames::contextmenu, |
| 1697 event, 0); |
| 2212 } | 1698 } |
| 2213 | 1699 |
| 2214 WebInputEventResult EventHandler::sendContextMenuEventForKey( | 1700 WebInputEventResult EventHandler::sendContextMenuEventForKey( |
| 2215 Element* overrideTargetElement) { | 1701 Element* overrideTargetElement) { |
| 2216 FrameView* view = m_frame->view(); | 1702 FrameView* view = m_frame->view(); |
| 2217 if (!view) | 1703 if (!view) |
| 2218 return WebInputEventResult::NotHandled; | 1704 return WebInputEventResult::NotHandled; |
| 2219 | 1705 |
| 2220 Document* doc = m_frame->document(); | 1706 Document* doc = m_frame->document(); |
| 2221 if (!doc) | 1707 if (!doc) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2308 | 1794 |
| 2309 if (!m_cursorUpdateTimer.isActive()) | 1795 if (!m_cursorUpdateTimer.isActive()) |
| 2310 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, BLINK_FROM_HERE); | 1796 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, BLINK_FROM_HERE); |
| 2311 } | 1797 } |
| 2312 | 1798 |
| 2313 bool EventHandler::cursorUpdatePending() { | 1799 bool EventHandler::cursorUpdatePending() { |
| 2314 return m_cursorUpdateTimer.isActive(); | 1800 return m_cursorUpdateTimer.isActive(); |
| 2315 } | 1801 } |
| 2316 | 1802 |
| 2317 void EventHandler::dispatchFakeMouseMoveEventSoon() { | 1803 void EventHandler::dispatchFakeMouseMoveEventSoon() { |
| 2318 if (m_mousePressed) | 1804 m_mouseEventManager->dispatchFakeMouseMoveEventSoon(); |
| 2319 return; | |
| 2320 | |
| 2321 if (m_mousePositionIsUnknown) | |
| 2322 return; | |
| 2323 | |
| 2324 Settings* settings = m_frame->settings(); | |
| 2325 if (settings && !settings->deviceSupportsMouse()) | |
| 2326 return; | |
| 2327 | |
| 2328 // Reschedule the timer, to prevent dispatching mouse move events | |
| 2329 // during a scroll. This avoids a potential source of scroll jank. | |
| 2330 if (m_fakeMouseMoveEventTimer.isActive()) | |
| 2331 m_fakeMouseMoveEventTimer.stop(); | |
| 2332 m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveInterval, | |
| 2333 BLINK_FROM_HERE); | |
| 2334 } | 1805 } |
| 2335 | 1806 |
| 2336 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad) { | 1807 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad) { |
| 2337 FrameView* view = m_frame->view(); | 1808 m_mouseEventManager->dispatchFakeMouseMoveEventSoonInQuad(quad); |
| 2338 if (!view) | |
| 2339 return; | |
| 2340 | |
| 2341 if (!quad.containsPoint(view->rootFrameToContents(m_lastKnownMousePosition))) | |
| 2342 return; | |
| 2343 | |
| 2344 dispatchFakeMouseMoveEventSoon(); | |
| 2345 } | |
| 2346 | |
| 2347 void EventHandler::fakeMouseMoveEventTimerFired(TimerBase* timer) { | |
| 2348 TRACE_EVENT0("input", "EventHandler::fakeMouseMoveEventTimerFired"); | |
| 2349 ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer); | |
| 2350 ASSERT(!m_mousePressed); | |
| 2351 | |
| 2352 Settings* settings = m_frame->settings(); | |
| 2353 if (settings && !settings->deviceSupportsMouse()) | |
| 2354 return; | |
| 2355 | |
| 2356 FrameView* view = m_frame->view(); | |
| 2357 if (!view) | |
| 2358 return; | |
| 2359 | |
| 2360 if (!m_frame->page() || !m_frame->page()->focusController().isActive()) | |
| 2361 return; | |
| 2362 | |
| 2363 // Don't dispatch a synthetic mouse move event if the mouse cursor is not visi
ble to the user. | |
| 2364 if (!isCursorVisible()) | |
| 2365 return; | |
| 2366 | |
| 2367 PlatformMouseEvent fakeMouseMoveEvent( | |
| 2368 m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, | |
| 2369 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, 0, | |
| 2370 static_cast<PlatformEvent::Modifiers>( | |
| 2371 KeyboardEventManager::getCurrentModifierState()), | |
| 2372 PlatformMouseEvent::RealOrIndistinguishable, | |
| 2373 monotonicallyIncreasingTime(), WebPointerProperties::PointerType::Mouse); | |
| 2374 handleMouseMoveEvent(fakeMouseMoveEvent); | |
| 2375 } | |
| 2376 | |
| 2377 void EventHandler::cancelFakeMouseMoveEvent() { | |
| 2378 m_fakeMouseMoveEventTimer.stop(); | |
| 2379 } | |
| 2380 | |
| 2381 bool EventHandler::isCursorVisible() const { | |
| 2382 return m_frame->page()->isCursorVisible(); | |
| 2383 } | 1809 } |
| 2384 | 1810 |
| 2385 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet) { | 1811 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet) { |
| 2386 m_frameSetBeingResized = frameSet; | 1812 m_frameSetBeingResized = frameSet; |
| 2387 } | 1813 } |
| 2388 | 1814 |
| 2389 void EventHandler::resizeScrollableAreaDestroyed() { | 1815 void EventHandler::resizeScrollableAreaDestroyed() { |
| 2390 m_scrollManager->clearResizeScrollableArea(true); | 1816 m_scrollManager->clearResizeScrollableArea(true); |
| 2391 } | 1817 } |
| 2392 | 1818 |
| 2393 void EventHandler::hoverTimerFired(TimerBase*) { | 1819 void EventHandler::hoverTimerFired(TimerBase*) { |
| 2394 TRACE_EVENT0("input", "EventHandler::hoverTimerFired"); | 1820 TRACE_EVENT0("input", "EventHandler::hoverTimerFired"); |
| 2395 m_hoverTimer.stop(); | 1821 m_hoverTimer.stop(); |
| 2396 | 1822 |
| 2397 ASSERT(m_frame); | 1823 ASSERT(m_frame); |
| 2398 ASSERT(m_frame->document()); | 1824 ASSERT(m_frame->document()); |
| 2399 | 1825 |
| 2400 if (LayoutViewItem layoutItem = m_frame->contentLayoutItem()) { | 1826 if (LayoutViewItem layoutItem = m_frame->contentLayoutItem()) { |
| 2401 if (FrameView* view = m_frame->view()) { | 1827 if (FrameView* view = m_frame->view()) { |
| 2402 HitTestRequest request(HitTestRequest::Move); | 1828 HitTestRequest request(HitTestRequest::Move); |
| 2403 HitTestResult result(request, | 1829 HitTestResult result(request, |
| 2404 view->rootFrameToContents(m_lastKnownMousePosition)); | 1830 view->rootFrameToContents( |
| 1831 m_mouseEventManager->lastKnownMousePosition())); |
| 2405 layoutItem.hitTest(result); | 1832 layoutItem.hitTest(result); |
| 2406 m_frame->document()->updateHoverActiveState(request, | 1833 m_frame->document()->updateHoverActiveState(request, |
| 2407 result.innerElement()); | 1834 result.innerElement()); |
| 2408 } | 1835 } |
| 2409 } | 1836 } |
| 2410 } | 1837 } |
| 2411 | 1838 |
| 2412 void EventHandler::activeIntervalTimerFired(TimerBase*) { | 1839 void EventHandler::activeIntervalTimerFired(TimerBase*) { |
| 2413 TRACE_EVENT0("input", "EventHandler::activeIntervalTimerFired"); | 1840 TRACE_EVENT0("input", "EventHandler::activeIntervalTimerFired"); |
| 2414 m_activeIntervalTimer.stop(); | 1841 m_activeIntervalTimer.stop(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2434 bool EventHandler::handleAccessKey(const WebKeyboardEvent& evt) { | 1861 bool EventHandler::handleAccessKey(const WebKeyboardEvent& evt) { |
| 2435 return m_keyboardEventManager->handleAccessKey(evt); | 1862 return m_keyboardEventManager->handleAccessKey(evt); |
| 2436 } | 1863 } |
| 2437 | 1864 |
| 2438 WebInputEventResult EventHandler::keyEvent( | 1865 WebInputEventResult EventHandler::keyEvent( |
| 2439 const WebKeyboardEvent& initialKeyEvent) { | 1866 const WebKeyboardEvent& initialKeyEvent) { |
| 2440 return m_keyboardEventManager->keyEvent(initialKeyEvent); | 1867 return m_keyboardEventManager->keyEvent(initialKeyEvent); |
| 2441 } | 1868 } |
| 2442 | 1869 |
| 2443 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) { | 1870 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) { |
| 2444 m_keyboardEventManager->defaultKeyboardEventHandler(event, m_mousePressNode); | 1871 m_keyboardEventManager->defaultKeyboardEventHandler( |
| 2445 } | 1872 event, m_mouseEventManager->mousePressNode()); |
| 2446 | |
| 2447 bool EventHandler::dragHysteresisExceeded( | |
| 2448 const IntPoint& dragLocationInRootFrame) const { | |
| 2449 FrameView* view = m_frame->view(); | |
| 2450 if (!view) | |
| 2451 return false; | |
| 2452 IntPoint dragLocation = view->rootFrameToContents(dragLocationInRootFrame); | |
| 2453 IntSize delta = dragLocation - m_mouseDownPos; | |
| 2454 | |
| 2455 int threshold = GeneralDragHysteresis; | |
| 2456 switch (dragState().m_dragType) { | |
| 2457 case DragSourceActionSelection: | |
| 2458 threshold = TextDragHysteresis; | |
| 2459 break; | |
| 2460 case DragSourceActionImage: | |
| 2461 threshold = ImageDragHysteresis; | |
| 2462 break; | |
| 2463 case DragSourceActionLink: | |
| 2464 threshold = LinkDragHysteresis; | |
| 2465 break; | |
| 2466 case DragSourceActionDHTML: | |
| 2467 break; | |
| 2468 case DragSourceActionNone: | |
| 2469 ASSERT_NOT_REACHED(); | |
| 2470 } | |
| 2471 | |
| 2472 return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold; | |
| 2473 } | |
| 2474 | |
| 2475 void EventHandler::clearDragDataTransfer() { | |
| 2476 if (dragState().m_dragDataTransfer) { | |
| 2477 dragState().m_dragDataTransfer->clearDragImage(); | |
| 2478 dragState().m_dragDataTransfer->setAccessPolicy(DataTransferNumb); | |
| 2479 } | |
| 2480 } | 1873 } |
| 2481 | 1874 |
| 2482 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, | 1875 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, |
| 2483 DragOperation operation) { | 1876 DragOperation operation) { |
| 2484 // Send a hit test request so that Layer gets a chance to update the :hover an
d :active pseudoclasses. | 1877 m_mouseEventManager->dragSourceEndedAt(event, operation); |
| 2485 HitTestRequest request(HitTestRequest::Release); | |
| 2486 prepareMouseEvent(request, event); | |
| 2487 | |
| 2488 if (dragState().m_dragSrc) { | |
| 2489 dragState().m_dragDataTransfer->setDestinationOperation(operation); | |
| 2490 // for now we don't care if event handler cancels default behavior, since th
ere is none | |
| 2491 dispatchDragSrcEvent(EventTypeNames::dragend, event); | |
| 2492 } | |
| 2493 clearDragDataTransfer(); | |
| 2494 dragState().m_dragSrc = nullptr; | |
| 2495 // In case the drag was ended due to an escape key press we need to ensure | |
| 2496 // that consecutive mousemove events don't reinitiate the drag and drop. | |
| 2497 m_mouseDownMayStartDrag = false; | |
| 2498 } | 1878 } |
| 2499 | 1879 |
| 2500 void EventHandler::updateDragStateAfterEditDragIfNeeded( | 1880 void EventHandler::updateDragStateAfterEditDragIfNeeded( |
| 2501 Element* rootEditableElement) { | 1881 Element* rootEditableElement) { |
| 2502 // If inserting the dragged contents removed the drag source, we still want to
fire dragend at the root editble element. | 1882 // If inserting the dragged contents removed the drag source, we still want to
fire dragend at the root editble element. |
| 2503 if (dragState().m_dragSrc && !dragState().m_dragSrc->isConnected()) | 1883 if (m_mouseEventManager->dragState().m_dragSrc && |
| 2504 dragState().m_dragSrc = rootEditableElement; | 1884 !m_mouseEventManager->dragState().m_dragSrc->isConnected()) |
| 2505 } | 1885 m_mouseEventManager->dragState().m_dragSrc = rootEditableElement; |
| 2506 | |
| 2507 // returns if we should continue "default processing", i.e., whether eventhandle
r canceled | |
| 2508 WebInputEventResult EventHandler::dispatchDragSrcEvent( | |
| 2509 const AtomicString& eventType, | |
| 2510 const PlatformMouseEvent& event) { | |
| 2511 return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, | |
| 2512 dragState().m_dragDataTransfer.get()); | |
| 2513 } | |
| 2514 | |
| 2515 bool EventHandler::handleDragDropIfPossible( | |
| 2516 const GestureEventWithHitTestResults& targetedEvent) { | |
| 2517 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && | |
| 2518 m_frame->view()) { | |
| 2519 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
| 2520 IntPoint adjustedPoint = gestureEvent.position(); | |
| 2521 unsigned modifiers = gestureEvent.getModifiers(); | |
| 2522 | |
| 2523 // TODO(mustaq): Suppressing long-tap MouseEvents could break | |
| 2524 // drag-drop. Will do separately because of the risk. crbug.com/606938. | |
| 2525 PlatformMouseEvent mouseDownEvent( | |
| 2526 adjustedPoint, gestureEvent.globalPosition(), | |
| 2527 WebPointerProperties::Button::Left, PlatformEvent::MousePressed, 1, | |
| 2528 static_cast<PlatformEvent::Modifiers>(modifiers | | |
| 2529 PlatformEvent::LeftButtonDown), | |
| 2530 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), | |
| 2531 WebPointerProperties::PointerType::Mouse); | |
| 2532 m_mouseDown = mouseDownEvent; | |
| 2533 | |
| 2534 PlatformMouseEvent mouseDragEvent( | |
| 2535 adjustedPoint, gestureEvent.globalPosition(), | |
| 2536 WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 1, | |
| 2537 static_cast<PlatformEvent::Modifiers>(modifiers | | |
| 2538 PlatformEvent::LeftButtonDown), | |
| 2539 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), | |
| 2540 WebPointerProperties::PointerType::Mouse); | |
| 2541 HitTestRequest request(HitTestRequest::ReadOnly); | |
| 2542 MouseEventWithHitTestResults mev = | |
| 2543 prepareMouseEvent(request, mouseDragEvent); | |
| 2544 m_mouseDownMayStartDrag = true; | |
| 2545 dragState().m_dragSrc = nullptr; | |
| 2546 m_mouseDownPos = | |
| 2547 m_frame->view()->rootFrameToContents(mouseDragEvent.position()); | |
| 2548 return handleDrag(mev, DragInitiator::Touch); | |
| 2549 } | |
| 2550 return false; | |
| 2551 } | |
| 2552 | |
| 2553 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, | |
| 2554 DragInitiator initiator) { | |
| 2555 ASSERT(event.event().type() == PlatformEvent::MouseMoved); | |
| 2556 // Callers must protect the reference to FrameView, since this function may di
spatch DOM | |
| 2557 // events, causing page/FrameView to go away. | |
| 2558 ASSERT(m_frame); | |
| 2559 ASSERT(m_frame->view()); | |
| 2560 if (!m_frame->page()) | |
| 2561 return false; | |
| 2562 | |
| 2563 if (m_mouseDownMayStartDrag) { | |
| 2564 HitTestRequest request(HitTestRequest::ReadOnly); | |
| 2565 HitTestResult result(request, m_mouseDownPos); | |
| 2566 m_frame->contentLayoutItem().hitTest(result); | |
| 2567 Node* node = result.innerNode(); | |
| 2568 if (node) { | |
| 2569 DragController::SelectionDragPolicy selectionDragPolicy = | |
| 2570 event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay | |
| 2571 ? DragController::DelayedSelectionDragResolution | |
| 2572 : DragController::ImmediateSelectionDragResolution; | |
| 2573 dragState().m_dragSrc = m_frame->page()->dragController().draggableNode( | |
| 2574 m_frame, node, m_mouseDownPos, selectionDragPolicy, | |
| 2575 dragState().m_dragType); | |
| 2576 } else { | |
| 2577 dragState().m_dragSrc = nullptr; | |
| 2578 } | |
| 2579 | |
| 2580 if (!dragState().m_dragSrc) | |
| 2581 m_mouseDownMayStartDrag = false; // no element is draggable | |
| 2582 } | |
| 2583 | |
| 2584 if (!m_mouseDownMayStartDrag) | |
| 2585 return initiator == DragInitiator::Mouse && | |
| 2586 !selectionController().mouseDownMayStartSelect() && | |
| 2587 !m_mouseDownMayStartAutoscroll; | |
| 2588 | |
| 2589 // We are starting a text/image/url drag, so the cursor should be an arrow | |
| 2590 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and dro
p (default to pointer). | |
| 2591 m_frame->view()->setCursor(pointerCursor()); | |
| 2592 | |
| 2593 if (initiator == DragInitiator::Mouse && | |
| 2594 !dragHysteresisExceeded(event.event().position())) | |
| 2595 return true; | |
| 2596 | |
| 2597 // Once we're past the hysteresis point, we don't want to treat this gesture a
s a click | |
| 2598 invalidateClick(); | |
| 2599 | |
| 2600 if (!tryStartDrag(event)) { | |
| 2601 // Something failed to start the drag, clean up. | |
| 2602 clearDragDataTransfer(); | |
| 2603 dragState().m_dragSrc = nullptr; | |
| 2604 } | |
| 2605 | |
| 2606 m_mouseDownMayStartDrag = false; | |
| 2607 // Whether or not the drag actually started, no more default handling (like se
lection). | |
| 2608 return true; | |
| 2609 } | |
| 2610 | |
| 2611 bool EventHandler::tryStartDrag(const MouseEventWithHitTestResults& event) { | |
| 2612 // The DataTransfer would only be non-empty if we missed a dragEnd. | |
| 2613 // Clear it anyway, just to make sure it gets numbified. | |
| 2614 clearDragDataTransfer(); | |
| 2615 | |
| 2616 dragState().m_dragDataTransfer = createDraggingDataTransfer(); | |
| 2617 | |
| 2618 // Check to see if this a DOM based drag, if it is get the DOM specified drag | |
| 2619 // image and offset | |
| 2620 if (dragState().m_dragType == DragSourceActionDHTML) { | |
| 2621 if (LayoutObject* layoutObject = dragState().m_dragSrc->layoutObject()) { | |
| 2622 IntRect boundingIncludingDescendants = | |
| 2623 layoutObject->absoluteBoundingBoxRectIncludingDescendants(); | |
| 2624 IntSize delta = m_mouseDownPos - boundingIncludingDescendants.location(); | |
| 2625 dragState().m_dragDataTransfer->setDragImageElement( | |
| 2626 dragState().m_dragSrc.get(), IntPoint(delta)); | |
| 2627 } else { | |
| 2628 // The layoutObject has disappeared, this can happen if the onStartDrag ha
ndler has hidden | |
| 2629 // the element in some way. In this case we just kill the drag. | |
| 2630 return false; | |
| 2631 } | |
| 2632 } | |
| 2633 | |
| 2634 DragController& dragController = m_frame->page()->dragController(); | |
| 2635 if (!dragController.populateDragDataTransfer(m_frame, dragState(), | |
| 2636 m_mouseDownPos)) | |
| 2637 return false; | |
| 2638 | |
| 2639 // If dispatching dragstart brings about another mouse down -- one way | |
| 2640 // this will happen is if a DevTools user breaks within a dragstart | |
| 2641 // handler and then clicks on the suspended page -- the drag state is | |
| 2642 // reset. Hence, need to check if this particular drag operation can | |
| 2643 // continue even if dispatchEvent() indicates no (direct) cancellation. | |
| 2644 // Do that by checking if m_dragSrc is still set. | |
| 2645 m_mouseDownMayStartDrag = | |
| 2646 dispatchDragSrcEvent(EventTypeNames::dragstart, m_mouseDown) == | |
| 2647 WebInputEventResult::NotHandled && | |
| 2648 !m_frame->selection().isInPasswordField() && dragState().m_dragSrc; | |
| 2649 | |
| 2650 // Invalidate clipboard here against anymore pasteboard writing for security.
The drag | |
| 2651 // image can still be changed as we drag, but not the pasteboard data. | |
| 2652 dragState().m_dragDataTransfer->setAccessPolicy(DataTransferImageWritable); | |
| 2653 | |
| 2654 if (m_mouseDownMayStartDrag) { | |
| 2655 // Dispatching the event could cause Page to go away. Make sure it's still v
alid before trying to use DragController. | |
| 2656 if (m_frame->page() && | |
| 2657 dragController.startDrag(m_frame, dragState(), event.event(), | |
| 2658 m_mouseDownPos)) | |
| 2659 return true; | |
| 2660 // Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event | |
| 2661 dispatchDragSrcEvent(EventTypeNames::dragend, event.event()); | |
| 2662 } | |
| 2663 | |
| 2664 return false; | |
| 2665 } | 1886 } |
| 2666 | 1887 |
| 2667 bool EventHandler::handleTextInputEvent(const String& text, | 1888 bool EventHandler::handleTextInputEvent(const String& text, |
| 2668 Event* underlyingEvent, | 1889 Event* underlyingEvent, |
| 2669 TextEventInputType inputType) { | 1890 TextEventInputType inputType) { |
| 2670 // Platforms should differentiate real commands like selectAll from text input
in disguise (like insertNewline), | 1891 // Platforms should differentiate real commands like selectAll from text input
in disguise (like insertNewline), |
| 2671 // and avoid dispatching text input events from keydown default handlers. | 1892 // and avoid dispatching text input events from keydown default handlers. |
| 2672 ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || | 1893 ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || |
| 2673 toKeyboardEvent(underlyingEvent)->type() == EventTypeNames::keypress); | 1894 toKeyboardEvent(underlyingEvent)->type() == EventTypeNames::keypress); |
| 2674 | 1895 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2727 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; | 1948 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; |
| 2728 } | 1949 } |
| 2729 } | 1950 } |
| 2730 | 1951 |
| 2731 WebInputEventResult EventHandler::handleTouchEvent( | 1952 WebInputEventResult EventHandler::handleTouchEvent( |
| 2732 const PlatformTouchEvent& event) { | 1953 const PlatformTouchEvent& event) { |
| 2733 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); | 1954 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); |
| 2734 return m_pointerEventManager->handleTouchEvents(event); | 1955 return m_pointerEventManager->handleTouchEvents(event); |
| 2735 } | 1956 } |
| 2736 | 1957 |
| 2737 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) { | |
| 2738 m_mousePositionIsUnknown = false; | |
| 2739 m_lastKnownMousePosition = event.position(); | |
| 2740 m_lastKnownMouseGlobalPosition = event.globalPosition(); | |
| 2741 } | |
| 2742 | |
| 2743 WebInputEventResult EventHandler::passMousePressEventToSubframe( | 1958 WebInputEventResult EventHandler::passMousePressEventToSubframe( |
| 2744 MouseEventWithHitTestResults& mev, | 1959 MouseEventWithHitTestResults& mev, |
| 2745 LocalFrame* subframe) { | 1960 LocalFrame* subframe) { |
| 2746 selectionController().passMousePressEventToSubframe(mev); | 1961 selectionController().passMousePressEventToSubframe(mev); |
| 2747 WebInputEventResult result = | 1962 WebInputEventResult result = |
| 2748 subframe->eventHandler().handleMousePressEvent(mev.event()); | 1963 subframe->eventHandler().handleMousePressEvent(mev.event()); |
| 2749 if (result != WebInputEventResult::NotHandled) | 1964 if (result != WebInputEventResult::NotHandled) |
| 2750 return result; | 1965 return result; |
| 2751 return WebInputEventResult::HandledSystem; | 1966 return WebInputEventResult::HandledSystem; |
| 2752 } | 1967 } |
| 2753 | 1968 |
| 2754 WebInputEventResult EventHandler::passMouseMoveEventToSubframe( | 1969 WebInputEventResult EventHandler::passMouseMoveEventToSubframe( |
| 2755 MouseEventWithHitTestResults& mev, | 1970 MouseEventWithHitTestResults& mev, |
| 2756 LocalFrame* subframe, | 1971 LocalFrame* subframe, |
| 2757 HitTestResult* hoveredNode) { | 1972 HitTestResult* hoveredNode) { |
| 2758 if (m_mouseDownMayStartDrag) | 1973 if (m_mouseEventManager->mouseDownMayStartDrag()) |
| 2759 return WebInputEventResult::NotHandled; | 1974 return WebInputEventResult::NotHandled; |
| 2760 WebInputEventResult result = | 1975 WebInputEventResult result = |
| 2761 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), | 1976 subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), |
| 2762 hoveredNode); | 1977 hoveredNode); |
| 2763 if (result != WebInputEventResult::NotHandled) | 1978 if (result != WebInputEventResult::NotHandled) |
| 2764 return result; | 1979 return result; |
| 2765 return WebInputEventResult::HandledSystem; | 1980 return WebInputEventResult::HandledSystem; |
| 2766 } | 1981 } |
| 2767 | 1982 |
| 2768 WebInputEventResult EventHandler::passMouseReleaseEventToSubframe( | 1983 WebInputEventResult EventHandler::passMouseReleaseEventToSubframe( |
| 2769 MouseEventWithHitTestResults& mev, | 1984 MouseEventWithHitTestResults& mev, |
| 2770 LocalFrame* subframe) { | 1985 LocalFrame* subframe) { |
| 2771 WebInputEventResult result = | 1986 WebInputEventResult result = |
| 2772 subframe->eventHandler().handleMouseReleaseEvent(mev.event()); | 1987 subframe->eventHandler().handleMouseReleaseEvent(mev.event()); |
| 2773 if (result != WebInputEventResult::NotHandled) | 1988 if (result != WebInputEventResult::NotHandled) |
| 2774 return result; | 1989 return result; |
| 2775 return WebInputEventResult::HandledSystem; | 1990 return WebInputEventResult::HandledSystem; |
| 2776 } | 1991 } |
| 2777 | 1992 |
| 2778 DataTransfer* EventHandler::createDraggingDataTransfer() const { | |
| 2779 return DataTransfer::create(DataTransfer::DragAndDrop, DataTransferWritable, | |
| 2780 DataObject::create()); | |
| 2781 } | |
| 2782 | |
| 2783 void EventHandler::focusDocumentView() { | |
| 2784 Page* page = m_frame->page(); | |
| 2785 if (!page) | |
| 2786 return; | |
| 2787 page->focusController().focusDocumentView(m_frame); | |
| 2788 } | |
| 2789 | 1993 |
| 2790 FrameHost* EventHandler::frameHost() const { | 1994 FrameHost* EventHandler::frameHost() const { |
| 2791 if (!m_frame->page()) | 1995 if (!m_frame->page()) |
| 2792 return nullptr; | 1996 return nullptr; |
| 2793 | 1997 |
| 2794 return &m_frame->page()->frameHost(); | 1998 return &m_frame->page()->frameHost(); |
| 2795 } | 1999 } |
| 2796 | 2000 |
| 2797 } // namespace blink | 2001 } // namespace blink |
| OLD | NEW |