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