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