a5f683192bc420ee766518b85dd9e9f47da7e0d7
[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 {
427 }
428
429 EventHandler::~EventHandler()
430 {
431 #if !ENABLE(IOS_TOUCH_EVENTS)
432     ASSERT(!m_fakeMouseMoveEventTimer.isActive());
433 #endif
434 #if ENABLE(CURSOR_VISIBILITY)
435     ASSERT(!m_autoHideCursorTimer.isActive());
436 #endif
437 }
438     
439 #if ENABLE(DRAG_SUPPORT)
440 DragState& EventHandler::dragState()
441 {
442     DEPRECATED_DEFINE_STATIC_LOCAL(DragState, state, ());
443     return state;
444 }
445 #endif // ENABLE(DRAG_SUPPORT)
446     
447 void EventHandler::clear()
448 {
449     m_hoverTimer.stop();
450 #if ENABLE(CURSOR_SUPPORT)
451     m_cursorUpdateTimer.stop();
452 #endif
453 #if !ENABLE(IOS_TOUCH_EVENTS)
454     m_fakeMouseMoveEventTimer.stop();
455 #endif
456 #if ENABLE(CURSOR_VISIBILITY)
457     cancelAutoHideCursorTimer();
458 #endif
459     clearLongMousePressState();
460     m_resizeLayer = nullptr;
461     m_elementUnderMouse = nullptr;
462     m_lastElementUnderMouse = nullptr;
463     m_lastMouseMoveEventSubframe = nullptr;
464     m_lastScrollbarUnderMouse = nullptr;
465     m_clickCount = 0;
466     m_clickNode = nullptr;
467 #if ENABLE(IOS_GESTURE_EVENTS)
468     m_gestureInitialDiameter = GestureUnknown;
469     m_gestureLastDiameter = GestureUnknown;
470     m_gestureInitialRotation = GestureUnknown;
471     m_gestureLastRotation = GestureUnknown;
472     m_gestureTargets.clear();
473 #endif
474 #if ENABLE(IOS_TOUCH_EVENTS)
475     m_touches.clear();
476     m_firstTouchID = InvalidTouchIdentifier;
477     m_touchEventTargetSubframe = nullptr;
478 #endif
479     m_frameSetBeingResized = nullptr;
480 #if ENABLE(DRAG_SUPPORT)
481     m_dragTarget = nullptr;
482     m_shouldOnlyFireDragOverEvent = false;
483 #endif
484     m_mousePositionIsUnknown = true;
485     m_lastKnownMousePosition = IntPoint();
486     m_lastKnownMouseGlobalPosition = IntPoint();
487     m_mousePressNode = 0;
488     m_mousePressed = false;
489     m_capturesDragging = false;
490     m_capturingMouseEventsElement = nullptr;
491 #if PLATFORM(MAC)
492     m_frame.mainFrame().resetLatchingState();
493 #endif
494 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
495     m_originatingTouchPointTargets.clear();
496     m_originatingTouchPointDocument.clear();
497     m_originatingTouchPointTargetKey = 0;
498 #endif
499     m_maxMouseMovedDuration = 0;
500     m_baseEventType = PlatformEvent::NoType;
501     m_didStartDrag = false;
502     m_didLongPressInvokeContextMenu = false;
503 }
504
505 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
506 {
507     if (nodeToBeRemoved.contains(m_clickNode.get()))
508         m_clickNode = nullptr;
509 }
510
511 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
512 {
513     if (selection.selection() != newSelection && selection.shouldChangeSelection(newSelection))
514         selection.setSelection(newSelection);
515 }
516
517 static inline bool dispatchSelectStart(Node* node)
518 {
519     if (!node || !node->renderer())
520         return true;
521
522     return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
523 }
524
525 static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
526 {
527 #if ENABLE(USERSELECT_ALL)
528     Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode);
529     if (!rootUserSelectAll)
530         return selection;
531
532     VisibleSelection newSelection(selection);
533     newSelection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
534     newSelection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary));
535
536     return newSelection;
537 #else
538     UNUSED_PARAM(targetNode);
539     return selection;
540 #endif
541 }
542
543 bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& selection, TextGranularity granularity)
544 {
545     if (Position::nodeIsUserSelectNone(targetNode))
546         return false;
547
548     if (!dispatchSelectStart(targetNode))
549         return false;
550
551     if (selection.isRange())
552         m_selectionInitiationState = ExtendedSelection;
553     else {
554         granularity = CharacterGranularity;
555         m_selectionInitiationState = PlacedCaret;
556     }
557
558     m_frame.selection().setSelectionByMouseIfDifferent(selection, granularity);
559
560     return true;
561 }
562
563 void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
564 {
565     Node* targetNode = result.targetNode();
566     VisibleSelection newSelection;
567
568     if (targetNode && targetNode->renderer()) {
569         VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
570         if (pos.isNotNull()) {
571             newSelection = VisibleSelection(pos);
572             newSelection.expandUsingGranularity(WordGranularity);
573         }
574
575         if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
576             newSelection.appendTrailingWhitespace();
577
578         updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectUserSelectAll(targetNode, newSelection), WordGranularity);
579     }
580 }
581
582 void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
583 {
584     if (m_mouseDownMayStartSelect) {
585         selectClosestWordFromHitTestResult(result.hitTestResult(),
586             (result.event().clickCount() == 2 && m_frame.editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
587     }
588 }
589
590 void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
591 {
592     if (!result.hitTestResult().isLiveLink())
593         return selectClosestWordFromMouseEvent(result);
594
595     Node* targetNode = result.targetNode();
596
597     if (targetNode && targetNode->renderer() && m_mouseDownMayStartSelect) {
598         VisibleSelection newSelection;
599         Element* URLElement = result.hitTestResult().URLElement();
600         VisiblePosition pos(targetNode->renderer()->positionForPoint(result.localPoint(), nullptr));
601         if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
602             newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
603
604         updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectUserSelectAll(targetNode, newSelection), WordGranularity);
605     }
606 }
607
608 bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
609 {
610     if (event.event().button() != LeftButton)
611         return false;
612
613     if (m_frame.selection().isRange())
614         // A double-click when range is already selected
615         // should not change the selection.  So, do not call
616         // selectClosestWordFromMouseEvent, but do set
617         // m_beganSelectingText to prevent handleMouseReleaseEvent
618         // from setting caret selection.
619         m_selectionInitiationState = ExtendedSelection;
620     else
621         selectClosestWordFromMouseEvent(event);
622
623     return true;
624 }
625
626 bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
627 {
628     if (event.event().button() != LeftButton)
629         return false;
630     
631     Node* targetNode = event.targetNode();
632     if (!(targetNode && targetNode->renderer() && m_mouseDownMayStartSelect))
633         return false;
634
635     VisibleSelection newSelection;
636     VisiblePosition pos(targetNode->renderer()->positionForPoint(event.localPoint(), nullptr));
637     if (pos.isNotNull()) {
638         newSelection = VisibleSelection(pos);
639         newSelection.expandUsingGranularity(ParagraphGranularity);
640     }
641
642     return updateSelectionForMouseDownDispatchingSelectStart(targetNode, expandSelectionToRespectUserSelectAll(targetNode, newSelection), ParagraphGranularity);
643 }
644
645 static int textDistance(const Position& start, const Position& end)
646 {
647     RefPtr<Range> range = Range::create(start.anchorNode()->document(), start, end);
648     return TextIterator::rangeLength(range.get(), true);
649 }
650
651 bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
652 {
653     m_frame.document()->updateLayoutIgnorePendingStylesheets();
654     Node* targetNode = event.targetNode();
655     if (!(targetNode && targetNode->renderer() && m_mouseDownMayStartSelect))
656         return false;
657
658     // Extend the selection if the Shift key is down, unless the click is in a link.
659     bool extendSelection = event.event().shiftKey() && !event.isOverLink();
660
661     // Don't restart the selection when the mouse is pressed on an
662     // existing selection so we can allow for text dragging.
663     if (FrameView* view = m_frame.view()) {
664         LayoutPoint vPoint = view->windowToContents(event.event().position());
665         if (!extendSelection && m_frame.selection().contains(vPoint)) {
666             m_mouseDownWasSingleClickInSelection = true;
667             return false;
668         }
669     }
670
671     VisiblePosition visiblePos(targetNode->renderer()->positionForPoint(event.localPoint(), nullptr));
672     if (visiblePos.isNull())
673         visiblePos = VisiblePosition(firstPositionInOrBeforeNode(targetNode), DOWNSTREAM);
674     Position pos = visiblePos.deepEquivalent();
675
676     VisibleSelection newSelection = m_frame.selection().selection();
677     TextGranularity granularity = CharacterGranularity;
678
679     if (extendSelection && newSelection.isCaretOrRange()) {
680         VisibleSelection selectionInUserSelectAll = expandSelectionToRespectUserSelectAll(targetNode, VisibleSelection(pos));
681         if (selectionInUserSelectAll.isRange()) {
682             if (comparePositions(selectionInUserSelectAll.start(), newSelection.start()) < 0)
683                 pos = selectionInUserSelectAll.start();
684             else if (comparePositions(newSelection.end(), selectionInUserSelectAll.end()) < 0)
685                 pos = selectionInUserSelectAll.end();
686         }
687
688         if (!m_frame.editor().behavior().shouldConsiderSelectionAsDirectional() && pos.isNotNull()) {
689             // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
690             // was created right-to-left
691             Position start = newSelection.start();
692             Position end = newSelection.end();
693             int distanceToStart = textDistance(start, pos);
694             int distanceToEnd = textDistance(pos, end);
695             if (distanceToStart <= distanceToEnd)
696                 newSelection = VisibleSelection(end, pos);
697             else
698                 newSelection = VisibleSelection(start, pos);
699         } else
700             newSelection.setExtent(pos);
701
702         if (m_frame.selection().granularity() != CharacterGranularity) {
703             granularity = m_frame.selection().granularity();
704             newSelection.expandUsingGranularity(m_frame.selection().granularity());
705         }
706     } else
707         newSelection = expandSelectionToRespectUserSelectAll(targetNode, visiblePos);
708
709     bool handled = updateSelectionForMouseDownDispatchingSelectStart(targetNode, newSelection, granularity);
710
711     if (event.event().button() == MiddleButton) {
712         // Ignore handled, since we want to paste to where the caret was placed anyway.
713         handled = handlePasteGlobalSelection(event.event()) || handled;
714     }
715     return handled;
716 }
717
718 static inline bool canMouseDownStartSelect(Node* node)
719 {
720     if (!node || !node->renderer())
721         return true;
722
723     return node->canStartSelection() || Position::nodeIsUserSelectAll(node);
724 }
725
726 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
727 {
728 #if ENABLE(DRAG_SUPPORT)
729     // Reset drag state.
730     dragState().source = nullptr;
731 #endif
732
733 #if !ENABLE(IOS_TOUCH_EVENTS)
734     cancelFakeMouseMoveEvent();
735 #endif
736
737     m_frame.document()->updateLayoutIgnorePendingStylesheets();
738
739     if (ScrollView* scrollView = m_frame.view()) {
740         if (scrollView->isPointInScrollbarCorner(event.event().position()))
741             return false;
742     }
743
744     bool singleClick = event.event().clickCount() <= 1;
745
746     // If we got the event back, that must mean it wasn't prevented,
747     // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
748     m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode()) && !event.scrollbar();
749     
750 #if ENABLE(DRAG_SUPPORT)
751     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
752     m_mouseDownMayStartDrag = singleClick;
753 #endif
754
755     m_mouseDownWasSingleClickInSelection = false;
756
757     m_mouseDown = event.event();
758
759     if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
760         return true;
761
762     if (is<SVGDocument>(*m_frame.document()) && downcast<SVGDocument>(*m_frame.document()).zoomAndPanEnabled()) {
763         if (event.event().shiftKey() && singleClick) {
764             m_svgPan = true;
765             downcast<SVGDocument>(*m_frame.document()).startPan(m_frame.view()->windowToContents(event.event().position()));
766             return true;
767         }
768     }
769
770     if (event.event().button() == LeftButton && event.isOverLink()) {
771         // FIXME 135703: Handle long press for more than just links.
772         beginTrackingPotentialLongMousePress(event.hitTestResult());
773     }
774
775     // We don't do this at the start of mouse down handling,
776     // because we don't want to do it until we know we didn't hit a widget.
777     if (singleClick)
778         focusDocumentView();
779
780     m_mousePressNode = event.targetNode();
781 #if ENABLE(DRAG_SUPPORT)
782     m_dragStartPos = event.event().position();
783 #endif
784
785     bool swallowEvent = false;
786     m_mousePressed = true;
787     m_selectionInitiationState = HaveNotStartedSelection;
788
789     if (event.event().clickCount() == 2)
790         swallowEvent = handleMousePressEventDoubleClick(event);
791     else if (event.event().clickCount() >= 3)
792         swallowEvent = handleMousePressEventTripleClick(event);
793     else
794         swallowEvent = handleMousePressEventSingleClick(event);
795     
796     m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect
797         || (m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled());
798
799     return swallowEvent;
800 }
801
802 #if ENABLE(DRAG_SUPPORT)
803 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event)
804 {
805     if (!m_mousePressed)
806         return false;
807
808     if (handleDrag(event, ShouldCheckDragHysteresis))
809         return true;
810
811     Node* targetNode = event.targetNode();
812     if (event.event().button() != LeftButton || !targetNode)
813         return false;
814
815     RenderObject* renderer = targetNode->renderer();
816     if (!renderer) {
817         Element* parent = targetNode->parentOrShadowHostElement();
818         if (!parent)
819             return false;
820
821         renderer = parent->renderer();
822         if (!renderer || !renderer->isListBox())
823             return false;
824     }
825
826 #if PLATFORM(COCOA) // FIXME: Why does this assertion fire on other platforms?
827     ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
828 #endif
829
830     m_mouseDownMayStartDrag = false;
831
832     if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
833         m_autoscrollController->startAutoscrollForSelection(renderer);
834         m_mouseDownMayStartAutoscroll = false;
835     }
836
837     if (m_selectionInitiationState != ExtendedSelection) {
838         HitTestResult result(m_mouseDownPos);
839         m_frame.document()->renderView()->hitTest(HitTestRequest(), result);
840
841         updateSelectionForMouseDrag(result);
842     }
843     updateSelectionForMouseDrag(event.hitTestResult());
844     return true;
845 }
846     
847 bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
848 {
849     // This is a pre-flight check of whether the event might lead to a drag being started.  Be careful
850     // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
851     // in handleMousePressEvent
852     RenderView* renderView = m_frame.contentRenderer();
853     if (!renderView)
854         return false;
855
856     if (event.button() != LeftButton || event.clickCount() != 1)
857         return false;
858
859     if (m_didRecognizeLongMousePress)
860         return false;
861     
862     FrameView* view = m_frame.view();
863     if (!view)
864         return false;
865
866     Page* page = m_frame.page();
867     if (!page)
868         return false;
869
870     updateDragSourceActionsAllowed();
871     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
872     HitTestResult result(view->windowToContents(event.position()));
873     renderView->hitTest(request, result);
874     DragState state;
875     return result.innerElement() && page->dragController().draggableElement(&m_frame, result.innerElement(), result.roundedPointInInnerNodeFrame(), state);
876 }
877
878 void EventHandler::updateSelectionForMouseDrag()
879 {
880     FrameView* view = m_frame.view();
881     if (!view)
882         return;
883     RenderView* renderView = m_frame.contentRenderer();
884     if (!renderView)
885         return;
886
887     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::DisallowShadowContent);
888     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
889     renderView->hitTest(request, result);
890     updateSelectionForMouseDrag(result);
891 }
892
893 static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const LayoutPoint& localPoint, Node* targetNode)
894 {
895     FloatPoint selectionEndPoint = localPoint;
896     Element* editableElement = selection.rootEditableElement();
897
898     if (!targetNode->renderer())
899         return VisiblePosition();
900
901     if (editableElement && !editableElement->contains(targetNode)) {
902         if (!editableElement->renderer())
903             return VisiblePosition();
904
905         FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint));
906         selectionEndPoint = editableElement->renderer()->absoluteToLocal(absolutePoint);
907         targetNode = editableElement;
908     }
909
910     return targetNode->renderer()->positionForPoint(LayoutPoint(selectionEndPoint), nullptr);
911 }
912
913 void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
914 {
915     if (!m_mouseDownMayStartSelect)
916         return;
917
918     Node* target = hitTestResult.targetNode();
919     if (!target)
920         return;
921
922     VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(m_frame.selection().selection(), hitTestResult.localPoint(), target);
923
924     // Don't modify the selection if we're not on a node.
925     if (targetPosition.isNull())
926         return;
927
928     // Restart the selection if this is the first mouse move. This work is usually
929     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
930     VisibleSelection newSelection = m_frame.selection().selection();
931
932     // Special case to limit selection to the containing block for SVG text.
933     // FIXME: Isn't there a better non-SVG-specific way to do this?
934     if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
935         if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
936             if (selectionBaseRenderer->isSVGText())
937                 if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
938                     return;
939
940     if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
941         return;
942
943     if (m_selectionInitiationState != ExtendedSelection) {
944         // Always extend selection here because it's caused by a mouse drag
945         m_selectionInitiationState = ExtendedSelection;
946         newSelection = VisibleSelection(targetPosition);
947     }
948
949 #if ENABLE(USERSELECT_ALL)
950     Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllForNode(m_mousePressNode.get());
951     if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePressNode == Position::rootUserSelectAllForNode(target)) {
952         newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePressNode).upstream(CanCrossEditingBoundary));
953         newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
954     } else {
955         // Reset base for user select all when base is inside user-select-all area and extent < base.
956         if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos, nullptr)) < 0)
957             newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
958         
959         Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
960         if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint(), nullptr), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos, nullptr)) < 0)
961             newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
962         else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
963             newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
964         else
965             newSelection.setExtent(targetPosition);
966     }
967 #else
968     newSelection.setExtent(targetPosition);
969 #endif
970
971     if (m_frame.selection().granularity() != CharacterGranularity)
972         newSelection.expandUsingGranularity(m_frame.selection().granularity());
973
974     m_frame.selection().setSelectionByMouseIfDifferent(newSelection, m_frame.selection().granularity(),
975         FrameSelection::AdjustEndpointsAtBidiBoundary);
976 }
977 #endif // ENABLE(DRAG_SUPPORT)
978
979 void EventHandler::lostMouseCapture()
980 {
981     m_frame.selection().setCaretBlinkingSuspended(false);
982 }
983
984 bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
985 {
986     if (eventLoopHandleMouseUp(event))
987         return true;
988     
989     // If this was the first click in the window, we don't even want to clear the selection.
990     // This case occurs when the user clicks on a draggable element, since we have to process
991     // the mouse down and drag events to see if we might start a drag.  For other first clicks
992     // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets
993     // ignored upstream of this layer.
994     return eventActivatedView(event.event());
995 }    
996
997 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
998 {
999     if (autoscrollInProgress())
1000         stopAutoscrollTimer();
1001
1002     if (handleMouseUp(event))
1003         return true;
1004
1005     // Used to prevent mouseMoveEvent from initiating a drag before
1006     // the mouse is pressed again.
1007     m_mousePressed = false;
1008     m_capturesDragging = false;
1009 #if ENABLE(DRAG_SUPPORT)
1010     m_mouseDownMayStartDrag = false;
1011 #endif
1012     m_mouseDownMayStartSelect = false;
1013     m_mouseDownMayStartAutoscroll = false;
1014     m_mouseDownWasInSubframe = false;
1015   
1016     bool handled = false;
1017     
1018     if (event.event().button() == LeftButton) {
1019         // FIXME 135767: Implement long mouse press for arbitrary mouse buttons.
1020         clearLongMousePressState();
1021     }
1022
1023     // Clear the selection if the mouse didn't move after the last mouse
1024     // press and it's not a context menu click.  We do this so when clicking
1025     // on the selection, the selection goes away.  However, if we are
1026     // editing, place the caret.
1027     if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
1028 #if ENABLE(DRAG_SUPPORT)
1029             && m_dragStartPos == event.event().position()
1030 #endif
1031             && m_frame.selection().isRange()
1032             && event.event().button() != RightButton) {
1033         VisibleSelection newSelection;
1034         Node* node = event.targetNode();
1035         bool caretBrowsing = m_frame.settings().caretBrowsingEnabled();
1036         if (node && node->renderer() && (caretBrowsing || node->hasEditableStyle())) {
1037             VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint(), nullptr);
1038             newSelection = VisibleSelection(pos);
1039         }
1040
1041         setSelectionIfNeeded(m_frame.selection(), newSelection);
1042
1043         handled = true;
1044     }
1045
1046     if (event.event().button() == MiddleButton) {
1047         // Ignore handled, since we want to paste to where the caret was placed anyway.
1048         handled = handlePasteGlobalSelection(event.event()) || handled;
1049     }
1050
1051     return handled;
1052 }
1053
1054 #if ENABLE(PAN_SCROLLING)
1055
1056 void EventHandler::didPanScrollStart()
1057 {
1058     m_autoscrollController->didPanScrollStart();
1059 }
1060
1061 void EventHandler::didPanScrollStop()
1062 {
1063     m_autoscrollController->didPanScrollStop();
1064 }
1065
1066 void EventHandler::startPanScrolling(RenderElement* renderer)
1067 {
1068 #if !PLATFORM(IOS)
1069     if (!is<RenderBox>(*renderer))
1070         return;
1071     m_autoscrollController->startPanScrolling(downcast<RenderBox>(renderer), lastKnownMousePosition());
1072     invalidateClick();
1073 #endif
1074 }
1075
1076 #endif // ENABLE(PAN_SCROLLING)
1077
1078 RenderBox* EventHandler::autoscrollRenderer() const
1079 {
1080     return m_autoscrollController->autoscrollRenderer();
1081 }
1082
1083 void EventHandler::updateAutoscrollRenderer()
1084 {
1085     m_autoscrollController->updateAutoscrollRenderer();
1086 }
1087
1088 bool EventHandler::autoscrollInProgress() const
1089 {
1090     return m_autoscrollController->autoscrollInProgress();
1091 }
1092
1093 bool EventHandler::panScrollInProgress() const
1094 {
1095     return m_autoscrollController->panScrollInProgress();
1096 }
1097
1098 #if ENABLE(DRAG_SUPPORT)
1099 DragSourceAction EventHandler::updateDragSourceActionsAllowed() const
1100 {
1101     Page* page = m_frame.page();
1102     if (!page)
1103         return DragSourceActionNone;
1104
1105     FrameView* view = m_frame.view();
1106     if (!view)
1107         return DragSourceActionNone;
1108
1109     return page->dragController().delegateDragSourceAction(view->contentsToRootView(m_mouseDownPos));
1110 }
1111 #endif // ENABLE(DRAG_SUPPORT)
1112
1113 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding)
1114 {
1115     // We always send hitTestResultAtPoint to the main frame if we have one,
1116     // otherwise we might hit areas that are obscured by higher frames.
1117     if (!m_frame.isMainFrame()) {
1118         Frame& mainFrame = m_frame.mainFrame();
1119         FrameView* frameView = m_frame.view();
1120         FrameView* mainView = mainFrame.view();
1121         if (frameView && mainView) {
1122             IntPoint mainFramePoint = mainView->rootViewToContents(frameView->contentsToRootView(roundedIntPoint(point)));
1123             return mainFrame.eventHandler().hitTestResultAtPoint(mainFramePoint, hitType, padding);
1124         }
1125     }
1126
1127     HitTestResult result(point, padding.height(), padding.width(), padding.height(), padding.width());
1128
1129     RenderView* renderView = m_frame.contentRenderer();
1130     if (!renderView)
1131         return result;
1132     
1133     // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
1134     HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
1135     renderView->hitTest(request, result);
1136     if (!request.readOnly())
1137         m_frame.document()->updateHoverActiveState(request, result.innerElement());
1138
1139     if (request.disallowsShadowContent())
1140         result.setToNonShadowAncestor();
1141
1142     return result;
1143 }
1144
1145 void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
1146 {
1147     m_autoscrollController->stopAutoscrollTimer(rendererIsBeingDestroyed);
1148 }
1149
1150 bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1151 {
1152     Node* node = startingNode;
1153
1154     if (!node)
1155         node = m_frame.document()->focusedElement();
1156
1157     if (!node)
1158         node = m_mousePressNode.get();
1159     
1160     if (node) {
1161         auto r = node->renderer();
1162         if (r && !r->isListBox() && r->enclosingBox().scroll(direction, granularity)) {
1163             setFrameWasScrolledByUser();
1164             return true;
1165         }
1166     }
1167
1168     return false;
1169 }
1170
1171 bool EventHandler::logicalScrollOverflow(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1172 {
1173     Node* node = startingNode;
1174
1175     if (!node)
1176         node = m_frame.document()->focusedElement();
1177
1178     if (!node)
1179         node = m_mousePressNode.get();
1180     
1181     if (node) {
1182         auto r = node->renderer();
1183         if (r && !r->isListBox() && r->enclosingBox().logicalScroll(direction, granularity)) {
1184             setFrameWasScrolledByUser();
1185             return true;
1186         }
1187     }
1188
1189     return false;
1190 }
1191
1192 bool EventHandler::scrollRecursively(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1193 {
1194     // The layout needs to be up to date to determine if we can scroll. We may be
1195     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1196     m_frame.document()->updateLayoutIgnorePendingStylesheets();
1197     if (scrollOverflow(direction, granularity, startingNode))
1198         return true;    
1199     Frame* frame = &m_frame;
1200     FrameView* view = frame->view();
1201     if (view && view->scroll(direction, granularity))
1202         return true;
1203     frame = frame->tree().parent();
1204     if (!frame)
1205         return false;
1206     return frame->eventHandler().scrollRecursively(direction, granularity, m_frame.ownerElement());
1207 }
1208
1209 bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1210 {
1211     // The layout needs to be up to date to determine if we can scroll. We may be
1212     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1213     m_frame.document()->updateLayoutIgnorePendingStylesheets();
1214     if (logicalScrollOverflow(direction, granularity, startingNode))
1215         return true;    
1216     Frame* frame = &m_frame;
1217     FrameView* view = frame->view();
1218     
1219     bool scrolled = false;
1220 #if PLATFORM(COCOA)
1221     // Mac also resets the scroll position in the inline direction.
1222     if (granularity == ScrollByDocument && view && view->logicalScroll(ScrollInlineDirectionBackward, ScrollByDocument))
1223         scrolled = true;
1224 #endif
1225     if (view && view->logicalScroll(direction, granularity))
1226         scrolled = true;
1227     
1228     if (scrolled)
1229         return true;
1230     
1231     frame = frame->tree().parent();
1232     if (!frame)
1233         return false;
1234
1235     return frame->eventHandler().logicalScrollRecursively(direction, granularity, m_frame.ownerElement());
1236 }
1237
1238 IntPoint EventHandler::lastKnownMousePosition() const
1239 {
1240     return m_lastKnownMousePosition;
1241 }
1242
1243 Frame* EventHandler::subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
1244 {
1245     if (!hitTestResult.isOverWidget())
1246         return 0;
1247     return subframeForTargetNode(hitTestResult.targetNode());
1248 }
1249
1250 Frame* EventHandler::subframeForTargetNode(Node* node)
1251 {
1252     if (!node)
1253         return nullptr;
1254
1255     auto renderer = node->renderer();
1256     if (!is<RenderWidget>(renderer))
1257         return nullptr;
1258
1259     Widget* widget = downcast<RenderWidget>(*renderer).widget();
1260     if (!is<FrameView>(widget))
1261         return nullptr;
1262
1263     return &downcast<FrameView>(*widget).frame();
1264 }
1265
1266 #if ENABLE(CURSOR_SUPPORT)
1267 static bool isSubmitImage(Node* node)
1268 {
1269     return is<HTMLInputElement>(node) && downcast<HTMLInputElement>(*node).isImageButton();
1270 }
1271
1272 // Returns true if the node's editable block is not current focused for editing
1273 static bool nodeIsNotBeingEdited(const Node& node, const Frame& frame)
1274 {
1275     return frame.selection().selection().rootEditableElement() != node.rootEditableElement();
1276 }
1277
1278 bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
1279 {
1280     if (!node)
1281         return false;
1282
1283     bool editable = node->hasEditableStyle();
1284     bool editableLinkEnabled = false;
1285
1286     // If the link is editable, then we need to check the settings to see whether or not the link should be followed
1287     if (editable) {
1288         switch (m_frame.settings().editableLinkBehavior()) {
1289         default:
1290         case EditableLinkDefaultBehavior:
1291         case EditableLinkAlwaysLive:
1292             editableLinkEnabled = true;
1293             break;
1294
1295         case EditableLinkNeverLive:
1296             editableLinkEnabled = false;
1297             break;
1298
1299         case EditableLinkLiveWhenNotFocused:
1300             editableLinkEnabled = nodeIsNotBeingEdited(*node, m_frame) || shiftKey;
1301             break;
1302
1303         case EditableLinkOnlyLiveWithShiftKey:
1304             editableLinkEnabled = shiftKey;
1305             break;
1306         }
1307     }
1308
1309     return ((isOverLink || isSubmitImage(node)) && (!editable || editableLinkEnabled));
1310 }
1311
1312 void EventHandler::cursorUpdateTimerFired()
1313 {
1314     ASSERT(m_frame.document());
1315     updateCursor();
1316 }
1317
1318 void EventHandler::updateCursor()
1319 {
1320     if (m_mousePositionIsUnknown)
1321         return;
1322
1323     FrameView* view = m_frame.view();
1324     if (!view)
1325         return;
1326
1327     RenderView* renderView = view->renderView();
1328     if (!renderView)
1329         return;
1330
1331     if (!view->shouldSetCursor())
1332         return;
1333
1334     bool shiftKey;
1335     bool ctrlKey;
1336     bool altKey;
1337     bool metaKey;
1338     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
1339
1340     HitTestRequest request(HitTestRequest::ReadOnly);
1341     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
1342     renderView->hitTest(request, result);
1343
1344     OptionalCursor optionalCursor = selectCursor(result, shiftKey);
1345     if (optionalCursor.isCursorChange()) {
1346         m_currentMouseCursor = optionalCursor.cursor();
1347         view->setCursor(m_currentMouseCursor);
1348     }
1349 }
1350
1351 OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shiftKey)
1352 {
1353     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1354         return NoCursorChange;
1355
1356     if (!m_frame.page())
1357         return NoCursorChange;
1358
1359 #if ENABLE(PAN_SCROLLING)
1360     if (m_frame.mainFrame().eventHandler().panScrollInProgress())
1361         return NoCursorChange;
1362 #endif
1363
1364     Node* node = result.targetNode();
1365     if (!node)
1366         return NoCursorChange;
1367
1368     auto renderer = node->renderer();
1369     RenderStyle* style = renderer ? &renderer->style() : nullptr;
1370     bool horizontalText = !style || style->isHorizontalWritingMode();
1371     const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
1372
1373 #if ENABLE(CURSOR_VISIBILITY)
1374     if (style && style->cursorVisibility() == CursorVisibilityAutoHide)
1375         startAutoHideCursorTimer();
1376     else
1377         cancelAutoHideCursorTimer();
1378 #endif
1379
1380     if (renderer) {
1381         Cursor overrideCursor;
1382         switch (renderer->getCursor(roundedIntPoint(result.localPoint()), overrideCursor)) {
1383         case SetCursorBasedOnStyle:
1384             break;
1385         case SetCursor:
1386             return overrideCursor;
1387         case DoNotSetCursor:
1388             return NoCursorChange;
1389         }
1390     }
1391
1392     if (style && style->cursors()) {
1393         const CursorList* cursors = style->cursors();
1394         for (unsigned i = 0; i < cursors->size(); ++i) {
1395             StyleImage* styleImage = (*cursors)[i].image();
1396             if (!styleImage)
1397                 continue;
1398             CachedImage* cachedImage = styleImage->cachedImage();
1399             if (!cachedImage)
1400                 continue;
1401             float scale = styleImage->imageScaleFactor();
1402             // Get hotspot and convert from logical pixels to physical pixels.
1403             IntPoint hotSpot = (*cursors)[i].hotSpot();
1404             hotSpot.scale(scale, scale);
1405             FloatSize size = cachedImage->imageForRenderer(renderer)->size();
1406             if (cachedImage->errorOccurred())
1407                 continue;
1408             // Limit the size of cursors (in UI pixels) so that they cannot be
1409             // used to cover UI elements in chrome.
1410             size.scale(1 / scale);
1411             if (size.width() > maximumCursorSize || size.height() > maximumCursorSize)
1412                 continue;
1413
1414             Image* image = cachedImage->imageForRenderer(renderer);
1415 #if ENABLE(MOUSE_CURSOR_SCALE)
1416             // Ensure no overflow possible in calculations above.
1417             if (scale < minimumCursorScale)
1418                 continue;
1419             return Cursor(image, hotSpot, scale);
1420 #else
1421             ASSERT(scale == 1);
1422             return Cursor(image, hotSpot);
1423 #endif // ENABLE(MOUSE_CURSOR_SCALE)
1424         }
1425     }
1426
1427     // During selection, use an I-beam regardless of the content beneath the cursor.
1428     // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
1429     if (m_mousePressed
1430         && m_mouseDownMayStartSelect
1431 #if ENABLE(DRAG_SUPPORT)
1432         && !m_mouseDownMayStartDrag
1433 #endif
1434         && m_frame.selection().isCaretOrRange()
1435         && !m_capturingMouseEventsElement)
1436         return iBeam;
1437
1438     switch (style ? style->cursor() : CursorAuto) {
1439     case CursorAuto: {
1440         bool editable = node->hasEditableStyle();
1441
1442         if (useHandCursor(node, result.isOverLink(), shiftKey))
1443             return handCursor();
1444
1445         bool inResizer = false;
1446         if (renderer) {
1447             if (RenderLayer* layer = renderer->enclosingLayer()) {
1448                 if (FrameView* view = m_frame.view())
1449                     inResizer = layer->isPointInResizeControl(view->windowToContents(roundedIntPoint(result.localPoint())));
1450             }
1451         }
1452
1453         if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !result.scrollbar())
1454             return iBeam;
1455         return pointerCursor();
1456     }
1457     case CursorCross:
1458         return crossCursor();
1459     case CursorPointer:
1460         return handCursor();
1461     case CursorMove:
1462         return moveCursor();
1463     case CursorAllScroll:
1464         return moveCursor();
1465     case CursorEResize:
1466         return eastResizeCursor();
1467     case CursorWResize:
1468         return westResizeCursor();
1469     case CursorNResize:
1470         return northResizeCursor();
1471     case CursorSResize:
1472         return southResizeCursor();
1473     case CursorNeResize:
1474         return northEastResizeCursor();
1475     case CursorSwResize:
1476         return southWestResizeCursor();
1477     case CursorNwResize:
1478         return northWestResizeCursor();
1479     case CursorSeResize:
1480         return southEastResizeCursor();
1481     case CursorNsResize:
1482         return northSouthResizeCursor();
1483     case CursorEwResize:
1484         return eastWestResizeCursor();
1485     case CursorNeswResize:
1486         return northEastSouthWestResizeCursor();
1487     case CursorNwseResize:
1488         return northWestSouthEastResizeCursor();
1489     case CursorColResize:
1490         return columnResizeCursor();
1491     case CursorRowResize:
1492         return rowResizeCursor();
1493     case CursorText:
1494         return iBeamCursor();
1495     case CursorWait:
1496         return waitCursor();
1497     case CursorHelp:
1498         return helpCursor();
1499     case CursorVerticalText:
1500         return verticalTextCursor();
1501     case CursorCell:
1502         return cellCursor();
1503     case CursorContextMenu:
1504         return contextMenuCursor();
1505     case CursorProgress:
1506         return progressCursor();
1507     case CursorNoDrop:
1508         return noDropCursor();
1509     case CursorAlias:
1510         return aliasCursor();
1511     case CursorCopy:
1512         return copyCursor();
1513     case CursorNone:
1514         return noneCursor();
1515     case CursorNotAllowed:
1516         return notAllowedCursor();
1517     case CursorDefault:
1518         return pointerCursor();
1519     case CursorZoomIn:
1520         return zoomInCursor();
1521     case CursorZoomOut:
1522         return zoomOutCursor();
1523     case CursorWebkitGrab:
1524         return grabCursor();
1525     case CursorWebkitGrabbing:
1526         return grabbingCursor();
1527     }
1528     return pointerCursor();
1529 }
1530 #endif // ENABLE(CURSOR_SUPPORT)
1531
1532 #if ENABLE(CURSOR_VISIBILITY)
1533 void EventHandler::startAutoHideCursorTimer()
1534 {
1535     Page* page = m_frame.page();
1536     if (!page)
1537         return;
1538
1539     m_autoHideCursorTimer.startOneShot(page->settings().timeWithoutMouseMovementBeforeHidingControls());
1540
1541 #if !ENABLE(IOS_TOUCH_EVENTS)
1542     // The fake mouse move event screws up the auto-hide feature (by resetting the auto-hide timer)
1543     // so cancel any pending fake mouse moves.
1544     if (m_fakeMouseMoveEventTimer.isActive())
1545         m_fakeMouseMoveEventTimer.stop();
1546 #endif
1547 }
1548
1549 void EventHandler::cancelAutoHideCursorTimer()
1550 {
1551     if (m_autoHideCursorTimer.isActive())
1552         m_autoHideCursorTimer.stop();
1553 }
1554
1555 void EventHandler::autoHideCursorTimerFired()
1556 {
1557     m_currentMouseCursor = noneCursor();
1558     FrameView* view = m_frame.view();
1559     if (view && view->isActive())
1560         view->setCursor(m_currentMouseCursor);
1561 }
1562 #endif
1563     
1564 void EventHandler::beginTrackingPotentialLongMousePress(const HitTestResult& hitTestResult)
1565 {
1566     clearLongMousePressState();
1567
1568     Page* page = m_frame.page();
1569     if (!(page && page->settings().longMousePressEnabled()))
1570         return;
1571
1572     m_longMousePressTimer.startOneShot(longMousePressRecognitionDelay);
1573
1574     page->chrome().didBeginTrackingPotentialLongMousePress(m_mouseDownPos, hitTestResult);
1575 }
1576     
1577 void EventHandler::recognizeLongMousePress()
1578 {
1579     Page* page = m_frame.page();
1580     if (!page)
1581         return;
1582
1583     m_didRecognizeLongMousePress = true;
1584
1585     // Clear mouse state to avoid initiating a drag.
1586     m_mousePressed = false;
1587     invalidateClick();
1588
1589     page->chrome().didRecognizeLongMousePress();
1590 }
1591     
1592 void EventHandler::cancelTrackingPotentialLongMousePress()
1593 {
1594     if (!m_longMousePressTimer.isActive())
1595         return;
1596
1597     clearLongMousePressState();
1598
1599     Page* page = m_frame.page();
1600     if (!page)
1601         return;
1602
1603     page->chrome().didCancelTrackingPotentialLongMousePress();
1604 }
1605
1606 void EventHandler::clearLongMousePressState()
1607 {
1608     m_longMousePressTimer.stop();
1609     m_didRecognizeLongMousePress = false;
1610 }
1611     
1612 bool EventHandler::handleLongMousePressMouseMovedEvent(const PlatformMouseEvent& mouseEvent)
1613 {
1614     if (mouseEvent.button() != LeftButton || mouseEvent.type() != PlatformEvent::MouseMoved)
1615         return false;
1616
1617     if (m_didRecognizeLongMousePress)
1618         return true;
1619
1620     if (!mouseMovementExceedsThreshold(mouseEvent.position(), maximumLongMousePressDragDistance))
1621         cancelTrackingPotentialLongMousePress();
1622
1623     return false;
1624 }
1625
1626 static LayoutPoint documentPointForWindowPoint(Frame& frame, const IntPoint& windowPoint)
1627 {
1628     FrameView* view = frame.view();
1629     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
1630     // Historically the code would just crash; this is clearly no worse than that.
1631     return view ? view->windowToContents(windowPoint) : windowPoint;
1632 }
1633
1634 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& platformMouseEvent)
1635 {
1636     RefPtr<FrameView> protector(m_frame.view());
1637
1638     if (InspectorInstrumentation::handleMousePress(m_frame)) {
1639         invalidateClick();
1640         return true;
1641     }
1642
1643     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
1644         return true;
1645
1646 #if ENABLE(TOUCH_EVENTS)
1647     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
1648     if (defaultPrevented)
1649         return true;
1650 #endif
1651
1652     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
1653
1654     // FIXME (bug 68185): this call should be made at another abstraction layer
1655     m_frame.loader().resetMultipleFormSubmissionProtection();
1656
1657 #if !ENABLE(IOS_TOUCH_EVENTS)
1658     cancelFakeMouseMoveEvent();
1659 #endif
1660     m_mousePressed = true;
1661     m_capturesDragging = true;
1662     setLastKnownMousePosition(platformMouseEvent);
1663     m_mouseDownTimestamp = platformMouseEvent.timestamp();
1664 #if ENABLE(DRAG_SUPPORT)
1665     m_mouseDownMayStartDrag = false;
1666 #endif
1667     m_mouseDownMayStartSelect = false;
1668     m_mouseDownMayStartAutoscroll = false;
1669     if (FrameView* view = m_frame.view())
1670         m_mouseDownPos = view->windowToContents(platformMouseEvent.position());
1671     else {
1672         invalidateClick();
1673         return false;
1674     }
1675     m_mouseDownWasInSubframe = false;
1676
1677     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
1678     // Save the document point we generate in case the window coordinate is invalidated by what happens
1679     // when we dispatch the event.
1680     LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, platformMouseEvent.position());
1681     MouseEventWithHitTestResults mouseEvent = m_frame.document()->prepareMouseEvent(request, documentPoint, platformMouseEvent);
1682
1683     if (!mouseEvent.targetNode()) {
1684         invalidateClick();
1685         return false;
1686     }
1687
1688     m_mousePressNode = mouseEvent.targetNode();
1689
1690     RefPtr<Frame> subframe = subframeForHitTestResult(mouseEvent);
1691     if (subframe && passMousePressEventToSubframe(mouseEvent, subframe.get())) {
1692         // Start capturing future events for this frame.  We only do this if we didn't clear
1693         // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
1694         m_capturesDragging = subframe->eventHandler().capturesDragging();
1695         if (m_mousePressed && m_capturesDragging) {
1696             m_capturingMouseEventsElement = subframe->ownerElement();
1697             m_eventHandlerWillResetCapturingMouseEventsElement = true;
1698         }
1699         invalidateClick();
1700         return true;
1701     }
1702
1703 #if ENABLE(PAN_SCROLLING)
1704     // We store whether pan scrolling is in progress before calling stopAutoscrollTimer()
1705     // because it will set m_autoscrollType to NoAutoscroll on return.
1706     bool isPanScrollInProgress = m_frame.mainFrame().eventHandler().panScrollInProgress();
1707     stopAutoscrollTimer();
1708     if (isPanScrollInProgress) {
1709         // We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate
1710         // away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>.
1711         invalidateClick();
1712         return true;
1713     }
1714 #endif
1715
1716     m_clickCount = platformMouseEvent.clickCount();
1717     m_clickNode = mouseEvent.targetNode();
1718
1719     if (!m_clickNode) {
1720         invalidateClick();
1721         return false;
1722     }
1723
1724     if (FrameView* view = m_frame.view()) {
1725         RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;
1726         IntPoint p = view->windowToContents(platformMouseEvent.position());
1727         if (layer && layer->isPointInResizeControl(p)) {
1728             layer->setInResizeMode(true);
1729             m_resizeLayer = layer;
1730             m_offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
1731             invalidateClick();
1732             return true;
1733         }
1734     }
1735
1736     m_frame.selection().setCaretBlinkingSuspended(true);
1737
1738     bool swallowEvent = !dispatchMouseEvent(eventNames().mousedownEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
1739     m_capturesDragging = !swallowEvent || mouseEvent.scrollbar();
1740
1741     // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
1742     // in case the scrollbar widget was destroyed when the mouse event was handled.
1743     if (mouseEvent.scrollbar()) {
1744         const bool wasLastScrollBar = mouseEvent.scrollbar() == m_lastScrollbarUnderMouse.get();
1745         mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
1746         if (wasLastScrollBar && mouseEvent.scrollbar() != m_lastScrollbarUnderMouse.get())
1747             m_lastScrollbarUnderMouse = nullptr;
1748     }
1749
1750     if (swallowEvent) {
1751         // scrollbars should get events anyway, even disabled controls might be scrollable
1752         Scrollbar* scrollbar = mouseEvent.scrollbar();
1753
1754         updateLastScrollbarUnderMouse(scrollbar, true);
1755
1756         if (scrollbar)
1757             passMousePressEventToScrollbar(mouseEvent, scrollbar);
1758     } else {
1759         // Refetch the event target node if it currently is the shadow node inside an <input> element.
1760         // If a mouse event handler changes the input element type to one that has a widget associated,
1761         // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
1762         // event target node can't still be the shadow node.
1763         if (is<ShadowRoot>(*mouseEvent.targetNode()) && is<HTMLInputElement>(*downcast<ShadowRoot>(*mouseEvent.targetNode()).hostElement()))
1764             mouseEvent = m_frame.document()->prepareMouseEvent(HitTestRequest(), documentPoint, platformMouseEvent);
1765
1766         FrameView* view = m_frame.view();
1767         Scrollbar* scrollbar = view ? view->scrollbarAtPoint(platformMouseEvent.position()) : 0;
1768         if (!scrollbar)
1769             scrollbar = mouseEvent.scrollbar();
1770
1771         updateLastScrollbarUnderMouse(scrollbar, true);
1772
1773         if (scrollbar && passMousePressEventToScrollbar(mouseEvent, scrollbar))
1774             swallowEvent = true;
1775         else
1776             swallowEvent = handleMousePressEvent(mouseEvent);
1777     }
1778
1779     return swallowEvent;
1780 }
1781
1782 // This method only exists for platforms that don't know how to deliver 
1783 bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& platformMouseEvent)
1784 {
1785     RefPtr<FrameView> protector(m_frame.view());
1786
1787     m_frame.selection().setCaretBlinkingSuspended(false);
1788
1789     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
1790
1791     // We get this instead of a second mouse-up 
1792     m_mousePressed = false;
1793     setLastKnownMousePosition(platformMouseEvent);
1794
1795     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
1796     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
1797     Frame* subframe = subframeForHitTestResult(mouseEvent);
1798     if (m_eventHandlerWillResetCapturingMouseEventsElement)
1799         m_capturingMouseEventsElement = nullptr;
1800     if (subframe && passMousePressEventToSubframe(mouseEvent, subframe))
1801         return true;
1802
1803     m_clickCount = platformMouseEvent.clickCount();
1804     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
1805
1806     bool swallowClickEvent = platformMouseEvent.button() != RightButton && mouseEvent.targetNode() == m_clickNode && !dispatchMouseEvent(eventNames().clickEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
1807
1808     if (m_lastScrollbarUnderMouse)
1809         swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
1810
1811     bool swallowMouseReleaseEvent = !swallowMouseUpEvent && handleMouseReleaseEvent(mouseEvent);
1812
1813     invalidateClick();
1814
1815     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1816 }
1817
1818 static RenderLayer* layerForNode(Node* node)
1819 {
1820     if (!node)
1821         return 0;
1822
1823     auto renderer = node->renderer();
1824     if (!renderer)
1825         return 0;
1826
1827     RenderLayer* layer = renderer->enclosingLayer();
1828     if (!layer)
1829         return 0;
1830
1831     return layer;
1832 }
1833
1834 bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
1835 {
1836     RefPtr<FrameView> protector(m_frame.view());
1837     MaximumDurationTracker maxDurationTracker(&m_maxMouseMovedDuration);
1838
1839     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(event))
1840         return true;
1841
1842     HitTestResult hoveredNode = HitTestResult(LayoutPoint());
1843     bool result = handleMouseMoveEvent(event, &hoveredNode);
1844
1845     Page* page = m_frame.page();
1846     if (!page)
1847         return result;
1848
1849     if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
1850         if (FrameView* frameView = m_frame.view()) {
1851             if (frameView->containsScrollableArea(layer))
1852                 layer->mouseMovedInContentArea();
1853         }
1854     }
1855
1856     if (FrameView* frameView = m_frame.view())
1857         frameView->mouseMovedInContentArea();  
1858
1859     hoveredNode.setToNonShadowAncestor();
1860     page->chrome().mouseDidMoveOverElement(hoveredNode, event.modifierFlags());
1861     page->chrome().setToolTip(hoveredNode);
1862     return result;
1863 }
1864
1865 bool EventHandler::passMouseMovedEventToScrollbars(const PlatformMouseEvent& event)
1866 {
1867     HitTestResult hoveredNode;
1868     return handleMouseMoveEvent(event, &hoveredNode, true);
1869 }
1870
1871 bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& platformMouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
1872 {
1873 #if ENABLE(TOUCH_EVENTS)
1874     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
1875     if (defaultPrevented)
1876         return true;
1877 #endif
1878
1879     if (handleLongMousePressMouseMovedEvent(platformMouseEvent))
1880         return true;
1881
1882     RefPtr<FrameView> protector(m_frame.view());
1883     
1884     setLastKnownMousePosition(platformMouseEvent);
1885
1886     if (m_hoverTimer.isActive())
1887         m_hoverTimer.stop();
1888
1889 #if ENABLE(CURSOR_SUPPORT)
1890     m_cursorUpdateTimer.stop();
1891 #endif
1892
1893 #if !ENABLE(IOS_TOUCH_EVENTS)
1894     cancelFakeMouseMoveEvent();
1895 #endif
1896
1897     if (m_svgPan) {
1898         downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
1899         return true;
1900     }
1901
1902     if (m_frameSetBeingResized)
1903         return !dispatchMouseEvent(eventNames().mousemoveEvent, m_frameSetBeingResized.get(), false, 0, platformMouseEvent, false);
1904
1905     // On iOS, our scrollbars are managed by UIKit.
1906 #if !PLATFORM(IOS)
1907     // Send events right to a scrollbar if the mouse is pressed.
1908     if (m_lastScrollbarUnderMouse && m_mousePressed)
1909         return m_lastScrollbarUnderMouse->mouseMoved(platformMouseEvent);
1910 #endif
1911
1912     HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::DisallowShadowContent | HitTestRequest::AllowFrameScrollbars;
1913     if (m_mousePressed)
1914         hitType |= HitTestRequest::Active;
1915     else if (onlyUpdateScrollbars) {
1916         // Mouse events should be treated as "read-only" if we're updating only scrollbars. This  
1917         // means that :hover and :active freeze in the state they were in, rather than updating  
1918         // for nodes the mouse moves while the window is not key (which will be the case if 
1919         // onlyUpdateScrollbars is true). 
1920         hitType |= HitTestRequest::ReadOnly;
1921     }
1922
1923 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
1924     // Treat any mouse move events as readonly if the user is currently touching the screen.
1925     if (m_touchPressed)
1926         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
1927 #endif
1928     HitTestRequest request(hitType);
1929     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
1930     if (hoveredNode)
1931         *hoveredNode = mouseEvent.hitTestResult();
1932
1933     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1934         m_resizeLayer->resize(platformMouseEvent, m_offsetFromResizeCorner);
1935     else {
1936         Scrollbar* scrollbar = mouseEvent.scrollbar();
1937         updateLastScrollbarUnderMouse(scrollbar, !m_mousePressed);
1938
1939         // On iOS, our scrollbars are managed by UIKit.
1940 #if !PLATFORM(IOS)
1941         if (!m_mousePressed && scrollbar)
1942             scrollbar->mouseMoved(platformMouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
1943 #endif
1944         if (onlyUpdateScrollbars)
1945             return true;
1946     }
1947
1948     bool swallowEvent = false;
1949     RefPtr<Frame> newSubframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
1950  
1951     // 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.
1952     if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(&m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
1953         passMouseMoveEventToSubframe(mouseEvent, m_lastMouseMoveEventSubframe.get());
1954
1955     if (newSubframe) {
1956         // Update over/out state before passing the event to the subframe.
1957         updateMouseEventTargetNode(mouseEvent.targetNode(), platformMouseEvent, true);
1958         
1959         // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
1960         // node to be detached from its FrameView, in which case the event should not be passed.
1961         if (newSubframe->view())
1962             swallowEvent |= passMouseMoveEventToSubframe(mouseEvent, newSubframe.get(), hoveredNode);
1963 #if ENABLE(CURSOR_SUPPORT)
1964     } else {
1965         if (FrameView* view = m_frame.view()) {
1966             OptionalCursor optionalCursor = selectCursor(mouseEvent.hitTestResult(), platformMouseEvent.shiftKey());
1967             if (optionalCursor.isCursorChange()) {
1968                 m_currentMouseCursor = optionalCursor.cursor();
1969                 view->setCursor(m_currentMouseCursor);
1970             }
1971         }
1972 #endif
1973     }
1974     
1975     m_lastMouseMoveEventSubframe = newSubframe;
1976
1977     if (swallowEvent)
1978         return true;
1979     
1980     swallowEvent = !dispatchMouseEvent(eventNames().mousemoveEvent, mouseEvent.targetNode(), false, 0, platformMouseEvent, true);
1981 #if ENABLE(DRAG_SUPPORT)
1982     if (!swallowEvent)
1983         swallowEvent = handleMouseDraggedEvent(mouseEvent);
1984 #endif // ENABLE(DRAG_SUPPORT)
1985
1986     return swallowEvent;
1987 }
1988
1989 void EventHandler::invalidateClick()
1990 {
1991     m_clickCount = 0;
1992     m_clickNode = nullptr;
1993 }
1994
1995 inline static bool mouseIsReleasedOnPressedElement(Node* targetNode, Node* clickNode)
1996 {
1997     if (targetNode == clickNode)
1998         return true;
1999
2000     if (!targetNode)
2001         return false;
2002
2003     ShadowRoot* containingShadowRoot = targetNode->containingShadowRoot();
2004     if (!containingShadowRoot)
2005         return false;
2006
2007     // FIXME: When an element in UA ShadowDOM (e.g. inner element in <input>) is clicked,
2008     // we assume that the host element is clicked. This is necessary for implementing <input type="range"> etc.
2009     // However, we should not check ShadowRoot type basically.
2010     // https://bugs.webkit.org/show_bug.cgi?id=108047
2011     if (containingShadowRoot->type() != ShadowRoot::UserAgentShadowRoot)
2012         return false;
2013
2014     Node* adjustedTargetNode = targetNode->shadowHost();
2015     Node* adjustedClickNode = clickNode ? clickNode->shadowHost() : 0;
2016     return adjustedTargetNode == adjustedClickNode;
2017 }
2018
2019 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& platformMouseEvent)
2020 {
2021     RefPtr<FrameView> protector(m_frame.view());
2022
2023     m_frame.selection().setCaretBlinkingSuspended(false);
2024
2025     if (m_frame.mainFrame().pageOverlayController().handleMouseEvent(platformMouseEvent))
2026         return true;
2027
2028 #if ENABLE(TOUCH_EVENTS)
2029     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(platformMouseEvent);
2030     if (defaultPrevented)
2031         return true;
2032 #endif
2033
2034     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
2035
2036 #if ENABLE(PAN_SCROLLING)
2037     m_autoscrollController->handleMouseReleaseEvent(platformMouseEvent);
2038 #endif
2039
2040     m_mousePressed = false;
2041     setLastKnownMousePosition(platformMouseEvent);
2042
2043     if (m_svgPan) {
2044         m_svgPan = false;
2045         downcast<SVGDocument>(*m_frame.document()).updatePan(m_frame.view()->windowToContents(m_lastKnownMousePosition));
2046         return true;
2047     }
2048
2049     if (m_frameSetBeingResized)
2050         return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, platformMouseEvent, false);
2051
2052     if (m_lastScrollbarUnderMouse) {
2053         invalidateClick();
2054         m_lastScrollbarUnderMouse->mouseUp(platformMouseEvent);
2055         bool cancelable = true;
2056         bool setUnder = false;
2057         return !dispatchMouseEvent(eventNames().mouseupEvent, m_lastElementUnderMouse.get(), cancelable, m_clickCount, platformMouseEvent, setUnder);
2058     }
2059
2060     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowShadowContent);
2061     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
2062     Frame* subframe = m_capturingMouseEventsElement.get() ? subframeForTargetNode(m_capturingMouseEventsElement.get()) : subframeForHitTestResult(mouseEvent);
2063     if (m_eventHandlerWillResetCapturingMouseEventsElement)
2064         m_capturingMouseEventsElement = nullptr;
2065     if (subframe && passMouseReleaseEventToSubframe(mouseEvent, subframe))
2066         return true;
2067
2068     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, false);
2069
2070     bool contextMenuEvent = platformMouseEvent.button() == RightButton;
2071
2072     bool swallowClickEvent = m_clickCount > 0 && !contextMenuEvent && mouseIsReleasedOnPressedElement(mouseEvent.targetNode(), m_clickNode.get()) && !dispatchMouseEvent(eventNames().clickEvent, mouseEvent.targetNode(), true, m_clickCount, platformMouseEvent, true);
2073
2074     if (m_resizeLayer) {
2075         m_resizeLayer->setInResizeMode(false);
2076         m_resizeLayer = nullptr;
2077     }
2078
2079     bool swallowMouseReleaseEvent = false;
2080     if (!swallowMouseUpEvent)
2081         swallowMouseReleaseEvent = handleMouseReleaseEvent(mouseEvent);
2082
2083     invalidateClick();
2084
2085     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
2086 }
2087
2088 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& platformMouseEvent)
2089 {
2090     // If the event was a middle click, attempt to copy global selection in after
2091     // the newly set caret position.
2092     //
2093     // This code is called from either the mouse up or mouse down handling. There
2094     // is some debate about when the global selection is pasted:
2095     //   xterm: pastes on up.
2096     //   GTK: pastes on down.
2097     //   Qt: pastes on up.
2098     //   Firefox: pastes on up.
2099     //   Chromium: pastes on up.
2100     //
2101     // There is something of a webcompat angle to this well, as highlighted by
2102     // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
2103     // down then the text is pasted just before the onclick handler runs and
2104     // clears the text box. So it's important this happens after the event
2105     // handlers have been fired.
2106 #if PLATFORM(GTK)
2107     if (platformMouseEvent.type() != PlatformEvent::MousePressed)
2108         return false;
2109 #else
2110     if (platformMouseEvent.type() != PlatformEvent::MouseReleased)
2111         return false;
2112 #endif
2113
2114     if (!m_frame.page())
2115         return false;
2116     Frame& focusFrame = m_frame.page()->focusController().focusedOrMainFrame();
2117     // Do not paste here if the focus was moved somewhere else.
2118     if (&m_frame == &focusFrame && m_frame.editor().client()->supportsGlobalSelection())
2119         return m_frame.editor().command(ASCIILiteral("PasteGlobalSelection")).execute();
2120
2121     return false;
2122 }
2123
2124 #if ENABLE(DRAG_SUPPORT)
2125
2126 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Element& dragTarget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2127 {
2128     FrameView* view = m_frame.view();
2129
2130     // FIXME: We might want to dispatch a dragleave even if the view is gone.
2131     if (!view)
2132         return false;
2133
2134     view->disableLayerFlushThrottlingTemporarilyForInteraction();
2135     RefPtr<MouseEvent> me = MouseEvent::create(eventType,
2136         true, true, event.timestamp(), m_frame.document()->defaultView(),
2137         0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
2138 #if ENABLE(POINTER_LOCK)
2139         event.movementDelta().x(), event.movementDelta().y(),
2140 #endif
2141         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
2142         0, 0, dataTransfer);
2143
2144     dragTarget.dispatchEvent(me.get(), IGNORE_EXCEPTION);
2145     return me->defaultPrevented();
2146 }
2147
2148 static bool targetIsFrame(Node* target, Frame*& frame)
2149 {
2150     if (!is<HTMLFrameElementBase>(target))
2151         return false;
2152
2153     frame = downcast<HTMLFrameElementBase>(*target).contentFrame();
2154     return true;
2155 }
2156
2157 static DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
2158 {
2159     if (dragOperation == "copy")
2160         return DragOperationCopy;
2161     if (dragOperation == "move")
2162         return DragOperationMove;
2163     if (dragOperation == "link")
2164         return DragOperationLink;
2165     return DragOperationNone;
2166 }
2167
2168 static String convertDragOperationToDropZoneOperation(DragOperation operation)
2169 {
2170     switch (operation) {
2171     case DragOperationCopy:
2172         return ASCIILiteral("copy");
2173     case DragOperationMove:
2174         return ASCIILiteral("move");
2175     case DragOperationLink:
2176         return ASCIILiteral("link");
2177     default:
2178         return ASCIILiteral("copy");
2179     }
2180 }
2181
2182 static bool hasDropZoneType(DataTransfer& dataTransfer, const String& keyword)
2183 {
2184     if (keyword.startsWith("file:"))
2185         return dataTransfer.hasFileOfType(keyword.substring(5));
2186
2187     if (keyword.startsWith("string:"))
2188         return dataTransfer.hasStringOfType(keyword.substring(7));
2189
2190     return false;
2191 }
2192
2193 static bool findDropZone(Node* target, DataTransfer* dataTransfer)
2194 {
2195     ASSERT(target);
2196     Element* element = is<Element>(*target) ? downcast<Element>(target) : target->parentElement();
2197     for (; element; element = element->parentElement()) {
2198         bool matched = false;
2199         String dropZoneStr = element->fastGetAttribute(webkitdropzoneAttr);
2200
2201         if (dropZoneStr.isEmpty())
2202             continue;
2203         
2204         dropZoneStr = dropZoneStr.lower();
2205         
2206         SpaceSplitString keywords(dropZoneStr, false);
2207         if (keywords.isEmpty())
2208             continue;
2209         
2210         DragOperation dragOperation = DragOperationNone;
2211         for (unsigned int i = 0; i < keywords.size(); i++) {
2212             DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
2213             if (op != DragOperationNone) {
2214                 if (dragOperation == DragOperationNone)
2215                     dragOperation = op;
2216             } else
2217                 matched = matched || hasDropZoneType(*dataTransfer, keywords[i].string());
2218
2219             if (matched && dragOperation != DragOperationNone)
2220                 break;
2221         }
2222         if (matched) {
2223             dataTransfer->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
2224             return true;
2225         }
2226     }
2227     return false;
2228 }
2229     
2230 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2231 {
2232     bool accept = false;
2233
2234     if (!m_frame.view())
2235         return false;
2236
2237     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
2238     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, event);
2239
2240     RefPtr<Element> newTarget;
2241     if (Node* targetNode = mouseEvent.targetNode()) {
2242         // Drag events should never go to non-element nodes (following IE, and proper mouseover/out dispatch)
2243         if (!is<Element>(*targetNode))
2244             newTarget = targetNode->parentOrShadowHostElement();
2245         else
2246             newTarget = downcast<Element>(targetNode);
2247     }
2248
2249     m_autoscrollController->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
2250
2251     if (m_dragTarget != newTarget) {
2252         // FIXME: this ordering was explicitly chosen to match WinIE. However,
2253         // it is sometimes incorrect when dragging within subframes, as seen with
2254         // LayoutTests/fast/events/drag-in-frames.html.
2255         //
2256         // 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>.
2257         Frame* targetFrame;
2258         if (targetIsFrame(newTarget.get(), targetFrame)) {
2259             if (targetFrame)
2260                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
2261         } else if (newTarget) {
2262             // 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.
2263             if (dragState().source && dragState().shouldDispatchEvents) {
2264                 // for now we don't care if event handler cancels default behavior, since there is none
2265                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2266             }
2267             accept = dispatchDragEvent(eventNames().dragenterEvent, *newTarget, event, dataTransfer);
2268             if (!accept)
2269                 accept = findDropZone(newTarget.get(), dataTransfer);
2270         }
2271
2272         if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2273             if (targetFrame)
2274                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
2275         } else if (m_dragTarget)
2276             dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer);
2277
2278         if (newTarget) {
2279             // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
2280             // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function.
2281             m_shouldOnlyFireDragOverEvent = true;
2282         }
2283     } else {
2284         Frame* targetFrame;
2285         if (targetIsFrame(newTarget.get(), targetFrame)) {
2286             if (targetFrame)
2287                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
2288         } else if (newTarget) {
2289             // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
2290             if (!m_shouldOnlyFireDragOverEvent && dragState().source && dragState().shouldDispatchEvents) {
2291                 // for now we don't care if event handler cancels default behavior, since there is none
2292                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2293             }
2294             accept = dispatchDragEvent(eventNames().dragoverEvent, *newTarget, event, dataTransfer);
2295             if (!accept)
2296                 accept = findDropZone(newTarget.get(), dataTransfer);
2297             m_shouldOnlyFireDragOverEvent = false;
2298         }
2299     }
2300     m_dragTarget = newTarget.release();
2301     return accept;
2302 }
2303
2304 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2305 {
2306     Frame* targetFrame;
2307     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2308         if (targetFrame)
2309             targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer);
2310     } else if (m_dragTarget) {
2311         if (dragState().source && dragState().shouldDispatchEvents)
2312             dispatchDragSrcEvent(eventNames().dragEvent, event);
2313         dispatchDragEvent(eventNames().dragleaveEvent, *m_dragTarget, event, dataTransfer);
2314     }
2315     clearDragState();
2316 }
2317
2318 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
2319 {
2320     Frame* targetFrame;
2321     bool preventedDefault = false;
2322     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2323         if (targetFrame)
2324             preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, dataTransfer);
2325     } else if (m_dragTarget)
2326         preventedDefault = dispatchDragEvent(eventNames().dropEvent, *m_dragTarget, event, dataTransfer);
2327     clearDragState();
2328     return preventedDefault;
2329 }
2330
2331 void EventHandler::clearDragState()
2332 {
2333     stopAutoscrollTimer();
2334     m_dragTarget = nullptr;
2335     m_capturingMouseEventsElement = nullptr;
2336     m_shouldOnlyFireDragOverEvent = false;
2337 #if PLATFORM(COCOA)
2338     m_sendingEventToSubview = false;
2339 #endif
2340 }
2341 #endif // ENABLE(DRAG_SUPPORT)
2342
2343 void EventHandler::setCapturingMouseEventsElement(PassRefPtr<Element> element)
2344 {
2345     m_capturingMouseEventsElement = element;
2346     m_eventHandlerWillResetCapturingMouseEventsElement = false;
2347 }
2348
2349 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mouseEvent)
2350 {
2351     ASSERT(m_frame.document());
2352     return m_frame.document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mouseEvent.position()), mouseEvent);
2353 }
2354
2355 static RenderElement* nearestCommonHoverAncestor(RenderElement* obj1, RenderElement* obj2)
2356 {
2357     if (!obj1 || !obj2)
2358         return nullptr;
2359
2360     for (RenderElement* currObj1 = obj1; currObj1; currObj1 = currObj1->hoverAncestor()) {
2361         for (RenderElement* currObj2 = obj2; currObj2; currObj2 = currObj2->hoverAncestor()) {
2362             if (currObj1 == currObj2)
2363                 return currObj1;
2364         }
2365     }
2366
2367     return nullptr;
2368 }
2369
2370 static bool hierarchyHasCapturingEventListeners(Element* element, const AtomicString& eventName)
2371 {
2372     for (ContainerNode* curr = element; curr; curr = curr->parentOrShadowHostNode()) {
2373         if (curr->hasCapturingEventListeners(eventName))
2374             return true;
2375     }
2376     return false;
2377 }
2378
2379 void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& platformMouseEvent, bool fireMouseOverOut)
2380 {
2381     Element* targetElement = nullptr;
2382     
2383     // If we're capturing, we always go right to that element.
2384     if (m_capturingMouseEventsElement)
2385         targetElement = m_capturingMouseEventsElement.get();
2386     else if (targetNode) {
2387         // If the target node is a non-element, dispatch on the parent. <rdar://problem/4196646>
2388         if (!is<Element>(*targetNode))
2389             targetElement = targetNode->parentOrShadowHostElement();
2390         else
2391             targetElement = downcast<Element>(targetNode);
2392     }
2393
2394     m_elementUnderMouse = targetElement;
2395
2396     // Fire mouseout/mouseover if the mouse has shifted to a different node.
2397     if (fireMouseOverOut) {
2398         RenderLayer* layerForLastNode = layerForNode(m_lastElementUnderMouse.get());
2399         RenderLayer* layerForNodeUnderMouse = layerForNode(m_elementUnderMouse.get());
2400         Page* page = m_frame.page();
2401
2402         if (m_lastElementUnderMouse && (!m_elementUnderMouse || &m_elementUnderMouse->document() != m_frame.document())) {
2403             // The mouse has moved between frames.
2404             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
2405                 if (FrameView* frameView = frame->view())
2406                     frameView->mouseExitedContentArea();
2407             }
2408         } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
2409             // The mouse has moved between layers.
2410             if (Frame* frame = m_lastElementUnderMouse->document().frame()) {
2411                 if (FrameView* frameView = frame->view()) {
2412                     if (frameView->containsScrollableArea(layerForLastNode))
2413                         layerForLastNode->mouseExitedContentArea();
2414                 }
2415             }
2416         }
2417
2418         if (m_elementUnderMouse && (!m_lastElementUnderMouse || &m_lastElementUnderMouse->document() != m_frame.document())) {
2419             // The mouse has moved between frames.
2420             if (Frame* frame = m_elementUnderMouse->document().frame()) {
2421                 if (FrameView* frameView = frame->view())
2422                     frameView->mouseEnteredContentArea();
2423             }
2424         } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
2425             // The mouse has moved between layers.
2426             if (Frame* frame = m_elementUnderMouse->document().frame()) {
2427                 if (FrameView* frameView = frame->view()) {
2428                     if (frameView->containsScrollableArea(layerForNodeUnderMouse))
2429                         layerForNodeUnderMouse->mouseEnteredContentArea();
2430                 }
2431             }
2432         }
2433
2434         if (m_lastElementUnderMouse && &m_lastElementUnderMouse->document() != m_frame.document()) {
2435             m_lastElementUnderMouse = nullptr;
2436             m_lastScrollbarUnderMouse = nullptr;
2437         }
2438
2439         if (m_lastElementUnderMouse != m_elementUnderMouse) {
2440             // mouseenter and mouseleave events are only dispatched if there is a capturing eventhandler on an ancestor
2441             // or a normal eventhandler on the element itself (they don't bubble).
2442             // This optimization is necessary since these events can cause O(n^2) capturing event-handler checks.
2443             bool hasCapturingMouseEnterListener = hierarchyHasCapturingEventListeners(m_elementUnderMouse.get(), eventNames().mouseenterEvent);
2444             bool hasCapturingMouseLeaveListener = hierarchyHasCapturingEventListeners(m_lastElementUnderMouse.get(), eventNames().mouseleaveEvent);
2445
2446             RenderElement* oldHoverRenderer = m_lastElementUnderMouse ? m_lastElementUnderMouse->renderer() : nullptr;
2447             RenderElement* newHoverRenderer = m_elementUnderMouse ? m_elementUnderMouse->renderer() : nullptr;
2448             RenderElement* ancestor = nearestCommonHoverAncestor(oldHoverRenderer, newHoverRenderer);
2449
2450             Vector<Ref<Element>, 32> leftElementsChain;
2451             if (oldHoverRenderer) {
2452                 for (RenderElement* curr = oldHoverRenderer; curr && curr != ancestor; curr = curr->hoverAncestor()) {
2453                     if (Element* element = curr->element())
2454                         leftElementsChain.append(*element);
2455                 }
2456             } else {
2457                 // If the old hovered element is not null but it's renderer is, it was probably detached.
2458                 // In this case, the old hovered element (and its ancestors) must be updated, to ensure it's normal style is re-applied.
2459                 for (Element* element = m_lastElementUnderMouse.get(); element; element = element->parentElement())
2460                     leftElementsChain.append(*element);
2461             }
2462
2463             Vector<Ref<Element>, 32> enteredElementsChain;
2464             const Element* ancestorElement = ancestor ? ancestor->element() : nullptr;
2465             for (RenderElement* curr = newHoverRenderer; curr; curr = curr->hoverAncestor()) {
2466                 if (Element *element = curr->element()) {
2467                     if (element == ancestorElement)
2468                         break;
2469                     enteredElementsChain.append(*element);
2470                 }
2471             }
2472
2473             // Send mouseout event to the old node.
2474             if (m_lastElementUnderMouse)
2475                 m_lastElementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoutEvent, 0, m_elementUnderMouse.get());
2476
2477             // Send mouseleave to the node hierarchy no longer under the mouse.
2478             for (size_t i = 0; i < leftElementsChain.size(); ++i) {
2479                 if (hasCapturingMouseLeaveListener || leftElementsChain[i]->hasEventListeners(eventNames().mouseleaveEvent))
2480                     leftElementsChain[i]->dispatchMouseEvent(platformMouseEvent, eventNames().mouseleaveEvent, 0, m_elementUnderMouse.get());
2481             }
2482
2483             // Send mouseover event to the new node.
2484             if (m_elementUnderMouse)
2485                 m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventNames().mouseoverEvent, 0, m_lastElementUnderMouse.get());
2486
2487             // Send mouseleave event to the nodes hierarchy under the mouse.
2488             for (size_t i = 0, size = enteredElementsChain.size(); i < size; ++i) {
2489                 if (hasCapturingMouseEnterListener || enteredElementsChain[i]->hasEventListeners(eventNames().mouseenterEvent))
2490                     enteredElementsChain[i]->dispatchMouseEvent(platformMouseEvent, eventNames().mouseenterEvent, 0, m_lastElementUnderMouse.get());
2491             }
2492         }
2493         m_lastElementUnderMouse = m_elementUnderMouse;
2494     }
2495 }
2496
2497 bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& platformMouseEvent, bool setUnder)
2498 {
2499     if (FrameView* view = m_frame.view())
2500         view->disableLayerFlushThrottlingTemporarilyForInteraction();
2501
2502     updateMouseEventTargetNode(targetNode, platformMouseEvent, setUnder);
2503
2504     bool swallowEvent = false;
2505
2506     if (m_elementUnderMouse)
2507         swallowEvent = !(m_elementUnderMouse->dispatchMouseEvent(platformMouseEvent, eventType, clickCount));
2508
2509     if (!swallowEvent && eventType == eventNames().mousedownEvent) {
2510
2511         // If clicking on a frame scrollbar, do not mess up with content focus.
2512         if (FrameView* view = m_frame.view()) {
2513             if (view->scrollbarAtPoint(platformMouseEvent.position()))
2514                 return true;
2515         }
2516
2517         // The layout needs to be up to date to determine if an element is focusable.
2518         m_frame.document()->updateLayoutIgnorePendingStylesheets();
2519
2520         // Blur current focus node when a link/button is clicked; this
2521         // is expected by some sites that rely on onChange handlers running
2522         // from form fields before the button click is processed.
2523
2524         Element* element = m_elementUnderMouse.get();
2525
2526         // Walk up the DOM tree to search for an element to focus.
2527         while (element) {
2528             if (element->isMouseFocusable()) {
2529                 // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus a
2530                 // node on mouse down if it's selected and inside a focused node. It will be
2531                 // focused if the user does a mouseup over it, however, because the mouseup
2532                 // will set a selection inside it, which will call setFocuseNodeIfNeeded.
2533                 if (m_frame.selection().isRange()
2534                     && m_frame.selection().toNormalizedRange()->compareNode(element, IGNORE_EXCEPTION) == Range::NODE_INSIDE
2535                     && element->isDescendantOf(m_frame.document()->focusedElement()))
2536                     return true;
2537                     
2538                 break;
2539             }
2540             element = element->parentOrShadowHostElement();
2541         }
2542
2543         // Only change the focus when clicking scrollbars if it can transfered to a mouse focusable node.
2544         if ((!element || !element->isMouseFocusable()) && isInsideScrollbar(platformMouseEvent.position()))
2545             return false;
2546
2547         // If focus shift is blocked, we eat the event.  Note we should never clear swallowEvent
2548         // if the page already set it (e.g., by canceling default behavior).
2549         if (Page* page = m_frame.page()) {
2550             if (element && element->isMouseFocusable()) {
2551                 if (!page->focusController().setFocusedElement(element, &m_frame))
2552                     swallowEvent = true;
2553             } else if (!element || !element->focused()) {
2554                 if (!page->focusController().setFocusedElement(0, &m_frame))
2555                     swallowEvent = true;
2556             }
2557         }
2558     }
2559
2560     return !swallowEvent;
2561 }
2562
2563 bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
2564 {
2565     if (RenderView* renderView = m_frame.contentRenderer()) {
2566         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
2567         HitTestResult result(windowPoint);
2568         renderView->hitTest(request, result);
2569         return result.scrollbar();
2570     }
2571
2572     return false;
2573 }
2574
2575 #if !PLATFORM(GTK)
2576
2577 bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const
2578 {
2579     return false;
2580 }
2581
2582 #endif
2583
2584 #if !PLATFORM(MAC)
2585
2586 void EventHandler::platformPrepareForWheelEvents(const PlatformWheelEvent&, const HitTestResult&, RefPtr<Element>&, RefPtr<ContainerNode>&, ScrollableArea*&, bool&)
2587 {
2588 }
2589
2590 void EventHandler::platformRecordWheelEvent(const PlatformWheelEvent& event)
2591 {
2592     m_frame.mainFrame().wheelEventDeltaTracker()->recordWheelEventDelta(event);
2593 }
2594
2595 bool EventHandler::platformCompleteWheelEvent(const PlatformWheelEvent& event, Element*, ContainerNode*, ScrollableArea*)
2596 {
2597     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
2598     FrameView* view = m_frame.view();
2599     
2600     bool didHandleEvent = view ? view->wheelEvent(event) : false;
2601     m_isHandlingWheelEvent = false;
2602     return didHandleEvent;
2603 }
2604
2605 bool EventHandler::platformCompletePlatformWidgetWheelEvent(const PlatformWheelEvent&, const Widget&, ContainerNode*)
2606 {
2607     return true;
2608 }
2609
2610 #if ENABLE(CSS_SCROLL_SNAP)
2611 void EventHandler::platformNotifySnapIfNecessary(const PlatformWheelEvent&, ScrollableArea&)
2612 {
2613 }
2614 #endif
2615
2616 #endif
2617
2618 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
2619 {
2620     RenderView* renderView = m_frame.contentRenderer();
2621     if (!renderView)
2622         return false;
2623
2624     RefPtr<FrameView> protector(m_frame.view());
2625
2626     FrameView* view = m_frame.view();
2627     if (!view)
2628         return false;
2629
2630     m_isHandlingWheelEvent = true;
2631     setFrameWasScrolledByUser();
2632
2633     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
2634     HitTestResult result(view->windowToContents(event.position()));
2635     renderView->hitTest(request, result);
2636
2637     RefPtr<Element> element = result.innerElement();
2638     RefPtr<ContainerNode> scrollableContainer;
2639     ScrollableArea* scrollableArea = nullptr;
2640     bool isOverWidget = result.isOverWidget();
2641     platformPrepareForWheelEvents(event, result, element, scrollableContainer, scrollableArea, isOverWidget);
2642
2643 #if PLATFORM(MAC)
2644     if (event.phase() == PlatformWheelEventPhaseNone && event.momentumPhase() == PlatformWheelEventPhaseNone)
2645         m_frame.mainFrame().resetLatchingState();
2646 #endif
2647
2648     // FIXME: It should not be necessary to do this mutation here.
2649     // Instead, the handlers should know convert vertical scrolls appropriately.
2650     PlatformWheelEvent adjustedEvent = event;
2651     if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, event))
2652         adjustedEvent = event.copyTurningVerticalTicksIntoHorizontalTicks();
2653
2654     platformRecordWheelEvent(adjustedEvent);
2655
2656     if (element) {
2657         if (isOverWidget) {
2658             RenderElement* target = element->renderer();
2659             if (is<RenderWidget>(target)) {
2660                 Widget* widget = downcast<RenderWidget>(*target).widget();
2661                 if (widget && passWheelEventToWidget(event, *widget)) {
2662                     m_isHandlingWheelEvent = false;
2663                     if (scrollableArea)
2664                         scrollableArea->setScrolledProgrammatically(false);
2665                     if (!widget->platformWidget())
2666                         return true;
2667                     return platformCompletePlatformWidgetWheelEvent(event, *widget, scrollableContainer.get());
2668                 }
2669             }
2670         }
2671
2672         if (!element->dispatchWheelEvent(adjustedEvent)) {
2673             m_isHandlingWheelEvent = false;
2674             if (scrollableArea && scrollableArea->isScrolledProgrammatically()) {
2675                 // Web developer is controlling scrolling, so don't attempt to latch.
2676                 clearLatchedState();
2677                 scrollableArea->setScrolledProgrammatically(false);
2678             }
2679
2680 #if ENABLE(CSS_SCROLL_SNAP)
2681             if (scrollableArea)
2682                 platformNotifySnapIfNecessary(adjustedEvent, *scrollableArea);
2683 #endif
2684             return true;
2685         }
2686     }
2687
2688     if (scrollableArea)
2689         scrollableArea->setScrolledProgrammatically(false);
2690
2691     return platformCompleteWheelEvent(event, element.get(), scrollableContainer.get(), scrollableArea);
2692 }
2693
2694 void EventHandler::clearLatchedState()
2695 {
2696 #if PLATFORM(MAC)
2697     m_frame.mainFrame().resetLatchingState();
2698 #endif
2699     m_frame.mainFrame().wheelEventDeltaTracker()->endTrackingDeltas();
2700 }
2701
2702 void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
2703 {
2704     if (!startNode || !wheelEvent)
2705         return;
2706     
2707     DominantScrollGestureDirection dominantDirection = DominantScrollGestureDirection::None;
2708
2709 #if PLATFORM(MAC)
2710     ScrollLatchingState* latchedState = m_frame.mainFrame().latchingState();
2711     Element* stopElement = latchedState ? latchedState->previousWheelScrolledElement() : nullptr;
2712
2713     // Workaround for scrolling issues <rdar://problem/14758615>.
2714     if (m_frame.mainFrame().wheelEventDeltaTracker()->isTrackingDeltas())
2715         dominantDirection = m_frame.mainFrame().wheelEventDeltaTracker()->dominantScrollGestureDirection();
2716 #else
2717     Element* stopElement = nullptr;
2718 #endif
2719     
2720     // Break up into two scrolls if we need to.  Diagonal movement on 
2721     // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
2722     if (dominantDirection != DominantScrollGestureDirection::Vertical && handleWheelEventInAppropriateEnclosingBoxForSingleAxis(startNode, wheelEvent, &stopElement, ScrollEventAxis::Horizontal))
2723         wheelEvent->setDefaultHandled();
2724     
2725     if (dominantDirection != DominantScrollGestureDirection::Horizontal && handleWheelEventInAppropriateEnclosingBoxForSingleAxis(startNode, wheelEvent, &stopElement, ScrollEventAxis::Vertical))
2726         wheelEvent->setDefaultHandled();
2727     
2728 #if PLATFORM(MAC)
2729     if (latchedState && !latchedState->wheelEventElement())
2730         latchedState->setPreviousWheelScrolledElement(stopElement);
2731 #endif
2732 }
2733
2734 #if ENABLE(CONTEXT_MENUS)
2735 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2736 {
2737     Document* doc = m_frame.document();
2738     FrameView* v = m_frame.view();
2739     if (!v)
2740         return false;
2741     
2742     // Clear mouse press state to avoid initiating a drag while context menu is up.
2743     m_mousePressed = false;
2744     bool swallowEvent;
2745     LayoutPoint viewportPos = v->windowToContents(event.position());
2746     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
2747     MouseEventWithHitTestResults mouseEvent = doc->prepareMouseEvent(request, viewportPos, event);
2748
2749     if (m_frame.editor().behavior().shouldSelectOnContextualMenuClick()
2750         && !m_frame.selection().contains(viewportPos)
2751         && !mouseEvent.scrollbar()
2752         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
2753         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
2754         // available for text selections.  But only if we're above text.
2755         && (m_frame.selection().selection().isContentEditable() || (mouseEvent.targetNode() && mouseEvent.targetNode()->isTextNode()))) {
2756         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
2757         selectClosestWordOrLinkFromMouseEvent(mouseEvent);
2758     }
2759
2760     swallowEvent = !dispatchMouseEvent(eventNames().contextmenuEvent, mouseEvent.targetNode(), true, 0, event, false);
2761     
2762     return swallowEvent;
2763 }
2764
2765 bool EventHandler::sendContextMenuEventForKey()
2766 {
2767     FrameView* view = m_frame.view();
2768     if (!view)
2769         return false;
2770
2771     Document* doc = m_frame.document();
2772     if (!doc)
2773         return false;
2774
2775     // Clear mouse press state to avoid initiating a drag while context menu is up.
2776     m_mousePressed = false;
2777
2778     static const int kContextMenuMargin = 1;
2779
2780 #if OS(WINDOWS)
2781     int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
2782 #else
2783     int rightAligned = 0;
2784 #endif
2785     IntPoint location;
2786
2787     Element* focusedElement = doc->focusedElement();
2788     const VisibleSelection& selection = m_frame.selection().selection();
2789     Position start = selection.start();
2790
2791     if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
2792         RefPtr<Range> selectionRange = selection.toNormalizedRange();
2793         IntRect firstRect = m_frame.editor().firstRectForRange(selectionRange.get());
2794
2795         int x = rightAligned ? firstRect.maxX() : firstRect.x();
2796         // In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
2797         int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
2798         location = IntPoint(x, y);
2799     } else if (focusedElement) {
2800         RenderBoxModelObject* box = focusedElement->renderBoxModelObject();
2801         if (!box)
2802             return false;
2803         IntRect clippedRect = box->pixelSnappedAbsoluteClippedOverflowRect();
2804         location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1);
2805     } else {
2806         location = IntPoint(
2807             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
2808             kContextMenuMargin);
2809     }
2810
2811     m_frame.view()->setCursor(pointerCursor());
2812
2813     IntPoint position = view->contentsToRootView(location);
2814     IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
2815
2816     Node* targetNode = doc->focusedElement();
2817     if (!targetNode)
2818         targetNode = doc;
2819
2820     // Use the focused node as the target for hover and active.
2821     HitTestResult result(position);
2822     result.setInnerNode(targetNode);
2823     doc->updateHoverActiveState(HitTestRequest::Active | HitTestRequest::DisallowShadowContent, result.innerElement());
2824
2825     // The contextmenu event is a mouse event even when invoked using the keyboard.
2826     // This is required for web compatibility.
2827
2828 #if OS(WINDOWS)
2829     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2830 #else
2831     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2832 #endif
2833
2834     PlatformMouseEvent platformMouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
2835
2836     return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, platformMouseEvent, false);
2837 }
2838 #endif // ENABLE(CONTEXT_MENUS)
2839
2840 void EventHandler::scheduleHoverStateUpdate()
2841 {
2842     if (!m_hoverTimer.isActive())
2843         m_hoverTimer.startOneShot(0);
2844 }
2845
2846 #if ENABLE(CURSOR_SUPPORT)
2847 void EventHandler::scheduleCursorUpdate()
2848 {
2849     if (!m_cursorUpdateTimer.isActive())
2850         m_cursorUpdateTimer.startOneShot(cursorUpdateInterval);
2851 }
2852 #endif
2853
2854 void EventHandler::dispatchFakeMouseMoveEventSoon()
2855 {
2856 #if !ENABLE(IOS_TOUCH_EVENTS)
2857     if (m_mousePressed)
2858         return;
2859
2860     if (m_mousePositionIsUnknown)
2861         return;
2862
2863     if (Page* page = m_frame.page()) {
2864         if (!page->chrome().client().shouldDispatchFakeMouseMoveEvents())
2865             return;
2866     }
2867
2868     // If the content has ever taken longer than fakeMouseMoveShortInterval we
2869     // reschedule the timer and use a longer time. This will cause the content
2870     // to receive these moves only after the user is done scrolling, reducing
2871     // pauses during the scroll.
2872     if (m_maxMouseMovedDuration > fakeMouseMoveDurationThreshold) {
2873         if (m_fakeMouseMoveEventTimer.isActive())
2874             m_fakeMouseMoveEventTimer.stop();
2875         m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval);
2876     } else {
2877         if (!m_fakeMouseMoveEventTimer.isActive())
2878             m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval);
2879     }
2880 #endif
2881 }
2882
2883 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
2884 {
2885 #if ENABLE(IOS_TOUCH_EVENTS)
2886     UNUSED_PARAM(quad);
2887 #else
2888     FrameView* view = m_frame.view();
2889     if (!view)
2890         return;
2891
2892     if (!quad.containsPoint(view->windowToContents(m_lastKnownMousePosition)))
2893         return;
2894
2895     dispatchFakeMouseMoveEventSoon();
2896 #endif
2897 }
2898
2899 #if !ENABLE(IOS_TOUCH_EVENTS)
2900 void EventHandler::cancelFakeMouseMoveEvent()
2901 {
2902     m_fakeMouseMoveEventTimer.stop();
2903 }
2904
2905 void EventHandler::fakeMouseMoveEventTimerFired()
2906 {
2907     ASSERT(!m_mousePressed);
2908
2909     FrameView* view = m_frame.view();
2910     if (!view)
2911         return;
2912
2913     if (!m_frame.page() || !m_frame.page()->isVisible() || !m_frame.page()->focusController().isActive())
2914         return;
2915
2916     bool shiftKey;
2917     bool ctrlKey;
2918     bool altKey;
2919     bool metaKey;
2920     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
2921     PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
2922     mouseMoved(fakeMouseMoveEvent);
2923 }
2924 #endif // !ENABLE(IOS_TOUCH_EVENTS)
2925
2926 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
2927 {
2928     m_frameSetBeingResized = frameSet;
2929 }
2930
2931 void EventHandler::resizeLayerDestroyed()
2932 {
2933     ASSERT(m_resizeLayer);
2934     m_resizeLayer = 0;
2935 }
2936
2937 void EventHandler::hoverTimerFired()
2938 {
2939     m_hoverTimer.stop();
2940
2941     ASSERT(m_frame.document());
2942
2943     if (RenderView* renderView = m_frame.contentRenderer()) {
2944         if (FrameView* view = m_frame.view()) {
2945             HitTestRequest request(HitTestRequest::Move | HitTestRequest::DisallowShadowContent);
2946             HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
2947             renderView->hitTest(request, result);
2948             m_frame.document()->updateHoverActiveState(request, result.innerElement());
2949         }
2950     }
2951 }
2952
2953 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
2954 {
2955     // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
2956     // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
2957     // lower case variants are present in a document, the correct element is matched based on Shift key state.
2958     // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
2959     ASSERT(!(accessKeyModifiers() & PlatformEvent::ShiftKey));
2960     if ((evt.modifiers() & ~PlatformEvent::ShiftKey) != accessKeyModifiers())
2961         return false;
2962     String key = evt.unmodifiedText();
2963     Element* elem = m_frame.document()->getElementByAccessKey(key.lower());
2964     if (!elem)
2965         return false;
2966     elem->accessKeyAction(false);
2967     return true;
2968 }
2969
2970 #if !PLATFORM(MAC)
2971 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
2972 {
2973     return false;
2974 }
2975 #endif
2976
2977 #if ENABLE(FULLSCREEN_API)
2978 bool EventHandler::isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent& keyEvent) const
2979 {
2980     Document* document = m_frame.document();
2981     if (document->webkitFullScreenKeyboardInputAllowed())
2982         return true;
2983
2984     if (keyEvent.type() == PlatformKeyboardEvent::Char) {
2985         if (keyEvent.text().length() != 1)
2986             return false;
2987         UChar character = keyEvent.text()[0];
2988         return character == ' ';
2989     }
2990
2991     int keyCode = keyEvent.windowsVirtualKeyCode();
2992     return (keyCode >= VK_BACK && keyCode <= VK_CAPITAL)
2993         || (keyCode >= VK_SPACE && keyCode <= VK_DELETE)
2994         || (keyCode >= VK_OEM_1 && keyCode <= VK_OEM_PLUS)
2995         || (keyCode >= VK_MULTIPLY && keyCode <= VK_OEM_8);
2996 }
2997 #endif
2998
2999 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
3000 {
3001     RefPtr<FrameView> protector(m_frame.view());
3002
3003 #if ENABLE(FULLSCREEN_API)
3004     if (m_frame.document()->webkitIsFullScreen() && !isKeyEventAllowedInFullScreen(initialKeyEvent))
3005         return false;
3006 #endif
3007
3008     if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL)
3009         capsLockStateMayHaveChanged();
3010
3011 #if ENABLE(PAN_SCROLLING)
3012     if (m_frame.mainFrame().eventHandler().panScrollInProgress()) {
3013         // If a key is pressed while the panScroll is in progress then we want to stop
3014         if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown)
3015             stopAutoscrollTimer();
3016
3017         // If we were in panscroll mode, we swallow the key event
3018         return true;
3019     }
3020 #endif
3021
3022     // Check for cases where we are too early for events -- possible unmatched key up
3023     // from pressing return in the location bar.
3024     RefPtr<Element> element = eventTargetElementForDocument(m_frame.document());
3025     if (!element)
3026         return false;
3027
3028     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
3029     UserTypingGestureIndicator typingGestureIndicator(m_frame);
3030
3031     if (FrameView* view = m_frame.view())
3032         view->disableLayerFlushThrottlingTemporarilyForInteraction();
3033
3034     // FIXME (bug 68185): this call should be made at another abstraction layer
3035     m_frame.loader().resetMultipleFormSubmissionProtection();
3036
3037     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
3038     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
3039     // with access keys. Then we dispatch keydown, but suppress its default handling.
3040     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
3041     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
3042     bool matchedAnAccessKey = false;
3043     if (initialKeyEvent.type() == PlatformEvent::KeyDown)
3044         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
3045
3046     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
3047     if (initialKeyEvent.type() == PlatformEvent::KeyUp || initialKeyEvent.type() == PlatformEvent::Char)
3048         return !element->dispatchKeyEvent(initialKeyEvent);
3049
3050     bool backwardCompatibilityMode = needsKeyboardEventDisambiguationQuirks();
3051
3052     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;    
3053     if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
3054         keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown, backwardCompatibilityMode);
3055     RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
3056     if (matchedAnAccessKey)
3057         keydown->setDefaultPrevented(true);
3058     keydown->setTarget(element);
3059
3060     if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
3061         element->dispatchEvent(keydown, IGNORE_EXCEPTION);
3062         // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
3063         bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
3064         return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3065     }
3066
3067     // Run input method in advance of DOM event handling.  This may result in the IM
3068     // modifying the page prior the keydown event, but this behaviour is necessary
3069     // in order to match IE:
3070     // 1. preventing default handling of keydown and keypress events has no effect on IM input;
3071     // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
3072     m_frame.editor().handleInputMethodKeydown(keydown.get());
3073     
3074     bool handledByInputMethod = keydown->defaultHandled();
3075     
3076     if (handledByInputMethod) {
3077         keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
3078         keydown = KeyboardEvent::create(keyDownEvent, m_frame.document()->defaultView());
3079         keydown->setTarget(element);
3080         keydown->setDefaultHandled();
3081     }
3082
3083     element->dispatchEvent(keydown, IGNORE_EXCEPTION);
3084     // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
3085     bool changedFocusedFrame = m_frame.page() && &m_frame != &m_frame.page()->focusController().focusedOrMainFrame();
3086     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3087     if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
3088         return keydownResult;
3089     
3090     // Focus may have changed during keydown handling, so refetch element.
3091     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original element.
3092     if (!keydownResult) {
3093         element = eventTargetElementForDocument(m_frame.document());
3094         if (!element)
3095             return false;
3096     }
3097
3098     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
3099     keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char, backwardCompatibilityMode);
3100     if (keyPressEvent.text().isEmpty())
3101         return keydownResult;
3102     RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame.document()->defaultView());
3103     keypress->setTarget(element);
3104     if (keydownResult)
3105         keypress->setDefaultPrevented(true);
3106 #if PLATFORM(COCOA)
3107     keypress->keypressCommands() = keydown->keypressCommands();
3108 #endif
3109     element->dispatchEvent(keypress, IGNORE_EXCEPTION);
3110
3111     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
3112 }
3113
3114 static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
3115 {
3116     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down", AtomicString::ConstructFromLiteral));
3117     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up", AtomicString::ConstructFromLiteral));
3118     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left", AtomicString::ConstructFromLiteral));
3119     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right", AtomicString::ConstructFromLiteral));
3120
3121     FocusDirection retVal = FocusDirectionNone;
3122
3123     if (keyIdentifier == Down)
3124         retVal = FocusDirectionDown;
3125     else if (keyIdentifier == Up)
3126         retVal = FocusDirectionUp;
3127     else if (keyIdentifier == Left)
3128         retVal = FocusDirectionLeft;
3129     else if (keyIdentifier == Right)
3130         retVal = FocusDirectionRight;
3131
3132     return retVal;
3133 }
3134
3135 static void setInitialKeyboardSelection(Frame& frame, SelectionDirection direction)
3136 {
3137     Document* document = frame.document();
3138     if (!document)
3139         return;
3140
3141     FrameSelection& selection = frame.selection();
3142
3143     if (!selection.isNone())
3144         return;
3145
3146     Element* focusedElement = document->focusedElement();
3147     VisiblePosition visiblePosition;
3148
3149     switch (direction) {
3150     case DirectionBackward:
3151     case DirectionLeft:
3152         if (focusedElement)
3153             visiblePosition = VisiblePosition(positionBeforeNode(focusedElement));
3154         else
3155             visiblePosition = endOfDocument(document);
3156         break;
3157     case DirectionForward:
3158     case DirectionRight:
3159         if (focusedElement)
3160             visiblePosition = VisiblePosition(positionAfterNode(focusedElement));
3161         else
3162             visiblePosition = startOfDocument(document);
3163         break;
3164     }
3165
3166     selection.setSelection(visiblePosition, FrameSelection::defaultSetSelectionOptions(UserTriggered));
3167 }
3168
3169 static void handleKeyboardSelectionMovement(Frame& frame, KeyboardEvent* event)
3170 {
3171     if (!event)
3172         return;
3173
3174     FrameSelection& selection = frame.selection();
3175
3176     bool isCommanded = event->getModifierState("Meta");
3177     bool isOptioned = event->getModifierState("Alt");
3178     bool isSelection = !selection.isNone();
3179
3180     FrameSelection::EAlteration alternation = event->getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
3181     SelectionDirection direction = DirectionForward;
3182     TextGranularity granularity = CharacterGranularity;
3183
3184     switch (focusDirectionForKey(event->keyIdentifier())) {
3185     case FocusDirectionNone:
3186         return;
3187     case FocusDirectionForward:
3188     case FocusDirectionBackward:
3189         ASSERT_NOT_REACHED();
3190         return;
3191     case FocusDirectionUp:
3192         direction = DirectionBackward;
3193         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3194         break;
3195     case FocusDirectionDown:
3196         direction = DirectionForward;
3197         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3198         break;
3199     case FocusDirectionLeft:
3200         direction = DirectionLeft;
3201         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3202         break;
3203     case FocusDirectionRight:
3204         direction = DirectionRight;
3205         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3206         break;
3207     }
3208
3209     if (isSelection)
3210         selection.modify(alternation, direction, granularity, UserTriggered);
3211     else
3212         setInitialKeyboardSelection(frame, direction);
3213
3214     event->setDefaultHandled();
3215 }
3216
3217 void EventHandler::handleKeyboardSelectionMovementForAccessibility(KeyboardEvent* event)
3218 {
3219     if (event->type() == eventNames().keydownEvent) {
3220         if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3221             handleKeyboardSelectionMovement(m_frame, event);
3222     }
3223 }
3224
3225 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
3226 {
3227     if (event->type() == eventNames().keydownEvent) {
3228         m_frame.editor().handleKeyboardEvent(event);
3229         if (event->defaultHandled())
3230             return;
3231         if (event->keyIdentifier() == "U+0009")
3232             defaultTabEventHandler(event);
3233         else if (event->keyIdentifier() == "U+0008")
3234             defaultBackspaceEventHandler(event);
3235         else {
3236             FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
3237             if (direction != FocusDirectionNone)
3238                 defaultArrowEventHandler(direction, event);
3239         }
3240
3241         handleKeyboardSelectionMovementForAccessibility(event);
3242     }
3243     if (event->type() == eventNames().keypressEvent) {
3244         m_frame.editor().handleKeyboardEvent(event);
3245         if (event->defaultHandled())
3246             return;
3247         if (event->charCode() == ' ')
3248             defaultSpaceEventHandler(event);
3249     }
3250 }
3251
3252 #if ENABLE(DRAG_SUPPORT)
3253 bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocation) const
3254 {
3255     FloatPoint dragViewportLocation(floatDragViewportLocation.x(), floatDragViewportLocation.y());
3256     return dragHysteresisExceeded(dragViewportLocation);
3257 }
3258
3259 bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
3260 {
3261     int threshold = GeneralDragHysteresis;
3262     switch (dragState().type) {
3263     case DragSourceActionSelection:
3264         threshold = TextDragHysteresis;
3265         break;
3266     case DragSourceActionImage:
3267         threshold = ImageDragHysteresis;
3268         break;
3269     case DragSourceActionLink:
3270         threshold = LinkDragHysteresis;
3271         break;
3272     case DragSourceActionDHTML:
3273         break;
3274     case DragSourceActionNone:
3275     case DragSourceActionAny:
3276         ASSERT_NOT_REACHED();
3277     }
3278     
3279     return mouseMovementExceedsThreshold(dragViewportLocation, threshold);
3280 }
3281     
3282 void EventHandler::freeDataTransfer()
3283 {
3284     if (!dragState().dataTransfer)
3285         return;
3286     dragState().dataTransfer->setAccessPolicy(DataTransferAccessPolicy::Numb);
3287     dragState().dataTransfer = 0;
3288 }
3289
3290 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
3291 {
3292     // Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses.
3293     HitTestRequest request(HitTestRequest::Release | HitTestRequest::DisallowShadowContent);
3294     prepareMouseEvent(request, event);
3295
3296     if (dragState().source && dragState().shouldDispatchEvents) {
3297         dragState().dataTransfer->setDestinationOperation(operation);
3298         // For now we don't care if event handler cancels default behavior, since there is no default behavior.
3299         dispatchDragSrcEvent(eventNames().dragendEvent, event);
3300     }
3301     freeDataTransfer();
3302     dragState().source = 0;
3303     // In case the drag was ended due to an escape key press we need to ensure
3304     // that consecutive mousemove events don't reinitiate the drag and drop.
3305     m_mouseDownMayStartDrag = false;
3306 }
3307
3308 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement)
3309 {
3310     // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editable element.
3311     if (dragState().source && !dragState().source->inDocument())
3312         dragState().source = rootEditableElement;
3313 }
3314
3315 // Return value indicates if we should continue "default processing", i.e., whether event handler canceled.
3316 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
3317 {
3318     return !dispatchDragEvent(eventType, *dragState().source, event, dragState().dataTransfer.get());
3319 }
3320     
3321 static bool ExactlyOneBitSet(DragSourceAction n)
3322 {
3323     return n && !(n & (n - 1));
3324 }
3325
3326 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDragHysteresis checkDragHysteresis)
3327 {
3328     if (event.event().button() != LeftButton || event.event().type() != PlatformEvent::MouseMoved) {
3329         // If we allowed the other side of the bridge to handle a drag
3330         // last time, then m_mousePressed might still be set. So we
3331         // clear it now to make sure the next move after a drag
3332         // doesn't look like a drag.
3333         m_mousePressed = false;
3334         return false;
3335     }
3336     
3337     if (eventLoopHandleMouseDragged(event))
3338         return true;
3339     
3340     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
3341     
3342     if (m_mouseDownMayStartDrag && !dragState().source) {
3343         dragState().shouldDispatchEvents = (updateDragSourceActionsAllowed() & DragSourceActionDHTML);
3344
3345         // try to find an element that wants to be dragged
3346         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
3347         HitTestResult result(m_mouseDownPos);
3348         m_frame.contentRenderer()->hitTest(request, result);
3349         if (m_frame.page())
3350             dragState().source = m_frame.page()->dragController().draggableElement(&m_frame, result.innerElement(), m_mouseDownPos, dragState());
3351         
3352         if (!dragState().source)
3353             m_mouseDownMayStartDrag = false; // no element is draggable
3354         else
3355             m_dragMayStartSelectionInstead = (dragState().type & DragSourceActionSelection);
3356     }
3357     
3358     // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
3359     // or else we bail on the dragging stuff and allow selection to occur
3360     if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState().type & DragSourceActionSelection) && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
3361         ASSERT(event.event().type() == PlatformEvent::MouseMoved);
3362         if ((dragState().type & DragSourceActionImage)) {
3363             // ... unless the mouse is over an image, then we start dragging just the image
3364             dragState().type = DragSourceActionImage;
3365         } else if (!(dragState().type & (DragSourceActionDHTML | DragSourceActionLink))) {
3366             // ... but only bail if we're not over an unselectable element.
3367             m_mouseDownMayStartDrag = false;
3368             dragState().source = 0;
3369             // ... but if this was the first click in the window, we don't even want to start selection
3370             if (eventActivatedView(event.event()))
3371                 m_mouseDownMayStartSelect = false;
3372         } else {
3373             // Prevent the following case from occuring:
3374             // 1. User starts a drag immediately after mouse down over an unselectable element.
3375             // 2. We enter this block and decided that since we're over an unselectable element, don't cancel the drag.
3376             // 3. The drag gets resolved as a potential selection drag below /but/ we haven't exceeded the drag hysteresis yet.
3377             // 4. We enter this block again, and since it's now marked as a selection drag, we cancel the drag.
3378             m_dragMayStartSelectionInstead = false;
3379         }
3380     }
3381     
3382     if (!m_mouseDownMayStartDrag)
3383         return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
3384     
3385     if (!ExactlyOneBitSet(dragState().type)) {
3386         ASSERT((dragState().type & DragSourceActionSelection));
3387         ASSERT((dragState().type & ~DragSourceActionSelection) == DragSourceActionDHTML
3388             || (dragState().type & ~DragSourceActionSelection) == DragSourceActionImage
3389             || (dragState().type & ~DragSourceActionSelection) == DragSourceActionLink);
3390         dragState().type = DragSourceActionSelection;
3391     }
3392
3393     // We are starting a text/image/url drag, so the cursor should be an arrow
3394     if (FrameView* view = m_frame.view()) {
3395         // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer).
3396         view->setCursor(pointerCursor());
3397     }
3398
3399     if (checkDragHysteresis == ShouldCheckDragHysteresis && !dragHysteresisExceeded(event.event().position()))
3400         return true;
3401     
3402     // Once we're past the hysteresis point, we don't want to treat this gesture as a click
3403     invalidateClick();
3404     
3405     DragOperation srcOp = DragOperationNone;      
3406     
3407     // This does work only if we missed a dragEnd. Do it anyway, just to make sure the old dataTransfer gets numbed.
3408     freeDataTransfer();
3409
3410     dragState().dataTransfer = createDraggingDataTransfer();
3411     
3412     if (dragState().shouldDispatchEvents) {
3413         // Check to see if the is a DOM based drag. If it is, get the DOM specified drag image and offset.
3414         if (dragState().type == DragSourceActionDHTML) {
3415             if (RenderObject* renderer = dragState().source->renderer()) {
3416                 // FIXME: This doesn't work correctly with transforms.
3417                 FloatPoint absPos = renderer->localToAbsolute();
3418                 IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
3419                 dragState().dataTransfer->setDragImage(dragState().source.get(), delta.width(), delta.height());
3420             } else {
3421                 // The renderer has disappeared, this can happen if the onStartDrag handler has hidden
3422                 // the element in some way.  In this case we just kill the drag.
3423                 m_mouseDownMayStartDrag = false;
3424                 goto cleanupDrag;
3425             }
3426         } 
3427         
3428         m_mouseDownMayStartDrag = dispatchDragSrcEvent(eventNames().dragstartEvent, m_mouseDown)
3429             && !m_frame.selection().selection().isInPasswordField();
3430         
3431         // Invalidate dataTransfer here against anymore pasteboard writing for security. The drag
3432         // image can still be changed as we drag, but not the pasteboard data.
3433         dragState().dataTransfer->setAccessPolicy(DataTransferAccessPolicy::ImageWritable);
3434         
3435         if (m_mouseDownMayStartDrag) {
3436             // Gather values from DHTML element, if it set any.
3437             srcOp = dragState().dataTransfer->sourceOperation();
3438             
3439             // Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the
3440             // drag with dragImage! Because of that dumb reentrancy, we may think we've not
3441             // started the drag when that happens. So we have to assume it's started before we kick it off.
3442             dragState().dataTransfer->setDragHasStarted();
3443         }
3444     }
3445     
3446     if (m_mouseDownMayStartDrag) {
3447         Page* page = m_frame.page();
3448         m_didStartDrag = page && page->dragController().startDrag(m_frame, dragState(), srcOp, event.event(), m_mouseDownPos);
3449         // In WebKit2 we could re-enter this code and start another drag.
3450         // On OS X this causes problems with the ownership of the pasteboard and the promised types.
3451         if (m_didStartDrag) {
3452             m_mouseDownMayStartDrag = false;
3453
3454             cancelTrackingPotentialLongMousePress();
3455             return true;
3456         }
3457         if (dragState().source && dragState().shouldDispatchEvents) {
3458             // Drag was canned at the last minute. We owe dragSource a dragend event.
3459             dispatchDragSrcEvent(eventNames().dragendEvent, event.event());
3460             m_mouseDownMayStartDrag = false;
3461         }
3462     } 
3463
3464 cleanupDrag:
3465     if (!m_mouseDownMayStartDrag) {
3466         // Something failed to start the drag, clean up.
3467         freeDataTransfer();
3468         dragState().source = 0;
3469     }
3470     
3471     // No more default handling (like selection), whether we're past the hysteresis bounds or not
3472     return true;
3473 }
3474 #endif // ENABLE(DRAG_SUPPORT)
3475
3476 bool EventHandler::mouseMovementExceedsThreshold(const FloatPoint& viewportLocation, int pointsThreshold) const
3477 {
3478     FrameView* view = m_frame.view();
3479     if (!view)
3480         return false;
3481     IntPoint location = view->windowToContents(flooredIntPoint(viewportLocation));
3482     IntSize delta = location - m_mouseDownPos;
3483     
3484     return abs(delta.width()) >= pointsThreshold || abs(delta.height()) >= pointsThreshold;
3485 }
3486
3487 bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, TextEventInputType inputType)
3488 {
3489     // Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
3490     // and avoid dispatching text input events from keydown default handlers.
3491     ASSERT(!is<KeyboardEvent>(underlyingEvent) || downcast<KeyboardEvent>(*underlyingEvent).type() == eventNames().keypressEvent);
3492
3493     EventTarget* target;
3494     if (underlyingEvent)
3495         target = underlyingEvent->target();
3496     else
3497         target = eventTargetElementForDocument(m_frame.document());
3498     if (!target)
3499         return false;
3500     
3501     if (FrameView* view = m_frame.view())
3502         view->disableLayerFlushThrottlingTemporarilyForInteraction();
3503
3504     RefPtr<TextEvent> event = TextEvent::create(m_frame.document()->domWindow(), text, inputType);
3505     event->setUnderlyingEvent(underlyingEvent);
3506
3507     target->dispatchEvent(event, IGNORE_EXCEPTION);
3508     return event->defaultHandled();
3509 }
3510     
3511 bool EventHandler::isKeyboardOptionTab(KeyboardEvent* event)
3512 {
3513     return event
3514         && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent)
3515         && event->altKey()
3516         && event->keyIdentifier() == "U+0009";    
3517 }
3518
3519 bool EventHandler::eventInvertsTabsToLinksClientCallResult(KeyboardEvent* event)
3520 {
3521 #if PLATFORM(COCOA) || PLATFORM(EFL)
3522     return EventHandler::isKeyboardOptionTab(event);
3523 #else
3524     UNUSED_PARAM(event);
3525     return false;
3526 #endif
3527 }
3528
3529 bool EventHandler::tabsToLinks(KeyboardEvent* event) const
3530 {
3531     // FIXME: This function needs a better name. It can be called for keypresses other than Tab when spatial navigation is enabled.
3532
3533     Page* page = m_frame.page();
3534     if (!page)
3535         return false;
3536
3537     bool tabsToLinksClientCallResult = page->chrome().client().keyboardUIMode() & KeyboardAccessTabsToLinks;
3538     return eventInvertsTabsToLinksClientCallResult(event) ? !tabsToLinksClientCallResult : tabsToLinksClientCallResult;
3539 }
3540
3541 void EventHandler::defaultTextInputEventHandler(TextEvent* event)
3542 {
3543     if (m_frame.editor().handleTextEvent(event))
3544         event->setDefaultHandled();
3545 }
3546
3547
3548 void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
3549 {
3550     ASSERT(event->type() == eventNames().keypressEvent);
3551
3552     if (event->ctrlKey() || event->metaKey() || event->altKey() || event->altGraphKey())
3553         return;
3554
3555     ScrollLogicalDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward;
3556     if (logicalScrollOverflow(direction, ScrollByPage)) {
3557         event->setDefaultHandled();
3558         return;
3559     }
3560
3561     FrameView* view = m_frame.view();
3562     if (!view)
3563         return;
3564
3565     if (view->logicalScroll(direction, ScrollByPage))
3566         event->setDefaultHandled();
3567 }
3568
3569 void EventHandler::defaultBackspaceEventHandler(KeyboardEvent* event)
3570 {
3571     ASSERT(event->type() == eventNames().keydownEvent);
3572
3573     if (event->ctrlKey() || event->metaKey() || event->altKey() || event->altGraphKey())
3574         return;
3575
3576     if (!m_frame.editor().behavior().shouldNavigateBackOnBackspace())
3577         return;
3578     
3579     Page* page = m_frame.page();
3580     if (!page)
3581         return;
3582
3583     if (!m_frame.settings().backspaceKeyNavigationEnabled())
3584         return;
3585     
3586     bool handledEvent = false;
3587
3588     if (event->shiftKey())
3589         handledEvent = page->backForward().goForward();
3590     else
3591         handledEvent = page->backForward().goBack();
3592
3593     if (handledEvent)
3594         event->setDefaultHandled();
3595 }
3596
3597
3598 void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event)
3599 {
3600     ASSERT(event->type() == eventNames().keydownEvent);
3601
3602     if (event->ctrlKey() || event->metaKey() || event->altGraphKey() || event->shiftKey())
3603         return;
3604
3605     Page* page = m_frame.page();
3606     if (!page)
3607         return;
3608
3609     if (!isSpatialNavigationEnabled(&m_frame))
3610         return;
3611
3612     // Arrows and other possible directional navigation keys can be used in design
3613     // mode editing.
3614     if (m_frame.document()->inDesignMode())
3615         return;
3616
3617     if (page->focusController().advanceFocus(focusDirection, event))
3618         event->setDefaultHandled();
3619 }
3620
3621 void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
3622 {
3623     ASSERT(event->type() == eventNames().keydownEvent);
3624
3625     // We should only advance focus on tabs if no special modifier keys are held down.
3626     if (event->ctrlKey() || event->metaKey() || event->altGraphKey())
3627         return;
3628
3629     Page* page = m_frame.page();
3630     if (!page)
3631         return;
3632     if (!page->tabKeyCyclesThroughElements())
3633         return;
3634
3635     FocusDirection focusDirection = event->shiftKey() ? FocusDirectionBackward : FocusDirectionForward;
3636
3637     // Tabs can be used in design mode editing.
3638     if (m_frame.document()->inDesignMode())
3639         return;
3640
3641     if (page->focusController().advanceFocus(focusDirection, event))
3642         event->setDefaultHandled();
3643 }
3644
3645 void EventHandler::capsLockStateMayHaveChanged()
3646 {
3647     Document* document = m_frame.document();
3648     if (auto* element = document->focusedElement()) {
3649         if (is<HTMLInputElement>(*element))
3650             downcast<HTMLInputElement>(*element).capsLockStateMayHaveChanged();
3651     }
3652 }
3653
3654 void EventHandler::sendScrollEvent()
3655 {
3656     setFrameWasScrolledByUser();
3657     if (m_frame.view() && m_frame.document())
3658         m_frame.document()->eventQueue().enqueueOrDispatchScrollEvent(*m_frame.document());
3659 }
3660
3661 void EventHandler::setFrameWasScrolledByUser()
3662 {
3663     FrameView* v = m_frame.view();
3664     if (v)
3665         v->setWasScrolledByUser(true);
3666 }
3667
3668 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mouseEvent, Scrollbar* scrollbar)
3669 {
3670     if (!scrollbar || !scrollbar->enabled())
3671         return false;
3672     setFrameWasScrolledByUser();
3673     return scrollbar->mouseDown(mouseEvent.event());
3674 }
3675
3676 // If scrollbar (under mouse) is different from last, send a mouse exited. Set
3677 // last to scrollbar if setLast is true; else set last to nullptr.
3678 void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setLast)
3679 {
3680     if (m_lastScrollbarUnderMouse.get() != scrollbar) {
3681         // Send mouse exited to the old scrollbar.
3682         if (m_lastScrollbarUnderMouse)
3683             m_lastScrollbarUnderMouse->mouseExited();
3684
3685         // Send mouse entered if we're setting a new scrollbar.
3686         if (scrollbar && setLast)
3687             scrollbar->mouseEntered();
3688
3689         if (setLast && scrollbar)
3690             m_lastScrollbarUnderMouse = scrollbar->createWeakPtr();
3691         else
3692             m_lastScrollbarUnderMouse = nullptr;
3693     }
3694 }
3695
3696 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
3697 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State state)
3698 {
3699     switch (state) {
3700     case PlatformTouchPoint::TouchReleased:
3701         return eventNames().touchendEvent;
3702     case PlatformTouchPoint::TouchCancelled:
3703         return eventNames().touchcancelEvent;
3704     case PlatformTouchPoint::TouchPressed:
3705         return eventNames().touchstartEvent;
3706     case PlatformTouchPoint::TouchMoved:
3707         return eventNames().touchmoveEvent;
3708     case PlatformTouchPoint::TouchStationary:
3709         // TouchStationary state is not converted to touch events, so fall through to assert.
3710     default:
3711         ASSERT_NOT_REACHED();
3712         return emptyAtom;
3713     }
3714 }
3715
3716 static HitTestResult hitTestResultInFrame(Frame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
3717 {
3718     HitTestResult result(point);
3719
3720     if (!frame || !frame->contentRenderer())
3721         return result;
3722
3723     if (frame->view()) {
3724         IntRect rect = frame->view()->visibleContentRect();
3725         if (!rect.contains(roundedIntPoint(point)))
3726             return result;
3727     }
3728     frame->contentRenderer()->hitTest(HitTestRequest(hitType), result);
3729     return result;
3730 }
3731
3732 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
3733 {
3734     // First build up the lists to use for the 'touches', 'targetTouches' and 'changedTouches' attributes
3735     // in the JS event. See http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
3736     // for an overview of how these lists fit together.
3737
3738     // Holds the complete set of touches on the screen and will be used as the 'touches' list in the JS event.
3739     RefPtr<TouchList> touches = TouchList::create();
3740
3741     // A different view on the 'touches' list above, filtered and grouped by event target. Used for the
3742     // 'targetTouches' list in the JS event.
3743     typedef HashMap<EventTarget*, RefPtr<TouchList>> TargetTouchesMap;
3744     TargetTouchesMap touchesByTarget;
3745
3746     // Array of touches per state, used to assemble the 'changedTouches' list in the JS event.
3747     typedef HashSet<RefPtr<EventTarget>> EventTargetSet;
3748     struct {
3749         // The touches corresponding to the particular change state this struct instance represents.
3750         RefPtr<TouchList> m_touches;
3751         // Set of targets involved in m_touches.
3752         EventTargetSet m_targets;
3753     } changedTouches[PlatformTouchPoint::TouchStateEnd];
3754
3755     const Vector<PlatformTouchPoint>& points = event.touchPoints();
3756
3757     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture, m_frame.document());
3758
3759     unsigned i;
3760     bool freshTouchEvents = true;
3761     bool allTouchReleased = true;
3762     for (i = 0; i < points.size(); ++i) {
3763         const PlatformTouchPoint& point = points[i];
3764         if (point.state() != PlatformTouchPoint::TouchPressed)
3765             freshTouchEvents = false;
3766         if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
3767             allTouchReleased = false;
3768     }
3769
3770     for (i = 0; i < points.size(); ++i) {
3771         const PlatformTouchPoint& point = points[i];
3772         PlatformTouchPoint::State pointState = point.state();
3773         LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
3774
3775         HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
3776         // The HitTestRequest types used for mouse events map quite adequately
3777         // to touch events. Note that in addition to meaning that the hit test
3778         // should affect the active state of the current node if necessary,
3779         // HitTestRequest::Active signifies that the hit test is taking place
3780         // with the mouse (or finger in this case) being pressed.
3781         switch (pointState) {
3782         case PlatformTouchPoint::TouchPressed:
3783             hitType |= HitTestRequest::Active;
3784             break;
3785         case PlatformTouchPoint::TouchMoved:
3786             hitType |= HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::ReadOnly;
3787             break;
3788         case PlatformTouchPoint::TouchReleased:
3789         case PlatformTouchPoint::TouchCancelled:
3790             hitType |= HitTestRequest::Release;
3791             break;
3792         case PlatformTouchPoint::TouchStationary:
3793             hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
3794             break;
3795         default:
3796             ASSERT_NOT_REACHED();
3797             break;
3798         }
3799
3800         if (shouldGesturesTriggerActive())
3801             hitType |= HitTestRequest::ReadOnly;
3802
3803         // Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
3804         unsigned touchPointTargetKey = point.id() + 1;
3805         RefPtr<EventTarget> touchTarget;
3806         if (pointState == PlatformTouchPoint::TouchPressed) {
3807             HitTestResult result;
3808             if (freshTouchEvents) {
3809                 result = hitTestResultAtPoint(pagePoint, hitType);
3810                 m_originatingTouchPointTargetKey = touchPointTargetKey;
3811             } else if (m_originatingTouchPointDocument.get() && m_originatingTouchPointDocument->frame()) {
3812                 LayoutPoint pagePointInOriginatingDocument = documentPointForWindowPoint(*m_originatingTouchPointDocument->frame(), point.pos());
3813                 result = hitTestResultInFrame(m_originatingTouchPointDocument->frame(), pagePointInOriginatingDocument, hitType);
3814                 if (!result.innerNode())
3815                     continue;
3816             } else
3817                 continue;
3818
3819             // FIXME: This code should use Element* instead of Node*.
3820             Node* node = result.innerElement();
3821             ASSERT(node);
3822
3823             if (node && InspectorInstrumentation::handleTouchEvent(m_frame, *node))
3824                 return true;
3825
3826             Document& doc = node->document();
3827             // Record the originating touch document even if it does not have a touch listener.
3828             if (freshTouchEvents) {
3829                 m_originatingTouchPointDocument = &doc;
3830                 freshTouchEvents = false;
3831             }
3832             if (!doc.hasTouchEventHandlers())
3833                 continue;
3834             m_originatingTouchPointTargets.set(touchPointTargetKey, node);
3835             touchTarget = node;
3836         } else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
3837             // No need to perform a hit-test since we only need to unset :hover and :active states.
3838             if (!shouldGesturesTriggerActive() && allTouchReleased)
3839                 m_frame.document()->updateHoverActiveState(hitType, 0);
3840             if (touchPointTargetKey == m_originatingTouchPointTargetKey)
3841                 m_originatingTouchPointTargetKey = 0;
3842
3843             // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
3844             // we also remove it from the map.
3845             touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
3846         } else
3847             // No hittest is performed on move or stationary, since the target is not allowed to change anyway.
3848             touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
3849
3850         if (!touchTarget.get())
3851             continue;
3852         Document& doc = touchTarget->toNode()->document();
3853         if (!doc.hasTouchEventHandlers())
3854             continue;
3855         Frame* targetFrame = doc.frame();
3856         if (!targetFrame)
3857             continue;
3858
3859         if (&m_frame != targetFrame) {
3860             // pagePoint should always be relative to the target elements containing frame.
3861             pagePoint = documentPointForWindowPoint(*targetFrame, point.pos());
3862         }
3863
3864         float scaleFactor = targetFrame->pageZoomFactor() * targetFrame->frameScaleFactor();
3865
3866         int adjustedPageX = lroundf(pagePoint.x() / scaleFactor);
3867         int adjustedPageY = lroundf(pagePoint.y() / scaleFactor);
3868
3869         RefPtr<Touch> touch = Touch::create(targetFrame, touchTarget.get(), point.id(),
3870                                             point.screenPos().x(), point.screenPos().y(),
3871                                             adjustedPageX, adjustedPageY,
3872                                             point.radiusX(), point.radiusY(), point.rotationAngle(), point.force());
3873
3874         // Ensure this target's touch list exists, even if it ends up empty, so it can always be passed to TouchEvent::Create below.
3875         TargetTouchesMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
3876         if (targetTouchesIterator == touchesByTarget.end())
3877             targetTouchesIterator = touchesByTarget.set(touchTarget.get(), TouchList::create()).iterator;
3878
3879         // touches and targetTouches should only contain information about touches still on the screen, so if this point is
3880         // released or cancelled it will only appear in the changedTouches list.
3881         if (pointState != PlatformTouchPoint::TouchReleased && pointState != PlatformTouchPoint::TouchCancelled) {
3882             touches->append(touch);
3883             targetTouchesIterator->value->append(touch);
3884         }
3885
3886         // Now build up the correct list for changedTouches.
3887         // Note that  any touches that are in the TouchStationary state (e.g. if
3888         // the user had several points touched but did not move them all) should
3889         // never be in the changedTouches list so we do not handle them explicitly here.
3890         // See https://bugs.webkit.org/show_bug.cgi?id=37609 for further discussion
3891         // about the TouchStationary state.
3892         if (pointState != PlatformTouchPoint::TouchStationary) {
3893             ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
3894             if (!changedTouches[pointState].m_touches)
3895                 changedTouches[pointState].m_touches = TouchList::create();
3896             changedTouches[pointState].m_touches->append(touch);
3897             changedTouches[pointState].m_targets.add(touchTarget);
3898         }
3899     }
3900     m_touchPressed = touches->length() > 0;
3901     if (allTouchReleased)
3902         m_originatingTouchPointDocument.clear();
3903
3904     // Now iterate the changedTouches list and m_targets within it, sending events to the targets as required.
3905     bool swallowedEvent = false;
3906     RefPtr<TouchList> emptyList = TouchList::create();
3907     for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
3908         if (!changedTouches[state].m_touches)
3909             continue;
3910
3911         // When sending a touch cancel event, use empty touches and targetTouches lists.
3912         bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
3913         RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
3914         const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
3915         const EventTargetSet& targetsForState = changedTouches[state].m_targets;
3916
3917         for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
3918             EventTarget* touchEventTarget = it->get();
3919             RefPtr<TouchList> targetTouches(isTouchCancelEvent ? emptyList : touchesByTarget.get(touchEventTarget));
3920             ASSERT(targetTouches);
3921
3922             RefPtr<TouchEvent> touchEvent =
3923                 TouchEvent::create(effectiveTouches.get(), targetTouches.get(), changedTouches[state].m_touches.get(),
3924                     stateName, touchEventTarget->toNode()->document().defaultView(),
3925                     0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey());
3926             touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
3927             swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
3928         }
3929     }
3930
3931     return swallowedEvent;
3932 }
3933 #endif // ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
3934
3935 #if ENABLE(TOUCH_EVENTS)
3936 bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& platformMouseEvent)
3937 {
3938 #if ENABLE(IOS_TOUCH_EVENTS)
3939     UNUSED_PARAM(platformMouseEvent);
3940     return false;
3941 #else
3942     if (!m_frame.settings().isTouchEventEmulationEnabled())
3943         return false;
3944
3945     PlatformEvent::Type eventType = platformMouseEvent.type();
3946     if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
3947         return false;
3948
3949     HitTestRequest request(HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
3950     MouseEventWithHitTestResults mouseEvent = prepareMouseEvent(request, platformMouseEvent);
3951     if (mouseEvent.scrollbar() || subframeForHitTestResult(mouseEvent))
3952         return false;
3953
3954     // The order is important. This check should follow the subframe test: http://webkit.org/b/111292.
3955     if (eventType == PlatformEvent::MouseMoved && !m_touchPressed)
3956         return true;
3957
3958     SyntheticSingleTouchEvent touchEvent(platformMouseEvent);
3959     return handleTouchEvent(touchEvent);
3960 #endif
3961 }
3962 #endif // ENABLE(TOUCH_EVENTS)
3963
3964 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
3965 {
3966     m_mousePositionIsUnknown = false;
3967     m_lastKnownMousePosition = event.position();
3968     m_lastKnownMouseGlobalPosition = event.globalPosition();
3969 }
3970
3971 } // namespace WebCore