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