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