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