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