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