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