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