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