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