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