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