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