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