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