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