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