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