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