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