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