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