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