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