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