Chromium Code Reviews| 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" | |
| 88 #include "core/style/ComputedStyle.h" | 84 #include "core/style/ComputedStyle.h" |
| 89 #include "core/style/CursorData.h" | 85 #include "core/style/CursorData.h" |
| 90 #include "core/svg/SVGDocumentExtensions.h" | 86 #include "core/svg/SVGDocumentExtensions.h" |
| 91 #include "platform/PlatformGestureEvent.h" | 87 #include "platform/PlatformGestureEvent.h" |
| 92 #include "platform/PlatformTouchEvent.h" | 88 #include "platform/PlatformTouchEvent.h" |
| 93 #include "platform/PlatformWheelEvent.h" | 89 #include "platform/PlatformWheelEvent.h" |
| 94 #include "platform/RuntimeEnabledFeatures.h" | 90 #include "platform/RuntimeEnabledFeatures.h" |
| 95 #include "platform/TraceEvent.h" | 91 #include "platform/TraceEvent.h" |
| 96 #include "platform/WindowsKeyboardCodes.h" | 92 #include "platform/WindowsKeyboardCodes.h" |
| 97 #include "platform/geometry/FloatPoint.h" | 93 #include "platform/geometry/FloatPoint.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 119 Node* targetNode = mev.innerNode(); | 115 Node* targetNode = mev.innerNode(); |
| 120 if (!targetNode || !targetNode->parentNode()) | 116 if (!targetNode || !targetNode->parentNode()) |
| 121 return true; | 117 return true; |
| 122 return targetNode->isShadowRoot() && isHTMLInputElement(toShadowRoot(targetN ode)->host()); | 118 return targetNode->isShadowRoot() && isHTMLInputElement(toShadowRoot(targetN ode)->host()); |
| 123 } | 119 } |
| 124 | 120 |
| 125 } // namespace | 121 } // namespace |
| 126 | 122 |
| 127 using namespace HTMLNames; | 123 using namespace HTMLNames; |
| 128 | 124 |
| 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 | 125 // 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 | 126 // Set to 50Hz, no need to be faster than common screen refresh rate |
| 143 static const double cursorUpdateInterval = 0.02; | 127 static const double cursorUpdateInterval = 0.02; |
| 144 | 128 |
| 145 static const int maximumCursorSize = 128; | 129 static const int maximumCursorSize = 128; |
| 146 | 130 |
| 147 // It's pretty unlikely that a scale of less than one would ever be used. But al l we really | 131 // 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 | 132 // 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. | 133 // dividing cursor sizes (limited above) by the scale. |
| 150 static const double minimumCursorScale = 0.001; | 134 static const double minimumCursorScale = 0.001; |
| 151 | 135 |
| 152 // The minimum amount of time an element stays active after a ShowPress | 136 // 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. | 137 // This is roughly 9 frames, which should be long enough to be noticeable. |
| 154 static const double minimumActiveInterval = 0.15; | 138 static const double minimumActiveInterval = 0.15; |
| 155 | 139 |
| 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 }; | 140 enum NoCursorChangeType { NoCursorChange }; |
| 163 | 141 |
| 164 enum class DragInitiator { Mouse, Touch }; | |
| 165 | |
| 166 class OptionalCursor { | 142 class OptionalCursor { |
| 167 public: | 143 public: |
| 168 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { } | 144 OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { } |
| 169 OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(curs or) { } | 145 OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(curs or) { } |
| 170 | 146 |
| 171 bool isCursorChange() const { return m_isCursorChange; } | 147 bool isCursorChange() const { return m_isCursorChange; } |
| 172 const Cursor& cursor() const { ASSERT(m_isCursorChange); return m_cursor; } | 148 const Cursor& cursor() const { ASSERT(m_isCursorChange); return m_cursor; } |
| 173 | 149 |
| 174 private: | 150 private: |
| 175 bool m_isCursorChange; | 151 bool m_isCursorChange; |
| 176 Cursor m_cursor; | 152 Cursor m_cursor; |
| 177 }; | 153 }; |
| 178 | 154 |
| 179 EventHandler::EventHandler(LocalFrame* frame) | 155 EventHandler::EventHandler(LocalFrame* frame) |
| 180 : m_frame(frame) | 156 : m_frame(frame) |
| 181 , m_mousePressed(false) | |
| 182 , m_capturesDragging(false) | |
| 183 , m_mouseDownMayStartDrag(false) | |
| 184 , m_selectionController(SelectionController::create(*frame)) | 157 , m_selectionController(SelectionController::create(*frame)) |
| 185 , m_hoverTimer(this, &EventHandler::hoverTimerFired) | 158 , m_hoverTimer(this, &EventHandler::hoverTimerFired) |
| 186 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) | 159 , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired) |
| 187 , m_mouseDownMayStartAutoscroll(false) | |
| 188 , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFire d) | |
| 189 , m_svgPan(false) | |
| 190 , m_eventHandlerWillResetCapturingMouseEventsNode(0) | 160 , m_eventHandlerWillResetCapturingMouseEventsNode(0) |
| 191 , m_clickCount(0) | |
| 192 , m_shouldOnlyFireDragOverEvent(false) | 161 , m_shouldOnlyFireDragOverEvent(false) |
| 193 , m_mousePositionIsUnknown(true) | |
| 194 , m_mouseDownTimestamp(0) | |
| 195 , m_scrollManager(new ScrollManager(frame)) | 162 , m_scrollManager(new ScrollManager(frame)) |
| 196 , m_mouseEventManager(new MouseEventManager(frame)) | 163 , m_mouseEventManager(new MouseEventManager(frame, m_scrollManager)) |
| 197 , m_keyboardEventManager(new KeyboardEventManager(frame, m_scrollManager)) | 164 , m_keyboardEventManager(new KeyboardEventManager(frame, m_scrollManager)) |
| 198 , m_pointerEventManager(new PointerEventManager(frame, m_mouseEventManager)) | 165 , m_pointerEventManager(new PointerEventManager(frame, m_mouseEventManager)) |
| 199 , m_gestureManager(new GestureManager(frame, m_scrollManager, m_pointerEvent Manager, m_selectionController)) | 166 , m_gestureManager(new GestureManager(frame, m_scrollManager, m_mouseEventMa nager, m_pointerEventManager, m_selectionController)) |
| 200 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) | 167 , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired) |
| 201 { | 168 { |
| 202 } | 169 } |
| 203 | 170 |
| 204 EventHandler::~EventHandler() | |
| 205 { | |
| 206 ASSERT(!m_fakeMouseMoveEventTimer.isActive()); | |
| 207 } | |
| 208 | |
| 209 DEFINE_TRACE(EventHandler) | 171 DEFINE_TRACE(EventHandler) |
| 210 { | 172 { |
| 211 visitor->trace(m_frame); | 173 visitor->trace(m_frame); |
| 212 visitor->trace(m_mousePressNode); | |
| 213 visitor->trace(m_selectionController); | 174 visitor->trace(m_selectionController); |
| 214 visitor->trace(m_capturingMouseEventsNode); | 175 visitor->trace(m_capturingMouseEventsNode); |
| 215 visitor->trace(m_nodeUnderMouse); | |
| 216 visitor->trace(m_lastMouseMoveEventSubframe); | 176 visitor->trace(m_lastMouseMoveEventSubframe); |
| 217 visitor->trace(m_lastScrollbarUnderMouse); | 177 visitor->trace(m_lastScrollbarUnderMouse); |
| 218 visitor->trace(m_clickNode); | |
| 219 visitor->trace(m_dragTarget); | 178 visitor->trace(m_dragTarget); |
| 220 visitor->trace(m_frameSetBeingResized); | 179 visitor->trace(m_frameSetBeingResized); |
| 221 visitor->trace(m_scrollManager); | 180 visitor->trace(m_scrollManager); |
| 222 visitor->trace(m_mouseEventManager); | 181 visitor->trace(m_mouseEventManager); |
| 223 visitor->trace(m_keyboardEventManager); | 182 visitor->trace(m_keyboardEventManager); |
| 224 visitor->trace(m_pointerEventManager); | 183 visitor->trace(m_pointerEventManager); |
| 225 visitor->trace(m_gestureManager); | 184 visitor->trace(m_gestureManager); |
| 226 visitor->trace(m_lastDeferredTapElement); | 185 visitor->trace(m_lastDeferredTapElement); |
| 227 } | 186 } |
| 228 | 187 |
| 229 DragState& EventHandler::dragState() | |
| 230 { | |
| 231 DEFINE_STATIC_LOCAL(DragState, state, (new DragState)); | |
| 232 return state; | |
| 233 } | |
| 234 | |
| 235 void EventHandler::clear() | 188 void EventHandler::clear() |
| 236 { | 189 { |
| 237 m_hoverTimer.stop(); | 190 m_hoverTimer.stop(); |
| 238 m_cursorUpdateTimer.stop(); | 191 m_cursorUpdateTimer.stop(); |
| 239 m_fakeMouseMoveEventTimer.stop(); | |
| 240 m_activeIntervalTimer.stop(); | 192 m_activeIntervalTimer.stop(); |
| 241 m_nodeUnderMouse = nullptr; | |
| 242 m_lastMouseMoveEventSubframe = nullptr; | 193 m_lastMouseMoveEventSubframe = nullptr; |
| 243 m_lastScrollbarUnderMouse = nullptr; | 194 m_lastScrollbarUnderMouse = nullptr; |
| 244 m_clickCount = 0; | |
| 245 m_clickNode = nullptr; | |
| 246 m_frameSetBeingResized = nullptr; | 195 m_frameSetBeingResized = nullptr; |
| 247 m_dragTarget = nullptr; | 196 m_dragTarget = nullptr; |
| 248 m_shouldOnlyFireDragOverEvent = false; | 197 m_shouldOnlyFireDragOverEvent = false; |
| 249 m_mousePositionIsUnknown = true; | |
| 250 m_lastKnownMousePosition = IntPoint(); | |
| 251 m_lastKnownMouseGlobalPosition = IntPoint(); | |
| 252 m_lastMouseDownUserGestureToken.clear(); | 198 m_lastMouseDownUserGestureToken.clear(); |
| 253 m_mousePressNode = nullptr; | |
| 254 m_mousePressed = false; | |
| 255 m_capturesDragging = false; | |
| 256 m_capturingMouseEventsNode = nullptr; | 199 m_capturingMouseEventsNode = nullptr; |
| 257 m_pointerEventManager->clear(); | 200 m_pointerEventManager->clear(); |
| 258 m_scrollManager->clear(); | 201 m_scrollManager->clear(); |
| 259 m_gestureManager->clear(); | 202 m_gestureManager->clear(); |
| 260 m_mouseEventManager->clear(); | 203 m_mouseEventManager->clear(); |
| 261 m_mouseDownMayStartDrag = false; | |
| 262 m_lastDeferredTapElement = nullptr; | 204 m_lastDeferredTapElement = nullptr; |
| 263 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 205 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
| 264 m_mouseDownMayStartAutoscroll = false; | |
| 265 m_svgPan = false; | |
| 266 m_mouseDownPos = IntPoint(); | |
| 267 m_mouseDownTimestamp = 0; | |
| 268 m_dragStartPos = LayoutPoint(); | |
| 269 m_mouseDown = PlatformMouseEvent(); | |
| 270 } | 206 } |
| 271 | 207 |
| 272 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) | 208 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved) |
| 273 { | 209 { |
| 274 if (nodeToBeRemoved.isShadowIncludingInclusiveAncestorOf(m_clickNode.get())) { | 210 m_mouseEventManager->nodeWillBeRemoved(nodeToBeRemoved); |
| 275 // We don't dispatch click events if the mousedown node is removed | |
| 276 // before a mouseup event. It is compatible with IE and Firefox. | |
| 277 m_clickNode = nullptr; | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 WebInputEventResult EventHandler::handleMousePressEvent(const MouseEventWithHitT estResults& event) | |
| 282 { | |
| 283 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); | |
| 284 | |
| 285 // Reset drag state. | |
| 286 dragState().m_dragSrc = nullptr; | |
| 287 | |
| 288 cancelFakeMouseMoveEvent(); | |
| 289 | |
| 290 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 291 | |
| 292 if (FrameView* frameView = m_frame->view()) { | |
| 293 if (frameView->isPointInScrollbarCorner(event.event().position())) | |
| 294 return WebInputEventResult::NotHandled; | |
| 295 } | |
| 296 | |
| 297 bool singleClick = event.event().clickCount() <= 1; | |
| 298 | |
| 299 m_mouseDownMayStartDrag = singleClick && !isLinkSelection(event) && !isExten dingSelection(event); | |
| 300 | |
| 301 selectionController().handleMousePressEvent(event); | |
| 302 | |
| 303 m_mouseDown = event.event(); | |
| 304 | |
| 305 if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGEx tensions().zoomAndPanEnabled()) { | |
| 306 if (event.event().shiftKey() && singleClick) { | |
| 307 m_svgPan = true; | |
| 308 m_frame->document()->accessSVGExtensions().startPan(m_frame->view()- >rootFrameToContents(event.event().position())); | |
| 309 return WebInputEventResult::HandledSystem; | |
| 310 } | |
| 311 } | |
| 312 | |
| 313 // We don't do this at the start of mouse down handling, | |
| 314 // because we don't want to do it until we know we didn't hit a widget. | |
| 315 if (singleClick) | |
| 316 focusDocumentView(); | |
| 317 | |
| 318 Node* innerNode = event.innerNode(); | |
| 319 | |
| 320 m_mousePressNode = innerNode; | |
| 321 m_frame->document()->setSequentialFocusNavigationStartingPoint(innerNode); | |
| 322 m_dragStartPos = event.event().position(); | |
| 323 | |
| 324 bool swallowEvent = false; | |
| 325 m_mousePressed = true; | |
| 326 | |
| 327 if (event.event().clickCount() == 2) | |
| 328 swallowEvent = selectionController().handleMousePressEventDoubleClick(ev ent); | |
| 329 else if (event.event().clickCount() >= 3) | |
| 330 swallowEvent = selectionController().handleMousePressEventTripleClick(ev ent); | |
| 331 else | |
| 332 swallowEvent = selectionController().handleMousePressEventSingleClick(ev ent); | |
| 333 | |
| 334 m_mouseDownMayStartAutoscroll = selectionController().mouseDownMayStartSelec t() | |
| 335 || (m_mousePressNode && m_mousePressNode->layoutBox() && m_mousePressNod e->layoutBox()->canBeProgramaticallyScrolled()); | |
| 336 | |
| 337 return swallowEvent ? WebInputEventResult::HandledSystem : WebInputEventResu lt::NotHandled; | |
| 338 } | |
| 339 | |
| 340 WebInputEventResult EventHandler::handleMouseDraggedEvent(const MouseEventWithHi tTestResults& event) | |
| 341 { | |
| 342 TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent"); | |
| 343 | |
| 344 // While resetting m_mousePressed here may seem out of place, it turns out | |
| 345 // to be needed to handle some bugs^Wfeatures in Blink mouse event handling: | |
| 346 // 1. Certain elements, such as <embed>, capture mouse events. They do not | |
| 347 // bubble back up. One way for a <embed> to start capturing mouse events | |
| 348 // is on a mouse press. The problem is the <embed> node only starts | |
| 349 // capturing mouse events *after* m_mousePressed for the containing frame | |
| 350 // has already been set to true. As a result, the frame's EventHandler | |
| 351 // never sees the mouse release event, which is supposed to reset | |
| 352 // m_mousePressed... so m_mousePressed ends up remaining true until the | |
| 353 // event handler finally gets another mouse released event. Oops. | |
| 354 // 2. Dragging doesn't start until after a mouse press event, but a drag | |
| 355 // that ends as a result of a mouse release does not send a mouse release | |
| 356 // event. As a result, m_mousePressed also ends up remaining true until | |
| 357 // the next mouse release event seen by the EventHandler. | |
| 358 if (event.event().pointerProperties().button != WebPointerProperties::Button ::Left) | |
| 359 m_mousePressed = false; | |
| 360 | |
| 361 if (!m_mousePressed) | |
| 362 return WebInputEventResult::NotHandled; | |
| 363 | |
| 364 if (handleDrag(event, DragInitiator::Mouse)) | |
| 365 return WebInputEventResult::HandledSystem; | |
| 366 | |
| 367 Node* targetNode = event.innerNode(); | |
| 368 if (!targetNode) | |
| 369 return WebInputEventResult::NotHandled; | |
| 370 | |
| 371 LayoutObject* layoutObject = targetNode->layoutObject(); | |
| 372 if (!layoutObject) { | |
| 373 Node* parent = FlatTreeTraversal::parent(*targetNode); | |
| 374 if (!parent) | |
| 375 return WebInputEventResult::NotHandled; | |
| 376 | |
| 377 layoutObject = parent->layoutObject(); | |
| 378 if (!layoutObject || !layoutObject->isListBox()) | |
| 379 return WebInputEventResult::NotHandled; | |
| 380 } | |
| 381 | |
| 382 m_mouseDownMayStartDrag = false; | |
| 383 | |
| 384 if (m_mouseDownMayStartAutoscroll && !m_scrollManager->middleClickAutoscroll InProgress()) { | |
| 385 if (AutoscrollController* controller = m_scrollManager->autoscrollContro ller()) { | |
| 386 controller->startAutoscrollForSelection(layoutObject); | |
| 387 m_mouseDownMayStartAutoscroll = false; | |
| 388 } | |
| 389 } | |
| 390 | |
| 391 selectionController().handleMouseDraggedEvent(event, m_mouseDownPos, m_dragS tartPos, m_mousePressNode.get(), m_lastKnownMousePosition); | |
| 392 return WebInputEventResult::HandledSystem; | |
| 393 } | 211 } |
| 394 | 212 |
| 395 void EventHandler::updateSelectionForMouseDrag() | 213 void EventHandler::updateSelectionForMouseDrag() |
| 396 { | 214 { |
| 397 selectionController().updateSelectionForMouseDrag(m_mousePressNode.get(), m_ dragStartPos, m_lastKnownMousePosition); | 215 m_mouseEventManager->updateSelectionForMouseDrag(); |
| 398 } | |
| 399 | |
| 400 // TODO(nzolghadr): Refactor the mouse related functions to MouseEventManager. | |
| 401 WebInputEventResult EventHandler::handleMouseReleaseEvent(const MouseEventWithHi tTestResults& event) | |
| 402 { | |
| 403 AutoscrollController* controller = m_scrollManager->autoscrollController(); | |
| 404 if (controller && controller->autoscrollInProgress()) | |
| 405 m_scrollManager->stopAutoscroll(); | |
| 406 | |
| 407 return selectionController().handleMouseReleaseEvent(event, m_dragStartPos) ? WebInputEventResult::HandledSystem : WebInputEventResult::NotHandled; | |
| 408 } | 216 } |
| 409 | 217 |
| 410 void EventHandler::startMiddleClickAutoscroll(LayoutObject* layoutObject) | 218 void EventHandler::startMiddleClickAutoscroll(LayoutObject* layoutObject) |
| 411 { | 219 { |
| 412 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); | 220 DCHECK(RuntimeEnabledFeatures::middleClickAutoscrollEnabled()); |
| 413 if (!layoutObject->isBox()) | 221 if (!layoutObject->isBox()) |
| 414 return; | 222 return; |
| 415 AutoscrollController* controller = m_scrollManager->autoscrollController(); | 223 AutoscrollController* controller = m_scrollManager->autoscrollController(); |
| 416 if (!controller) | 224 if (!controller) |
| 417 return; | 225 return; |
| 418 controller->startMiddleClickAutoscroll(toLayoutBox(layoutObject), lastKnownM ousePosition()); | 226 controller->startMiddleClickAutoscroll(toLayoutBox(layoutObject), m_mouseEve ntManager->lastKnownMousePosition()); |
| 419 invalidateClick(); | 227 m_mouseEventManager->invalidateClick(); |
| 420 } | 228 } |
| 421 | 229 |
| 422 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTe stRequest::HitTestRequestType hitType, const LayoutSize& padding) | 230 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTe stRequest::HitTestRequestType hitType, const LayoutSize& padding) |
| 423 { | 231 { |
| 424 TRACE_EVENT0("blink", "EventHandler::hitTestResultAtPoint"); | 232 TRACE_EVENT0("blink", "EventHandler::hitTestResultAtPoint"); |
| 425 | 233 |
| 426 ASSERT((hitType & HitTestRequest::ListBased) || padding.isEmpty()); | 234 ASSERT((hitType & HitTestRequest::ListBased) || padding.isEmpty()); |
| 427 | 235 |
| 428 // We always send hitTestResultAtPoint to the main frame if we have one, | 236 // We always send hitTestResultAtPoint to the main frame if we have one, |
| 429 // otherwise we might hit areas that are obscured by higher frames. | 237 // otherwise we might hit areas that are obscured by higher frames. |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 441 | 249 |
| 442 // hitTestResultAtPoint is specifically used to hitTest into all frames, thu s it always allows child frame content. | 250 // hitTestResultAtPoint is specifically used to hitTest into all frames, thu s it always allows child frame content. |
| 443 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); | 251 HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent); |
| 444 HitTestResult result(request, point, padding.height().toUnsigned(), padding. width().toUnsigned(), padding.height().toUnsigned(), padding.width().toUnsigned( )); | 252 HitTestResult result(request, point, padding.height().toUnsigned(), padding. width().toUnsigned(), padding.height().toUnsigned(), padding.width().toUnsigned( )); |
| 445 | 253 |
| 446 // LayoutView::hitTest causes a layout, and we don't want to hit that until the first | 254 // LayoutView::hitTest causes a layout, and we don't want to hit that until the first |
| 447 // layout because until then, there is nothing shown on the screen - the use r can't | 255 // layout because until then, there is nothing shown on the screen - the use r can't |
| 448 // have intentionally clicked on something belonging to this page. Furthermo re, | 256 // have intentionally clicked on something belonging to this page. Furthermo re, |
| 449 // mousemove events before the first layout should not lead to a premature l ayout() | 257 // mousemove events before the first layout should not lead to a premature l ayout() |
| 450 // happening, which could show a flash of white. | 258 // happening, which could show a flash of white. |
| 451 // See also the similar code in Document::prepareMouseEvent. | 259 // See also the similar code in Document::performMouseEventHitTest. |
| 452 if (m_frame->contentLayoutItem().isNull() || !m_frame->view() || !m_frame->v iew()->didFirstLayout()) | 260 if (m_frame->contentLayoutItem().isNull() || !m_frame->view() || !m_frame->v iew()->didFirstLayout()) |
| 453 return result; | 261 return result; |
| 454 | 262 |
| 455 m_frame->contentLayoutItem().hitTest(result); | 263 m_frame->contentLayoutItem().hitTest(result); |
| 456 if (!request.readOnly()) | 264 if (!request.readOnly()) |
| 457 m_frame->document()->updateHoverActiveState(request, result.innerElement ()); | 265 m_frame->document()->updateHoverActiveState(request, result.innerElement ()); |
| 458 | 266 |
| 459 return result; | 267 return result; |
| 460 } | 268 } |
| 461 | 269 |
| 462 void EventHandler::stopAutoscroll() | 270 void EventHandler::stopAutoscroll() |
| 463 { | 271 { |
| 464 m_scrollManager->stopAutoscroll(); | 272 m_scrollManager->stopAutoscroll(); |
| 465 } | 273 } |
| 466 | 274 |
| 467 // TODO(bokan): This should be merged with logicalScroll assuming | 275 // TODO(bokan): This should be merged with logicalScroll assuming |
| 468 // defaultSpaceEventHandler's chaining scroll can be done crossing frames. | 276 // defaultSpaceEventHandler's chaining scroll can be done crossing frames. |
| 469 bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity g ranularity, Node* startingNode) | 277 bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity g ranularity, Node* startingNode) |
| 470 { | 278 { |
| 471 return m_scrollManager->bubblingScroll(direction, granularity, startingNode, m_mousePressNode); | 279 return m_scrollManager->bubblingScroll(direction, granularity, startingNode, m_mouseEventManager->mousePressNode()); |
| 472 } | 280 } |
| 473 | 281 |
| 474 IntPoint EventHandler::lastKnownMousePosition() const | 282 IntPoint EventHandler::lastKnownMousePosition() const |
| 475 { | 283 { |
| 476 return m_lastKnownMousePosition; | 284 return m_mouseEventManager->lastKnownMousePosition(); |
| 477 } | 285 } |
| 478 | 286 |
| 479 IntPoint EventHandler::dragDataTransferLocationForTesting() | 287 IntPoint EventHandler::dragDataTransferLocationForTesting() |
| 480 { | 288 { |
| 481 if (dragState().m_dragDataTransfer) | 289 if (m_mouseEventManager->dragState().m_dragDataTransfer) |
| 482 return dragState().m_dragDataTransfer->dragLocation(); | 290 return m_mouseEventManager->dragState().m_dragDataTransfer->dragLocation (); |
| 483 | 291 |
| 484 return IntPoint(); | 292 return IntPoint(); |
| 485 } | 293 } |
| 486 | 294 |
| 487 static LocalFrame* subframeForTargetNode(Node* node) | 295 static LocalFrame* subframeForTargetNode(Node* node) |
| 488 { | 296 { |
| 489 if (!node) | 297 if (!node) |
| 490 return nullptr; | 298 return nullptr; |
| 491 | 299 |
| 492 LayoutObject* layoutObject = node->layoutObject(); | 300 LayoutObject* layoutObject = node->layoutObject(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 529 } | 337 } |
| 530 | 338 |
| 531 void EventHandler::updateCursor() | 339 void EventHandler::updateCursor() |
| 532 { | 340 { |
| 533 TRACE_EVENT0("input", "EventHandler::updateCursor"); | 341 TRACE_EVENT0("input", "EventHandler::updateCursor"); |
| 534 | 342 |
| 535 // We must do a cross-frame hit test because the frame that triggered the cu rsor | 343 // We must do a cross-frame hit test because the frame that triggered the cu rsor |
| 536 // update could be occluded by a different frame. | 344 // update could be occluded by a different frame. |
| 537 ASSERT(m_frame == m_frame->localFrameRoot()); | 345 ASSERT(m_frame == m_frame->localFrameRoot()); |
| 538 | 346 |
| 539 if (m_mousePositionIsUnknown) | 347 if (m_mouseEventManager->isMousePositionUnknown()) |
| 540 return; | 348 return; |
| 541 | 349 |
| 542 FrameView* view = m_frame->view(); | 350 FrameView* view = m_frame->view(); |
| 543 if (!view || !view->shouldSetCursor()) | 351 if (!view || !view->shouldSetCursor()) |
| 544 return; | 352 return; |
| 545 | 353 |
| 546 LayoutViewItem layoutViewItem = view->layoutViewItem(); | 354 LayoutViewItem layoutViewItem = view->layoutViewItem(); |
| 547 if (layoutViewItem.isNull()) | 355 if (layoutViewItem.isNull()) |
| 548 return; | 356 return; |
| 549 | 357 |
| 550 m_frame->document()->updateStyleAndLayout(); | 358 m_frame->document()->updateStyleAndLayout(); |
| 551 | 359 |
| 552 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::AllowChild FrameContent); | 360 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::AllowChild FrameContent); |
| 553 HitTestResult result(request, view->rootFrameToContents(m_lastKnownMousePosi tion)); | 361 HitTestResult result(request, view->rootFrameToContents(m_mouseEventManager- >lastKnownMousePosition())); |
| 554 layoutViewItem.hitTest(result); | 362 layoutViewItem.hitTest(result); |
| 555 | 363 |
| 556 if (LocalFrame* frame = result.innerNodeFrame()) { | 364 if (LocalFrame* frame = result.innerNodeFrame()) { |
| 557 OptionalCursor optionalCursor = frame->eventHandler().selectCursor(resul t); | 365 OptionalCursor optionalCursor = frame->eventHandler().selectCursor(resul t); |
| 558 if (optionalCursor.isCursorChange()) { | 366 if (optionalCursor.isCursorChange()) { |
| 559 view->setCursor(optionalCursor.cursor()); | 367 view->setCursor(optionalCursor.cursor()); |
| 560 } | 368 } |
| 561 } | 369 } |
| 562 } | 370 } |
| 563 | 371 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 | 520 |
| 713 bool inResizer = false; | 521 bool inResizer = false; |
| 714 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; | 522 LayoutObject* layoutObject = node ? node->layoutObject() : nullptr; |
| 715 if (layoutObject && m_frame->view()) { | 523 if (layoutObject && m_frame->view()) { |
| 716 PaintLayer* layer = layoutObject->enclosingLayer(); | 524 PaintLayer* layer = layoutObject->enclosingLayer(); |
| 717 inResizer = layer->getScrollableArea() && layer->getScrollableArea()->is PointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer); | 525 inResizer = layer->getScrollableArea() && layer->getScrollableArea()->is PointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer); |
| 718 } | 526 } |
| 719 | 527 |
| 720 // During selection, use an I-beam no matter what we're over. | 528 // During selection, use an I-beam no matter what we're over. |
| 721 // If a drag may be starting or we're capturing mouse events for a particula r node, don't treat this as a selection. | 529 // If a drag may be starting or we're capturing mouse events for a particula r node, don't treat this as a selection. |
| 722 if (m_mousePressed && selectionController().mouseDownMayStartSelect() | 530 if (m_mouseEventManager->mousePressed() && selectionController().mouseDownMa yStartSelect() |
| 723 && !m_mouseDownMayStartDrag | 531 && !m_mouseEventManager->mouseDownMayStartDrag() |
| 724 && !m_frame->selection().isNone() | 532 && !m_frame->selection().isNone() |
| 725 && !m_capturingMouseEventsNode) { | 533 && !m_capturingMouseEventsNode) { |
| 726 return iBeam; | 534 return iBeam; |
| 727 } | 535 } |
| 728 | 536 |
| 729 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar()) | 537 if ((editable || (layoutObject && layoutObject->isText() && node->canStartSe lection())) && !inResizer && !result.scrollbar()) |
| 730 return iBeam; | 538 return iBeam; |
| 731 return pointerCursor(); | 539 return pointerCursor(); |
| 732 } | 540 } |
| 733 | 541 |
| 734 static LayoutPoint contentPointFromRootFrame(LocalFrame* frame, const IntPoint& pointInRootFrame) | |
| 735 { | |
| 736 FrameView* view = frame->view(); | |
| 737 // FIXME: Is it really OK to use the wrong coordinates here when view is 0? | |
| 738 // Historically the code would just crash; this is clearly no worse than tha t. | |
| 739 return view ? view->rootFrameToContents(pointInRootFrame) : pointInRootFrame ; | |
| 740 } | |
| 741 | |
| 742 WebInputEventResult EventHandler::handleMousePressEvent(const PlatformMouseEvent & mouseEvent) | 542 WebInputEventResult EventHandler::handleMousePressEvent(const PlatformMouseEvent & mouseEvent) |
| 743 { | 543 { |
| 744 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); | 544 TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent"); |
| 745 | 545 |
| 746 // For 4th/5th button in the mouse since Chrome does not yet send | 546 // For 4th/5th button in the mouse since Chrome does not yet send |
| 747 // button value to Blink but in some cases it does send the event. | 547 // button value to Blink but in some cases it does send the event. |
| 748 // This check is needed to suppress such an event (crbug.com/574959) | 548 // This check is needed to suppress such an event (crbug.com/574959) |
| 749 if (mouseEvent.pointerProperties().button == WebPointerProperties::Button::N oButton) | 549 if (mouseEvent.pointerProperties().button == WebPointerProperties::Button::N oButton) |
| 750 return WebInputEventResult::HandledSuppressed; | 550 return WebInputEventResult::HandledSuppressed; |
| 751 | 551 |
| 752 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); | 552 UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture); |
| 753 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = UserGestureIndicator::currentToken(); | 553 m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = UserGestureIndicator::currentToken(); |
| 754 | 554 |
| 755 cancelFakeMouseMoveEvent(); | |
| 756 if (m_eventHandlerWillResetCapturingMouseEventsNode) | 555 if (m_eventHandlerWillResetCapturingMouseEventsNode) |
| 757 m_capturingMouseEventsNode = nullptr; | 556 m_capturingMouseEventsNode = nullptr; |
| 758 m_mousePressed = true; | 557 m_mouseEventManager->handleMousePressEventUpdateStates(mouseEvent); |
| 759 m_capturesDragging = true; | |
| 760 setLastKnownMousePosition(mouseEvent); | |
| 761 m_mouseDownTimestamp = mouseEvent.timestamp(); | |
| 762 m_mouseDownMayStartDrag = false; | |
| 763 selectionController().setMouseDownMayStartSelect(false); | 558 selectionController().setMouseDownMayStartSelect(false); |
| 764 m_mouseDownMayStartAutoscroll = false; | 559 |
| 765 if (FrameView* view = m_frame->view()) { | 560 if (!m_frame->view()) |
| 766 m_mouseDownPos = view->rootFrameToContents(mouseEvent.position()); | |
| 767 } else { | |
| 768 invalidateClick(); | |
| 769 return WebInputEventResult::NotHandled; | 561 return WebInputEventResult::NotHandled; |
| 770 } | |
| 771 | 562 |
| 772 HitTestRequest request(HitTestRequest::Active); | 563 HitTestRequest request(HitTestRequest::Active); |
| 773 // Save the document point we generate in case the window coordinate is inva lidated by what happens | 564 // Save the document point we generate in case the window coordinate is inva lidated by what happens |
| 774 // when we dispatch the event. | 565 // when we dispatch the event. |
| 775 LayoutPoint documentPoint = contentPointFromRootFrame(m_frame, mouseEvent.po sition()); | 566 LayoutPoint documentPoint = EventHandlingUtil::contentPointFromRootFrame(m_f rame, mouseEvent.position()); |
|
bokan
2016/09/30 16:57:55
We don't need this helper method, all it does is n
Navid Zolghadr
2016/10/03 16:03:00
Done.
| |
| 776 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, documentPoint, mouseEvent); | 567 MouseEventWithHitTestResults mev = m_frame->document()->performMouseEventHit Test(request, documentPoint, mouseEvent); |
| 777 | 568 |
| 778 if (!mev.innerNode()) { | 569 if (!mev.innerNode()) { |
| 779 invalidateClick(); | 570 m_mouseEventManager->invalidateClick(); |
| 780 return WebInputEventResult::NotHandled; | 571 return WebInputEventResult::NotHandled; |
| 781 } | 572 } |
| 782 | 573 |
| 783 m_mousePressNode = mev.innerNode(); | 574 m_mouseEventManager->setMousePressNode(mev.innerNode()); |
| 784 m_frame->document()->setSequentialFocusNavigationStartingPoint(mev.innerNode ()); | 575 m_frame->document()->setSequentialFocusNavigationStartingPoint(mev.innerNode ()); |
| 785 | 576 |
| 786 LocalFrame* subframe = subframeForHitTestResult(mev); | 577 LocalFrame* subframe = subframeForHitTestResult(mev); |
| 787 if (subframe) { | 578 if (subframe) { |
| 788 WebInputEventResult result = passMousePressEventToSubframe(mev, subframe ); | 579 WebInputEventResult result = passMousePressEventToSubframe(mev, subframe ); |
| 789 // Start capturing future events for this frame. We only do this if we didn't clear | 580 // Start capturing future events for this frame. We only do this if we didn't clear |
| 790 // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop. | 581 // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop. |
| 791 // The capturing should be done only when the result indicates it | 582 // The capturing should be done only when the result indicates it |
| 792 // has been handled. See crbug.com/269917 | 583 // has been handled. See crbug.com/269917 |
| 793 m_capturesDragging = subframe->eventHandler().capturesDragging(); | 584 m_mouseEventManager->setCapturesDragging(subframe->eventHandler().m_mous eEventManager->capturesDragging()); |
| 794 if (m_mousePressed && m_capturesDragging) { | 585 if (m_mouseEventManager->mousePressed() && m_mouseEventManager->captures Dragging()) { |
| 795 m_capturingMouseEventsNode = mev.innerNode(); | 586 m_capturingMouseEventsNode = mev.innerNode(); |
| 796 m_eventHandlerWillResetCapturingMouseEventsNode = true; | 587 m_eventHandlerWillResetCapturingMouseEventsNode = true; |
| 797 } | 588 } |
| 798 invalidateClick(); | 589 m_mouseEventManager->invalidateClick(); |
| 799 return result; | 590 return result; |
| 800 } | 591 } |
| 801 | 592 |
| 802 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { | 593 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { |
| 803 // We store whether middle click autoscroll is in progress before callin g stopAutoscroll() | 594 // We store whether middle click autoscroll is in progress before callin g stopAutoscroll() |
| 804 // because it will set m_autoscrollType to NoAutoscroll on return. | 595 // because it will set m_autoscrollType to NoAutoscroll on return. |
| 805 bool isMiddleClickAutoscrollInProgress = m_scrollManager->middleClickAut oscrollInProgress(); | 596 bool isMiddleClickAutoscrollInProgress = m_scrollManager->middleClickAut oscrollInProgress(); |
| 806 m_scrollManager->stopAutoscroll(); | 597 m_scrollManager->stopAutoscroll(); |
| 807 if (isMiddleClickAutoscrollInProgress) { | 598 if (isMiddleClickAutoscrollInProgress) { |
| 808 // We invalidate the click when exiting middle click auto scroll so that we don't inadvertently navigate | 599 // We invalidate the click when exiting middle click auto scroll so that we don't inadvertently navigate |
| 809 // away from the current page (e.g. the click was on a hyperlink). S ee <rdar://problem/6095023>. | 600 // away from the current page (e.g. the click was on a hyperlink). S ee <rdar://problem/6095023>. |
| 810 invalidateClick(); | 601 m_mouseEventManager->invalidateClick(); |
| 811 return WebInputEventResult::HandledSuppressed; | 602 return WebInputEventResult::HandledSuppressed; |
| 812 } | 603 } |
| 813 } | 604 } |
| 814 | 605 |
| 815 m_clickCount = mouseEvent.clickCount(); | 606 m_mouseEventManager->setClickCount(mouseEvent.clickCount()); |
| 816 m_clickNode = mev.innerNode()->isTextNode() ? FlatTreeTraversal::parent(*me v.innerNode()) : mev.innerNode(); | 607 m_mouseEventManager->setClickNode(mev.innerNode()->isTextNode() ? FlatTreeT raversal::parent(*mev.innerNode()) : mev.innerNode()); |
| 817 | 608 |
| 818 if (!mouseEvent.fromTouch()) | 609 if (!mouseEvent.fromTouch()) |
| 819 m_frame->selection().setCaretBlinkingSuspended(true); | 610 m_frame->selection().setCaretBlinkingSuspended(true); |
| 820 | 611 |
| 821 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mousedown, mev.innerNode(), m_clickCount, mev.event()); | 612 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mousedown, mev.innerNode(), mev.event()); |
| 822 | 613 |
| 823 if (eventResult == WebInputEventResult::NotHandled && m_frame->view()) { | 614 if (eventResult == WebInputEventResult::NotHandled && m_frame->view()) { |
| 824 FrameView* view = m_frame->view(); | 615 FrameView* view = m_frame->view(); |
| 825 PaintLayer* layer = mev.innerNode()->layoutObject() ? mev.innerNode()->l ayoutObject()->enclosingLayer() : nullptr; | 616 PaintLayer* layer = mev.innerNode()->layoutObject() ? mev.innerNode()->l ayoutObject()->enclosingLayer() : nullptr; |
| 826 IntPoint p = view->rootFrameToContents(mouseEvent.position()); | 617 IntPoint p = view->rootFrameToContents(mouseEvent.position()); |
| 827 if (layer && layer->getScrollableArea() && layer->getScrollableArea()->i sPointInResizeControl(p, ResizerForPointer)) { | 618 if (layer && layer->getScrollableArea() && layer->getScrollableArea()->i sPointInResizeControl(p, ResizerForPointer)) { |
| 828 m_scrollManager->setResizeScrollableArea(layer, p); | 619 m_scrollManager->setResizeScrollableArea(layer, p); |
| 829 return WebInputEventResult::HandledSystem; | 620 return WebInputEventResult::HandledSystem; |
| 830 } | 621 } |
| 831 } | 622 } |
| 832 | 623 |
| 833 // m_selectionInitiationState is initialized after dispatching mousedown | 624 // m_selectionInitiationState is initialized after dispatching mousedown |
| 834 // event in order not to keep the selection by DOM APIs because we can't | 625 // event in order not to keep the selection by DOM APIs because we can't |
| 835 // give the user the chance to handle the selection by user action like | 626 // give the user the chance to handle the selection by user action like |
| 836 // dragging if we keep the selection in case of mousedown. FireFox also has | 627 // dragging if we keep the selection in case of mousedown. FireFox also has |
| 837 // the same behavior and it's more compatible with other browsers. | 628 // the same behavior and it's more compatible with other browsers. |
| 838 selectionController().initializeSelectionState(); | 629 selectionController().initializeSelectionState(); |
| 839 HitTestResult hitTestResult = EventHandlingUtil::hitTestResultInFrame(m_fram e, documentPoint, HitTestRequest::ReadOnly); | 630 HitTestResult hitTestResult = EventHandlingUtil::hitTestResultInFrame(m_fram e, documentPoint, HitTestRequest::ReadOnly); |
| 840 InputDeviceCapabilities* sourceCapabilities = mouseEvent.getSyntheticEventTy pe() == PlatformMouseEvent::FromTouch ? InputDeviceCapabilities::firesTouchEvent sSourceCapabilities() : | 631 InputDeviceCapabilities* sourceCapabilities = mouseEvent.getSyntheticEventTy pe() == PlatformMouseEvent::FromTouch ? InputDeviceCapabilities::firesTouchEvent sSourceCapabilities() : |
| 841 InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities(); | 632 InputDeviceCapabilities::doesntFireTouchEventsSourceCapabilities(); |
| 842 if (eventResult == WebInputEventResult::NotHandled) | 633 if (eventResult == WebInputEventResult::NotHandled) |
| 843 eventResult = handleMouseFocus(hitTestResult, sourceCapabilities); | 634 eventResult = m_mouseEventManager->handleMouseFocus(hitTestResult, sourc eCapabilities); |
| 844 m_capturesDragging = eventResult == WebInputEventResult::NotHandled || mev.s crollbar(); | 635 m_mouseEventManager->setCapturesDragging(eventResult == WebInputEventResult: :NotHandled || mev.scrollbar()); |
| 845 | 636 |
| 846 // If the hit testing originally determined the event was in a scrollbar, re fetch the MouseEventWithHitTestResults | 637 // If the hit testing originally determined the event was in a scrollbar, re fetch the MouseEventWithHitTestResults |
| 847 // in case the scrollbar widget was destroyed when the mouse event was handl ed. | 638 // in case the scrollbar widget was destroyed when the mouse event was handl ed. |
| 848 if (mev.scrollbar()) { | 639 if (mev.scrollbar()) { |
| 849 const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMou se.get(); | 640 const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMou se.get(); |
| 850 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active ); | 641 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active ); |
| 851 mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mou seEvent); | 642 mev = m_frame->document()->performMouseEventHitTest(request, documentPoi nt, mouseEvent); |
| 852 if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get ()) | 643 if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get ()) |
| 853 m_lastScrollbarUnderMouse = nullptr; | 644 m_lastScrollbarUnderMouse = nullptr; |
| 854 } | 645 } |
| 855 | 646 |
| 856 if (eventResult != WebInputEventResult::NotHandled) { | 647 if (eventResult != WebInputEventResult::NotHandled) { |
| 857 // scrollbars should get events anyway, even disabled controls might be scrollable | 648 // scrollbars should get events anyway, even disabled controls might be scrollable |
| 858 passMousePressEventToScrollbar(mev); | 649 passMousePressEventToScrollbar(mev); |
| 859 } else { | 650 } else { |
| 860 if (shouldRefetchEventTarget(mev)) { | 651 if (shouldRefetchEventTarget(mev)) { |
| 861 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Ac tive); | 652 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Ac tive); |
| 862 mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent); | 653 mev = m_frame->document()->performMouseEventHitTest(request, documen tPoint, mouseEvent); |
| 863 } | 654 } |
| 864 | 655 |
| 865 if (passMousePressEventToScrollbar(mev)) | 656 if (passMousePressEventToScrollbar(mev)) |
| 866 eventResult = WebInputEventResult::HandledSystem; | 657 eventResult = WebInputEventResult::HandledSystem; |
| 867 else | 658 else |
| 868 eventResult = handleMousePressEvent(mev); | 659 eventResult = m_mouseEventManager->handleMousePressEvent(mev); |
| 869 } | 660 } |
| 870 | 661 |
| 871 if (mev.hitTestResult().innerNode() && mouseEvent.pointerProperties().button == WebPointerProperties::Button::Left) { | 662 if (mev.hitTestResult().innerNode() && mouseEvent.pointerProperties().button == WebPointerProperties::Button::Left) { |
| 872 ASSERT(mouseEvent.type() == PlatformEvent::MousePressed); | 663 ASSERT(mouseEvent.type() == PlatformEvent::MousePressed); |
| 873 HitTestResult result = mev.hitTestResult(); | 664 HitTestResult result = mev.hitTestResult(); |
| 874 result.setToShadowHostIfInUserAgentShadowRoot(); | 665 result.setToShadowHostIfInUserAgentShadowRoot(); |
| 875 m_frame->chromeClient().onMouseDown(result.innerNode()); | 666 m_frame->chromeClient().onMouseDown(result.innerNode()); |
| 876 } | 667 } |
| 877 | 668 |
| 878 return eventResult; | 669 return eventResult; |
| 879 } | 670 } |
| 880 | 671 |
| 881 static PaintLayer* layerForNode(Node* node) | |
| 882 { | |
| 883 if (!node) | |
| 884 return nullptr; | |
| 885 | |
| 886 LayoutObject* layoutObject = node->layoutObject(); | |
| 887 if (!layoutObject) | |
| 888 return nullptr; | |
| 889 | |
| 890 PaintLayer* layer = layoutObject->enclosingLayer(); | |
| 891 if (!layer) | |
| 892 return nullptr; | |
| 893 | |
| 894 return layer; | |
| 895 } | |
| 896 | |
| 897 ScrollableArea* EventHandler::associatedScrollableArea(const PaintLayer* layer) const | |
| 898 { | |
| 899 if (PaintLayerScrollableArea* scrollableArea = layer->getScrollableArea()) { | |
| 900 if (scrollableArea->scrollsOverflow()) | |
| 901 return scrollableArea; | |
| 902 } | |
| 903 | |
| 904 return nullptr; | |
| 905 } | |
| 906 | |
| 907 WebInputEventResult EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event) | 672 WebInputEventResult EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event) |
| 908 { | 673 { |
| 909 TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent"); | 674 TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent"); |
| 910 | 675 |
| 911 HitTestResult hoveredNode = HitTestResult(); | 676 HitTestResult hoveredNode = HitTestResult(); |
| 912 WebInputEventResult result = handleMouseMoveOrLeaveEvent(event, &hoveredNode ); | 677 WebInputEventResult result = handleMouseMoveOrLeaveEvent(event, &hoveredNode ); |
| 913 | 678 |
| 914 Page* page = m_frame->page(); | 679 Page* page = m_frame->page(); |
| 915 if (!page) | 680 if (!page) |
| 916 return result; | 681 return result; |
| 917 | 682 |
| 918 if (PaintLayer* layer = layerForNode(hoveredNode.innerNode())) { | 683 if (PaintLayer* layer = EventHandlingUtil::layerForNode(hoveredNode.innerNod e())) { |
| 919 if (ScrollableArea* layerScrollableArea = associatedScrollableArea(layer )) | 684 if (ScrollableArea* layerScrollableArea = EventHandlingUtil::associatedS crollableArea(layer)) |
| 920 layerScrollableArea->mouseMovedInContentArea(); | 685 layerScrollableArea->mouseMovedInContentArea(); |
| 921 } | 686 } |
| 922 | 687 |
| 923 if (FrameView* frameView = m_frame->view()) | 688 if (FrameView* frameView = m_frame->view()) |
| 924 frameView->mouseMovedInContentArea(); | 689 frameView->mouseMovedInContentArea(); |
| 925 | 690 |
| 926 hoveredNode.setToShadowHostIfInUserAgentShadowRoot(); | 691 hoveredNode.setToShadowHostIfInUserAgentShadowRoot(); |
| 927 page->chromeClient().mouseDidMoveOverElement(hoveredNode); | 692 page->chromeClient().mouseDidMoveOverElement(hoveredNode); |
| 928 | 693 |
| 929 return result; | 694 return result; |
| 930 } | 695 } |
| 931 | 696 |
| 932 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) | 697 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event) |
| 933 { | 698 { |
| 934 TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent"); | 699 TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent"); |
| 935 | 700 |
| 936 handleMouseMoveOrLeaveEvent(event, 0, false, true); | 701 handleMouseMoveOrLeaveEvent(event, 0, false, true); |
| 937 } | 702 } |
| 938 | 703 |
| 939 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMous eEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars, bool forceLeave) | 704 WebInputEventResult EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMous eEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars, bool forceLeave) |
| 940 { | 705 { |
| 941 ASSERT(m_frame); | 706 ASSERT(m_frame); |
| 942 ASSERT(m_frame->view()); | 707 ASSERT(m_frame->view()); |
| 943 | 708 |
| 944 setLastKnownMousePosition(mouseEvent); | 709 m_mouseEventManager->setLastKnownMousePosition(mouseEvent); |
| 945 | 710 |
| 946 if (m_hoverTimer.isActive()) | 711 if (m_hoverTimer.isActive()) |
| 947 m_hoverTimer.stop(); | 712 m_hoverTimer.stop(); |
| 948 | 713 |
| 949 m_cursorUpdateTimer.stop(); | 714 m_cursorUpdateTimer.stop(); |
| 950 | 715 |
| 951 cancelFakeMouseMoveEvent(); | 716 m_mouseEventManager->cancelFakeMouseMoveEvent(); |
| 952 | 717 |
| 953 if (m_svgPan) { | 718 m_mouseEventManager->handleSvgPanIfNeeded(false); |
| 954 m_frame->document()->accessSVGExtensions().updatePan(m_frame->view()->ro otFrameToContents(m_lastKnownMousePosition)); | |
| 955 return WebInputEventResult::HandledSuppressed; | |
| 956 } | |
| 957 | 719 |
| 958 if (m_frameSetBeingResized) | 720 if (m_frameSetBeingResized) |
| 959 return updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove, m _frameSetBeingResized.get(), 0, mouseEvent); | 721 return updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove, m _frameSetBeingResized.get(), mouseEvent); |
| 960 | 722 |
| 961 // Send events right to a scrollbar if the mouse is pressed. | 723 // Send events right to a scrollbar if the mouse is pressed. |
| 962 if (m_lastScrollbarUnderMouse && m_mousePressed) { | 724 if (m_lastScrollbarUnderMouse && m_mouseEventManager->mousePressed()) { |
| 963 m_lastScrollbarUnderMouse->mouseMoved(mouseEvent); | 725 m_lastScrollbarUnderMouse->mouseMoved(mouseEvent); |
| 964 return WebInputEventResult::HandledSystem; | 726 return WebInputEventResult::HandledSystem; |
| 965 } | 727 } |
| 966 | 728 |
| 967 // Mouse events simulated from touch should not hit-test again. | 729 // Mouse events simulated from touch should not hit-test again. |
| 968 ASSERT(!mouseEvent.fromTouch()); | 730 ASSERT(!mouseEvent.fromTouch()); |
| 969 | 731 |
| 970 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; | 732 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move; |
| 971 if (m_mousePressed) { | 733 if (m_mouseEventManager->mousePressed()) { |
| 972 hitType |= HitTestRequest::Active; | 734 hitType |= HitTestRequest::Active; |
| 973 } else if (onlyUpdateScrollbars) { | 735 } else if (onlyUpdateScrollbars) { |
| 974 // Mouse events should be treated as "read-only" if we're updating only scrollbars. This | 736 // Mouse events should be treated as "read-only" if we're updating only scrollbars. This |
| 975 // means that :hover and :active freeze in the state they were in, rathe r than updating | 737 // means that :hover and :active freeze in the state they were in, rathe r than updating |
| 976 // for nodes the mouse moves while the window is not key (which will be the case if | 738 // for nodes the mouse moves while the window is not key (which will be the case if |
| 977 // onlyUpdateScrollbars is true). | 739 // onlyUpdateScrollbars is true). |
| 978 hitType |= HitTestRequest::ReadOnly; | 740 hitType |= HitTestRequest::ReadOnly; |
| 979 } | 741 } |
| 980 | 742 |
| 981 // Treat any mouse move events as readonly if the user is currently touching the screen. | 743 // Treat any mouse move events as readonly if the user is currently touching the screen. |
| 982 if (m_pointerEventManager->isAnyTouchActive()) | 744 if (m_pointerEventManager->isAnyTouchActive()) |
| 983 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; | 745 hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly; |
| 984 HitTestRequest request(hitType); | 746 HitTestRequest request(hitType); |
| 985 MouseEventWithHitTestResults mev = MouseEventWithHitTestResults(mouseEvent, HitTestResult(request, LayoutPoint())); | 747 MouseEventWithHitTestResults mev = MouseEventWithHitTestResults(mouseEvent, HitTestResult(request, LayoutPoint())); |
| 986 | 748 |
| 987 // We don't want to do a hit-test in forceLeave scenarios because there migh t actually be some other frame above this one at the specified co-ordinate. | 749 // We don't want to do a hit-test in forceLeave scenarios because there migh t actually be some other frame above this one at the specified co-ordinate. |
| 988 // So we must force the hit-test to fail, while still clearing hover/active state. | 750 // So we must force the hit-test to fail, while still clearing hover/active state. |
| 989 if (forceLeave) | 751 if (forceLeave) |
| 990 m_frame->document()->updateHoverActiveState(request, 0); | 752 m_frame->document()->updateHoverActiveState(request, 0); |
| 991 else | 753 else |
| 992 mev = prepareMouseEvent(request, mouseEvent); | 754 mev = EventHandlingUtil::performMouseEventHitTest(m_frame, request, mous eEvent); |
| 993 | 755 |
| 994 if (hoveredNode) | 756 if (hoveredNode) |
| 995 *hoveredNode = mev.hitTestResult(); | 757 *hoveredNode = mev.hitTestResult(); |
| 996 | 758 |
| 997 Scrollbar* scrollbar = nullptr; | 759 Scrollbar* scrollbar = nullptr; |
| 998 | 760 |
| 999 if (m_scrollManager->inResizeMode()) { | 761 if (m_scrollManager->inResizeMode()) { |
| 1000 m_scrollManager->resize(mev.event()); | 762 m_scrollManager->resize(mev.event()); |
| 1001 } else { | 763 } else { |
| 1002 if (!scrollbar) | 764 if (!scrollbar) |
| 1003 scrollbar = mev.scrollbar(); | 765 scrollbar = mev.scrollbar(); |
| 1004 | 766 |
| 1005 updateLastScrollbarUnderMouse(scrollbar, !m_mousePressed); | 767 updateLastScrollbarUnderMouse(scrollbar, !m_mouseEventManager->mousePres sed()); |
| 1006 if (onlyUpdateScrollbars) | 768 if (onlyUpdateScrollbars) |
| 1007 return WebInputEventResult::HandledSuppressed; | 769 return WebInputEventResult::HandledSuppressed; |
| 1008 } | 770 } |
| 1009 | 771 |
| 1010 WebInputEventResult eventResult = WebInputEventResult::NotHandled; | 772 WebInputEventResult eventResult = WebInputEventResult::NotHandled; |
| 1011 LocalFrame* newSubframe = m_capturingMouseEventsNode.get() ? subframeForTarg etNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); | 773 LocalFrame* newSubframe = m_capturingMouseEventsNode.get() ? subframeForTarg etNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); |
| 1012 | 774 |
| 1013 // We want mouseouts to happen first, from the inside out. First send a mov e event to the last subframe so that it will fire mouseouts. | 775 // We want mouseouts to happen first, from the inside out. First send a mov e event to the last subframe so that it will fire mouseouts. |
| 1014 if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isD escendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe) | 776 if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isD escendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe) |
| 1015 m_lastMouseMoveEventSubframe->eventHandler().handleMouseLeaveEvent(mev.e vent()); | 777 m_lastMouseMoveEventSubframe->eventHandler().handleMouseLeaveEvent(mev.e vent()); |
| 1016 | 778 |
| 1017 if (newSubframe) { | 779 if (newSubframe) { |
| 1018 // Update over/out state before passing the event to the subframe. | 780 // Update over/out state before passing the event to the subframe. |
| 1019 updateMouseEventTargetNodeAndSendEvents(mev.innerNode(), mev.event(), tr ue); | 781 m_pointerEventManager->sendMouseAndPointerBoundaryEvents(updateMouseEven tTargetNode(mev.innerNode()), mev.event()); |
| 1020 | 782 |
| 1021 // Event dispatch in updateMouseEventTargetNodeAndSendEvents may have ca used the subframe of the target | 783 // Event dispatch in sendMouseAndPointerBoundaryEvents may have caused t he subframe of the target |
| 1022 // node to be detached from its FrameView, in which case the event shoul d not be passed. | 784 // node to be detached from its FrameView, in which case the event shoul d not be passed. |
| 1023 if (newSubframe->view()) | 785 if (newSubframe->view()) |
| 1024 eventResult = passMouseMoveEventToSubframe(mev, newSubframe, hovered Node); | 786 eventResult = passMouseMoveEventToSubframe(mev, newSubframe, hovered Node); |
| 1025 } else { | 787 } else { |
| 1026 if (scrollbar && !m_mousePressed) | 788 if (scrollbar && !m_mouseEventManager->mousePressed()) |
| 1027 scrollbar->mouseMoved(mev.event()); // Handle hover effects on platf orms that support visual feedback on scrollbar hovering. | 789 scrollbar->mouseMoved(mev.event()); // Handle hover effects on platf orms that support visual feedback on scrollbar hovering. |
| 1028 if (FrameView* view = m_frame->view()) { | 790 if (FrameView* view = m_frame->view()) { |
| 1029 OptionalCursor optionalCursor = selectCursor(mev.hitTestResult()); | 791 OptionalCursor optionalCursor = selectCursor(mev.hitTestResult()); |
| 1030 if (optionalCursor.isCursorChange()) { | 792 if (optionalCursor.isCursorChange()) { |
| 1031 view->setCursor(optionalCursor.cursor()); | 793 view->setCursor(optionalCursor.cursor()); |
| 1032 } | 794 } |
| 1033 } | 795 } |
| 1034 } | 796 } |
| 1035 | 797 |
| 1036 m_lastMouseMoveEventSubframe = newSubframe; | 798 m_lastMouseMoveEventSubframe = newSubframe; |
| 1037 | 799 |
| 1038 if (eventResult != WebInputEventResult::NotHandled) | 800 if (eventResult != WebInputEventResult::NotHandled) |
| 1039 return eventResult; | 801 return eventResult; |
| 1040 | 802 |
| 1041 eventResult = updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove , mev.innerNode(), 0, mev.event()); | 803 eventResult = updatePointerTargetAndDispatchEvents(EventTypeNames::mousemove , mev.innerNode(), mev.event()); |
| 1042 if (eventResult != WebInputEventResult::NotHandled) | 804 if (eventResult != WebInputEventResult::NotHandled) |
| 1043 return eventResult; | 805 return eventResult; |
| 1044 | 806 |
| 1045 return handleMouseDraggedEvent(mev); | 807 return m_mouseEventManager->handleMouseDraggedEvent(mev); |
| 1046 } | |
| 1047 | |
| 1048 void EventHandler::invalidateClick() | |
| 1049 { | |
| 1050 m_clickCount = 0; | |
| 1051 m_clickNode = nullptr; | |
| 1052 } | |
| 1053 | |
| 1054 ContainerNode* EventHandler::parentForClickEvent(const Node& node) | |
| 1055 { | |
| 1056 // IE doesn't dispatch click events for mousedown/mouseup events across form | |
| 1057 // controls. | |
| 1058 if (node.isHTMLElement() && toHTMLElement(node).isInteractiveContent()) | |
| 1059 return nullptr; | |
| 1060 | |
| 1061 return FlatTreeTraversal::parent(node); | |
| 1062 } | 808 } |
| 1063 | 809 |
| 1064 WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve nt& mouseEvent) | 810 WebInputEventResult EventHandler::handleMouseReleaseEvent(const PlatformMouseEve nt& mouseEvent) |
| 1065 { | 811 { |
| 1066 TRACE_EVENT0("blink", "EventHandler::handleMouseReleaseEvent"); | 812 TRACE_EVENT0("blink", "EventHandler::handleMouseReleaseEvent"); |
| 1067 | 813 |
| 1068 // For 4th/5th button in the mouse since Chrome does not yet send | 814 // For 4th/5th button in the mouse since Chrome does not yet send |
| 1069 // button value to Blink but in some cases it does send the event. | 815 // button value to Blink but in some cases it does send the event. |
| 1070 // This check is needed to suppress such an event (crbug.com/574959) | 816 // This check is needed to suppress such an event (crbug.com/574959) |
| 1071 if (mouseEvent.pointerProperties().button == WebPointerProperties::Button::N oButton) | 817 if (mouseEvent.pointerProperties().button == WebPointerProperties::Button::N oButton) |
| 1072 return WebInputEventResult::HandledSuppressed; | 818 return WebInputEventResult::HandledSuppressed; |
| 1073 | 819 |
| 1074 if (!mouseEvent.fromTouch()) | 820 if (!mouseEvent.fromTouch()) |
| 1075 m_frame->selection().setCaretBlinkingSuspended(false); | 821 m_frame->selection().setCaretBlinkingSuspended(false); |
| 1076 | 822 |
| 1077 std::unique_ptr<UserGestureIndicator> gestureIndicator; | 823 std::unique_ptr<UserGestureIndicator> gestureIndicator; |
| 1078 | 824 |
| 1079 if (m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToke n) | 825 if (m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToke n) |
| 1080 gestureIndicator = wrapUnique(new UserGestureIndicator(m_frame->localFra meRoot()->eventHandler().m_lastMouseDownUserGestureToken.release())); | 826 gestureIndicator = wrapUnique(new UserGestureIndicator(m_frame->localFra meRoot()->eventHandler().m_lastMouseDownUserGestureToken.release())); |
| 1081 else | 827 else |
| 1082 gestureIndicator = wrapUnique(new UserGestureIndicator(DefinitelyProcess ingUserGesture)); | 828 gestureIndicator = wrapUnique(new UserGestureIndicator(DefinitelyProcess ingUserGesture)); |
| 1083 | 829 |
| 1084 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { | 830 if (RuntimeEnabledFeatures::middleClickAutoscrollEnabled()) { |
| 1085 if (Page* page = m_frame->page()) | 831 if (Page* page = m_frame->page()) |
| 1086 page->autoscrollController().handleMouseReleaseForMiddleClickAutoscr oll(m_frame, mouseEvent); | 832 page->autoscrollController().handleMouseReleaseForMiddleClickAutoscr oll(m_frame, mouseEvent); |
| 1087 } | 833 } |
| 1088 | 834 |
| 1089 m_mousePressed = false; | 835 m_mouseEventManager->setMousePressed(false); |
| 1090 setLastKnownMousePosition(mouseEvent); | 836 m_mouseEventManager->setLastKnownMousePosition(mouseEvent); |
| 1091 | 837 m_mouseEventManager->handleSvgPanIfNeeded(true); |
| 1092 if (m_svgPan) { | |
| 1093 m_svgPan = false; | |
| 1094 m_frame->document()->accessSVGExtensions().updatePan(m_frame->view()->ro otFrameToContents(m_lastKnownMousePosition)); | |
| 1095 return WebInputEventResult::HandledSuppressed; | |
| 1096 } | |
| 1097 | 838 |
| 1098 if (m_frameSetBeingResized) | 839 if (m_frameSetBeingResized) |
| 1099 return dispatchMouseEvent(EventTypeNames::mouseup, m_frameSetBeingResize d.get(), m_clickCount, mouseEvent); | 840 return m_mouseEventManager->setMousePositionAndDispatchMouseEvent(update MouseEventTargetNode(m_frameSetBeingResized.get()), EventTypeNames::mouseup, mou seEvent); |
| 1100 | 841 |
| 1101 if (m_lastScrollbarUnderMouse) { | 842 if (m_lastScrollbarUnderMouse) { |
| 1102 invalidateClick(); | 843 m_mouseEventManager->invalidateClick(); |
| 1103 m_lastScrollbarUnderMouse->mouseUp(mouseEvent); | 844 m_lastScrollbarUnderMouse->mouseUp(mouseEvent); |
| 1104 return updatePointerTargetAndDispatchEvents(EventTypeNames::mouseup, m_n odeUnderMouse.get(), m_clickCount, mouseEvent); | 845 return updatePointerTargetAndDispatchEvents(EventTypeNames::mouseup, m_m ouseEventManager->getNodeUnderMouse(), mouseEvent); |
| 1105 } | 846 } |
| 1106 | 847 |
| 1107 // Mouse events simulated from touch should not hit-test again. | 848 // Mouse events simulated from touch should not hit-test again. |
| 1108 ASSERT(!mouseEvent.fromTouch()); | 849 ASSERT(!mouseEvent.fromTouch()); |
| 1109 | 850 |
| 1110 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release; | 851 HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release; |
| 1111 HitTestRequest request(hitType); | 852 HitTestRequest request(hitType); |
| 1112 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent); | 853 MouseEventWithHitTestResults mev = EventHandlingUtil::performMouseEventHitTe st(m_frame, request, mouseEvent); |
| 1113 LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetN ode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); | 854 LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetN ode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev); |
| 1114 if (m_eventHandlerWillResetCapturingMouseEventsNode) | 855 if (m_eventHandlerWillResetCapturingMouseEventsNode) |
| 1115 m_capturingMouseEventsNode = nullptr; | 856 m_capturingMouseEventsNode = nullptr; |
| 1116 if (subframe) | 857 if (subframe) |
| 1117 return passMouseReleaseEventToSubframe(mev, subframe); | 858 return passMouseReleaseEventToSubframe(mev, subframe); |
| 1118 | 859 |
| 1119 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mouseup, mev.innerNode(), m_clickCount, mev.event()); | 860 WebInputEventResult eventResult = updatePointerTargetAndDispatchEvents(Event TypeNames::mouseup, mev.innerNode(), mev.event()); |
| 1120 | 861 |
| 1121 // We only prevent click event when the click may cause contextmenu to popup . | 862 WebInputEventResult clickEventResult = m_mouseEventManager->dispatchMouseCli ckIfNeeded(mev); |
| 1122 // However, we always send auxclick. | |
| 1123 bool contextMenuEvent = !RuntimeEnabledFeatures::auxclickEnabled() | |
| 1124 && mouseEvent.pointerProperties().button == WebPointerProperties::Button ::Right; | |
| 1125 #if OS(MACOSX) | |
| 1126 // FIXME: The Mac port achieves the same behavior by checking whether the co ntext menu is currently open in WebPage::mouseEvent(). Consider merging the impl ementations. | |
| 1127 if (mouseEvent.pointerProperties().button == WebPointerProperties::Button::L eft | |
| 1128 && mouseEvent.getModifiers() & PlatformEvent::CtrlKey) | |
| 1129 contextMenuEvent = true; | |
| 1130 #endif | |
| 1131 | |
| 1132 WebInputEventResult clickEventResult = WebInputEventResult::NotHandled; | |
| 1133 const bool shouldDispatchClickEvent = m_clickCount > 0 | |
| 1134 && !contextMenuEvent | |
| 1135 && mev.innerNode() && m_clickNode | |
| 1136 && mev.innerNode()->canParticipateInFlatTree() && m_clickNode->canPartic ipateInFlatTree() | |
| 1137 && !(selectionController().hasExtendedSelection() && isLinkSelection(mev )); | |
| 1138 if (shouldDispatchClickEvent) { | |
| 1139 Node* clickTargetNode = nullptr; | |
| 1140 // Updates distribution because a 'mouseup' event listener can make the | |
| 1141 // tree dirty at dispatchMouseEvent() invocation above. | |
| 1142 // Unless distribution is updated, commonAncestor would hit ASSERT. | |
| 1143 if (m_clickNode == mev.innerNode()) { | |
| 1144 clickTargetNode = m_clickNode; | |
| 1145 clickTargetNode->updateDistribution(); | |
| 1146 } else if (m_clickNode->document() == mev.innerNode()->document()) { | |
| 1147 m_clickNode->updateDistribution(); | |
| 1148 mev.innerNode()->updateDistribution(); | |
| 1149 clickTargetNode = mev.innerNode()->commonAncestor( | |
| 1150 *m_clickNode, parentForClickEvent); | |
| 1151 } | |
| 1152 if (clickTargetNode) { | |
| 1153 // Dispatch mouseup directly w/o calling updateMouseEventTargetNodeA ndSendEvents | |
| 1154 // because the mouseup dispatch above has already updated it | |
| 1155 // correctly. Moreover, clickTargetNode is different from | |
| 1156 // mev.innerNode at drag-release. | |
| 1157 clickEventResult = EventHandlingUtil::toWebInputEventResult( | |
| 1158 clickTargetNode->dispatchMouseEvent(mev.event(), | |
| 1159 !RuntimeEnabledFeatures::auxclickEnabled() | |
| 1160 || (mev.event().pointerProperties().button == WebPointerProp erties::Button::Left) | |
| 1161 ? EventTypeNames::click | |
| 1162 : EventTypeNames::auxclick, | |
| 1163 m_clickCount)); | |
| 1164 } | |
| 1165 } | |
| 1166 | |
| 1167 m_scrollManager->clearResizeScrollableArea(false); | 863 m_scrollManager->clearResizeScrollableArea(false); |
| 1168 | 864 |
| 1169 if (eventResult == WebInputEventResult::NotHandled) | 865 if (eventResult == WebInputEventResult::NotHandled) |
| 1170 eventResult = handleMouseReleaseEvent(mev); | 866 eventResult = m_mouseEventManager->handleMouseReleaseEvent(mev); |
| 1171 clearDragHeuristicState(); | 867 m_mouseEventManager->clearDragHeuristicState(); |
| 1172 | 868 |
| 1173 invalidateClick(); | 869 m_mouseEventManager->invalidateClick(); |
| 1174 | 870 |
| 1175 return EventHandlingUtil::mergeEventResult(clickEventResult, eventResult); | 871 return EventHandlingUtil::mergeEventResult(clickEventResult, eventResult); |
| 1176 } | 872 } |
| 1177 | 873 |
| 1178 WebInputEventResult EventHandler::dispatchDragEvent(const AtomicString& eventTyp e, Node* dragTarget, const PlatformMouseEvent& event, DataTransfer* dataTransfer ) | |
| 1179 { | |
| 1180 FrameView* view = m_frame->view(); | |
| 1181 | |
| 1182 // FIXME: We might want to dispatch a dragleave even if the view is gone. | |
| 1183 if (!view) | |
| 1184 return WebInputEventResult::NotHandled; | |
| 1185 | |
| 1186 DragEvent* me = DragEvent::create(eventType, | |
| 1187 true, true, m_frame->document()->domWindow(), | |
| 1188 0, event.globalPosition().x(), event.globalPosition().y(), event.positio n().x(), event.position().y(), | |
| 1189 event.movementDelta().x(), event.movementDelta().y(), | |
| 1190 event.getModifiers(), | |
| 1191 0, MouseEvent::platformModifiersToButtons(event.getModifiers()), nullptr , event.timestamp(), dataTransfer, event.getSyntheticEventType()); | |
| 1192 | |
| 1193 return EventHandlingUtil::toWebInputEventResult(dragTarget->dispatchEvent(me )); | |
| 1194 } | |
| 1195 | |
| 1196 static bool targetIsFrame(Node* target, LocalFrame*& frame) | 874 static bool targetIsFrame(Node* target, LocalFrame*& frame) |
| 1197 { | 875 { |
| 1198 if (!isHTMLFrameElementBase(target)) | 876 if (!isHTMLFrameElementBase(target)) |
| 1199 return false; | 877 return false; |
| 1200 | 878 |
| 1201 // Cross-process drag and drop is not yet supported. | 879 // Cross-process drag and drop is not yet supported. |
| 1202 if (toHTMLFrameElementBase(target)->contentFrame() && !toHTMLFrameElementBas e(target)->contentFrame()->isLocalFrame()) | 880 if (toHTMLFrameElementBase(target)->contentFrame() && !toHTMLFrameElementBas e(target)->contentFrame()->isLocalFrame()) |
| 1203 return false; | 881 return false; |
| 1204 | 882 |
| 1205 frame = toLocalFrame(toHTMLFrameElementBase(target)->contentFrame()); | 883 frame = toLocalFrame(toHTMLFrameElementBase(target)->contentFrame()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1246 } | 924 } |
| 1247 | 925 |
| 1248 WebInputEventResult EventHandler::updateDragAndDrop(const PlatformMouseEvent& ev ent, DataTransfer* dataTransfer) | 926 WebInputEventResult EventHandler::updateDragAndDrop(const PlatformMouseEvent& ev ent, DataTransfer* dataTransfer) |
| 1249 { | 927 { |
| 1250 WebInputEventResult eventResult = WebInputEventResult::NotHandled; | 928 WebInputEventResult eventResult = WebInputEventResult::NotHandled; |
| 1251 | 929 |
| 1252 if (!m_frame->view()) | 930 if (!m_frame->view()) |
| 1253 return eventResult; | 931 return eventResult; |
| 1254 | 932 |
| 1255 HitTestRequest request(HitTestRequest::ReadOnly); | 933 HitTestRequest request(HitTestRequest::ReadOnly); |
| 1256 MouseEventWithHitTestResults mev = prepareMouseEvent(request, event); | 934 MouseEventWithHitTestResults mev = EventHandlingUtil::performMouseEventHitTe st(m_frame, request, event); |
| 1257 | 935 |
| 1258 // Drag events should never go to text nodes (following IE, and proper mouse over/out dispatch) | 936 // Drag events should never go to text nodes (following IE, and proper mouse over/out dispatch) |
| 1259 Node* newTarget = mev.innerNode(); | 937 Node* newTarget = mev.innerNode(); |
| 1260 if (newTarget && newTarget->isTextNode()) | 938 if (newTarget && newTarget->isTextNode()) |
| 1261 newTarget = FlatTreeTraversal::parent(*newTarget); | 939 newTarget = FlatTreeTraversal::parent(*newTarget); |
| 1262 | 940 |
| 1263 if (AutoscrollController* controller = m_scrollManager->autoscrollController ()) | 941 if (AutoscrollController* controller = m_scrollManager->autoscrollController ()) |
| 1264 controller->updateDragAndDrop(newTarget, event.position(), event.timesta mp()); | 942 controller->updateDragAndDrop(newTarget, event.position(), event.timesta mp()); |
| 1265 | 943 |
| 1266 if (m_dragTarget != newTarget) { | 944 if (m_dragTarget != newTarget) { |
| 1267 // FIXME: this ordering was explicitly chosen to match WinIE. However, | 945 // FIXME: this ordering was explicitly chosen to match WinIE. However, |
| 1268 // it is sometimes incorrect when dragging within subframes, as seen wit h | 946 // it is sometimes incorrect when dragging within subframes, as seen wit h |
| 1269 // LayoutTests/fast/events/drag-in-frames.html. | 947 // LayoutTests/fast/events/drag-in-frames.html. |
| 1270 // | 948 // |
| 1271 // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. | 949 // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>. |
| 1272 LocalFrame* targetFrame; | 950 LocalFrame* targetFrame; |
| 1273 if (targetIsFrame(newTarget, targetFrame)) { | 951 if (targetIsFrame(newTarget, targetFrame)) { |
| 1274 if (targetFrame) | 952 if (targetFrame) |
| 1275 eventResult = targetFrame->eventHandler().updateDragAndDrop(even t, dataTransfer); | 953 eventResult = targetFrame->eventHandler().updateDragAndDrop(even t, dataTransfer); |
| 1276 } else if (newTarget) { | 954 } else if (newTarget) { |
| 1277 // As per section 7.9.4 of the HTML 5 spec., we must always fire a d rag event before firing a dragenter, dragleave, or dragover event. | 955 // As per section 7.9.4 of the HTML 5 spec., we must always fire a d rag event before firing a dragenter, dragleave, or dragover event. |
| 1278 if (dragState().m_dragSrc) { | 956 if (m_mouseEventManager->dragState().m_dragSrc) { |
| 1279 // for now we don't care if event handler cancels default behavi or, since there is none | 957 // for now we don't care if event handler cancels default behavi or, since there is none |
| 1280 dispatchDragSrcEvent(EventTypeNames::drag, event); | 958 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
| 1281 } | 959 } |
| 1282 eventResult = dispatchDragEvent(EventTypeNames::dragenter, newTarget , event, dataTransfer); | 960 eventResult = m_mouseEventManager->dispatchDragEvent(EventTypeNames: :dragenter, newTarget, event, dataTransfer); |
| 1283 if (eventResult == WebInputEventResult::NotHandled && findDropZone(n ewTarget, dataTransfer)) | 961 if (eventResult == WebInputEventResult::NotHandled && findDropZone(n ewTarget, dataTransfer)) |
| 1284 eventResult = WebInputEventResult::HandledSystem; | 962 eventResult = WebInputEventResult::HandledSystem; |
| 1285 } | 963 } |
| 1286 | 964 |
| 1287 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 965 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
| 1288 if (targetFrame) | 966 if (targetFrame) |
| 1289 eventResult = targetFrame->eventHandler().updateDragAndDrop(even t, dataTransfer); | 967 eventResult = targetFrame->eventHandler().updateDragAndDrop(even t, dataTransfer); |
| 1290 } else if (m_dragTarget) { | 968 } else if (m_dragTarget) { |
| 1291 dispatchDragEvent(EventTypeNames::dragleave, m_dragTarget.get(), eve nt, dataTransfer); | 969 m_mouseEventManager->dispatchDragEvent(EventTypeNames::dragleave, m_ dragTarget.get(), event, dataTransfer); |
| 1292 } | 970 } |
| 1293 | 971 |
| 1294 if (newTarget) { | 972 if (newTarget) { |
| 1295 // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that | 973 // We do not explicitly call m_mouseEventManager->dispatchDragEvent here because it could ultimately result in the appearance that |
| 1296 // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function. | 974 // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function. |
| 1297 m_shouldOnlyFireDragOverEvent = true; | 975 m_shouldOnlyFireDragOverEvent = true; |
| 1298 } | 976 } |
| 1299 } else { | 977 } else { |
| 1300 LocalFrame* targetFrame; | 978 LocalFrame* targetFrame; |
| 1301 if (targetIsFrame(newTarget, targetFrame)) { | 979 if (targetIsFrame(newTarget, targetFrame)) { |
| 1302 if (targetFrame) | 980 if (targetFrame) |
| 1303 eventResult = targetFrame->eventHandler().updateDragAndDrop(even t, dataTransfer); | 981 eventResult = targetFrame->eventHandler().updateDragAndDrop(even t, dataTransfer); |
| 1304 } else if (newTarget) { | 982 } else if (newTarget) { |
| 1305 // Note, when dealing with sub-frames, we may need to fire only a dr agover event as a drag event may have been fired earlier. | 983 // Note, when dealing with sub-frames, we may need to fire only a dr agover event as a drag event may have been fired earlier. |
| 1306 if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc) { | 984 if (!m_shouldOnlyFireDragOverEvent && m_mouseEventManager->dragState ().m_dragSrc) { |
| 1307 // for now we don't care if event handler cancels default behavi or, since there is none | 985 // for now we don't care if event handler cancels default behavi or, since there is none |
| 1308 dispatchDragSrcEvent(EventTypeNames::drag, event); | 986 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, event); |
| 1309 } | 987 } |
| 1310 eventResult = dispatchDragEvent(EventTypeNames::dragover, newTarget, event, dataTransfer); | 988 eventResult = m_mouseEventManager->dispatchDragEvent(EventTypeNames: :dragover, newTarget, event, dataTransfer); |
| 1311 if (eventResult == WebInputEventResult::NotHandled && findDropZone(n ewTarget, dataTransfer)) | 989 if (eventResult == WebInputEventResult::NotHandled && findDropZone(n ewTarget, dataTransfer)) |
| 1312 eventResult = WebInputEventResult::HandledSystem; | 990 eventResult = WebInputEventResult::HandledSystem; |
| 1313 m_shouldOnlyFireDragOverEvent = false; | 991 m_shouldOnlyFireDragOverEvent = false; |
| 1314 } | 992 } |
| 1315 } | 993 } |
| 1316 m_dragTarget = newTarget; | 994 m_dragTarget = newTarget; |
| 1317 | 995 |
| 1318 return eventResult; | 996 return eventResult; |
| 1319 } | 997 } |
| 1320 | 998 |
| 1321 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, DataTransf er* dataTransfer) | 999 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, DataTransf er* dataTransfer) |
| 1322 { | 1000 { |
| 1323 LocalFrame* targetFrame; | 1001 LocalFrame* targetFrame; |
| 1324 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 1002 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
| 1325 if (targetFrame) | 1003 if (targetFrame) |
| 1326 targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer); | 1004 targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer); |
| 1327 } else if (m_dragTarget.get()) { | 1005 } else if (m_dragTarget.get()) { |
| 1328 if (dragState().m_dragSrc) | 1006 if (m_mouseEventManager->dragState().m_dragSrc) |
| 1329 dispatchDragSrcEvent(EventTypeNames::drag, event); | 1007 m_mouseEventManager->dispatchDragSrcEvent(EventTypeNames::drag, even t); |
| 1330 dispatchDragEvent(EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer); | 1008 m_mouseEventManager->dispatchDragEvent(EventTypeNames::dragleave, m_drag Target.get(), event, dataTransfer); |
| 1331 } | 1009 } |
| 1332 clearDragState(); | 1010 clearDragState(); |
| 1333 } | 1011 } |
| 1334 | 1012 |
| 1335 WebInputEventResult EventHandler::performDragAndDrop(const PlatformMouseEvent& e vent, DataTransfer* dataTransfer) | 1013 WebInputEventResult EventHandler::performDragAndDrop(const PlatformMouseEvent& e vent, DataTransfer* dataTransfer) |
| 1336 { | 1014 { |
| 1337 LocalFrame* targetFrame; | 1015 LocalFrame* targetFrame; |
| 1338 WebInputEventResult result = WebInputEventResult::NotHandled; | 1016 WebInputEventResult result = WebInputEventResult::NotHandled; |
| 1339 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { | 1017 if (targetIsFrame(m_dragTarget.get(), targetFrame)) { |
| 1340 if (targetFrame) | 1018 if (targetFrame) |
| 1341 result = targetFrame->eventHandler().performDragAndDrop(event, dataT ransfer); | 1019 result = targetFrame->eventHandler().performDragAndDrop(event, dataT ransfer); |
| 1342 } else if (m_dragTarget.get()) { | 1020 } else if (m_dragTarget.get()) { |
| 1343 result = dispatchDragEvent(EventTypeNames::drop, m_dragTarget.get(), eve nt, dataTransfer); | 1021 result = m_mouseEventManager->dispatchDragEvent(EventTypeNames::drop, m_ dragTarget.get(), event, dataTransfer); |
| 1344 } | 1022 } |
| 1345 clearDragState(); | 1023 clearDragState(); |
| 1346 return result; | 1024 return result; |
| 1347 } | 1025 } |
| 1348 | 1026 |
| 1349 void EventHandler::clearDragHeuristicState() | |
| 1350 { | |
| 1351 // Used to prevent mouseMoveEvent from initiating a drag before | |
| 1352 // the mouse is pressed again. | |
| 1353 m_mousePressed = false; | |
| 1354 m_capturesDragging = false; | |
| 1355 m_mouseDownMayStartDrag = false; | |
| 1356 m_mouseDownMayStartAutoscroll = false; | |
| 1357 } | |
| 1358 | |
| 1359 void EventHandler::clearDragState() | 1027 void EventHandler::clearDragState() |
| 1360 { | 1028 { |
| 1361 m_scrollManager->stopAutoscroll(); | 1029 m_scrollManager->stopAutoscroll(); |
| 1362 m_dragTarget = nullptr; | 1030 m_dragTarget = nullptr; |
| 1363 m_capturingMouseEventsNode = nullptr; | 1031 m_capturingMouseEventsNode = nullptr; |
| 1364 m_shouldOnlyFireDragOverEvent = false; | 1032 m_shouldOnlyFireDragOverEvent = false; |
| 1365 } | 1033 } |
| 1366 | 1034 |
| 1367 void EventHandler::setCapturingMouseEventsNode(Node* n) | 1035 void EventHandler::setCapturingMouseEventsNode(Node* n) |
| 1368 { | 1036 { |
| 1369 m_capturingMouseEventsNode = n; | 1037 m_capturingMouseEventsNode = n; |
| 1370 m_eventHandlerWillResetCapturingMouseEventsNode = false; | 1038 m_eventHandlerWillResetCapturingMouseEventsNode = false; |
| 1371 } | 1039 } |
| 1372 | 1040 |
| 1373 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestReques t& request, const PlatformMouseEvent& mev) | 1041 Node* EventHandler::updateMouseEventTargetNode(Node* targetNode) |
| 1374 { | |
| 1375 ASSERT(m_frame); | |
| 1376 ASSERT(m_frame->document()); | |
| 1377 | |
| 1378 return m_frame->document()->prepareMouseEvent(request, contentPointFromRootF rame(m_frame, mev.position()), mev); | |
| 1379 } | |
| 1380 | |
| 1381 Node* EventHandler::updateMouseEventTargetNode(Node* targetNode, | |
| 1382 const PlatformMouseEvent& mouseEvent) | |
| 1383 { | 1042 { |
| 1384 Node* newNodeUnderMouse = targetNode; | 1043 Node* newNodeUnderMouse = targetNode; |
| 1385 | 1044 |
| 1386 // If we're capturing, we always go right to that node. | 1045 // If we're capturing, we always go right to that node. |
| 1387 EventTarget* mousePointerCapturingNode = m_pointerEventManager->getMouseCapt uringNode(); | 1046 EventTarget* mousePointerCapturingNode = m_pointerEventManager->getMouseCapt uringNode(); |
| 1388 if (mousePointerCapturingNode | 1047 if (mousePointerCapturingNode |
| 1389 && !RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { | 1048 && !RuntimeEnabledFeatures::pointerEventV1SpecCapturingEnabled()) { |
| 1390 newNodeUnderMouse = mousePointerCapturingNode->toNode(); | 1049 newNodeUnderMouse = mousePointerCapturingNode->toNode(); |
| 1391 DCHECK(newNodeUnderMouse); | 1050 DCHECK(newNodeUnderMouse); |
| 1392 } else if (m_capturingMouseEventsNode) { | 1051 } else if (m_capturingMouseEventsNode) { |
| 1393 newNodeUnderMouse = m_capturingMouseEventsNode.get(); | 1052 newNodeUnderMouse = m_capturingMouseEventsNode.get(); |
| 1394 } else { | 1053 } else { |
| 1395 // If the target node is a text node, dispatch on the parent node - rdar ://4196646 | 1054 // If the target node is a text node, dispatch on the parent node - rdar ://4196646 |
| 1396 if (newNodeUnderMouse && newNodeUnderMouse->isTextNode()) | 1055 if (newNodeUnderMouse && newNodeUnderMouse->isTextNode()) |
| 1397 newNodeUnderMouse = FlatTreeTraversal::parent(*newNodeUnderMouse); | 1056 newNodeUnderMouse = FlatTreeTraversal::parent(*newNodeUnderMouse); |
| 1398 } | 1057 } |
| 1399 Node* lastNodeUnderMouse = m_nodeUnderMouse; | 1058 return newNodeUnderMouse; |
| 1400 m_nodeUnderMouse = newNodeUnderMouse; | |
| 1401 | |
| 1402 PaintLayer* layerForLastNode = layerForNode(lastNodeUnderMouse); | |
| 1403 PaintLayer* layerForNodeUnderMouse = layerForNode(m_nodeUnderMouse.get()); | |
| 1404 Page* page = m_frame->page(); | |
| 1405 | |
| 1406 if (lastNodeUnderMouse && (!m_nodeUnderMouse || m_nodeUnderMouse->document() != m_frame->document())) { | |
| 1407 // The mouse has moved between frames. | |
| 1408 if (LocalFrame* frame = lastNodeUnderMouse->document().frame()) { | |
| 1409 if (FrameView* frameView = frame->view()) | |
| 1410 frameView->mouseExitedContentArea(); | |
| 1411 } | |
| 1412 } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerFor NodeUnderMouse != layerForLastNode))) { | |
| 1413 // The mouse has moved between layers. | |
| 1414 if (ScrollableArea* scrollableAreaForLastNode = associatedScrollableArea (layerForLastNode)) | |
| 1415 scrollableAreaForLastNode->mouseExitedContentArea(); | |
| 1416 } | |
| 1417 | |
| 1418 if (m_nodeUnderMouse && (!lastNodeUnderMouse || lastNodeUnderMouse->document () != m_frame->document())) { | |
| 1419 // The mouse has moved between frames. | |
| 1420 if (LocalFrame* frame = m_nodeUnderMouse->document().frame()) { | |
| 1421 if (FrameView* frameView = frame->view()) | |
| 1422 frameView->mouseEnteredContentArea(); | |
| 1423 } | |
| 1424 } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerFor NodeUnderMouse != layerForLastNode))) { | |
| 1425 // The mouse has moved between layers. | |
| 1426 if (ScrollableArea* scrollableAreaForNodeUnderMouse = associatedScrollab leArea(layerForNodeUnderMouse)) | |
| 1427 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea(); | |
| 1428 } | |
| 1429 | |
| 1430 if (lastNodeUnderMouse && lastNodeUnderMouse->document() != m_frame->documen t()) { | |
| 1431 lastNodeUnderMouse = nullptr; | |
| 1432 m_lastScrollbarUnderMouse = nullptr; | |
| 1433 } | |
| 1434 | |
| 1435 return lastNodeUnderMouse; | |
| 1436 } | |
| 1437 | |
| 1438 void EventHandler::updateMouseEventTargetNodeAndSendEvents(Node* targetNode, | |
| 1439 const PlatformMouseEvent& mouseEvent, bool isFrameBoundaryTransition) | |
| 1440 { | |
| 1441 Node* lastNodeUnderMouse = updateMouseEventTargetNode(targetNode, mouseEvent ); | |
| 1442 m_pointerEventManager->sendMouseAndPossiblyPointerBoundaryEvents( | |
| 1443 lastNodeUnderMouse, m_nodeUnderMouse, mouseEvent, | |
| 1444 isFrameBoundaryTransition); | |
| 1445 } | |
| 1446 | |
| 1447 WebInputEventResult EventHandler::dispatchMouseEvent(const AtomicString& eventTy pe, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent) | |
| 1448 { | |
| 1449 updateMouseEventTargetNodeAndSendEvents(targetNode, mouseEvent); | |
| 1450 | |
| 1451 return m_mouseEventManager->dispatchMouseEvent(m_nodeUnderMouse, eventType, | |
| 1452 mouseEvent, nullptr, clickCount); | |
| 1453 } | 1059 } |
| 1454 | 1060 |
| 1455 bool EventHandler::isPointerEventActive(int pointerId) | 1061 bool EventHandler::isPointerEventActive(int pointerId) |
| 1456 { | 1062 { |
| 1457 return m_pointerEventManager->isActive(pointerId); | 1063 return m_pointerEventManager->isActive(pointerId); |
| 1458 } | 1064 } |
| 1459 | 1065 |
| 1460 void EventHandler::setPointerCapture(int pointerId, EventTarget* target) | 1066 void EventHandler::setPointerCapture(int pointerId, EventTarget* target) |
| 1461 { | 1067 { |
| 1462 // TODO(crbug.com/591387): This functionality should be per page not per fra me. | 1068 // TODO(crbug.com/591387): This functionality should be per page not per fra me. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1476 bool EventHandler::hasProcessedPointerCapture(int pointerId, const EventTarget* target) const | 1082 bool EventHandler::hasProcessedPointerCapture(int pointerId, const EventTarget* target) const |
| 1477 { | 1083 { |
| 1478 return m_pointerEventManager->hasProcessedPointerCapture(pointerId, target); | 1084 return m_pointerEventManager->hasProcessedPointerCapture(pointerId, target); |
| 1479 } | 1085 } |
| 1480 | 1086 |
| 1481 void EventHandler::elementRemoved(EventTarget* target) | 1087 void EventHandler::elementRemoved(EventTarget* target) |
| 1482 { | 1088 { |
| 1483 m_pointerEventManager->elementRemoved(target); | 1089 m_pointerEventManager->elementRemoved(target); |
| 1484 } | 1090 } |
| 1485 | 1091 |
| 1486 // TODO(mustaq): Make PE drive ME dispatch & bookkeeping in EventHandler. | 1092 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato micString& mouseEventType, Node* targetNode, const PlatformMouseEvent& mouseEven t) |
| 1487 WebInputEventResult EventHandler::updatePointerTargetAndDispatchEvents(const Ato micString& mouseEventType, Node* targetNode, int clickCount, const PlatformMouse Event& mouseEvent) | |
| 1488 { | 1093 { |
| 1489 ASSERT(mouseEventType == EventTypeNames::mousedown | 1094 ASSERT(mouseEventType == EventTypeNames::mousedown |
| 1490 || mouseEventType == EventTypeNames::mousemove | 1095 || mouseEventType == EventTypeNames::mousemove |
| 1491 || mouseEventType == EventTypeNames::mouseup); | 1096 || mouseEventType == EventTypeNames::mouseup); |
| 1492 | 1097 |
| 1493 Node* lastNodeUnderMouse = updateMouseEventTargetNode(targetNode, mouseEvent ); | |
| 1494 | |
| 1495 Node* newNodeUnderMouse = nullptr; | |
| 1496 const auto& eventResult = m_pointerEventManager->sendMousePointerEvent( | 1098 const auto& eventResult = m_pointerEventManager->sendMousePointerEvent( |
| 1497 m_nodeUnderMouse, mouseEventType, clickCount, mouseEvent, | 1099 updateMouseEventTargetNode(targetNode), mouseEventType, mouseEvent); |
| 1498 lastNodeUnderMouse, &newNodeUnderMouse); | |
| 1499 m_nodeUnderMouse = newNodeUnderMouse; | |
| 1500 return eventResult; | 1100 return eventResult; |
| 1501 } | 1101 } |
| 1502 | 1102 |
| 1503 void EventHandler::setClickNode(Node* node) | |
| 1504 { | |
| 1505 m_clickNode = node; | |
| 1506 } | |
| 1507 | |
| 1508 WebInputEventResult EventHandler::handleMouseFocus(const HitTestResult& hitTestR esult, InputDeviceCapabilities* sourceCapabilities) | |
| 1509 { | |
| 1510 // If clicking on a frame scrollbar, do not mess up with content focus. | |
| 1511 if (hitTestResult.scrollbar() && !m_frame->contentLayoutItem().isNull()) { | |
| 1512 if (hitTestResult.scrollbar()->getScrollableArea() == m_frame->contentLa youtItem().getScrollableArea()) | |
| 1513 return WebInputEventResult::NotHandled; | |
| 1514 } | |
| 1515 | |
| 1516 // The layout needs to be up to date to determine if an element is focusable . | |
| 1517 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 1518 | |
| 1519 Element* element = nullptr; | |
| 1520 if (m_nodeUnderMouse) | |
| 1521 element = m_nodeUnderMouse->isElementNode() ? toElement(m_nodeUnderMouse ) : m_nodeUnderMouse->parentOrShadowHostElement(); | |
| 1522 for (; element; element = element->parentOrShadowHostElement()) { | |
| 1523 if (element->isFocusable() && element->isFocusedElementInDocument()) | |
| 1524 return WebInputEventResult::NotHandled; | |
| 1525 if (element->isMouseFocusable()) | |
| 1526 break; | |
| 1527 } | |
| 1528 ASSERT(!element || element->isMouseFocusable()); | |
| 1529 | |
| 1530 // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus | |
| 1531 // a node on mouse down if it's selected and inside a focused node. It will | |
| 1532 // be focused if the user does a mouseup over it, however, because the | |
| 1533 // mouseup will set a selection inside it, which will call | |
| 1534 // FrameSelection::setFocusedNodeIfNeeded. | |
| 1535 if (element && m_frame->selection().isRange()) { | |
| 1536 // TODO(yosin) We should not create |Range| object for calling | |
| 1537 // |isNodeFullyContained()|. | |
| 1538 if (createRange(m_frame->selection().selection().toNormalizedEphemeralRa nge())->isNodeFullyContained(*element) | |
| 1539 && element->isDescendantOf(m_frame->document()->focusedElement())) | |
| 1540 return WebInputEventResult::NotHandled; | |
| 1541 } | |
| 1542 | |
| 1543 | |
| 1544 // Only change the focus when clicking scrollbars if it can transfered to a | |
| 1545 // mouse focusable node. | |
| 1546 if (!element && hitTestResult.scrollbar()) | |
| 1547 return WebInputEventResult::HandledSystem; | |
| 1548 | |
| 1549 if (Page* page = m_frame->page()) { | |
| 1550 // If focus shift is blocked, we eat the event. Note we should never | |
| 1551 // clear swallowEvent if the page already set it (e.g., by canceling | |
| 1552 // default behavior). | |
| 1553 if (element) { | |
| 1554 if (slideFocusOnShadowHostIfNecessary(*element)) | |
| 1555 return WebInputEventResult::HandledSystem; | |
| 1556 if (!page->focusController().setFocusedElement(element, m_frame, Foc usParams(SelectionBehaviorOnFocus::None, WebFocusTypeMouse, sourceCapabilities)) ) | |
| 1557 return WebInputEventResult::HandledSystem; | |
| 1558 } else { | |
| 1559 // We call setFocusedElement even with !element in order to blur | |
| 1560 // current focus element when a link is clicked; this is expected by | |
| 1561 // some sites that rely on onChange handlers running from form | |
| 1562 // fields before the button click is processed. | |
| 1563 if (!page->focusController().setFocusedElement(nullptr, m_frame, Foc usParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, sourceCapabilities))) | |
| 1564 return WebInputEventResult::HandledSystem; | |
| 1565 } | |
| 1566 } | |
| 1567 | |
| 1568 return WebInputEventResult::NotHandled; | |
| 1569 } | |
| 1570 | |
| 1571 bool EventHandler::slideFocusOnShadowHostIfNecessary(const Element& element) | |
| 1572 { | |
| 1573 if (element.authorShadowRoot() && element.authorShadowRoot()->delegatesFocus ()) { | |
| 1574 Document* doc = m_frame->document(); | |
| 1575 if (element.isShadowIncludingInclusiveAncestorOf(doc->focusedElement())) { | |
| 1576 // If the inner element is already focused, do nothing. | |
| 1577 return true; | |
| 1578 } | |
| 1579 | |
| 1580 // If the host has a focusable inner element, focus it. Otherwise, the h ost takes focus. | |
| 1581 Page* page = m_frame->page(); | |
| 1582 ASSERT(page); | |
| 1583 Element* found = page->focusController().findFocusableElementInShadowHos t(element); | |
| 1584 if (found && element.isShadowIncludingInclusiveAncestorOf(found)) { | |
| 1585 // Use WebFocusTypeForward instead of WebFocusTypeMouse here to mean the focus has slided. | |
| 1586 found->focus(FocusParams(SelectionBehaviorOnFocus::Reset, WebFocusTy peForward, nullptr)); | |
| 1587 return true; | |
| 1588 } | |
| 1589 } | |
| 1590 return false; | |
| 1591 } | |
| 1592 | |
| 1593 WebInputEventResult EventHandler::handleWheelEvent(const PlatformWheelEvent& eve nt) | 1103 WebInputEventResult EventHandler::handleWheelEvent(const PlatformWheelEvent& eve nt) |
| 1594 { | 1104 { |
| 1595 #if OS(MACOSX) | 1105 #if OS(MACOSX) |
| 1596 // Filter Mac OS specific phases, usually with a zero-delta. | 1106 // Filter Mac OS specific phases, usually with a zero-delta. |
| 1597 // https://crbug.com/553732 | 1107 // https://crbug.com/553732 |
| 1598 // TODO(chongz): EventSender sends events with |PlatformWheelEventPhaseNone| , but it shouldn't. | 1108 // TODO(chongz): EventSender sends events with |PlatformWheelEventPhaseNone| , but it shouldn't. |
| 1599 const int kPlatformWheelEventPhaseNoEventMask = PlatformWheelEventPhaseEnded | PlatformWheelEventPhaseCancelled | PlatformWheelEventPhaseMayBegin; | 1109 const int kPlatformWheelEventPhaseNoEventMask = PlatformWheelEventPhaseEnded | PlatformWheelEventPhaseCancelled | PlatformWheelEventPhaseMayBegin; |
| 1600 if ((event.phase() & kPlatformWheelEventPhaseNoEventMask) || (event.momentum Phase() & kPlatformWheelEventPhaseNoEventMask)) | 1110 if ((event.phase() & kPlatformWheelEventPhaseNoEventMask) || (event.momentum Phase() & kPlatformWheelEventPhaseNoEventMask)) |
| 1601 return WebInputEventResult::NotHandled; | 1111 return WebInputEventResult::NotHandled; |
| 1602 #endif | 1112 #endif |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1697 WebInputEventResult EventHandler::handleGestureScrollEnd(const PlatformGestureEv ent& gestureEvent) | 1207 WebInputEventResult EventHandler::handleGestureScrollEnd(const PlatformGestureEv ent& gestureEvent) |
| 1698 { | 1208 { |
| 1699 return m_scrollManager->handleGestureScrollEnd(gestureEvent); | 1209 return m_scrollManager->handleGestureScrollEnd(gestureEvent); |
| 1700 } | 1210 } |
| 1701 | 1211 |
| 1702 bool EventHandler::isScrollbarHandlingGestures() const | 1212 bool EventHandler::isScrollbarHandlingGestures() const |
| 1703 { | 1213 { |
| 1704 return m_scrollManager->isScrollbarHandlingGestures(); | 1214 return m_scrollManager->isScrollbarHandlingGestures(); |
| 1705 } | 1215 } |
| 1706 | 1216 |
| 1217 void EventHandler::setMouseDownMayStartAutoscroll() | |
| 1218 { | |
| 1219 m_mouseEventManager->setMouseDownMayStartAutoscroll(); | |
| 1220 } | |
| 1221 | |
| 1707 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const | 1222 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const |
| 1708 { | 1223 { |
| 1709 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) | 1224 if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled()) |
| 1710 return false; | 1225 return false; |
| 1711 return !event.area().isEmpty(); | 1226 return !event.area().isEmpty(); |
| 1712 } | 1227 } |
| 1713 | 1228 |
| 1714 bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result , IntPoint& targetPoint, Node*& targetNode) | 1229 bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result , IntPoint& targetPoint, Node*& targetNode) |
| 1715 { | 1230 { |
| 1716 // FIXME: Unify this with the other best* functions which are very similar. | 1231 // FIXME: Unify this with the other best* functions which are very similar. |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1839 enteredFrameChain.append(enteredFrameInDocument); | 1354 enteredFrameChain.append(enteredFrameInDocument); |
| 1840 Frame* parentFrame = enteredFrameInDocument->tree().parent(); | 1355 Frame* parentFrame = enteredFrameInDocument->tree().parent(); |
| 1841 enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() ? to LocalFrame(parentFrame) : nullptr; | 1356 enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() ? to LocalFrame(parentFrame) : nullptr; |
| 1842 } | 1357 } |
| 1843 | 1358 |
| 1844 size_t indexEnteredFrameChain = enteredFrameChain.size(); | 1359 size_t indexEnteredFrameChain = enteredFrameChain.size(); |
| 1845 LocalFrame* exitedFrameInDocument = m_frame; | 1360 LocalFrame* exitedFrameInDocument = m_frame; |
| 1846 HeapVector<Member<LocalFrame>> exitedFrameChain; | 1361 HeapVector<Member<LocalFrame>> exitedFrameChain; |
| 1847 // Insert the frame from the disagreement between last frames and entered fr ames | 1362 // Insert the frame from the disagreement between last frames and entered fr ames |
| 1848 while (exitedFrameInDocument) { | 1363 while (exitedFrameInDocument) { |
| 1849 Node* lastNodeUnderTap = exitedFrameInDocument->eventHandler().m_nodeUnd erMouse.get(); | 1364 Node* lastNodeUnderTap = exitedFrameInDocument->eventHandler().m_mouseEv entManager->getNodeUnderMouse(); |
| 1850 if (!lastNodeUnderTap) | 1365 if (!lastNodeUnderTap) |
| 1851 break; | 1366 break; |
| 1852 | 1367 |
| 1853 LocalFrame* nextExitedFrameInDocument = nullptr; | 1368 LocalFrame* nextExitedFrameInDocument = nullptr; |
| 1854 if (lastNodeUnderTap->isFrameOwnerElement()) { | 1369 if (lastNodeUnderTap->isFrameOwnerElement()) { |
| 1855 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnder Tap); | 1370 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnder Tap); |
| 1856 if (owner->contentFrame() && owner->contentFrame()->isLocalFrame()) | 1371 if (owner->contentFrame() && owner->contentFrame()->isLocalFrame()) |
| 1857 nextExitedFrameInDocument = toLocalFrame(owner->contentFrame()); | 1372 nextExitedFrameInDocument = toLocalFrame(owner->contentFrame()); |
| 1858 } | 1373 } |
| 1859 | 1374 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1873 unsigned modifiers = gestureEvent.getModifiers(); | 1388 unsigned modifiers = gestureEvent.getModifiers(); |
| 1874 PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.globa lPosition(), | 1389 PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.globa lPosition(), |
| 1875 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, /* cl ickCount */ 0, | 1390 WebPointerProperties::Button::NoButton, PlatformEvent::MouseMoved, /* cl ickCount */ 0, |
| 1876 static_cast<PlatformEvent::Modifiers>(modifiers), | 1391 static_cast<PlatformEvent::Modifiers>(modifiers), |
| 1877 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerPrope rties::PointerType::Mouse); | 1392 PlatformMouseEvent::FromTouch, gestureEvent.timestamp(), WebPointerPrope rties::PointerType::Mouse); |
| 1878 | 1393 |
| 1879 // Update the mouseout/mouseleave event | 1394 // Update the mouseout/mouseleave event |
| 1880 size_t indexExitedFrameChain = exitedFrameChain.size(); | 1395 size_t indexExitedFrameChain = exitedFrameChain.size(); |
| 1881 while (indexExitedFrameChain) { | 1396 while (indexExitedFrameChain) { |
| 1882 LocalFrame* leaveFrame = exitedFrameChain[--indexExitedFrameChain]; | 1397 LocalFrame* leaveFrame = exitedFrameChain[--indexExitedFrameChain]; |
| 1883 leaveFrame->eventHandler().updateMouseEventTargetNodeAndSendEvents(nullp tr, fakeMouseMove); | 1398 leaveFrame->eventHandler().m_mouseEventManager->setNodeUnderMouse(update MouseEventTargetNode(nullptr), fakeMouseMove); |
| 1884 } | 1399 } |
| 1885 | 1400 |
| 1886 // update the mouseover/mouseenter event | 1401 // update the mouseover/mouseenter event |
| 1887 while (indexEnteredFrameChain) { | 1402 while (indexEnteredFrameChain) { |
| 1888 Frame* parentFrame = enteredFrameChain[--indexEnteredFrameChain]->tree() .parent(); | 1403 Frame* parentFrame = enteredFrameChain[--indexEnteredFrameChain]->tree() .parent(); |
| 1889 if (parentFrame && parentFrame->isLocalFrame()) | 1404 if (parentFrame && parentFrame->isLocalFrame()) |
| 1890 toLocalFrame(parentFrame)->eventHandler().updateMouseEventTargetNode AndSendEvents(toHTMLFrameOwnerElement(enteredFrameChain[indexEnteredFrameChain]- >owner()), fakeMouseMove); | 1405 toLocalFrame(parentFrame)->eventHandler().m_mouseEventManager->setNo deUnderMouse(updateMouseEventTargetNode(toHTMLFrameOwnerElement(enteredFrameChai n[indexEnteredFrameChain]->owner())), fakeMouseMove); |
| 1891 } | 1406 } |
| 1892 } | 1407 } |
| 1893 | 1408 |
| 1894 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe stureEvent& gestureEvent, bool readOnly) | 1409 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGe stureEvent& gestureEvent, bool readOnly) |
| 1895 { | 1410 { |
| 1896 TRACE_EVENT0("input", "EventHandler::targetGestureEvent"); | 1411 TRACE_EVENT0("input", "EventHandler::targetGestureEvent"); |
| 1897 | 1412 |
| 1898 ASSERT(m_frame == m_frame->localFrameRoot()); | 1413 ASSERT(m_frame == m_frame->localFrameRoot()); |
| 1899 // Scrolling events get hit tested per frame (like wheel events do). | 1414 // Scrolling events get hit tested per frame (like wheel events do). |
| 1900 ASSERT(!gestureEvent.isScrollEvent()); | 1415 ASSERT(!gestureEvent.isScrollEvent()); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1999 } | 1514 } |
| 2000 } | 1515 } |
| 2001 | 1516 |
| 2002 WebInputEventResult EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event, Node* overrideTargetNode) | 1517 WebInputEventResult EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event, Node* overrideTargetNode) |
| 2003 { | 1518 { |
| 2004 FrameView* v = m_frame->view(); | 1519 FrameView* v = m_frame->view(); |
| 2005 if (!v) | 1520 if (!v) |
| 2006 return WebInputEventResult::NotHandled; | 1521 return WebInputEventResult::NotHandled; |
| 2007 | 1522 |
| 2008 // Clear mouse press state to avoid initiating a drag while context menu is up. | 1523 // Clear mouse press state to avoid initiating a drag while context menu is up. |
| 2009 m_mousePressed = false; | 1524 m_mouseEventManager->setMousePressed(false); |
| 2010 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); | 1525 LayoutPoint positionInContents = v->rootFrameToContents(event.position()); |
| 2011 HitTestRequest request(HitTestRequest::Active); | 1526 HitTestRequest request(HitTestRequest::Active); |
| 2012 MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(re quest, positionInContents, event); | 1527 MouseEventWithHitTestResults mev = m_frame->document()->performMouseEventHit Test(request, positionInContents, event); |
| 2013 // Since |Document::prepareMouseEvent()| modifies layout tree for setting | 1528 // Since |Document::performMouseEventHitTest| modifies layout tree for setti ng |
| 2014 // hover element, we need to update layout tree for requirement of | 1529 // hover element, we need to update layout tree for requirement of |
| 2015 // |SelectionController::sendContextMenuEvent()|. | 1530 // |SelectionController::sendContextMenuEvent()|. |
| 2016 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); | 1531 m_frame->document()->updateStyleAndLayoutIgnorePendingStylesheets(); |
| 2017 | 1532 |
| 2018 selectionController().sendContextMenuEvent(mev, positionInContents); | 1533 selectionController().sendContextMenuEvent(mev, positionInContents); |
| 2019 | 1534 |
| 2020 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ; | 1535 Node* targetNode = overrideTargetNode ? overrideTargetNode : mev.innerNode() ; |
| 2021 return dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, 0, event) ; | 1536 return m_mouseEventManager->dispatchMouseEvent(updateMouseEventTargetNode(ta rgetNode), EventTypeNames::contextmenu, event, 0); |
| 2022 } | 1537 } |
| 2023 | 1538 |
| 2024 WebInputEventResult EventHandler::sendContextMenuEventForKey(Element* overrideTa rgetElement) | 1539 WebInputEventResult EventHandler::sendContextMenuEventForKey(Element* overrideTa rgetElement) |
| 2025 { | 1540 { |
| 2026 FrameView* view = m_frame->view(); | 1541 FrameView* view = m_frame->view(); |
| 2027 if (!view) | 1542 if (!view) |
| 2028 return WebInputEventResult::NotHandled; | 1543 return WebInputEventResult::NotHandled; |
| 2029 | 1544 |
| 2030 Document* doc = m_frame->document(); | 1545 Document* doc = m_frame->document(); |
| 2031 if (!doc) | 1546 if (!doc) |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2107 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, BLINK_FROM_HERE); | 1622 m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, BLINK_FROM_HERE); |
| 2108 } | 1623 } |
| 2109 | 1624 |
| 2110 bool EventHandler::cursorUpdatePending() | 1625 bool EventHandler::cursorUpdatePending() |
| 2111 { | 1626 { |
| 2112 return m_cursorUpdateTimer.isActive(); | 1627 return m_cursorUpdateTimer.isActive(); |
| 2113 } | 1628 } |
| 2114 | 1629 |
| 2115 void EventHandler::dispatchFakeMouseMoveEventSoon() | 1630 void EventHandler::dispatchFakeMouseMoveEventSoon() |
| 2116 { | 1631 { |
| 2117 if (m_mousePressed) | 1632 m_mouseEventManager->dispatchFakeMouseMoveEventSoon(); |
| 2118 return; | |
| 2119 | |
| 2120 if (m_mousePositionIsUnknown) | |
| 2121 return; | |
| 2122 | |
| 2123 Settings* settings = m_frame->settings(); | |
| 2124 if (settings && !settings->deviceSupportsMouse()) | |
| 2125 return; | |
| 2126 | |
| 2127 // Reschedule the timer, to prevent dispatching mouse move events | |
| 2128 // during a scroll. This avoids a potential source of scroll jank. | |
| 2129 if (m_fakeMouseMoveEventTimer.isActive()) | |
| 2130 m_fakeMouseMoveEventTimer.stop(); | |
| 2131 m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveInterval, BLINK_FROM_HER E); | |
| 2132 } | 1633 } |
| 2133 | 1634 |
| 2134 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad) | 1635 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad) |
| 2135 { | 1636 { |
| 2136 FrameView* view = m_frame->view(); | 1637 m_mouseEventManager->dispatchFakeMouseMoveEventSoonInQuad(quad); |
| 2137 if (!view) | |
| 2138 return; | |
| 2139 | |
| 2140 if (!quad.containsPoint(view->rootFrameToContents(m_lastKnownMousePosition)) ) | |
| 2141 return; | |
| 2142 | |
| 2143 dispatchFakeMouseMoveEventSoon(); | |
| 2144 } | |
| 2145 | |
| 2146 void EventHandler::fakeMouseMoveEventTimerFired(TimerBase* timer) | |
| 2147 { | |
| 2148 TRACE_EVENT0("input", "EventHandler::fakeMouseMoveEventTimerFired"); | |
| 2149 ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer); | |
| 2150 ASSERT(!m_mousePressed); | |
| 2151 | |
| 2152 Settings* settings = m_frame->settings(); | |
| 2153 if (settings && !settings->deviceSupportsMouse()) | |
| 2154 return; | |
| 2155 | |
| 2156 FrameView* view = m_frame->view(); | |
| 2157 if (!view) | |
| 2158 return; | |
| 2159 | |
| 2160 if (!m_frame->page() || !m_frame->page()->focusController().isActive()) | |
| 2161 return; | |
| 2162 | |
| 2163 // Don't dispatch a synthetic mouse move event if the mouse cursor is not vi sible to the user. | |
| 2164 if (!isCursorVisible()) | |
| 2165 return; | |
| 2166 | |
| 2167 PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownM ouseGlobalPosition, WebPointerProperties::Button::NoButton, PlatformEvent::Mouse Moved, 0, static_cast<PlatformEvent::Modifiers>(KeyboardEventManager::getCurrent ModifierState()), PlatformMouseEvent::RealOrIndistinguishable, monotonicallyIncr easingTime(), WebPointerProperties::PointerType::Mouse); | |
| 2168 handleMouseMoveEvent(fakeMouseMoveEvent); | |
| 2169 } | |
| 2170 | |
| 2171 void EventHandler::cancelFakeMouseMoveEvent() | |
| 2172 { | |
| 2173 m_fakeMouseMoveEventTimer.stop(); | |
| 2174 } | |
| 2175 | |
| 2176 bool EventHandler::isCursorVisible() const | |
| 2177 { | |
| 2178 return m_frame->page()->isCursorVisible(); | |
| 2179 } | 1638 } |
| 2180 | 1639 |
| 2181 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet) | 1640 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet) |
| 2182 { | 1641 { |
| 2183 m_frameSetBeingResized = frameSet; | 1642 m_frameSetBeingResized = frameSet; |
| 2184 } | 1643 } |
| 2185 | 1644 |
| 2186 void EventHandler::resizeScrollableAreaDestroyed() | 1645 void EventHandler::resizeScrollableAreaDestroyed() |
| 2187 { | 1646 { |
| 2188 m_scrollManager->clearResizeScrollableArea(true); | 1647 m_scrollManager->clearResizeScrollableArea(true); |
| 2189 } | 1648 } |
| 2190 | 1649 |
| 2191 void EventHandler::hoverTimerFired(TimerBase*) | 1650 void EventHandler::hoverTimerFired(TimerBase*) |
| 2192 { | 1651 { |
| 2193 TRACE_EVENT0("input", "EventHandler::hoverTimerFired"); | 1652 TRACE_EVENT0("input", "EventHandler::hoverTimerFired"); |
| 2194 m_hoverTimer.stop(); | 1653 m_hoverTimer.stop(); |
| 2195 | 1654 |
| 2196 ASSERT(m_frame); | 1655 ASSERT(m_frame); |
| 2197 ASSERT(m_frame->document()); | 1656 ASSERT(m_frame->document()); |
| 2198 | 1657 |
| 2199 if (LayoutViewItem layoutItem = m_frame->contentLayoutItem()) { | 1658 if (LayoutViewItem layoutItem = m_frame->contentLayoutItem()) { |
| 2200 if (FrameView* view = m_frame->view()) { | 1659 if (FrameView* view = m_frame->view()) { |
| 2201 HitTestRequest request(HitTestRequest::Move); | 1660 HitTestRequest request(HitTestRequest::Move); |
| 2202 HitTestResult result(request, view->rootFrameToContents(m_lastKnownM ousePosition)); | 1661 HitTestResult result(request, view->rootFrameToContents(m_mouseEvent Manager->lastKnownMousePosition())); |
| 2203 layoutItem.hitTest(result); | 1662 layoutItem.hitTest(result); |
| 2204 m_frame->document()->updateHoverActiveState(request, result.innerEle ment()); | 1663 m_frame->document()->updateHoverActiveState(request, result.innerEle ment()); |
| 2205 } | 1664 } |
| 2206 } | 1665 } |
| 2207 } | 1666 } |
| 2208 | 1667 |
| 2209 void EventHandler::activeIntervalTimerFired(TimerBase*) | 1668 void EventHandler::activeIntervalTimerFired(TimerBase*) |
| 2210 { | 1669 { |
| 2211 TRACE_EVENT0("input", "EventHandler::activeIntervalTimerFired"); | 1670 TRACE_EVENT0("input", "EventHandler::activeIntervalTimerFired"); |
| 2212 m_activeIntervalTimer.stop(); | 1671 m_activeIntervalTimer.stop(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 2235 return m_keyboardEventManager->handleAccessKey(evt); | 1694 return m_keyboardEventManager->handleAccessKey(evt); |
| 2236 } | 1695 } |
| 2237 | 1696 |
| 2238 WebInputEventResult EventHandler::keyEvent(const WebKeyboardEvent& initialKeyEve nt) | 1697 WebInputEventResult EventHandler::keyEvent(const WebKeyboardEvent& initialKeyEve nt) |
| 2239 { | 1698 { |
| 2240 return m_keyboardEventManager->keyEvent(initialKeyEvent); | 1699 return m_keyboardEventManager->keyEvent(initialKeyEvent); |
| 2241 } | 1700 } |
| 2242 | 1701 |
| 2243 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) | 1702 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event) |
| 2244 { | 1703 { |
| 2245 m_keyboardEventManager->defaultKeyboardEventHandler(event, m_mousePressNode) ; | 1704 m_keyboardEventManager->defaultKeyboardEventHandler(event, m_mouseEventManag er->mousePressNode()); |
| 2246 } | |
| 2247 | |
| 2248 bool EventHandler::dragHysteresisExceeded(const IntPoint& dragLocationInRootFram e) const | |
| 2249 { | |
| 2250 FrameView* view = m_frame->view(); | |
| 2251 if (!view) | |
| 2252 return false; | |
| 2253 IntPoint dragLocation = view->rootFrameToContents(dragLocationInRootFrame); | |
| 2254 IntSize delta = dragLocation - m_mouseDownPos; | |
| 2255 | |
| 2256 int threshold = GeneralDragHysteresis; | |
| 2257 switch (dragState().m_dragType) { | |
| 2258 case DragSourceActionSelection: | |
| 2259 threshold = TextDragHysteresis; | |
| 2260 break; | |
| 2261 case DragSourceActionImage: | |
| 2262 threshold = ImageDragHysteresis; | |
| 2263 break; | |
| 2264 case DragSourceActionLink: | |
| 2265 threshold = LinkDragHysteresis; | |
| 2266 break; | |
| 2267 case DragSourceActionDHTML: | |
| 2268 break; | |
| 2269 case DragSourceActionNone: | |
| 2270 ASSERT_NOT_REACHED(); | |
| 2271 } | |
| 2272 | |
| 2273 return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold; | |
| 2274 } | |
| 2275 | |
| 2276 void EventHandler::clearDragDataTransfer() | |
| 2277 { | |
| 2278 if (dragState().m_dragDataTransfer) { | |
| 2279 dragState().m_dragDataTransfer->clearDragImage(); | |
| 2280 dragState().m_dragDataTransfer->setAccessPolicy(DataTransferNumb); | |
| 2281 } | |
| 2282 } | 1705 } |
| 2283 | 1706 |
| 2284 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat ion operation) | 1707 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat ion operation) |
| 2285 { | 1708 { |
| 2286 // Send a hit test request so that Layer gets a chance to update the :hover and :active pseudoclasses. | 1709 m_mouseEventManager->dragSourceEndedAt(event, operation); |
| 2287 HitTestRequest request(HitTestRequest::Release); | |
| 2288 prepareMouseEvent(request, event); | |
| 2289 | |
| 2290 if (dragState().m_dragSrc) { | |
| 2291 dragState().m_dragDataTransfer->setDestinationOperation(operation); | |
| 2292 // for now we don't care if event handler cancels default behavior, sinc e there is none | |
| 2293 dispatchDragSrcEvent(EventTypeNames::dragend, event); | |
| 2294 } | |
| 2295 clearDragDataTransfer(); | |
| 2296 dragState().m_dragSrc = nullptr; | |
| 2297 // In case the drag was ended due to an escape key press we need to ensure | |
| 2298 // that consecutive mousemove events don't reinitiate the drag and drop. | |
| 2299 m_mouseDownMayStartDrag = false; | |
| 2300 } | 1710 } |
| 2301 | 1711 |
| 2302 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableEle ment) | 1712 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableEle ment) |
| 2303 { | 1713 { |
| 2304 // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element. | 1714 // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element. |
| 2305 if (dragState().m_dragSrc && !dragState().m_dragSrc->isConnected()) | 1715 if (m_mouseEventManager->dragState().m_dragSrc && !m_mouseEventManager->drag State().m_dragSrc->isConnected()) |
| 2306 dragState().m_dragSrc = rootEditableElement; | 1716 m_mouseEventManager->dragState().m_dragSrc = rootEditableElement; |
| 2307 } | |
| 2308 | |
| 2309 // returns if we should continue "default processing", i.e., whether eventhandle r canceled | |
| 2310 WebInputEventResult EventHandler::dispatchDragSrcEvent(const AtomicString& event Type, const PlatformMouseEvent& event) | |
| 2311 { | |
| 2312 return dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, drag State().m_dragDataTransfer.get()); | |
| 2313 } | |
| 2314 | |
| 2315 bool EventHandler::handleDragDropIfPossible(const GestureEventWithHitTestResults & targetedEvent) | |
| 2316 { | |
| 2317 if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_ frame->view()) { | |
| 2318 const PlatformGestureEvent& gestureEvent = targetedEvent.event(); | |
| 2319 IntPoint adjustedPoint = gestureEvent.position(); | |
| 2320 unsigned modifiers = gestureEvent.getModifiers(); | |
| 2321 | |
| 2322 // TODO(mustaq): Suppressing long-tap MouseEvents could break | |
| 2323 // drag-drop. Will do separately because of the risk. crbug.com/606938. | |
| 2324 PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosi tion(), WebPointerProperties::Button::Left, PlatformEvent::MousePressed, 1, | |
| 2325 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::Lef tButtonDown), | |
| 2326 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), W ebPointerProperties::PointerType::Mouse); | |
| 2327 m_mouseDown = mouseDownEvent; | |
| 2328 | |
| 2329 PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosi tion(), WebPointerProperties::Button::Left, PlatformEvent::MouseMoved, 1, | |
| 2330 static_cast<PlatformEvent::Modifiers>(modifiers | PlatformEvent::Lef tButtonDown), | |
| 2331 PlatformMouseEvent::FromTouch, WTF::monotonicallyIncreasingTime(), W ebPointerProperties::PointerType::Mouse); | |
| 2332 HitTestRequest request(HitTestRequest::ReadOnly); | |
| 2333 MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragE vent); | |
| 2334 m_mouseDownMayStartDrag = true; | |
| 2335 dragState().m_dragSrc = nullptr; | |
| 2336 m_mouseDownPos = m_frame->view()->rootFrameToContents(mouseDragEvent.pos ition()); | |
| 2337 return handleDrag(mev, DragInitiator::Touch); | |
| 2338 } | |
| 2339 return false; | |
| 2340 } | |
| 2341 | |
| 2342 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, DragIni tiator initiator) | |
| 2343 { | |
| 2344 ASSERT(event.event().type() == PlatformEvent::MouseMoved); | |
| 2345 // Callers must protect the reference to FrameView, since this function may dispatch DOM | |
| 2346 // events, causing page/FrameView to go away. | |
| 2347 ASSERT(m_frame); | |
| 2348 ASSERT(m_frame->view()); | |
| 2349 if (!m_frame->page()) | |
| 2350 return false; | |
| 2351 | |
| 2352 if (m_mouseDownMayStartDrag) { | |
| 2353 HitTestRequest request(HitTestRequest::ReadOnly); | |
| 2354 HitTestResult result(request, m_mouseDownPos); | |
| 2355 m_frame->contentLayoutItem().hitTest(result); | |
| 2356 Node* node = result.innerNode(); | |
| 2357 if (node) { | |
| 2358 DragController::SelectionDragPolicy selectionDragPolicy = event.even t().timestamp() - m_mouseDownTimestamp < TextDragDelay | |
| 2359 ? DragController::DelayedSelectionDragResolution | |
| 2360 : DragController::ImmediateSelectionDragResolution; | |
| 2361 dragState().m_dragSrc = m_frame->page()->dragController().draggableN ode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType); | |
| 2362 } else { | |
| 2363 dragState().m_dragSrc = nullptr; | |
| 2364 } | |
| 2365 | |
| 2366 if (!dragState().m_dragSrc) | |
| 2367 m_mouseDownMayStartDrag = false; // no element is draggable | |
| 2368 } | |
| 2369 | |
| 2370 if (!m_mouseDownMayStartDrag) | |
| 2371 return initiator == DragInitiator::Mouse && !selectionController().mouse DownMayStartSelect() && !m_mouseDownMayStartAutoscroll; | |
| 2372 | |
| 2373 // We are starting a text/image/url drag, so the cursor should be an arrow | |
| 2374 // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and d rop (default to pointer). | |
| 2375 m_frame->view()->setCursor(pointerCursor()); | |
| 2376 | |
| 2377 if (initiator == DragInitiator::Mouse && !dragHysteresisExceeded(event.event ().position())) | |
| 2378 return true; | |
| 2379 | |
| 2380 // Once we're past the hysteresis point, we don't want to treat this gesture as a click | |
| 2381 invalidateClick(); | |
| 2382 | |
| 2383 if (!tryStartDrag(event)) { | |
| 2384 // Something failed to start the drag, clean up. | |
| 2385 clearDragDataTransfer(); | |
| 2386 dragState().m_dragSrc = nullptr; | |
| 2387 } | |
| 2388 | |
| 2389 m_mouseDownMayStartDrag = false; | |
| 2390 // Whether or not the drag actually started, no more default handling (like selection). | |
| 2391 return true; | |
| 2392 } | |
| 2393 | |
| 2394 bool EventHandler::tryStartDrag(const MouseEventWithHitTestResults& event) | |
| 2395 { | |
| 2396 // The DataTransfer would only be non-empty if we missed a dragEnd. | |
| 2397 // Clear it anyway, just to make sure it gets numbified. | |
| 2398 clearDragDataTransfer(); | |
| 2399 | |
| 2400 dragState().m_dragDataTransfer = createDraggingDataTransfer(); | |
| 2401 | |
| 2402 // Check to see if this a DOM based drag, if it is get the DOM specified dra g | |
| 2403 // image and offset | |
| 2404 if (dragState().m_dragType == DragSourceActionDHTML) { | |
| 2405 if (LayoutObject* layoutObject = dragState().m_dragSrc->layoutObject()) { | |
| 2406 IntRect boundingIncludingDescendants = layoutObject->absoluteBoundin gBoxRectIncludingDescendants(); | |
| 2407 IntSize delta = m_mouseDownPos - boundingIncludingDescendants.locati on(); | |
| 2408 dragState().m_dragDataTransfer->setDragImageElement(dragState().m_dr agSrc.get(), IntPoint(delta)); | |
| 2409 } else { | |
| 2410 // The layoutObject has disappeared, this can happen if the onStartD rag handler has hidden | |
| 2411 // the element in some way. In this case we just kill the drag. | |
| 2412 return false; | |
| 2413 } | |
| 2414 } | |
| 2415 | |
| 2416 DragController& dragController = m_frame->page()->dragController(); | |
| 2417 if (!dragController.populateDragDataTransfer(m_frame, dragState(), m_mouseDo wnPos)) | |
| 2418 return false; | |
| 2419 | |
| 2420 // If dispatching dragstart brings about another mouse down -- one way | |
| 2421 // this will happen is if a DevTools user breaks within a dragstart | |
| 2422 // handler and then clicks on the suspended page -- the drag state is | |
| 2423 // reset. Hence, need to check if this particular drag operation can | |
| 2424 // continue even if dispatchEvent() indicates no (direct) cancellation. | |
| 2425 // Do that by checking if m_dragSrc is still set. | |
| 2426 m_mouseDownMayStartDrag = dispatchDragSrcEvent(EventTypeNames::dragstart, m_ mouseDown) == WebInputEventResult::NotHandled | |
| 2427 && !m_frame->selection().isInPasswordField() && dragState().m_dragSrc; | |
| 2428 | |
| 2429 // Invalidate clipboard here against anymore pasteboard writing for security . The drag | |
| 2430 // image can still be changed as we drag, but not the pasteboard data. | |
| 2431 dragState().m_dragDataTransfer->setAccessPolicy(DataTransferImageWritable); | |
| 2432 | |
| 2433 if (m_mouseDownMayStartDrag) { | |
| 2434 // Dispatching the event could cause Page to go away. Make sure it's sti ll valid before trying to use DragController. | |
| 2435 if (m_frame->page() && dragController.startDrag(m_frame, dragState(), ev ent.event(), m_mouseDownPos)) | |
| 2436 return true; | |
| 2437 // Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event | |
| 2438 dispatchDragSrcEvent(EventTypeNames::dragend, event.event()); | |
| 2439 } | |
| 2440 | |
| 2441 return false; | |
| 2442 } | 1717 } |
| 2443 | 1718 |
| 2444 bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve nt, TextEventInputType inputType) | 1719 bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve nt, TextEventInputType inputType) |
| 2445 { | 1720 { |
| 2446 // Platforms should differentiate real commands like selectAll from text inp ut in disguise (like insertNewline), | 1721 // Platforms should differentiate real commands like selectAll from text inp ut in disguise (like insertNewline), |
| 2447 // and avoid dispatching text input events from keydown default handlers. | 1722 // and avoid dispatching text input events from keydown default handlers. |
| 2448 ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || toKeyboard Event(underlyingEvent)->type() == EventTypeNames::keypress); | 1723 ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || toKeyboard Event(underlyingEvent)->type() == EventTypeNames::keypress); |
| 2449 | 1724 |
| 2450 if (!m_frame) | 1725 if (!m_frame) |
| 2451 return false; | 1726 return false; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2504 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; | 1779 m_lastScrollbarUnderMouse = setLast ? scrollbar : nullptr; |
| 2505 } | 1780 } |
| 2506 } | 1781 } |
| 2507 | 1782 |
| 2508 WebInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& eve nt) | 1783 WebInputEventResult EventHandler::handleTouchEvent(const PlatformTouchEvent& eve nt) |
| 2509 { | 1784 { |
| 2510 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); | 1785 TRACE_EVENT0("blink", "EventHandler::handleTouchEvent"); |
| 2511 return m_pointerEventManager->handleTouchEvents(event); | 1786 return m_pointerEventManager->handleTouchEvents(event); |
| 2512 } | 1787 } |
| 2513 | 1788 |
| 2514 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event) | |
| 2515 { | |
| 2516 m_mousePositionIsUnknown = false; | |
| 2517 m_lastKnownMousePosition = event.position(); | |
| 2518 m_lastKnownMouseGlobalPosition = event.globalPosition(); | |
| 2519 } | |
| 2520 | |
| 2521 WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHi tTestResults& mev, LocalFrame* subframe) | 1789 WebInputEventResult EventHandler::passMousePressEventToSubframe(MouseEventWithHi tTestResults& mev, LocalFrame* subframe) |
| 2522 { | 1790 { |
| 2523 selectionController().passMousePressEventToSubframe(mev); | 1791 selectionController().passMousePressEventToSubframe(mev); |
| 2524 WebInputEventResult result = subframe->eventHandler().handleMousePressEvent( mev.event()); | 1792 WebInputEventResult result = subframe->eventHandler().handleMousePressEvent( mev.event()); |
| 2525 if (result != WebInputEventResult::NotHandled) | 1793 if (result != WebInputEventResult::NotHandled) |
| 2526 return result; | 1794 return result; |
| 2527 return WebInputEventResult::HandledSystem; | 1795 return WebInputEventResult::HandledSystem; |
| 2528 } | 1796 } |
| 2529 | 1797 |
| 2530 WebInputEventResult EventHandler::passMouseMoveEventToSubframe(MouseEventWithHit TestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode) | 1798 WebInputEventResult EventHandler::passMouseMoveEventToSubframe(MouseEventWithHit TestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode) |
| 2531 { | 1799 { |
| 2532 if (m_mouseDownMayStartDrag) | 1800 if (m_mouseEventManager->mouseDownMayStartDrag()) |
| 2533 return WebInputEventResult::NotHandled; | 1801 return WebInputEventResult::NotHandled; |
| 2534 WebInputEventResult result = subframe->eventHandler().handleMouseMoveOrLeave Event(mev.event(), hoveredNode); | 1802 WebInputEventResult result = subframe->eventHandler().handleMouseMoveOrLeave Event(mev.event(), hoveredNode); |
| 2535 if (result != WebInputEventResult::NotHandled) | 1803 if (result != WebInputEventResult::NotHandled) |
| 2536 return result; | 1804 return result; |
| 2537 return WebInputEventResult::HandledSystem; | 1805 return WebInputEventResult::HandledSystem; |
| 2538 } | 1806 } |
| 2539 | 1807 |
| 2540 WebInputEventResult EventHandler::passMouseReleaseEventToSubframe(MouseEventWith HitTestResults& mev, LocalFrame* subframe) | 1808 WebInputEventResult EventHandler::passMouseReleaseEventToSubframe(MouseEventWith HitTestResults& mev, LocalFrame* subframe) |
| 2541 { | 1809 { |
| 2542 WebInputEventResult result = subframe->eventHandler().handleMouseReleaseEven t(mev.event()); | 1810 WebInputEventResult result = subframe->eventHandler().handleMouseReleaseEven t(mev.event()); |
| 2543 if (result != WebInputEventResult::NotHandled) | 1811 if (result != WebInputEventResult::NotHandled) |
| 2544 return result; | 1812 return result; |
| 2545 return WebInputEventResult::HandledSystem; | 1813 return WebInputEventResult::HandledSystem; |
| 2546 } | 1814 } |
| 2547 | 1815 |
| 2548 DataTransfer* EventHandler::createDraggingDataTransfer() const | |
| 2549 { | |
| 2550 return DataTransfer::create(DataTransfer::DragAndDrop, DataTransferWritable, DataObject::create()); | |
| 2551 } | |
| 2552 | |
| 2553 void EventHandler::focusDocumentView() | |
| 2554 { | |
| 2555 Page* page = m_frame->page(); | |
| 2556 if (!page) | |
| 2557 return; | |
| 2558 page->focusController().focusDocumentView(m_frame); | |
| 2559 } | |
| 2560 | |
| 2561 FrameHost* EventHandler::frameHost() const | 1816 FrameHost* EventHandler::frameHost() const |
| 2562 { | 1817 { |
| 2563 if (!m_frame->page()) | 1818 if (!m_frame->page()) |
| 2564 return nullptr; | 1819 return nullptr; |
| 2565 | 1820 |
| 2566 return &m_frame->page()->frameHost(); | 1821 return &m_frame->page()->frameHost(); |
| 2567 } | 1822 } |
| 2568 | 1823 |
| 2569 } // namespace blink | 1824 } // namespace blink |
| OLD | NEW |