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