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