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