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