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