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