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