919f8e45cc4688a3a3932e9e9e89148f7bad5164
[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     HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
2418     if (gestureEvent.type() == PlatformEvent::GestureTapDown)
2419         hitType |= HitTestRequest::Active;
2420     else if (gestureEvent.type() == PlatformEvent::GestureTap || gestureEvent.type() == PlatformEvent::GestureTapDownCancel)
2421         hitType |= HitTestRequest::Release;
2422     else
2423         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
2424
2425     if (!shouldGesturesTriggerActive())
2426         hitType |= HitTestRequest::ReadOnly;
2427
2428     if (!eventTarget || !(hitType & HitTestRequest::ReadOnly)) {
2429         IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.position());
2430         HitTestResult result = hitTestResultAtPoint(hitTestPoint, false, false, DontHitTestScrollbars, hitType);
2431         eventTarget = result.targetNode();
2432     }
2433
2434     if (eventTarget) {
2435         bool eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
2436
2437         if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
2438             if (eventSwallowed)
2439                 m_scrollGestureHandlingNode = eventTarget;
2440             else
2441                 m_scrollGestureHandlingNode = 0;
2442         }
2443
2444         if (eventSwallowed)
2445             return true;
2446     }
2447
2448     // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi?id=80596) will
2449     // eliminate the need for this.
2450     TemporaryChange<PlatformEvent::Type> baseEventType(m_baseEventType, gestureEvent.type());
2451
2452     switch (gestureEvent.type()) {
2453     case PlatformEvent::GestureScrollBegin:
2454         return handleGestureScrollCore(gestureEvent, ScrollByPixelWheelEvent, false);
2455     case PlatformEvent::GestureScrollEnd:
2456         return handleGestureScrollCore(gestureEvent, ScrollByPixelVelocityWheelEvent, true);
2457     case PlatformEvent::GestureScrollUpdate:
2458         return handleGestureScrollUpdate(gestureEvent);
2459     case PlatformEvent::GestureTap:
2460         return handleGestureTap(gestureEvent);
2461     case PlatformEvent::GestureTapDown:
2462         return handleGestureTapDown();
2463     case PlatformEvent::GestureDoubleTap:
2464     case PlatformEvent::GestureLongPress:
2465     case PlatformEvent::GesturePinchBegin:
2466     case PlatformEvent::GesturePinchEnd:
2467     case PlatformEvent::GesturePinchUpdate:
2468     case PlatformEvent::GestureTapDownCancel:
2469         break;
2470     default:
2471         ASSERT_NOT_REACHED();
2472     }
2473
2474     return false;
2475 }
2476
2477 bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent)
2478 {
2479     // 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.
2480     IntPoint adjustedPoint = gestureEvent.position();
2481 #if ENABLE(TOUCH_ADJUSTMENT)
2482     if (!gestureEvent.area().isEmpty())
2483         adjustGesturePosition(gestureEvent, adjustedPoint);
2484 #endif
2485
2486     PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition(),
2487         NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
2488         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2489     mouseMoved(fakeMouseMove);
2490
2491     int tapCount = 1;
2492     // FIXME: deletaX is overloaded to mean different things for different gestures.
2493     // http://wkb.ug/93123
2494     if (gestureEvent.deltaX() > 0)
2495         tapCount = static_cast<int>(gestureEvent.deltaX());
2496
2497     bool defaultPrevented = false;
2498     PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition(),
2499         LeftButton, PlatformEvent::MousePressed, tapCount,
2500         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2501     defaultPrevented |= handleMousePressEvent(fakeMouseDown);
2502
2503     PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(),
2504         LeftButton, PlatformEvent::MouseReleased, tapCount,
2505         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
2506     defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp);
2507
2508     return defaultPrevented;
2509 }
2510
2511 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
2512 {
2513     return handleGestureScrollCore(gestureEvent, ScrollByPixelWheelEvent, true);
2514 }
2515
2516 bool EventHandler::handleGestureScrollCore(const PlatformGestureEvent& gestureEvent, PlatformWheelEventGranularity granularity, bool latchedWheel)
2517 {
2518     const float tickDivisor = (float)WheelEvent::tickMultiplier;
2519     IntPoint point(gestureEvent.position().x(), gestureEvent.position().y());
2520     IntPoint globalPoint(gestureEvent.globalPosition().x(), gestureEvent.globalPosition().y());
2521     PlatformWheelEvent syntheticWheelEvent(point, globalPoint,
2522         gestureEvent.deltaX(), gestureEvent.deltaY(), gestureEvent.deltaX() / tickDivisor, gestureEvent.deltaY() / tickDivisor,
2523         granularity,
2524         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
2525     syntheticWheelEvent.setUseLatchedEventNode(latchedWheel);
2526     return handleWheelEvent(syntheticWheelEvent);
2527 }
2528 #endif
2529
2530 #if ENABLE(TOUCH_ADJUSTMENT)
2531 bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
2532 {
2533     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
2534     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2535     HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
2536
2537     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2538     RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
2539
2540     // FIXME: Should be able to handle targetNode being a shadow DOM node to avoid performing uncessary hit tests
2541     // in the case where further processing on the node is required. Returning the shadow ancestor prevents a
2542     // regression in touchadjustment/html-label.html. Some refinement is required to testing/internals to
2543     // handle targetNode being a shadow DOM node. 
2544     bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, *nodeList.get());
2545     if (success && targetNode)
2546         targetNode = targetNode->shadowAncestorNode();
2547     return success;
2548 }
2549
2550 bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
2551 {
2552     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
2553     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2554     HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ true, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
2555
2556     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2557     RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
2558     return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, *nodeList.get());
2559 }
2560
2561 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
2562 {
2563     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
2564     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
2565     HitTestResult result = hitTestResultAtPoint(hitTestPoint, /*allowShadowContent*/ false, /*ignoreClipping*/ false, DontHitTestScrollbars, hitType, touchRadius);
2566
2567     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
2568     RefPtr<StaticHashSetNodeList> nodeList = StaticHashSetNodeList::adopt(result.rectBasedTestResult());
2569     return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, *nodeList.get());
2570 }
2571
2572 bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
2573 {
2574     Node* targetNode = 0;
2575     switch (gestureEvent.type()) {
2576     case PlatformEvent::GestureTap:
2577         bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
2578         break;
2579     case PlatformEvent::GestureLongPress:
2580         bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
2581         break;
2582     default:
2583         // FIXME: Implement handling for other types as needed.
2584         ASSERT_NOT_REACHED();
2585     }
2586     return targetNode;
2587 }
2588 #endif
2589
2590 #if ENABLE(CONTEXT_MENUS)
2591 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
2592 {
2593     Document* doc = m_frame->document();
2594     FrameView* v = m_frame->view();
2595     if (!v)
2596         return false;
2597     
2598     bool swallowEvent;
2599     LayoutPoint viewportPos = v->windowToContents(event.position());
2600     HitTestRequest request(HitTestRequest::Active);
2601     MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
2602
2603     if (m_frame->editor()->behavior().shouldSelectOnContextualMenuClick()
2604         && !m_frame->selection()->contains(viewportPos)
2605         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
2606         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
2607         // available for text selections.  But only if we're above text.
2608         && (m_frame->selection()->isContentEditable() || (mev.targetNode() && mev.targetNode()->isTextNode()))) {
2609         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
2610         selectClosestWordOrLinkFromMouseEvent(mev);
2611     }
2612
2613     swallowEvent = dispatchMouseEvent(eventNames().contextmenuEvent, mev.targetNode(), true, 0, event, false);
2614     
2615     return swallowEvent;
2616 }
2617
2618 bool EventHandler::sendContextMenuEventForKey()
2619 {
2620     FrameView* view = m_frame->view();
2621     if (!view)
2622         return false;
2623
2624     Document* doc = m_frame->document();
2625     if (!doc)
2626         return false;
2627
2628     static const int kContextMenuMargin = 1;
2629
2630 #if OS(WINDOWS) && !OS(WINCE)
2631     int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
2632 #else
2633     int rightAligned = 0;
2634 #endif
2635     IntPoint location;
2636
2637     Node* focusedNode = doc->focusedNode();
2638     FrameSelection* selection = m_frame->selection();
2639     Position start = selection->selection().start();
2640
2641     if (start.deprecatedNode() && (selection->rootEditableElement() || selection->isRange())) {
2642         RefPtr<Range> selectionRange = selection->toNormalizedRange();
2643         IntRect firstRect = m_frame->editor()->firstRectForRange(selectionRange.get());
2644
2645         int x = rightAligned ? firstRect.maxX() : firstRect.x();
2646         // In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
2647         int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
2648         location = IntPoint(x, y);
2649     } else if (focusedNode) {
2650         RenderBoxModelObject* box = focusedNode->renderBoxModelObject();
2651         if (!box)
2652             return false;
2653         IntRect clippedRect = box->pixelSnappedAbsoluteClippedOverflowRect();
2654         location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1);
2655     } else {
2656         location = IntPoint(
2657             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
2658             kContextMenuMargin);
2659     }
2660
2661     m_frame->view()->setCursor(pointerCursor());
2662
2663     IntPoint position = view->contentsToRootView(location);
2664     IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
2665
2666     Node* targetNode = doc->focusedNode();
2667     if (!targetNode)
2668         targetNode = doc;
2669
2670     // Use the focused node as the target for hover and active.
2671     HitTestResult result(position);
2672     result.setInnerNode(targetNode);
2673     HitTestRequest request(HitTestRequest::Active);
2674     doc->updateHoverActiveState(request, result);
2675     doc->updateStyleIfNeeded();
2676    
2677     // The contextmenu event is a mouse event even when invoked using the keyboard.
2678     // This is required for web compatibility.
2679
2680 #if OS(WINDOWS)
2681     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2682 #else
2683     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2684 #endif
2685
2686     PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
2687
2688     return dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, mouseEvent, false);
2689 }
2690
2691 #if ENABLE(GESTURE_EVENTS)
2692 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& event)
2693 {
2694 #if OS(WINDOWS)
2695     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
2696 #else
2697     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
2698 #endif
2699
2700     IntPoint adjustedPoint = event.position();
2701 #if ENABLE(TOUCH_ADJUSTMENT)
2702     if (!event.area().isEmpty())
2703         adjustGesturePosition(event, adjustedPoint);
2704 #endif
2705     PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
2706     return sendContextMenuEvent(mouseEvent);
2707 }
2708 #endif // ENABLE(GESTURE_EVENTS)
2709 #endif // ENABLE(CONTEXT_MENUS)
2710
2711 void EventHandler::scheduleHoverStateUpdate()
2712 {
2713     if (!m_hoverTimer.isActive())
2714         m_hoverTimer.startOneShot(0);
2715 }
2716
2717 void EventHandler::dispatchFakeMouseMoveEventSoon()
2718 {
2719     if (m_mousePressed)
2720         return;
2721
2722     Settings* settings = m_frame->settings();
2723     if (settings && !settings->deviceSupportsMouse())
2724         return;
2725
2726     // If the content has ever taken longer than fakeMouseMoveShortInterval we
2727     // reschedule the timer and use a longer time. This will cause the content
2728     // to receive these moves only after the user is done scrolling, reducing
2729     // pauses during the scroll.
2730     if (m_maxMouseMovedDuration > fakeMouseMoveShortInterval) {
2731         if (m_fakeMouseMoveEventTimer.isActive())
2732             m_fakeMouseMoveEventTimer.stop();
2733         m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval);
2734     } else {
2735         if (!m_fakeMouseMoveEventTimer.isActive())
2736             m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval);
2737     }
2738 }
2739
2740 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
2741 {
2742     FrameView* view = m_frame->view();
2743     if (!view)
2744         return;
2745
2746     if (!quad.containsPoint(view->windowToContents(m_currentMousePosition)))
2747         return;
2748
2749     dispatchFakeMouseMoveEventSoon();
2750 }
2751
2752 void EventHandler::cancelFakeMouseMoveEvent()
2753 {
2754     m_fakeMouseMoveEventTimer.stop();
2755 }
2756
2757 void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>* timer)
2758 {
2759     ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer);
2760     ASSERT(!m_mousePressed);
2761
2762     Settings* settings = m_frame->settings();
2763     if (settings && !settings->deviceSupportsMouse())
2764         return;
2765
2766     FrameView* view = m_frame->view();
2767     if (!view)
2768         return;
2769
2770     if (!m_frame->page() || !m_frame->page()->isOnscreen() || !m_frame->page()->focusController()->isActive())
2771         return;
2772
2773     bool shiftKey;
2774     bool ctrlKey;
2775     bool altKey;
2776     bool metaKey;
2777     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
2778     PlatformMouseEvent fakeMouseMoveEvent(m_currentMousePosition, m_currentMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, currentTime());
2779     mouseMoved(fakeMouseMoveEvent);
2780 }
2781
2782 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
2783 {
2784     m_frameSetBeingResized = frameSet;
2785 }
2786
2787 void EventHandler::resizeLayerDestroyed()
2788 {
2789     ASSERT(m_resizeLayer);
2790     m_resizeLayer = 0;
2791 }
2792
2793 void EventHandler::hoverTimerFired(Timer<EventHandler>*)
2794 {
2795     m_hoverTimer.stop();
2796
2797     ASSERT(m_frame);
2798     ASSERT(m_frame->document());
2799
2800     if (RenderView* renderer = m_frame->contentRenderer()) {
2801         if (FrameView* view = m_frame->view()) {
2802             HitTestRequest request(HitTestRequest::Move);
2803             HitTestResult result(view->windowToContents(m_currentMousePosition));
2804             renderer->hitTest(request, result);
2805             m_frame->document()->updateStyleIfNeeded();
2806         }
2807     }
2808 }
2809
2810 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
2811 {
2812     // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
2813     // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
2814     // lower case variants are present in a document, the correct element is matched based on Shift key state.
2815     // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
2816     ASSERT(!(accessKeyModifiers() & PlatformEvent::ShiftKey));
2817     if ((evt.modifiers() & ~PlatformEvent::ShiftKey) != accessKeyModifiers())
2818         return false;
2819     String key = evt.unmodifiedText();
2820     Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
2821     if (!elem)
2822         return false;
2823     elem->accessKeyAction(false);
2824     return true;
2825 }
2826
2827 #if !PLATFORM(MAC)
2828 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
2829 {
2830     return false;
2831 }
2832 #endif
2833
2834 #if ENABLE(FULLSCREEN_API)
2835 bool EventHandler::isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent& keyEvent) const
2836 {
2837     Document* document = m_frame->document();
2838     if (document->webkitFullScreenKeyboardInputAllowed())
2839         return true;
2840
2841     if (keyEvent.type() == PlatformKeyboardEvent::Char) {
2842         if (keyEvent.text().length() != 1)
2843             return false;
2844         UChar character = keyEvent.text()[0];
2845         return character == ' ';
2846     }
2847
2848     int keyCode = keyEvent.windowsVirtualKeyCode();
2849     return (keyCode >= VK_BACK && keyCode <= VK_CAPITAL)
2850         || (keyCode >= VK_SPACE && keyCode <= VK_DELETE)
2851         || (keyCode >= VK_OEM_1 && keyCode <= VK_OEM_PLUS)
2852         || (keyCode >= VK_MULTIPLY && keyCode <= VK_OEM_8);
2853 }
2854 #endif
2855
2856 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
2857 {
2858     RefPtr<FrameView> protector(m_frame->view()); 
2859
2860 #if ENABLE(FULLSCREEN_API)
2861     if (m_frame->document()->webkitIsFullScreen() && !isKeyEventAllowedInFullScreen(initialKeyEvent))
2862         return false;
2863 #endif
2864
2865     if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL)
2866         capsLockStateMayHaveChanged();
2867
2868 #if ENABLE(PAN_SCROLLING)
2869     if (Page* page = m_frame->page()) {
2870         if (page->mainFrame()->eventHandler()->m_panScrollInProgress) {
2871             // If a key is pressed while the panScroll is in progress then we want to stop
2872             if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown) 
2873                 stopAutoscrollTimer();
2874
2875             // If we were in panscroll mode, we swallow the key event
2876             return true;
2877         }
2878     }
2879 #endif
2880
2881     // Check for cases where we are too early for events -- possible unmatched key up
2882     // from pressing return in the location bar.
2883     RefPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
2884     if (!node)
2885         return false;
2886
2887     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
2888     UserTypingGestureIndicator typingGestureIndicator(m_frame);
2889
2890     if (FrameView* view = m_frame->view())
2891         view->resetDeferredRepaintDelay();
2892
2893     // FIXME (bug 68185): this call should be made at another abstraction layer
2894     m_frame->loader()->resetMultipleFormSubmissionProtection();
2895
2896     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
2897     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
2898     // with access keys. Then we dispatch keydown, but suppress its default handling.
2899     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
2900     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
2901     bool matchedAnAccessKey = false;
2902     if (initialKeyEvent.type() == PlatformEvent::KeyDown)
2903         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
2904
2905     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
2906     if (initialKeyEvent.type() == PlatformEvent::KeyUp || initialKeyEvent.type() == PlatformEvent::Char)
2907         return !node->dispatchKeyEvent(initialKeyEvent);
2908
2909     bool backwardCompatibilityMode = needsKeyboardEventDisambiguationQuirks();
2910
2911     ExceptionCode ec;
2912     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;    
2913     if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
2914         keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown, backwardCompatibilityMode);
2915     RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
2916     if (matchedAnAccessKey)
2917         keydown->setDefaultPrevented(true);
2918     keydown->setTarget(node);
2919
2920     if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
2921         node->dispatchEvent(keydown, ec);
2922         // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
2923         bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController()->focusedOrMainFrame();
2924         return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
2925     }
2926
2927     // Run input method in advance of DOM event handling.  This may result in the IM
2928     // modifying the page prior the keydown event, but this behaviour is necessary
2929     // in order to match IE:
2930     // 1. preventing default handling of keydown and keypress events has no effect on IM input;
2931     // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
2932     m_frame->editor()->handleInputMethodKeydown(keydown.get());
2933     
2934     bool handledByInputMethod = keydown->defaultHandled();
2935     
2936     if (handledByInputMethod) {
2937         keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
2938         keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
2939         keydown->setTarget(node);
2940         keydown->setDefaultHandled();
2941     }
2942
2943     node->dispatchEvent(keydown, ec);
2944     // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
2945     bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController()->focusedOrMainFrame();
2946     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
2947     if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
2948         return keydownResult;
2949     
2950     // Focus may have changed during keydown handling, so refetch node.
2951     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original node.
2952     if (!keydownResult) {
2953         node = eventTargetNodeForDocument(m_frame->document());
2954         if (!node)
2955             return false;
2956     }
2957
2958     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
2959     keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char, backwardCompatibilityMode);
2960     if (keyPressEvent.text().isEmpty())
2961         return keydownResult;
2962     RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->defaultView());
2963     keypress->setTarget(node);
2964     if (keydownResult)
2965         keypress->setDefaultPrevented(true);
2966 #if PLATFORM(MAC)
2967     keypress->keypressCommands() = keydown->keypressCommands();
2968 #endif
2969     node->dispatchEvent(keypress, ec);
2970
2971     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
2972 }
2973
2974 static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
2975 {
2976     DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down"));
2977     DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up"));
2978     DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left"));
2979     DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right"));
2980
2981     FocusDirection retVal = FocusDirectionNone;
2982
2983     if (keyIdentifier == Down)
2984         retVal = FocusDirectionDown;
2985     else if (keyIdentifier == Up)
2986         retVal = FocusDirectionUp;
2987     else if (keyIdentifier == Left)
2988         retVal = FocusDirectionLeft;
2989     else if (keyIdentifier == Right)
2990         retVal = FocusDirectionRight;
2991
2992     return retVal;
2993 }
2994
2995 static void handleKeyboardSelectionMovement(FrameSelection* selection, KeyboardEvent* event)
2996 {
2997     if (!event)
2998         return;
2999
3000     bool isOptioned = event->getModifierState("Alt");
3001     bool isCommanded = event->getModifierState("Meta");
3002
3003     SelectionDirection direction = DirectionForward;
3004     TextGranularity granularity = CharacterGranularity;
3005
3006     switch (focusDirectionForKey(event->keyIdentifier())) {
3007     case FocusDirectionNone:
3008         return;
3009     case FocusDirectionForward:
3010     case FocusDirectionBackward:
3011         ASSERT_NOT_REACHED();
3012         return;
3013     case FocusDirectionUp:
3014         direction = DirectionBackward;
3015         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3016         break;
3017     case FocusDirectionDown:
3018         direction = DirectionForward;
3019         granularity = isCommanded ? DocumentBoundary : LineGranularity;
3020         break;
3021     case FocusDirectionLeft:
3022         direction = DirectionLeft;
3023         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3024         break;
3025     case FocusDirectionRight:
3026         direction = DirectionRight;
3027         granularity = (isCommanded) ? LineBoundary : (isOptioned) ? WordGranularity : CharacterGranularity;
3028         break;
3029     }
3030
3031     FrameSelection::EAlteration alternation = event->getModifierState("Shift") ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove;
3032     selection->modify(alternation, direction, granularity, UserTriggered);
3033     event->setDefaultHandled();
3034 }
3035     
3036 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
3037 {
3038     if (event->type() == eventNames().keydownEvent) {
3039         m_frame->editor()->handleKeyboardEvent(event);
3040         if (event->defaultHandled())
3041             return;
3042         if (event->keyIdentifier() == "U+0009")
3043             defaultTabEventHandler(event);
3044         else if (event->keyIdentifier() == "U+0008")
3045             defaultBackspaceEventHandler(event);
3046         else {
3047             FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
3048             if (direction != FocusDirectionNone)
3049                 defaultArrowEventHandler(direction, event);
3050         }
3051
3052         // provides KB navigation and selection for enhanced accessibility users
3053         if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
3054             handleKeyboardSelectionMovement(m_frame->selection(), event);
3055     }
3056     if (event->type() == eventNames().keypressEvent) {
3057         m_frame->editor()->handleKeyboardEvent(event);
3058         if (event->defaultHandled())
3059             return;
3060         if (event->charCode() == ' ')
3061             defaultSpaceEventHandler(event);
3062     }
3063 }
3064
3065 #if ENABLE(DRAG_SUPPORT)
3066 bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocation) const
3067 {
3068     FloatPoint dragViewportLocation(floatDragViewportLocation.x(), floatDragViewportLocation.y());
3069     return dragHysteresisExceeded(dragViewportLocation);
3070 }
3071
3072 bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
3073 {
3074     FrameView* view = m_frame->view();
3075     if (!view)
3076         return false;
3077     IntPoint dragLocation = view->windowToContents(flooredIntPoint(dragViewportLocation));
3078     IntSize delta = dragLocation - m_mouseDownPos;
3079     
3080     int threshold = GeneralDragHysteresis;
3081     switch (dragState().m_dragType) {
3082     case DragSourceActionSelection:
3083         threshold = TextDragHysteresis;
3084         break;
3085     case DragSourceActionImage:
3086         threshold = ImageDragHysteresis;
3087         break;
3088     case DragSourceActionLink:
3089         threshold = LinkDragHysteresis;
3090         break;
3091     case DragSourceActionDHTML:
3092         break;
3093     case DragSourceActionNone:
3094     case DragSourceActionAny:
3095         ASSERT_NOT_REACHED();
3096     }
3097     
3098     return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold;
3099 }
3100     
3101 void EventHandler::freeClipboard()
3102 {
3103     if (dragState().m_dragClipboard)
3104         dragState().m_dragClipboard->setAccessPolicy(ClipboardNumb);
3105 }
3106
3107 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
3108 {
3109     // Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses.
3110     HitTestRequest request(HitTestRequest::Release);
3111     prepareMouseEvent(request, event);
3112
3113     if (dragState().m_dragSrc && dragState().shouldDispatchEvents()) {
3114         dragState().m_dragClipboard->setDestinationOperation(operation);
3115         // for now we don't care if event handler cancels default behavior, since there is none
3116         dispatchDragSrcEvent(eventNames().dragendEvent, event);
3117     }
3118     freeClipboard();
3119     dragState().m_dragSrc = 0;
3120     // In case the drag was ended due to an escape key press we need to ensure
3121     // that consecutive mousemove events don't reinitiate the drag and drop.
3122     m_mouseDownMayStartDrag = false;
3123 }
3124
3125 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement)
3126 {
3127     // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element.
3128     if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument())
3129         dragState().m_dragSrc = rootEditableElement;
3130 }
3131
3132 // returns if we should continue "default processing", i.e., whether eventhandler canceled
3133 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
3134 {
3135     return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragClipboard.get());
3136 }
3137     
3138 static bool ExactlyOneBitSet(DragSourceAction n)
3139 {
3140     return n && !(n & (n - 1));
3141 }
3142
3143 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
3144 {
3145     if (event.event().button() != LeftButton || event.event().type() != PlatformEvent::MouseMoved) {
3146         // If we allowed the other side of the bridge to handle a drag
3147         // last time, then m_mousePressed might still be set. So we
3148         // clear it now to make sure the next move after a drag
3149         // doesn't look like a drag.
3150         m_mousePressed = false;
3151         return false;
3152     }
3153     
3154     if (eventLoopHandleMouseDragged(event))
3155         return true;
3156     
3157     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
3158     
3159     if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
3160         dragState().m_eventDispatchPolicy = (updateDragSourceActionsAllowed() & DragSourceActionDHTML) ? DragState::DispatchEvents: DragState::DoNotDispatchEvents;
3161
3162         // try to find an element that wants to be dragged
3163         HitTestRequest request(HitTestRequest::ReadOnly);
3164         HitTestResult result(m_mouseDownPos);
3165         m_frame->contentRenderer()->hitTest(request, result);
3166         Node* node = result.innerNode();
3167         if (node && m_frame->page())
3168             dragState().m_dragSrc = m_frame->page()->dragController()->draggableNode(m_frame, node, m_mouseDownPos, dragState());
3169         else
3170             dragState().m_dragSrc = 0;
3171         
3172         if (!dragState().m_dragSrc)
3173             m_mouseDownMayStartDrag = false; // no element is draggable
3174         else
3175             m_dragMayStartSelectionInstead = (dragState().m_dragType & DragSourceActionSelection);
3176     }
3177     
3178     // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
3179     // or else we bail on the dragging stuff and allow selection to occur
3180     if (m_mouseDownMayStartDrag && m_dragMayStartSelectionInstead && (dragState().m_dragType & DragSourceActionSelection) && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
3181         ASSERT(event.event().type() == PlatformEvent::MouseMoved);
3182         if ((dragState().m_dragType & DragSourceActionImage)) {
3183             // ... unless the mouse is over an image, then we start dragging just the image
3184             dragState().m_dragType = DragSourceActionImage;
3185         } else if (!(dragState().m_dragType & (DragSourceActionDHTML | DragSourceActionLink))) {
3186             // ... but only bail if we're not over an unselectable element.
3187             m_mouseDownMayStartDrag = false;
3188             dragState().m_dragSrc = 0;
3189             // ... but if this was the first click in the window, we don't even want to start selection
3190             if (eventActivatedView(event.event()))
3191                 m_mouseDownMayStartSelect = false;
3192         } else {
3193             // Prevent the following case from occuring:
3194             // 1. User starts a drag immediately after mouse down over an unselectable element.
3195             // 2. We enter this block and decided that since we're over an unselectable element,
3196             //    don't cancel the drag.
3197             // 3. The drag gets resolved as a potential selection drag below /but/ we haven't
3198             //    exceeded the drag hysteresis yet.
3199             // 4. We enter this block again, and since it's now marked as a selection drag, we
3200             //    cancel the drag.
3201             m_dragMayStartSelectionInstead = false;
3202         }
3203     }
3204     
3205     if (!m_mouseDownMayStartDrag)
3206         return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
3207     
3208     if (!ExactlyOneBitSet(dragState().m_dragType)) {
3209         ASSERT((dragState().m_dragType & DragSourceActionSelection));
3210         ASSERT((dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionDHTML
3211                 || (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionImage
3212                 || (dragState().m_dragType & ~DragSourceActionSelection) == DragSourceActionLink);
3213         dragState().m_dragType = DragSourceActionSelection;
3214     }
3215
3216     // We are starting a text/image/url drag, so the cursor should be an arrow
3217     if (FrameView* view = m_frame->view()) {
3218         // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer).
3219         view->setCursor(pointerCursor());
3220     }
3221
3222     if (!dragHysteresisExceeded(event.event().position())) 
3223         return true;
3224     
3225     // Once we're past the hysteresis point, we don't want to treat this gesture as a click
3226     invalidateClick();
3227     
3228     DragOperation srcOp = DragOperationNone;      
3229     
3230     freeClipboard(); // would only happen if we missed a dragEnd.  Do it anyway, just
3231                      // to make sure it gets numbified
3232     dragState().m_dragClipboard = createDraggingClipboard();  
3233     
3234     if (dragState().shouldDispatchEvents()) {
3235         // Check to see if the is a DOM based drag, if it is get the DOM specified drag 
3236         // image and offset
3237         if (dragState().m_dragType == DragSourceActionDHTML) {
3238             if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
3239                 // FIXME: This doesn't work correctly with transforms.
3240                 FloatPoint absPos = renderer->localToAbsolute();
3241                 IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
3242                 dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), toPoint(delta));
3243             } else {
3244                 // The renderer has disappeared, this can happen if the onStartDrag handler has hidden
3245                 // the element in some way.  In this case we just kill the drag.
3246                 m_mouseDownMayStartDrag = false;
3247                 goto cleanupDrag;
3248             }
3249         } 
3250         
3251         m_mouseDownMayStartDrag = dispatchDragSrcEvent(eventNames().dragstartEvent, m_mouseDown)
3252             && !m_frame->selection()->isInPasswordField();
3253         
3254         // Invalidate clipboard here against anymore pasteboard writing for security.  The drag
3255         // image can still be changed as we drag, but not the pasteboard data.
3256         dragState().m_dragClipboard->setAccessPolicy(ClipboardImageWritable);
3257         
3258         if (m_mouseDownMayStartDrag) {
3259             // gather values from DHTML element, if it set any
3260             srcOp = dragState().m_dragClipboard->sourceOperation();
3261             
3262             // Yuck, a draggedImage:moveTo: message can be fired as a result of kicking off the
3263             // drag with dragImage!  Because of that dumb reentrancy, we may think we've not
3264             // started the drag when that happens.  So we have to assume it's started before we
3265             // kick it off.
3266             dragState().m_dragClipboard->setDragHasStarted();
3267         }
3268     }
3269     
3270     if (m_mouseDownMayStartDrag) {
3271         Page* page = m_frame->page();
3272         DragController* dragController = page ? page->dragController() : 0;
3273         bool startedDrag = dragController && dragController->startDrag(m_frame, dragState(), srcOp, event.event(), m_mouseDownPos);
3274         // In WebKit2 we could reenter this code and start another drag.
3275         // On OS X this causes problems with the ownership of the pasteboard
3276         // and the promised types.
3277         if (startedDrag) {
3278             m_mouseDownMayStartDrag = false;
3279             return true;
3280         }
3281         if (dragState().shouldDispatchEvents()) {
3282             // Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event
3283             dispatchDragSrcEvent(eventNames().dragendEvent, event.event());
3284             m_mouseDownMayStartDrag = false;
3285         }
3286     } 
3287
3288 cleanupDrag:
3289     if (!m_mouseDownMayStartDrag) {
3290         // something failed to start the drag, cleanup
3291         freeClipboard();
3292         dragState().m_dragSrc = 0;
3293     }
3294     
3295     // No more default handling (like selection), whether we're past the hysteresis bounds or not
3296     return true;
3297 }
3298 #endif // ENABLE(DRAG_SUPPORT)
3299   
3300 bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, TextEventInputType inputType)
3301 {
3302     // Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
3303     // and avoid dispatching text input events from keydown default handlers.
3304     ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || static_cast<KeyboardEvent*>(underlyingEvent)->type() == eventNames().keypressEvent);
3305
3306     if (!m_frame)
3307         return false;
3308
3309     EventTarget* target;
3310     if (underlyingEvent)
3311         target = underlyingEvent->target();
3312     else
3313         target = eventTargetNodeForDocument(m_frame->document());
3314     if (!target)
3315         return false;
3316     
3317     if (FrameView* view = m_frame->view())
3318         view->resetDeferredRepaintDelay();
3319
3320     RefPtr<TextEvent> event = TextEvent::create(m_frame->document()->domWindow(), text, inputType);
3321     event->setUnderlyingEvent(underlyingEvent);
3322
3323     ExceptionCode ec;
3324     target->dispatchEvent(event, ec);
3325     return event->defaultHandled();
3326 }
3327     
3328 bool EventHandler::isKeyboardOptionTab(KeyboardEvent* event)
3329 {
3330     return event
3331         && (event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent)
3332         && event->altKey()
3333         && event->keyIdentifier() == "U+0009";    
3334 }
3335
3336 bool EventHandler::eventInvertsTabsToLinksClientCallResult(KeyboardEvent* event)
3337 {
3338 #if PLATFORM(MAC) || PLATFORM(QT) || PLATFORM(EFL)
3339     return EventHandler::isKeyboardOptionTab(event);
3340 #else
3341     return false;
3342 #endif
3343 }
3344
3345 bool EventHandler::tabsToLinks(KeyboardEvent* event) const
3346 {
3347     // FIXME: This function needs a better name. It can be called for keypresses other than Tab when spatial navigation is enabled.
3348
3349     Page* page = m_frame->page();
3350     if (!page)
3351         return false;
3352
3353     bool tabsToLinksClientCallResult = page->chrome()->client()->keyboardUIMode() & KeyboardAccessTabsToLinks;
3354     return eventInvertsTabsToLinksClientCallResult(event) ? !tabsToLinksClientCallResult : tabsToLinksClientCallResult;
3355 }
3356
3357 void EventHandler::defaultTextInputEventHandler(TextEvent* event)
3358 {
3359     if (m_frame->editor()->handleTextEvent(event))
3360         event->setDefaultHandled();
3361 }
3362
3363 #if PLATFORM(QT)
3364 // Qt handles the space event in platform-specific WebKit code.
3365 // Eventually it would be good to eliminate that and use the code here instead.
3366 void EventHandler::defaultSpaceEventHandler(KeyboardEvent*)
3367 {
3368 }
3369 #else
3370
3371 void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
3372 {
3373     ASSERT(event->type() == eventNames().keypressEvent);
3374
3375     if (event->ctrlKey() || event->metaKey() || event->altKey() || event->altGraphKey())
3376         return;
3377
3378     ScrollLogicalDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward;
3379     if (logicalScrollOverflow(direction, ScrollByPage)) {
3380         event->setDefaultHandled();
3381         return;
3382     }
3383
3384     FrameView* view = m_frame->view();
3385     if (!view)
3386         return;
3387
3388     if (view->logicalScroll(direction, ScrollByPage))
3389         event->setDefaultHandled();
3390 }
3391
3392 #endif
3393
3394 void EventHandler::defaultBackspaceEventHandler(KeyboardEvent* event)
3395 {
3396     ASSERT(event->type() == eventNames().keydownEvent);
3397
3398     if (event->ctrlKey() || event->metaKey() || event->altKey() || event->altGraphKey())
3399         return;
3400
3401     if (!m_frame->editor()->behavior().shouldNavigateBackOnBackspace())
3402         return;
3403     
3404     Page* page = m_frame->page();
3405     if (!page)
3406         return;
3407
3408     if (!m_frame->settings()->backspaceKeyNavigationEnabled())
3409         return;
3410     
3411     bool handledEvent = false;
3412
3413     if (event->shiftKey())
3414         handledEvent = page->goForward();
3415     else
3416         handledEvent = page->goBack();
3417
3418     if (handledEvent)
3419         event->setDefaultHandled();
3420 }
3421
3422
3423 void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event)
3424 {
3425     ASSERT(event->type() == eventNames().keydownEvent);
3426
3427     if (event->ctrlKey() || event->metaKey() || event->altGraphKey() || event->shiftKey())
3428         return;
3429
3430     Page* page = m_frame->page();
3431     if (!page)
3432         return;
3433
3434     if (!isSpatialNavigationEnabled(m_frame))
3435         return;
3436
3437     // Arrows and other possible directional navigation keys can be used in design
3438     // mode editing.
3439     if (m_frame->document()->inDesignMode())
3440         return;
3441
3442     if (page->focusController()->advanceFocus(focusDirection, event))
3443         event->setDefaultHandled();
3444 }
3445
3446 void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
3447 {
3448     ASSERT(event->type() == eventNames().keydownEvent);
3449
3450     // We should only advance focus on tabs if no special modifier keys are held down.
3451     if (event->ctrlKey() || event->metaKey() || event->altGraphKey())
3452         return;
3453
3454     Page* page = m_frame->page();
3455     if (!page)
3456         return;
3457     if (!page->tabKeyCyclesThroughElements())
3458         return;
3459
3460     FocusDirection focusDirection = event->shiftKey() ? FocusDirectionBackward : FocusDirectionForward;
3461
3462     // Tabs can be used in design mode editing.
3463     if (m_frame->document()->inDesignMode())
3464         return;
3465
3466     if (page->focusController()->advanceFocus(focusDirection, event))
3467         event->setDefaultHandled();
3468 }
3469
3470 void EventHandler::capsLockStateMayHaveChanged()
3471 {
3472     Document* d = m_frame->document();
3473     if (Node* node = d->focusedNode()) {
3474         if (RenderObject* r = node->renderer()) {
3475             if (r->isTextField())
3476                 toRenderTextControlSingleLine(r)->capsLockStateMayHaveChanged();
3477         }
3478     }
3479 }
3480
3481 void EventHandler::sendResizeEvent()
3482 {
3483     m_frame->document()->enqueueWindowEvent(Event::create(eventNames().resizeEvent, false, false));
3484 }
3485
3486 void EventHandler::sendScrollEvent()
3487 {
3488     setFrameWasScrolledByUser();
3489     if (m_frame->view() && m_frame->document())
3490         m_frame->document()->eventQueue()->enqueueOrDispatchScrollEvent(m_frame->document(), DocumentEventQueue::ScrollEventDocumentTarget);
3491 }
3492
3493 void EventHandler::setFrameWasScrolledByUser()
3494 {
3495     FrameView* v = m_frame->view();
3496     if (v)
3497         v->setWasScrolledByUser(true);
3498 }
3499
3500 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
3501 {
3502     if (!scrollbar || !scrollbar->enabled())
3503         return false;
3504     setFrameWasScrolledByUser();
3505     return scrollbar->mouseDown(mev.event());
3506 }
3507
3508 // If scrollbar (under mouse) is different from last, send a mouse exited. Set
3509 // last to scrollbar if setLast is true; else set last to 0.
3510 void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setLast)
3511 {
3512     if (m_lastScrollbarUnderMouse != scrollbar) {
3513         // Send mouse exited to the old scrollbar.
3514         if (m_lastScrollbarUnderMouse)
3515             m_lastScrollbarUnderMouse->mouseExited();
3516
3517         // Send mouse entered if we're setting a new scrollbar.
3518         if (scrollbar && setLast)
3519             scrollbar->mouseEntered();
3520
3521         m_lastScrollbarUnderMouse = setLast ? scrollbar : 0;
3522     }
3523 }
3524
3525 #if ENABLE(TOUCH_EVENTS)
3526
3527 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State state)
3528 {
3529     switch (state) {
3530     case PlatformTouchPoint::TouchReleased:
3531         return eventNames().touchendEvent;
3532     case PlatformTouchPoint::TouchCancelled:
3533         return eventNames().touchcancelEvent;
3534     case PlatformTouchPoint::TouchPressed:
3535         return eventNames().touchstartEvent;
3536     case PlatformTouchPoint::TouchMoved:
3537         return eventNames().touchmoveEvent;
3538     case PlatformTouchPoint::TouchStationary:
3539         // TouchStationary state is not converted to touch events, so fall through to assert.
3540     default:
3541         ASSERT_NOT_REACHED();
3542         return emptyAtom;
3543     }
3544 }
3545
3546 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
3547 {
3548     // First build up the lists to use for the 'touches', 'targetTouches' and 'changedTouches' attributes
3549     // in the JS event. See http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
3550     // for an overview of how these lists fit together.
3551
3552     // Holds the complete set of touches on the screen and will be used as the 'touches' list in the JS event.
3553     RefPtr<TouchList> touches = TouchList::create();
3554
3555     // A different view on the 'touches' list above, filtered and grouped by event target. Used for the
3556     // 'targetTouches' list in the JS event.
3557     typedef HashMap<EventTarget*, RefPtr<TouchList> > TargetTouchesMap;
3558     TargetTouchesMap touchesByTarget;
3559
3560     // Array of touches per state, used to assemble the 'changedTouches' list in the JS event.
3561     typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
3562     struct {
3563         // The touches corresponding to the particular change state this struct instance represents.
3564         RefPtr<TouchList> m_touches;
3565         // Set of targets involved in m_touches.
3566         EventTargetSet m_targets;
3567     } changedTouches[PlatformTouchPoint::TouchStateEnd];
3568
3569     const Vector<PlatformTouchPoint>& points = event.touchPoints();
3570
3571     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
3572
3573     for (unsigned i = 0; i < points.size(); ++i) {
3574         const PlatformTouchPoint& point = points[i];
3575         PlatformTouchPoint::State pointState = point.state();
3576         LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
3577
3578         HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
3579         // The HitTestRequest types used for mouse events map quite adequately
3580         // to touch events. Note that in addition to meaning that the hit test
3581         // should affect the active state of the current node if necessary,
3582         // HitTestRequest::Active signifies that the hit test is taking place
3583         // with the mouse (or finger in this case) being pressed.
3584         switch (pointState) {
3585         case PlatformTouchPoint::TouchPressed:
3586             hitType |= HitTestRequest::Active;
3587             break;
3588         case PlatformTouchPoint::TouchMoved:
3589             hitType |= HitTestRequest::Active | HitTestRequest::Move | HitTestRequest::ReadOnly;
3590             break;
3591         case PlatformTouchPoint::TouchReleased:
3592         case PlatformTouchPoint::TouchCancelled:
3593             hitType |= HitTestRequest::Release;
3594             break;
3595         case PlatformTouchPoint::TouchStationary:
3596             hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
3597             break;
3598         default:
3599             ASSERT_NOT_REACHED();
3600             break;
3601         }
3602
3603 #if ENABLE(GESTURE_EVENTS)
3604         if (shouldGesturesTriggerActive())
3605             hitType |= HitTestRequest::ReadOnly;
3606 #endif
3607
3608         // Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
3609         unsigned touchPointTargetKey = point.id() + 1;
3610         RefPtr<EventTarget> touchTarget;
3611         if (pointState == PlatformTouchPoint::TouchPressed) {
3612             HitTestResult result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType);
3613             Node* node = result.innerNode();
3614             ASSERT(node);
3615
3616             // Touch events should not go to text nodes
3617             if (node->isTextNode())
3618                 node = node->parentNode();
3619
3620             Document* doc = node->document();
3621             if (!doc)
3622                 continue;
3623             if (!doc->touchEventHandlerCount())
3624                 continue;
3625
3626             m_originatingTouchPointTargets.set(touchPointTargetKey, node);
3627             touchTarget = node;
3628         } else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
3629             // We only perform a hittest on release or cancel to unset :active or :hover state.
3630             hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType);
3631             // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
3632             // we also remove it from the map.
3633             touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
3634         } else
3635             // No hittest is performed on move or stationary, since the target is not allowed to change anyway.
3636             touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
3637
3638         if (!touchTarget.get())
3639             continue;
3640         Document* doc = touchTarget->toNode()->document();
3641         if (!doc)
3642             continue;
3643         if (!doc->touchEventHandlerCount())
3644             continue;
3645         Frame* targetFrame = doc->frame();
3646         if (!targetFrame)
3647             continue;
3648
3649         if (m_frame != targetFrame) {
3650             // pagePoint should always be relative to the target elements containing frame.
3651             pagePoint = documentPointForWindowPoint(targetFrame, point.pos());
3652         }
3653
3654         float scaleFactor = targetFrame->pageZoomFactor() * targetFrame->frameScaleFactor();
3655
3656         int adjustedPageX = lroundf(pagePoint.x() / scaleFactor);
3657         int adjustedPageY = lroundf(pagePoint.y() / scaleFactor);
3658
3659         RefPtr<Touch> touch = Touch::create(targetFrame, touchTarget.get(), point.id(),
3660                                             point.screenPos().x(), point.screenPos().y(),
3661                                             adjustedPageX, adjustedPageY,
3662                                             point.radiusX(), point.radiusY(), point.rotationAngle(), point.force());
3663
3664         // Ensure this target's touch list exists, even if it ends up empty, so it can always be passed to TouchEvent::Create below.
3665         TargetTouchesMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
3666         if (targetTouchesIterator == touchesByTarget.end())
3667             targetTouchesIterator = touchesByTarget.set(touchTarget.get(), TouchList::create()).iterator;
3668
3669         // touches and targetTouches should only contain information about touches still on the screen, so if this point is
3670         // released or cancelled it will only appear in the changedTouches list.
3671         if (pointState != PlatformTouchPoint::TouchReleased && pointState != PlatformTouchPoint::TouchCancelled) {
3672             touches->append(touch);
3673             targetTouchesIterator->second->append(touch);
3674         }
3675
3676         // Now build up the correct list for changedTouches.
3677         // Note that  any touches that are in the TouchStationary state (e.g. if
3678         // the user had several points touched but did not move them all) should
3679         // never be in the changedTouches list so we do not handle them explicitly here.
3680         // See https://bugs.webkit.org/show_bug.cgi?id=37609 for further discussion
3681         // about the TouchStationary state.
3682         if (pointState != PlatformTouchPoint::TouchStationary) {
3683             ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
3684             if (!changedTouches[pointState].m_touches)
3685                 changedTouches[pointState].m_touches = TouchList::create();
3686             changedTouches[pointState].m_touches->append(touch);
3687             changedTouches[pointState].m_targets.add(touchTarget);
3688         }
3689     }
3690     m_touchPressed = touches->length() > 0;
3691
3692     // Now iterate the changedTouches list and m_targets within it, sending events to the targets as required.
3693     bool swallowedEvent = false;
3694     RefPtr<TouchList> emptyList = TouchList::create();
3695     for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
3696         if (!changedTouches[state].m_touches)
3697             continue;
3698
3699         // When sending a touch cancel event, use empty touches and targetTouches lists.
3700         bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
3701         RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
3702         const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
3703         const EventTargetSet& targetsForState = changedTouches[state].m_targets;
3704
3705         for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
3706             EventTarget* touchEventTarget = it->get();
3707             RefPtr<TouchList> targetTouches(isTouchCancelEvent ? emptyList : touchesByTarget.get(touchEventTarget));
3708             ASSERT(targetTouches);
3709
3710             RefPtr<TouchEvent> touchEvent =
3711                 TouchEvent::create(effectiveTouches.get(), targetTouches.get(), changedTouches[state].m_touches.get(),
3712                                    stateName, touchEventTarget->toNode()->document()->defaultView(),
3713                                    0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey());
3714             ExceptionCode ec = 0;
3715             touchEventTarget->dispatchEvent(touchEvent.get(), ec);
3716             swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
3717         }
3718     }
3719
3720     return swallowedEvent;
3721 }
3722
3723 bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& event)
3724 {
3725     if (!m_frame || !m_frame->settings() || !m_frame->settings()->isTouchEventEmulationEnabled())
3726         return false;
3727
3728     PlatformEvent::Type eventType = event.type();
3729     if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
3730         return false;
3731
3732     if (eventType == PlatformEvent::MouseMoved && !m_touchPressed)
3733         return false;
3734
3735     SyntheticSingleTouchEvent touchEvent(event);
3736     return handleTouchEvent(touchEvent);
3737 }
3738
3739 #endif
3740
3741 }