dragenter and dragleave shouldn't use the same data transfer object
[WebKit-https.git] / Source / WebCore / page / EventHandler.cpp
1 /*
2  * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
4  * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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. 
26  */
27
28 #include "config.h"
29 #include "EventHandler.h"
30
31 #include "AutoscrollController.h"
32 #include "BackForwardController.h"
33 #include "CachedImage.h"
34 #include "Chrome.h"
35 #include "ChromeClient.h"
36 #include "CursorList.h"
37 #include "DocumentMarkerController.h"
38 #include "DragController.h"
39 #include "DragState.h"
40 #include "Editing.h"
41 #include "Editor.h"
42 #include "EditorClient.h"
43 #include "EventNames.h"
44 #include "FileList.h"
45 #include "FloatPoint.h"
46 #include "FloatRect.h"
47 #include "FocusController.h"
48 #include "FrameLoader.h"
49 #include "FrameSelection.h"
50 #include "FrameTree.h"
51 #include "FrameView.h"
52 #include "HTMLFrameElement.h"
53 #include "HTMLFrameSetElement.h"
54 #include "HTMLHtmlElement.h"
55 #include "HTMLIFrameElement.h"
56 #include "HTMLInputElement.h"
57 #include "HTMLNames.h"
58 #include "HitTestRequest.h"
59 #include "HitTestResult.h"
60 #include "Image.h"
61 #include "InspectorInstrumentation.h"
62 #include "KeyboardEvent.h"
63 #include "Logging.h"
64 #include "MainFrame.h"
65 #include "MouseEvent.h"
66 #include "MouseEventWithHitTestResults.h"
67 #include "Page.h"
68 #include "PageOverlayController.h"
69 #include "Pasteboard.h"
70 #include "PlatformEvent.h"
71 #include "PlatformKeyboardEvent.h"
72 #include "PlatformWheelEvent.h"
73 #include "PluginDocument.h"
74 #include "Range.h"
75 #include "RenderFrameSet.h"
76 #include "RenderLayer.h"
77 #include "RenderListBox.h"
78 #include "RenderTextControlSingleLine.h"
79 #include "RenderView.h"
80 #include "RenderWidget.h"
81 #include "RuntimeApplicationChecks.h"
82 #include "SVGDocument.h"
83 #include "SVGNames.h"
84 #include "ScrollLatchingState.h"
85 #include "Scrollbar.h"
86 #include "Settings.h"
87 #include "ShadowRoot.h"
88 #include "SpatialNavigation.h"
89 #include "StaticPasteboard.h"
90 #include "StyleCachedImage.h"
91 #include "TextEvent.h"
92 #include "TextIterator.h"
93 #include "UserGestureIndicator.h"
94 #include "UserTypingGestureIndicator.h"
95 #include "ValidationMessageClient.h"
96 #include "VisibleUnits.h"
97 #include "WheelEvent.h"
98 #include "WheelEventDeltaFilter.h"
99 #include "WindowsKeyboardCodes.h"
100 #include <wtf/Assertions.h>
101 #include <wtf/CurrentTime.h>
102 #include <wtf/NeverDestroyed.h>
103 #include <wtf/StdLibExtras.h>
104
105 #if ENABLE(IOS_TOUCH_EVENTS)
106 #include "PlatformTouchEventIOS.h"
107 #endif
108
109 #if ENABLE(TOUCH_EVENTS)
110 #include "TouchEvent.h"
111 #include "TouchList.h"
112 #endif
113
114 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
115 #include "PlatformTouchEvent.h"
116 #endif
117
118 #if ENABLE(MAC_GESTURE_EVENTS)
119 #include "PlatformGestureEventMac.h"
120 #endif
121
122 #if ENABLE(POINTER_LOCK)
123 #include "PointerLockController.h"
124 #endif
125
126 namespace WebCore {
127
128 using namespace HTMLNames;
129
130 #if ENABLE(DRAG_SUPPORT)
131 // The link drag hysteresis is much larger than the others because there
132 // needs to be enough space to cancel the link press without starting a link drag,
133 // and because dragging links is rare.
134 const int LinkDragHysteresis = 40;
135 const int ImageDragHysteresis = 5;
136 const int TextDragHysteresis = 3;
137 const int GeneralDragHysteresis = 3;
138 #if PLATFORM(COCOA)
139 const Seconds EventHandler::TextDragDelay { 150_ms };
140 #endif
141 #endif // ENABLE(DRAG_SUPPORT)
142
143 #if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
144 const float GestureUnknown = 0;
145 #endif
146
147 #if ENABLE(IOS_TOUCH_EVENTS)
148 // FIXME: Share this constant with EventHandler and SliderThumbElement.
149 const unsigned InvalidTouchIdentifier = 0;
150 #endif
151
152 // Match key code of composition keydown event on windows.
153 // IE sends VK_PROCESSKEY which has value 229;
154 const int CompositionEventKeyCode = 229;
155
156 using namespace SVGNames;
157
158 #if !ENABLE(IOS_TOUCH_EVENTS)
159 // The amount of time to wait before sending a fake mouse event, triggered
160 // during a scroll. The short interval is used if the content responds to the mouse events
161 // in fakeMouseMoveDurationThreshold or less, otherwise the long interval is used.
162 const double fakeMouseMoveDurationThreshold = 0.01;
163 const Seconds fakeMouseMoveShortInterval = { 100_ms };
164 const Seconds fakeMouseMoveLongInterval = { 250_ms };
165 #endif
166
167 #if ENABLE(CURSOR_SUPPORT)
168 // The amount of time to wait for a cursor update on style and layout changes
169 // Set to 50Hz, no need to be faster than common screen refresh rate
170 static const Seconds cursorUpdateInterval { 20_ms };
171
172 const int maximumCursorSize = 128;
173 #endif
174
175 #if ENABLE(MOUSE_CURSOR_SCALE)
176 // It's pretty unlikely that a scale of less than one would ever be used. But all we really
177 // need to ensure here is that the scale isn't so small that integer overflow can occur when
178 // dividing cursor sizes (limited above) by the scale.
179 const double minimumCursorScale = 0.001;
180 #endif
181
182 class MaximumDurationTracker {
183 public:
184     explicit MaximumDurationTracker(double *maxDuration)
185         : m_maxDuration(maxDuration)
186         , m_start(monotonicallyIncreasingTime())
187     {
188     }
189
190     ~MaximumDurationTracker()
191     {
192         *m_maxDuration = std::max(*m_maxDuration, monotonicallyIncreasingTime() - m_start);
193     }
194
195 private:
196     double* m_maxDuration;
197     double m_start;
198 };
199
200 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
201 class SyntheticTouchPoint : public PlatformTouchPoint {
202 public:
203
204     // The default values are based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
205     explicit SyntheticTouchPoint(const PlatformMouseEvent& event)
206     {
207         const static int idDefaultValue = 0;
208         const static int radiusYDefaultValue = 1;
209         const static int radiusXDefaultValue = 1;
210         const static float rotationAngleDefaultValue = 0.0f;
211         const static float forceDefaultValue = 1.0f;
212
213         m_id = idDefaultValue; // There is only one active TouchPoint.
214         m_screenPos = event.globalPosition();
215         m_pos = event.position();
216         m_radiusY = radiusYDefaultValue;
217         m_radiusX = radiusXDefaultValue;
218         m_rotationAngle = rotationAngleDefaultValue;
219         m_force = forceDefaultValue;
220
221         PlatformEvent::Type type = event.type();
222         ASSERT(type == PlatformEvent::MouseMoved || type == PlatformEvent::MousePressed || type == PlatformEvent::MouseReleased);
223
224         switch (type) {
225         case PlatformEvent::MouseMoved:
226             m_state = TouchMoved;
227             break;
228         case PlatformEvent::MousePressed:
229             m_state = TouchPressed;
230             break;
231         case PlatformEvent::MouseReleased:
232             m_state = TouchReleased;
233             break;
234         default:
235             ASSERT_NOT_REACHED();
236             break;
237         }
238     }
239 };
240
241 class SyntheticSingleTouchEvent : public PlatformTouchEvent {
242 public:
243     explicit SyntheticSingleTouchEvent(const PlatformMouseEvent& event)
244     {
245         switch (event.type()) {
246         case PlatformEvent::MouseMoved:
247             m_type = TouchMove;
248             break;
249         case PlatformEvent::MousePressed:
250             m_type = TouchStart;
251             break;
252         case PlatformEvent::MouseReleased:
253             m_type = TouchEnd;
254             break;
255         default:
256             ASSERT_NOT_REACHED();
257             m_type = NoType;
258             break;
259         }
260         m_timestamp = event.timestamp();
261         m_modifiers = event.modifiers();
262         m_touchPoints.append(SyntheticTouchPoint(event));
263     }
264 };
265 #endif // ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
266
267 static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned deltaMode)
268 {
269     switch (deltaMode) {
270     case WheelEvent::DOM_DELTA_PAGE:
271         return ScrollByPage;
272     case WheelEvent::DOM_DELTA_LINE:
273         return ScrollByLine;
274     case WheelEvent::DOM_DELTA_PIXEL:
275         return ScrollByPixel;
276     default:
277         return ScrollByPixel;
278     }
279 }
280
281 static inline bool didScrollInScrollableArea(ScrollableArea* scrollableArea, WheelEvent& wheelEvent)
282 {
283     ScrollGranularity scrollGranularity = wheelGranularityToScrollGranularity(wheelEvent.deltaMode());
284     bool didHandleWheelEvent = false;
285     if (float absoluteDelta = std::abs(wheelEvent.deltaX()))
286         didHandleWheelEvent |= scrollableArea->scroll(wheelEvent.deltaX() > 0 ? ScrollRight : ScrollLeft, scrollGranularity, absoluteDelta);
287     
288     if (float absoluteDelta = std::abs(wheelEvent.deltaY()))
289         didHandleWheelEvent |= scrollableArea->scroll(wheelEvent.deltaY() > 0 ? ScrollDown : ScrollUp, scrollGranularity, absoluteDelta);
290     
291     return didHandleWheelEvent;
292 }
293
294 static inline bool handleWheelEventInAppropriateEnclosingBox(Node* startNode, WheelEvent& wheelEvent, Element** stopElement, const FloatSize& filteredPlatformDelta, const FloatSize& filteredVelocity)
295 {
296     bool shouldHandleEvent = wheelEvent.deltaX() || wheelEvent.deltaY();
297 #if PLATFORM(MAC)
298     shouldHandleEvent |= wheelEvent.phase() == PlatformWheelEventPhaseEnded;
299 #if ENABLE(CSS_SCROLL_SNAP)
300     shouldHandleEvent |= wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded;
301 #endif
302 #endif
303     if (!startNode->renderer() || !shouldHandleEvent)
304         return false;
305
306     RenderBox& initialEnclosingBox = startNode->renderer()->enclosingBox();
307     if (initialEnclosingBox.isListBox())
308         return didScrollInScrollableArea(static_cast<RenderListBox*>(&initialEnclosingBox), wheelEvent);
309
310     RenderBox* currentEnclosingBox = &initialEnclosingBox;
311     while (currentEnclosingBox) {
312         if (RenderLayer* boxLayer = currentEnclosingBox->layer()) {
313             const PlatformWheelEvent* platformEvent = wheelEvent.wheelEvent();
314             bool scrollingWasHandled;
315             if (platformEvent != nullptr) {
316                 auto copiedEvent = platformEvent->copyWithDeltasAndVelocity(filteredPlatformDelta.width(), filteredPlatformDelta.height(), filteredVelocity);
317                 scrollingWasHandled = boxLayer->handleWheelEvent(copiedEvent);
318             } else
319                 scrollingWasHandled = didScrollInScrollableArea(boxLayer, wheelEvent);
320
321             if (scrollingWasHandled) {
322                 if (stopElement)
323                     *stopElement = currentEnclosingBox->element();
324                 return true;
325             }
326         }
327
328         if (stopElement && *stopElement && *stopElement == currentEnclosingBox->element())
329             return true;
330
331         currentEnclosingBox = currentEnclosingBox->containingBlock();
332         if (!currentEnclosingBox || currentEnclosingBox->isRenderView())
333             return false;
334     }
335     return false;
336 }
337
338 #if (ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS))
339 static inline bool shouldGesturesTriggerActive()
340 {
341     // If the platform we're on supports GestureTapDown and GestureTapCancel then we'll
342     // rely on them to set the active state. Unfortunately there's no generic way to
343     // know in advance what event types are supported.
344     return false;
345 }
346 #endif
347
348 #if !PLATFORM(COCOA)
349
350 inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
351 {
352     return false;
353 }
354
355 #if ENABLE(DRAG_SUPPORT)
356 inline bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&)
357 {
358     return false;
359 }
360 #endif
361
362 #endif
363
364 EventHandler::EventHandler(Frame& frame)
365     : m_frame(frame)
366     , m_hoverTimer(*this, &EventHandler::hoverTimerFired)
367 #if ENABLE(CURSOR_SUPPORT)
368     , m_cursorUpdateTimer(*this, &EventHandler::cursorUpdateTimerFired)
369 #endif
370 #if PLATFORM(MAC)
371     , m_pendingMomentumWheelEventsTimer(*this, &EventHandler::clearLatchedState)
372 #endif
373     , m_autoscrollController(std::make_unique<AutoscrollController>())
374 #if !ENABLE(IOS_TOUCH_EVENTS)
375     , m_fakeMouseMoveEventTimer(*this, &EventHandler::fakeMouseMoveEventTimerFired)
376 #endif
377 #if ENABLE(CURSOR_VISIBILITY)
378     , m_autoHideCursorTimer(*this, &EventHandler::autoHideCursorTimerFired)
379 #endif
380 {
381 }
382
383 EventHandler::~EventHandler()
384 {
385 #if !ENABLE(IOS_TOUCH_EVENTS)
386     ASSERT(!m_fakeMouseMoveEventTimer.isActive());
387 #endif
388 #if ENABLE(CURSOR_VISIBILITY)
389     ASSERT(!m_autoHideCursorTimer.isActive());
390 #endif
391 }
392     
393 #if ENABLE(DRAG_SUPPORT)
394
395 DragState& EventHandler::dragState()
396 {
397     static NeverDestroyed<DragState> state;
398     return state;
399 }
400
401 #endif
402     
403 void EventHandler::clear()
404 {
405     m_hoverTimer.stop();
406 #if ENABLE(CURSOR_SUPPORT)
407     m_cursorUpdateTimer.stop();
408 #endif
409 #if !ENABLE(IOS_TOUCH_EVENTS)
410     m_fakeMouseMoveEventTimer.stop();
411 #endif
412 #if ENABLE(CURSOR_VISIBILITY)
413     cancelAutoHideCursorTimer();
414 #endif
415     m_resizeLayer = nullptr;
416     m_elementUnderMouse = nullptr;
417     m_lastElementUnderMouse = nullptr;
418     m_lastMouseMoveEventSubframe = nullptr;
419     m_lastScrollbarUnderMouse = nullptr;
420     m_clickCount = 0;
421     m_clickNode = nullptr;
422 #if ENABLE(IOS_GESTURE_EVENTS)
423     m_gestureInitialDiameter = GestureUnknown;
424     m_gestureInitialRotation = GestureUnknown;
425 #endif
426 #if ENABLE(IOS_GESTURE_EVENTS) || ENABLE(MAC_GESTURE_EVENTS)
427     m_gestureLastDiameter = GestureUnknown;
428     m_gestureLastRotation = GestureUnknown;
429     m_gestureTargets.clear();
430 #endif
431 #if ENABLE(IOS_TOUCH_EVENTS)
432     m_touches.clear();
433     m_firstTouchID = InvalidTouchIdentifier;
434     m_touchEventTargetSubframe = nullptr;
435 #endif
436     m_frameSetBeingResized = nullptr;
437 #if ENABLE(DRAG_SUPPORT)
438     m_dragTarget = nullptr;
439     m_shouldOnlyFireDragOverEvent = false;
440 #endif
441     m_mousePositionIsUnknown = true;
442     m_lastKnownMousePosition = IntPoint();
443     m_lastKnownMouseGlobalPosition = IntPoint();
444     m_mousePressNode = nullptr;
445     m_mousePressed = false;
446     m_capturesDragging = false;
447     m_capturingMouseEventsElement = nullptr;
448     clearLatchedState();
449 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
450     m_originatingTouchPointTargets.clear();
451     m_originatingTouchPointDocument = nullptr;
452     m_originatingTouchPointTargetKey = 0;
453 #endif
454     m_maxMouseMovedDuration = 0;
455     m_didStartDrag = false;
456 }
457
458 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
459 {
460     if (nodeToBeRemoved.contains(m_clickNode.get()))
461         m_clickNode = nullptr;
462 }
463
464 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
465 {
466     if (selection.selection() != newSelection && selection.shouldChangeSelection(newSelection))
467         selection.setSelection(newSelection);
468 }
469
470 static inline bool dispatchSelectStart(Node* node)
471 {
472     if (!node || !node->renderer())
473         return true;
474
475     return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
476 }
477
478 static Node* nodeToSelectOnMouseDownForNode(Node& targetNode)
479 {
480 #if ENABLE(USERSELECT_ALL)
481     if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(&targetNode))
482         return rootUserSelectAll;
483 #endif
484
485     if (targetNode.shouldSelectOnMouseDown())
486         return &targetNode;
487
488     return nullptr;
489 }
490
491 static VisibleSelection expandSelectionToRespectSelectOnMouseDown(Node& targetNode, const VisibleSelection& selection)
492 {
493     Node* nodeToSelect = nodeToSelectOnMouseDownForNode(targetNode);
494     if (!nodeToSelect)
495         return selection;
496
497     VisibleSelection newSelection(selection);
498     newSelection.setBase(positionBeforeNode(nodeToSelect).upstream(CanCrossEditingBoundary));
499     newSelection.setExtent(positionAfterNode(nodeToSelect).downstream(CanCrossEditingBoundary));
500
501     return newSelection;
502 }
503
504 bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& selection, TextGranularity granularity)
505 {
506     if (Position::nodeIsUserSelectNone(targetNode))
507         return false;
508
509     if (!dispatchSelectStart(targetNode))
510         return false;
511
512     if (selection.isRange())
513         m_selectionInitiationState = ExtendedSelection;
514     else {
515         granularity = CharacterGranularity;
516         m_selectionInitiationState = PlacedCaret;
517     }
518
519     m_frame.selection().setSelectionByMouseIfDifferent(selection, granularity);
520
521     return true;
522 }
523
524 void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
525 {
526     Node* targetNode = result.targetNode();
527     VisibleSelection newSelection;
528
529     if (targetNode && targetNode->renderer()) {
530         VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
531         if (pos.isNotNull()) {
532             newSelection = VisibleSelection(pos);
533             newSelection.expandUsingGranularity(WordGranularity);
534         }
535
536         if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
537             newSelection.appendTrailingWhitespace();
538
539         updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), WordGranularity);
540     }
541 }
542
543 static AppendTrailingWhitespace shouldAppendTrailingWhitespace(const MouseEventWithHitTestResults& result, const Frame& frame)
544 {
545     return (result.event().clickCount() == 2 && frame.editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace;
546 }
547
548 void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
549 {
550     if (m_mouseDownMayStartSelect)
551         selectClosestWordFromHitTestResult(result.hitTestResult(), shouldAppendTrailingWhitespace(result, m_frame));
552 }
553
554 #if !PLATFORM(MAC)
555 VisibleSelection EventHandler::selectClosestWordFromHitTestResultBasedOnLookup(const HitTestResult&)
556 {
557     return VisibleSelection();
558 }
559 #endif
560     
561 void EventHandler::selectClosestContextualWordFromMouseEvent(const MouseEventWithHitTestResults& mouseEvent)
562 {
563     Node* targetNode = mouseEvent.targetNode();
564     const HitTestResult& result = mouseEvent.hitTestResult();
565     VisibleSelection newSelection;
566     bool appendTrailingWhitespace = shouldAppendTrailingWhitespace(mouseEvent, m_frame);
567     
568     if (targetNode && targetNode->renderer()) {
569         newSelection = selectClosestWordFromHitTestResultBasedOnLookup(result);
570         if (newSelection.isNone()) {
571             VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
572             if (pos.isNotNull()) {
573                 newSelection = VisibleSelection(pos);
574                 newSelection.expandUsingGranularity(WordGranularity);
575             }
576         }
577         
578         if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
579             newSelection.appendTrailingWhitespace();
580         
581         updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), WordGranularity);
582     }
583 }
584     
585 void EventHandler::selectClosestContextualWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
586 {
587     Element* urlElement = result.hitTestResult().URLElement();
588     if (!urlElement || !isDraggableLink(*urlElement)) {
589         if (Node* targetNode = result.targetNode()) {
590             if (isEditableNode(*targetNode))
591                 return selectClosestWordFromMouseEvent(result);
592         }
593
594         return selectClosestContextualWordFromMouseEvent(result);
595     }
596
597     Node* targetNode = result.targetNode();
598
599     if (targetNode && targetNode->renderer() && m_mouseDownMayStartSelect) {
600         VisibleSelection newSelection;
601         VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
602         if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(*urlElement))
603             newSelection = VisibleSelection::selectionFromContentsOfNode(urlElement);
604
605         updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), WordGranularity);
606     }
607 }
608
609 bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
610 {
611     if (event.event().button() != LeftButton)
612         return false;
613
614     if (m_frame.selection().isRange())
615         // A double-click when range is already selected
616         // should not change the selection.  So, do not call
617         // selectClosestWordFromMouseEvent, but do set
618         // m_beganSelectingText to prevent handleMouseReleaseEvent
619         // from setting caret selection.
620         m_selectionInitiationState = ExtendedSelection;
621     else
622         selectClosestWordFromMouseEvent(event);
623
624     return true;
625 }
626
627 bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
628 {
629     if (event.event().button() != LeftButton)
630         return false;
631     
632     Node* targetNode = event.targetNode();
633     if (!(targetNode && targetNode->renderer() && m_mouseDownMayStartSelect))
634         return false;
635
636     VisibleSelection newSelection;
637     VisiblePosition pos(targetNode->renderer()->positionForPoint(event.localPoint(), nullptr));
638     if (pos.isNotNull()) {
639         newSelection = VisibleSelection(pos);
640         newSelection.expandUsingGranularity(ParagraphGranularity);
641     }
642
643     return updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectSelectOnMouseDown(*targetNode, newSelection), ParagraphGranularity);
644 }
645
646 static int textDistance(const Position& start, const Position& end)
647 {
648     RefPtr<Range> range = Range::create(start.anchorNode()->document(), start, end);
649     return TextIterator::rangeLength(range.get(), true);
650 }
651
652 bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
653 {
654     Ref<Frame> protectedFrame(m_frame);
655
656     m_frame.document()->updateLayoutIgnorePendingStylesheets();
657     Node* targetNode = event.targetNode();
658     if (!(targetNode && targetNode->renderer() && m_mouseDownMayStartSelect))
659         return false;
660
661     // Extend the selection if the Shift key is down, unless the click is in a link.
662     bool extendSelection = event.event().shiftKey() && !event.isOverLink();
663
664     // Don't restart the selection when the mouse is pressed on an
665     // existing selection so we can allow for text dragging.
666     if (FrameView* view = m_frame.view()) {
667         LayoutPoint vPoint = view->windowToContents(event.event().position());
668         if (!extendSelection && m_frame.selection().contains(vPoint)) {
669             m_mouseDownWasSingleClickInSelection = true;
670             return false;
671         }
672     }
673
674     VisiblePosition visiblePos(targetNode->renderer()->positionForPoint(event.localPoint(), nullptr));
675     if (visiblePos.isNull())
676         visiblePos = VisiblePosition(firstPositionInOrBeforeNode(targetNode), DOWNSTREAM);
677     Position pos = visiblePos.deepEquivalent();
678
679     VisibleSelection newSelection = m_frame.selection().selection();
680     TextGranularity granularity = CharacterGranularity;
681
682     if (extendSelection && newSelection.isCaretOrRange()) {
683         VisibleSelection selectionInUserSelectAll = expandSelectionToRespectSelectOnMouseDown(*targetNode, VisibleSelection(pos));
684         if (selectionInUserSelectAll.isRange()) {
685             if (comparePositions(selectionInUserSelectAll.start(), newSelection.start()) < 0)
686                 pos = selectionInUserSelectAll.start();
687             else if (comparePositions(newSelection.end(), selectionInUserSelectAll.end()) < 0)
688                 pos = selectionInUserSelectAll.end();
689         }
690
691         if (!m_frame.editor().behavior().shouldConsiderSelectionAsDirectional() && pos.isNotNull()) {
692             // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
693             // was created right-to-left
694             Position start = newSelection.start();
695             Position end = newSelection.end();
696             int distanceToStart = textDistance(start, pos);
697             int distanceToEnd = textDistance(pos, end);
698             if (distanceToStart <= distanceToEnd)
699                 newSelection = VisibleSelection(end, pos);
700             else
701                 newSelection = VisibleSelection(start, pos);
702         } else
703             newSelection.setExtent(pos);
704
705         if (m_frame.selection().granularity() != CharacterGranularity) {
706             granularity = m_frame.selection().granularity();
707             newSelection.expandUsingGranularity(m_frame.selection().granularity());
708         }
709     } else
710         newSelection = expandSelectionToRespectSelectOnMouseDown(*targetNode, visiblePos);
711
712     bool handled = updateSelectionForMouseDownDispatchingSelectStart(targetNode, newSelection, granularity);
713
714     if (event.event().button() == MiddleButton) {
715         // Ignore handled, since we want to paste to where the caret was placed anyway.
716         handled = handlePasteGlobalSelection(event.event()) || handled;
717     }
718     return handled;
719 }
720
721 static inline bool canMouseDownStartSelect(Node* node)
722 {
723     if (!node || !node->renderer())
724         return true;
725
726     return node->canStartSelection() || Position::nodeIsUserSelectAll(node);
727 }
728
729 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
730 {
731     Ref<Frame> protectedFrame(m_frame);
732
733 #if ENABLE(DRAG_SUPPORT)
734     // Reset drag state.
735     dragState().source = nullptr;
736 #endif
737
738 #if !ENABLE(IOS_TOUCH_EVENTS)
739     cancelFakeMouseMoveEvent();
740 #endif
741
742     m_frame.document()->updateLayoutIgnorePendingStylesheets();
743
744     if (ScrollView* scrollView = m_frame.view()) {
745         if (scrollView->isPointInScrollbarCorner(event.event().position()))
746             return false;
747     }
748
749     bool singleClick = event.event().clickCount() <= 1;
750
751     // If we got the event back, that must mean it wasn't prevented,
752     // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
753     m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode()) && !event.scrollbar();
754     
755 #if ENABLE(DRAG_SUPPORT)
756     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
757     // FIXME: eventMayStartDrag() does not check for shift key press, link or image event targets.
758     // Bug: https://bugs.webkit.org/show_bug.cgi?id=155390
759
760     // Single mouse down on links or images can always trigger drag-n-drop.
761     bool isMouseDownOnLinkOrImage = event.isOverLink() || event.hitTestResult().image();
762     m_mouseDownMayStartDrag = singleClick && (!event.event().shiftKey() || isMouseDownOnLinkOrImage);
763 #endif
764
765     m_mouseDownWasSingleClickInSelection = false;
766
767     m_mouseDown = event.event();
768
769     if (m_immediateActionStage != ImmediateActionStage::PerformedHitTest)
770         m_immediateActionStage = ImmediateActionStage::None;
771
772     if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
773         return true;
774
775     if (is<SVGDocument>(*m_frame.document()) && downcast<SVGDocument>(*m_frame.document()).zoomAndPanEnabled()) {
776         if (event.event().shiftKey() && singleClick) {
777             m_svgPan = true;
778             downcast<SVGDocument>(*m_frame.document()).startPan(m_frame.view()->windowToContents(event.event().position()));
779             return true;
780         }
781     }
782
783     // We don't do this at the start of mouse down handling,
784     // because we don't want to do it until we know we didn't hit a widget.
785     if (singleClick)
786         focusDocumentView();
787
788     m_mousePressNode = event.targetNode();
789     m_frame.document()->setFocusNavigationStartingNode(event.targetNode());
790
791 #if ENABLE(DRAG_SUPPORT)
792     m_dragStartPosition = event.event().position();
793 #endif
794
795     m_mousePressed = true;
796     m_selectionInitiationState = HaveNotStartedSelection;
797
798     bool swallowEvent = false;
799     if (event.event().clickCount() == 2)
800         swallowEvent = handleMousePressEventDoubleClick(event);
801     else if (event.event().clickCount() >= 3)
802         swallowEvent = handleMousePressEventTripleClick(event);
803     else
804         swallowEvent = handleMousePressEventSingleClick(event);
805     
806     m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect
807         || (m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled());
808
809     return swallowEvent;
810 }
811
812 #if ENABLE(DRAG_SUPPORT)
813 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event, CheckDragHysteresis checkDragHysteresis)
814 {
815     if (!m_mousePressed)
816         return false;
817
818     Ref<Frame> protectedFrame(m_frame);
819
820     if (handleDrag(event, checkDragHysteresis))
821         return true;
822
823     Node* targetNode = event.targetNode();
824     if (event.event().button() != LeftButton || !targetNode)
825         return false;
826
827     RenderObject* renderer = targetNode->renderer();
828     if (!renderer) {
829         Element* parent = targetNode->parentOrShadowHostElement();
830         if (!parent)
831             return false;
832
833         renderer = parent->renderer();
834         if (!renderer || !renderer->isListBox())
835             return false;
836     }
837
838 #if PLATFORM(COCOA) // FIXME: Why does this assertion fire on other platforms?
839     ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
840 #endif
841
842     m_mouseDownMayStartDrag = false;
843
844     if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
845         m_autoscrollController->startAutoscrollForSelection(renderer);
846         m_mouseDownMayStartAutoscroll = false;
847     }
848
849     if (m_selectionInitiationState != ExtendedSelection) {
850         HitTestResult result(m_mouseDownPos);
851         m_frame.document()->renderView()->hitTest(HitTestRequest(), result);
852
853         updateSelectionForMouseDrag(result);
854     }
855     updateSelectionForMouseDrag(event.hitTestResult());
856     return true;
857 }
858     
859 bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
860 {
861     // This is a pre-flight check of whether the event might lead to a drag being started.  Be careful
862     // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
863     // in handleMousePressEvent
864     RenderView* renderView = m_frame.contentRenderer();
865     if (!renderView)
866         return false;
867
868     if (event.button() != LeftButton || event.clickCount() != 1)
869         return false;
870
871     FrameView* view = m_frame.view();
872     if (!view)
873         return false;
874
875     Page* page = m_frame.page();
876     if (!page)
877         return false;
878
879     Ref<Frame> protectedFrame(m_frame);
880
881     updateDragSourceActionsAllowed();
882     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowUserAgentShadowContent);
883     HitTestResult result(view->windowToContents(event.position()));
884     renderView->hitTest(request, result);
885     DragState state;
886     Element* targetElement = result.targetElement();
887     return targetElement && page->dragController().draggableElement(&m_frame, targetElement, result.roundedPointInInnerNodeFrame(), state);
888 }
889
890 void EventHandler::updateSelectionForMouseDrag()
891 {
892     FrameView* view = m_frame.view();
893     if (!view)
894         return;
895     RenderView* renderView = m_frame.contentRenderer();
896     if (!renderView)
897         return;
898
899     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent);
900     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
901     renderView->hitTest(request, result);
902     updateSelectionForMouseDrag(result);
903 }
904
905 static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const LayoutPoint& localPoint, Node* targetNode)
906 {
907     FloatPoint selectionEndPoint = localPoint;
908     Element* editableElement = selection.rootEditableElement();
909
910     if (!targetNode->renderer())
911         return VisiblePosition();
912
913     if (editableElement && !editableElement->contains(targetNode)) {
914         if (!editableElement->renderer())
915             return VisiblePosition();
916
917         FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint));
918         selectionEndPoint = editableElement->renderer()->absoluteToLocal(absolutePoint);
919         targetNode = editableElement;
920     }
921
922     return targetNode->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
923 }
924
925 void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
926 {
927     if (!m_mouseDownMayStartSelect)
928         return;
929
930     Node* target = hitTestResult.targetNode();
931     if (!target)
932         return;
933
934     VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(m_frame.selection().selection(), hitTestResult.localPoint(), target);
935
936     // Don't modify the selection if we're not on a node.
937     if (targetPosition.isNull())
938         return;
939
940     // Restart the selection if this is the first mouse move. This work is usually
941     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
942     VisibleSelection newSelection = m_frame.selection().selection();
943
944     // Special case to limit selection to the containing block for SVG text.
945     // FIXME: Isn't there a better non-SVG-specific way to do this?
946     if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
947         if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
948             if (selectionBaseRenderer->isSVGText())
949                 if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
950                     return;
951
952     if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
953         return;
954
955     if (m_selectionInitiationState != ExtendedSelection) {
956         // Always extend selection here because it's caused by a mouse drag
957         m_selectionInitiationState = ExtendedSelection;
958         newSelection = VisibleSelection(targetPosition);
959     }
960
961 #if ENABLE(USERSELECT_ALL)
962     Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllForNode(m_mousePressNode.get());
963     if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePressNode == Position::rootUserSelectAllForNode(target)) {
964         newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePressNode).upstream(CanCrossEditingBoundary));
965         newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
966     } else {
967         // Reset base for user select all when base is inside user-select-all area and extent < base.
968         if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPosition, nullptr)) < 0)
969             newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
970         
971         Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
972         if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPosition, nullptr)) < 0)
973             newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
974         else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
975             newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
976         else
977             newSelection.setExtent(targetPosition);
978     }
979 #else
980     newSelection.setExtent(targetPosition);
981 #endif
982
983     if (m_frame.selection().granularity() != CharacterGranularity)
984         newSelection.expandUsingGranularity(m_frame.selection().granularity());
985
986     m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
987         FrameSelection::AdjustEndpointsAtBidiBoundary);
988 }
989 #endif // ENABLE(DRAG_SUPPORT)
990
991 void EventHandler::lostMouseCapture()
992 {
993     m_frame.selection().setCaretBlinkingSuspended(false);
994 }
995
996 bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
997 {
998     if (eventLoopHandleMouseUp(event))
999         return true;
1000     
1001     // If this was the first click in the window, we don't even want to clear the selection.
1002     // This case occurs when the user clicks on a draggable element, since we have to process
1003     // the mouse down and drag events to see if we might start a drag.  For other first clicks
1004     // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets
1005     // ignored upstream of this layer.
1006     return eventActivatedView(event.event());
1007 }    
1008
1009 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
1010 {
1011     if (autoscrollInProgress())
1012         stopAutoscrollTimer();
1013
1014     Ref<Frame> protectedFrame(m_frame);
1015
1016     if (handleMouseUp(event))
1017         return true;
1018
1019     // Used to prevent mouseMoveEvent from initiating a drag before
1020     // the mouse is pressed again.
1021     m_mousePressed = false;
1022     m_capturesDragging = false;
1023 #if ENABLE(DRAG_SUPPORT)
1024     m_mouseDownMayStartDrag = false;
1025 #endif
1026     m_mouseDownMayStartSelect = false;
1027     m_mouseDownMayStartAutoscroll = false;
1028     m_mouseDownWasInSubframe = false;
1029   
1030     bool handled = false;
1031
1032     // Clear the selection if the mouse didn't move after the last mouse
1033     // press and it's not a context menu click.  We do this so when clicking
1034     // on the selection, the selection goes away.  However, if we are
1035     // editing, place the caret.
1036     if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
1037 #if ENABLE(DRAG_SUPPORT)
1038             && m_dragStartPosition == event.event().position()
1039 #endif
1040             && m_frame.selection().isRange()
1041             && event.event().button() != RightButton) {
1042         VisibleSelection newSelection;
1043         Node* node = event.targetNode();
1044         bool caretBrowsing = m_frame.settings().caretBrowsingEnabled();
1045         if (node && node->renderer() && (caretBrowsing || node->hasEditableStyle())) {
1046             VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint(), nullptr);
1047             newSelection = VisibleSelection(pos);
1048         }
1049
1050         setSelectionIfNeeded(m_frame.selection(), newSelection);
1051
1052         handled = true;
1053     }
1054
1055     if (event.event().button() == MiddleButton) {
1056         // Ignore handled, since we want to paste to where the caret was placed anyway.
1057         handled = handlePasteGlobalSelection(event.event()) || handled;
1058     }
1059
1060     return handled;
1061 }
1062
1063 #if ENABLE(PAN_SCROLLING)
1064
1065 void EventHandler::didPanScrollStart()
1066 {
1067     m_autoscrollController->didPanScrollStart();
1068 }
1069
1070 void EventHandler::didPanScrollStop()
1071 {
1072     m_autoscrollController->didPanScrollStop();
1073 }
1074
1075 void EventHandler::startPanScrolling(RenderElement& renderer)
1076 {
1077 #if !PLATFORM(IOS)
1078     if (!is<RenderBox>(renderer))
1079         return;
1080     m_autoscrollController->startPanScrolling(&downcast<RenderBox>(renderer), lastKnownMousePosition());
1081     invalidateClick();
1082 #endif
1083 }
1084
1085 #endif // ENABLE(PAN_SCROLLING)
1086
1087 RenderBox* EventHandler::autoscrollRenderer() const
1088 {
1089     return m_autoscrollController->autoscrollRenderer();
1090 }
1091
1092 void EventHandler::updateAutoscrollRenderer()
1093 {
1094     m_autoscrollController->updateAutoscrollRenderer();
1095 }
1096
1097 bool EventHandler::autoscrollInProgress() const
1098 {
1099     return m_autoscrollController->autoscrollInProgress();
1100 }
1101
1102 bool EventHandler::panScrollInProgress() const
1103 {
1104     return m_autoscrollController->panScrollInProgress();
1105 }
1106
1107 #if ENABLE(DRAG_SUPPORT)
1108 DragSourceAction EventHandler::updateDragSourceActionsAllowed() const
1109 {
1110     Page* page = m_frame.page();
1111     if (!page)
1112         return DragSourceActionNone;
1113
1114     FrameView* view = m_frame.view();
1115     if (!view)
1116         return DragSourceActionNone;
1117
1118     return page->dragController().delegateDragSourceAction(view->contentsToRootView(m_mouseDownPos));
1119 }
1120 #endif // ENABLE(DRAG_SUPPORT)
1121
1122 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding) const
1123 {
1124     ASSERT((hitType & HitTestRequest::CollectMultipleElements) || padding.isEmpty());
1125
1126     Ref<Frame> protectedFrame(m_frame);
1127
1128     // We always send hitTestResultAtPoint to the main frame if we have one,
1129     // otherwise we might hit areas that are obscured by higher frames.
1130     if (!m_frame.isMainFrame()) {
1131         Frame& mainFrame = m_frame.mainFrame();
1132         FrameView* frameView = m_frame.view();
1133         FrameView* mainView = mainFrame.view();
1134         if (frameView && mainView) {
1135             IntPoint mainFramePoint = mainView->rootViewToContents(frameView->contentsToRootView(roundedIntPoint(point)));
1136             return mainFrame.eventHandler().hitTestResultAtPoint(mainFramePoint, hitType, padding);
1137         }
1138     }
1139
1140     unsigned nonNegativePaddingWidth = std::max<LayoutUnit>(0, padding.width()).toUnsigned();
1141     unsigned nonNegativePaddingHeight = std::max<LayoutUnit>(0, padding.height()).toUnsigned();
1142
1143     // We should always start hit testing a clean tree.
1144     if (auto* frameView = m_frame.view())
1145         frameView->updateLayoutAndStyleIfNeededRecursive();
1146
1147     HitTestResult result(point, nonNegativePaddingHeight, nonNegativePaddingWidth, nonNegativePaddingHeight, nonNegativePaddingWidth);
1148     RenderView* renderView = m_frame.contentRenderer();
1149     if (!renderView)
1150         return result;
1151
1152     // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
1153     HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
1154     renderView->hitTest(request, result);
1155     if (!request.readOnly())
1156         m_frame.document()->updateHoverActiveState(request, result.targetElement());
1157
1158     if (request.disallowsUserAgentShadowContent())
1159         result.setToNonUserAgentShadowAncestor();
1160
1161     return result;
1162 }
1163
1164 void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
1165 {
1166     m_autoscrollController->stopAutoscrollTimer(rendererIsBeingDestroyed);
1167 }
1168
1169 bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1170 {
1171     Node* node = startingNode;
1172
1173     if (!node)
1174         node = m_frame.document()->focusedElement();
1175
1176     if (!node)
1177         node = m_mousePressNode.get();
1178     
1179     if (node) {
1180         auto r = node->renderer();
1181         if (r && !r->isListBox() && r->enclosingBox().scroll(direction, granularity)) {
1182             setFrameWasScrolledByUser();
1183             return true;
1184         }
1185     }
1186
1187     return false;
1188 }
1189
1190 bool EventHandler::logicalScrollOverflow(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1191 {
1192     Node* node = startingNode;
1193
1194     if (!node)
1195         node = m_frame.document()->focusedElement();
1196
1197     if (!node)
1198         node = m_mousePressNode.get();
1199     
1200     if (node) {
1201         auto r = node->renderer();
1202         if (r && !r->isListBox() && r->enclosingBox().logicalScroll(direction, granularity)) {
1203             setFrameWasScrolledByUser();
1204             return true;
1205         }
1206     }
1207
1208     return false;
1209 }
1210
1211 bool EventHandler::scrollRecursively(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1212 {
1213     Ref<Frame> protectedFrame(m_frame);
1214
1215     // The layout needs to be up to date to determine if we can scroll. We may be
1216     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1217     m_frame.document()->updateLayoutIgnorePendingStylesheets();
1218     if (scrollOverflow(direction, granularity, startingNode))
1219         return true;    
1220     Frame* frame = &m_frame;
1221     FrameView* view = frame->view();
1222     if (view && view->scroll(direction, granularity))
1223         return true;
1224     frame = frame->tree().parent();
1225     if (!frame)
1226         return false;
1227     return frame->eventHandler().scrollRecursively(direction, granularity, m_frame.ownerElement());
1228 }
1229
1230 bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1231 {
1232     Ref<Frame> protectedFrame(m_frame);
1233
1234     // The layout needs to be up to date to determine if we can scroll. We may be
1235     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1236     m_frame.document()->updateLayoutIgnorePendingStylesheets();
1237     if (logicalScrollOverflow(direction, granularity, startingNode))
1238         return true;    
1239     Frame* frame = &m_frame;
1240     FrameView* view = frame->view();
1241     
1242     bool scrolled = false;
1243 #if PLATFORM(COCOA)
1244     // Mac also resets the scroll position in the inline direction.
1245     if (granularity == ScrollByDocument && view && view->logicalScroll(ScrollInlineDirectionBackward, ScrollByDocument))
1246         scrolled = true;
1247 #endif
1248     if (view && view->logicalScroll(direction, granularity))
1249         scrolled = true;
1250     
1251     if (scrolled)
1252         return true;
1253     
1254     frame = frame->tree().parent();
1255     if (!frame)
1256         return false;
1257
1258     return frame->eventHandler().logicalScrollRecursively(direction, granularity, m_frame.ownerElement());
1259 }
1260
1261 IntPoint EventHandler::lastKnownMousePosition() const
1262 {
1263     return m_lastKnownMousePosition;
1264 }
1265
1266 Frame* EventHandler::subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
1267 {
1268     if (!hitTestResult.isOverWidget())
1269         return 0;
1270     return subframeForTargetNode(hitTestResult.targetNode());
1271 }
1272
1273 Frame* EventHandler::subframeForTargetNode(Node* node)
1274 {
1275     if (!node)
1276         return nullptr;
1277
1278     auto renderer = node->renderer();
1279     if (!is<RenderWidget>(renderer))
1280         return nullptr;
1281
1282     Widget* widget = downcast<RenderWidget>(*renderer).widget();
1283     if (!is<FrameView>(widget))
1284         return nullptr;
1285
1286     return &downcast<FrameView>(*widget).frame();
1287 }
1288
1289 #if ENABLE(CURSOR_SUPPORT)
1290 static bool isSubmitImage(Node* node)
1291 {
1292     return is<HTMLInputElement>(node) && downcast<HTMLInputElement>(*node).isImageButton();
1293 }
1294
1295 // Returns true if the node's editable block is not current focused for editing
1296 static bool nodeIsNotBeingEdited(const Node& node, const Frame& frame)
1297 {
1298     return frame.selection().selection().rootEditableElement() != node.rootEditableElement();
1299 }
1300
1301 bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
1302 {
1303     if (!node)
1304         return false;
1305
1306     bool editable = node->hasEditableStyle();
1307     bool editableLinkEnabled = false;
1308
1309     // If the link is editable, then we need to check the settings to see whether or not the link should be followed
1310     if (editable) {
1311         switch (m_frame.settings().editableLinkBehavior()) {
1312         default:
1313         case EditableLinkDefaultBehavior:
1314         case EditableLinkAlwaysLive:
1315             editableLinkEnabled = true;
1316             break;
1317
1318         case EditableLinkNeverLive:
1319             editableLinkEnabled = false;
1320             break;
1321
1322         case EditableLinkLiveWhenNotFocused:
1323             editableLinkEnabled = nodeIsNotBeingEdited(*node, m_frame) || shiftKey;
1324             break;
1325
1326         case EditableLinkOnlyLiveWithShiftKey:
1327             editableLinkEnabled = shiftKey;
1328             break;
1329         }
1330     }
1331
1332     return ((isOverLink || isSubmitImage(node)) && (!editable || editableLinkEnabled));
1333 }
1334
1335 void EventHandler::cursorUpdateTimerFired()
1336 {
1337     ASSERT(m_frame.document());
1338     updateCursor();
1339 }
1340
1341 void EventHandler::updateCursor()
1342 {
1343     if (m_mousePositionIsUnknown)
1344         return;
1345
1346     FrameView* view = m_frame.view();
1347     if (!view)
1348         return;
1349
1350     RenderView* renderView = view->renderView();
1351     if (!renderView)
1352         return;
1353
1354     if (!view->shouldSetCursor())
1355         return;
1356
1357     bool shiftKey;
1358     bool ctrlKey;
1359     bool altKey;
1360     bool metaKey;
1361     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
1362
1363     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::AllowFrameScrollbars);
1364     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
1365     renderView->hitTest(request, result);
1366
1367     updateCursor(*view, result, shiftKey);
1368 }
1369
1370 void EventHandler::updateCursor(FrameView& view, const HitTestResult& result, bool shiftKey)
1371 {
1372     if (auto optionalCursor = selectCursor(result, shiftKey)) {
1373         m_currentMouseCursor = WTFMove(optionalCursor.value());
1374         view.setCursor(m_currentMouseCursor);
1375     }
1376 }
1377
1378 std::optional<Cursor> EventHandler::selectCursor(const HitTestResult& result, bool shiftKey)
1379 {
1380     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1381         return std::nullopt;
1382
1383     if (!m_frame.page())
1384         return std::nullopt;
1385
1386 #if ENABLE(PAN_SCROLLING)
1387     if (m_frame.mainFrame().eventHandler().panScrollInProgress())
1388         return std::nullopt;
1389 #endif
1390
1391     Ref<Frame> protectedFrame(m_frame);
1392
1393     // Use always pointer cursor for scrollbars.
1394     if (result.scrollbar()) {
1395 #if ENABLE(CURSOR_VISIBILITY)
1396         cancelAutoHideCursorTimer();
1397 #endif
1398         return pointerCursor();
1399     }
1400
1401     Node* node = result.targetNode();
1402     if (!node)
1403         return std::nullopt;
1404
1405     auto renderer = node->renderer();
1406     auto* style = renderer ? &renderer->style() : nullptr;
1407     bool horizontalText = !style || style->isHorizontalWritingMode();
1408     const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
1409
1410 #if ENABLE(CURSOR_VISIBILITY)
1411     if (style && style->cursorVisibility() == CursorVisibilityAutoHide)
1412         startAutoHideCursorTimer();
1413     else
1414         cancelAutoHideCursorTimer();
1415 #endif
1416
1417     if (renderer) {
1418         Cursor overrideCursor;
1419         switch (renderer->getCursor(roundedIntPoint(result.localPoint()), overrideCursor)) {
1420         case SetCursorBasedOnStyle:
1421             break;
1422         case SetCursor:
1423             return overrideCursor;
1424         case DoNotSetCursor:
1425             return std::nullopt;
1426         }
1427     }
1428
1429     if (style && style->cursors()) {
1430         const CursorList* cursors = style->cursors();
1431         for (unsigned i = 0; i < cursors->size(); ++i) {
1432             StyleImage* styleImage = (*cursors)[i].image();
1433             if (!styleImage)
1434                 continue;
1435             CachedImage* cachedImage = styleImage->cachedImage();
1436             if (!cachedImage)
1437                 continue;
1438             float scale = styleImage->imageScaleFactor();
1439             // Get hotspot and convert from logical pixels to physical pixels.
1440             IntPoint hotSpot = (*cursors)[i].hotSpot();
1441             FloatSize size = cachedImage->imageForRenderer(renderer)->size();
1442             if (cachedImage->errorOccurred())
1443                 continue;
1444             // Limit the size of cursors (in UI pixels) so that they cannot be
1445             // used to cover UI elements in chrome.
1446             size.scale(1 / scale);
1447             if (size.width() > maximumCursorSize || size.height() > maximumCursorSize)
1448                 continue;
1449
1450             Image* image = cachedImage->imageForRenderer(renderer);
1451 #if ENABLE(MOUSE_CURSOR_SCALE)
1452             // Ensure no overflow possible in calculations above.
1453             if (scale < minimumCursorScale)
1454                 continue;
1455             return Cursor(image, hotSpot, scale);
1456 #else
1457             ASSERT(scale == 1);
1458             return Cursor(image, hotSpot);
1459 #endif // ENABLE(MOUSE_CURSOR_SCALE)
1460         }
1461     }
1462
1463     // During selection, use an I-beam regardless of the content beneath the cursor.
1464     // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
1465     if (m_mousePressed
1466         && m_mouseDownMayStartSelect
1467 #if ENABLE(DRAG_SUPPORT)
1468         && !m_mouseDownMayStartDrag
1469 #endif
1470         && m_frame.selection().isCaretOrRange()
1471         && !m_capturingMouseEventsElement)
1472         return iBeam;
1473
1474     switch (style ? style->cursor() : CursorAuto) {
1475     case CursorAuto: {
1476         bool editable = node->hasEditableStyle();
1477
1478         if (useHandCursor(node, result.isOverLink(), shiftKey))
1479             return handCursor();
1480
1481         bool inResizer = false;
1482         if (renderer) {
1483             if (RenderLayer* layer = renderer->enclosingLayer()) {
1484                 if (FrameView* view = m_frame.view())
1485                     inResizer = layer->isPointInResizeControl(view->windowToContents(roundedIntPoint(result.localPoint())));
1486             }
1487         }
1488
1489         if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !result.scrollbar())
1490             return iBeam;
1491         return pointerCursor();
1492     }
1493     case CursorDefault:
1494         return pointerCursor();
1495     case CursorNone:
1496         return noneCursor();
1497     case CursorContextMenu:
1498         return contextMenuCursor();
1499     case CursorHelp:
1500         return helpCursor();
1501     case CursorPointer:
1502         return handCursor();
1503     case CursorProgress:
1504         return progressCursor();
1505     case CursorWait:
1506         return waitCursor();
1507     case CursorCell:
1508         return cellCursor();
1509     case CursorCrosshair:
1510         return crossCursor();
1511     case CursorText:
1512         return iBeamCursor();
1513     case CursorVerticalText:
1514         return verticalTextCursor();
1515     case CursorAlias:
1516         return aliasCursor();
1517     case CursorCopy:
1518         return copyCursor();
1519     case CursorMove:
1520         return moveCursor();
1521     case CursorNoDrop:
1522         return noDropCursor();
1523     case CursorNotAllowed:
1524         return notAllowedCursor();
1525     case CursorGrab:
1526         return grabCursor();
1527     case CursorGrabbing:
1528         return grabbingCursor();
1529     case CursorEResize:
1530         return eastResizeCursor();
1531     case CursorNResize:
1532         return northResizeCursor();
1533     case CursorNeResize:
1534         return northEastResizeCursor();
1535     case CursorNwResize:
1536         return northWestResizeCursor();
1537     case CursorSResize:
1538         return southResizeCursor();
1539     case CursorSeResize:
1540         return southEastResizeCursor();
1541     case CursorSwResize:
1542         return southWestResizeCursor();
1543     case CursorWResize:
1544         return westResizeCursor();
1545     case CursorEwResize:
1546         return eastWestResizeCursor();
1547     case CursorNsResize:
1548         return northSouthResizeCursor();
1549     case CursorNeswResize:
1550         return northEastSouthWestResizeCursor();
1551     case CursorNwseResize:
1552         return northWestSouthEastResizeCursor();
1553     case CursorColResize:
1554         return columnResizeCursor();
1555     case CursorRowResize:
1556         return rowResizeCursor();
1557     case CursorAllScroll:
1558         return moveCursor();
1559     case CursorZoomIn:
1560         return zoomInCursor();
1561     case CursorZoomOut:
1562         return zoomOutCursor();
1563     }
1564     return pointerCursor();
1565 }
1566 #endif // ENABLE(CURSOR_SUPPORT)
1567
1568 #if ENABLE(CURSOR_VISIBILITY)
1569 void EventHandler::startAutoHideCursorTimer()
1570 {
1571     Page* page = m_frame.page();
1572     if (!page)
1573         return;
1574
1575     m_autoHideCursorTimer.startOneShot(page->settings().timeWithoutMouseMovementBeforeHidingControls());
1576
1577 #if !ENABLE(IOS_TOUCH_EVENTS)
1578     // The fake mouse move event screws up the auto-hide feature (by resetting the auto-hide timer)
1579     // so cancel any pending fake mouse moves.
1580     if (m_fakeMouseMoveEventTimer.isActive())
1581         m_fakeMouseMoveEventTimer.stop();
1582 #endif
1583 }
1584
1585 void EventHandler::cancelAutoHideCursorTimer()
1586 {
1587     if (m_autoHideCursorTimer.isActive())
1588         m_autoHideCursorTimer.stop();
1589 }
1590
1591 void EventHandler::autoHideCursorTimerFired()
1592 {
1593     m_currentMouseCursor = noneCursor();
1594     FrameView* view = m_frame.view();
1595     if (view && view->isActive())
1596         view->setCursor(m_currentMouseCursor);
1597 }
1598 #endif
1599
1600 static LayoutPoint documentPointForWindowPoint(Frame& frame, const IntPoint& windowPoint)
1601 {
1602     FrameView* view = frame.view();
1603     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
1604     // Historically the code would just crash; this is clearly no worse than that.
1605     return view ? view->windowToContents(windowPoint) : windowPoint;
1606 }
1607
1608 static Scrollbar* scrollbarForMouseEvent(const MouseEventWithHitTestResults& mouseEvent, FrameView* view)
1609 {
1610     if (view) {
1611         if (auto* scrollbar = view->scrollbarAtPoint(mouseEvent.event().position()))
1612             return scrollbar;
1613     }
1614     return mouseEvent.scrollbar();
1615
1616 }
1617
1618 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouseEvent)
1619 {
1620     Ref<Frame> protectedFrame(m_frame);
1621     RefPtr<FrameView> protector(m_frame.view());
1622
1623     if (InspectorInstrumentation::handleMousePress(m_frame)) {
1624         invalidateClick();
1625         return true;
1626     }
1627
1628 #if ENABLE(POINTER_LOCK)
1629     if (m_frame.page()->pointerLockController().isLocked()) {
1630         m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mousedownEvent);
1631         return true;
1632     }
1633 #endif
1634
1635     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
1636         return true;
1637
1638 #if ENABLE(TOUCH_EVENTS)
1639     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
1640     if (defaultPrevented)
1641         return true;
1642 #endif
1643
1644     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
1645
1646     // FIXME (bug 68185): this call should be made at another abstraction layer
1647     m_frame.loader().resetMultipleFormSubmissionProtection();
1648
1649 #if !ENABLE(IOS_TOUCH_EVENTS)
1650     cancelFakeMouseMoveEvent();
1651 #endif
1652     m_mousePressed = true;
1653     m_capturesDragging = true;
1654     setLastKnownMousePosition(platformMouseEvent);
1655     m_mouseDownTimestamp = platformMouseEvent.timestamp();
1656 #if ENABLE(DRAG_SUPPORT)
1657     m_mouseDownMayStartDrag = false;
1658 #endif
1659     m_mouseDownMayStartSelect = false;
1660     m_mouseDownMayStartAutoscroll = false;
1661     if (FrameView* view = m_frame.view())
1662         m_mouseDownPos = view->windowToContents(platformMouseEvent.position());
1663     else {
1664         invalidateClick();
1665         return false;
1666     }
1667     m_mouseDownWasInSubframe = false;
1668
1669     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent);
1670     // Save the document point we generate in case the window coordinate is invalidated by what happens
1671     // when we dispatch the event.
1672     LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, platformMouseEvent.position());
1673     MouseEventWithHitTestResults mouseEvent = m_frame.document()->prepareMouseEvent(request, documentPoint, platformMouseEvent);
1674
1675     if (!mouseEvent.targetNode()) {
1676         invalidateClick();
1677         return false;
1678     }
1679
1680     m_mousePressNode = mouseEvent.targetNode();
1681     m_frame.document()->setFocusNavigationStartingNode(mouseEvent.targetNode());
1682
1683     Scrollbar* scrollbar = scrollbarForMouseEvent(mouseEvent, m_frame.view());
1684     updateLastScrollbarUnderMouse(scrollbar, SetOrClearLastScrollbar::Set);
1685     bool passedToScrollbar = scrollbar && passMousePressEventToScrollbar(mouseEvent, scrollbar);
1686
1687     if (!passedToScrollbar) {
1688         RefPtr<Frame> subframe = subframeForHitTestResult(mouseEvent);
1689         if (subframe && passMousePressEventToSubframe(mouseEvent, subframe.get())) {
1690             // Start capturing future events for this frame. We only do this if we didn't clear
1691             // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
1692             m_capturesDragging = subframe->eventHandler().capturesDragging();
1693             if (m_mousePressed && m_capturesDragging) {
1694                 m_capturingMouseEventsElement = subframe->ownerElement();
1695                 m_eventHandlerWillResetCapturingMouseEventsElement = true;
1696             }
1697             invalidateClick();
1698             return true;
1699         }
1700     }
1701
1702 #if ENABLE(PAN_SCROLLING)
1703     // We store whether pan scrolling is in progress before calling stopAutoscrollTimer()
1704     // because it will set m_autoscrollType to NoAutoscroll on return.
1705     bool isPanScrollInProgress = m_frame.mainFrame().eventHandler().panScrollInProgress();
1706     stopAutoscrollTimer();
1707     if (isPanScrollInProgress) {
1708         // We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate
1709         // away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>.
1710         invalidateClick();
1711         return true;
1712     }
1713 #endif
1714
1715     m_clickCount = platformMouseEvent.clickCount();
1716     m_clickNode = mouseEvent.targetNode();
1717
1718     if (!m_clickNode) {
1719         invalidateClick();
1720         return false;
1721     }
1722
1723     if (FrameView* view = m_frame.view()) {
1724         RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;
1725         IntPoint p = view->windowToContents(platformMouseEvent.position());
1726         if (layer && layer->isPointInResizeControl(p)) {
1727             layer->setInResizeMode(true);
1728             m_resizeLayer = layer;
1729             m_offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
1730             invalidateClick();
1731             return true;
1732         }
1733     }
1734
1735     m_frame.selection().setCaretBlinkingSuspended(true);
1736
1737     bool swallowEvent = !dispatchMouseEvent(eventNames().mousedownEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
1738     m_capturesDragging = !swallowEvent || mouseEvent.scrollbar();
1739
1740     // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
1741     // in case the scrollbar widget was destroyed when the mouse event was handled.
1742     if (mouseEvent.scrollbar()) {
1743         const bool wasLastScrollBar = mouseEvent.scrollbar() == m_lastScrollbarUnderMouse;
1744         mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
1745         if (wasLastScrollBar && mouseEvent.scrollbar() != m_lastScrollbarUnderMouse)
1746             m_lastScrollbarUnderMouse = nullptr;
1747     }
1748
1749     if (!swallowEvent) {
1750         // Refetch the event target node if it currently is the shadow node inside an <input> element.
1751         // If a mouse event handler changes the input element type to one that has a widget associated,
1752         // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
1753         // event target node can't still be the shadow node.
1754         if (is<ShadowRoot>(*mouseEvent.targetNode()) && is<HTMLInputElement>(*downcast<ShadowRoot>(*mouseEvent.targetNode()).host()))
1755             mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
1756     }
1757
1758     if (!swallowEvent) {
1759         if (passedToScrollbar)
1760             swallowEvent = true;
1761         else
1762             swallowEvent = handleMousePressEvent(mouseEvent);
1763     }
1764     return swallowEvent;
1765 }
1766
1767 // This method only exists for platforms that don't know how to deliver 
1768 bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& platformMouseEvent)
1769 {
1770     Ref<Frame> protectedFrame(m_frame);
1771     RefPtr<FrameView> protector(m_frame.view());
1772
1773     m_frame.selection().setCaretBlinkingSuspended(false);
1774
1775     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
1776
1777 #if ENABLE(POINTER_LOCK)
1778     if (m_frame.page()->pointerLockController().isLocked()) {
1779         m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mouseupEvent);
1780         return true;
1781     }
1782 #endif
1783
1784     // We get this instead of a second mouse-up 
1785     m_mousePressed = false;
1786     setLastKnownMousePosition(platformMouseEvent);
1787
1788     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowUserAgentShadowContent);
1789     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
1790     Frame* subframe = subframeForHitTestResult(mouseEvent);
1791     if (m_eventHandlerWillResetCapturingMouseEventsElement)
1792         m_capturingMouseEventsElement = nullptr;
1793     if (subframe && passMousePressEventToSubframe(mouseEvent, subframe))
1794         return true;
1795
1796     m_clickCount = platformMouseEvent.clickCount();
1797     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
1798
1799     bool swallowClickEvent = platformMouseEvent.button() != RightButton && mouseEvent.targetNode() == m_clickNode && !dispatchMouseEvent(eventNames().clickEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
1800
1801     if (m_lastScrollbarUnderMouse)
1802         swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
1803
1804     bool swallowMouseReleaseEvent = !swallowMouseUpEvent && handleMouseReleaseEvent(mouseEvent);
1805
1806     invalidateClick();
1807
1808     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1809 }
1810
1811 static ScrollableArea* enclosingScrollableArea(Node* node)
1812 {
1813     for (auto ancestor = node; ancestor; ancestor = ancestor->parentOrShadowHostNode()) {
1814         if (is<HTMLIFrameElement>(*ancestor) || is<HTMLHtmlElement>(*ancestor) || is<HTMLDocument>(*ancestor))
1815             return nullptr;
1816
1817         auto renderer = ancestor->renderer();
1818         if (!renderer)
1819             continue;
1820
1821         if (is<RenderListBox>(*renderer))
1822             return downcast<RenderListBox>(renderer);
1823
1824         return renderer->enclosingLayer();
1825     }
1826
1827     return nullptr;
1828 }
1829
1830 bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
1831 {
1832     Ref<Frame> protectedFrame(m_frame);
1833     RefPtr<FrameView> protector(m_frame.view());
1834     MaximumDurationTracker maxDurationTracker(&m_maxMouseMovedDuration);
1835
1836     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(event))
1837         return true;
1838
1839     HitTestResult hoveredNode = HitTestResult(LayoutPoint());
1840     bool result = handleMouseMoveEvent(event, &hoveredNode);
1841
1842     Page* page = m_frame.page();
1843     if (!page)
1844         return result;
1845
1846     if (auto scrolledArea = enclosingScrollableArea(hoveredNode.innerNode())) {
1847         if (FrameView* frameView = m_frame.view()) {
1848             if (frameView->containsScrollableArea(scrolledArea))
1849                 scrolledArea->mouseMovedInContentArea();
1850         }
1851     }
1852
1853     if (FrameView* frameView = m_frame.view())
1854         frameView->mouseMovedInContentArea();  
1855
1856     hoveredNode.setToNonUserAgentShadowAncestor();
1857     page->chrome().mouseDidMoveOverElement(hoveredNode, event.modifierFlags());
1858     page->chrome().setToolTip(hoveredNode);
1859     return result;
1860 }
1861
1862 bool EventHandler::passMouseMovedEventToScrollbars(const PlatformMouseEvent& event)
1863 {
1864     HitTestResult hoveredNode;
1865     return handleMouseMoveEvent(event, &hoveredNode, true);
1866 }
1867
1868 bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
1869 {
1870 #if ENABLE(TOUCH_EVENTS)
1871     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
1872     if (defaultPrevented)
1873         return true;
1874 #endif
1875
1876     Ref<Frame> protectedFrame(m_frame);
1877     RefPtr<FrameView> protector(m_frame.view());
1878
1879 #if ENABLE(POINTER_LOCK)
1880     if (m_frame.page()->pointerLockController().isLocked()) {
1881         m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mousemoveEvent);
1882         return true;
1883     }
1884 #endif
1885
1886     setLastKnownMousePosition(platformMouseEvent);
1887
1888     if (m_hoverTimer.isActive())
1889         m_hoverTimer.stop();
1890
1891 #if ENABLE(CURSOR_SUPPORT)
1892     m_cursorUpdateTimer.stop();
1893 #endif
1894
1895 #if !ENABLE(IOS_TOUCH_EVENTS)
1896     cancelFakeMouseMoveEvent();
1897 #endif
1898
1899     if (m_svgPan) {
1900         downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
1901         return true;
1902     }
1903
1904     if (m_frameSetBeingResized)
1905         return !dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, platformMouseEvent, false);
1906
1907     // On iOS, our scrollbars are managed by UIKit.
1908 #if !PLATFORM(IOS)
1909     // Send events right to a scrollbar if the mouse is pressed.
1910     if (m_lastScrollbarUnderMouse && m_mousePressed)
1911         return m_lastScrollbarUnderMouse->mouseMoved(platformMouseEvent);
1912 #endif
1913
1914     HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowFrameScrollbars;
1915     if (m_mousePressed)
1916         hitType |= HitTestRequest::Active;
1917     else if (onlyUpdateScrollbars) {
1918         // Mouse events should be treated as "read-only" if we're updating only scrollbars. This  
1919         // means that :hover and :active freeze in the state they were in, rather than updating  
1920         // for nodes the mouse moves while the window is not key (which will be the case if 
1921         // onlyUpdateScrollbars is true). 
1922         hitType |= HitTestRequest::ReadOnly;
1923     }
1924
1925 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
1926     // Treat any mouse move events as readonly if the user is currently touching the screen.
1927     if (m_touchPressed)
1928         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
1929 #endif
1930     HitTestRequest request(hitType);
1931     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
1932     if (hoveredNode)
1933         *hoveredNode = mouseEvent.hitTestResult();
1934
1935     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1936         m_resizeLayer->resize(platformMouseEvent, m_offsetFromResizeCorner);
1937     else {
1938         Scrollbar* scrollbar = mouseEvent.scrollbar();
1939         updateLastScrollbarUnderMouse(scrollbar, m_mousePressed ? SetOrClearLastScrollbar::Clear : SetOrClearLastScrollbar::Set);
1940
1941         // On iOS, our scrollbars are managed by UIKit.
1942 #if !PLATFORM(IOS)
1943         if (!m_mousePressed && scrollbar)
1944             scrollbar->mouseMoved(platformMouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
1945 #endif
1946         if (onlyUpdateScrollbars) {
1947             updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
1948             return true;
1949         }
1950     }
1951
1952     bool swallowEvent = false;
1953     RefPtr<Frame> newSubframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
1954  
1955     // We want mouseouts to happen first, from the inside out.  First send a move event to the last subframe so that it will fire mouseouts.
1956     if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(&m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
1957         passMouseMoveEventToSubframe(mouseEvent, m_lastMouseMoveEventSubframe.get());
1958
1959     if (newSubframe) {
1960         // Update over/out state before passing the event to the subframe.
1961         updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
1962         
1963         // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
1964         // node to be detached from its FrameView, in which case the event should not be passed.
1965         if (newSubframe->view())
1966             swallowEvent |= passMouseMoveEventToSubframe(mouseEvent, newSubframe.get(), hoveredNode);
1967     }
1968
1969     if (!newSubframe || mouseEvent.scrollbar()) {
1970 #if ENABLE(CURSOR_SUPPORT)
1971         if (auto* view = m_frame.view())
1972             updateCursor(*view, mouseEvent.hitTestResult(), platformMouseEvent.shiftKey());
1973 #endif
1974     }
1975     
1976     m_lastMouseMoveEventSubframe = newSubframe;
1977
1978     if (swallowEvent)
1979         return true;
1980     
1981     swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), false, 0, platformMouseEvent, true);
1982 #if ENABLE(DRAG_SUPPORT)
1983     if (!swallowEvent)
1984         swallowEvent = handleMouseDraggedEvent(mouseEvent);
1985 #endif
1986
1987     return swallowEvent;
1988 }
1989
1990 void EventHandler::invalidateClick()
1991 {
1992     m_clickCount = 0;
1993     m_clickNode = nullptr;
1994 }
1995
1996 static Node* targetNodeForClickEvent(Node* mousePressNode, Node* mouseReleaseNode)
1997 {
1998     if (!mousePressNode || !mouseReleaseNode)
1999         return nullptr;
2000
2001     if (mousePressNode == mouseReleaseNode)
2002         return mouseReleaseNode;
2003
2004     // If mousePressNode and mouseReleaseNode differ, we should fire the event at their common ancestor if there is one.
2005     if (&mousePressNode->document() == &mouseReleaseNode->document()) {
2006         if (auto* commonAncestor = Range::commonAncestorContainer(mousePressNode, mouseReleaseNode))
2007             return commonAncestor;
2008     }
2009
2010     Element* mouseReleaseShadowHost = mouseReleaseNode->shadowHost();
2011     if (mouseReleaseShadowHost && mouseReleaseShadowHost == mousePressNode->shadowHost()) {
2012         // We want to dispatch the click to the shadow tree host element to give listeners the illusion that the
2013         // shadom tree is a single element. For example, we want to give the illusion that <input type="range">
2014         // is a single element even though it is a composition of multiple shadom tree elements.
2015         return mouseReleaseShadowHost;
2016     }
2017     return nullptr;
2018 }
2019
2020 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& platformMouseEvent)
2021 {
2022     Ref<Frame> protectedFrame(m_frame);
2023     RefPtr<FrameView> protector(m_frame.view());
2024
2025     m_frame.selection().setCaretBlinkingSuspended(false);
2026
2027 #if ENABLE(POINTER_LOCK)
2028     if (m_frame.page()->pointerLockController().isLocked()) {
2029         m_frame.page()->pointerLockController().dispatchLockedMouseEvent(platformMouseEvent, eventNames().mouseupEvent);
2030         return true;
2031     }
2032 #endif
2033
2034     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
2035         return true;
2036
2037 #if ENABLE(TOUCH_EVENTS)
2038     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
2039     if (defaultPrevented)
2040         return true;
2041 #endif
2042
2043     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
2044
2045 #if ENABLE(PAN_SCROLLING)
2046     m_autoscrollController->handleMouseReleaseEvent(platformMouseEvent);
2047 #endif
2048
2049     m_mousePressed = false;
2050     setLastKnownMousePosition(platformMouseEvent);
2051
2052     if (m_svgPan) {
2053         m_svgPan = false;
2054         downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
2055         return true;
2056     }
2057
2058     if (m_frameSetBeingResized)
2059         return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, platformMouseEvent, false);
2060
2061     // If an immediate action began or was completed using this series of mouse events, then we should send mouseup to
2062     // the DOM and return now so that we don't perform our own default behaviors.
2063     if (m_immediateActionStage == ImmediateActionStage::ActionCompleted || m_immediateActionStage == ImmediateActionStage::ActionUpdated || m_immediateActionStage == ImmediateActionStage::ActionCancelledAfterUpdate) {
2064         m_immediateActionStage = ImmediateActionStage::None;
2065         return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), true, m_clickCount, platformMouseEvent, false);
2066     }
2067     m_immediateActionStage = ImmediateActionStage::None;
2068
2069     if (m_lastScrollbarUnderMouse) {
2070         invalidateClick();
2071         m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
2072         bool cancelable = true;
2073         bool setUnder = false;
2074         return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), cancelable, m_clickCount, platformMouseEvent, setUnder);
2075     }
2076
2077     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowUserAgentShadowContent);
2078     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
2079     Frame* subframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
2080     if (m_eventHandlerWillResetCapturingMouseEventsElement)
2081         m_capturingMouseEventsElement = nullptr;
2082     if (subframe && passMouseReleaseEventToSubframe(mouseEvent, subframe))
2083         return true;
2084
2085     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
2086
2087     bool contextMenuEvent = platformMouseEvent.button() == RightButton;
2088
2089     Node* nodeToClick = targetNodeForClickEvent(m_clickNode.get(), mouseEvent.targetNode());
2090     bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && nodeToClick && !dispatchMouseEvent(eventNames().clickEvent, nodeToClick, true, m_clickCount, platformMouseEvent, true);
2091
2092     if (m_resizeLayer) {
2093         m_resizeLayer->setInResizeMode(false);
2094         m_resizeLayer = nullptr;
2095     }
2096
2097     bool swallowMouseReleaseEvent = false;
2098     if (!swallowMouseUpEvent)
2099         swallowMouseReleaseEvent = handleMouseReleaseEvent(mouseEvent);
2100
2101     invalidateClick();
2102
2103     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
2104 }
2105
2106 #if ENABLE(MOUSE_FORCE_EVENTS)
2107 bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& event)
2108 {
2109     Ref<Frame> protectedFrame(m_frame);
2110     RefPtr<FrameView> protector(m_frame.view());
2111
2112 #if ENABLE(POINTER_LOCK)
2113     if (m_frame.page()->pointerLockController().isLocked()) {
2114         m_frame.page()->pointerLockController().dispatchLockedMouseEvent(event, eventNames().webkitmouseforcechangedEvent);
2115         if (event.type() == PlatformEvent::MouseForceDown)
2116             m_frame.page()->pointerLockController().dispatchLockedMouseEvent(event, eventNames().webkitmouseforcedownEvent);
2117         if (event.type() == PlatformEvent::MouseForceUp)
2118             m_frame.page()->pointerLockController().dispatchLockedMouseEvent(event, eventNames().webkitmouseforceupEvent);
2119         return true;
2120     }
2121 #endif
2122
2123     setLastKnownMousePosition(event);
2124
2125     HitTestRequest::HitTestRequestType hitType = HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::Active;
2126
2127     HitTestRequest request(hitType);
2128     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
2129
2130     bool swallowedEvent = !dispatchMouseEvent(eventNames().webkitmouseforcechangedEvent, mouseEvent.targetNode(), false, 0, event, false);
2131     if (event.type() == PlatformEvent::MouseForceDown)
2132         swallowedEvent |= !dispatchMouseEvent(eventNames().webkitmouseforcedownEvent, mouseEvent.targetNode(), false, 0, event, false);
2133     if (event.type() == PlatformEvent::MouseForceUp)
2134         swallowedEvent |= !dispatchMouseEvent(eventNames().webkitmouseforceupEvent, mouseEvent.targetNode(), false, 0, event, false);
2135
2136     return swallowedEvent;
2137 }
2138 #else
2139 bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& )
2140 {
2141     return false;
2142 }
2143 #endif // #if ENABLE(MOUSE_FORCE_EVENTS)
2144
2145 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& platformMouseEvent)
2146 {
2147     // If the event was a middle click, attempt to copy global selection in after
2148     // the newly set caret position.
2149     //
2150     // This code is called from either the mouse up or mouse down handling. There
2151     // is some debate about when the global selection is pasted:
2152     //   xterm: pastes on up.
2153     //   GTK: pastes on down.
2154     //   Qt: pastes on up.
2155     //   Firefox: pastes on up.
2156     //   Chromium: pastes on up.
2157     //
2158     // There is something of a webcompat angle to this well, as highlighted by
2159     // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
2160     // down then the text is pasted just before the onclick handler runs and
2161     // clears the text box. So it's important this happens after the event
2162     // handlers have been fired.
2163 #if PLATFORM(GTK)
2164     if (platformMouseEvent.type() != PlatformEvent::MousePressed)
2165         return false;
2166 #else
2167     if (platformMouseEvent.type() != PlatformEvent::MouseReleased)
2168         return false;
2169 #endif
2170
2171     if (!m_frame.page())
2172         return false;
2173     Frame& focusFrame = m_frame.page()->focusController().focusedOrMainFrame();
2174     // Do not paste here if the focus was moved somewhere else.
2175     if (&m_frame == &focusFrame && m_frame.editor().client()->supportsGlobalSelection())
2176         return m_frame.editor().command(ASCIILiteral("PasteGlobalSelection")).execute();
2177
2178     return false;
2179 }
2180
2181 #if ENABLE(DRAG_SUPPORT)
2182
2183 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Element& dragTarget, const PlatformMouseEvent& event, DataTransfer& dataTransfer)
2184 {
2185     Ref<Frame> protectedFrame(m_frame);
2186     FrameView* view = m_frame.view();
2187
2188     // FIXME: We might want to dispatch a dragleave even if the view is gone.
2189     if (!view)
2190         return false;
2191
2192     view->disableLayerFlushThrottlingTemporarilyForInteraction();
2193     Ref<MouseEvent> me = MouseEvent::create(eventType,
2194         true, true, event.timestamp().approximateMonotonicTime(), m_frame.document()->defaultView(),
2195         0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
2196 #if ENABLE(POINTER_LOCK)
2197         event.movementDelta().x(), event.movementDelta().y(),
2198 #endif
2199         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
2200         0, 0, event.force(), NoTap, &dataTransfer);
2201
2202     dragTarget.dispatchEvent(me);
2203     return me->defaultPrevented();
2204 }
2205
2206 static bool targetIsFrame(Node* target, Frame*& frame)
2207 {
2208     if (!is<HTMLFrameElementBase>(target))
2209         return false;
2210
2211     frame = downcast<HTMLFrameElementBase>(*target).contentFrame();
2212     return true;
2213 }
2214
2215 static DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
2216 {
2217     if (dragOperation == "copy")
2218         return DragOperationCopy;
2219     if (dragOperation == "move")
2220         return DragOperationMove;
2221     if (dragOperation == "link")
2222         return DragOperationLink;
2223     return DragOperationNone;
2224 }
2225
2226 static String convertDragOperationToDropZoneOperation(DragOperation operation)
2227 {
2228     switch (operation) {
2229     case DragOperationCopy:
2230         return ASCIILiteral("copy");
2231     case DragOperationMove:
2232         return ASCIILiteral("move");
2233     case DragOperationLink:
2234         return ASCIILiteral("link");
2235     default:
2236         return ASCIILiteral("copy");
2237     }
2238 }
2239
2240 static bool hasDropZoneType(DataTransfer& dataTransfer, const String& keyword)
2241 {
2242     if (keyword.startsWith("file:"))
2243         return dataTransfer.hasFileOfType(keyword.substring(5));
2244
2245     if (keyword.startsWith("string:"))
2246         return dataTransfer.hasStringOfType(keyword.substring(7));
2247
2248     return false;
2249 }
2250
2251 static bool findDropZone(Node& target, DataTransfer& dataTransfer)
2252 {
2253     RefPtr<Element> element = is<Element>(target) ? &downcast<Element>(target) : target.parentElement();
2254     for (; element; element = element->parentElement()) {
2255         SpaceSplitString keywords(element->attributeWithoutSynchronization(webkitdropzoneAttr), true);
2256         bool matched = false;
2257         DragOperation dragOperation = DragOperationNone;
2258         for (unsigned i = 0, size = keywords.size(); i < size; ++i) {
2259             DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
2260             if (op != DragOperationNone) {
2261                 if (dragOperation == DragOperationNone)
2262                     dragOperation = op;
2263             } else
2264                 matched = matched || hasDropZoneType(dataTransfer, keywords[i].string());
2265             if (matched && dragOperation != DragOperationNone)
2266                 break;
2267         }
2268         if (matched) {
2269             dataTransfer.setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
2270             return true;
2271         }
2272     }
2273     return false;
2274 }
2275
2276 EventHandler::DragTargetResponse EventHandler::dispatchDragEnterOrDragOverEvent(const AtomicString& eventType, Element& target, const PlatformMouseEvent& event,
2277     std::unique_ptr<Pasteboard>&& pasteboard, DragOperation sourceOperation, bool draggingFiles)
2278 {
2279     auto dataTransfer = DataTransfer::createForUpdatingDropTarget(target.document(), WTFMove(pasteboard), sourceOperation, draggingFiles);
2280     bool accept = dispatchDragEvent(eventType, target, event, dataTransfer.get());
2281     if (!accept)
2282         accept = findDropZone(target, dataTransfer);
2283     dataTransfer->makeInvalidForSecurity();
2284     if (accept && !dataTransfer->dropEffectIsUninitialized())
2285         return { true, dataTransfer->destinationOperation() };
2286     return { accept, std::nullopt };
2287 }
2288
2289 EventHandler::DragTargetResponse EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, const std::function<std::unique_ptr<Pasteboard>()>& makePasteboard, DragOperation sourceOperation, bool draggingFiles)
2290 {
2291     Ref<Frame> protectedFrame(m_frame);
2292     if (!m_frame.view())
2293         return { };
2294
2295     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowUserAgentShadowContent);
2296     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
2297
2298     RefPtr<Element> newTarget;
2299     if (Node* targetNode = mouseEvent.targetNode()) {
2300         // Drag events should never go to non-element nodes (following IE, and proper mouseover/out dispatch)
2301         if (!is<Element>(*targetNode))
2302             newTarget = targetNode->parentOrShadowHostElement();
2303         else
2304             newTarget = downcast<Element>(targetNode);
2305     }
2306
2307     m_autoscrollController->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
2308
2309     DragTargetResponse response;
2310     if (m_dragTarget != newTarget) {
2311         // FIXME: this ordering was explicitly chosen to match WinIE. However,
2312         // it is sometimes incorrect when dragging within subframes, as seen with
2313         // LayoutTests/fast/events/drag-in-frames.html.
2314         //
2315         // 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>.
2316         Frame* targetFrame;
2317         if (targetIsFrame(newTarget.get(), targetFrame)) {
2318             if (targetFrame)
2319                 response = targetFrame->eventHandler().updateDragAndDrop(event, makePasteboard, sourceOperation, draggingFiles);
2320         } else if (newTarget) {
2321             // As per section 7.9.4 of the HTML 5 spec., we must always fire a drag event before firing a dragenter, dragleave, or dragover event.
2322             if (dragState().source && dragState().shouldDispatchEvents) {
2323                 // for now we don't care if event handler cancels default behavior, since there is none
2324                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2325             }
2326             response = dispatchDragEnterOrDragOverEvent(eventNames().dragenterEvent, *newTarget, event, makePasteboard(), sourceOperation, draggingFiles);
2327         }
2328
2329         if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2330             // FIXME: Recursing again here doesn't make sense if the newTarget and m_dragTarget were in the same frame.
2331             if (targetFrame)
2332                 response = targetFrame->eventHandler().updateDragAndDrop(event, makePasteboard, sourceOperation, draggingFiles);
2333         } else if (m_dragTarget) {
2334             auto dataTransfer = DataTransfer::createForUpdatingDropTarget(m_dragTarget->document(), makePasteboard(), sourceOperation, draggingFiles);
2335             dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer.get());
2336             dataTransfer->makeInvalidForSecurity();
2337         }
2338
2339         if (newTarget) {
2340             // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
2341             // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function.
2342             m_shouldOnlyFireDragOverEvent = true;
2343         }
2344     } else {
2345         Frame* targetFrame;
2346         if (targetIsFrame(newTarget.get(), targetFrame)) {
2347             if (targetFrame)
2348                 response = targetFrame->eventHandler().updateDragAndDrop(event, makePasteboard, sourceOperation, draggingFiles);
2349         } else if (newTarget) {
2350             // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
2351             if (!m_shouldOnlyFireDragOverEvent && dragState().source && dragState().shouldDispatchEvents) {
2352                 // for now we don't care if event handler cancels default behavior, since there is none
2353                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2354             }
2355             response = dispatchDragEnterOrDragOverEvent(eventNames().dragoverEvent, *newTarget, event, makePasteboard(), sourceOperation, draggingFiles);
2356             m_shouldOnlyFireDragOverEvent = false;
2357         }
2358     }
2359     m_dragTarget = WTFMove(newTarget);
2360     return response;
2361 }
2362
2363 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, std::unique_ptr<Pasteboard>&& pasteboard, DragOperation sourceOperation, bool draggingFiles)
2364 {
2365     Ref<Frame> protectedFrame(m_frame);
2366
2367     Frame* targetFrame;
2368     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2369         if (targetFrame)
2370             targetFrame->eventHandler().cancelDragAndDrop(event, WTFMove(pasteboard), sourceOperation, draggingFiles);
2371     } else if (m_dragTarget) {
2372         if (dragState().source && dragState().shouldDispatchEvents)
2373             dispatchDragSrcEvent(eventNames().dragEvent, event);
2374
2375         auto dataTransfer = DataTransfer::createForUpdatingDropTarget(m_dragTarget->document(), WTFMove(pasteboard), sourceOperation, draggingFiles);
2376         dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer.get());
2377         dataTransfer->makeInvalidForSecurity();
2378     }
2379     clearDragState();
2380 }
2381
2382 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, std::unique_ptr<Pasteboard>&& pasteboard, DragOperation sourceOperation, bool draggingFiles)
2383 {
2384     Ref<Frame> protectedFrame(m_frame);
2385
2386     Frame* targetFrame;
2387     bool preventedDefault = false;
2388     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2389         if (targetFrame)
2390             preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, WTFMove(pasteboard), sourceOperation, draggingFiles);
2391     } else if (m_dragTarget) {
2392         auto dataTransfer = DataTransfer::createForDrop(WTFMove(pasteboard), sourceOperation, draggingFiles);
2393         preventedDefault = dispatchDragEvent(eventNames().dropEvent, *m_dragTarget, event, dataTransfer);
2394         dataTransfer->makeInvalidForSecurity();
2395     }
2396     clearDragState();
2397     return preventedDefault;
2398 }
2399
2400 void EventHandler::clearDragState()
2401 {
2402     stopAutoscrollTimer();
2403     m_dragTarget = nullptr;
2404     m_capturingMouseEventsElement = nullptr;
2405     m_shouldOnlyFireDragOverEvent = false;
2406 #if PLATFORM(COCOA)
2407     m_sendingEventToSubview = false;
2408 #endif
2409 }
2410
2411 #endif // ENABLE(DRAG_SUPPORT)
2412
2413 void EventHandler::setCapturingMouseEventsElement(Element* element)
2414 {
2415     m_capturingMouseEventsElement = element;
2416     m_eventHandlerWillResetCapturingMouseEventsElement = false;
2417 }
2418
2419 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mouseEvent)
2420 {
2421     Ref<Frame> protectedFrame(m_frame);
2422     ASSERT(m_frame.document());
2423     return m_frame.document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mouseEvent.position()), mouseEvent);
2424 }
2425
2426 static RenderElement* nearestCommonHoverAncestor(RenderElement* obj1, RenderElement* obj2)
2427 {
2428     if (!obj1 || !obj2)
2429         return nullptr;
2430
2431     for (RenderElement* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
2432         for (RenderElement* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
2433             if (currObj1 == currObj2)
2434                 return currObj1;
2435         }
2436     }
2437
2438     return nullptr;
2439 }
2440
2441 static bool hierarchyHasCapturingEventListeners(Element* element, const AtomicString& eventName)
2442 {
2443     for (ContainerNode* curr = element; curr; curr = curr->parentOrShadowHostNode()) {
2444         if (curr->hasCapturingEventListeners(eventName))
2445             return true;
2446     }
2447     return false;
2448 }
2449
2450 void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& platformMouseEvent, bool fireMouseOverOut)
2451 {
2452     Ref<Frame> protectedFrame(m_frame);
2453     Element* targetElement = nullptr;
2454     
2455     // If we're capturing, we always go right to that element.
2456     if (m_capturingMouseEventsElement)
2457         targetElement = m_capturingMouseEventsElement.get();
2458     else if (targetNode) {
2459         // If the target node is a non-element, dispatch on the parent. <rdar://problem/4196646>
2460         while (targetNode && !is<Element>(*targetNode))
2461             targetNode = targetNode->parentInComposedTree();
2462         targetElement = downcast<Element>(targetNode);
2463     }
2464
2465     m_elementUnderMouse = targetElement;
2466
2467     // Fire mouseout/mouseover if the mouse has shifted to a different node.
2468     if (fireMouseOverOut) {
2469         auto scrollableAreaForLastNode = enclosingScrollableArea(m_lastElementUnderMouse.get());
2470         auto scrollableAreaForNodeUnderMouse = enclosingScrollableArea(m_elementUnderMouse.get());
2471         Page* page = m_frame.page();
2472
2473         if (m_lastElementUnderMouse && (!m_elementUnderMouse || &m_elementUnderMouse->document() != m_frame.document())) {
2474             // The mouse has moved between frames.
2475             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
2476                 if (FrameView* frameView = frame->view())
2477                     frameView->mouseExitedContentArea();
2478             }
2479         } else if (page && (scrollableAreaForLastNode && (!scrollableAreaForNodeUnderMouse || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
2480             // The mouse has moved between layers.
2481             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
2482                 if (FrameView* frameView = frame->view()) {
2483                     if (frameView->containsScrollableArea(scrollableAreaForLastNode))
2484                         scrollableAreaForLastNode->mouseExitedContentArea();
2485                 }
2486             }
2487         }
2488
2489         if (m_elementUnderMouse && (!m_lastElementUnderMouse || &m_lastElementUnderMouse->document() != m_frame.document())) {
2490             // The mouse has moved between frames.
2491             if (Frame* frame = m_elementUnderMouse->document().frame()) {
2492                 if (FrameView* frameView = frame->view())
2493                     frameView->mouseEnteredContentArea();
2494             }
2495         } else if (page && (scrollableAreaForNodeUnderMouse && (!scrollableAreaForLastNode || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
2496             // The mouse has moved between layers.
2497             if (Frame* frame = m_elementUnderMouse->document().frame()) {
2498                 if (FrameView* frameView = frame->view()) {
2499                     if (frameView->containsScrollableArea(scrollableAreaForNodeUnderMouse))
2500                         scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
2501                 }
2502             }
2503         }
2504
2505         if (m_lastElementUnderMouse && &m_lastElementUnderMouse->document() != m_frame.document()) {
2506             m_lastElementUnderMouse = nullptr;
2507             m_lastScrollbarUnderMouse = nullptr;
2508         }
2509
2510         if (m_lastElementUnderMouse != m_elementUnderMouse) {
2511             // mouseenter and mouseleave events are only dispatched if there is a capturing eventhandler on an ancestor
2512             // or a normal eventhandler on the element itself (they don't bubble).
2513             // This optimization is necessary since these events can cause O(n^2) capturing event-handler checks.
2514             bool hasCapturingMouseEnterListener = hierarchyHasCapturingEventListeners(m_elementUnderMouse.get(), eventNames().mouseenterEvent);
2515             bool hasCapturingMouseLeaveListener = hierarchyHasCapturingEventListeners(m_lastElementUnderMouse.get(), eventNames().mouseleaveEvent);
2516
2517             RenderElement* oldHoverRenderer = m_lastElementUnderMouse ? m_lastElementUnderMouse->renderer() : nullptr;
2518             RenderElement* newHoverRenderer = m_elementUnderMouse ? m_elementUnderMouse->renderer() : nullptr;
2519             RenderElement* ancestor = nearestCommonHoverAncestor(oldHoverRenderer, newHoverRenderer);
2520
2521             Vector<Ref<Element>, 32> leftElementsChain;
2522             if (oldHoverRenderer) {
2523                 for (RenderElement* curr = oldHoverRenderer; curr && curr != ancestor; curr = curr->hoverAncestor()) {
2524                     if (Element* element = curr->element())
2525                         leftElementsChain.append(*element);
2526                 }
2527             } else {
2528                 // If the old hovered element is not null but it's renderer is, it was probably detached.
2529                 // In this case, the old hovered element (and its ancestors) must be updated, to ensure it's normal style is re-applied.
2530                 for (Element* element = m_lastElementUnderMouse.get(); element; element = element->parentElement())
2531                     leftElementsChain.append(*element);
2532             }
2533
2534             Vector<Ref<Element>, 32> enteredElementsChain;
2535             const Element* ancestorElement = ancestor ? ancestor->element() : nullptr;
2536             for (RenderElement* curr = newHoverRenderer; curr; curr = curr->hoverAncestor()) {
2537                 if (Element *element = curr->element()) {
2538                     if (element == ancestorElement)
2539                         break;
2540                     enteredElementsChain.append(*element);
2541                 }
2542             }
2543
2544             // Send mouseout event to the old node.
2545             if (m_lastElementUnderMouse)
2546                 m_lastElementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoutEvent, 0, m_elementUnderMouse.get());
2547
2548             // Send mouseleave to the node hierarchy no longer under the mouse.
2549             for (auto& chain : leftElementsChain) {
2550                 if (hasCapturingMouseLeaveListener || chain->hasEventListeners(eventNames().mouseleaveEvent))
2551                     chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseleaveEvent, 0, m_elementUnderMouse.get());
2552             }
2553
2554             // Send mouseover event to the new node.
2555             if (m_elementUnderMouse)
2556                 m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoverEvent, 0, m_lastElementUnderMouse.get());
2557
2558             // Send mouseleave event to the nodes hierarchy under the mouse.
2559             for (auto& chain : enteredElementsChain) {
2560                 if (hasCapturingMouseEnterListener || chain->hasEventListeners(eventNames().mouseenterEvent))
2561                     chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseenterEvent, 0, m_lastElementUnderMouse.get());
2562             }
2563         }
2564         m_lastElementUnderMouse = m_elementUnderMouse;
2565     }
2566 }
2567
2568 bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& platformMouseEvent, bool setUnder)
2569 {
2570     Ref<Frame> protectedFrame(m_frame);
2571
2572     if (auto* view = m_frame.view())
2573         view->disableLayerFlushThrottlingTemporarilyForInteraction();
2574
2575     updateMouseEventTargetNode(targetNode, platformMouseEvent, setUnder);
2576
2577     if (m_elementUnderMouse && !m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventType, clickCount))
2578         return false;
2579
2580     if (eventType != eventNames().mousedownEvent)
2581         return true;
2582
2583     // If clicking on a frame scrollbar, do not make any change to which element is focused.
2584     auto* view = m_frame.view();
2585     if (view && view->scrollbarAtPoint(platformMouseEvent.position()))
2586         return true;
2587
2588     // The layout needs to be up to date to determine if an element is focusable.
2589     m_frame.document()->updateLayoutIgnorePendingStylesheets();
2590
2591     // Remove focus from the currently focused element when a link or button is clicked.
2592     // This is expected by some sites that rely on change event handlers running
2593     // from form fields before the button click is processed, behavior that was inherited
2594     // from the user interface of Windows, where pushing a button moves focus to the button.
2595
2596     // Walk up the DOM tree to search for an element to focus.
2597     Element* element;
2598     for (element = m_elementUnderMouse.get(); element; element = element->parentOrShadowHostElement()) {
2599         if (element->isMouseFocusable())
2600             break;
2601     }
2602
2603     // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus an
2604     // element on mouse down if it's selected and inside a focused element. It will be
2605     // focused if the user does a mouseup over it, however, because the mouseup
2606     // will set a selection inside it, which will also set the focused element.
2607     if (element && m_frame.selection().isRange()) {
2608         if (auto range = m_frame.selection().toNormalizedRange()) {
2609             auto result = range->compareNode(*element);
2610             if (!result.hasException() && result.releaseReturnValue() == Range::NODE_INSIDE && element->isDescendantOf(m_frame.document()->focusedElement()))
2611                 return true;
2612         }
2613     }
2614
2615     // Only change the focus when clicking scrollbars if it can be transferred to a mouse focusable node.
2616     if (!element && isInsideScrollbar(platformMouseEvent.position()))
2617         return false;
2618
2619     // If focus shift is blocked, we eat the event.
2620     auto* page = m_frame.page();
2621     if (page && !page->focusController().setFocusedElement(element, m_frame))
2622         return false;
2623
2624     return true;
2625 }
2626
2627 bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
2628 {
2629     if (RenderView* renderView = m_frame.contentRenderer()) {
2630         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowUserAgentShadowContent);
2631         HitTestResult result(windowPoint);
2632         renderView->hitTest(request, result);
2633         return result.scrollbar();
2634     }
2635
2636     return false;
2637 }
2638
2639 #if !PLATFORM(GTK) && !PLATFORM(WPE)
2640
2641 bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const
2642 {
2643     return false;
2644 }
2645
2646 #endif
2647
2648 #if !PLATFORM(MAC)
2649
2650 void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, WeakPtr<ScrollableArea>&, bool&)
2651 {
2652 }
2653
2654 void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& event)
2655 {
2656     m_frame.mainFrame().wheelEventDeltaFilter()->updateFromDelta(FloatSize(event.deltaX(), event.deltaY()));
2657 }
2658
2659 bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, ContainerNode*, const WeakPtr<ScrollableArea>&)
2660 {
2661     Ref<Frame> protectedFrame(m_frame);
2662
2663     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
2664     FrameView* view = m_frame.view();
2665     
2666     bool didHandleEvent = view ? view->wheelEvent(event) : false;
2667     m_isHandlingWheelEvent = false;
2668     return didHandleEvent;
2669 }
2670
2671 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode*)
2672 {
2673     return true;
2674 }
2675
2676 void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&)
2677 {
2678 }
2679
2680 IntPoint EventHandler::effectiveMousePositionForSelectionAutoscroll() const
2681 {
2682     return m_lastKnownMousePosition;
2683 }
2684
2685 void EventHandler::clearOrScheduleClearingLatchedStateIfNeeded(const PlatformWheelEvent&)
2686 {
2687     clearLatchedState();
2688 }
2689 #endif
2690
2691 Widget* EventHandler::widgetForEventTarget(Element* eventTarget)
2692 {
2693     if (!eventTarget)
2694         return nullptr;
2695
2696     auto* target = eventTarget->renderer();
2697     if (!is<RenderWidget>(target))
2698         return nullptr;
2699
2700     return downcast<RenderWidget>(*target).widget();
2701 }
2702
2703 static WeakPtr<Widget> widgetForElement(const Element& element)
2704 {
2705     auto target = element.renderer();
2706     if (!is<RenderWidget>(target) || !downcast<RenderWidget>(*target).widget())
2707         return { };
2708
2709     return downcast<RenderWidget>(*target).widget()->createWeakPtr();
2710 }
2711
2712 bool EventHandler::completeWidgetWheelEvent(const PlatformWheelEvent& event, const WeakPtr<Widget>& widget, const WeakPtr<ScrollableArea>& scrollableArea, ContainerNode* scrollableContainer)
2713 {
2714     m_isHandlingWheelEvent = false;
2715     
2716     // We do another check on the widget because the event handler can run JS which results in the frame getting destroyed.
2717     if (!widget)
2718         return false;
2719     
2720     if (scrollableArea)
2721         scrollableArea->setScrolledProgrammatically(false);
2722
2723     platformNotifyIfEndGesture(event, scrollableArea);
2724
2725     if (!widget->platformWidget())
2726         return true;
2727
2728     return platformCompletePlatformWidgetWheelEvent(event, *widget.get(), scrollableContainer);
2729 }
2730
2731 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
2732 {
2733     RenderView* renderView = m_frame.contentRenderer();
2734     if (!renderView)
2735         return false;
2736
2737     Ref<Frame> protectedFrame(m_frame);
2738     RefPtr<FrameView> protector(m_frame.view());
2739
2740     FrameView* view = m_frame.view();
2741     if (!view)
2742         return false;
2743
2744 #if ENABLE(POINTER_LOCK)
2745     if (m_frame.page()->pointerLockController().isLocked()) {
2746         m_frame.page()->pointerLockController().dispatchLockedWheelEvent(event);
2747         return true;
2748     }
2749 #endif
2750
2751     m_isHandlingWheelEvent = true;
2752     setFrameWasScrolledByUser();
2753
2754     HitTestRequest request;
2755     HitTestResult result(view->windowToContents(event.position()));
2756     renderView->hitTest(request, result);
2757
2758     RefPtr<Element> element = result.targetElement();
2759     RefPtr<ContainerNode> scrollableContainer;
2760     WeakPtr<ScrollableArea> scrollableArea;
2761     bool isOverWidget = result.isOverWidget();
2762     platformPrepareForWheelEvents(event, result, element, scrollableContainer, scrollableArea, isOverWidget);
2763
2764 #if PLATFORM(MAC)
2765     if (event.phase() == PlatformWheelEventPhaseNone && event.momentumPhase() == PlatformWheelEventPhaseNone)
2766         m_frame.mainFrame().resetLatchingState();
2767 #endif
2768
2769     // FIXME: It should not be necessary to do this mutation here.
2770     // Instead, the handlers should know convert vertical scrolls appropriately.
2771     PlatformWheelEvent adjustedEvent = event;
2772     if (shouldTurnVerticalTicksIntoHorizontal(result, event))
2773         adjustedEvent = event.copyTurningVerticalTicksIntoHorizontalTicks();
2774
2775     platformRecordWheelEvent(adjustedEvent);
2776
2777     if (element) {
2778         if (isOverWidget) {
2779             if (WeakPtr<Widget> widget = widgetForElement(*element)) {
2780                 if (widgetDidHandleWheelEvent(event, *widget.get()))
2781                     return completeWidgetWheelEvent(adjustedEvent, widget, scrollableArea, scrollableContainer.get());
2782             }
2783         }
2784
2785         if (!element->dispatchWheelEvent(adjustedEvent)) {
2786             m_isHandlingWheelEvent = false;
2787             if (scrollableArea && scrollableArea->isScrolledProgrammatically()) {
2788                 // Web developer is controlling scrolling, so don't attempt to latch.
2789                 clearLatchedState();
2790                 scrollableArea->setScrolledProgrammatically(false);
2791             }
2792
2793             platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
2794             return true;
2795         }
2796     }
2797
2798     if (scrollableArea)
2799         scrollableArea->setScrolledProgrammatically(false);
2800
2801     bool handledEvent = platformCompleteWheelEvent(adjustedEvent, scrollableContainer.get(), scrollableArea);
2802     platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
2803     return handledEvent;
2804 }
2805
2806 void EventHandler::clearLatchedState()
2807 {
2808 #if PLATFORM(MAC)
2809     m_frame.mainFrame().resetLatchingState();
2810 #endif
2811     if (auto filter = m_frame.mainFrame().wheelEventDeltaFilter())
2812         filter->endFilteringDeltas();
2813 }
2814
2815 void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent& wheelEvent)
2816 {
2817     if (!startNode)
2818         return;
2819     
2820     Ref<Frame> protectedFrame(m_frame);
2821
2822     FloatSize filteredPlatformDelta(wheelEvent.deltaX(), wheelEvent.deltaY());
2823     FloatSize filteredVelocity;
2824     if (const PlatformWheelEvent* platformWheelEvent = wheelEvent.wheelEvent()) {
2825         filteredPlatformDelta.setWidth(platformWheelEvent->deltaX());
2826         filteredPlatformDelta.setHeight(platformWheelEvent->deltaY());
2827     }
2828     
2829 #if PLATFORM(MAC)
2830     ScrollLatchingState* latchedState = m_frame.mainFrame().latchingState();
2831     Element* stopElement = latchedState ? latchedState->previousWheelScrolledElement() : nullptr;
2832
2833     if (m_frame.mainFrame().wheelEventDeltaFilter()->isFilteringDeltas()) {
2834         filteredPlatformDelta = m_frame.mainFrame().wheelEventDeltaFilter()->filteredDelta();
2835         filteredVelocity = m_frame.mainFrame().wheelEventDeltaFilter()->filteredVelocity();
2836     }
2837 #else
2838     Element* stopElement = nullptr;
2839 #endif
2840     
2841     
2842     if (handleWheelEventInAppropriateEnclosingBox(startNode, wheelEvent, &stopElement, filteredPlatformDelta, filteredVelocity))
2843         wheelEvent.setDefaultHandled();
2844     
2845 #if PLATFORM(MAC)
2846     if (latchedState && !latchedState->wheelEventElement())
2847         latchedState->setPreviousWheelScrolledElement(stopElement);
2848 #endif
2849 }
2850
2851 #if ENABLE(CONTEXT_MENUS)
2852 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2853 {
2854     Ref<Frame> protectedFrame(m_frame);
2855
2856     Document* doc = m_frame.document();
2857     FrameView* view = m_frame.view();
2858     if (!view)
2859         return false;
2860
2861     // Clear mouse press state to avoid initiating a drag while context menu is up.
2862     m_mousePressed = false;
2863     bool swallowEvent;
2864     LayoutPoint viewportPos = view->windowToContents(event.position());
2865     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent);
2866     MouseEventWithHitTestResults mouseEvent = doc->prepareMouseEvent(request, viewportPos, event);
2867
2868     // Do not show context menus when clicking on scrollbars.
2869     if (mouseEvent.scrollbar() || view->scrollbarAtPoint(event.position()))
2870         return false;
2871
2872     if (m_frame.editor().behavior().shouldSelectOnContextualMenuClick()
2873         && !m_frame.selection().contains(viewportPos)
2874         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
2875         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
2876         // available for text selections.  But only if we're above text.
2877         && (m_frame.selection().selection().isContentEditable() || (mouseEvent.targetNode() && mouseEvent.targetNode()->isTextNode()))) {
2878         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
2879         selectClosestContextualWordOrLinkFromMouseEvent(mouseEvent);
2880     }
2881
2882     swallowEvent = !dispatchMouseEvent(eventNames().contextmenuEvent, mouseEvent.targetNode(), true, 0, event, false);
2883     
2884     return swallowEvent;
2885 }
2886
2887 bool EventHandler::sendContextMenuEventForKey()
2888 {
2889     Ref<Frame> protectedFrame(m_frame);
2890
2891     FrameView* view = m_frame.view();
2892     if (!view)
2893         return false;
2894
2895     Document* doc = m_frame.document();
2896     if (!doc)
2897         return false;
2898
2899     // Clear mouse press state to avoid initiating a drag while context menu is up.
2900     m_mousePressed = false;
2901
2902     static const int kContextMenuMargin = 1;
2903
2904 #if OS(WINDOWS)
2905     int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
2906 #else
2907     int rightAligned = 0;
2908 #endif
2909     IntPoint location;
2910
2911     Element* focusedElement = doc->focusedElement();
2912     const VisibleSelection& selection = m_frame.selection().selection();
2913     Position start = selection.start();
2914
2915     if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
2916         RefPtr<Range> selectionRange = selection.toNormalizedRange();
2917         IntRect firstRect = m_frame.editor().firstRectForRange(selectionRange.get());
2918
2919         int x = rightAligned ? firstRect.maxX() : firstRect.x();
2920         // In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
2921         int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
2922         location = IntPoint(x, y);
2923     } else if (focusedElement) {
2924         RenderBoxModelObject* box = focusedElement->renderBoxModelObject();
2925         if (!box)
2926             return false;
2927
2928         IntRect boundingBoxRect = box->absoluteBoundingBoxRect(true);
2929         location = IntPoint(boundingBoxRect.x(), boundingBoxRect.maxY() - 1);
2930     } else {
2931         location = IntPoint(
2932             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
2933             kContextMenuMargin);
2934     }
2935
2936     m_frame.view()->setCursor(pointerCursor());
2937
2938     IntPoint position = view->contentsToRootView(location);
2939     IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
2940
2941     Node* targetNode = doc->focusedElement();
2942     if (!targetNode)
2943         targetNode = doc;
2944
2945     // Use the focused node as the target for hover and active.
2946     HitTestResult result(position);
2947     result.setInnerNode(targetNode);
2948     doc->updateHoverActiveState(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent, result.targetElement());
2949
2950     // The contextmenu event is a mouse event even when invoked using the keyboard.
2951     // This is required for web compatibility.
2952
2953 #if OS(WINDOWS)
2954     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2955 #else
2956     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2957 #endif
2958
2959     PlatformMouseEvent platformMouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WallTime::now(), ForceAtClick, NoTap);
2960
2961     return sendContextMenuEvent(platformMouseEvent);
2962 }
2963 #endif // ENABLE(CONTEXT_MENUS)
2964
2965 void EventHandler::scheduleHoverStateUpdate()
2966 {
2967     if (!m_hoverTimer.isActive())
2968         m_hoverTimer.startOneShot(0_s);
2969 }
2970
2971 #if ENABLE(CURSOR_SUPPORT)
2972 void EventHandler::scheduleCursorUpdate()
2973 {
2974     if (!m_cursorUpdateTimer.isActive())
2975         m_cursorUpdateTimer.startOneShot(cursorUpdateInterval);
2976 }
2977 #endif
2978
2979 void EventHandler::dispatchFakeMouseMoveEventSoon()
2980 {
2981 #if !ENABLE(IOS_TOUCH_EVENTS)
2982     if (m_mousePressed)
2983         return;
2984
2985     if (m_mousePositionIsUnknown)
2986         return;
2987
2988     if (Page* page = m_frame.page()) {
2989         if (!page->chrome().client().shouldDispatchFakeMouseMoveEvents())
2990             return;
2991     }
2992
2993     // If the content has ever taken longer than fakeMouseMoveShortInterval we
2994     // reschedule the timer and use a longer time. This will cause the content
2995     // to receive these moves only after the user is done scrolling, reducing
2996     // pauses during the scroll.
2997     if (m_fakeMouseMoveEventTimer.isActive())
2998         m_fakeMouseMoveEventTimer.stop();
2999     m_fakeMouseMoveEventTimer.startOneShot(m_maxMouseMovedDuration > fakeMouseMoveDurationThreshold ? fakeMouseMoveLongInterval : fakeMouseMoveShortInterval);
3000 #endif
3001 }
3002
3003 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
3004 {
3005 #if ENABLE(IOS_TOUCH_EVENTS)
3006     UNUSED_PARAM(quad);
3007 #else
3008     FrameView* view = m_frame.view();
3009     if (!view)
3010         return;
3011
3012     if (!quad.containsPoint(view->windowToContents(m_lastKnownMousePosition)))
3013         return;
3014
3015     dispatchFakeMouseMoveEventSoon();
3016 #endif
3017 }
3018
3019 #if !ENABLE(IOS_TOUCH_EVENTS)
3020 void EventHandler::cancelFakeMouseMoveEvent()
3021 {
3022     m_fakeMouseMoveEventTimer.stop();
3023 }
3024
3025 void EventHandler::fakeMouseMoveEventTimerFired()
3026 {
3027     ASSERT(!m_mousePressed);
3028
3029     FrameView* view = m_frame.view();
3030     if (!view)
3031         return;
3032
3033     if (!m_frame.page() || !m_frame.page()->isVisible() || !m_frame.page()->focusController().isActive())
3034         return;
3035
3036     bool shiftKey;
3037     bool ctrlKey;
3038     bool altKey;
3039     bool metaKey;
3040     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
3041     PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, WallTime::now(), 0, NoTap);
3042     mouseMoved(fakeMouseMoveEvent);
3043 }
3044 #endif // !ENABLE(IOS_TOUCH_EVENTS)
3045
3046 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
3047 {
3048     m_frameSetBeingResized = frameSet;
3049 }
3050
3051 void EventHandler::resizeLayerDestroyed()
3052 {
3053     ASSERT(m_resizeLayer);
3054     m_resizeLayer = nullptr;
3055 }
3056
3057 void EventHandler::hoverTimerFired()
3058 {
3059     m_hoverTimer.stop();
3060
3061     ASSERT(m_frame.document());
3062
3063     Ref<Frame> protectedFrame(m_frame);
3064
3065     if (RenderView* renderView = m_frame.contentRenderer()) {
3066         if (FrameView* view = m_frame.view()) {
3067             HitTestRequest request(HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent);
3068             HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
3069             renderView->hitTest(request, result);
3070             m_frame.document()->updateHoverActiveState(request, result.targetElement());
3071         }
3072     }
3073 }
3074
3075 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& event)
3076 {
3077     // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
3078     // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
3079     // lower case variants are present in a document, the correct element is matched based on Shift key state.
3080     // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
3081     ASSERT(!accessKeyModifiers().contains(PlatformEvent::Modifier::ShiftKey));
3082
3083     if ((event.modifiers() - PlatformEvent::Modifier::ShiftKey) != accessKeyModifiers())
3084         return false;
3085     Element* element = m_frame.document()->getElementByAccessKey(event.unmodifiedText());
3086     if (!element)
3087         return false;
3088     element->accessKeyAction(false);
3089     return true;
3090 }
3091
3092 #if !PLATFORM(MAC)
3093 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
3094 {
3095     return false;
3096 }
3097 #endif
3098
3099 #if ENABLE(FULLSCREEN_API)
3100 bool EventHandler::isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent& keyEvent) const
3101 {
3102     Document* document = m_frame.document();
3103     if (document->webkitFullScreenKeyboardInputAllowed())
3104         return true;
3105
3106     if (keyEvent.type() == PlatformKeyboardEvent::Char) {
3107         if (keyEvent.text().length() != 1)
3108             return false;
3109         UChar character = keyEvent.text()[0];
3110         return character == ' ';
3111     }
3112
3113     int keyCode = keyEvent.windowsVirtualKeyCode();
3114     return (keyCode >= VK_BACK && keyCode <= VK_CAPITAL)
3115         || (keyCode >= VK_SPACE && keyCode <= VK_DELETE)
3116         || (keyCode >= VK_OEM_1 && keyCode <= VK_OEM_PLUS)
3117         || (keyCode >= VK_MULTIPLY && keyCode <= VK_OEM_8);
3118 }
3119 #endif
3120
3121 bool EventHandler::keyEvent(const PlatformKeyboardEvent& keyEvent)
3122 {
3123     Document* topDocument = m_frame.document() ? &m_frame.document()->topDocument() : nullptr;
3124     bool savedUserDidInteractWithPage = topDocument ? topDocument->userDidInteractWithPage() : false;
3125     bool wasHandled = internalKeyEvent(keyEvent);
3126
3127     // If the key event was not handled, do not treat it as user interaction with the page.
3128     if (topDocument && !wasHandled)
3129         topDocument->setUserDidInteractWithPage(savedUserDidInteractWithPage);
3130
3131     return wasHandled;
3132 }
3133
3134 bool EventHandler::internalKeyEvent(const PlatformKeyboardEvent& initialKeyEvent)
3135 {
3136     Ref<Frame> protectedFrame(m_frame);
3137     RefPtr<FrameView> protector(m_frame.view());
3138
3139     LOG(Editing, "EventHandler %p keyEvent (text %s keyIdentifier %s)", this, initialKeyEvent.text().utf8().data(), initialKeyEvent.keyIdentifier().utf8().data());
3140
3141 #if ENABLE(POINTER_LOCK)
3142     if (initialKeyEvent.type() == PlatformEvent::KeyDown && initialKeyEvent.windowsVirtualKeyCode() == VK_ESCAPE && m_frame.page()->pointerLockController().element()) {
3143         m_frame.page()->pointerLockController().requestPointerUnlockAndForceCursorVisible();
3144     }
3145 #endif
3146
3147     if (initialKeyEvent.type() == PlatformEvent::KeyDown && initialKeyEvent.windowsVirtualKeyCode() == VK_ESCAPE) {
3148         if (auto* page = m_frame.page()) {
3149             if (auto* validationMessageClient = page->validationMessageClient())
3150                 validationMessageClient->hideAnyValidationMessage();
3151         }
3152     }
3153
3154 #if ENABLE(FULLSCREEN_API)
3155     if (m_frame.document()->webkitIsFullScreen()) {
3156         if (initialKeyEvent.type() == PlatformEvent::KeyDown && initialKeyEvent.windowsVirtualKeyCode() == VK_ESCAPE) {
3157             m_frame.document()->webkitCancelFullScreen();
3158             return true;
3159         }
3160
3161         if (!isKeyEventAllowedInFullScreen(initialKeyEvent))
3162             return false;
3163     }
3164 #endif
3165
3166     if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL) {
3167         if (auto* element = m_frame.document()->focusedElement()) {
3168             if (is<HTMLInputElement>(*element))
3169                 downcast<HTMLInputElement>(*element).capsLockStateMayHaveChanged();
3170         }
3171     }
3172
3173 #if ENABLE(PAN_SCROLLING)
3174     if (m_frame.mainFrame().eventHandler().panScrollInProgress()) {
3175         // If a key is pressed while the panScroll is in progress then we want to stop
3176         if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown)
3177             stopAutoscrollTimer();
3178
3179         // If we were in panscroll mode, we swallow the key event
3180         return true;
3181     }
3182 #endif
3183
3184     // Check for cases where we are too early for events -- possible unmatched key up
3185     // from pressing return in the location bar.
3186     RefPtr<Element> element = eventTargetElementForDocument(m_frame.document());
3187     if (!element)
3188         return false;
3189
3190     UserGestureType gestureType = UserGestureType::Other;
3191     if (initialKeyEvent.windowsVirtualKeyCode() == VK_ESCAPE)
3192         gestureType = UserGestureType::EscapeKey;
3193
3194     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document(), gestureType);
3195     UserTypingGestureIndicator typingGestureIndicator(m_frame);
3196
3197     if (FrameView* view = m_frame.view())
3198         view->disableLayerFlushThrottlingTemporarilyForInteraction();
3199
3200     // FIXME (bug 68185): this call should be made at another abstraction layer
3201     m_frame.loader().resetMultipleFormSubmissionProtection();
3202
3203     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
3204     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
3205     // with access keys. Then we dispatch keydown, but suppress its default handling.
3206     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
3207     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
3208     bool matchedAnAccessKey = false;
3209     if (initialKeyEvent.type() == PlatformEvent::KeyDown)
3210         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
3211
3212     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
3213     if (initialKeyEvent.type() == PlatformEvent::KeyUp || initialKeyEvent.type() == PlatformEvent::Char)
3214         return !element->dispatchKeyEvent(initialKeyEvent);
3215
3216     bool backwardCompatibilityMode = needsKeyboardEventDisambiguationQuirks();
3217
3218     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;    
3219     if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
3220         keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown, backwardCompatibilityMode);
3221     Ref<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
3222     if (matchedAnAccessKey)
3223         keydown->setDefaultPrevented(true);
3224     keydown->setTarget(element);
3225
3226     if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
3227         element->dispatchEvent(keydown);
3228         // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
3229         bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
3230         return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3231     }
3232
3233     // Run input method in advance of DOM event handling.  This may result in the IM
3234     // modifying the page prior the keydown event, but this behaviour is necessary
3235     // in order to match IE:
3236     // 1. preventing default handling of keydown and keypress events has no effect on IM input;
3237     // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
3238     m_frame.editor().handleInputMethodKeydown(keydown.get());
3239     
3240     bool handledByInputMethod = keydown->defaultHandled();
3241     
3242     if (handledByInputMethod) {
3243         keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
3244         keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
3245         keydown->setTarget(element);
3246         keydown->setDefaultHandled();
3247     }
3248     
3249     if (accessibilityPreventsEventPropogation(keydown))
3250         keydown->stopPropagation();
3251
3252     element->dispatchEvent(keydown);
3253     // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
3254     bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
3255     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3256     if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
3257         return keydownResult;
3258     
3259     // Focus may have changed during keydown handling, so refetch element.
3260     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original element.
3261     if (!keydownResult) {
3262         element = eventTargetElementForDocument(m_frame.document());
3263         if (!element)
3264             return false;
3265     }
3266
3267     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
3268     keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char, backwardCompatibilityMode);
3269     if (keyPressEvent.text().isEmpty())
3270         return keydownResult;
3271     Ref<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame.document()->defaultView());
3272     keypress->setTarget(element);
3273     if (keydownResult)
3274         keypress->setDefaultPrevented(true);
3275 #if PLATFORM(COCOA)
3276     keypress->keypressCommands() = keydown->keypressCommands();
3277 #endif
3278     element->dispatchEvent(keypress);
3279
3280     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
3281 }
3282
3283 static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
3284 {
3285     static NeverDestroyed<AtomicString> Down("Down", AtomicString::ConstructFromLiteral);
3286     static NeverDestroyed<AtomicString> Up("Up", AtomicString::ConstructFromLiteral);
3287     static NeverDestroyed<AtomicString> Left("Left", AtomicString::ConstructFromLiteral);
3288     static NeverDestroyed<AtomicString> Right("Right", AtomicString::ConstructFromLiteral);
3289
3290     FocusDirection retVal = FocusDirectionNone;
3291
3292     if (keyIdentifier == Down)
3293         retVal = FocusDirectionDown;
3294     else if (keyIdentifier == Up)
3295         retVal = FocusDirectionUp;
3296     else if (keyIdentifier == Left)
3297         retVal = FocusDirectionLeft;
3298     else if (keyIdentifier == Right)
3299         retVal = FocusDirectionRight;
3300
3301     return retVal;
3302 }
3303
3304 static void setInitialKeyboardSelection(Frame& frame, SelectionDirection direction)
3305 {
3306     Document* document = frame.document();
3307     if (!document)
3308         return;
3309
3310     FrameSelection& selection = frame.selection();
3311
3312     if (!selection.isNone())
3313         return;
3314
3315     Element* focusedElement = document->focusedElement();
3316     VisiblePosition visiblePosition;
3317
3318     switch (direction) {
3319     case DirectionBackward:
3320     case DirectionLeft:
3321         if (focusedElement)
3322             visiblePosition = VisiblePosition(positionBeforeNode(focusedElement));
3323         else
3324             visiblePosition = endOfDocument(document);
3325         break;
3326     case DirectionForward:
3327     case DirectionRight:
3328         if (focusedElement)
3329             visiblePosition = VisiblePosition(positionAfterNode(focusedElement));
3330         else
3331             visiblePosition = startOfDocument(document);
3332         break;
3333     }
3334
3335     AXTextStateChangeIntent intent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, false });
3336     selection.setSelection(visiblePosition, FrameSelection::defaultSetSelectionOptions(UserTriggered), intent);
3337 }
3338
3339 static void handleKeyboardSelectionMovement(Frame& frame, KeyboardEvent& event)
3340 {
3341     FrameSelection& selection = frame.selection();
3342
3343     bool isCommanded = event.getModifierState("Meta");
3344     bool isOptioned = event.getModifierState("Alt");
3345     bool isSelection = !selection.isNone();
3346
3347     FrameSelection::EAlteration alternation = event.getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
3348     SelectionDirection direction = DirectionForward;
3349     TextGranularity granularity = CharacterGranularity;
3350
3351     switch (focusDirectionForKey(event.keyIdentifier())) {
3352     case FocusDirectionNone:
3353         return;
3354     case FocusDirectionForward:
3355     case FocusDirectionBackward:
3356         ASSERT_NOT_REACHED();
3357         return;
3358     case FocusDirectionUp:
3359         direction = DirectionBackward;
3360         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3361         break;
3362     case FocusDirectionDown:
3363         direction = DirectionForward;
3364         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3365         break;
3366     case FocusDirectionLeft:
3367         direction = DirectionLeft;
3368         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3369         break;
3370     case FocusDirectionRight:
3371         direction = DirectionRight;
3372         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3373         break;
3374     }
3375
3376     if (isSelection)
3377         selection.modify(alternation, direction, granularity, UserTriggered);
3378     else
3379         setInitialKeyboardSelection(frame, direction);
3380
3381     event.setDefaultHandled();
3382 }
3383
3384 void EventHandler::handleKeyboardSelectionMovementForAccessibility(KeyboardEvent& event)
3385 {
3386     if (event.type() == eventNames().keydownEvent) {
3387         if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3388             handleKeyboardSelectionMovement(m_frame, event);
3389     }
3390 }
3391
3392 bool EventHandler::accessibilityPreventsEventPropogation(KeyboardEvent& event)
3393 {
3394 #if PLATFORM(COCOA)
3395     if (!AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3396         return false;
3397
3398     if (!m_frame.settings().preventKeyboardDOMEventDispatch())
3399         return false;
3400
3401     // Check for key events that are relevant to accessibility: tab and arrows keys that change focus
3402     if (event.keyIdentifier() == "U+0009")
3403         return true;
3404     FocusDirection direction = focusDirectionForKey(event.keyIdentifier());
3405     if (direction != FocusDirectionNone)
3406         return true;
3407 #else
3408     UNUSED_PARAM(event);
3409 #endif
3410     return false;
3411 }
3412
3413 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent& event)
3414 {
3415     Ref<Frame> protectedFrame(m_frame);
3416
3417     if (event.type() == eventNames().keydownEvent) {
3418         m_frame.editor().handleKeyboardEvent(event);
3419         if (event.defaultHandled())
3420             return;
3421         if (event.keyIdentifier() == "U+0009")
3422             defaultTabEventHandler(event);
3423         else if (event.keyIdentifier() == "U+0008")
3424             defaultBackspaceEventHandler(event);
3425         else {
3426             FocusDirection direction = focusDirectionForKey(event.keyIdentifier());
3427             if (direction != FocusDirectionNone)
3428                 defaultArrowEventHandler(direction, event);
3429         }
3430
3431         handleKeyboardSelectionMovementForAccessibility(event);
3432     }
3433     if (event.type() == eventNames().keypressEvent) {
3434         m_frame.editor().handleKeyboardEvent(event);
3435         if (event.defaultHandled())
3436             return;
3437         if (event.charCode() == ' ')
3438             defaultSpaceEventHandler(event);
3439     }
3440 }
3441
3442 #if ENABLE(DRAG_SUPPORT)
3443 bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocation) const
3444 {
3445     FloatPoint dragViewportLocation(floatDragViewportLocation.x(), floatDragViewportLocation.y());
3446     return dragHysteresisExceeded(dragViewportLocation);
3447 }
3448
3449 bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
3450 {
3451     int threshold = GeneralDragHysteresis;
3452     switch (dragState().type) {
3453     case DragSourceActionSelection:
3454         threshold = TextDragHysteresis;
3455         break;
3456     case DragSourceActionImage:
3457 #if ENABLE(ATTACHMENT_ELEMENT)
3458     case DragSourceActionAttachment:
3459 #endif
3460         threshold = ImageDragHysteresis;
3461         break;
3462     case DragSourceActionLink:
3463         threshold = LinkDragHysteresis;
3464         break;
3465     case DragSourceActionDHTML:
3466         break;
3467     case DragSourceActionNone:
3468     case DragSourceActionAny:
3469         ASSERT_NOT_REACHED();
3470     }
3471     
3472     return mouseMovementExceedsThreshold(dragViewportLocation, threshold);
3473 }
3474     
3475 void EventHandler::invalidateDataTransfer()
3476 {
3477     if (!dragState().dataTransfer)
3478         return;
3479     dragState().dataTransfer->makeInvalidForSecurity();
3480     dragState().dataTransfer = nullptr;
3481 }
3482
3483 static void removeDraggedContentDocumentMarkersFromAllFramesInPage(Page& page)
3484 {
3485     for (Frame* frame = &page.mainFrame(); frame; frame = frame->tree().traverseNext()) {
3486         if (auto* document = frame->document())
3487             document->markers().removeMarkers(DocumentMarker::DraggedContent);
3488     }
3489
3490     if (auto* mainFrameRenderer = page.mainFrame().contentRenderer())
3491         mainFrameRenderer->repaintRootContents();
3492 }
3493
3494 void EventHandler::dragCancelled()
3495 {
3496 #if ENABLE(DATA_INTERACTION)
3497     if (auto* page = m_frame.page())
3498         removeDraggedContentDocumentMarkersFromAllFramesInPage(*page);
3499 #endif