Hovering over a slotted Text node clears hover state
[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     Element* targetElement = result.targetElement();
896     return targetElement && page->dragController().draggableElement(&m_frame, targetElement, result.roundedPointInInnerNodeFrame(), state);
897 }
898
899 void EventHandler::updateSelectionForMouseDrag()
900 {
901     FrameView* view = m_frame.view();
902     if (!view)
903         return;
904     RenderView* renderView = m_frame.contentRenderer();
905     if (!renderView)
906         return;
907
908     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent);
909     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
910     renderView->hitTest(request, result);
911     updateSelectionForMouseDrag(result);
912 }
913
914 static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const LayoutPoint& localPoint, Node* targetNode)
915 {
916     FloatPoint selectionEndPoint = localPoint;
917     Element* editableElement = selection.rootEditableElement();
918
919     if (!targetNode->renderer())
920         return VisiblePosition();
921
922     if (editableElement && !editableElement->contains(targetNode)) {
923         if (!editableElement->renderer())
924             return VisiblePosition();
925
926         FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint));
927         selectionEndPoint = editableElement->renderer()->absoluteToLocal(absolutePoint);
928         targetNode = editableElement;
929     }
930
931     return targetNode->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
932 }
933
934 void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
935 {
936     if (!m_mouseDownMayStartSelect)
937         return;
938
939     Node* target = hitTestResult.targetNode();
940     if (!target)
941         return;
942
943     VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(m_frame.selection().selection(), hitTestResult.localPoint(), target);
944
945     // Don't modify the selection if we're not on a node.
946     if (targetPosition.isNull())
947         return;
948
949     // Restart the selection if this is the first mouse move. This work is usually
950     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
951     VisibleSelection newSelection = m_frame.selection().selection();
952
953     // Special case to limit selection to the containing block for SVG text.
954     // FIXME: Isn't there a better non-SVG-specific way to do this?
955     if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
956         if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
957             if (selectionBaseRenderer->isSVGText())
958                 if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
959                     return;
960
961     if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
962         return;
963
964     if (m_selectionInitiationState != ExtendedSelection) {
965         // Always extend selection here because it's caused by a mouse drag
966         m_selectionInitiationState = ExtendedSelection;
967         newSelection = VisibleSelection(targetPosition);
968     }
969
970 #if ENABLE(USERSELECT_ALL)
971     Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllForNode(m_mousePressNode.get());
972     if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePressNode == Position::rootUserSelectAllForNode(target)) {
973         newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePressNode).upstream(CanCrossEditingBoundary));
974         newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
975     } else {
976         // Reset base for user select all when base is inside user-select-all area and extent < base.
977         if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos, nullptr)) < 0)
978             newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
979         
980         Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
981         if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos, nullptr)) < 0)
982             newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
983         else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
984             newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
985         else
986             newSelection.setExtent(targetPosition);
987     }
988 #else
989     newSelection.setExtent(targetPosition);
990 #endif
991
992     if (m_frame.selection().granularity() != CharacterGranularity)
993         newSelection.expandUsingGranularity(m_frame.selection().granularity());
994
995     m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
996         FrameSelection::AdjustEndpointsAtBidiBoundary);
997 }
998 #endif // ENABLE(DRAG_SUPPORT)
999
1000 void EventHandler::lostMouseCapture()
1001 {
1002     m_frame.selection().setCaretBlinkingSuspended(false);
1003 }
1004
1005 bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
1006 {
1007     if (eventLoopHandleMouseUp(event))
1008         return true;
1009     
1010     // If this was the first click in the window, we don't even want to clear the selection.
1011     // This case occurs when the user clicks on a draggable element, since we have to process
1012     // the mouse down and drag events to see if we might start a drag.  For other first clicks
1013     // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets
1014     // ignored upstream of this layer.
1015     return eventActivatedView(event.event());
1016 }    
1017
1018 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
1019 {
1020     if (autoscrollInProgress())
1021         stopAutoscrollTimer();
1022
1023     Ref<Frame> protectedFrame(m_frame);
1024
1025     if (handleMouseUp(event))
1026         return true;
1027
1028     // Used to prevent mouseMoveEvent from initiating a drag before
1029     // the mouse is pressed again.
1030     m_mousePressed = false;
1031     m_capturesDragging = false;
1032 #if ENABLE(DRAG_SUPPORT)
1033     m_mouseDownMayStartDrag = false;
1034 #endif
1035     m_mouseDownMayStartSelect = false;
1036     m_mouseDownMayStartAutoscroll = false;
1037     m_mouseDownWasInSubframe = false;
1038   
1039     bool handled = false;
1040
1041     // Clear the selection if the mouse didn't move after the last mouse
1042     // press and it's not a context menu click.  We do this so when clicking
1043     // on the selection, the selection goes away.  However, if we are
1044     // editing, place the caret.
1045     if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
1046 #if ENABLE(DRAG_SUPPORT)
1047             && m_dragStartPos == event.event().position()
1048 #endif
1049             && m_frame.selection().isRange()
1050             && event.event().button() != RightButton) {
1051         VisibleSelection newSelection;
1052         Node* node = event.targetNode();
1053         bool caretBrowsing = m_frame.settings().caretBrowsingEnabled();
1054         if (node && node->renderer() && (caretBrowsing || node->hasEditableStyle())) {
1055             VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint(), nullptr);
1056             newSelection = VisibleSelection(pos);
1057         }
1058
1059         setSelectionIfNeeded(m_frame.selection(), newSelection);
1060
1061         handled = true;
1062     }
1063
1064     if (event.event().button() == MiddleButton) {
1065         // Ignore handled, since we want to paste to where the caret was placed anyway.
1066         handled = handlePasteGlobalSelection(event.event()) || handled;
1067     }
1068
1069     return handled;
1070 }
1071
1072 #if ENABLE(PAN_SCROLLING)
1073
1074 void EventHandler::didPanScrollStart()
1075 {
1076     m_autoscrollController->didPanScrollStart();
1077 }
1078
1079 void EventHandler::didPanScrollStop()
1080 {
1081     m_autoscrollController->didPanScrollStop();
1082 }
1083
1084 void EventHandler::startPanScrolling(RenderElement* renderer)
1085 {
1086 #if !PLATFORM(IOS)
1087     if (!is<RenderBox>(*renderer))
1088         return;
1089     m_autoscrollController->startPanScrolling(downcast<RenderBox>(renderer), lastKnownMousePosition());
1090     invalidateClick();
1091 #endif
1092 }
1093
1094 #endif // ENABLE(PAN_SCROLLING)
1095
1096 RenderBox* EventHandler::autoscrollRenderer() const
1097 {
1098     return m_autoscrollController->autoscrollRenderer();
1099 }
1100
1101 void EventHandler::updateAutoscrollRenderer()
1102 {
1103     m_autoscrollController->updateAutoscrollRenderer();
1104 }
1105
1106 bool EventHandler::autoscrollInProgress() const
1107 {
1108     return m_autoscrollController->autoscrollInProgress();
1109 }
1110
1111 bool EventHandler::panScrollInProgress() const
1112 {
1113     return m_autoscrollController->panScrollInProgress();
1114 }
1115
1116 #if ENABLE(DRAG_SUPPORT)
1117 DragSourceAction EventHandler::updateDragSourceActionsAllowed() const
1118 {
1119     Page* page = m_frame.page();
1120     if (!page)
1121         return DragSourceActionNone;
1122
1123     FrameView* view = m_frame.view();
1124     if (!view)
1125         return DragSourceActionNone;
1126
1127     return page->dragController().delegateDragSourceAction(view->contentsToRootView(m_mouseDownPos));
1128 }
1129 #endif // ENABLE(DRAG_SUPPORT)
1130
1131 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding)
1132 {
1133     Ref<Frame> protectedFrame(m_frame);
1134
1135     // We always send hitTestResultAtPoint to the main frame if we have one,
1136     // otherwise we might hit areas that are obscured by higher frames.
1137     if (!m_frame.isMainFrame()) {
1138         Frame& mainFrame = m_frame.mainFrame();
1139         FrameView* frameView = m_frame.view();
1140         FrameView* mainView = mainFrame.view();
1141         if (frameView && mainView) {
1142             IntPoint mainFramePoint = mainView->rootViewToContents(frameView->contentsToRootView(roundedIntPoint(point)));
1143             return mainFrame.eventHandler().hitTestResultAtPoint(mainFramePoint, hitType, padding);
1144         }
1145     }
1146
1147     unsigned nonNegativePaddingWidth = std::max<LayoutUnit>(0, padding.width()).toUnsigned();
1148     unsigned nonNegativePaddingHeight = std::max<LayoutUnit>(0, padding.height()).toUnsigned();
1149
1150     // We should always start hit testing a clean tree.
1151     if (auto* frameView = m_frame.view())
1152         frameView->updateLayoutAndStyleIfNeededRecursive();
1153
1154     HitTestResult result(point, nonNegativePaddingHeight, nonNegativePaddingWidth, nonNegativePaddingHeight, nonNegativePaddingWidth);
1155     RenderView* renderView = m_frame.contentRenderer();
1156     if (!renderView)
1157         return result;
1158
1159     // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
1160     HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
1161     renderView->hitTest(request, result);
1162     if (!request.readOnly())
1163         m_frame.document()->updateHoverActiveState(request, result.targetElement());
1164
1165     if (request.disallowsUserAgentShadowContent())
1166         result.setToNonUserAgentShadowAncestor();
1167
1168     return result;
1169 }
1170
1171 void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
1172 {
1173     m_autoscrollController->stopAutoscrollTimer(rendererIsBeingDestroyed);
1174 }
1175
1176 bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1177 {
1178     Node* node = startingNode;
1179
1180     if (!node)
1181         node = m_frame.document()->focusedElement();
1182
1183     if (!node)
1184         node = m_mousePressNode.get();
1185     
1186     if (node) {
1187         auto r = node->renderer();
1188         if (r && !r->isListBox() && r->enclosingBox().scroll(direction, granularity)) {
1189             setFrameWasScrolledByUser();
1190             return true;
1191         }
1192     }
1193
1194     return false;
1195 }
1196
1197 bool EventHandler::logicalScrollOverflow(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1198 {
1199     Node* node = startingNode;
1200
1201     if (!node)
1202         node = m_frame.document()->focusedElement();
1203
1204     if (!node)
1205         node = m_mousePressNode.get();
1206     
1207     if (node) {
1208         auto r = node->renderer();
1209         if (r && !r->isListBox() && r->enclosingBox().logicalScroll(direction, granularity)) {
1210             setFrameWasScrolledByUser();
1211             return true;
1212         }
1213     }
1214
1215     return false;
1216 }
1217
1218 bool EventHandler::scrollRecursively(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1219 {
1220     Ref<Frame> protectedFrame(m_frame);
1221
1222     // The layout needs to be up to date to determine if we can scroll. We may be
1223     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1224     m_frame.document()->updateLayoutIgnorePendingStylesheets();
1225     if (scrollOverflow(direction, granularity, startingNode))
1226         return true;    
1227     Frame* frame = &m_frame;
1228     FrameView* view = frame->view();
1229     if (view && view->scroll(direction, granularity))
1230         return true;
1231     frame = frame->tree().parent();
1232     if (!frame)
1233         return false;
1234     return frame->eventHandler().scrollRecursively(direction, granularity, m_frame.ownerElement());
1235 }
1236
1237 bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1238 {
1239     Ref<Frame> protectedFrame(m_frame);
1240
1241     // The layout needs to be up to date to determine if we can scroll. We may be
1242     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1243     m_frame.document()->updateLayoutIgnorePendingStylesheets();
1244     if (logicalScrollOverflow(direction, granularity, startingNode))
1245         return true;    
1246     Frame* frame = &m_frame;
1247     FrameView* view = frame->view();
1248     
1249     bool scrolled = false;
1250 #if PLATFORM(COCOA)
1251     // Mac also resets the scroll position in the inline direction.
1252     if (granularity == ScrollByDocument && view && view->logicalScroll(ScrollInlineDirectionBackward, ScrollByDocument))
1253         scrolled = true;
1254 #endif
1255     if (view && view->logicalScroll(direction, granularity))
1256         scrolled = true;
1257     
1258     if (scrolled)
1259         return true;
1260     
1261     frame = frame->tree().parent();
1262     if (!frame)
1263         return false;
1264
1265     return frame->eventHandler().logicalScrollRecursively(direction, granularity, m_frame.ownerElement());
1266 }
1267
1268 IntPoint EventHandler::lastKnownMousePosition() const
1269 {
1270     return m_lastKnownMousePosition;
1271 }
1272
1273 Frame* EventHandler::subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
1274 {
1275     if (!hitTestResult.isOverWidget())
1276         return 0;
1277     return subframeForTargetNode(hitTestResult.targetNode());
1278 }
1279
1280 Frame* EventHandler::subframeForTargetNode(Node* node)
1281 {
1282     if (!node)
1283         return nullptr;
1284
1285     auto renderer = node->renderer();
1286     if (!is<RenderWidget>(renderer))
1287         return nullptr;
1288
1289     Widget* widget = downcast<RenderWidget>(*renderer).widget();
1290     if (!is<FrameView>(widget))
1291         return nullptr;
1292
1293     return &downcast<FrameView>(*widget).frame();
1294 }
1295
1296 #if ENABLE(CURSOR_SUPPORT)
1297 static bool isSubmitImage(Node* node)
1298 {
1299     return is<HTMLInputElement>(node) && downcast<HTMLInputElement>(*node).isImageButton();
1300 }
1301
1302 // Returns true if the node's editable block is not current focused for editing
1303 static bool nodeIsNotBeingEdited(const Node& node, const Frame& frame)
1304 {
1305     return frame.selection().selection().rootEditableElement() != node.rootEditableElement();
1306 }
1307
1308 bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
1309 {
1310     if (!node)
1311         return false;
1312
1313     bool editable = node->hasEditableStyle();
1314     bool editableLinkEnabled = false;
1315
1316     // If the link is editable, then we need to check the settings to see whether or not the link should be followed
1317     if (editable) {
1318         switch (m_frame.settings().editableLinkBehavior()) {
1319         default:
1320         case EditableLinkDefaultBehavior:
1321         case EditableLinkAlwaysLive:
1322             editableLinkEnabled = true;
1323             break;
1324
1325         case EditableLinkNeverLive:
1326             editableLinkEnabled = false;
1327             break;
1328
1329         case EditableLinkLiveWhenNotFocused:
1330             editableLinkEnabled = nodeIsNotBeingEdited(*node, m_frame) || shiftKey;
1331             break;
1332
1333         case EditableLinkOnlyLiveWithShiftKey:
1334             editableLinkEnabled = shiftKey;
1335             break;
1336         }
1337     }
1338
1339     return ((isOverLink || isSubmitImage(node)) && (!editable || editableLinkEnabled));
1340 }
1341
1342 void EventHandler::cursorUpdateTimerFired()
1343 {
1344     ASSERT(m_frame.document());
1345     updateCursor();
1346 }
1347
1348 void EventHandler::updateCursor()
1349 {
1350     if (m_mousePositionIsUnknown)
1351         return;
1352
1353     FrameView* view = m_frame.view();
1354     if (!view)
1355         return;
1356
1357     RenderView* renderView = view->renderView();
1358     if (!renderView)
1359         return;
1360
1361     if (!view->shouldSetCursor())
1362         return;
1363
1364     bool shiftKey;
1365     bool ctrlKey;
1366     bool altKey;
1367     bool metaKey;
1368     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
1369
1370     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::AllowFrameScrollbars);
1371     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
1372     renderView->hitTest(request, result);
1373
1374     OptionalCursor optionalCursor = selectCursor(result, shiftKey);
1375     if (optionalCursor.isCursorChange()) {
1376         m_currentMouseCursor = optionalCursor.cursor();
1377         view->setCursor(m_currentMouseCursor);
1378     }
1379 }
1380
1381 OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shiftKey)
1382 {
1383     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1384         return NoCursorChange;
1385
1386     if (!m_frame.page())
1387         return NoCursorChange;
1388
1389 #if ENABLE(PAN_SCROLLING)
1390     if (m_frame.mainFrame().eventHandler().panScrollInProgress())
1391         return NoCursorChange;
1392 #endif
1393
1394     Ref<Frame> protectedFrame(m_frame);
1395
1396     // Use always pointer cursor for scrollbars.
1397     if (result.scrollbar()) {
1398 #if ENABLE(CURSOR_VISIBILITY)
1399         cancelAutoHideCursorTimer();
1400 #endif
1401         return pointerCursor();
1402     }
1403
1404     Node* node = result.targetNode();
1405     if (!node)
1406         return NoCursorChange;
1407
1408     auto renderer = node->renderer();
1409     auto* style = renderer ? &renderer->style() : nullptr;
1410     bool horizontalText = !style || style->isHorizontalWritingMode();
1411     const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
1412
1413 #if ENABLE(CURSOR_VISIBILITY)
1414     if (style && style->cursorVisibility() == CursorVisibilityAutoHide)
1415         startAutoHideCursorTimer();
1416     else
1417         cancelAutoHideCursorTimer();
1418 #endif
1419
1420     if (renderer) {
1421         Cursor overrideCursor;
1422         switch (renderer->getCursor(roundedIntPoint(result.localPoint()), overrideCursor)) {
1423         case SetCursorBasedOnStyle:
1424             break;
1425         case SetCursor:
1426             return overrideCursor;
1427         case DoNotSetCursor:
1428             return NoCursorChange;
1429         }
1430     }
1431
1432     if (style && style->cursors()) {
1433         const CursorList* cursors = style->cursors();
1434         for (unsigned i = 0; i < cursors->size(); ++i) {
1435             StyleImage* styleImage = (*cursors)[i].image();
1436             if (!styleImage)
1437                 continue;
1438             CachedImage* cachedImage = styleImage->cachedImage();
1439             if (!cachedImage)
1440                 continue;
1441             float scale = styleImage->imageScaleFactor();
1442             // Get hotspot and convert from logical pixels to physical pixels.
1443             IntPoint hotSpot = (*cursors)[i].hotSpot();
1444             FloatSize size = cachedImage->imageForRenderer(renderer)->size();
1445             if (cachedImage->errorOccurred())
1446                 continue;
1447             // Limit the size of cursors (in UI pixels) so that they cannot be
1448             // used to cover UI elements in chrome.
1449             size.scale(1 / scale);
1450             if (size.width() > maximumCursorSize || size.height() > maximumCursorSize)
1451                 continue;
1452
1453             Image* image = cachedImage->imageForRenderer(renderer);
1454 #if ENABLE(MOUSE_CURSOR_SCALE)
1455             // Ensure no overflow possible in calculations above.
1456             if (scale < minimumCursorScale)
1457                 continue;
1458             return Cursor(image, hotSpot, scale);
1459 #else
1460             ASSERT(scale == 1);
1461             return Cursor(image, hotSpot);
1462 #endif // ENABLE(MOUSE_CURSOR_SCALE)
1463         }
1464     }
1465
1466     // During selection, use an I-beam regardless of the content beneath the cursor.
1467     // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
1468     if (m_mousePressed
1469         && m_mouseDownMayStartSelect
1470 #if ENABLE(DRAG_SUPPORT)
1471         && !m_mouseDownMayStartDrag
1472 #endif
1473         && m_frame.selection().isCaretOrRange()
1474         && !m_capturingMouseEventsElement)
1475         return iBeam;
1476
1477     switch (style ? style->cursor() : CursorAuto) {
1478     case CursorAuto: {
1479         bool editable = node->hasEditableStyle();
1480
1481         if (useHandCursor(node, result.isOverLink(), shiftKey))
1482             return handCursor();
1483
1484         bool inResizer = false;
1485         if (renderer) {
1486             if (RenderLayer* layer = renderer->enclosingLayer()) {
1487                 if (FrameView* view = m_frame.view())
1488                     inResizer = layer->isPointInResizeControl(view->windowToContents(roundedIntPoint(result.localPoint())));
1489             }
1490         }
1491
1492         if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !result.scrollbar())
1493             return iBeam;
1494         return pointerCursor();
1495     }
1496     case CursorCross:
1497         return crossCursor();
1498     case CursorPointer:
1499         return handCursor();
1500     case CursorMove:
1501         return moveCursor();
1502     case CursorAllScroll:
1503         return moveCursor();
1504     case CursorEResize:
1505         return eastResizeCursor();
1506     case CursorWResize:
1507         return westResizeCursor();
1508     case CursorNResize:
1509         return northResizeCursor();
1510     case CursorSResize:
1511         return southResizeCursor();
1512     case CursorNeResize:
1513         return northEastResizeCursor();
1514     case CursorSwResize:
1515         return southWestResizeCursor();
1516     case CursorNwResize:
1517         return northWestResizeCursor();
1518     case CursorSeResize:
1519         return southEastResizeCursor();
1520     case CursorNsResize:
1521         return northSouthResizeCursor();
1522     case CursorEwResize:
1523         return eastWestResizeCursor();
1524     case CursorNeswResize:
1525         return northEastSouthWestResizeCursor();
1526     case CursorNwseResize:
1527         return northWestSouthEastResizeCursor();
1528     case CursorColResize:
1529         return columnResizeCursor();
1530     case CursorRowResize:
1531         return rowResizeCursor();
1532     case CursorText:
1533         return iBeamCursor();
1534     case CursorWait:
1535         return waitCursor();
1536     case CursorHelp:
1537         return helpCursor();
1538     case CursorVerticalText:
1539         return verticalTextCursor();
1540     case CursorCell:
1541         return cellCursor();
1542     case CursorContextMenu:
1543         return contextMenuCursor();
1544     case CursorProgress:
1545         return progressCursor();
1546     case CursorNoDrop:
1547         return noDropCursor();
1548     case CursorAlias:
1549         return aliasCursor();
1550     case CursorCopy:
1551         return copyCursor();
1552     case CursorNone:
1553         return noneCursor();
1554     case CursorNotAllowed:
1555         return notAllowedCursor();
1556     case CursorDefault:
1557         return pointerCursor();
1558     case CursorZoomIn:
1559         return zoomInCursor();
1560     case CursorZoomOut:
1561         return zoomOutCursor();
1562     case CursorWebkitGrab:
1563         return grabCursor();
1564     case CursorWebkitGrabbing:
1565         return grabbingCursor();
1566     }
1567     return pointerCursor();
1568 }
1569 #endif // ENABLE(CURSOR_SUPPORT)
1570
1571 #if ENABLE(CURSOR_VISIBILITY)
1572 void EventHandler::startAutoHideCursorTimer()
1573 {
1574     Page* page = m_frame.page();
1575     if (!page)
1576         return;
1577
1578     m_autoHideCursorTimer.startOneShot(page->settings().timeWithoutMouseMovementBeforeHidingControls());
1579
1580 #if !ENABLE(IOS_TOUCH_EVENTS)
1581     // The fake mouse move event screws up the auto-hide feature (by resetting the auto-hide timer)
1582     // so cancel any pending fake mouse moves.
1583     if (m_fakeMouseMoveEventTimer.isActive())
1584         m_fakeMouseMoveEventTimer.stop();
1585 #endif
1586 }
1587
1588 void EventHandler::cancelAutoHideCursorTimer()
1589 {
1590     if (m_autoHideCursorTimer.isActive())
1591         m_autoHideCursorTimer.stop();
1592 }
1593
1594 void EventHandler::autoHideCursorTimerFired()
1595 {
1596     m_currentMouseCursor = noneCursor();
1597     FrameView* view = m_frame.view();
1598     if (view && view->isActive())
1599         view->setCursor(m_currentMouseCursor);
1600 }
1601 #endif
1602
1603 static LayoutPoint documentPointForWindowPoint(Frame& frame, const IntPoint& windowPoint)
1604 {
1605     FrameView* view = frame.view();
1606     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
1607     // Historically the code would just crash; this is clearly no worse than that.
1608     return view ? view->windowToContents(windowPoint) : windowPoint;
1609 }
1610
1611 static Scrollbar* scrollbarForMouseEvent(const MouseEventWithHitTestResults& mouseEvent, FrameView* view)
1612 {
1613     if (view) {
1614         if (auto* scrollbar = view->scrollbarAtPoint(mouseEvent.event().position()))
1615             return scrollbar;
1616     }
1617     return mouseEvent.scrollbar();
1618
1619 }
1620
1621 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouseEvent)
1622 {
1623     Ref<Frame> protectedFrame(m_frame);
1624     RefPtr<FrameView> protector(m_frame.view());
1625
1626     if (InspectorInstrumentation::handleMousePress(m_frame)) {
1627         invalidateClick();
1628         return true;
1629     }
1630
1631     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
1632         return true;
1633
1634 #if ENABLE(TOUCH_EVENTS)
1635     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
1636     if (defaultPrevented)
1637         return true;
1638 #endif
1639
1640     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
1641
1642     // FIXME (bug 68185): this call should be made at another abstraction layer
1643     m_frame.loader().resetMultipleFormSubmissionProtection();
1644
1645 #if !ENABLE(IOS_TOUCH_EVENTS)
1646     cancelFakeMouseMoveEvent();
1647 #endif
1648     m_mousePressed = true;
1649     m_capturesDragging = true;
1650     setLastKnownMousePosition(platformMouseEvent);
1651     m_mouseDownTimestamp = platformMouseEvent.timestamp();
1652 #if ENABLE(DRAG_SUPPORT)
1653     m_mouseDownMayStartDrag = false;
1654 #endif
1655     m_mouseDownMayStartSelect = false;
1656     m_mouseDownMayStartAutoscroll = false;
1657     if (FrameView* view = m_frame.view())
1658         m_mouseDownPos = view->windowToContents(platformMouseEvent.position());
1659     else {
1660         invalidateClick();
1661         return false;
1662     }
1663     m_mouseDownWasInSubframe = false;
1664
1665     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent);
1666     // Save the document point we generate in case the window coordinate is invalidated by what happens
1667     // when we dispatch the event.
1668     LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, platformMouseEvent.position());
1669     MouseEventWithHitTestResults mouseEvent = m_frame.document()->prepareMouseEvent(request, documentPoint, platformMouseEvent);
1670
1671     if (!mouseEvent.targetNode()) {
1672         invalidateClick();
1673         return false;
1674     }
1675
1676     m_mousePressNode = mouseEvent.targetNode();
1677     m_frame.document()->setFocusNavigationStartingNode(mouseEvent.targetNode());
1678
1679     RefPtr<Frame> subframe = subframeForHitTestResult(mouseEvent);
1680     if (subframe && passMousePressEventToSubframe(mouseEvent, subframe.get())) {
1681         // Start capturing future events for this frame.  We only do this if we didn't clear
1682         // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
1683         m_capturesDragging = subframe->eventHandler().capturesDragging();
1684         if (m_mousePressed && m_capturesDragging) {
1685             m_capturingMouseEventsElement = subframe->ownerElement();
1686             m_eventHandlerWillResetCapturingMouseEventsElement = true;
1687         }
1688         invalidateClick();
1689         return true;
1690     }
1691
1692 #if ENABLE(PAN_SCROLLING)
1693     // We store whether pan scrolling is in progress before calling stopAutoscrollTimer()
1694     // because it will set m_autoscrollType to NoAutoscroll on return.
1695     bool isPanScrollInProgress = m_frame.mainFrame().eventHandler().panScrollInProgress();
1696     stopAutoscrollTimer();
1697     if (isPanScrollInProgress) {
1698         // We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate
1699         // away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>.
1700         invalidateClick();
1701         return true;
1702     }
1703 #endif
1704
1705     m_clickCount = platformMouseEvent.clickCount();
1706     m_clickNode = mouseEvent.targetNode();
1707
1708     if (!m_clickNode) {
1709         invalidateClick();
1710         return false;
1711     }
1712
1713     if (FrameView* view = m_frame.view()) {
1714         RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;
1715         IntPoint p = view->windowToContents(platformMouseEvent.position());
1716         if (layer && layer->isPointInResizeControl(p)) {
1717             layer->setInResizeMode(true);
1718             m_resizeLayer = layer;
1719             m_offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
1720             invalidateClick();
1721             return true;
1722         }
1723     }
1724
1725     m_frame.selection().setCaretBlinkingSuspended(true);
1726
1727     bool swallowEvent = !dispatchMouseEvent(eventNames().mousedownEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
1728     m_capturesDragging = !swallowEvent || mouseEvent.scrollbar();
1729
1730     // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
1731     // in case the scrollbar widget was destroyed when the mouse event was handled.
1732     if (mouseEvent.scrollbar()) {
1733         const bool wasLastScrollBar = mouseEvent.scrollbar() == m_lastScrollbarUnderMouse;
1734         mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
1735         if (wasLastScrollBar && mouseEvent.scrollbar() != m_lastScrollbarUnderMouse)
1736             m_lastScrollbarUnderMouse = nullptr;
1737     }
1738
1739     if (!swallowEvent) {
1740         // Refetch the event target node if it currently is the shadow node inside an <input> element.
1741         // If a mouse event handler changes the input element type to one that has a widget associated,
1742         // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
1743         // event target node can't still be the shadow node.
1744         if (is<ShadowRoot>(*mouseEvent.targetNode()) && is<HTMLInputElement>(*downcast<ShadowRoot>(*mouseEvent.targetNode()).host()))
1745             mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
1746     }
1747
1748     Scrollbar* scrollbar = scrollbarForMouseEvent(mouseEvent, m_frame.view());
1749     updateLastScrollbarUnderMouse(scrollbar, true);
1750
1751     bool passedToScrollbar = scrollbar && passMousePressEventToScrollbar(mouseEvent, scrollbar);
1752     if (!swallowEvent) {
1753         if (passedToScrollbar)
1754             swallowEvent = true;
1755         else
1756             swallowEvent = handleMousePressEvent(mouseEvent);
1757     }
1758     return swallowEvent;
1759 }
1760
1761 // This method only exists for platforms that don't know how to deliver 
1762 bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& platformMouseEvent)
1763 {
1764     Ref<Frame> protectedFrame(m_frame);
1765     RefPtr<FrameView> protector(m_frame.view());
1766
1767     m_frame.selection().setCaretBlinkingSuspended(false);
1768
1769     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
1770
1771     // We get this instead of a second mouse-up 
1772     m_mousePressed = false;
1773     setLastKnownMousePosition(platformMouseEvent);
1774
1775     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowUserAgentShadowContent);
1776     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
1777     Frame* subframe = subframeForHitTestResult(mouseEvent);
1778     if (m_eventHandlerWillResetCapturingMouseEventsElement)
1779         m_capturingMouseEventsElement = nullptr;
1780     if (subframe && passMousePressEventToSubframe(mouseEvent, subframe))
1781         return true;
1782
1783     m_clickCount = platformMouseEvent.clickCount();
1784     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
1785
1786     bool swallowClickEvent = platformMouseEvent.button() != RightButton && mouseEvent.targetNode() == m_clickNode && !dispatchMouseEvent(eventNames().clickEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
1787
1788     if (m_lastScrollbarUnderMouse)
1789         swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
1790
1791     bool swallowMouseReleaseEvent = !swallowMouseUpEvent && handleMouseReleaseEvent(mouseEvent);
1792
1793     invalidateClick();
1794
1795     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1796 }
1797
1798 static ScrollableArea* enclosingScrollableArea(Node* node)
1799 {
1800     for (auto ancestor = node; ancestor; ancestor = ancestor->parentOrShadowHostNode()) {
1801         if (is<HTMLIFrameElement>(*ancestor) || is<HTMLHtmlElement>(*ancestor) || is<HTMLDocument>(*ancestor))
1802             return nullptr;
1803
1804         auto renderer = ancestor->renderer();
1805         if (!renderer)
1806             continue;
1807
1808         if (is<RenderListBox>(*renderer))
1809             return downcast<RenderListBox>(renderer);
1810
1811         return renderer->enclosingLayer();
1812     }
1813
1814     return nullptr;
1815 }
1816
1817 bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
1818 {
1819     Ref<Frame> protectedFrame(m_frame);
1820     RefPtr<FrameView> protector(m_frame.view());
1821     MaximumDurationTracker maxDurationTracker(&m_maxMouseMovedDuration);
1822
1823     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(event))
1824         return true;
1825
1826     HitTestResult hoveredNode = HitTestResult(LayoutPoint());
1827     bool result = handleMouseMoveEvent(event, &hoveredNode);
1828
1829     Page* page = m_frame.page();
1830     if (!page)
1831         return result;
1832
1833     if (auto scrolledArea = enclosingScrollableArea(hoveredNode.innerNode())) {
1834         if (FrameView* frameView = m_frame.view()) {
1835             if (frameView->containsScrollableArea(scrolledArea))
1836                 scrolledArea->mouseMovedInContentArea();
1837         }
1838     }
1839
1840     if (FrameView* frameView = m_frame.view())
1841         frameView->mouseMovedInContentArea();  
1842
1843     hoveredNode.setToNonUserAgentShadowAncestor();
1844     page->chrome().mouseDidMoveOverElement(hoveredNode, event.modifierFlags());
1845     page->chrome().setToolTip(hoveredNode);
1846     return result;
1847 }
1848
1849 bool EventHandler::passMouseMovedEventToScrollbars(const PlatformMouseEvent& event)
1850 {
1851     HitTestResult hoveredNode;
1852     return handleMouseMoveEvent(event, &hoveredNode, true);
1853 }
1854
1855 bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
1856 {
1857 #if ENABLE(TOUCH_EVENTS)
1858     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
1859     if (defaultPrevented)
1860         return true;
1861 #endif
1862
1863     Ref<Frame> protectedFrame(m_frame);
1864     RefPtr<FrameView> protector(m_frame.view());
1865     
1866     setLastKnownMousePosition(platformMouseEvent);
1867
1868     if (m_hoverTimer.isActive())
1869         m_hoverTimer.stop();
1870
1871 #if ENABLE(CURSOR_SUPPORT)
1872     m_cursorUpdateTimer.stop();
1873 #endif
1874
1875 #if !ENABLE(IOS_TOUCH_EVENTS)
1876     cancelFakeMouseMoveEvent();
1877 #endif
1878
1879     if (m_svgPan) {
1880         downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
1881         return true;
1882     }
1883
1884     if (m_frameSetBeingResized)
1885         return !dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, platformMouseEvent, false);
1886
1887     // On iOS, our scrollbars are managed by UIKit.
1888 #if !PLATFORM(IOS)
1889     // Send events right to a scrollbar if the mouse is pressed.
1890     if (m_lastScrollbarUnderMouse && m_mousePressed)
1891         return m_lastScrollbarUnderMouse->mouseMoved(platformMouseEvent);
1892 #endif
1893
1894     HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::AllowFrameScrollbars;
1895     if (m_mousePressed)
1896         hitType |= HitTestRequest::Active;
1897     else if (onlyUpdateScrollbars) {
1898         // Mouse events should be treated as "read-only" if we're updating only scrollbars. This  
1899         // means that :hover and :active freeze in the state they were in, rather than updating  
1900         // for nodes the mouse moves while the window is not key (which will be the case if 
1901         // onlyUpdateScrollbars is true). 
1902         hitType |= HitTestRequest::ReadOnly;
1903     }
1904
1905 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
1906     // Treat any mouse move events as readonly if the user is currently touching the screen.
1907     if (m_touchPressed)
1908         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
1909 #endif
1910     HitTestRequest request(hitType);
1911     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
1912     if (hoveredNode)
1913         *hoveredNode = mouseEvent.hitTestResult();
1914
1915     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1916         m_resizeLayer->resize(platformMouseEvent, m_offsetFromResizeCorner);
1917     else {
1918         Scrollbar* scrollbar = mouseEvent.scrollbar();
1919         updateLastScrollbarUnderMouse(scrollbar, !m_mousePressed);
1920
1921         // On iOS, our scrollbars are managed by UIKit.
1922 #if !PLATFORM(IOS)
1923         if (!m_mousePressed && scrollbar)
1924             scrollbar->mouseMoved(platformMouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
1925 #endif
1926         if (onlyUpdateScrollbars) {
1927             updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
1928             return true;
1929         }
1930     }
1931
1932     bool swallowEvent = false;
1933     RefPtr<Frame> newSubframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
1934  
1935     // 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.
1936     if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(&m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
1937         passMouseMoveEventToSubframe(mouseEvent, m_lastMouseMoveEventSubframe.get());
1938
1939     if (newSubframe) {
1940         // Update over/out state before passing the event to the subframe.
1941         updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
1942         
1943         // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
1944         // node to be detached from its FrameView, in which case the event should not be passed.
1945         if (newSubframe->view())
1946             swallowEvent |= passMouseMoveEventToSubframe(mouseEvent, newSubframe.get(), hoveredNode);
1947 #if ENABLE(CURSOR_SUPPORT)
1948     } else {
1949         if (FrameView* view = m_frame.view()) {
1950             OptionalCursor optionalCursor = selectCursor(mouseEvent.hitTestResult(), platformMouseEvent.shiftKey());
1951             if (optionalCursor.isCursorChange()) {
1952                 m_currentMouseCursor = optionalCursor.cursor();
1953                 view->setCursor(m_currentMouseCursor);
1954             }
1955         }
1956 #endif
1957     }
1958     
1959     m_lastMouseMoveEventSubframe = newSubframe;
1960
1961     if (swallowEvent)
1962         return true;
1963     
1964     swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), false, 0, platformMouseEvent, true);
1965 #if ENABLE(DRAG_SUPPORT)
1966     if (!swallowEvent)
1967         swallowEvent = handleMouseDraggedEvent(mouseEvent);
1968 #endif // ENABLE(DRAG_SUPPORT)
1969
1970     return swallowEvent;
1971 }
1972
1973 void EventHandler::invalidateClick()
1974 {
1975     m_clickCount = 0;
1976     m_clickNode = nullptr;
1977 }
1978
1979 static Node* targetNodeForClickEvent(Node* mousePressNode, Node* mouseReleaseNode)
1980 {
1981     if (!mousePressNode || !mouseReleaseNode)
1982         return nullptr;
1983
1984     if (mousePressNode == mouseReleaseNode)
1985         return mouseReleaseNode;
1986
1987     Element* mouseReleaseShadowHost = mouseReleaseNode->shadowHost();
1988     if (mouseReleaseShadowHost && mouseReleaseShadowHost == mousePressNode->shadowHost()) {
1989         // We want to dispatch the click to the shadow tree host element to give listeners the illusion that the
1990         // shadom tree is a single element. For example, we want to give the illusion that <input type="range">
1991         // is a single element even though it is a composition of multiple shadom tree elements.
1992         return mouseReleaseShadowHost;
1993     }
1994     return nullptr;
1995 }
1996
1997 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& platformMouseEvent)
1998 {
1999     Ref<Frame> protectedFrame(m_frame);
2000     RefPtr<FrameView> protector(m_frame.view());
2001
2002     m_frame.selection().setCaretBlinkingSuspended(false);
2003
2004     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
2005         return true;
2006
2007 #if ENABLE(TOUCH_EVENTS)
2008     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
2009     if (defaultPrevented)
2010         return true;
2011 #endif
2012
2013     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
2014
2015 #if ENABLE(PAN_SCROLLING)
2016     m_autoscrollController->handleMouseReleaseEvent(platformMouseEvent);
2017 #endif
2018
2019     m_mousePressed = false;
2020     setLastKnownMousePosition(platformMouseEvent);
2021
2022     if (m_svgPan) {
2023         m_svgPan = false;
2024         downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
2025         return true;
2026     }
2027
2028     if (m_frameSetBeingResized)
2029         return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, platformMouseEvent, false);
2030
2031     // If an immediate action began or was completed using this series of mouse events, then we should send mouseup to
2032     // the DOM and return now so that we don't perform our own default behaviors.
2033     if (m_immediateActionStage == ImmediateActionStage::ActionCompleted || m_immediateActionStage == ImmediateActionStage::ActionUpdated || m_immediateActionStage == ImmediateActionStage::ActionCancelledAfterUpdate) {
2034         m_immediateActionStage = ImmediateActionStage::None;
2035         return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), true, m_clickCount, platformMouseEvent, false);
2036     }
2037     m_immediateActionStage = ImmediateActionStage::None;
2038
2039     if (m_lastScrollbarUnderMouse) {
2040         invalidateClick();
2041         m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
2042         bool cancelable = true;
2043         bool setUnder = false;
2044         return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), cancelable, m_clickCount, platformMouseEvent, setUnder);
2045     }
2046
2047     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowUserAgentShadowContent);
2048     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
2049     Frame* subframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
2050     if (m_eventHandlerWillResetCapturingMouseEventsElement)
2051         m_capturingMouseEventsElement = nullptr;
2052     if (subframe && passMouseReleaseEventToSubframe(mouseEvent, subframe))
2053         return true;
2054
2055     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
2056
2057     bool contextMenuEvent = platformMouseEvent.button() == RightButton;
2058
2059     Node* nodeToClick = targetNodeForClickEvent(m_clickNode.get(), mouseEvent.targetNode());
2060     bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && nodeToClick && !dispatchMouseEvent(eventNames().clickEvent, nodeToClick, true, m_clickCount, platformMouseEvent, true);
2061
2062     if (m_resizeLayer) {
2063         m_resizeLayer->setInResizeMode(false);
2064         m_resizeLayer = nullptr;
2065     }
2066
2067     bool swallowMouseReleaseEvent = false;
2068     if (!swallowMouseUpEvent)
2069         swallowMouseReleaseEvent = handleMouseReleaseEvent(mouseEvent);
2070
2071     invalidateClick();
2072
2073     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
2074 }
2075
2076 #if ENABLE(MOUSE_FORCE_EVENTS)
2077 bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& event)
2078 {
2079     Ref<Frame> protectedFrame(m_frame);
2080     RefPtr<FrameView> protector(m_frame.view());
2081
2082     setLastKnownMousePosition(event);
2083
2084     HitTestRequest::HitTestRequestType hitType = HitTestRequest::DisallowUserAgentShadowContent | HitTestRequest::Active;
2085
2086     HitTestRequest request(hitType);
2087     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
2088
2089     bool swallowedEvent = !dispatchMouseEvent(eventNames().webkitmouseforcechangedEvent, mouseEvent.targetNode(), false, 0, event, false);
2090     if (event.type() == PlatformEvent::MouseForceDown)
2091         swallowedEvent |= !dispatchMouseEvent(eventNames().webkitmouseforcedownEvent, mouseEvent.targetNode(), false, 0, event, false);
2092     if (event.type() == PlatformEvent::MouseForceUp)
2093         swallowedEvent |= !dispatchMouseEvent(eventNames().webkitmouseforceupEvent, mouseEvent.targetNode(), false, 0, event, false);
2094
2095     return swallowedEvent;
2096 }
2097 #else
2098 bool EventHandler::handleMouseForceEvent(const PlatformMouseEvent& )
2099 {
2100     return false;
2101 }
2102 #endif // #if ENABLE(MOUSE_FORCE_EVENTS)
2103
2104 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& platformMouseEvent)
2105 {
2106     // If the event was a middle click, attempt to copy global selection in after
2107     // the newly set caret position.
2108     //
2109     // This code is called from either the mouse up or mouse down handling. There
2110     // is some debate about when the global selection is pasted:
2111     //   xterm: pastes on up.
2112     //   GTK: pastes on down.
2113     //   Qt: pastes on up.
2114     //   Firefox: pastes on up.
2115     //   Chromium: pastes on up.
2116     //
2117     // There is something of a webcompat angle to this well, as highlighted by
2118     // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
2119     // down then the text is pasted just before the onclick handler runs and
2120     // clears the text box. So it's important this happens after the event
2121     // handlers have been fired.
2122 #if PLATFORM(GTK)
2123     if (platformMouseEvent.type() != PlatformEvent::MousePressed)
2124         return false;
2125 #else
2126     if (platformMouseEvent.type() != PlatformEvent::MouseReleased)
2127         return false;
2128 #endif
2129
2130     if (!m_frame.page())
2131         return false;
2132     Frame& focusFrame = m_frame.page()->focusController().focusedOrMainFrame();
2133     // Do not paste here if the focus was moved somewhere else.
2134     if (&m_frame == &focusFrame && m_frame.editor().client()->supportsGlobalSelection())
2135         return m_frame.editor().command(ASCIILiteral("PasteGlobalSelection")).execute();
2136
2137     return false;
2138 }
2139
2140 #if ENABLE(DRAG_SUPPORT)
2141
2142 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Element& dragTarget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2143 {
2144     Ref<Frame> protectedFrame(m_frame);
2145     FrameView* view = m_frame.view();
2146
2147     // FIXME: We might want to dispatch a dragleave even if the view is gone.
2148     if (!view)
2149         return false;
2150
2151     view->disableLayerFlushThrottlingTemporarilyForInteraction();
2152     Ref<MouseEvent> me = MouseEvent::create(eventType,
2153         true, true, event.timestamp(), m_frame.document()->defaultView(),
2154         0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
2155 #if ENABLE(POINTER_LOCK)
2156         event.movementDelta().x(), event.movementDelta().y(),
2157 #endif
2158         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
2159         0, 0, event.force(), NoTap, dataTransfer);
2160
2161     dragTarget.dispatchEvent(me);
2162     return me->defaultPrevented();
2163 }
2164
2165 static bool targetIsFrame(Node* target, Frame*& frame)
2166 {
2167     if (!is<HTMLFrameElementBase>(target))
2168         return false;
2169
2170     frame = downcast<HTMLFrameElementBase>(*target).contentFrame();
2171     return true;
2172 }
2173
2174 static DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
2175 {
2176     if (dragOperation == "copy")
2177         return DragOperationCopy;
2178     if (dragOperation == "move")
2179         return DragOperationMove;
2180     if (dragOperation == "link")
2181         return DragOperationLink;
2182     return DragOperationNone;
2183 }
2184
2185 static String convertDragOperationToDropZoneOperation(DragOperation operation)
2186 {
2187     switch (operation) {
2188     case DragOperationCopy:
2189         return ASCIILiteral("copy");
2190     case DragOperationMove:
2191         return ASCIILiteral("move");
2192     case DragOperationLink:
2193         return ASCIILiteral("link");
2194     default:
2195         return ASCIILiteral("copy");
2196     }
2197 }
2198
2199 static bool hasDropZoneType(DataTransfer& dataTransfer, const String& keyword)
2200 {
2201     if (keyword.startsWith("file:"))
2202         return dataTransfer.hasFileOfType(keyword.substring(5));
2203
2204     if (keyword.startsWith("string:"))
2205         return dataTransfer.hasStringOfType(keyword.substring(7));
2206
2207     return false;
2208 }
2209
2210 static bool findDropZone(Node* target, DataTransfer* dataTransfer)
2211 {
2212     ASSERT(target);
2213     Element* element = is<Element>(*target) ? downcast<Element>(target) : target->parentElement();
2214     for (; element; element = element->parentElement()) {
2215         SpaceSplitString keywords(element->attributeWithoutSynchronization(webkitdropzoneAttr), true);
2216         bool matched = false;
2217         DragOperation dragOperation = DragOperationNone;
2218         for (unsigned i = 0, size = keywords.size(); i < size; ++i) {
2219             DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
2220             if (op != DragOperationNone) {
2221                 if (dragOperation == DragOperationNone)
2222                     dragOperation = op;
2223             } else
2224                 matched = matched || hasDropZoneType(*dataTransfer, keywords[i].string());
2225             if (matched && dragOperation != DragOperationNone)
2226                 break;
2227         }
2228         if (matched) {
2229             dataTransfer->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
2230             return true;
2231         }
2232     }
2233     return false;
2234 }
2235     
2236 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2237 {
2238     Ref<Frame> protectedFrame(m_frame);
2239
2240     bool accept = false;
2241
2242     if (!m_frame.view())
2243         return false;
2244
2245     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowUserAgentShadowContent);
2246     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
2247
2248     RefPtr<Element> newTarget;
2249     if (Node* targetNode = mouseEvent.targetNode()) {
2250         // Drag events should never go to non-element nodes (following IE, and proper mouseover/out dispatch)
2251         if (!is<Element>(*targetNode))
2252             newTarget = targetNode->parentOrShadowHostElement();
2253         else
2254             newTarget = downcast<Element>(targetNode);
2255     }
2256
2257     m_autoscrollController->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
2258
2259     if (m_dragTarget != newTarget) {
2260         // FIXME: this ordering was explicitly chosen to match WinIE. However,
2261         // it is sometimes incorrect when dragging within subframes, as seen with
2262         // LayoutTests/fast/events/drag-in-frames.html.
2263         //
2264         // 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>.
2265         Frame* targetFrame;
2266         if (targetIsFrame(newTarget.get(), targetFrame)) {
2267             if (targetFrame)
2268                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
2269         } else if (newTarget) {
2270             // 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.
2271             if (dragState().source && dragState().shouldDispatchEvents) {
2272                 // for now we don't care if event handler cancels default behavior, since there is none
2273                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2274             }
2275             accept = dispatchDragEvent(eventNames().dragenterEvent, *newTarget, event, dataTransfer);
2276             if (!accept)
2277                 accept = findDropZone(newTarget.get(), dataTransfer);
2278         }
2279
2280         if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2281             if (targetFrame)
2282                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
2283         } else if (m_dragTarget)
2284             dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer);
2285
2286         if (newTarget) {
2287             // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
2288             // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function.
2289             m_shouldOnlyFireDragOverEvent = true;
2290         }
2291     } else {
2292         Frame* targetFrame;
2293         if (targetIsFrame(newTarget.get(), targetFrame)) {
2294             if (targetFrame)
2295                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
2296         } else if (newTarget) {
2297             // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
2298             if (!m_shouldOnlyFireDragOverEvent && dragState().source && dragState().shouldDispatchEvents) {
2299                 // for now we don't care if event handler cancels default behavior, since there is none
2300                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2301             }
2302             accept = dispatchDragEvent(eventNames().dragoverEvent, *newTarget, event, dataTransfer);
2303             if (!accept)
2304                 accept = findDropZone(newTarget.get(), dataTransfer);
2305             m_shouldOnlyFireDragOverEvent = false;
2306         }
2307     }
2308     m_dragTarget = WTFMove(newTarget);
2309     return accept;
2310 }
2311
2312 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2313 {
2314     Ref<Frame> protectedFrame(m_frame);
2315
2316     Frame* targetFrame;
2317     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2318         if (targetFrame)
2319             targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer);
2320     } else if (m_dragTarget) {
2321         if (dragState().source && dragState().shouldDispatchEvents)
2322             dispatchDragSrcEvent(eventNames().dragEvent, event);
2323         dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer);
2324     }
2325     clearDragState();
2326 }
2327
2328 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2329 {
2330     Ref<Frame> protectedFrame(m_frame);
2331
2332     Frame* targetFrame;
2333     bool preventedDefault = false;
2334     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2335         if (targetFrame)
2336             preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, dataTransfer);
2337     } else if (m_dragTarget)
2338         preventedDefault = dispatchDragEvent(eventNames().dropEvent, *m_dragTarget, event, dataTransfer);
2339     clearDragState();
2340     return preventedDefault;
2341 }
2342
2343 void EventHandler::clearDragState()
2344 {
2345     stopAutoscrollTimer();
2346     m_dragTarget = nullptr;
2347     m_capturingMouseEventsElement = nullptr;
2348     m_shouldOnlyFireDragOverEvent = false;
2349 #if PLATFORM(COCOA)
2350     m_sendingEventToSubview = false;
2351 #endif
2352 }
2353 #endif // ENABLE(DRAG_SUPPORT)
2354
2355 void EventHandler::setCapturingMouseEventsElement(PassRefPtr<Element> element)
2356 {
2357     m_capturingMouseEventsElement = element;
2358     m_eventHandlerWillResetCapturingMouseEventsElement = false;
2359 }
2360
2361 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mouseEvent)
2362 {
2363     Ref<Frame> protectedFrame(m_frame);
2364     ASSERT(m_frame.document());
2365     return m_frame.document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mouseEvent.position()), mouseEvent);
2366 }
2367
2368 static RenderElement* nearestCommonHoverAncestor(RenderElement* obj1, RenderElement* obj2)
2369 {
2370     if (!obj1 || !obj2)
2371         return nullptr;
2372
2373     for (RenderElement* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
2374         for (RenderElement* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
2375             if (currObj1 == currObj2)
2376                 return currObj1;
2377         }
2378     }
2379
2380     return nullptr;
2381 }
2382
2383 static bool hierarchyHasCapturingEventListeners(Element* element, const AtomicString& eventName)
2384 {
2385     for (ContainerNode* curr = element; curr; curr = curr->parentOrShadowHostNode()) {
2386         if (curr->hasCapturingEventListeners(eventName))
2387             return true;
2388     }
2389     return false;
2390 }
2391
2392 void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& platformMouseEvent, bool fireMouseOverOut)
2393 {
2394     Ref<Frame> protectedFrame(m_frame);
2395     Element* targetElement = nullptr;
2396     
2397     // If we're capturing, we always go right to that element.
2398     if (m_capturingMouseEventsElement)
2399         targetElement = m_capturingMouseEventsElement.get();
2400     else if (targetNode) {
2401         // If the target node is a non-element, dispatch on the parent. <rdar://problem/4196646>
2402         while (targetNode && !is<Element>(*targetNode))
2403             targetNode = targetNode->parentInComposedTree();
2404         targetElement = downcast<Element>(targetNode);
2405     }
2406
2407     m_elementUnderMouse = targetElement;
2408
2409     // Fire mouseout/mouseover if the mouse has shifted to a different node.
2410     if (fireMouseOverOut) {
2411         auto scrollableAreaForLastNode = enclosingScrollableArea(m_lastElementUnderMouse.get());
2412         auto scrollableAreaForNodeUnderMouse = enclosingScrollableArea(m_elementUnderMouse.get());
2413         Page* page = m_frame.page();
2414
2415         if (m_lastElementUnderMouse && (!m_elementUnderMouse || &m_elementUnderMouse->document() != m_frame.document())) {
2416             // The mouse has moved between frames.
2417             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
2418                 if (FrameView* frameView = frame->view())
2419                     frameView->mouseExitedContentArea();
2420             }
2421         } else if (page && (scrollableAreaForLastNode && (!scrollableAreaForNodeUnderMouse || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
2422             // The mouse has moved between layers.
2423             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
2424                 if (FrameView* frameView = frame->view()) {
2425                     if (frameView->containsScrollableArea(scrollableAreaForLastNode))
2426                         scrollableAreaForLastNode->mouseExitedContentArea();
2427                 }
2428             }
2429         }
2430
2431         if (m_elementUnderMouse && (!m_lastElementUnderMouse || &m_lastElementUnderMouse->document() != m_frame.document())) {
2432             // The mouse has moved between frames.
2433             if (Frame* frame = m_elementUnderMouse->document().frame()) {
2434                 if (FrameView* frameView = frame->view())
2435                     frameView->mouseEnteredContentArea();
2436             }
2437         } else if (page && (scrollableAreaForNodeUnderMouse && (!scrollableAreaForLastNode || scrollableAreaForNodeUnderMouse != scrollableAreaForLastNode))) {
2438             // The mouse has moved between layers.
2439             if (Frame* frame = m_elementUnderMouse->document().frame()) {
2440                 if (FrameView* frameView = frame->view()) {
2441                     if (frameView->containsScrollableArea(scrollableAreaForNodeUnderMouse))
2442                         scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
2443                 }
2444             }
2445         }
2446
2447         if (m_lastElementUnderMouse && &m_lastElementUnderMouse->document() != m_frame.document()) {
2448             m_lastElementUnderMouse = nullptr;
2449             m_lastScrollbarUnderMouse = nullptr;
2450         }
2451
2452         if (m_lastElementUnderMouse != m_elementUnderMouse) {
2453             // mouseenter and mouseleave events are only dispatched if there is a capturing eventhandler on an ancestor
2454             // or a normal eventhandler on the element itself (they don't bubble).
2455             // This optimization is necessary since these events can cause O(n^2) capturing event-handler checks.
2456             bool hasCapturingMouseEnterListener = hierarchyHasCapturingEventListeners(m_elementUnderMouse.get(), eventNames().mouseenterEvent);
2457             bool hasCapturingMouseLeaveListener = hierarchyHasCapturingEventListeners(m_lastElementUnderMouse.get(), eventNames().mouseleaveEvent);
2458
2459             RenderElement* oldHoverRenderer = m_lastElementUnderMouse ? m_lastElementUnderMouse->renderer() : nullptr;
2460             RenderElement* newHoverRenderer = m_elementUnderMouse ? m_elementUnderMouse->renderer() : nullptr;
2461             RenderElement* ancestor = nearestCommonHoverAncestor(oldHoverRenderer, newHoverRenderer);
2462
2463             Vector<Ref<Element>, 32> leftElementsChain;
2464             if (oldHoverRenderer) {
2465                 for (RenderElement* curr = oldHoverRenderer; curr && curr != ancestor; curr = curr->hoverAncestor()) {
2466                     if (Element* element = curr->element())
2467                         leftElementsChain.append(*element);
2468                 }
2469             } else {
2470                 // If the old hovered element is not null but it's renderer is, it was probably detached.
2471                 // In this case, the old hovered element (and its ancestors) must be updated, to ensure it's normal style is re-applied.
2472                 for (Element* element = m_lastElementUnderMouse.get(); element; element = element->parentElement())
2473                     leftElementsChain.append(*element);
2474             }
2475
2476             Vector<Ref<Element>, 32> enteredElementsChain;
2477             const Element* ancestorElement = ancestor ? ancestor->element() : nullptr;
2478             for (RenderElement* curr = newHoverRenderer; curr; curr = curr->hoverAncestor()) {
2479                 if (Element *element = curr->element()) {
2480                     if (element == ancestorElement)
2481                         break;
2482                     enteredElementsChain.append(*element);
2483                 }
2484             }
2485
2486             // Send mouseout event to the old node.
2487             if (m_lastElementUnderMouse)
2488                 m_lastElementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoutEvent, 0, m_elementUnderMouse.get());
2489
2490             // Send mouseleave to the node hierarchy no longer under the mouse.
2491             for (auto& chain : leftElementsChain) {
2492                 if (hasCapturingMouseLeaveListener || chain->hasEventListeners(eventNames().mouseleaveEvent))
2493                     chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseleaveEvent, 0, m_elementUnderMouse.get());
2494             }
2495
2496             // Send mouseover event to the new node.
2497             if (m_elementUnderMouse)
2498                 m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoverEvent, 0, m_lastElementUnderMouse.get());
2499
2500             // Send mouseleave event to the nodes hierarchy under the mouse.
2501             for (auto& chain : enteredElementsChain) {
2502                 if (hasCapturingMouseEnterListener || chain->hasEventListeners(eventNames().mouseenterEvent))
2503                     chain->dispatchMouseEvent(platformMouseEvent, eventNames().mouseenterEvent, 0, m_lastElementUnderMouse.get());
2504             }
2505         }
2506         m_lastElementUnderMouse = m_elementUnderMouse;
2507     }
2508 }
2509
2510 bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& platformMouseEvent, bool setUnder)
2511 {
2512     Ref<Frame> protectedFrame(m_frame);
2513
2514     if (auto* view = m_frame.view())
2515         view->disableLayerFlushThrottlingTemporarilyForInteraction();
2516
2517     updateMouseEventTargetNode(targetNode, platformMouseEvent, setUnder);
2518
2519     if (m_elementUnderMouse && !m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventType, clickCount))
2520         return false;
2521
2522     if (eventType != eventNames().mousedownEvent)
2523         return true;
2524
2525     // If clicking on a frame scrollbar, do not make any change to which element is focused.
2526     auto* view = m_frame.view();
2527     if (view && view->scrollbarAtPoint(platformMouseEvent.position()))
2528         return true;
2529
2530     // The layout needs to be up to date to determine if an element is focusable.
2531     m_frame.document()->updateLayoutIgnorePendingStylesheets();
2532
2533     // Remove focus from the currently focused element when a link or button is clicked.
2534     // This is expected by some sites that rely on change event handlers running
2535     // from form fields before the button click is processed, behavior that was inherited
2536     // from the user interface of Windows, where pushing a button moves focus to the button.
2537
2538     // Walk up the DOM tree to search for an element to focus.
2539     Element* element;
2540     for (element = m_elementUnderMouse.get(); element; element = element->parentOrShadowHostElement()) {
2541         if (element->isMouseFocusable())
2542             break;
2543     }
2544
2545     // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus an
2546     // element on mouse down if it's selected and inside a focused element. It will be
2547     // focused if the user does a mouseup over it, however, because the mouseup
2548     // will set a selection inside it, which will also set the focused element.
2549     if (element && m_frame.selection().isRange()) {
2550         if (auto range = m_frame.selection().toNormalizedRange()) {
2551             auto result = range->compareNode(*element);
2552             if (!result.hasException() && result.releaseReturnValue() == Range::NODE_INSIDE && element->isDescendantOf(m_frame.document()->focusedElement()))
2553                 return true;
2554         }
2555     }
2556
2557     // Only change the focus when clicking scrollbars if it can be transferred to a mouse focusable node.
2558     if (!element && isInsideScrollbar(platformMouseEvent.position()))
2559         return false;
2560
2561     // If focus shift is blocked, we eat the event.
2562     auto* page = m_frame.page();
2563     if (page && !page->focusController().setFocusedElement(element, &m_frame))
2564         return false;
2565
2566     return true;
2567 }
2568
2569 bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
2570 {
2571     if (RenderView* renderView = m_frame.contentRenderer()) {
2572         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowUserAgentShadowContent);
2573         HitTestResult result(windowPoint);
2574         renderView->hitTest(request, result);
2575         return result.scrollbar();
2576     }
2577
2578     return false;
2579 }
2580
2581 #if !PLATFORM(GTK)
2582
2583 bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const
2584 {
2585     return false;
2586 }
2587
2588 #endif
2589
2590 #if !PLATFORM(MAC)
2591
2592 void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, WeakPtr<ScrollableArea>&, bool&)
2593 {
2594 }
2595
2596 void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& event)
2597 {
2598     m_frame.mainFrame().wheelEventDeltaFilter()->updateFromDelta(FloatSize(event.deltaX(), event.deltaY()));
2599 }
2600
2601 bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, ContainerNode*, const WeakPtr<ScrollableArea>&)
2602 {
2603     Ref<Frame> protectedFrame(m_frame);
2604
2605     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
2606     FrameView* view = m_frame.view();
2607     
2608     bool didHandleEvent = view ? view->wheelEvent(event) : false;
2609     m_isHandlingWheelEvent = false;
2610     return didHandleEvent;
2611 }
2612
2613 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode*)
2614 {
2615     return true;
2616 }
2617
2618 void EventHandler::platformNotifyIfEndGesture(const PlatformWheelEvent&, const WeakPtr<ScrollableArea>&)
2619 {
2620 }
2621
2622 IntPoint EventHandler::effectiveMousePositionForSelectionAutoscroll() const
2623 {
2624     return m_lastKnownMousePosition;
2625 }
2626
2627 void EventHandler::clearOrScheduleClearingLatchedStateIfNeeded(const PlatformWheelEvent&)
2628 {
2629     clearLatchedState();
2630 }
2631 #endif
2632
2633 Widget* EventHandler::widgetForEventTarget(Element* eventTarget)
2634 {
2635     if (!eventTarget)
2636         return nullptr;
2637
2638     auto* target = eventTarget->renderer();
2639     if (!is<RenderWidget>(target))
2640         return nullptr;
2641
2642     return downcast<RenderWidget>(*target).widget();
2643 }
2644
2645 static WeakPtr<Widget> widgetForElement(const Element& element)
2646 {
2647     auto target = element.renderer();
2648     if (!is<RenderWidget>(target) || !downcast<RenderWidget>(*target).widget())
2649         return { };
2650
2651     return downcast<RenderWidget>(*target).widget()->createWeakPtr();
2652 }
2653
2654 bool EventHandler::completeWidgetWheelEvent(const PlatformWheelEvent& event, const WeakPtr<Widget>& widget, const WeakPtr<ScrollableArea>& scrollableArea, ContainerNode* scrollableContainer)
2655 {
2656     m_isHandlingWheelEvent = false;
2657     
2658     // We do another check on the widget because the event handler can run JS which results in the frame getting destroyed.
2659     if (!widget)
2660         return false;
2661     
2662     if (scrollableArea)
2663         scrollableArea->setScrolledProgrammatically(false);
2664
2665     platformNotifyIfEndGesture(event, scrollableArea);
2666
2667     if (!widget->platformWidget())
2668         return true;
2669
2670     return platformCompletePlatformWidgetWheelEvent(event, *widget.get(), scrollableContainer);
2671 }
2672
2673 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
2674 {
2675     RenderView* renderView = m_frame.contentRenderer();
2676     if (!renderView)
2677         return false;
2678
2679     Ref<Frame> protectedFrame(m_frame);
2680     RefPtr<FrameView> protector(m_frame.view());
2681
2682     FrameView* view = m_frame.view();
2683     if (!view)
2684         return false;
2685
2686     m_isHandlingWheelEvent = true;
2687     setFrameWasScrolledByUser();
2688
2689     HitTestRequest request;
2690     HitTestResult result(view->windowToContents(event.position()));
2691     renderView->hitTest(request, result);
2692
2693     RefPtr<Element> element = result.targetElement();
2694     RefPtr<ContainerNode> scrollableContainer;
2695     WeakPtr<ScrollableArea> scrollableArea;
2696     bool isOverWidget = result.isOverWidget();
2697     platformPrepareForWheelEvents(event, result, element, scrollableContainer, scrollableArea, isOverWidget);
2698
2699 #if PLATFORM(MAC)
2700     if (event.phase() == PlatformWheelEventPhaseNone && event.momentumPhase() == PlatformWheelEventPhaseNone)
2701         m_frame.mainFrame().resetLatchingState();
2702 #endif
2703
2704     // FIXME: It should not be necessary to do this mutation here.
2705     // Instead, the handlers should know convert vertical scrolls appropriately.
2706     PlatformWheelEvent adjustedEvent = event;
2707     if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, event))
2708         adjustedEvent = event.copyTurningVerticalTicksIntoHorizontalTicks();
2709
2710     platformRecordWheelEvent(adjustedEvent);
2711
2712     if (element) {
2713         if (isOverWidget) {
2714             if (WeakPtr<Widget> widget = widgetForElement(*element)) {
2715                 if (widgetDidHandleWheelEvent(event, *widget.get()))
2716                     return completeWidgetWheelEvent(adjustedEvent, widget, scrollableArea, scrollableContainer.get());
2717             }
2718         }
2719
2720         if (!element->dispatchWheelEvent(adjustedEvent)) {
2721             m_isHandlingWheelEvent = false;
2722             if (scrollableArea && scrollableArea->isScrolledProgrammatically()) {
2723                 // Web developer is controlling scrolling, so don't attempt to latch.
2724                 clearLatchedState();
2725                 scrollableArea->setScrolledProgrammatically(false);
2726             }
2727
2728             platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
2729             return true;
2730         }
2731     }
2732
2733     if (scrollableArea)
2734         scrollableArea->setScrolledProgrammatically(false);
2735
2736     bool handledEvent = platformCompleteWheelEvent(adjustedEvent, scrollableContainer.get(), scrollableArea);
2737     platformNotifyIfEndGesture(adjustedEvent, scrollableArea);
2738     return handledEvent;
2739 }
2740
2741 void EventHandler::clearLatchedState()
2742 {
2743 #if PLATFORM(MAC)
2744     m_frame.mainFrame().resetLatchingState();
2745 #endif
2746     if (auto filter = m_frame.mainFrame().wheelEventDeltaFilter())
2747         filter->endFilteringDeltas();
2748 }
2749
2750 void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent& wheelEvent)
2751 {
2752     if (!startNode)
2753         return;
2754     
2755     Ref<Frame> protectedFrame(m_frame);
2756
2757     FloatSize filteredPlatformDelta(wheelEvent.deltaX(), wheelEvent.deltaY());
2758     if (const PlatformWheelEvent* platformWheelEvent = wheelEvent.wheelEvent()) {
2759         filteredPlatformDelta.setWidth(platformWheelEvent->deltaX());
2760         filteredPlatformDelta.setHeight(platformWheelEvent->deltaY());
2761     }
2762     
2763 #if PLATFORM(MAC)
2764     ScrollLatchingState* latchedState = m_frame.mainFrame().latchingState();
2765     Element* stopElement = latchedState ? latchedState->previousWheelScrolledElement() : nullptr;
2766
2767     if (m_frame.mainFrame().wheelEventDeltaFilter()->isFilteringDeltas())
2768         filteredPlatformDelta = m_frame.mainFrame().wheelEventDeltaFilter()->filteredDelta();
2769 #else
2770     Element* stopElement = nullptr;
2771 #endif
2772     
2773     
2774     if (handleWheelEventInAppropriateEnclosingBox(startNode, wheelEvent, &stopElement, filteredPlatformDelta))
2775         wheelEvent.setDefaultHandled();
2776     
2777 #if PLATFORM(MAC)
2778     if (latchedState && !latchedState->wheelEventElement())
2779         latchedState->setPreviousWheelScrolledElement(stopElement);
2780 #endif
2781 }
2782
2783 #if ENABLE(CONTEXT_MENUS)
2784 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2785 {
2786     Ref<Frame> protectedFrame(m_frame);
2787
2788     Document* doc = m_frame.document();
2789     FrameView* view = m_frame.view();
2790     if (!view)
2791         return false;
2792
2793     // Clear mouse press state to avoid initiating a drag while context menu is up.
2794     m_mousePressed = false;
2795     bool swallowEvent;
2796     LayoutPoint viewportPos = view->windowToContents(event.position());
2797     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent);
2798     MouseEventWithHitTestResults mouseEvent = doc->prepareMouseEvent(request, viewportPos, event);
2799
2800     // Do not show context menus when clicking on scrollbars.
2801     if (mouseEvent.scrollbar() || view->scrollbarAtPoint(event.position()))
2802         return false;
2803
2804     if (m_frame.editor().behavior().shouldSelectOnContextualMenuClick()
2805         && !m_frame.selection().contains(viewportPos)
2806         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
2807         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
2808         // available for text selections.  But only if we're above text.
2809         && (m_frame.selection().selection().isContentEditable() || (mouseEvent.targetNode() && mouseEvent.targetNode()->isTextNode()))) {
2810         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
2811         selectClosestContextualWordOrLinkFromMouseEvent(mouseEvent);
2812     }
2813
2814     swallowEvent = !dispatchMouseEvent(eventNames().contextmenuEvent, mouseEvent.targetNode(), true, 0, event, false);
2815     
2816     return swallowEvent;
2817 }
2818
2819 bool EventHandler::sendContextMenuEventForKey()
2820 {
2821     Ref<Frame> protectedFrame(m_frame);
2822
2823     FrameView* view = m_frame.view();
2824     if (!view)
2825         return false;
2826
2827     Document* doc = m_frame.document();
2828     if (!doc)
2829         return false;
2830
2831     // Clear mouse press state to avoid initiating a drag while context menu is up.
2832     m_mousePressed = false;
2833
2834     static const int kContextMenuMargin = 1;
2835
2836 #if OS(WINDOWS)
2837     int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
2838 #else
2839     int rightAligned = 0;
2840 #endif
2841     IntPoint location;
2842
2843     Element* focusedElement = doc->focusedElement();
2844     const VisibleSelection& selection = m_frame.selection().selection();
2845     Position start = selection.start();
2846
2847     if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
2848         RefPtr<Range> selectionRange = selection.toNormalizedRange();
2849         IntRect firstRect = m_frame.editor().firstRectForRange(selectionRange.get());
2850
2851         int x = rightAligned ? firstRect.maxX() : firstRect.x();
2852         // In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
2853         int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
2854         location = IntPoint(x, y);
2855     } else if (focusedElement) {
2856         RenderBoxModelObject* box = focusedElement->renderBoxModelObject();
2857         if (!box)
2858             return false;
2859         IntRect clippedRect = box->pixelSnappedAbsoluteClippedOverflowRect();
2860         location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1);
2861     } else {
2862         location = IntPoint(
2863             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
2864             kContextMenuMargin);
2865     }
2866
2867     m_frame.view()->setCursor(pointerCursor());
2868
2869     IntPoint position = view->contentsToRootView(location);
2870     IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
2871
2872     Node* targetNode = doc->focusedElement();
2873     if (!targetNode)
2874         targetNode = doc;
2875
2876     // Use the focused node as the target for hover and active.
2877     HitTestResult result(position);
2878     result.setInnerNode(targetNode);
2879     doc->updateHoverActiveState(HitTestRequest::Active | HitTestRequest::DisallowUserAgentShadowContent, result.targetElement());
2880
2881     // The contextmenu event is a mouse event even when invoked using the keyboard.
2882     // This is required for web compatibility.
2883
2884 #if OS(WINDOWS)
2885     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2886 #else
2887     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2888 #endif
2889
2890     PlatformMouseEvent platformMouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime(), ForceAtClick, NoTap);
2891
2892     return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, platformMouseEvent, false);
2893 }
2894 #endif // ENABLE(CONTEXT_MENUS)
2895
2896 void EventHandler::scheduleHoverStateUpdate()
2897 {
2898     if (!m_hoverTimer.isActive())
2899         m_hoverTimer.startOneShot(0);
2900 }
2901
2902 #if ENABLE(CURSOR_SUPPORT)
2903 void EventHandler::scheduleCursorUpdate()
2904 {
2905     if (!m_cursorUpdateTimer.isActive())
2906         m_cursorUpdateTimer.startOneShot(cursorUpdateInterval);
2907 }
2908 #endif
2909
2910 void EventHandler::dispatchFakeMouseMoveEventSoon()
2911 {
2912 #if !ENABLE(IOS_TOUCH_EVENTS)
2913     if (m_mousePressed)
2914         return;
2915
2916     if (m_mousePositionIsUnknown)
2917         return;
2918
2919     if (Page* page = m_frame.page()) {
2920         if (!page->chrome().client().shouldDispatchFakeMouseMoveEvents())
2921             return;
2922     }
2923
2924     // If the content has ever taken longer than fakeMouseMoveShortInterval we
2925     // reschedule the timer and use a longer time. This will cause the content
2926     // to receive these moves only after the user is done scrolling, reducing
2927     // pauses during the scroll.
2928     if (m_fakeMouseMoveEventTimer.isActive())
2929         m_fakeMouseMoveEventTimer.stop();
2930     m_fakeMouseMoveEventTimer.startOneShot(m_maxMouseMovedDuration > fakeMouseMoveDurationThreshold ? fakeMouseMoveLongInterval : fakeMouseMoveShortInterval);
2931 #endif
2932 }
2933
2934 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
2935 {
2936 #if ENABLE(IOS_TOUCH_EVENTS)
2937     UNUSED_PARAM(quad);
2938 #else
2939     FrameView* view = m_frame.view();
2940     if (!view)
2941         return;
2942
2943     if (!quad.containsPoint(view->windowToContents(m_lastKnownMousePosition)))
2944         return;
2945
2946     dispatchFakeMouseMoveEventSoon();
2947 #endif
2948 }
2949
2950 #if !ENABLE(IOS_TOUCH_EVENTS)
2951 void EventHandler::cancelFakeMouseMoveEvent()
2952 {
2953     m_fakeMouseMoveEventTimer.stop();
2954 }
2955
2956 void EventHandler::fakeMouseMoveEventTimerFired()
2957 {
2958     ASSERT(!m_mousePressed);
2959
2960     FrameView* view = m_frame.view();
2961     if (!view)
2962         return;
2963
2964     if (!m_frame.page() || !m_frame.page()->isVisible() || !m_frame.page()->focusController().isActive())
2965         return;
2966
2967     bool shiftKey;
2968     bool ctrlKey;
2969     bool altKey;
2970     bool metaKey;
2971     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
2972     PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime(), 0, NoTap);
2973     mouseMoved(fakeMouseMoveEvent);
2974 }
2975 #endif // !ENABLE(IOS_TOUCH_EVENTS)
2976
2977 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
2978 {
2979     m_frameSetBeingResized = frameSet;
2980 }
2981
2982 void EventHandler::resizeLayerDestroyed()
2983 {
2984     ASSERT(m_resizeLayer);
2985     m_resizeLayer = nullptr;
2986 }
2987
2988 void EventHandler::hoverTimerFired()
2989 {
2990     m_hoverTimer.stop();
2991
2992     ASSERT(m_frame.document());
2993
2994     Ref<Frame> protectedFrame(m_frame);
2995
2996     if (RenderView* renderView = m_frame.contentRenderer()) {
2997         if (FrameView* view = m_frame.view()) {
2998             HitTestRequest request(HitTestRequest::Move | HitTestRequest::DisallowUserAgentShadowContent);
2999             HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
3000             renderView->hitTest(request, result);
3001             m_frame.document()->updateHoverActiveState(request, result.targetElement());
3002         }
3003     }
3004 }
3005
3006 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& event)
3007 {
3008     // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
3009     // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
3010     // lower case variants are present in a document, the correct element is matched based on Shift key state.
3011     // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
3012     ASSERT(!accessKeyModifiers().contains(PlatformEvent::Modifier::ShiftKey));
3013
3014     if ((event.modifiers() - PlatformEvent::Modifier::ShiftKey) != accessKeyModifiers())
3015         return false;
3016     Element* element = m_frame.document()->getElementByAccessKey(event.unmodifiedText());
3017     if (!element)
3018         return false;
3019     element->accessKeyAction(false);
3020     return true;
3021 }
3022
3023 #if !PLATFORM(MAC)
3024 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
3025 {
3026     return false;
3027 }
3028 #endif
3029
3030 #if ENABLE(FULLSCREEN_API)
3031 bool EventHandler::isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent& keyEvent) const
3032 {
3033     Document* document = m_frame.document();
3034     if (document->webkitFullScreenKeyboardInputAllowed())
3035         return true;
3036
3037     if (keyEvent.type() == PlatformKeyboardEvent::Char) {
3038         if (keyEvent.text().length() != 1)
3039             return false;
3040         UChar character = keyEvent.text()[0];
3041         return character == ' ';
3042     }
3043
3044     int keyCode = keyEvent.windowsVirtualKeyCode();
3045     return (keyCode >= VK_BACK && keyCode <= VK_CAPITAL)
3046         || (keyCode >= VK_SPACE && keyCode <= VK_DELETE)
3047         || (keyCode >= VK_OEM_1 && keyCode <= VK_OEM_PLUS)
3048         || (keyCode >= VK_MULTIPLY && keyCode <= VK_OEM_8);
3049 }
3050 #endif
3051
3052 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
3053 {
3054     Ref<Frame> protectedFrame(m_frame);
3055     RefPtr<FrameView> protector(m_frame.view());
3056
3057     LOG(Editing, "EventHandler %p keyEvent (text %s keyIdentifier %s)", this, initialKeyEvent.text().utf8().data(), initialKeyEvent.keyIdentifier().utf8().data());
3058
3059 #if ENABLE(POINTER_LOCK)
3060     if (initialKeyEvent.type() == PlatformEvent::KeyDown && initialKeyEvent.windowsVirtualKeyCode() == VK_ESCAPE && m_frame.page()->pointerLockController().element()) {
3061         m_frame.page()->pointerLockController().requestPointerUnlock();
3062         return true;
3063     }
3064 #endif
3065
3066 #if ENABLE(FULLSCREEN_API)
3067     if (m_frame.document()->webkitIsFullScreen() && !isKeyEventAllowedInFullScreen(initialKeyEvent))
3068         return false;
3069 #endif
3070
3071     if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL) {
3072         if (auto* element = m_frame.document()->focusedElement()) {
3073             if (is<HTMLInputElement>(*element))
3074                 downcast<HTMLInputElement>(*element).capsLockStateMayHaveChanged();
3075         }
3076     }
3077
3078 #if ENABLE(PAN_SCROLLING)
3079     if (m_frame.mainFrame().eventHandler().panScrollInProgress()) {
3080         // If a key is pressed while the panScroll is in progress then we want to stop
3081         if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown)
3082             stopAutoscrollTimer();
3083
3084         // If we were in panscroll mode, we swallow the key event
3085         return true;
3086     }
3087 #endif
3088
3089     // Check for cases where we are too early for events -- possible unmatched key up
3090     // from pressing return in the location bar.
3091     RefPtr<Element> element = eventTargetElementForDocument(m_frame.document());
3092     if (!element)
3093         return false;
3094
3095     UserGestureIndicator gestureIndicator(ProcessingUserGesture, m_frame.document());
3096     UserTypingGestureIndicator typingGestureIndicator(m_frame);
3097
3098     if (FrameView* view = m_frame.view())
3099         view->disableLayerFlushThrottlingTemporarilyForInteraction();
3100
3101     // FIXME (bug 68185): this call should be made at another abstraction layer
3102     m_frame.loader().resetMultipleFormSubmissionProtection();
3103
3104     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
3105     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
3106     // with access keys. Then we dispatch keydown, but suppress its default handling.
3107     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
3108     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
3109     bool matchedAnAccessKey = false;
3110     if (initialKeyEvent.type() == PlatformEvent::KeyDown)
3111         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
3112
3113     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
3114     if (initialKeyEvent.type() == PlatformEvent::KeyUp || initialKeyEvent.type() == PlatformEvent::Char)
3115         return !element->dispatchKeyEvent(initialKeyEvent);
3116
3117     bool backwardCompatibilityMode = needsKeyboardEventDisambiguationQuirks();
3118
3119     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;    
3120     if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
3121         keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown, backwardCompatibilityMode);
3122     Ref<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
3123     if (matchedAnAccessKey)
3124         keydown->setDefaultPrevented(true);
3125     keydown->setTarget(element);
3126
3127     if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
3128         element->dispatchEvent(keydown);
3129         // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
3130         bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
3131         return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3132     }
3133
3134     // Run input method in advance of DOM event handling.  This may result in the IM
3135     // modifying the page prior the keydown event, but this behaviour is necessary
3136     // in order to match IE:
3137     // 1. preventing default handling of keydown and keypress events has no effect on IM input;
3138     // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
3139     m_frame.editor().handleInputMethodKeydown(keydown.get());
3140     
3141     bool handledByInputMethod = keydown->defaultHandled();
3142     
3143     if (handledByInputMethod) {
3144         keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
3145         keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
3146         keydown->setTarget(element);
3147         keydown->setDefaultHandled();
3148     }
3149     
3150     if (accessibilityPreventsEventPropogation(keydown))
3151         keydown->stopPropagation();
3152
3153     element->dispatchEvent(keydown);
3154     // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
3155     bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
3156     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3157     if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
3158         return keydownResult;
3159     
3160     // Focus may have changed during keydown handling, so refetch element.
3161     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original element.
3162     if (!keydownResult) {
3163         element = eventTargetElementForDocument(m_frame.document());
3164         if (!element)
3165             return false;
3166     }
3167
3168     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
3169     keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char, backwardCompatibilityMode);
3170     if (keyPressEvent.text().isEmpty())
3171         return keydownResult;
3172     Ref<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame.document()->defaultView());
3173     keypress->setTarget(element);
3174     if (keydownResult)
3175         keypress->setDefaultPrevented(true);
3176 #if PLATFORM(COCOA)
3177     keypress->keypressCommands() = keydown->keypressCommands();
3178 #endif
3179     element->dispatchEvent(keypress);
3180
3181     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
3182 }
3183
3184 static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
3185 {
3186     static NeverDestroyed<AtomicString> Down("Down", AtomicString::ConstructFromLiteral);
3187     static NeverDestroyed<AtomicString> Up("Up", AtomicString::ConstructFromLiteral);
3188     static NeverDestroyed<AtomicString> Left("Left", AtomicString::ConstructFromLiteral);
3189     static NeverDestroyed<AtomicString> Right("Right", AtomicString::ConstructFromLiteral);
3190
3191     FocusDirection retVal = FocusDirectionNone;
3192
3193     if (keyIdentifier == Down)
3194         retVal = FocusDirectionDown;
3195     else if (keyIdentifier == Up)
3196         retVal = FocusDirectionUp;
3197     else if (keyIdentifier == Left)
3198         retVal = FocusDirectionLeft;
3199     else if (keyIdentifier == Right)
3200         retVal = FocusDirectionRight;
3201
3202     return retVal;
3203 }
3204
3205 static void setInitialKeyboardSelection(Frame& frame, SelectionDirection direction)
3206 {
3207     Document* document = frame.document();
3208     if (!document)
3209         return;
3210
3211     FrameSelection& selection = frame.selection();
3212
3213     if (!selection.isNone())
3214         return;
3215
3216     Element* focusedElement = document->focusedElement();
3217     VisiblePosition visiblePosition;
3218
3219     switch (direction) {
3220     case DirectionBackward:
3221     case DirectionLeft:
3222         if (focusedElement)
3223             visiblePosition = VisiblePosition(positionBeforeNode(focusedElement));
3224         else
3225             visiblePosition = endOfDocument(document);
3226         break;
3227     case DirectionForward:
3228     case DirectionRight:
3229         if (focusedElement)
3230             visiblePosition = VisiblePosition(positionAfterNode(focusedElement));
3231         else
3232             visiblePosition = startOfDocument(document);
3233         break;
3234     }
3235
3236     AXTextStateChangeIntent intent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, false });
3237     selection.setSelection(visiblePosition, FrameSelection::defaultSetSelectionOptions(UserTriggered), intent);
3238 }
3239
3240 static void handleKeyboardSelectionMovement(Frame& frame, KeyboardEvent& event)
3241 {
3242     FrameSelection& selection = frame.selection();
3243
3244     bool isCommanded = event.getModifierState("Meta");
3245     bool isOptioned = event.getModifierState("Alt");
3246     bool isSelection = !selection.isNone();
3247
3248     FrameSelection::EAlteration alternation = event.getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
3249     SelectionDirection direction = DirectionForward;
3250     TextGranularity granularity = CharacterGranularity;
3251
3252     switch (focusDirectionForKey(event.keyIdentifier())) {
3253     case FocusDirectionNone:
3254         return;
3255     case FocusDirectionForward:
3256     case FocusDirectionBackward:
3257         ASSERT_NOT_REACHED();
3258         return;
3259     case FocusDirectionUp:
3260         direction = DirectionBackward;
3261         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3262         break;
3263     case FocusDirectionDown:
3264         direction = DirectionForward;
3265         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3266         break;
3267     case FocusDirectionLeft:
3268         direction = DirectionLeft;
3269         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3270         break;
3271     case FocusDirectionRight:
3272         direction = DirectionRight;
3273         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3274         break;
3275     }
3276
3277     if (isSelection)
3278         selection.modify(alternation, direction, granularity, UserTriggered);
3279     else
3280         setInitialKeyboardSelection(frame, direction);
3281
3282     event.setDefaultHandled();
3283 }
3284
3285 void EventHandler::handleKeyboardSelectionMovementForAccessibility(KeyboardEvent& event)
3286 {
3287     if (event.type() == eventNames().keydownEvent) {
3288         if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3289             handleKeyboardSelectionMovement(m_frame, event);
3290     }
3291 }
3292
3293 bool EventHandler::accessibilityPreventsEventPropogation(KeyboardEvent& event)
3294 {
3295 #if PLATFORM(COCOA)
3296     if (!AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3297         return false;
3298
3299     if (!m_frame.settings().preventKeyboardDOMEventDispatch())
3300         return false;
3301
3302     // Check for key events that are relevant to accessibility: tab and arrows keys that change focus
3303     if (event.keyIdentifier() == "U+0009")
3304         return true;
3305     FocusDirection direction = focusDirectionForKey(event.keyIdentifier());
3306     if (direction != FocusDirectionNone)
3307         return true;
3308 #else
3309     UNUSED_PARAM(event);
3310 #endif
3311     return false;
3312 }
3313
3314 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent& event)
3315 {
3316     Ref<Frame> protectedFrame(m_frame);
3317
3318     if (event.type() == eventNames().keydownEvent) {
3319         m_frame.editor().handleKeyboardEvent(event);
3320         if (event.defaultHandled())
3321             return;
3322         if (event.keyIdentifier() == "U+0009")
3323             defaultTabEventHandler(event);
3324         else if (event.keyIdentifier() == "U+0008")
3325             defaultBackspaceEventHandler(event);
3326         else {
3327             FocusDirection direction = focusDirectionForKey(event.keyIdentifier());
3328             if (direction != FocusDirectionNone)
3329                 defaultArrowEventHandler(direction, event);
3330         }
3331
3332         handleKeyboardSelectionMovementForAccessibility(event);
3333     }
3334     if (event.type() == eventNames().keypressEvent) {
3335         m_frame.editor().handleKeyboardEvent(event);
3336         if (event.defaultHandled())
3337             return;
3338         if (event.charCode() == ' ')
3339             defaultSpaceEventHandler(event);
3340     }
3341 }
3342
3343 #if ENABLE(DRAG_SUPPORT)
3344 bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocation) const
3345 {
3346     FloatPoint dragViewportLocation(floatDragViewportLocation.x(), floatDragViewportLocation.y());
3347     return dragHysteresisExceeded(dragViewportLocation);
3348 }
3349
3350 bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
3351 {
3352     int threshold = GeneralDragHysteresis;
3353     switch (dragState().type) {
3354     case DragSourceActionSelection:
3355         threshold = TextDragHysteresis;
3356         break;
3357     case DragSourceActionImage:
3358 #if ENABLE(ATTACHMENT_ELEMENT)
3359     case DragSourceActionAttachment:
3360 #endif
3361         threshold = ImageDragHysteresis;
3362         break;
3363     case DragSourceActionLink:
3364         threshold = LinkDragHysteresis;
3365         break;
3366     case DragSourceActionDHTML:
3367         break;
3368     case DragSourceActionNone:
3369     case DragSourceActionAny:
3370         ASSERT_NOT_REACHED();
3371     }
3372     
3373     return mouseMovementExceedsThreshold(dragViewportLocation, threshold);
3374 }
3375     
3376 void EventHandler::freeDataTransfer()
3377 {
3378     if (!dragState().dataTransfer)
3379         return;
3380     dragState().dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb);
3381     dragState().dataTransfer = nullptr;
3382 }
3383
3384 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
3385 {
3386     // Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses.
3387     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowUserAgentShadowContent);
3388     prepareMouseEvent(request, event);
3389
3390     if (dragState().source && dragState().shouldDispatchEvents) {
3391         dragState().dataTransfer->setDestinationOperation(operation);
3392         // For now we don't care if event handler cancels default behavior, since there is no default behavior.
3393         dispatchDragSrcEvent(eventNames().dragendEvent, event);
3394     }
3395     freeDataTransfer();
3396     dragState().source = nullptr;
3397     // In case the drag was ended due to an escape key press we need to ensure
3398     // that consecutive mousemove events don't reinitiate the drag and drop.
3399     m_mouseDownMayStartDrag = false;
3400 }
3401
3402 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement)
3403 {
3404     // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editable element.
3405     if (dragState().source && !dragState().source->inDocument())
3406         dragState().source = rootEditableElement;
3407 }
3408
3409 // Return value indicates if we should continue "default processing", i.e., whether event handler canceled.
3410 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
3411 {
3412     return !dispatchDragEvent(eventType, *dragState().source, event, dragState().dataTransfer.get());
3413 }
3414     
3415 static bool ExactlyOneBitSet(DragSourceAction n)
3416 {
3417     return n && !(n & (n - 1));
3418 }
3419
3420 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDragHysteresis checkDragHysteresis)
3421 {
3422     if (event.event().button() != LeftButton || event.event().type() != PlatformEvent::MouseMoved) {
3423         // If we allowed the other side of the bridge to handle a drag
3424         // last time, then m_mousePressed might still be set. So we
3425         // clear it now to make sure the next move after a drag
3426         // doesn't look like a drag.
3427         m_mousePressed = false;
3428         return false;
3429     }
3430     
3431     Ref<Frame> protectedFrame(m_frame);
3432
3433     if (eventLoopHandleMouseDragged(event))
3434         return true;
3435     
3436     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
3437     
3438     if (m_mouseDownMayStartDrag && !dragState().source) {
3439         dragState().shouldDispatchEvents = (updateDragSourceActionsAllowed() & DragSourceActionDHTML);
3440
3441         // try to find an element that wants to be dragged
3442         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowUserAgentShadowContent);
3443         HitTestResult result(m_mouseDownPos);
3444         m_frame.contentRenderer()->hitTest(request, result);
3445         if (m_frame.page())
3446             dragState().source = m_frame.page()->dragController().draggableElement(&m_frame, result.targetElement(), m_mouseDownPos, dragState());
3447         
3448         if (!dragState().source)
3449             m_mouseDownMayStartDrag = false; // no element is draggable
3450         else
3451             m_dragMayStartSelectionInstead = (dragState().type & DragSourceActionSelection);
3452     }
3453     
3454     // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
3455     // or else we bail on the dragging stuff and allow selection to occur
3456     if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState().type & DragSourceActionSelection) && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
3457         ASSERT(event.event().type() == PlatformEvent::MouseMoved);
3458         if ((dragState().type & DragSourceActionImage)) {
3459             // ... unless the mouse is over an image, then we start dragging just the image
3460             dragState().type = DragSourceActionImage;
3461         } else if (!(dragState().type & (DragSourceActionDHTML | DragSourceActionLink))) {
3462             // ... but only bail if we're not over an unselectable element.
3463             m_mouseDownMayStartDrag = false;
3464             dragState().source = nullptr;
3465             // ... but if this was the first click in the window, we don't even want to start selection
3466             if (eventActivatedView(event.event()))
3467                 m_mouseDownMayStartSelect = false;
3468         } else {
3469             // Prevent the following case from occuring:
3470             // 1. User starts a drag immediately after mouse down over an unselectable element.
3471             // 2. We enter this block and decided that since we're over an unselectable element, don't cancel the drag.
3472             // 3. The drag gets resolved as a potential selection drag below /but/ we haven't exceeded the drag hysteresis yet.
3473             // 4. We enter this block again, and since it's now marked as a selection drag, we cancel the drag.
3474             m_dragMayStartSelectionInstead = false;
3475         }
3476     }
3477     
3478     if (!m_mouseDownMayStartDrag)
3479         return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
3480     
3481     if (!ExactlyOneBitSet(dragState().type)) {
3482         ASSERT((dragState().type & DragSourceActionSelection));
3483 #if ENABLE(ATTACHMENT_ELEMENT)
3484         ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
3485                || (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage
3486                || (dragState().type & ~DragSourceActionSelection) == DragSourceActionAttachment
3487                || (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink);
3488 #else
3489         ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
3490             || (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage