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