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