Don't dispatch fake mousemove events when we don't know where the cursor is
[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_mousePositionIsUnknown(true)
351     , m_mouseDownTimestamp(0)
352     , m_widgetIsLatched(false)
353 #if PLATFORM(MAC)
354     , m_mouseDownView(nil)
355     , m_sendingEventToSubview(false)
356     , m_activationEventNumber(-1)
357 #endif
358 #if ENABLE(TOUCH_EVENTS)
359     , m_originatingTouchPointTargetKey(0)
360     , m_touchPressed(false)
361 #endif
362     , m_maxMouseMovedDuration(0)
363     , m_baseEventType(PlatformEvent::NoType)
364     , m_didStartDrag(false)
365     , m_didLongPressInvokeContextMenu(false)
366 {
367 }
368
369 EventHandler::~EventHandler()
370 {
371     ASSERT(!m_fakeMouseMoveEventTimer.isActive());
372 }
373     
374 #if ENABLE(DRAG_SUPPORT)
375 DragState& EventHandler::dragState()
376 {
377     DEFINE_STATIC_LOCAL(DragState, state, ());
378     return state;
379 }
380 #endif // ENABLE(DRAG_SUPPORT)
381     
382 void EventHandler::clear()
383 {
384     m_hoverTimer.stop();
385     m_fakeMouseMoveEventTimer.stop();
386     m_resizeLayer = 0;
387     m_nodeUnderMouse = 0;
388     m_lastNodeUnderMouse = 0;
389 #if ENABLE(SVG)
390     m_instanceUnderMouse = 0;
391     m_lastInstanceUnderMouse = 0;
392 #endif
393     m_lastMouseMoveEventSubframe = 0;
394     m_lastScrollbarUnderMouse = 0;
395     m_clickCount = 0;
396     m_clickNode = 0;
397     m_frameSetBeingResized = 0;
398 #if ENABLE(DRAG_SUPPORT)
399     m_dragTarget = 0;
400     m_shouldOnlyFireDragOverEvent = false;
401 #endif
402     m_mousePositionIsUnknown = true;
403     m_lastKnownMousePosition = IntPoint();
404     m_lastKnownMouseGlobalPosition = IntPoint();
405     m_mousePressNode = 0;
406     m_mousePressed = false;
407     m_capturesDragging = false;
408     m_capturingMouseEventsNode = 0;
409     m_latchedWheelEventNode = 0;
410     m_previousWheelScrolledNode = 0;
411 #if ENABLE(TOUCH_EVENTS)
412     m_originatingTouchPointTargets.clear();
413     m_originatingTouchPointDocument.clear();
414     m_originatingTouchPointTargetKey = 0;
415 #endif
416 #if ENABLE(GESTURE_EVENTS)
417     m_scrollGestureHandlingNode = 0;
418     m_scrollbarHandlingScrollGesture = 0;
419 #endif
420     m_maxMouseMovedDuration = 0;
421     m_baseEventType = PlatformEvent::NoType;
422     m_didStartDrag = false;
423     m_didLongPressInvokeContextMenu = false;
424 }
425
426 void EventHandler::nodeWillBeRemoved(Node* nodeToBeRemoved)
427 {
428     if (nodeToBeRemoved->contains(m_clickNode.get()))
429         m_clickNode = 0;
430 }
431
432 static void setSelectionIfNeeded(FrameSelection* selection, const VisibleSelection& newSelection)
433 {
434     ASSERT(selection);
435     if (selection->selection() != newSelection && selection->shouldChangeSelection(newSelection))
436         selection->setSelection(newSelection);
437 }
438
439 static inline bool dispatchSelectStart(Node* node)
440 {
441     if (!node || !node->renderer())
442         return true;
443
444     return node->dispatchEvent(Event::create(eventNames().selectstartEvent, true, true));
445 }
446
447 bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& newSelection, TextGranularity granularity)
448 {
449     if (Position::nodeIsUserSelectNone(targetNode))
450         return false;
451
452     if (!dispatchSelectStart(targetNode))
453         return false;
454
455     VisibleSelection selection(newSelection);
456 #if ENABLE(USERSELECT_ALL)
457     if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode)) {
458         selection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
459         selection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary));
460     }
461 #endif
462     if (selection.isRange())
463         m_selectionInitiationState = ExtendedSelection;
464     else {
465         granularity = CharacterGranularity;
466         m_selectionInitiationState = PlacedCaret;
467     }
468
469     m_frame->selection()->setNonDirectionalSelectionIfNeeded(selection, granularity);
470
471     return true;
472 }
473
474 void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
475 {
476     Node* innerNode = result.targetNode();
477     VisibleSelection newSelection;
478
479     if (innerNode && innerNode->renderer()) {
480         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
481         if (pos.isNotNull()) {
482             newSelection = VisibleSelection(pos);
483             newSelection.expandUsingGranularity(WordGranularity);
484         }
485
486         if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
487             newSelection.appendTrailingWhitespace();
488
489         updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, WordGranularity);
490     }
491 }
492
493 void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
494 {
495     if (m_mouseDownMayStartSelect) {
496         selectClosestWordFromHitTestResult(result.hitTestResult(),
497             (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
498     }
499 }
500
501 void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
502 {
503     if (!result.hitTestResult().isLiveLink())
504         return selectClosestWordFromMouseEvent(result);
505
506     Node* innerNode = result.targetNode();
507
508     if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
509         VisibleSelection newSelection;
510         Element* URLElement = result.hitTestResult().URLElement();
511         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
512         if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
513             newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
514
515         updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, WordGranularity);
516     }
517 }
518
519 bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
520 {
521     if (event.event().button() != LeftButton)
522         return false;
523
524     if (m_frame->selection()->isRange())
525         // A double-click when range is already selected
526         // should not change the selection.  So, do not call
527         // selectClosestWordFromMouseEvent, but do set
528         // m_beganSelectingText to prevent handleMouseReleaseEvent
529         // from setting caret selection.
530         m_selectionInitiationState = ExtendedSelection;
531     else
532         selectClosestWordFromMouseEvent(event);
533
534     return true;
535 }
536
537 bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
538 {
539     if (event.event().button() != LeftButton)
540         return false;
541     
542     Node* innerNode = event.targetNode();
543     if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
544         return false;
545
546     VisibleSelection newSelection;
547     VisiblePosition pos(innerNode->renderer()->positionForPoint(event.localPoint()));
548     if (pos.isNotNull()) {
549         newSelection = VisibleSelection(pos);
550         newSelection.expandUsingGranularity(ParagraphGranularity);
551     }
552
553     return updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, ParagraphGranularity);
554 }
555
556 static int textDistance(const Position& start, const Position& end)
557 {
558      RefPtr<Range> range = Range::create(start.anchorNode()->document(), start, end);
559      return TextIterator::rangeLength(range.get(), true);
560 }
561
562 bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
563 {
564     m_frame->document()->updateLayoutIgnorePendingStylesheets();
565     Node* innerNode = event.targetNode();
566     if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
567         return false;
568
569     // Extend the selection if the Shift key is down, unless the click is in a link.
570     bool extendSelection = event.event().shiftKey() && !event.isOverLink();
571
572     // Don't restart the selection when the mouse is pressed on an
573     // existing selection so we can allow for text dragging.
574     if (FrameView* view = m_frame->view()) {
575         LayoutPoint vPoint = view->windowToContents(event.event().position());
576         if (!extendSelection && m_frame->selection()->contains(vPoint)) {
577             m_mouseDownWasSingleClickInSelection = true;
578             return false;
579         }
580     }
581
582     VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(event.localPoint()));
583     if (visiblePos.isNull())
584         visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOWNSTREAM);
585     Position pos = visiblePos.deepEquivalent();
586
587     VisibleSelection newSelection = m_frame->selection()->selection();
588     TextGranularity granularity = CharacterGranularity;
589
590     if (extendSelection && newSelection.isCaretOrRange()) {
591         ASSERT(m_frame->settings());
592         if (m_frame->settings()->editingBehaviorType() == EditingMacBehavior) {
593             // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
594             // was created right-to-left
595             Position start = newSelection.start();
596             Position end = newSelection.end();
597             int distanceToStart = textDistance(start, pos);
598             int distanceToEnd = textDistance(pos, end);
599             if (distanceToStart <= distanceToEnd)
600                 newSelection = VisibleSelection(end, pos);
601             else
602                 newSelection = VisibleSelection(start, pos);
603         } else
604             newSelection.setExtent(pos);
605
606         if (m_frame->selection()->granularity() != CharacterGranularity) {
607             granularity = m_frame->selection()->granularity();
608             newSelection.expandUsingGranularity(m_frame->selection()->granularity());
609         }
610     } else
611         newSelection = VisibleSelection(visiblePos);
612     
613     bool handled = updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, granularity);
614
615     if (event.event().button() == MiddleButton) {
616         // Ignore handled, since we want to paste to where the caret was placed anyway.
617         handled = handlePasteGlobalSelection(event.event()) || handled;
618     }
619     return handled;
620 }
621
622 static inline bool canMouseDownStartSelect(Node* node)
623 {
624     if (!node || !node->renderer())
625         return true;
626
627     if (!node->canStartSelection())
628         return false;
629
630     return true;
631 }
632
633 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
634 {
635 #if ENABLE(DRAG_SUPPORT)
636     // Reset drag state.
637     dragState().m_dragSrc = 0;
638 #endif
639
640     cancelFakeMouseMoveEvent();
641
642     m_frame->document()->updateLayoutIgnorePendingStylesheets();
643
644     if (ScrollView* scrollView = m_frame->view()) {
645         if (scrollView->isPointInScrollbarCorner(event.event().position()))
646             return false;
647     }
648
649     bool singleClick = event.event().clickCount() <= 1;
650
651     // If we got the event back, that must mean it wasn't prevented,
652     // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
653     m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode()) && !event.scrollbar();
654     
655 #if ENABLE(DRAG_SUPPORT)
656     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
657     m_mouseDownMayStartDrag = singleClick;
658 #endif
659
660     m_mouseDownWasSingleClickInSelection = false;
661
662     m_mouseDown = event.event();
663
664     if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
665         return true;
666
667 #if ENABLE(SVG)
668     if (m_frame->document()->isSVGDocument()
669         && static_cast<SVGDocument*>(m_frame->document())->zoomAndPanEnabled()) {
670         if (event.event().shiftKey() && singleClick) {
671             m_svgPan = true;
672             static_cast<SVGDocument*>(m_frame->document())->startPan(m_frame->view()->windowToContents(event.event().position()));
673             return true;
674         }
675     }
676 #endif
677
678     // We don't do this at the start of mouse down handling,
679     // because we don't want to do it until we know we didn't hit a widget.
680     if (singleClick)
681         focusDocumentView();
682
683     Node* innerNode = event.targetNode();
684
685     m_mousePressNode = innerNode;
686 #if ENABLE(DRAG_SUPPORT)
687     m_dragStartPos = event.event().position();
688 #endif
689
690     bool swallowEvent = false;
691     m_mousePressed = true;
692     m_selectionInitiationState = HaveNotStartedSelection;
693
694     if (event.event().clickCount() == 2)
695         swallowEvent = handleMousePressEventDoubleClick(event);
696     else if (event.event().clickCount() >= 3)
697         swallowEvent = handleMousePressEventTripleClick(event);
698     else
699         swallowEvent = handleMousePressEventSingleClick(event);
700     
701     m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect
702         || (m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled());
703
704     return swallowEvent;
705 }
706
707 // There are two kinds of renderer that can autoscroll.
708 static bool canAutoscroll(RenderObject* renderer)
709 {
710     if (!renderer->isBox())
711         return false;
712
713     // Check for a box that can be scrolled in its own right.
714     if (toRenderBox(renderer)->canBeScrolledAndHasScrollableArea())
715         return true;
716
717     // Check for a box that represents the top level of a web page.
718     // This can be scrolled by calling Chrome::scrollRectIntoView.
719     // This only has an effect on the Mac platform in applications
720     // that put web views into scrolling containers, such as Mac OS X Mail.
721     // The code for this is in RenderLayer::scrollRectToVisible.
722     if (renderer->node() != renderer->document())
723         return false;
724     Frame* frame = renderer->frame();
725     if (!frame)
726         return false;
727     Page* page = frame->page();
728     return page && page->mainFrame() == frame;
729 }
730
731 #if ENABLE(DRAG_SUPPORT)
732 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event)
733 {
734     if (handleDrag(event, ShouldCheckDragHysteresis))
735         return true;
736
737     if (!m_mousePressed)
738         return false;
739
740     Node* targetNode = event.targetNode();
741     if (event.event().button() != LeftButton || !targetNode)
742         return false;
743
744     RenderObject* renderer = targetNode->renderer();
745     if (!renderer) {
746         renderer = targetNode->parentNode() ? targetNode->parentNode()->renderer() : 0;
747         if (!renderer || !renderer->isListBox())
748             return false;
749     }
750
751 #if PLATFORM(MAC) // FIXME: Why does this assertion fire on other platforms?
752     ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
753 #endif
754
755     m_mouseDownMayStartDrag = false;
756
757     if (m_mouseDownMayStartAutoscroll && !m_panScrollInProgress) {            
758         // Find a renderer that can autoscroll.
759         while (renderer && !canAutoscroll(renderer)) {
760             if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
761                 renderer = renderer->document()->ownerElement()->renderer();
762             else
763                 renderer = renderer->parent();
764         }
765         
766         if (renderer) {
767             m_autoscrollInProgress = true;
768             handleAutoscroll(renderer);
769         }
770         
771         m_mouseDownMayStartAutoscroll = false;
772     }
773
774     if (m_selectionInitiationState != ExtendedSelection) {
775         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
776         HitTestResult result(m_mouseDownPos);
777         m_frame->document()->renderView()->hitTest(request, result);
778
779         updateSelectionForMouseDrag(result);
780     }
781     updateSelectionForMouseDrag(event.hitTestResult());
782     return true;
783 }
784     
785 bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
786 {
787     // This is a pre-flight check of whether the event might lead to a drag being started.  Be careful
788     // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
789     // in handleMousePressEvent
790     
791     if (!m_frame->contentRenderer() || !m_frame->contentRenderer()->hasLayer())
792         return false;
793
794     if (event.button() != LeftButton || event.clickCount() != 1)
795         return false;
796     
797     FrameView* view = m_frame->view();
798     if (!view)
799         return false;
800
801     Page* page = m_frame->page();
802     if (!page)
803         return false;
804
805     updateDragSourceActionsAllowed();
806     HitTestRequest request(HitTestRequest::ReadOnly);
807     HitTestResult result(view->windowToContents(event.position()));
808     m_frame->contentRenderer()->hitTest(request, result);
809     DragState state;
810     return result.innerNode() && page->dragController()->draggableNode(m_frame, result.innerNode(), result.roundedPointInInnerNodeFrame(), state);
811 }
812
813 void EventHandler::updateSelectionForMouseDrag()
814 {
815     FrameView* view = m_frame->view();
816     if (!view)
817         return;
818     RenderView* renderer = m_frame->contentRenderer();
819     if (!renderer)
820         return;
821
822     HitTestRequest request(HitTestRequest::ReadOnly |
823                            HitTestRequest::Active |
824                            HitTestRequest::Move);
825     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
826     renderer->hitTest(request, result);
827     updateSelectionForMouseDrag(result);
828 }
829
830 static VisiblePosition selectionExtentRespectingEditingBoundary(const VisibleSelection& selection, const LayoutPoint& localPoint, Node* targetNode)
831 {
832     LayoutPoint selectionEndPoint = localPoint;
833     Element* editableElement = selection.rootEditableElement();
834
835     if (!targetNode->renderer())
836         return VisiblePosition();
837
838     if (editableElement && !editableElement->contains(targetNode)) {
839         if (!editableElement->renderer())
840             return VisiblePosition();
841
842         FloatPoint absolutePoint = targetNode->renderer()->localToAbsolute(FloatPoint(selectionEndPoint));
843         selectionEndPoint = roundedLayoutPoint(editableElement->renderer()->absoluteToLocal(absolutePoint));
844         targetNode = editableElement;
845     }
846
847     return targetNode->renderer()->positionForPoint(selectionEndPoint);
848 }
849
850 void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
851 {
852     if (!m_mouseDownMayStartSelect)
853         return;
854
855     Node* target = hitTestResult.targetNode();
856     if (!target)
857         return;
858
859     VisiblePosition targetPosition = selectionExtentRespectingEditingBoundary(m_frame->selection()->selection(), hitTestResult.localPoint(), target);
860
861     // Don't modify the selection if we're not on a node.
862     if (targetPosition.isNull())
863         return;
864
865     // Restart the selection if this is the first mouse move. This work is usually
866     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
867     VisibleSelection newSelection = m_frame->selection()->selection();
868
869 #if ENABLE(SVG)
870     // Special case to limit selection to the containing block for SVG text.
871     // FIXME: Isn't there a better non-SVG-specific way to do this?
872     if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
873         if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
874             if (selectionBaseRenderer->isSVGText())
875                 if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
876                     return;
877 #endif
878
879     if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
880         return;
881
882     if (m_selectionInitiationState != ExtendedSelection) {
883         // Always extend selection here because it's caused by a mouse drag
884         m_selectionInitiationState = ExtendedSelection;
885         newSelection = VisibleSelection(targetPosition);
886     }
887
888 #if ENABLE(USERSELECT_ALL)
889     Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllForNode(m_mousePressNode.get());
890     if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePressNode == Position::rootUserSelectAllForNode(target)) {
891         newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePressNode).upstream(CanCrossEditingBoundary));
892         newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
893     } else {
894         // Reset base for user select all when base is inside user-select-all area and extent < base.
895         if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
896             newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
897         
898         Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
899         if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
900             newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
901         else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
902             newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
903         else
904             newSelection.setExtent(targetPosition);
905     }
906 #else
907     newSelection.setExtent(targetPosition);
908 #endif
909
910     if (m_frame->selection()->granularity() != CharacterGranularity)
911         newSelection.expandUsingGranularity(m_frame->selection()->granularity());
912
913     m_frame->selection()->setNonDirectionalSelectionIfNeeded(newSelection, m_frame->selection()->granularity(),
914         FrameSelection::AdjustEndpointsAtBidiBoundary);
915 }
916 #endif // ENABLE(DRAG_SUPPORT)
917
918 void EventHandler::lostMouseCapture()
919 {
920     m_frame->selection()->setCaretBlinkingSuspended(false);
921 }
922
923 bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
924 {
925     if (eventLoopHandleMouseUp(event))
926         return true;
927     
928     // If this was the first click in the window, we don't even want to clear the selection.
929     // This case occurs when the user clicks on a draggable element, since we have to process
930     // the mouse down and drag events to see if we might start a drag.  For other first clicks
931     // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets
932     // ignored upstream of this layer.
933     return eventActivatedView(event.event());
934 }    
935
936 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
937 {
938     if (m_autoscrollInProgress)
939         stopAutoscrollTimer();
940
941     if (handleMouseUp(event))
942         return true;
943
944     // Used to prevent mouseMoveEvent from initiating a drag before
945     // the mouse is pressed again.
946     m_frame->selection()->setCaretBlinkingSuspended(false);
947     m_mousePressed = false;
948     m_capturesDragging = false;
949 #if ENABLE(DRAG_SUPPORT)
950     m_mouseDownMayStartDrag = false;
951 #endif
952     m_mouseDownMayStartSelect = false;
953     m_mouseDownMayStartAutoscroll = false;
954     m_mouseDownWasInSubframe = false;
955   
956     bool handled = false;
957
958     // Clear the selection if the mouse didn't move after the last mouse
959     // press and it's not a context menu click.  We do this so when clicking
960     // on the selection, the selection goes away.  However, if we are
961     // editing, place the caret.
962     if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
963 #if ENABLE(DRAG_SUPPORT)
964             && m_dragStartPos == event.event().position()
965 #endif
966             && m_frame->selection()->isRange()
967             && event.event().button() != RightButton) {
968         VisibleSelection newSelection;
969         Node* node = event.targetNode();
970         bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
971         if (node && (caretBrowsing || node->rendererIsEditable()) && node->renderer()) {
972             VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());
973             newSelection = VisibleSelection(pos);
974         }
975
976         setSelectionIfNeeded(m_frame->selection(), newSelection);
977
978         handled = true;
979     }
980
981     m_frame->selection()->notifyRendererOfSelectionChange(UserTriggered);
982
983     m_frame->selection()->selectFrameElementInParentIfFullySelected();
984
985     if (event.event().button() == MiddleButton) {
986         // Ignore handled, since we want to paste to where the caret was placed anyway.
987         handled = handlePasteGlobalSelection(event.event()) || handled;
988     }
989
990     return handled;
991 }
992
993 void EventHandler::handleAutoscroll(RenderObject* renderer)
994 {
995     // We don't want to trigger the autoscroll or the panScroll if it's already active
996     if (m_autoscrollTimer.isActive())
997         return;     
998
999     setAutoscrollRenderer(renderer);
1000
1001 #if ENABLE(PAN_SCROLLING)
1002     if (m_panScrollInProgress) {
1003         m_panScrollStartPos = lastKnownMousePosition();
1004         if (FrameView* view = m_frame->view())
1005             view->addPanScrollIcon(m_panScrollStartPos);
1006         // If we're not in the top frame we notify it that we doing a panScroll.
1007         if (Page* page = m_frame->page()) {
1008             Frame* mainFrame = page->mainFrame();
1009             if (m_frame != mainFrame)
1010                 mainFrame->eventHandler()->m_panScrollInProgress = true;
1011         }
1012     }
1013 #endif
1014
1015     startAutoscrollTimer();
1016 }
1017
1018 void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
1019 {
1020     RenderObject* r = autoscrollRenderer();
1021     if (!r || !r->isBox()) {
1022         stopAutoscrollTimer();
1023         return;
1024     }
1025
1026     if (m_autoscrollInProgress) {
1027         if (!m_mousePressed) {
1028             stopAutoscrollTimer();
1029             return;
1030         }
1031         toRenderBox(r)->autoscroll();
1032     } else {
1033         // we verify that the main frame hasn't received the order to stop the panScroll
1034         if (Page* page = m_frame->page()) {
1035             if (!page->mainFrame()->eventHandler()->m_panScrollInProgress) {
1036                 stopAutoscrollTimer();
1037                 return;
1038             }
1039         }
1040 #if ENABLE(PAN_SCROLLING)
1041         updatePanScrollState();
1042         toRenderBox(r)->panScroll(m_panScrollStartPos);
1043 #endif
1044     }
1045 }
1046
1047 #if ENABLE(PAN_SCROLLING)
1048
1049 void EventHandler::startPanScrolling(RenderObject* renderer)
1050 {
1051     m_panScrollInProgress = true;
1052     m_panScrollButtonPressed = true;
1053     handleAutoscroll(renderer);
1054     invalidateClick();
1055 }
1056
1057 void EventHandler::updatePanScrollState()
1058 {
1059     FrameView* view = m_frame->view();
1060     if (!view)
1061         return;
1062
1063     // At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll
1064     // So we don't want to change the cursor over this area
1065     bool east = m_panScrollStartPos.x() < (m_lastKnownMousePosition.x() - ScrollView::noPanScrollRadius);
1066     bool west = m_panScrollStartPos.x() > (m_lastKnownMousePosition.x() + ScrollView::noPanScrollRadius);
1067     bool north = m_panScrollStartPos.y() > (m_lastKnownMousePosition.y() + ScrollView::noPanScrollRadius);
1068     bool south = m_panScrollStartPos.y() < (m_lastKnownMousePosition.y() - ScrollView::noPanScrollRadius);
1069          
1070     if ((east || west || north || south) && m_panScrollButtonPressed)
1071         m_springLoadedPanScrollInProgress = true;
1072
1073     if (north) {
1074         if (east)
1075             view->setCursor(northEastPanningCursor());
1076         else if (west)
1077             view->setCursor(northWestPanningCursor());
1078         else
1079             view->setCursor(northPanningCursor());
1080     } else if (south) {
1081         if (east)
1082             view->setCursor(southEastPanningCursor());
1083         else if (west)
1084             view->setCursor(southWestPanningCursor());
1085         else
1086             view->setCursor(southPanningCursor());
1087     } else if (east)
1088         view->setCursor(eastPanningCursor());
1089     else if (west)
1090         view->setCursor(westPanningCursor());
1091     else
1092         view->setCursor(middlePanningCursor());
1093 }
1094
1095 #endif // ENABLE(PAN_SCROLLING)
1096
1097 RenderObject* EventHandler::autoscrollRenderer() const
1098 {
1099     return m_autoscrollRenderer;
1100 }
1101
1102 void EventHandler::updateAutoscrollRenderer()
1103 {
1104     if (!m_autoscrollRenderer)
1105         return;
1106
1107     HitTestResult hitTest = hitTestResultAtPoint(m_panScrollStartPos, true);
1108
1109     if (Node* nodeAtPoint = hitTest.innerNode())
1110         m_autoscrollRenderer = nodeAtPoint->renderer();
1111
1112     while (m_autoscrollRenderer && !canAutoscroll(m_autoscrollRenderer))
1113         m_autoscrollRenderer = m_autoscrollRenderer->parent();
1114 }
1115
1116 void EventHandler::setAutoscrollRenderer(RenderObject* renderer)
1117 {
1118     m_autoscrollRenderer = renderer;
1119 }
1120
1121 #if ENABLE(DRAG_SUPPORT)
1122 DragSourceAction EventHandler::updateDragSourceActionsAllowed() const
1123 {
1124     if (!m_frame)
1125         return DragSourceActionNone;
1126
1127     Page* page = m_frame->page();
1128     if (!page)
1129         return DragSourceActionNone;
1130
1131     FrameView* view = m_frame->view();
1132     if (!view)
1133         return DragSourceActionNone;
1134
1135     return page->dragController()->delegateDragSourceAction(view->contentsToRootView(m_mouseDownPos));
1136 }
1137 #endif // ENABLE(DRAG_SUPPORT)
1138
1139 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding)
1140 {
1141     // We always send hitTestResultAtPoint to the main frame if we have one,
1142     // otherwise we might hit areas that are obscured by higher frames.
1143     if (Page* page = m_frame->page()) {
1144         Frame* mainFrame = page->mainFrame();
1145         if (m_frame != mainFrame) {
1146             FrameView* frameView = m_frame->view();
1147             FrameView* mainView = mainFrame->view();
1148             if (frameView && mainView) {
1149                 IntPoint mainFramePoint = mainView->rootViewToContents(frameView->contentsToRootView(roundedIntPoint(point)));
1150                 return mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent, ignoreClipping, testScrollbars, hitType, padding);
1151             }
1152         }
1153     }
1154
1155     HitTestResult result(point, padding.height(), padding.width(), padding.height(), padding.width());
1156
1157     if (!m_frame->contentRenderer())
1158         return result;
1159     if (ignoreClipping)
1160         hitType |= HitTestRequest::IgnoreClipping;
1161     if (allowShadowContent)
1162         hitType |= HitTestRequest::AllowShadowContent;
1163     HitTestRequest request(hitType);
1164     m_frame->contentRenderer()->hitTest(request, result);
1165
1166     while (true) {
1167         Node* n = result.innerNode();
1168         if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget())
1169             break;
1170         RenderWidget* renderWidget = toRenderWidget(n->renderer());
1171         Widget* widget = renderWidget->widget();
1172         if (!widget || !widget->isFrameView())
1173             break;
1174         Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame();
1175         if (!frame || !frame->contentRenderer())
1176             break;
1177         FrameView* view = static_cast<FrameView*>(widget);
1178         LayoutPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(), 
1179             result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop());
1180         HitTestResult widgetHitTestResult(widgetPoint, padding.height(), padding.width(), padding.height(), padding.width());
1181         widgetHitTestResult.setPointInMainFrame(result.pointInMainFrame());
1182         frame->contentRenderer()->hitTest(request, widgetHitTestResult);
1183         result = widgetHitTestResult;
1184
1185         if (testScrollbars == ShouldHitTestScrollbars) {
1186             Scrollbar* eventScrollbar = view->scrollbarAtPoint(roundedIntPoint(point));
1187             if (eventScrollbar)
1188                 result.setScrollbar(eventScrollbar);
1189         }
1190     }
1191
1192     if (!allowShadowContent)
1193         result.setToNonShadowAncestor();
1194
1195     return result;
1196 }
1197
1198
1199 void EventHandler::startAutoscrollTimer()
1200 {
1201     m_autoscrollTimer.startRepeating(autoscrollInterval);
1202 }
1203
1204 void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
1205 {
1206     if (m_autoscrollInProgress) {
1207         if (m_mouseDownWasInSubframe) {
1208             if (Frame* subframe = subframeForTargetNode(m_mousePressNode.get()))
1209                 subframe->eventHandler()->stopAutoscrollTimer(rendererIsBeingDestroyed);
1210             return;
1211         }
1212     }
1213
1214     if (autoscrollRenderer()) {
1215         if (!rendererIsBeingDestroyed && (m_autoscrollInProgress || m_panScrollInProgress))
1216             toRenderBox(autoscrollRenderer())->stopAutoscroll();
1217 #if ENABLE(PAN_SCROLLING)
1218         if (m_panScrollInProgress) {
1219             if (FrameView* view = m_frame->view()) {
1220                 view->removePanScrollIcon();
1221                 view->setCursor(pointerCursor());
1222             }
1223         }
1224 #endif
1225
1226         setAutoscrollRenderer(0);
1227     }
1228
1229     m_autoscrollTimer.stop();
1230
1231     m_panScrollInProgress = false;
1232     m_springLoadedPanScrollInProgress = false;
1233
1234     // If we're not in the top frame we notify it that we are not doing a panScroll any more.
1235     if (Page* page = m_frame->page()) {
1236         Frame* mainFrame = page->mainFrame();
1237         if (m_frame != mainFrame)
1238             mainFrame->eventHandler()->m_panScrollInProgress = false;
1239     }
1240
1241     m_autoscrollInProgress = false;
1242 }
1243
1244 Node* EventHandler::mousePressNode() const
1245 {
1246     return m_mousePressNode.get();
1247 }
1248
1249 void EventHandler::setMousePressNode(PassRefPtr<Node> node)
1250 {
1251     m_mousePressNode = node;
1252 }
1253
1254 bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1255 {
1256     Node* node = startingNode;
1257
1258     if (!node)
1259         node = m_frame->document()->focusedNode();
1260
1261     if (!node)
1262         node = m_mousePressNode.get();
1263     
1264     if (node) {
1265         RenderObject* r = node->renderer();
1266         if (r && !r->isListBox() && r->enclosingBox()->scroll(direction, granularity)) {
1267             setFrameWasScrolledByUser();
1268             return true;
1269         }
1270     }
1271
1272     return false;
1273 }
1274
1275 bool EventHandler::logicalScrollOverflow(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1276 {
1277     Node* node = startingNode;
1278
1279     if (!node)
1280         node = m_frame->document()->focusedNode();
1281
1282     if (!node)
1283         node = m_mousePressNode.get();
1284     
1285     if (node) {
1286         RenderObject* r = node->renderer();
1287         if (r && !r->isListBox() && r->enclosingBox()->logicalScroll(direction, granularity)) {
1288             setFrameWasScrolledByUser();
1289             return true;
1290         }
1291     }
1292
1293     return false;
1294 }
1295
1296 bool EventHandler::scrollRecursively(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
1297 {
1298     // The layout needs to be up to date to determine if we can scroll. We may be
1299     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1300     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1301     if (scrollOverflow(direction, granularity, startingNode))
1302         return true;    
1303     Frame* frame = m_frame;
1304     FrameView* view = frame->view();
1305     if (view && view->scroll(direction, granularity))
1306         return true;
1307     frame = frame->tree()->parent();
1308     if (!frame)
1309         return false;
1310     return frame->eventHandler()->scrollRecursively(direction, granularity, m_frame->ownerElement());
1311 }
1312
1313 bool EventHandler::logicalScrollRecursively(ScrollLogicalDirection direction, ScrollGranularity granularity, Node* startingNode)
1314 {
1315     // The layout needs to be up to date to determine if we can scroll. We may be
1316     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
1317     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1318     if (logicalScrollOverflow(direction, granularity, startingNode))
1319         return true;    
1320     Frame* frame = m_frame;
1321     FrameView* view = frame->view();
1322     
1323     bool scrolled = false;
1324 #if PLATFORM(MAC)
1325     // Mac also resets the scroll position in the inline direction.
1326     if (granularity == ScrollByDocument && view && view->logicalScroll(ScrollInlineDirectionBackward, ScrollByDocument))
1327         scrolled = true;
1328 #endif
1329     if (view && view->logicalScroll(direction, granularity))
1330         scrolled = true;
1331     
1332     if (scrolled)
1333         return true;
1334     
1335     frame = frame->tree()->parent();
1336     if (!frame)
1337         return false;
1338
1339     return frame->eventHandler()->logicalScrollRecursively(direction, granularity, m_frame->ownerElement());
1340 }
1341
1342 IntPoint EventHandler::lastKnownMousePosition() const
1343 {
1344     return m_lastKnownMousePosition;
1345 }
1346
1347 Frame* EventHandler::subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
1348 {
1349     if (!hitTestResult.isOverWidget())
1350         return 0;
1351     return subframeForTargetNode(hitTestResult.targetNode());
1352 }
1353
1354 Frame* EventHandler::subframeForTargetNode(Node* node)
1355 {
1356     if (!node)
1357         return 0;
1358
1359     RenderObject* renderer = node->renderer();
1360     if (!renderer || !renderer->isWidget())
1361         return 0;
1362
1363     Widget* widget = toRenderWidget(renderer)->widget();
1364     if (!widget || !widget->isFrameView())
1365         return 0;
1366
1367     return static_cast<FrameView*>(widget)->frame();
1368 }
1369
1370 static bool isSubmitImage(Node* node)
1371 {
1372     return node && node->hasTagName(inputTag) && static_cast<HTMLInputElement*>(node)->isImageButton();
1373 }
1374
1375 // Returns true if the node's editable block is not current focused for editing
1376 static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
1377 {
1378     return frame->selection()->rootEditableElement() != node->rootEditableElement();
1379 }
1380
1381 bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
1382 {
1383     if (!node)
1384         return false;
1385
1386     bool editable = node->rendererIsEditable();
1387     bool editableLinkEnabled = false;
1388
1389     // If the link is editable, then we need to check the settings to see whether or not the link should be followed
1390     if (editable) {
1391         ASSERT(m_frame->settings());
1392         switch (m_frame->settings()->editableLinkBehavior()) {
1393         default:
1394         case EditableLinkDefaultBehavior:
1395         case EditableLinkAlwaysLive:
1396             editableLinkEnabled = true;
1397             break;
1398
1399         case EditableLinkNeverLive:
1400             editableLinkEnabled = false;
1401             break;
1402
1403         case EditableLinkLiveWhenNotFocused:
1404             editableLinkEnabled = nodeIsNotBeingEdited(node, m_frame) || shiftKey;
1405             break;
1406
1407         case EditableLinkOnlyLiveWithShiftKey:
1408             editableLinkEnabled = shiftKey;
1409             break;
1410         }
1411     }
1412
1413     return ((isOverLink || isSubmitImage(node)) && (!editable || editableLinkEnabled));
1414 }
1415
1416 OptionalCursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar)
1417 {
1418     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1419         return NoCursorChange;
1420
1421     Page* page = m_frame->page();
1422     if (!page)
1423         return NoCursorChange;
1424     if (page->mainFrame()->eventHandler()->m_panScrollInProgress)
1425         return NoCursorChange;
1426
1427     Node* node = event.targetNode();
1428     RenderObject* renderer = node ? node->renderer() : 0;
1429     RenderStyle* style = renderer ? renderer->style() : 0;
1430     bool horizontalText = !style || style->isHorizontalWritingMode();
1431     const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
1432
1433     // During selection, use an I-beam no matter what we're over.
1434     // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
1435     if (m_mousePressed && m_mouseDownMayStartSelect
1436 #if ENABLE(DRAG_SUPPORT)
1437         && !m_mouseDownMayStartDrag
1438 #endif
1439         && m_frame->selection()->isCaretOrRange() && !m_capturingMouseEventsNode)
1440         return iBeam;
1441
1442     if (renderer) {
1443         Cursor overrideCursor;
1444         switch (renderer->getCursor(roundedIntPoint(event.localPoint()), overrideCursor)) {
1445         case SetCursorBasedOnStyle:
1446             break;
1447         case SetCursor:
1448             return overrideCursor;
1449         case DoNotSetCursor:
1450             return NoCursorChange;
1451         }
1452     }
1453
1454     if (style && style->cursors()) {
1455         const CursorList* cursors = style->cursors();
1456         for (unsigned i = 0; i < cursors->size(); ++i) {
1457             StyleImage* styleImage = (*cursors)[i].image();
1458             if (!styleImage)
1459                 continue;
1460             CachedImage* cachedImage = styleImage->cachedImage();
1461             if (!cachedImage)
1462                 continue;
1463             float scale = styleImage->imageScaleFactor();
1464             // Get hotspot and convert from logical pixels to physical pixels.
1465             IntPoint hotSpot = (*cursors)[i].hotSpot();
1466             hotSpot.scale(scale, scale);
1467             IntSize size = cachedImage->imageForRenderer(renderer)->size();
1468             if (cachedImage->errorOccurred())
1469                 continue;
1470             // Limit the size of cursors (in UI pixels) so that they cannot be
1471             // used to cover UI elements in chrome.
1472             size.scale(1 / scale);
1473             if (size.width() > maximumCursorSize || size.height() > maximumCursorSize)
1474                 continue;
1475
1476             Image* image = cachedImage->imageForRenderer(renderer);
1477 #if ENABLE(MOUSE_CURSOR_SCALE)
1478             // Ensure no overflow possible in calculations above.
1479             if (scale < minimumCursorScale)
1480                 continue;
1481             return Cursor(image, hotSpot, scale);
1482 #else
1483             ASSERT(scale == 1);
1484             return Cursor(image, hotSpot);
1485 #endif // ENABLE(MOUSE_CURSOR_SCALE)
1486         }
1487     }
1488
1489     switch (style ? style->cursor() : CURSOR_AUTO) {
1490     case CURSOR_AUTO: {
1491         bool editable = (node && node->rendererIsEditable());
1492
1493         if (useHandCursor(node, event.isOverLink(), event.event().shiftKey()))
1494             return handCursor();
1495
1496         bool inResizer = false;
1497         if (renderer) {
1498             if (RenderLayer* layer = renderer->enclosingLayer()) {
1499                 if (FrameView* view = m_frame->view())
1500                     inResizer = layer->isPointInResizeControl(view->windowToContents(event.event().position()));
1501             }
1502         }
1503         if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !scrollbar)
1504             return iBeam;
1505         return pointerCursor();
1506     }
1507     case CURSOR_CROSS:
1508         return crossCursor();
1509     case CURSOR_POINTER:
1510         return handCursor();
1511     case CURSOR_MOVE:
1512         return moveCursor();
1513     case CURSOR_ALL_SCROLL:
1514         return moveCursor();
1515     case CURSOR_E_RESIZE:
1516         return eastResizeCursor();
1517     case CURSOR_W_RESIZE:
1518         return westResizeCursor();
1519     case CURSOR_N_RESIZE:
1520         return northResizeCursor();
1521     case CURSOR_S_RESIZE:
1522         return southResizeCursor();
1523     case CURSOR_NE_RESIZE:
1524         return northEastResizeCursor();
1525     case CURSOR_SW_RESIZE:
1526         return southWestResizeCursor();
1527     case CURSOR_NW_RESIZE:
1528         return northWestResizeCursor();
1529     case CURSOR_SE_RESIZE:
1530         return southEastResizeCursor();
1531     case CURSOR_NS_RESIZE:
1532         return northSouthResizeCursor();
1533     case CURSOR_EW_RESIZE:
1534         return eastWestResizeCursor();
1535     case CURSOR_NESW_RESIZE:
1536         return northEastSouthWestResizeCursor();
1537     case CURSOR_NWSE_RESIZE:
1538         return northWestSouthEastResizeCursor();
1539     case CURSOR_COL_RESIZE:
1540         return columnResizeCursor();
1541     case CURSOR_ROW_RESIZE:
1542         return rowResizeCursor();
1543     case CURSOR_TEXT:
1544         return iBeamCursor();
1545     case CURSOR_WAIT:
1546         return waitCursor();
1547     case CURSOR_HELP:
1548         return helpCursor();
1549     case CURSOR_VERTICAL_TEXT:
1550         return verticalTextCursor();
1551     case CURSOR_CELL:
1552         return cellCursor();
1553     case CURSOR_CONTEXT_MENU:
1554         return contextMenuCursor();
1555     case CURSOR_PROGRESS:
1556         return progressCursor();
1557     case CURSOR_NO_DROP:
1558         return noDropCursor();
1559     case CURSOR_ALIAS:
1560         return aliasCursor();
1561     case CURSOR_COPY:
1562         return copyCursor();
1563     case CURSOR_NONE:
1564         return noneCursor();
1565     case CURSOR_NOT_ALLOWED:
1566         return notAllowedCursor();
1567     case CURSOR_DEFAULT:
1568         return pointerCursor();
1569     case CURSOR_WEBKIT_ZOOM_IN:
1570         return zoomInCursor();
1571     case CURSOR_WEBKIT_ZOOM_OUT:
1572         return zoomOutCursor();
1573     case CURSOR_WEBKIT_GRAB:
1574         return grabCursor();
1575     case CURSOR_WEBKIT_GRABBING:
1576         return grabbingCursor();
1577     }
1578     return pointerCursor();
1579 }
1580
1581 static LayoutPoint documentPointForWindowPoint(Frame* frame, const IntPoint& windowPoint)
1582 {
1583     FrameView* view = frame->view();
1584     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
1585     // Historically the code would just crash; this is clearly no worse than that.
1586     return view ? view->windowToContents(windowPoint) : windowPoint;
1587 }
1588
1589 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
1590 {
1591     RefPtr<FrameView> protector(m_frame->view());
1592
1593     if (InspectorInstrumentation::handleMousePress(m_frame->page())) {
1594         invalidateClick();
1595         return true;
1596     }
1597
1598 #if ENABLE(TOUCH_EVENTS)
1599     bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
1600     if (defaultPrevented)
1601         return true;
1602 #endif
1603
1604     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
1605
1606     // FIXME (bug 68185): this call should be made at another abstraction layer
1607     m_frame->loader()->resetMultipleFormSubmissionProtection();
1608     
1609     cancelFakeMouseMoveEvent();
1610     m_mousePressed = true;
1611     m_capturesDragging = true;
1612     setLastKnownMousePosition(mouseEvent);
1613     m_mouseDownTimestamp = mouseEvent.timestamp();
1614 #if ENABLE(DRAG_SUPPORT)
1615     m_mouseDownMayStartDrag = false;
1616 #endif
1617     m_mouseDownMayStartSelect = false;
1618     m_mouseDownMayStartAutoscroll = false;
1619     if (FrameView* view = m_frame->view())
1620         m_mouseDownPos = view->windowToContents(mouseEvent.position());
1621     else {
1622         invalidateClick();
1623         return false;
1624     }
1625     m_mouseDownWasInSubframe = false;
1626
1627     HitTestRequest request(HitTestRequest::Active);
1628     // Save the document point we generate in case the window coordinate is invalidated by what happens 
1629     // when we dispatch the event.
1630     LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
1631     MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
1632
1633     if (!mev.targetNode()) {
1634         invalidateClick();
1635         return false;
1636     }
1637
1638     m_mousePressNode = mev.targetNode();
1639
1640     RefPtr<Frame> subframe = subframeForHitTestResult(mev);
1641     if (subframe && passMousePressEventToSubframe(mev, subframe.get())) {
1642         // Start capturing future events for this frame.  We only do this if we didn't clear
1643         // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
1644         m_capturesDragging = subframe->eventHandler()->capturesDragging();
1645         if (m_mousePressed && m_capturesDragging) {
1646             m_capturingMouseEventsNode = mev.targetNode();
1647             m_eventHandlerWillResetCapturingMouseEventsNode = true;
1648         }
1649         invalidateClick();
1650         return true;
1651     }
1652
1653 #if ENABLE(PAN_SCROLLING)
1654     // We store whether pan scrolling is in progress before calling stopAutoscrollTimer()
1655     // because it will set m_panScrollInProgress to false on return.
1656     bool isPanScrollInProgress = m_frame->page() && m_frame->page()->mainFrame()->eventHandler()->m_panScrollInProgress;
1657     if (isPanScrollInProgress || m_autoscrollInProgress)
1658         stopAutoscrollTimer();
1659     if (isPanScrollInProgress) {
1660         // We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate
1661         // away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>.
1662         invalidateClick();
1663         return true;
1664     }
1665 #endif
1666
1667     m_clickCount = mouseEvent.clickCount();
1668     m_clickNode = mev.targetNode();
1669
1670     if (FrameView* view = m_frame->view()) {
1671         RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;
1672         IntPoint p = view->windowToContents(mouseEvent.position());
1673         if (layer && layer->isPointInResizeControl(p)) {
1674             layer->setInResizeMode(true);
1675             m_resizeLayer = layer;
1676             m_offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
1677             invalidateClick();
1678             return true;
1679         }
1680     }
1681
1682     m_frame->selection()->setCaretBlinkingSuspended(true);
1683
1684     bool swallowEvent = !dispatchMouseEvent(eventNames().mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
1685     m_capturesDragging = !swallowEvent || mev.scrollbar();
1686
1687     // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
1688     // in case the scrollbar widget was destroyed when the mouse event was handled.
1689     if (mev.scrollbar()) {
1690         const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMouse.get();
1691         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
1692         mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
1693         if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
1694             m_lastScrollbarUnderMouse = 0;
1695     }
1696
1697     if (swallowEvent) {
1698         // scrollbars should get events anyway, even disabled controls might be scrollable
1699         Scrollbar* scrollbar = mev.scrollbar();
1700
1701         updateLastScrollbarUnderMouse(scrollbar, true);
1702
1703         if (scrollbar)
1704             passMousePressEventToScrollbar(mev, scrollbar);
1705     } else {
1706         // Refetch the event target node if it currently is the shadow node inside an <input> element.
1707         // If a mouse event handler changes the input element type to one that has a widget associated,
1708         // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
1709         // event target node can't still be the shadow node.
1710         if (mev.targetNode()->isShadowRoot() && toShadowRoot(mev.targetNode())->host()->hasTagName(inputTag)) {
1711             HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
1712             mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
1713         }
1714
1715         FrameView* view = m_frame->view();
1716         Scrollbar* scrollbar = view ? view->scrollbarAtPoint(mouseEvent.position()) : 0;
1717         if (!scrollbar)
1718             scrollbar = mev.scrollbar();
1719
1720         updateLastScrollbarUnderMouse(scrollbar, true);
1721
1722         if (scrollbar && passMousePressEventToScrollbar(mev, scrollbar))
1723             swallowEvent = true;
1724         else
1725             swallowEvent = handleMousePressEvent(mev);
1726     }
1727
1728     return !swallowEvent;
1729 }
1730
1731 // This method only exists for platforms that don't know how to deliver 
1732 bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent)
1733 {
1734     RefPtr<FrameView> protector(m_frame->view());
1735
1736     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
1737
1738     // We get this instead of a second mouse-up 
1739     m_mousePressed = false;
1740     setLastKnownMousePosition(mouseEvent);
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     
1835     setLastKnownMousePosition(mouseEvent);
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_lastKnownMousePosition));
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     setLastKnownMousePosition(mouseEvent);
1961
1962 #if ENABLE(SVG)
1963     if (m_svgPan) {
1964         m_svgPan = false;
1965         static_cast<SVGDocument*>(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
1966         return true;
1967     }
1968 #endif
1969
1970     if (m_frameSetBeingResized)
1971         return !dispatchMouseEvent(eventNames().mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);
1972
1973     if (m_lastScrollbarUnderMouse) {
1974         invalidateClick();
1975         return m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
1976     }
1977
1978     HitTestRequest request(HitTestRequest::Release);
1979     MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
1980     Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
1981     if (m_eventHandlerWillResetCapturingMouseEventsNode)
1982         m_capturingMouseEventsNode = 0;
1983     if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
1984         return true;
1985
1986     bool swallowMouseUpEvent = !dispatchMouseEvent(eventNames().mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
1987
1988     Node* clickTarget = mev.targetNode();
1989     if (clickTarget)
1990         clickTarget = clickTarget->shadowAncestorNode();
1991     Node* adjustedClickNode = m_clickNode ? m_clickNode->shadowAncestorNode() : 0;
1992
1993     bool swallowClickEvent = m_clickCount > 0 && mouseEvent.button() != RightButton && clickTarget == adjustedClickNode && !dispatchMouseEvent(eventNames().clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
1994
1995     if (m_resizeLayer) {
1996         m_resizeLayer->setInResizeMode(false);
1997         m_resizeLayer = 0;
1998     }
1999
2000     bool swallowMouseReleaseEvent = false;
2001     if (!swallowMouseUpEvent)
2002         swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
2003
2004     invalidateClick();
2005
2006     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
2007 }
2008
2009 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& mouseEvent)
2010 {
2011     // If the event was a middle click, attempt to copy global selection in after
2012     // the newly set caret position.
2013     //
2014     // This code is called from either the mouse up or mouse down handling. There
2015     // is some debate about when the global selection is pasted:
2016     //   xterm: pastes on up.
2017     //   GTK: pastes on down.
2018     //   Qt: pastes on up.
2019     //   Firefox: pastes on up.
2020     //   Chromium: pastes on up.
2021     //
2022     // There is something of a webcompat angle to this well, as highlighted by
2023     // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
2024     // down then the text is pasted just before the onclick handler runs and
2025     // clears the text box. So it's important this happens after the event
2026     // handlers have been fired.
2027 #if PLATFORM(GTK)
2028     if (mouseEvent.type() != PlatformEvent::MousePressed)
2029         return false;
2030 #else
2031     if (mouseEvent.type() != PlatformEvent::MouseReleased)
2032         return false;
2033 #endif
2034
2035     Frame* focusFrame = m_frame->page()->focusController()->focusedOrMainFrame();
2036     // Do not paste here if the focus was moved somewhere else.
2037     if (m_frame == focusFrame && m_frame->editor()->client()->supportsGlobalSelection())
2038         return m_frame->editor()->command(ASCIILiteral("PasteGlobalSelection")).execute();
2039
2040     return false;
2041 }
2042
2043
2044 #if ENABLE(DRAG_SUPPORT)
2045 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard)
2046 {
2047     FrameView* view = m_frame->view();
2048
2049     // FIXME: We might want to dispatch a dragleave even if the view is gone.
2050     if (!view)
2051         return false;
2052
2053     view->resetDeferredRepaintDelay();
2054     RefPtr<MouseEvent> me = MouseEvent::create(eventType,
2055         true, true, m_frame->document()->defaultView(),
2056         0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
2057 #if ENABLE(POINTER_LOCK)
2058         event.movementDelta().x(), event.movementDelta().y(),
2059 #endif
2060         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
2061         0, 0, clipboard);
2062
2063     ExceptionCode ec;
2064     dragTarget->dispatchEvent(me.get(), ec);
2065     return me->defaultPrevented();
2066 }
2067
2068 static bool targetIsFrame(Node* target, Frame*& frame)
2069 {
2070     if (!target)
2071         return false;
2072
2073     if (!target->hasTagName(frameTag) && !target->hasTagName(iframeTag))
2074         return false;
2075
2076     frame = static_cast<HTMLFrameElementBase*>(target)->contentFrame();
2077
2078     return true;
2079 }
2080
2081 static bool findDropZone(Node* target, Clipboard* clipboard)
2082 {
2083     Element* element = target->isElementNode() ? toElement(target) : target->parentElement();
2084     for (; element; element = element->parentElement()) {
2085         bool matched = false;
2086         String dropZoneStr = element->fastGetAttribute(webkitdropzoneAttr);
2087
2088         if (dropZoneStr.isEmpty())
2089             continue;
2090         
2091         dropZoneStr.makeLower();
2092         
2093         SpaceSplitString keywords(dropZoneStr, false);
2094         if (keywords.isNull())
2095             continue;
2096         
2097         DragOperation dragOperation = DragOperationNone;
2098         for (unsigned int i = 0; i < keywords.size(); i++) {
2099             DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
2100             if (op != DragOperationNone) {
2101                 if (dragOperation == DragOperationNone)
2102                     dragOperation = op;
2103             } else
2104                 matched = matched || clipboard->hasDropZoneType(keywords[i].string());
2105
2106             if (matched && dragOperation != DragOperationNone)
2107                 break;
2108         }
2109         if (matched) {
2110             clipboard->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
2111             return true;
2112         }
2113     }
2114     return false;
2115 }
2116     
2117 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
2118 {
2119     bool accept = false;
2120
2121     if (!m_frame->view())
2122         return false;
2123
2124     HitTestRequest request(HitTestRequest::ReadOnly);
2125     MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
2126
2127     // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
2128     RefPtr<Node> newTarget = mev.targetNode();
2129     if (newTarget && newTarget->isTextNode())
2130         newTarget = newTarget->parentNode();
2131
2132     if (m_dragTarget != newTarget) {
2133         // FIXME: this ordering was explicitly chosen to match WinIE. However,
2134         // it is sometimes incorrect when dragging within subframes, as seen with
2135         // LayoutTests/fast/events/drag-in-frames.html.
2136         //
2137         // 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>.
2138         Frame* targetFrame;
2139         if (targetIsFrame(newTarget.get(), targetFrame)) {
2140             if (targetFrame)
2141                 accept = targetFrame->eventHandler()->updateDragAndDrop(event, clipboard);
2142         } else if (newTarget) {
2143             // 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.
2144             if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
2145                 // for now we don't care if event handler cancels default behavior, since there is none
2146                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2147             }
2148             accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget.get(), event, clipboard);
2149             if (!accept)
2150                 accept = findDropZone(newTarget.get(), clipboard);
2151         }
2152
2153         if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2154             if (targetFrame)
2155                 accept = targetFrame->eventHandler()->updateDragAndDrop(event, clipboard);
2156         } else if (m_dragTarget)
2157             dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
2158
2159         if (newTarget) {
2160             // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
2161             // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function.
2162             m_shouldOnlyFireDragOverEvent = true;
2163         }
2164     } else {
2165         Frame* targetFrame;
2166         if (targetIsFrame(newTarget.get(), targetFrame)) {
2167             if (targetFrame)
2168                 accept = targetFrame->eventHandler()->updateDragAndDrop(event, clipboard);
2169         } else if (newTarget) {
2170             // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
2171             if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
2172                 // for now we don't care if event handler cancels default behavior, since there is none
2173                 dispatchDragSrcEvent(eventNames().dragEvent, event);
2174             }
2175             accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget.get(), event, clipboard);
2176             if (!accept)
2177                 accept = findDropZone(newTarget.get(), clipboard);
2178             m_shouldOnlyFireDragOverEvent = false;
2179         }
2180     }
2181     m_dragTarget = newTarget;
2182
2183     return accept;
2184 }
2185
2186 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
2187 {
2188     Frame* targetFrame;
2189     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2190         if (targetFrame)
2191             targetFrame->eventHandler()->cancelDragAndDrop(event, clipboard);
2192     } else if (m_dragTarget.get()) {
2193         if (dragState().m_dragSrc && dragState().shouldDispatchEvents())
2194             dispatchDragSrcEvent(eventNames().dragEvent, event);
2195         dispatchDragEvent(eventNames().dragleaveEvent, m_dragTarget.get(), event, clipboard);
2196     }
2197     clearDragState();
2198 }
2199
2200 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
2201 {
2202     Frame* targetFrame;
2203     bool preventedDefault = false;
2204     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
2205         if (targetFrame)
2206             preventedDefault = targetFrame->eventHandler()->performDragAndDrop(event, clipboard);
2207     } else if (m_dragTarget.get())
2208         preventedDefault = dispatchDragEvent(eventNames().dropEvent, m_dragTarget.get(), event, clipboard);
2209     clearDragState();
2210     return preventedDefault;
2211 }
2212
2213 void EventHandler::clearDragState()
2214 {
2215     m_dragTarget = 0;
2216     m_capturingMouseEventsNode = 0;
2217     m_shouldOnlyFireDragOverEvent = false;
2218 #if PLATFORM(MAC)
2219     m_sendingEventToSubview = false;
2220 #endif
2221 }
2222 #endif // ENABLE(DRAG_SUPPORT)
2223
2224 void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n)
2225 {
2226     m_capturingMouseEventsNode = n;
2227     m_eventHandlerWillResetCapturingMouseEventsNode = false;
2228 }
2229
2230 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mev)
2231 {
2232     ASSERT(m_frame);
2233     ASSERT(m_frame->document());
2234     
2235     return m_frame->document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mev.position()), mev);
2236 }
2237
2238 #if ENABLE(SVG)
2239 static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode)
2240 {
2241     if (!referenceNode || !referenceNode->isSVGElement())
2242         return 0;
2243
2244     ShadowRoot* shadowRoot = referenceNode->containingShadowRoot();
2245     if (!shadowRoot)
2246         return 0;
2247
2248     Element* shadowTreeParentElement = shadowRoot->host();
2249     if (!shadowTreeParentElement || !shadowTreeParentElement->hasTagName(useTag))
2250         return 0;
2251
2252     return static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);
2253 }
2254 #endif
2255
2256 void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut)
2257 {
2258     Node* result = targetNode;
2259     
2260     // If we're capturing, we always go right to that node.
2261     if (m_capturingMouseEventsNode)
2262         result = m_capturingMouseEventsNode.get();
2263     else {
2264         // If the target node is a text node, dispatch on the parent node - rdar://4196646
2265         if (result && result->isTextNode()) {
2266             AncestorChainWalker walker(result);
2267             walker.parent();
2268             result = walker.get();
2269         }
2270     }
2271     m_nodeUnderMouse = result;
2272 #if ENABLE(SVG)
2273     m_instanceUnderMouse = instanceAssociatedWithShadowTreeElement(result);
2274
2275     // <use> shadow tree elements may have been recloned, update node under mouse in any case
2276     if (m_lastInstanceUnderMouse) {
2277         SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();
2278         SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();
2279
2280         if (lastCorrespondingElement && lastCorrespondingUseElement) {
2281             HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();
2282
2283             // Locate the recloned shadow tree element for our corresponding instance
2284             HashSet<SVGElementInstance*>::iterator end = instances.end();
2285             for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {
2286                 SVGElementInstance* instance = (*it);
2287                 ASSERT(instance->correspondingElement() == lastCorrespondingElement);
2288
2289                 if (instance == m_lastInstanceUnderMouse)
2290                     continue;
2291
2292                 if (instance->correspondingUseElement() != lastCorrespondingUseElement)
2293                     continue;
2294
2295                 SVGElement* shadowTreeElement = instance->shadowTreeElement();
2296                 if (!shadowTreeElement->inDocument() || m_lastNodeUnderMouse == shadowTreeElement)
2297                     continue;
2298
2299                 m_lastNodeUnderMouse = shadowTreeElement;
2300                 m_lastInstanceUnderMouse = instance;
2301                 break;
2302             }
2303         }
2304     }
2305 #endif
2306
2307     // Fire mouseout/mouseover if the mouse has shifted to a different node.
2308     if (fireMouseOverOut) {
2309         RenderLayer* layerForLastNode = layerForNode(m_lastNodeUnderMouse.get());
2310         RenderLayer* layerForNodeUnderMouse = layerForNode(m_nodeUnderMouse.get());
2311         Page* page = m_frame->page();
2312
2313         if (m_lastNodeUnderMouse && (!m_nodeUnderMouse || m_nodeUnderMouse->document() != m_frame->document())) {
2314             // The mouse has moved between frames.
2315             if (Frame* frame = m_lastNodeUnderMouse->document()->frame()) {
2316                 if (FrameView* frameView = frame->view())
2317                     frameView->mouseExitedContentArea();
2318             }
2319         } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
2320             // The mouse has moved between layers.
2321             if (Frame* frame = m_lastNodeUnderMouse->document()->frame()) {
2322                 if (FrameView* frameView = frame->view()) {
2323                     if (frameView->containsScrollableArea(layerForLastNode))
2324                         layerForLastNode->mouseExitedContentArea();
2325                 }
2326             }
2327         }
2328
2329         if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
2330             // The mouse has moved between frames.
2331             if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
2332                 if (FrameView* frameView = frame->view())
2333                     frameView->mouseEnteredContentArea();
2334             }
2335         } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
2336             // The mouse has moved between layers.
2337             if (Frame* frame = m_nodeUnderMouse->document()->frame()) {
2338                 if (FrameView* frameView = frame->view()) {
2339                     if (frameView->containsScrollableArea(layerForNodeUnderMouse))
2340                         layerForNodeUnderMouse->mouseEnteredContentArea();
2341                 }
2342             }
2343         }
2344
2345         if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
2346             m_lastNodeUnderMouse = 0;
2347             m_lastScrollbarUnderMouse = 0;
2348 #if ENABLE(SVG)
2349             m_lastInstanceUnderMouse = 0;
2350 #endif
2351         }
2352
2353         if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
2354             // send mouseout event to the old node
2355             if (m_lastNodeUnderMouse)
2356                 m_lastNodeUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoutEvent, 0, m_nodeUnderMouse.get());
2357             // send mouseover event to the new node
2358             if (m_nodeUnderMouse)
2359                 m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventNames().mouseoverEvent, 0, m_lastNodeUnderMouse.get());
2360         }
2361         m_lastNodeUnderMouse = m_nodeUnderMouse;
2362 #if ENABLE(SVG)
2363         m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_nodeUnderMouse.get());
2364 #endif
2365     }
2366 }
2367
2368 bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
2369 {
2370     if (FrameView* view = m_frame->view())
2371         view->resetDeferredRepaintDelay();
2372
2373     updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
2374
2375     bool swallowEvent = false;
2376
2377     if (m_nodeUnderMouse)
2378         swallowEvent = !(m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount));
2379
2380     if (!swallowEvent && eventType == eventNames().mousedownEvent) {
2381
2382         // If clicking on a frame scrollbar, do not mess up with content focus.
2383         if (FrameView* view = m_frame->view()) {
2384             if (view->scrollbarAtPoint(mouseEvent.position()))
2385                 return true;
2386         }
2387
2388         // The layout needs to be up to date to determine if an element is focusable.
2389         m_frame->document()->updateLayoutIgnorePendingStylesheets();
2390
2391         // Blur current focus node when a link/button is clicked; this
2392         // is expected by some sites that rely on onChange handlers running
2393         // from form fields before the button click is processed.
2394         Node* node = m_nodeUnderMouse.get();
2395
2396         // Walk up the DOM tree to search for a node to focus.
2397         while (node) {
2398             if (node->isMouseFocusable()) {
2399                 // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus a
2400                 // node on mouse down if it's selected and inside a focused node. It will be
2401                 // focused if the user does a mouseup over it, however, because the mouseup
2402                 // will set a selection inside it, which will call setFocuseNodeIfNeeded.
2403                 ExceptionCode ec = 0;
2404                 Node* n = node->isShadowRoot() ? toShadowRoot(node)->host() : node;
2405                 if (m_frame->selection()->isRange()
2406                     && m_frame->selection()->toNormalizedRange()->compareNode(n, ec) == Range::NODE_INSIDE
2407                     && n->isDescendantOf(m_frame->document()->focusedNode()))
2408                     return true;
2409                     
2410                 break;
2411             }
2412             node = node->parentOrHostNode();
2413         }
2414
2415         // Only change the focus when clicking scrollbars if it can transfered to a mouse focusable node.
2416         if ((!node || !node->isMouseFocusable()) && isInsideScrollbar(mouseEvent.position()))
2417             return false;
2418
2419         // If focus shift is blocked, we eat the event.  Note we should never clear swallowEvent
2420         // if the page already set it (e.g., by canceling default behavior).
2421         if (Page* page = m_frame->page()) {
2422             if (node && node->isMouseFocusable()) {
2423                 if (!page->focusController()->setFocusedNode(node, m_frame))
2424                     swallowEvent = true;
2425             } else if (!node || !node->focused()) {
2426                 if (!page->focusController()->setFocusedNode(0, m_frame))
2427                     swallowEvent = true;
2428             }
2429         }
2430     }
2431
2432     return !swallowEvent;
2433 }
2434
2435 bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
2436 {
2437     if (RenderView* renderView = m_frame->contentRenderer()) {
2438         HitTestRequest request(HitTestRequest::ReadOnly);
2439         HitTestResult result(windowPoint);
2440         renderView->hitTest(request, result);
2441         return result.scrollbar();
2442     }
2443
2444     return false;
2445 }
2446
2447 #if !PLATFORM(GTK) && !(PLATFORM(CHROMIUM) && (OS(UNIX) && !OS(DARWIN)))
2448 bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const
2449 {
2450     return false;
2451 }
2452 #endif
2453
2454 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
2455 {
2456     Document* doc = m_frame->document();
2457
2458     RenderObject* docRenderer = doc->renderer();
2459     if (!docRenderer)
2460         return false;
2461     
2462     RefPtr<FrameView> protector(m_frame->view());
2463
2464     FrameView* view = m_frame->view();
2465     if (!view)
2466         return false;
2467     setFrameWasScrolledByUser();
2468     LayoutPoint vPoint = view->windowToContents(e.position());
2469
2470     Node* node;
2471     bool isOverWidget;
2472
2473     HitTestRequest request(HitTestRequest::ReadOnly);
2474     HitTestResult result(vPoint);
2475     doc->renderView()->hitTest(request, result);
2476
2477     bool useLatchedWheelEventNode = e.useLatchedEventNode();
2478
2479     if (useLatchedWheelEventNode) {
2480         if (!m_latchedWheelEventNode) {
2481             m_latchedWheelEventNode = closestScrollableNodeInDocumentIfPossible(result.innerNode());
2482             m_widgetIsLatched = result.isOverWidget();
2483         }
2484
2485         node = m_latchedWheelEventNode.get();
2486         isOverWidget = m_widgetIsLatched;
2487     } else {
2488         if (m_latchedWheelEventNode)
2489             m_latchedWheelEventNode = 0;
2490         if (m_previousWheelScrolledNode)
2491             m_previousWheelScrolledNode = 0;
2492
2493         node = result.innerNode();
2494         isOverWidget = result.isOverWidget();
2495     }
2496
2497     // FIXME: It should not be necessary to do this mutation here.
2498     // Instead, the handlers should know convert vertical scrolls
2499     // appropriately.
2500     PlatformWheelEvent event = e;
2501     if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, e))
2502         event = event.copyTurningVerticalTicksIntoHorizontalTicks();
2503
2504     if (node) {
2505         // Figure out which view to send the event to.
2506         RenderObject* target = node->renderer();
2507         
2508         if (isOverWidget && target && target->isWidget()) {
2509             Widget* widget = toRenderWidget(target)->widget();
2510             if (widget && passWheelEventToWidget(e, widget))
2511                 return true;
2512         }
2513
2514         if (node && !node->dispatchWheelEvent(event))
2515             return true;
2516     }
2517
2518
2519     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
2520     view = m_frame->view();
2521     if (!view)
2522         return false;
2523     
2524     return view->wheelEvent(event);
2525 }
2526
2527 void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
2528 {
2529     if (!startNode || !wheelEvent)
2530         return;
2531     
2532     Node* stopNode = m_previousWheelScrolledNode.get();
2533     ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->granularity());
2534     
2535     // Break up into two scrolls if we need to.  Diagonal movement on 
2536     // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
2537     if (scrollNode(wheelEvent->rawDeltaX(), granularity, ScrollLeft, ScrollRight, startNode, &stopNode))
2538         wheelEvent->setDefaultHandled();
2539     
2540     if (scrollNode(wheelEvent->rawDeltaY(), granularity, ScrollUp, ScrollDown, startNode, &stopNode))
2541         wheelEvent->setDefaultHandled();
2542     
2543     if (!m_latchedWheelEventNode)
2544         m_previousWheelScrolledNode = stopNode;
2545 }
2546
2547 #if ENABLE(GESTURE_EVENTS)
2548 bool EventHandler::handleGestureTapDown()
2549 {
2550     FrameView* view = m_frame->view();
2551     if (!view)
2552         return false;
2553     if (ScrollAnimator* scrollAnimator = view->existingScrollAnimator())
2554         scrollAnimator->cancelAnimations();
2555     const FrameView::ScrollableAreaSet* areas = view->scrollableAreas();
2556     if (!areas)
2557         return false;
2558     for (FrameView::ScrollableAreaSet::const_iterator it = areas->begin(); it != areas->end(); ++it) {
2559         ScrollableArea* sa = *it;
2560         ScrollAnimator* animator = sa->scrollAnimator();
2561         if (animator)
2562             animator->cancelAnimations();
2563     }
2564     return false;
2565 }
2566
2567 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
2568 {
2569     // We don't use DoubleTap at the moment, it's mostly redundant with tap since tap now contains
2570     // a tap count. FIXME: We should probably remove GestureDoubleTap (http://wkb.ug/93045).
2571     if (gestureEvent.type() == PlatformEvent::GestureDoubleTap)
2572         return false;
2573
2574     Node* eventTarget = 0;
2575     Scrollbar* scrollbar = 0;
2576     if (gestureEvent.type() == PlatformEvent::GestureScrollEnd || gestureEvent.type() == PlatformEvent::GestureScrollUpdate) {
2577         scrollbar = m_scrollbarHandlingScrollGesture.get();
2578         eventTarget = m_scrollGestureHandlingNode.get();
2579     }
2580
2581     IntPoint adjustedPoint = gestureEvent.position();
2582     HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
2583     if (gestureEvent.type() == PlatformEvent::GestureTapDown) {
2584 #if ENABLE(TOUCH_ADJUSTMENT)
2585         adjustGesturePosition(gestureEvent, adjustedPoint);
2586 #endif
2587         hitType |= HitTestRequest::Active;
2588     } else if (gestureEvent.type() == PlatformEvent::GestureTap || gestureEvent.type() == PlatformEvent::GestureTapDownCancel)
2589         hitType |= HitTestRequest::Release;
2590     else
2591         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
2592
2593     if (!shouldGesturesTriggerActive())
2594         hitType |= HitTestRequest::ReadOnly;
2595
2596     if ((!scrollbar && !eventTarget) || !(hitType & HitTestRequest::ReadOnly)) {
2597         IntPoint hitTestPoint = m_frame->view()->windowToContents(adjustedPoint);
2598         HitTestResult result = hitTestResultAtPoint(hitTestPoint, false, false, ShouldHitTestScrollbars, hitType);
2599         eventTarget = result.targetNode();
2600         if (!scrollbar) {
2601             FrameView* view = m_frame->view();
2602             scrollbar = view ? view->scrollbarAtPoint(gestureEvent.position()) : 0;
2603         }
2604         if (!scrollbar)
2605             scrollbar = result.scrollbar();
2606     }
2607
2608     if (scrollbar) {
2609         bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
2610         if (gestureEvent.type() == PlatformEvent::GestureScrollBegin && eventSwallowed)
2611             m_scrollbarHandlingScrollGesture = scrollbar;
2612         else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd || !eventSwallowed)
2613             m_scrollbarHandlingScrollGesture = 0;
2614
2615         if (eventSwallowed)
2616             return true;
2617     }
2618
2619     if (eventTarget) {
2620         bool eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
2621
2622         if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
2623             if (eventSwallowed)
2624                 m_scrollGestureHandlingNode = eventTarget;
2625             else
2626                 m_scrollGestureHandlingNode = 0;
2627         }
2628
2629         if (eventSwallowed)
2630             return true;
2631     }
2632
2633     // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi?id=80596) will
2634     // eliminate the need for this.
2635     TemporaryChange<PlatformEvent::Type> baseEventType(m_baseEventType, gestureEvent.type());
2636
2637     switch (gestureEvent.type()) {
2638     case PlatformEvent::GestureScrollBegin:
2639         return handleGestureScrollCore(gestureEvent, ScrollByPixelWheelEvent, false);
2640     case PlatformEvent::GestureScrollUpdate:
2641         return handleGestureScrollUpdate(gestureEvent);
2642     case PlatformEvent::GestureTap:
2643         return handleGestureTap(gestureEvent);
2644     case PlatformEvent::GestureTapDown:
2645         return handleGestureTapDown();
2646     case PlatformEvent::GestureLongPress:
2647         return handleGestureLongPress(gestureEvent);
2648     case PlatformEvent::GestureLongTap:
2649         return handleGestureLongTap(gestureEvent);
2650     case PlatformEvent::GestureTwoFingerTap:
2651         return handleGestureTwoFingerTap(gestureEvent);
2652     case PlatformEvent::GestureScrollEnd:
2653     case PlatformEvent::GestureDoubleTap:
2654     case PlatformEvent::GesturePinchBegin:
2655     case PlatformEvent::GesturePinchEnd:
2656     case PlatformEvent::GesturePinchUpdate:
2657     case PlatformEvent::GestureTapDownCancel:
2658         break;
2659     default:
2660         ASSERT_NOT_REACHED();
2661     }
2662
2663     return false;
2664 }
2665
2666 bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent)
2667 {
2668     // 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.
2669     IntPoint adjustedPoint = gestureEvent.position();
2670 #if ENABLE(TOUCH_ADJUSTMENT)
2671     adjustGesturePosition(gestureEvent, adjustedPoint);
2672 #endif
2673
2674     PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition(),
2675         NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
2676         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2677     mouseMoved(fakeMouseMove);
2678
2679     int tapCount = 1;
2680     // FIXME: deletaX is overloaded to mean different things for different gestures.
2681     // http://wkb.ug/93123
2682     if (gestureEvent.deltaX() > 0)
2683         tapCount = static_cast<int>(gestureEvent.deltaX());
2684
2685     bool defaultPrevented = false;
2686     PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition(),
2687         LeftButton, PlatformEvent::MousePressed, tapCount,
2688         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2689     defaultPrevented |= handleMousePressEvent(fakeMouseDown);
2690
2691     PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(),
2692         LeftButton, PlatformEvent::MouseReleased, tapCount,
2693         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2694     defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp);
2695
2696     return defaultPrevented;
2697 }
2698
2699 bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEvent)
2700 {
2701 #if ENABLE(DRAG_SUPPORT)
2702     if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled()) {
2703         IntPoint adjustedPoint = gestureEvent.position();
2704 #if ENABLE(TOUCH_ADJUSTMENT)
2705         adjustGesturePosition(gestureEvent, adjustedPoint);
2706 #endif
2707         PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 0, false, false, false, false, WTF::currentTime());
2708         handleMousePressEvent(mouseDownEvent);
2709         PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, WTF::currentTime());
2710         HitTestRequest request(HitTestRequest::ReadOnly);
2711         MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragEvent);
2712         m_didStartDrag = false;
2713         handleDrag(mev, DontCheckDragHysteresis);
2714         if (m_didStartDrag)
2715             return true;
2716     }
2717 #endif
2718     return handleGestureForTextSelectionOrContextMenu(gestureEvent);
2719 }
2720
2721 bool EventHandler::handleGestureLongTap(const PlatformGestureEvent& gestureEvent)
2722 {
2723 #if ENABLE(CONTEXT_MENUS) && !OS(ANDROID)
2724     if (!m_didLongPressInvokeContextMenu)
2725         return sendContextMenuEventForGesture(gestureEvent);
2726 #endif
2727     return false;
2728 }
2729
2730 bool EventHandler::handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent& gestureEvent)
2731 {
2732 #if OS(ANDROID)
2733     IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.position());
2734     HitTestResult result = hitTestResultAtPoint(hitTestPoint, true);
2735     Node* innerNode = result.targetNode();
2736     if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
2737         selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitespace);
2738         if (m_frame->selection()->isRange())
2739             return true;
2740     }
2741 #endif
2742 #if ENABLE(CONTEXT_MENUS)
2743     m_didLongPressInvokeContextMenu = (gestureEvent.type() == PlatformEvent::GestureLongPress);
2744     return sendContextMenuEventForGesture(gestureEvent);
2745 #else
2746     return false;
2747 #endif
2748 }
2749
2750 bool EventHandler::handleGestureTwoFingerTap(const PlatformGestureEvent& gestureEvent)
2751 {
2752     return handleGestureForTextSelectionOrContextMenu(gestureEvent);
2753 }
2754
2755 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
2756 {
2757     return handleGestureScrollCore(gestureEvent, ScrollByPixelWheelEvent, true);
2758 }
2759
2760 bool EventHandler::isScrollbarHandlingGestures() const
2761 {
2762     return m_scrollbarHandlingScrollGesture.get();
2763 }
2764
2765 bool EventHandler::handleGestureScrollCore(const PlatformGestureEvent& gestureEvent, PlatformWheelEventGranularity granularity, bool latchedWheel)
2766 {
2767     const float tickDivisor = (float)WheelEvent::tickMultiplier;
2768     IntPoint point(gestureEvent.position().x(), gestureEvent.position().y());
2769     IntPoint globalPoint(gestureEvent.globalPosition().x(), gestureEvent.globalPosition().y());
2770     PlatformWheelEvent syntheticWheelEvent(point, globalPoint,
2771         gestureEvent.deltaX(), gestureEvent.deltaY(), gestureEvent.deltaX() / tickDivisor, gestureEvent.deltaY() / tickDivisor,
2772         granularity,
2773         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
2774     syntheticWheelEvent.setUseLatchedEventNode(latchedWheel);
2775     return handleWheelEvent(syntheticWheelEvent);
2776 }
2777 #endif
2778
2779 #if ENABLE(TOUCH_ADJUSTMENT)
2780 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const
2781 {
2782     if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled())
2783         return false;
2784     return !event.area().isEmpty();
2785 }
2786
2787
2788 bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
2789 {
2790     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
2791     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2792     HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
2793
2794     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2795     RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
2796
2797     // FIXME: Should be able to handle targetNode being a shadow DOM node to avoid performing uncessary hit tests
2798     // in the case where further processing on the node is required. Returning the shadow ancestor prevents a
2799     // regression in touchadjustment/html-label.html. Some refinement is required to testing/internals to
2800     // handle targetNode being a shadow DOM node. 
2801     bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, *nodeList.get());
2802     if (success && targetNode)
2803         targetNode = targetNode->shadowAncestorNode();
2804     return success;
2805 }
2806
2807 bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
2808 {
2809     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
2810     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2811     HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
2812
2813     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2814     RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
2815     return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, *nodeList.get());
2816 }
2817
2818 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
2819 {
2820     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
2821     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2822     HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ false, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
2823
2824     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2825     RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
2826     return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, *nodeList.get());
2827 }
2828
2829 bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
2830 {
2831     if (!shouldApplyTouchAdjustment(gestureEvent))
2832         return false;
2833
2834     Node* targetNode = 0;
2835     switch (gestureEvent.type()) {
2836     case PlatformEvent::GestureTap:
2837     case PlatformEvent::GestureTapDown:
2838         bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
2839         break;
2840     case PlatformEvent::GestureLongPress:
2841     case PlatformEvent::GestureLongTap:
2842     case PlatformEvent::GestureTwoFingerTap:
2843         bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
2844         break;
2845     default:
2846         // FIXME: Implement handling for other types as needed.
2847         ASSERT_NOT_REACHED();
2848     }
2849     return targetNode;
2850 }
2851 #endif
2852
2853 #if ENABLE(CONTEXT_MENUS)
2854 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2855 {
2856     Document* doc = m_frame->document();
2857     FrameView* v = m_frame->view();
2858     if (!v)
2859         return false;
2860     
2861     // Clear mouse press state to avoid initiating a drag while context menu is up.
2862     m_mousePressed = false;
2863     bool swallowEvent;
2864     LayoutPoint viewportPos = v->windowToContents(event.position());
2865     HitTestRequest request(HitTestRequest::Active);
2866     MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
2867
2868     if (m_frame->editor()->behavior().shouldSelectOnContextualMenuClick()
2869         && !m_frame->selection()->contains(viewportPos)
2870         && !mev.scrollbar()
2871         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
2872         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
2873         // available for text selections.  But only if we're above text.
2874         && (m_frame->selection()->isContentEditable() || (mev.targetNode() && mev.targetNode()->isTextNode()))) {
2875         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
2876         selectClosestWordOrLinkFromMouseEvent(mev);
2877     }
2878
2879     swallowEvent = !dispatchMouseEvent(eventNames().contextmenuEvent, mev.targetNode(), true, 0, event, false);
2880     
2881     return swallowEvent;
2882 }
2883
2884 bool EventHandler::sendContextMenuEventForKey()
2885 {
2886     FrameView* view = m_frame->view();
2887     if (!view)
2888         return false;
2889
2890     Document* doc = m_frame->document();
2891     if (!doc)
2892         return false;
2893
2894     // Clear mouse press state to avoid initiating a drag while context menu is up.
2895     m_mousePressed = false;
2896
2897     static const int kContextMenuMargin = 1;
2898
2899 #if OS(WINDOWS) && !OS(WINCE)
2900     int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
2901 #else
2902     int rightAligned = 0;
2903 #endif
2904     IntPoint location;
2905
2906     Node* focusedNode = doc->focusedNode();
2907     FrameSelection* selection = m_frame->selection();
2908     Position start = selection->selection().start();
2909
2910     if (start.deprecatedNode() && (selection->rootEditableElement() || selection->isRange())) {
2911         RefPtr<Range> selectionRange = selection->toNormalizedRange();
2912         IntRect firstRect = m_frame->editor()->firstRectForRange(selectionRange.get());
2913
2914         int x = rightAligned ? firstRect.maxX() : firstRect.x();
2915         // In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
2916         int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
2917         location = IntPoint(x, y);
2918     } else if (focusedNode) {
2919         RenderBoxModelObject* box = focusedNode->renderBoxModelObject();
2920         if (!box)
2921             return false;
2922         IntRect clippedRect = box->pixelSnappedAbsoluteClippedOverflowRect();
2923         location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1);
2924     } else {
2925         location = IntPoint(
2926             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
2927             kContextMenuMargin);
2928     }
2929
2930     m_frame->view()->setCursor(pointerCursor());
2931
2932     IntPoint position = view->contentsToRootView(location);
2933     IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
2934
2935     Node* targetNode = doc->focusedNode();
2936     if (!targetNode)
2937         targetNode = doc;
2938
2939     // Use the focused node as the target for hover and active.
2940     HitTestResult result(position);
2941     result.setInnerNode(targetNode);
2942     HitTestRequest request(HitTestRequest::Active);
2943     doc->updateHoverActiveState(request, result);
2944     doc->updateStyleIfNeeded();
2945    
2946     // The contextmenu event is a mouse event even when invoked using the keyboard.
2947     // This is required for web compatibility.
2948
2949 #if OS(WINDOWS)
2950     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2951 #else
2952     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2953 #endif
2954
2955     PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
2956
2957     return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, mouseEvent, false);
2958 }
2959
2960 #if ENABLE(GESTURE_EVENTS)
2961 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& event)
2962 {
2963 #if OS(WINDOWS)
2964     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2965 #else
2966     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2967 #endif
2968
2969     IntPoint adjustedPoint = event.position();
2970 #if ENABLE(TOUCH_ADJUSTMENT)
2971     adjustGesturePosition(event, adjustedPoint);
2972 #endif
2973     PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
2974     // To simulate right-click behavior, we send a right mouse down and then
2975     // context menu event.
2976     handleMousePressEvent(mouseEvent);
2977     return sendContextMenuEvent(mouseEvent);
2978     // We do not need to send a corresponding mouse release because in case of
2979     // right-click, the context menu takes capture and consumes all events.
2980 }
2981 #endif // ENABLE(GESTURE_EVENTS)
2982 #endif // ENABLE(CONTEXT_MENUS)
2983
2984 void EventHandler::scheduleHoverStateUpdate()
2985 {
2986     if (!m_hoverTimer.isActive())
2987         m_hoverTimer.startOneShot(0);
2988 }
2989
2990 void EventHandler::dispatchFakeMouseMoveEventSoon()
2991 {
2992     if (m_mousePressed)
2993         return;
2994
2995     if (m_mousePositionIsUnknown)
2996         return;
2997
2998     Settings* settings = m_frame->settings();
2999     if (settings && !settings->deviceSupportsMouse())
3000         return;
3001
3002     // If the content has ever taken longer than fakeMouseMoveShortInterval we
3003     // reschedule the timer and use a longer time. This will cause the content
3004     // to receive these moves only after the user is done scrolling, reducing
3005     // pauses during the scroll.
3006     if (m_maxMouseMovedDuration > fakeMouseMoveShortInterval) {
3007         if (m_fakeMouseMoveEventTimer.isActive())
3008             m_fakeMouseMoveEventTimer.stop();
3009         m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval);
3010     } else {
3011         if (!m_fakeMouseMoveEventTimer.isActive())
3012             m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval);
3013     }
3014 }
3015
3016 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
3017 {
3018     FrameView* view = m_frame->view();
3019     if (!view)
3020         return;
3021
3022     if (!quad.containsPoint(view->windowToContents(m_lastKnownMousePosition)))
3023         return;
3024
3025     dispatchFakeMouseMoveEventSoon();
3026 }
3027
3028 void EventHandler::cancelFakeMouseMoveEvent()
3029 {
3030     m_fakeMouseMoveEventTimer.stop();
3031 }
3032
3033 void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>* timer)
3034 {
3035     ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer);
3036     ASSERT(!m_mousePressed);
3037
3038     Settings* settings = m_frame->settings();
3039     if (settings && !settings->deviceSupportsMouse())
3040         return;
3041
3042     FrameView* view = m_frame->view();
3043     if (!view)
3044         return;
3045
3046     if (!m_frame->page() || !m_frame->page()->isOnscreen() || !m_frame->page()->focusController()->isActive())
3047         return;
3048
3049     bool shiftKey;
3050     bool ctrlKey;
3051     bool altKey;
3052     bool metaKey;
3053     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
3054     PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
3055     mouseMoved(fakeMouseMoveEvent);
3056 }
3057
3058 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
3059 {
3060     m_frameSetBeingResized = frameSet;
3061 }
3062
3063 void EventHandler::resizeLayerDestroyed()
3064 {
3065     ASSERT(m_resizeLayer);
3066     m_resizeLayer = 0;
3067 }
3068
3069 void EventHandler::hoverTimerFired(Timer<EventHandler>*)
3070 {
3071     m_hoverTimer.stop();
3072
3073     ASSERT(m_frame);
3074     ASSERT(m_frame->document());
3075
3076     if (RenderView* renderer = m_frame->contentRenderer()) {
3077         if (FrameView* view = m_frame->view()) {
3078             HitTestRequest request(HitTestRequest::Move);
3079             HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
3080             renderer->hitTest(request, result);
3081             m_frame->document()->updateStyleIfNeeded();
3082         }
3083     }
3084 }
3085
3086 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
3087 {
3088     // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
3089     // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
3090     // lower case variants are present in a document, the correct element is matched based on Shift key state.
3091     // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
3092     ASSERT(!(accessKeyModifiers() & PlatformEvent::ShiftKey));
3093     if ((evt.modifiers() & ~PlatformEvent::ShiftKey) != accessKeyModifiers())
3094         return false;
3095     String key = evt.unmodifiedText();
3096     Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
3097     if (!elem)
3098         return false;
3099     elem->accessKeyAction(false);
3100     return true;
3101 }
3102
3103 #if !PLATFORM(MAC)
3104 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
3105 {
3106     return false;
3107 }
3108 #endif
3109
3110 #if ENABLE(FULLSCREEN_API)
3111 bool EventHandler::isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent& keyEvent) const
3112 {
3113     Document* document = m_frame->document();
3114     if (document->webkitFullScreenKeyboardInputAllowed())
3115         return true;
3116
3117     if (keyEvent.type() == PlatformKeyboardEvent::Char) {
3118         if (keyEvent.text().length() != 1)
3119             return false;
3120         UChar character = keyEvent.text()[0];
3121         return character == ' ';
3122     }
3123
3124     int keyCode = keyEvent.windowsVirtualKeyCode();
3125     return (keyCode >= VK_BACK && keyCode <= VK_CAPITAL)
3126         || (keyCode >= VK_SPACE && keyCode <= VK_DELETE)
3127         || (keyCode >= VK_OEM_1 && keyCode <= VK_OEM_PLUS)
3128         || (keyCode >= VK_MULTIPLY && keyCode <= VK_OEM_8);
3129 }
3130 #endif
3131
3132 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
3133 {
3134     RefPtr<FrameView> protector(m_frame->view()); 
3135
3136 #if ENABLE(FULLSCREEN_API)
3137     if (m_frame->document()->webkitIsFullScreen() && !isKeyEventAllowedInFullScreen(initialKeyEvent))
3138         return false;
3139 #endif
3140
3141     if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL)
3142         capsLockStateMayHaveChanged();
3143
3144 #if ENABLE(PAN_SCROLLING)
3145     if (Page* page = m_frame->page()) {
3146         if (page->mainFrame()->eventHandler()->m_panScrollInProgress) {
3147             // If a key is pressed while the panScroll is in progress then we want to stop
3148             if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown) 
3149                 stopAutoscrollTimer();
3150
3151             // If we were in panscroll mode, we swallow the key event
3152             return true;
3153         }
3154     }
3155 #endif
3156
3157     // Check for cases where we are too early for events -- possible unmatched key up
3158     // from pressing return in the location bar.
3159     RefPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
3160     if (!node)
3161         return false;
3162
3163     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
3164     UserTypingGestureIndicator typingGestureIndicator(m_frame);
3165
3166     if (FrameView* view = m_frame->view())
3167         view->resetDeferredRepaintDelay();
3168
3169     // FIXME (bug 68185): this call should be made at another abstraction layer
3170     m_frame->loader()->resetMultipleFormSubmissionProtection();
3171
3172     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
3173     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
3174     // with access keys. Then we dispatch keydown, but suppress its default handling.
3175     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
3176     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
3177     bool matchedAnAccessKey = false;
3178     if (initialKeyEvent.type() == PlatformEvent::KeyDown)
3179         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
3180
3181     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
3182     if (initialKeyEvent.type() == PlatformEvent::KeyUp || initialKeyEvent.type() == PlatformEvent::Char)
3183         return !node->dispatchKeyEvent(initialKeyEvent);
3184
3185     bool backwardCompatibilityMode = needsKeyboardEventDisambiguationQuirks();
3186
3187     ExceptionCode ec;
3188     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;    
3189     if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
3190         keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown, backwardCompatibilityMode);
3191     RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
3192     if (matchedAnAccessKey)
3193         keydown->setDefaultPrevented(true);
3194     keydown->setTarget(node);
3195
3196     if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
3197         node->dispatchEvent(keydown, ec);
3198         // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
3199         bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController()->focusedOrMainFrame();
3200         return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3201     }
3202
3203     // Run input method in advance of DOM event handling.  This may result in the IM
3204     // modifying the page prior the keydown event, but this behaviour is necessary
3205     // in order to match IE:
3206     // 1. preventing default handling of keydown and keypress events has no effect on IM input;
3207     // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
3208     m_frame->editor()->handleInputMethodKeydown(keydown.get());
3209     
3210     bool handledByInputMethod = keydown->defaultHandled();
3211     
3212     if (handledByInputMethod) {
3213         keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
3214         keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
3215         keydown->setTarget(node);
3216         keydown->setDefaultHandled();
3217     }
3218
3219     node->dispatchEvent(keydown, ec);
3220     // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
3221     bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController()->focusedOrMainFrame();
3222     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
3223     if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
3224         return keydownResult;
3225     
3226     // Focus may have changed during keydown handling, so refetch node.
3227     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original node.
3228     if (!keydownResult) {
3229         node = eventTargetNodeForDocument(m_frame->document());
3230         if (!node)
3231             return false;
3232     }
3233
3234     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
3235     keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char, backwardCompatibilityMode);
3236     if (keyPressEvent.text().isEmpty())
3237         return keydownResult;
3238     RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->defaultView());
3239     keypress->setTarget(node);
3240     if (keydownResult)
3241         keypress->setDefaultPrevented(true);
3242 #if PLATFORM(MAC)
3243     keypress->keypressCommands() = keydown->keypressCommands();
3244 #endif
3245     node->dispatchEvent(keypress, ec);
3246
3247     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
3248 }
3249
3250 static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
3251 {
3252     DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down", AtomicString::ConstructFromLiteral));
3253     DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up", AtomicString::ConstructFromLiteral));
3254     DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left", AtomicString::ConstructFromLiteral));
3255     DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right", AtomicString::ConstructFromLiteral));
3256
3257     FocusDirection retVal = FocusDirectionNone;
3258
3259     if (keyIdentifier == Down)
3260         retVal = FocusDirectionDown;
3261     else if (keyIdentifier == Up)
3262         retVal = FocusDirectionUp;
3263     else if (keyIdentifier == Left)
3264         retVal = FocusDirectionLeft;
3265     else if (keyIdentifier == Right)
3266         retVal = FocusDirectionRight;
3267
3268     return retVal;
3269 }
3270
3271 static void handleKeyboardSelectionMovement(FrameSelection* selection, KeyboardEvent* event)
3272 {
3273     if (!event)
3274         return;
3275
3276     bool isOptioned = event->getModifierState("Alt");
3277     bool isCommanded = event->getModifierState("Meta");
3278
3279     SelectionDirection direction = DirectionForward;
3280     TextGranularity granularity = CharacterGranularity;
3281
3282     switch (focusDirectionForKey(event->keyIdentifier())) {
3283     case FocusDirectionNone:
3284         return;
3285     case FocusDirectionForward:
3286     case FocusDirectionBackward:
3287         ASSERT_NOT_REACHED();
3288         return;
3289     case FocusDirectionUp:
3290         direction = DirectionBackward;
3291         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3292         break;
3293     case FocusDirectionDown:
3294         direction = DirectionForward;
3295         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3296         break;
3297     case FocusDirectionLeft:
3298         direction = DirectionLeft;
3299         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3300         break;
3301     case FocusDirectionRight:
3302         direction = DirectionRight;
3303         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3304         break;
3305     }
3306
3307     FrameSelection::EAlteration alternation = event->getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
3308     selection->modify(alternation, direction, granularity, UserTriggered);
3309     event->setDefaultHandled();
3310 }
3311     
3312 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
3313 {
3314     if (event->type() == eventNames().keydownEvent) {
3315         m_frame->editor()->handleKeyboardEvent(event);
3316         if (event->defaultHandled())
3317             return;
3318         if (event->keyIdentifier() == "U+0009")
3319             defaultTabEventHandler(event);
3320         else if (event->keyIdentifier() == "U+0008")
3321             defaultBackspaceEventHandler(event);
3322         else {
3323             FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
3324             if (direction != FocusDirectionNone)
3325                 defaultArrowEventHandler(direction, event);
3326         }
3327
3328         // provides KB navigation and selection for enhanced accessibility users
3329         if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3330             handleKeyboardSelectionMovement(m_frame->selection(), event);
3331     }
3332     if (event->type() == eventNames().keypressEvent) {
3333         m_frame->editor()->handleKeyboardEvent(event);
3334         if (event->defaultHandled())
3335             return;
3336         if (event->charCode() == ' ')
3337             defaultSpaceEventHandler(event);
3338     }
3339 }
3340
3341 #if ENABLE(DRAG_SUPPORT)
3342 bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocation) const
3343 {
3344     FloatPoint dragViewportLocation(floatDragViewportLocation.x(), floatDragViewportLocation.y());
3345     return dragHysteresisExceeded(dragViewportLocation);
3346 }
3347
3348 bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
3349 {
3350     FrameView* view = m_frame->view();
3351     if (!view)
3352         return false;
3353     IntPoint dragLocation = view->windowToContents(flooredIntPoint(dragViewportLocation));
3354     IntSize delta = dragLocation - m_mouseDownPos;
3355     
3356     int threshold = GeneralDragHysteresis;
3357     switch (dragState().m_dragType) {
3358     case DragSourceActionSelection:
3359         threshold = TextDragHysteresis;
3360         break;
3361     case DragSourceActionImage:
3362         threshold = ImageDragHysteresis;
3363         break;
3364     case DragSourceActionLink:
3365         threshold = LinkDragHysteresis;
3366         break;
3367     case DragSourceActionDHTML:
3368         break;
3369     case DragSourceActionNone:
3370     case DragSourceActionAny:
3371         ASSERT_NOT_REACHED();
3372     }
3373     
3374     return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold;
3375 }
3376     
3377 void EventHandler::freeClipboard()
3378 {
3379     if (dragState().m_dragClipboard)
3380         dragState().m_dragClipboard->setAccessPolicy(ClipboardNumb);
3381 }
3382
3383 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
3384 {
3385     // Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses.
3386     HitTestRequest request(HitTestRequest::Release);
3387     prepareMouseEvent(request, event);
3388
3389     if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
3390         dragState().m_dragClipboard->setDestinationOperation(operation);
3391         // for now we don't care if event handler cancels default behavior, since there is none
3392         dispatchDragSrcEvent(eventNames().dragendEvent, event);
3393     }
3394     freeClipboard();
3395     dragState().m_dragSrc = 0;
3396     // In case the drag was ended due to an escape key press we need to ensure
3397     // that consecutive mousemove events don't reinitiate the drag and drop.
3398     m_mouseDownMayStartDrag = false;
3399 }
3400
3401 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement)
3402 {
3403     // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element.
3404     if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument())
3405         dragState().m_dragSrc = rootEditableElement;
3406 }
3407
3408 // returns if we should continue "default processing", i.e., whether eventhandler canceled
3409 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
3410 {
3411     return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragClipboard.get());
3412 }
3413     
3414 static bool ExactlyOneBitSet(DragSourceAction n)
3415 {
3416     return n && !(n & (n - 1));
3417 }
3418
3419 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDragHysteresis checkDragHysteresis)
3420 {
3421     if (event.event().button() != LeftButton || event.event().type() != PlatformEvent::MouseMoved) {
3422         // If we allowed the other side of the bridge to handle a drag
3423         // last time, then m_mousePressed might still be set. So we
3424         // clear it now to make sure the next move after a drag
3425         // doesn't look like a drag.
3426         m_mousePressed = false;
3427         return false;
3428     }
3429     
3430     if (eventLoopHandleMouseDragged(event))
3431         return true;
3432     
3433     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
3434     
3435     if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
3436         dragState().m_eventDispatchPolicy = (updateDragSourceActionsAllowed() & DragSourceActionDHTML) ? DragState::DispatchEvents: DragState::DoNotDispatchEvents;
3437
3438         // try to find an element that wants to be dragged
3439         HitTestRequest request(HitTestRequest::ReadOnly);
3440         HitTestResult result(m_mouseDownPos);
3441         m_frame->contentRenderer()->hitTest(request, result);
3442         Node* node = result.innerNode();
3443         if (node && m_frame->page())
3444             dragState().m_dragSrc = m_frame->page()->dragController()->draggableNode(m_frame, node, m_mouseDownPos, dragState());
3445         else
3446             dragState().m_dragSrc = 0;
3447         
3448         if (!dragState().m_dragSrc)
3449             m_mouseDownMayStartDrag = false; // no element is draggable
3450         else
3451             m_dragMayStartSelectionInstead = (dragState().m_dragType & DragSourceActionSelection);
3452     }
3453     
3454     // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
3455     // or else we bail on the dragging stuff and allow selection to occur
3456     if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState().m_dragType & DragSourceActionSelection) && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
3457         ASSERT(event.event().type() == PlatformEvent::MouseMoved);
3458         if ((dragState().m_dragType & DragSourceActionImage)) {
3459             // ... unless the mouse is over an image, then we start dragging just the image
3460             dragState().m_dragType = DragSourceActionImage;
3461         } else if (!(dragState().m_dragType & (DragSourceActionDHTML | DragSourceActionLink))) {
3462             // ... but only bail if we're not over an unselectable element.
3463             m_mouseDownMayStartDrag = false;
3464             dragState().m_dragSrc = 0;
3465             // ... but if this was the first click in the window, we don't even want to start selection
3466             if (eventActivatedView(event.event()))
3467                 m_mouseDownMayStartSelect = false;
3468         } else {
3469             // Prevent the following case from occuring: