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