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