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