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