2008-10-09 Darin Fisher <darin@chromium.org>
[WebKit-https.git] / WebCore / page / EventHandler.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008 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 "ChromeClient.h"
33 #include "Cursor.h"
34 #include "Document.h"
35 #include "DragController.h"
36 #include "Editor.h"
37 #include "EventNames.h"
38 #include "FloatPoint.h"
39 #include "FloatRect.h"
40 #include "FocusController.h"
41 #include "Frame.h"
42 #include "FrameLoader.h"
43 #include "FrameTree.h"
44 #include "FrameView.h"
45 #include "HitTestRequest.h"
46 #include "HitTestResult.h"
47 #include "HTMLFrameSetElement.h"
48 #include "HTMLFrameElementBase.h"
49 #include "HTMLInputElement.h"
50 #include "HTMLNames.h"
51 #include "Image.h"
52 #include "InspectorController.h"
53 #include "KeyboardEvent.h"
54 #include "MouseEvent.h"
55 #include "MouseEventWithHitTestResults.h"
56 #include "Page.h"
57 #include "PlatformKeyboardEvent.h"
58 #include "PlatformWheelEvent.h"
59 #include "RenderFrameSet.h"
60 #include "RenderWidget.h"
61 #include "RenderView.h"
62 #include "Scrollbar.h"
63 #include "SelectionController.h"
64 #include "Settings.h"
65 #include "TextEvent.h"
66
67 #if ENABLE(SVG)
68 #include "SVGDocument.h"
69 #include "SVGElementInstance.h"
70 #include "SVGNames.h"
71 #include "SVGUseElement.h"
72 #endif
73
74 namespace WebCore {
75
76 using namespace EventNames;
77 using namespace HTMLNames;
78
79 // The link drag hysteresis is much larger than the others because there
80 // needs to be enough space to cancel the link press without starting a link drag,
81 // and because dragging links is rare.
82 const int LinkDragHysteresis = 40;
83 const int ImageDragHysteresis = 5;
84 const int TextDragHysteresis = 3;
85 const int GeneralDragHysteresis = 3;
86
87 // Match key code of composition keydown event on windows.
88 // IE sends VK_PROCESSKEY which has value 229;
89 const int CompositionEventKeyCode = 229;
90
91 #if ENABLE(SVG)
92 using namespace SVGNames;
93 #endif
94
95 // When the autoscroll or the panScroll is triggered when do the scroll every 0.05s to make it smooth
96 const double autoscrollInterval = 0.05;
97
98 static Frame* subframeForTargetNode(Node*);
99 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
100
101 static inline void scrollAndAcceptEvent(float delta, ScrollDirection positiveDirection, ScrollDirection negativeDirection, PlatformWheelEvent& e, Node* node)
102 {
103     if (!delta)
104         return;
105     if (e.granularity() == ScrollByPageWheelEvent) {
106         if (node->renderer()->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPage, 1))
107             e.accept();
108         return;
109     } 
110     float pixelsToScroll = delta > 0 ? delta : -delta;
111     if (e.granularity() == ScrollByLineWheelEvent)
112         pixelsToScroll *= cMouseWheelPixelsPerLineStep;
113     if (node->renderer()->scroll(delta < 0 ? negativeDirection : positiveDirection, ScrollByPixel, pixelsToScroll))
114         e.accept();
115 }
116
117 EventHandler::EventHandler(Frame* frame)
118     : m_frame(frame)
119     , m_mousePressed(false)
120     , m_mouseDownMayStartSelect(false)
121     , m_mouseDownMayStartDrag(false)
122     , m_mouseDownWasSingleClickInSelection(false)
123     , m_beganSelectingText(false)
124     , m_panScrollInProgress(false)
125     , m_hoverTimer(this, &EventHandler::hoverTimerFired)
126     , m_autoscrollTimer(this, &EventHandler::autoscrollTimerFired)
127     , m_autoscrollRenderer(0)
128     , m_autoscrollInProgress(false)
129     , m_mouseDownMayStartAutoscroll(false)
130     , m_mouseDownWasInSubframe(false)
131 #if ENABLE(SVG)
132     , m_svgPan(false)
133 #endif
134     , m_resizeLayer(0)
135     , m_capturingMouseEventsNode(0)
136     , m_clickCount(0)
137     , m_mouseDownTimestamp(0)
138     , m_pendingFrameUnloadEventCount(0)
139     , m_pendingFrameBeforeUnloadEventCount(0)
140 #if PLATFORM(MAC)
141     , m_mouseDownView(nil)
142     , m_sendingEventToSubview(false)
143     , m_activationEventNumber(0)
144 #endif
145 {
146 }
147
148 EventHandler::~EventHandler()
149 {
150 }
151     
152 EventHandler::EventHandlerDragState& EventHandler::dragState()
153 {
154     static EventHandlerDragState state;
155     return state;
156 }
157     
158 void EventHandler::clear()
159 {
160     m_hoverTimer.stop();
161     m_resizeLayer = 0;
162     m_nodeUnderMouse = 0;
163     m_lastNodeUnderMouse = 0;
164 #if ENABLE(SVG)
165     m_instanceUnderMouse = 0;
166     m_lastInstanceUnderMouse = 0;
167 #endif
168     m_lastMouseMoveEventSubframe = 0;
169     m_lastScrollbarUnderMouse = 0;
170     m_clickCount = 0;
171     m_clickNode = 0;
172     m_frameSetBeingResized = 0;
173     m_dragTarget = 0;
174     m_currentMousePosition = IntPoint();
175     m_mousePressNode = 0;
176     m_mousePressed = false;
177     m_capturingMouseEventsNode = 0;
178 }
179
180 void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
181 {
182     Node* innerNode = result.targetNode();
183     Selection newSelection;
184
185     if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
186         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
187         if (pos.isNotNull()) {
188             newSelection = Selection(pos);
189             newSelection.expandUsingGranularity(WordGranularity);
190         }
191     
192         if (newSelection.isRange()) {
193             m_frame->setSelectionGranularity(WordGranularity);
194             m_beganSelectingText = true;
195         }
196         
197         if (m_frame->shouldChangeSelection(newSelection))
198             m_frame->selection()->setSelection(newSelection);
199     }
200 }
201
202 void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
203 {
204     if (!result.hitTestResult().isLiveLink())
205         return selectClosestWordFromMouseEvent(result);
206
207     Node* innerNode = result.targetNode();
208
209     if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
210         Selection newSelection;
211         Element* URLElement = result.hitTestResult().URLElement();
212         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
213         if (pos.isNotNull() && pos.deepEquivalent().node()->isDescendantOf(URLElement))
214             newSelection = Selection::selectionFromContentsOfNode(URLElement);
215     
216         if (newSelection.isRange()) {
217             m_frame->setSelectionGranularity(WordGranularity);
218             m_beganSelectingText = true;
219         }
220
221         if (m_frame->shouldChangeSelection(newSelection))
222             m_frame->selection()->setSelection(newSelection);
223     }
224 }
225
226 bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
227 {
228     if (event.event().button() != LeftButton)
229         return false;
230
231     if (m_frame->selection()->isRange())
232         // A double-click when range is already selected
233         // should not change the selection.  So, do not call
234         // selectClosestWordFromMouseEvent, but do set
235         // m_beganSelectingText to prevent handleMouseReleaseEvent
236         // from setting caret selection.
237         m_beganSelectingText = true;
238     else
239         selectClosestWordFromMouseEvent(event);
240
241     return true;
242 }
243
244 bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
245 {
246     if (event.event().button() != LeftButton)
247         return false;
248     
249     Node* innerNode = event.targetNode();
250     if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
251         return false;
252
253     Selection newSelection;
254     VisiblePosition pos(innerNode->renderer()->positionForPoint(event.localPoint()));
255     if (pos.isNotNull()) {
256         newSelection = Selection(pos);
257         newSelection.expandUsingGranularity(ParagraphGranularity);
258     }
259     if (newSelection.isRange()) {
260         m_frame->setSelectionGranularity(ParagraphGranularity);
261         m_beganSelectingText = true;
262     }
263     
264     if (m_frame->shouldChangeSelection(newSelection))
265         m_frame->selection()->setSelection(newSelection);
266
267     return true;
268 }
269
270 bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
271 {
272     if (event.event().button() != LeftButton)
273         return false;
274     
275     Node* innerNode = event.targetNode();
276     if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
277         return false;
278
279     // Extend the selection if the Shift key is down, unless the click is in a link.
280     bool extendSelection = event.event().shiftKey() && !event.isOverLink();
281
282     // Don't restart the selection when the mouse is pressed on an
283     // existing selection so we can allow for text dragging.
284     IntPoint vPoint = m_frame->view()->windowToContents(event.event().pos());
285     if (!extendSelection && m_frame->selection()->contains(vPoint)) {
286         m_mouseDownWasSingleClickInSelection = true;
287         return false;
288     }
289
290     VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(event.localPoint()));
291     if (visiblePos.isNull())
292         visiblePos = VisiblePosition(innerNode, 0, DOWNSTREAM);
293     Position pos = visiblePos.deepEquivalent();
294     
295     Selection newSelection = m_frame->selection()->selection();
296     if (extendSelection && newSelection.isCaretOrRange()) {
297         m_frame->selection()->setLastChangeWasHorizontalExtension(false);
298         
299         // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection 
300         // was created right-to-left
301         Position start = newSelection.start();
302         Position end = newSelection.end();
303         short before = Range::compareBoundaryPoints(pos.node(), pos.offset(), start.node(), start.offset());
304         if (before <= 0)
305             newSelection = Selection(pos, end);
306         else
307             newSelection = Selection(start, pos);
308
309         if (m_frame->selectionGranularity() != CharacterGranularity)
310             newSelection.expandUsingGranularity(m_frame->selectionGranularity());
311         m_beganSelectingText = true;
312     } else {
313         newSelection = Selection(visiblePos);
314         m_frame->setSelectionGranularity(CharacterGranularity);
315     }
316     
317     if (m_frame->shouldChangeSelection(newSelection))
318         m_frame->selection()->setSelection(newSelection);
319
320     return true;
321 }
322
323 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
324 {
325     // Reset drag state.
326     dragState().m_dragSrc = 0;
327
328     bool singleClick = event.event().clickCount() <= 1;
329
330     // If we got the event back, that must mean it wasn't prevented,
331     // so it's allowed to start a drag or selection.
332     m_mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode());
333     
334     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
335     m_mouseDownMayStartDrag = singleClick;
336
337     m_mouseDownWasSingleClickInSelection = false;
338
339     if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
340         return true;
341
342 #if ENABLE(SVG)
343     if (m_frame->document()->isSVGDocument() &&
344        static_cast<SVGDocument*>(m_frame->document())->zoomAndPanEnabled()) {
345         if (event.event().shiftKey() && singleClick) {
346             m_svgPan = true;
347             static_cast<SVGDocument*>(m_frame->document())->startPan(event.event().pos());
348             return true;
349         }
350     }
351 #endif
352
353     // We don't do this at the start of mouse down handling,
354     // because we don't want to do it until we know we didn't hit a widget.
355     if (singleClick)
356         focusDocumentView();
357
358     Node* innerNode = event.targetNode();
359
360     m_mousePressNode = innerNode;
361     m_dragStartPos = event.event().pos();
362
363     bool swallowEvent = false;
364     if (event.event().button() == LeftButton || event.event().button() == MiddleButton) {
365         m_frame->selection()->setCaretBlinkingSuspended(true);
366         m_mousePressed = true;
367         m_beganSelectingText = false;
368
369         if (event.event().clickCount() == 2)
370             swallowEvent = handleMousePressEventDoubleClick(event);
371         else if (event.event().clickCount() >= 3)
372             swallowEvent = handleMousePressEventTripleClick(event);
373         else
374             swallowEvent = handleMousePressEventSingleClick(event);
375     }
376     
377    m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect || 
378         (m_mousePressNode && m_mousePressNode->renderer() && m_mousePressNode->renderer()->canBeProgramaticallyScrolled(true));
379
380    return swallowEvent;
381 }
382
383 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event)
384 {
385     if (handleDrag(event))
386         return true;
387
388     if (!m_mousePressed)
389         return false;
390
391     Node* targetNode = event.targetNode();
392     if (event.event().button() != LeftButton || !targetNode || !targetNode->renderer())
393         return false;
394
395 #if PLATFORM(MAC) // FIXME: Why does this assertion fire on other platforms?
396     ASSERT(m_mouseDownMayStartSelect || m_mouseDownMayStartAutoscroll);
397 #endif
398
399     m_mouseDownMayStartDrag = false;
400
401     if (m_mouseDownMayStartAutoscroll && !m_panScrollInProgress) {            
402         // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
403         // Otherwise, let the bridge handle it so the view can scroll itself.
404         RenderObject* renderer = targetNode->renderer();
405         while (renderer && !renderer->canBeProgramaticallyScrolled(false)) {
406             if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
407                 renderer = renderer->document()->ownerElement()->renderer();
408             else
409                 renderer = renderer->parent();
410         }
411         
412         if (renderer) {
413             m_autoscrollInProgress = true;
414             handleAutoscroll(renderer);
415         }
416         
417         m_mouseDownMayStartAutoscroll = false;
418     }
419     
420     updateSelectionForMouseDrag(targetNode, event.localPoint());
421     return true;
422 }
423     
424 bool EventHandler::eventMayStartDrag(const PlatformMouseEvent& event) const
425 {
426     // This is a pre-flight check of whether the event might lead to a drag being started.  Be careful
427     // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
428     // in handleMousePressEvent
429     
430     if (!m_frame->contentRenderer() || !m_frame->contentRenderer()->hasLayer()
431         || event.button() != LeftButton || event.clickCount() != 1)
432         return false;
433     
434     bool DHTMLFlag;
435     bool UAFlag;
436     allowDHTMLDrag(DHTMLFlag, UAFlag);
437     if (!DHTMLFlag && !UAFlag)
438         return false;
439     
440     HitTestRequest request(true, false);
441     HitTestResult result(m_frame->view()->windowToContents(event.pos()));
442     m_frame->contentRenderer()->layer()->hitTest(request, result);
443     bool srcIsDHTML;
444     return result.innerNode() && result.innerNode()->renderer()->draggableNode(DHTMLFlag, UAFlag, result.point().x(), result.point().y(), srcIsDHTML);
445 }
446
447 void EventHandler::updateSelectionForMouseDrag()
448 {
449     FrameView* view = m_frame->view();
450     if (!view)
451         return;
452     RenderObject* renderer = m_frame->contentRenderer();
453     if (!renderer)
454         return;
455     RenderLayer* layer = renderer->layer();
456     if (!layer)
457         return;
458
459     HitTestResult result(view->windowToContents(m_currentMousePosition));
460     layer->hitTest(HitTestRequest(true, true, true), result);
461     updateSelectionForMouseDrag(result.innerNode(), result.localPoint());
462 }
463
464 void EventHandler::updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint)
465 {
466     if (!m_mouseDownMayStartSelect)
467         return;
468
469     if (!targetNode)
470         return;
471
472     RenderObject* targetRenderer = targetNode->renderer();
473     if (!targetRenderer)
474         return;
475         
476     if (!canMouseDragExtendSelect(targetNode))
477         return;
478
479     VisiblePosition targetPosition(targetRenderer->positionForPoint(localPoint));
480
481     // Don't modify the selection if we're not on a node.
482     if (targetPosition.isNull())
483         return;
484
485     // Restart the selection if this is the first mouse move. This work is usually
486     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
487     Selection newSelection = m_frame->selection()->selection();
488
489 #if ENABLE(SVG)
490     // Special case to limit selection to the containing block for SVG text.
491     // FIXME: Isn't there a better non-SVG-specific way to do this?
492     if (Node* selectionBaseNode = newSelection.base().node())
493         if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
494             if (selectionBaseRenderer->isSVGText())
495                 if (targetNode->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
496                     return;
497 #endif
498
499     if (!m_beganSelectingText) {
500         m_beganSelectingText = true;
501         newSelection = Selection(targetPosition);
502     }
503
504     newSelection.setExtent(targetPosition);
505     if (m_frame->selectionGranularity() != CharacterGranularity)
506         newSelection.expandUsingGranularity(m_frame->selectionGranularity());
507
508     if (m_frame->shouldChangeSelection(newSelection)) {
509         m_frame->selection()->setLastChangeWasHorizontalExtension(false);
510         m_frame->selection()->setSelection(newSelection);
511     }
512 }
513     
514 bool EventHandler::handleMouseUp(const MouseEventWithHitTestResults& event)
515 {
516     if (eventLoopHandleMouseUp(event))
517         return true;
518     
519     // If this was the first click in the window, we don't even want to clear the selection.
520     // This case occurs when the user clicks on a draggable element, since we have to process
521     // the mouse down and drag events to see if we might start a drag.  For other first clicks
522     // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets
523     // ignored upstream of this layer.
524     return eventActivatedView(event.event());
525 }    
526
527 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
528 {
529     if (m_autoscrollInProgress)
530         stopAutoscrollTimer();
531
532     if (handleMouseUp(event))
533         return true;
534
535     // Used to prevent mouseMoveEvent from initiating a drag before
536     // the mouse is pressed again.
537     m_frame->selection()->setCaretBlinkingSuspended(false);
538     m_mousePressed = false;
539     m_mouseDownMayStartDrag = false;
540     m_mouseDownMayStartSelect = false;
541     m_mouseDownMayStartAutoscroll = false;
542     m_mouseDownWasInSubframe = false;
543   
544     bool handled = false;
545
546     // Clear the selection if the mouse didn't move after the last mouse press.
547     // We do this so when clicking on the selection, the selection goes away.
548     // However, if we are editing, place the caret.
549     if (m_mouseDownWasSingleClickInSelection && !m_beganSelectingText
550             && m_dragStartPos == event.event().pos()
551             && m_frame->selection()->isRange()) {
552         Selection newSelection;
553         Node *node = event.targetNode();
554         if (node && node->isContentEditable() && node->renderer()) {
555             VisiblePosition pos = node->renderer()->positionForPoint(event.localPoint());
556             newSelection = Selection(pos);
557         }
558         if (m_frame->shouldChangeSelection(newSelection))
559             m_frame->selection()->setSelection(newSelection);
560
561         handled = true;
562     }
563
564     m_frame->notifyRendererOfSelectionChange(true);
565
566     m_frame->selection()->selectFrameElementInParentIfFullySelected();
567
568     return handled;
569 }
570
571 void EventHandler::handleAutoscroll(RenderObject* renderer)
572 {
573     // We don't want to trigger the autoscroll or the panScroll if it's already active
574     if (m_autoscrollTimer.isActive())
575         return;     
576
577     setAutoscrollRenderer(renderer);
578
579 #if ENABLE(PAN_SCROLLING)
580     if (m_panScrollInProgress) {
581         m_panScrollStartPos = currentMousePosition();
582         m_frame->view()->addPanScrollIcon(m_panScrollStartPos);
583         // If we're not in the top frame we notify it that we are using the panScroll
584         if (m_frame != m_frame->page()->mainFrame())
585             m_frame->page()->mainFrame()->eventHandler()->setPanScrollInProgress(true);
586     }
587 #endif
588
589     startAutoscrollTimer();
590 }
591
592 void EventHandler::autoscrollTimerFired(Timer<EventHandler>*)
593 {
594     RenderObject* r = autoscrollRenderer();
595     if (!r) {
596         stopAutoscrollTimer();
597         return;
598     }
599
600     if (m_autoscrollInProgress) {
601         if (!m_mousePressed) {
602             stopAutoscrollTimer();
603             return;
604         }
605         r->autoscroll();
606     } else {
607         // we verify that the main frame hasn't received the order to stop the panScroll
608         if (!m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress()) {
609             stopAutoscrollTimer();
610             return;
611         }
612 #if ENABLE(PAN_SCROLLING)
613         setPanScrollCursor();
614         r->panScroll(m_panScrollStartPos);
615 #endif
616     }
617 }
618
619 void EventHandler::setPanScrollCursor()
620 {
621     // At the original click location we draw a 4 arrowed icon. Over this icon there won't be any scroll
622     // So we don't want to change the cursor over this area
623     const int noScrollRadius = 9;
624     bool east = m_panScrollStartPos.x() < (m_currentMousePosition.x() - noScrollRadius);
625     bool west = m_panScrollStartPos.x() > (m_currentMousePosition.x() + noScrollRadius);
626     bool north = m_panScrollStartPos.y() > (m_currentMousePosition.y() + noScrollRadius);
627     bool south = m_panScrollStartPos.y() < (m_currentMousePosition.y() - noScrollRadius);
628          
629     if (north) {
630         if (east)
631             m_frame->view()->setCursor(northEastPanningCursor());
632         else if (west)
633             m_frame->view()->setCursor(northWestPanningCursor());
634         else
635             m_frame->view()->setCursor(northPanningCursor());
636     } else if (south) {
637         if (east)
638             m_frame->view()->setCursor(southEastPanningCursor());
639         else if (west)
640             m_frame->view()->setCursor(southWestPanningCursor());
641         else
642             m_frame->view()->setCursor(southPanningCursor());
643     } else if (east)
644         m_frame->view()->setCursor(eastPanningCursor());
645     else if (west)
646         m_frame->view()->setCursor(westPanningCursor());
647     else
648         m_frame->view()->setCursor(middlePanningCursor());
649 }
650
651 RenderObject* EventHandler::autoscrollRenderer() const
652 {
653     return m_autoscrollRenderer;
654 }
655
656 void EventHandler::updateAutoscrollRenderer()
657 {
658     if (!m_autoscrollRenderer)
659         return;
660
661     HitTestResult hitTest = hitTestResultAtPoint(m_panScrollStartPos, true);
662
663     if (Node* nodeAtPoint = hitTest.innerNode())
664         m_autoscrollRenderer = nodeAtPoint->renderer();
665
666     while (m_autoscrollRenderer && !m_autoscrollRenderer->canBeProgramaticallyScrolled(false))
667         m_autoscrollRenderer = m_autoscrollRenderer->parent();
668 }
669
670 void EventHandler::setAutoscrollRenderer(RenderObject* renderer)
671 {
672     m_autoscrollRenderer = renderer;
673 }
674
675 void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const
676 {
677     if (!m_frame || !m_frame->document()) {
678         flagDHTML = false;
679         flagUA = false;
680     }
681     
682     unsigned mask = m_frame->page()->dragController()->delegateDragSourceAction(m_frame->view()->contentsToWindow(m_mouseDownPos));
683     flagDHTML = (mask & DragSourceActionDHTML) != DragSourceActionNone;
684     flagUA = ((mask & DragSourceActionImage) || (mask & DragSourceActionLink) || (mask & DragSourceActionSelection));
685 }
686     
687 HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent)
688 {
689     HitTestResult result(point);
690     if (!m_frame->contentRenderer())
691         return result;
692     m_frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), result);
693
694     while (true) {
695         Node* n = result.innerNode();
696         if (!result.isOverWidget() || !n || !n->renderer() || !n->renderer()->isWidget())
697             break;
698         Widget* widget = static_cast<RenderWidget*>(n->renderer())->widget();
699         if (!widget || !widget->isFrameView())
700             break;
701         Frame* frame = static_cast<HTMLFrameElementBase*>(n)->contentFrame();
702         if (!frame || !frame->contentRenderer())
703             break;
704         FrameView* view = static_cast<FrameView*>(widget);
705         IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - n->renderer()->borderLeft() - n->renderer()->paddingLeft(), 
706             result.localPoint().y() + view->scrollY() - n->renderer()->borderTop() - n->renderer()->paddingTop());
707         HitTestResult widgetHitTestResult(widgetPoint);
708         frame->contentRenderer()->layer()->hitTest(HitTestRequest(true, true), widgetHitTestResult);
709         result = widgetHitTestResult;
710     }
711     
712     // If our HitTestResult is not visible, then we started hit testing too far down the frame chain. 
713     // Another hit test at the main frame level should get us the correct visible result.
714     Frame* resultFrame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document()->frame() : 0;
715     Frame* mainFrame = m_frame->page()->mainFrame();
716     if (m_frame != mainFrame && resultFrame && resultFrame != mainFrame && !resultFrame->editor()->insideVisibleArea(result.point())) {
717         IntPoint windowPoint = resultFrame->view()->contentsToWindow(result.point());
718         IntPoint mainFramePoint = mainFrame->view()->windowToContents(windowPoint);
719         result = mainFrame->eventHandler()->hitTestResultAtPoint(mainFramePoint, allowShadowContent);
720     }
721
722     if (!allowShadowContent)
723         result.setToNonShadowAncestor();
724
725     return result;
726 }
727
728
729 void EventHandler::startAutoscrollTimer()
730 {
731     m_autoscrollTimer.startRepeating(autoscrollInterval);
732 }
733
734 void EventHandler::stopAutoscrollTimer(bool rendererIsBeingDestroyed)
735 {
736     if (m_autoscrollInProgress) {
737         if (m_mouseDownWasInSubframe) {
738             if (Frame* subframe = subframeForTargetNode(m_mousePressNode.get()))
739                 subframe->eventHandler()->stopAutoscrollTimer(rendererIsBeingDestroyed);
740             return;
741         }
742     }
743
744     if (autoscrollRenderer()) {
745         if (!rendererIsBeingDestroyed && (m_autoscrollInProgress || m_panScrollInProgress))
746             autoscrollRenderer()->stopAutoscroll();
747 #if ENABLE(PAN_SCROLLING)
748         if (m_panScrollInProgress) {
749             m_frame->view()->removePanScrollIcon();
750             m_frame->view()->setCursor(pointerCursor());
751         }
752 #endif
753
754         setAutoscrollRenderer(0);
755     }
756
757     m_autoscrollTimer.stop();
758
759     m_panScrollInProgress = false;
760     // If we're not in the top frame we notify it that we are not using the panScroll anymore
761     if (m_frame->page() && m_frame != m_frame->page()->mainFrame())
762             m_frame->page()->mainFrame()->eventHandler()->setPanScrollInProgress(false);
763     m_autoscrollInProgress = false;
764 }
765
766 Node* EventHandler::mousePressNode() const
767 {
768     return m_mousePressNode.get();
769 }
770
771 void EventHandler::setMousePressNode(PassRefPtr<Node> node)
772 {
773     m_mousePressNode = node;
774 }
775
776 bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity)
777 {
778     if (!m_frame->document())
779         return false;
780     
781     Node* node = m_frame->document()->focusedNode();
782     if (!node)
783         node = m_mousePressNode.get();
784     
785     if (node) {
786         RenderObject *r = node->renderer();
787         if (r && !r->isListBox())
788             return r->scroll(direction, granularity);
789     }
790
791     return false;
792 }
793
794 IntPoint EventHandler::currentMousePosition() const
795 {
796     return m_currentMousePosition;
797 }
798
799 Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
800 {
801     if (!hitTestResult.isOverWidget())
802         return 0;
803     return subframeForTargetNode(hitTestResult.targetNode());
804 }
805
806 Frame* subframeForTargetNode(Node* node)
807 {
808     if (!node)
809         return 0;
810
811     RenderObject* renderer = node->renderer();
812     if (!renderer || !renderer->isWidget())
813         return 0;
814
815     Widget* widget = static_cast<RenderWidget*>(renderer)->widget();
816     if (!widget || !widget->isFrameView())
817         return 0;
818
819     return static_cast<FrameView*>(widget)->frame();
820 }
821
822 static bool isSubmitImage(Node* node)
823 {
824     return node && node->hasTagName(inputTag)
825         && static_cast<HTMLInputElement*>(node)->inputType() == HTMLInputElement::IMAGE;
826 }
827
828 // Returns true if the node's editable block is not current focused for editing
829 static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
830 {
831     return frame->selection()->rootEditableElement() != node->rootEditableElement();
832 }
833
834 Cursor EventHandler::selectCursor(const MouseEventWithHitTestResults& event, Scrollbar* scrollbar)
835 {
836     // During selection, use an I-beam no matter what we're over.
837     // If you're capturing mouse events for a particular node, don't treat this as a selection.
838     if (m_mousePressed && m_mouseDownMayStartSelect && m_frame->selection()->isCaretOrRange() && !m_capturingMouseEventsNode)
839         return iBeamCursor();
840
841     Node* node = event.targetNode();
842     RenderObject* renderer = node ? node->renderer() : 0;
843     RenderStyle* style = renderer ? renderer->style() : 0;
844
845     if (renderer && renderer->isFrameSet()) {
846         RenderFrameSet* fs = static_cast<RenderFrameSet*>(renderer);
847         if (fs->canResizeRow(event.localPoint()))
848             return rowResizeCursor();
849         if (fs->canResizeColumn(event.localPoint()))
850             return columnResizeCursor();
851     }
852
853     if (style && style->cursors()) {
854         const CursorList* cursors = style->cursors();
855         for (unsigned i = 0; i < cursors->size(); ++i) {
856             CachedImage* cimage = (*cursors)[i].cursorImage.get();
857             IntPoint hotSpot = (*cursors)[i].hotSpot;
858             if (!cimage)
859                 continue;
860             // Limit the size of cursors so that they cannot be used to cover UI elements in chrome.
861             IntSize size = cimage->image()->size();
862             if (size.width() > 128 || size.height() > 128)
863                 continue;
864             // Do not let the hotspot be outside the bounds of the image. 
865             if (hotSpot.x() < 0 || hotSpot.y() < 0 || hotSpot.x() > size.width() || hotSpot.y() > size.height())
866                 continue;
867             if (cimage->image()->isNull())
868                 break;
869             if (!cimage->errorOccurred())
870                 return Cursor(cimage->image(), hotSpot);
871         }
872     }
873
874     switch (style ? style->cursor() : CURSOR_AUTO) {
875         case CURSOR_AUTO: {
876             bool editable = (node && node->isContentEditable());
877             bool editableLinkEnabled = false;
878
879             // If the link is editable, then we need to check the settings to see whether or not the link should be followed
880             if (editable) {
881                 ASSERT(m_frame->settings());
882                 switch(m_frame->settings()->editableLinkBehavior()) {
883                     default:
884                     case EditableLinkDefaultBehavior:
885                     case EditableLinkAlwaysLive:
886                         editableLinkEnabled = true;
887                         break;
888
889                     case EditableLinkNeverLive:
890                         editableLinkEnabled = false;
891                         break;
892
893                     case EditableLinkLiveWhenNotFocused:
894                         editableLinkEnabled = nodeIsNotBeingEdited(node, m_frame) || event.event().shiftKey();
895                         break;
896                     
897                     case EditableLinkOnlyLiveWithShiftKey:
898                         editableLinkEnabled = event.event().shiftKey();
899                         break;
900                 }
901             }
902             
903             if ((event.isOverLink() || isSubmitImage(node)) && (!editable || editableLinkEnabled))
904                 return handCursor();
905             RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0;
906             bool inResizer = false;
907             if (m_frame->view() && layer && layer->isPointInResizeControl(m_frame->view()->windowToContents(event.event().pos())))
908                 inResizer = true;
909             if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !scrollbar)
910                 return iBeamCursor();
911             return pointerCursor();
912         }
913         case CURSOR_CROSS:
914             return crossCursor();
915         case CURSOR_POINTER:
916             return handCursor();
917         case CURSOR_MOVE:
918             return moveCursor();
919         case CURSOR_ALL_SCROLL:
920             return moveCursor();
921         case CURSOR_E_RESIZE:
922             return eastResizeCursor();
923         case CURSOR_W_RESIZE:
924             return westResizeCursor();
925         case CURSOR_N_RESIZE:
926             return northResizeCursor();
927         case CURSOR_S_RESIZE:
928             return southResizeCursor();
929         case CURSOR_NE_RESIZE:
930             return northEastResizeCursor();
931         case CURSOR_SW_RESIZE:
932             return southWestResizeCursor();
933         case CURSOR_NW_RESIZE:
934             return northWestResizeCursor();
935         case CURSOR_SE_RESIZE:
936             return southEastResizeCursor();
937         case CURSOR_NS_RESIZE:
938             return northSouthResizeCursor();
939         case CURSOR_EW_RESIZE:
940             return eastWestResizeCursor();
941         case CURSOR_NESW_RESIZE:
942             return northEastSouthWestResizeCursor();
943         case CURSOR_NWSE_RESIZE:
944             return northWestSouthEastResizeCursor();
945         case CURSOR_COL_RESIZE:
946             return columnResizeCursor();
947         case CURSOR_ROW_RESIZE:
948             return rowResizeCursor();
949         case CURSOR_TEXT:
950             return iBeamCursor();
951         case CURSOR_WAIT:
952             return waitCursor();
953         case CURSOR_HELP:
954             return helpCursor();
955         case CURSOR_VERTICAL_TEXT:
956             return verticalTextCursor();
957         case CURSOR_CELL:
958             return cellCursor();
959         case CURSOR_CONTEXT_MENU:
960             return contextMenuCursor();
961         case CURSOR_PROGRESS:
962             return progressCursor();
963         case CURSOR_NO_DROP:
964             return noDropCursor();
965         case CURSOR_ALIAS:
966             return aliasCursor();
967         case CURSOR_COPY:
968             return copyCursor();
969         case CURSOR_NONE:
970             return noneCursor();
971         case CURSOR_NOT_ALLOWED:
972             return notAllowedCursor();
973         case CURSOR_DEFAULT:
974             return pointerCursor();
975         case CURSOR_WEBKIT_ZOOM_IN:
976             return zoomInCursor();
977         case CURSOR_WEBKIT_ZOOM_OUT:
978             return zoomOutCursor();
979     }
980     return pointerCursor();
981 }
982
983 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
984 {
985     if (!m_frame->document())
986         return false;
987
988     RefPtr<FrameView> protector(m_frame->view());
989
990     m_mousePressed = true;
991     m_currentMousePosition = mouseEvent.pos();
992     m_mouseDownTimestamp = mouseEvent.timestamp();
993     m_mouseDownMayStartDrag = false;
994     m_mouseDownMayStartSelect = false;
995     m_mouseDownMayStartAutoscroll = false;
996     m_mouseDownPos = m_frame->view()->windowToContents(mouseEvent.pos());
997     m_mouseDownWasInSubframe = false;
998
999     MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, true), mouseEvent);
1000
1001     if (!mev.targetNode()) {
1002         invalidateClick();
1003         return false;
1004     }
1005
1006     m_mousePressNode = mev.targetNode();
1007
1008     InspectorController* inspector = m_frame->page()->inspectorController();
1009     if (inspector && inspector->enabled() && inspector->searchingForNodeInPage()) {
1010         inspector->handleMousePressOnNode(m_mousePressNode.get());
1011         invalidateClick();
1012         return true;
1013     }
1014
1015     Frame* subframe = subframeForHitTestResult(mev);
1016     if (subframe && passMousePressEventToSubframe(mev, subframe)) {
1017         // Start capturing future events for this frame.  We only do this if we didn't clear
1018         // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
1019         if (m_mousePressed)
1020             m_capturingMouseEventsNode = mev.targetNode();
1021         invalidateClick();
1022         return true;
1023     }
1024
1025 #if ENABLE(PAN_SCROLLING)
1026     if (m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) {
1027         stopAutoscrollTimer();
1028         invalidateClick();
1029         return true;
1030     }
1031     
1032     if (mouseEvent.button() == MiddleButton && !mev.isOverLink()) {
1033         RenderObject* renderer = mev.targetNode()->renderer();
1034
1035         while (renderer && !renderer->canBeProgramaticallyScrolled(false)) {
1036             if (!renderer->parent() && renderer->node() == renderer->document() && renderer->document()->ownerElement())
1037                 renderer = renderer->document()->ownerElement()->renderer();
1038             else
1039                 renderer = renderer->parent();
1040         }
1041
1042         if (renderer) {
1043             m_panScrollInProgress = true;
1044             handleAutoscroll(renderer);
1045             invalidateClick();
1046             return true;
1047         }
1048    }
1049 #endif
1050
1051     m_clickCount = mouseEvent.clickCount();
1052     m_clickNode = mev.targetNode();
1053     
1054     RenderLayer* layer = m_clickNode->renderer() ? m_clickNode->renderer()->enclosingLayer() : 0;
1055     IntPoint p = m_frame->view()->windowToContents(mouseEvent.pos());
1056     if (layer && layer->isPointInResizeControl(p)) {
1057         layer->setInResizeMode(true);
1058         m_resizeLayer = layer;
1059         m_offsetFromResizeCorner = layer->offsetFromResizeCorner(p);
1060         invalidateClick();
1061         return true;
1062     }
1063
1064     bool swallowEvent = dispatchMouseEvent(mousedownEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
1065
1066     // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
1067     // in case the scrollbar widget was destroyed when the mouse event was handled.
1068     if (mev.scrollbar()) {
1069         const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMouse.get();
1070         mev = prepareMouseEvent(HitTestRequest(true, true), mouseEvent);
1071
1072         if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
1073             m_lastScrollbarUnderMouse = 0;
1074     }
1075
1076     if (swallowEvent) {
1077         // scrollbars should get events anyway, even disabled controls might be scrollable
1078         if (mev.scrollbar())
1079             passMousePressEventToScrollbar(mev, mev.scrollbar());
1080     } else {
1081         // Refetch the event target node if it currently is the shadow node inside an <input> element.
1082         // If a mouse event handler changes the input element type to one that has a widget associated,
1083         // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
1084         // event target node can't still be the shadow node.
1085         if (mev.targetNode()->isShadowNode() && mev.targetNode()->shadowParentNode()->hasTagName(inputTag))
1086             mev = prepareMouseEvent(HitTestRequest(true, true), mouseEvent);
1087
1088         Scrollbar* scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);
1089         if (!scrollbar)
1090             scrollbar = mev.scrollbar();
1091         if (scrollbar && passMousePressEventToScrollbar(mev, scrollbar))
1092             swallowEvent = true;
1093         else
1094             swallowEvent = handleMousePressEvent(mev);
1095     }
1096
1097     return swallowEvent;
1098 }
1099
1100 // This method only exists for platforms that don't know how to deliver 
1101 bool EventHandler::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent)
1102 {
1103     if (!m_frame->document())
1104         return false;
1105
1106     RefPtr<FrameView> protector(m_frame->view());
1107
1108     // We get this instead of a second mouse-up 
1109     m_mousePressed = false;
1110     m_currentMousePosition = mouseEvent.pos();
1111
1112     MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, true), mouseEvent);
1113     Frame* subframe = subframeForHitTestResult(mev);
1114     if (subframe && passMousePressEventToSubframe(mev, subframe)) {
1115         m_capturingMouseEventsNode = 0;
1116         return true;
1117     }
1118
1119     m_clickCount = mouseEvent.clickCount();
1120     bool swallowMouseUpEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
1121
1122     bool swallowClickEvent = false;
1123     // Don't ever dispatch click events for right clicks
1124     if (mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode)
1125         swallowClickEvent = dispatchMouseEvent(clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
1126
1127     if (m_lastScrollbarUnderMouse)
1128         swallowMouseUpEvent = m_lastScrollbarUnderMouse->mouseUp();
1129             
1130     bool swallowMouseReleaseEvent = false;
1131     if (!swallowMouseUpEvent)
1132         swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
1133
1134     invalidateClick();
1135
1136     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1137 }
1138
1139 bool EventHandler::mouseMoved(const PlatformMouseEvent& event)
1140 {
1141     HitTestResult hoveredNode = HitTestResult(IntPoint());
1142     bool result = handleMouseMoveEvent(event, &hoveredNode);
1143
1144     Page* page = m_frame->page();
1145     if (!page)
1146         return result;
1147
1148     hoveredNode.setToNonShadowAncestor();
1149     page->chrome()->mouseDidMoveOverElement(hoveredNode, event.modifierFlags());
1150     page->chrome()->setToolTip(hoveredNode);
1151     return result;
1152 }
1153
1154 bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent, HitTestResult* hoveredNode)
1155 {
1156     // in Radar 3703768 we saw frequent crashes apparently due to the
1157     // part being null here, which seems impossible, so check for nil
1158     // but also assert so that we can try to figure this out in debug
1159     // builds, if it happens.
1160     ASSERT(m_frame);
1161     if (!m_frame || !m_frame->document())
1162         return false;
1163
1164     RefPtr<FrameView> protector(m_frame->view());
1165     m_currentMousePosition = mouseEvent.pos();
1166
1167     if (m_hoverTimer.isActive())
1168         m_hoverTimer.stop();
1169
1170 #if ENABLE(SVG)
1171     if (m_svgPan) {
1172         static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);
1173         return true;
1174     }
1175 #endif
1176
1177     if (m_frameSetBeingResized)
1178         return dispatchMouseEvent(mousemoveEvent, m_frameSetBeingResized.get(), false, 0, mouseEvent, false);
1179
1180     // Send events right to a scrollbar if the mouse is pressed.
1181     if (m_lastScrollbarUnderMouse && m_mousePressed)
1182         return m_lastScrollbarUnderMouse->mouseMoved(m_lastScrollbarUnderMouse->transformEvent(mouseEvent));
1183
1184     // Treat mouse move events while the mouse is pressed as "read-only" in prepareMouseEvent
1185     // if we are allowed to select.
1186     // This means that :hover and :active freeze in the state they were in when the mouse
1187     // was pressed, rather than updating for nodes the mouse moves over as you hold the mouse down.
1188     HitTestRequest request(m_mousePressed && m_mouseDownMayStartSelect, m_mousePressed, true);
1189     MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
1190     if (hoveredNode)
1191         *hoveredNode = mev.hitTestResult();
1192
1193     Scrollbar* scrollbar = 0;
1194
1195     if (m_resizeLayer && m_resizeLayer->inResizeMode())
1196         m_resizeLayer->resize(mouseEvent, m_offsetFromResizeCorner);
1197     else {
1198         if (m_frame->view())
1199             scrollbar = m_frame->view()->scrollbarUnderMouse(mouseEvent);
1200
1201         if (!scrollbar)
1202             scrollbar = mev.scrollbar();
1203
1204         if (m_lastScrollbarUnderMouse != scrollbar) {
1205             // Send mouse exited to the old scrollbar.
1206             if (m_lastScrollbarUnderMouse)
1207                 m_lastScrollbarUnderMouse->mouseExited();
1208             m_lastScrollbarUnderMouse = m_mousePressed ? 0 : scrollbar;
1209         }
1210     }
1211
1212     bool swallowEvent = false;
1213     RefPtr<Frame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
1214  
1215     // 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.
1216     if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree()->isDescendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
1217         passMouseMoveEventToSubframe(mev, m_lastMouseMoveEventSubframe.get());
1218
1219     if (newSubframe) {
1220         // Update over/out state before passing the event to the subframe.
1221         updateMouseEventTargetNode(mev.targetNode(), mouseEvent, true);
1222         
1223         // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
1224         // node to be detached from its FrameView, in which case the event should not be passed.
1225         if (newSubframe->view())
1226             swallowEvent |= passMouseMoveEventToSubframe(mev, newSubframe.get(), hoveredNode);
1227     } else {
1228         if (scrollbar && !m_mousePressed)
1229             scrollbar->mouseMoved(scrollbar->transformEvent(mouseEvent)); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
1230         if ((!m_resizeLayer || !m_resizeLayer->inResizeMode()) && !m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() && m_frame->view())
1231             m_frame->view()->setCursor(selectCursor(mev, scrollbar));
1232     }
1233     
1234     m_lastMouseMoveEventSubframe = newSubframe;
1235
1236     if (swallowEvent)
1237         return true;
1238     
1239     swallowEvent = dispatchMouseEvent(mousemoveEvent, mev.targetNode(), false, 0, mouseEvent, true);
1240     if (!swallowEvent)
1241         swallowEvent = handleMouseDraggedEvent(mev);
1242
1243     return swallowEvent;
1244 }
1245
1246 void EventHandler::invalidateClick()
1247 {
1248     m_clickCount = 0;
1249     m_clickNode = 0;
1250 }
1251
1252 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
1253 {
1254     if (!m_frame->document())
1255         return false;
1256
1257     RefPtr<FrameView> protector(m_frame->view());
1258
1259     m_mousePressed = false;
1260     m_currentMousePosition = mouseEvent.pos();
1261
1262 #if ENABLE(SVG)
1263     if (m_svgPan) {
1264         m_svgPan = false;
1265         static_cast<SVGDocument*>(m_frame->document())->updatePan(m_currentMousePosition);
1266         return true;
1267     }
1268 #endif
1269
1270     if (m_frameSetBeingResized)
1271         return dispatchMouseEvent(mouseupEvent, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);
1272
1273     if (m_lastScrollbarUnderMouse) {
1274         invalidateClick();
1275         return m_lastScrollbarUnderMouse->mouseUp();
1276     }
1277
1278     MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(false, false, false, true), mouseEvent);
1279     Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
1280     if (subframe && passMouseReleaseEventToSubframe(mev, subframe)) {
1281         m_capturingMouseEventsNode = 0;
1282         return true;
1283     }
1284
1285     bool swallowMouseUpEvent = dispatchMouseEvent(mouseupEvent, mev.targetNode(), true, m_clickCount, mouseEvent, false);
1286
1287     // Don't ever dispatch click events for right clicks
1288     bool swallowClickEvent = false;
1289     if (m_clickCount > 0 && mouseEvent.button() != RightButton && mev.targetNode() == m_clickNode)
1290         swallowClickEvent = dispatchMouseEvent(clickEvent, mev.targetNode(), true, m_clickCount, mouseEvent, true);
1291
1292     if (m_resizeLayer) {
1293         m_resizeLayer->setInResizeMode(false);
1294         m_resizeLayer = 0;
1295     }
1296
1297     bool swallowMouseReleaseEvent = false;
1298     if (!swallowMouseUpEvent)
1299         swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
1300
1301     invalidateClick();
1302
1303     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
1304 }
1305
1306 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, Clipboard* clipboard)
1307 {
1308     IntPoint contentsPos = m_frame->view()->windowToContents(event.pos());
1309     
1310     RefPtr<MouseEvent> me = MouseEvent::create(eventType,
1311         true, true, m_frame->document()->defaultView(),
1312         0, event.globalX(), event.globalY(), contentsPos.x(), contentsPos.y(),
1313         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
1314         0, 0, clipboard);
1315
1316     ExceptionCode ec = 0;
1317     EventTargetNodeCast(dragTarget)->dispatchEvent(me.get(), ec, true);
1318     return me->defaultPrevented();
1319 }
1320
1321 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
1322 {
1323     bool accept = false;
1324
1325     if (!m_frame->document())
1326         return false;
1327
1328     if (!m_frame->view())
1329         return false;
1330     
1331     MouseEventWithHitTestResults mev = prepareMouseEvent(HitTestRequest(true, false), event);
1332
1333     // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
1334     Node* newTarget = mev.targetNode();
1335     if (newTarget && newTarget->isTextNode())
1336         newTarget = newTarget->parentNode();
1337     if (newTarget)
1338         newTarget = newTarget->shadowAncestorNode();
1339
1340     if (m_dragTarget != newTarget) {
1341         // FIXME: this ordering was explicitly chosen to match WinIE. However,
1342         // it is sometimes incorrect when dragging within subframes, as seen with
1343         // LayoutTests/fast/events/drag-in-frames.html.
1344         if (newTarget)
1345             if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
1346                 accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
1347             else
1348                 accept = dispatchDragEvent(dragenterEvent, newTarget, event, clipboard);
1349         
1350         if (m_dragTarget) {
1351             Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) 
1352                             ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
1353             if (frame)
1354                 accept = frame->eventHandler()->updateDragAndDrop(event, clipboard);
1355             else
1356                 dispatchDragEvent(dragleaveEvent, m_dragTarget.get(), event, clipboard);
1357         }
1358     } else {
1359         if (newTarget)
1360             if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag))
1361                 accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard);
1362             else
1363                 accept = dispatchDragEvent(dragoverEvent, newTarget, event, clipboard);
1364     }
1365     m_dragTarget = newTarget;
1366
1367     return accept;
1368 }
1369
1370 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
1371 {
1372     if (m_dragTarget) {
1373         Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) 
1374                         ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
1375         if (frame)
1376             frame->eventHandler()->cancelDragAndDrop(event, clipboard);
1377         else
1378             dispatchDragEvent(dragleaveEvent, m_dragTarget.get(), event, clipboard);
1379     }
1380     clearDragState();
1381 }
1382
1383 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
1384 {
1385     bool accept = false;
1386     if (m_dragTarget) {
1387         Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) 
1388                         ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0;
1389         if (frame)
1390             accept = frame->eventHandler()->performDragAndDrop(event, clipboard);
1391         else
1392             accept = dispatchDragEvent(dropEvent, m_dragTarget.get(), event, clipboard);
1393     }
1394     clearDragState();
1395     return accept;
1396 }
1397
1398 void EventHandler::clearDragState()
1399 {
1400     m_dragTarget = 0;
1401     m_capturingMouseEventsNode = 0;
1402 #if PLATFORM(MAC)
1403     m_sendingEventToSubview = false;
1404 #endif
1405 }
1406
1407 void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n)
1408 {
1409     m_capturingMouseEventsNode = n;
1410 }
1411
1412 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mev)
1413 {
1414     ASSERT(m_frame);
1415     ASSERT(m_frame->document());
1416     
1417     IntPoint documentPoint = m_frame->view()->windowToContents(mev.pos());
1418     return m_frame->document()->prepareMouseEvent(request, documentPoint, mev);
1419 }
1420
1421 #if ENABLE(SVG)
1422 static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode)
1423 {
1424     if (!referenceNode || !referenceNode->isSVGElement())
1425         return 0;
1426
1427     Node* shadowTreeElement = referenceNode->shadowTreeRootNode();
1428     if (!shadowTreeElement)
1429         return 0;
1430
1431     Node* shadowTreeParentElement = shadowTreeElement->shadowParentNode();
1432     if (!shadowTreeParentElement)
1433         return 0;
1434
1435     ASSERT(shadowTreeParentElement->hasTagName(useTag));
1436     return static_cast<SVGUseElement*>(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);
1437 }
1438 #endif
1439
1440 void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut)
1441 {
1442     Node* result = targetNode;
1443     
1444     // If we're capturing, we always go right to that node.
1445     if (m_capturingMouseEventsNode)
1446         result = m_capturingMouseEventsNode.get();
1447     else {
1448         // If the target node is a text node, dispatch on the parent node - rdar://4196646
1449         if (result && result->isTextNode())
1450             result = result->parentNode();
1451         if (result)
1452             result = result->shadowAncestorNode();
1453     }
1454     m_nodeUnderMouse = result;
1455 #if ENABLE(SVG)
1456     m_instanceUnderMouse = instanceAssociatedWithShadowTreeElement(result);
1457
1458     // <use> shadow tree elements may have been recloned, update node under mouse in any case
1459     if (m_lastInstanceUnderMouse) {
1460         SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();
1461         SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();
1462
1463         if (lastCorrespondingElement && lastCorrespondingUseElement) {
1464             HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();
1465
1466             // Locate the recloned shadow tree element for our corresponding instance
1467             HashSet<SVGElementInstance*>::iterator end = instances.end();
1468             for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {
1469                 SVGElementInstance* instance = (*it);
1470                 ASSERT(instance->correspondingElement() == lastCorrespondingElement);
1471
1472                 if (instance == m_lastInstanceUnderMouse)
1473                     continue;
1474
1475                 if (instance->correspondingUseElement() != lastCorrespondingUseElement)
1476                     continue;
1477
1478                 SVGElement* shadowTreeElement = instance->shadowTreeElement();
1479                 if (!shadowTreeElement->inDocument() || m_lastNodeUnderMouse == shadowTreeElement)
1480                     continue;
1481
1482                 m_lastNodeUnderMouse = shadowTreeElement;
1483                 m_lastInstanceUnderMouse = instance;
1484                 break;
1485             }
1486         }
1487     }
1488 #endif
1489
1490     // Fire mouseout/mouseover if the mouse has shifted to a different node.
1491     if (fireMouseOverOut) {
1492         if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
1493             m_lastNodeUnderMouse = 0;
1494             m_lastScrollbarUnderMouse = 0;
1495 #if ENABLE(SVG)
1496             m_lastInstanceUnderMouse = 0;
1497 #endif
1498         }
1499
1500         if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
1501             // send mouseout event to the old node
1502             if (m_lastNodeUnderMouse)
1503                 EventTargetNodeCast(m_lastNodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, mouseoutEvent, 0, m_nodeUnderMouse.get());
1504             // send mouseover event to the new node
1505             if (m_nodeUnderMouse)
1506                 EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, mouseoverEvent, 0, m_lastNodeUnderMouse.get());
1507         }
1508         m_lastNodeUnderMouse = m_nodeUnderMouse;
1509 #if ENABLE(SVG)
1510         m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_nodeUnderMouse.get());
1511 #endif
1512     }
1513 }
1514
1515 bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool cancelable, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
1516 {
1517     updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
1518
1519     bool swallowEvent = false;
1520
1521     if (m_nodeUnderMouse)
1522         swallowEvent = EventTargetNodeCast(m_nodeUnderMouse.get())->dispatchMouseEvent(mouseEvent, eventType, clickCount);
1523     
1524     if (!swallowEvent && eventType == mousedownEvent) {
1525         // Blur current focus node when a link/button is clicked; this
1526         // is expected by some sites that rely on onChange handlers running
1527         // from form fields before the button click is processed.
1528         Node* node = m_nodeUnderMouse.get();
1529         RenderObject* renderer = node ? node->renderer() : 0;
1530                 
1531         // Walk up the render tree to search for a node to focus.
1532         // Walking up the DOM tree wouldn't work for shadow trees, like those behind the engine-based text fields.
1533         while (renderer) {
1534             node = renderer->element();
1535             if (node && node->isFocusable()) {
1536                 // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus a 
1537                 // node on mouse down if it's selected and inside a focused node. It will be 
1538                 // focused if the user does a mouseup over it, however, because the mouseup
1539                 // will set a selection inside it, which will call setFocuseNodeIfNeeded.
1540                 ExceptionCode ec = 0;
1541                 Node* n = node->isShadowNode() ? node->shadowParentNode() : node;
1542                 if (m_frame->selection()->isRange() && 
1543                     m_frame->selection()->toRange()->compareNode(n, ec) == Range::NODE_INSIDE &&
1544                     n->isDescendantOf(m_frame->document()->focusedNode()))
1545                     return false;
1546                     
1547                 break;
1548             }
1549             
1550             renderer = renderer->parent();
1551         }
1552         // If focus shift is blocked, we eat the event.  Note we should never clear swallowEvent
1553         // if the page already set it (e.g., by canceling default behavior).
1554         if (node && node->isMouseFocusable()) {
1555             if (!m_frame->page()->focusController()->setFocusedNode(node, m_frame))
1556                 swallowEvent = true;
1557         } else if (!node || !node->focused()) {
1558             if (!m_frame->page()->focusController()->setFocusedNode(0, m_frame))
1559                 swallowEvent = true;
1560         }
1561     }
1562
1563     return swallowEvent;
1564 }
1565
1566 bool EventHandler::handleWheelEvent(PlatformWheelEvent& e)
1567 {
1568     Document* doc = m_frame->document();
1569     if (!doc)
1570         return false;
1571
1572     RenderObject* docRenderer = doc->renderer();
1573     if (!docRenderer)
1574         return false;
1575
1576     IntPoint vPoint = m_frame->view()->windowToContents(e.pos());
1577
1578     HitTestRequest request(true, false);
1579     HitTestResult result(vPoint);
1580     doc->renderer()->layer()->hitTest(request, result);
1581     Node* node = result.innerNode();
1582     
1583     if (node) {
1584         // Figure out which view to send the event to.
1585         RenderObject* target = node->renderer();
1586         
1587         if (result.isOverWidget() && target && target->isWidget()) {
1588             Widget* widget = static_cast<RenderWidget*>(target)->widget();
1589
1590             if (widget && passWheelEventToWidget(e, widget)) {
1591                 e.accept();
1592                 return true;
1593             }
1594         }
1595
1596         node = node->shadowAncestorNode();
1597         EventTargetNodeCast(node)->dispatchWheelEvent(e);
1598         if (e.isAccepted())
1599             return true;
1600             
1601         if (node->renderer()) {
1602             // Just break up into two scrolls if we need to.  Diagonal movement on 
1603             // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
1604             scrollAndAcceptEvent(e.deltaX(), ScrollLeft, ScrollRight, e, node);
1605             scrollAndAcceptEvent(e.deltaY(), ScrollUp, ScrollDown, e, node);
1606         }
1607     }
1608
1609     if (!e.isAccepted())
1610         m_frame->view()->wheelEvent(e);
1611     
1612     return e.isAccepted();
1613 }
1614
1615 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
1616 {
1617     Document* doc = m_frame->document();
1618     FrameView* v = m_frame->view();
1619     if (!doc || !v)
1620         return false;
1621     
1622     bool swallowEvent;
1623     IntPoint viewportPos = v->windowToContents(event.pos());
1624     MouseEventWithHitTestResults mev = doc->prepareMouseEvent(HitTestRequest(false, true), viewportPos, event);
1625
1626     // Context menu events shouldn't select text in GTK+ applications.
1627 #if !PLATFORM(GTK)
1628     if (!m_frame->selection()->contains(viewportPos) && 
1629         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
1630         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
1631         // available for text selections.  But only if we're above text.
1632         (m_frame->selection()->isContentEditable() || mev.targetNode() && mev.targetNode()->isTextNode())) {
1633         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
1634         selectClosestWordOrLinkFromMouseEvent(mev);
1635     }
1636 #endif
1637
1638     swallowEvent = dispatchMouseEvent(contextmenuEvent, mev.targetNode(), true, 0, event, true);
1639     
1640     return swallowEvent;
1641 }
1642
1643 void EventHandler::scheduleHoverStateUpdate()
1644 {
1645     if (!m_hoverTimer.isActive())
1646         m_hoverTimer.startOneShot(0);
1647 }
1648
1649 // Whether or not a mouse down can begin the creation of a selection.  Fires the selectStart event.
1650 bool EventHandler::canMouseDownStartSelect(Node* node)
1651 {
1652     if (!node || !node->renderer())
1653         return true;
1654     
1655     // Some controls and images can't start a select on a mouse down.
1656     if (!node->canStartSelection())
1657         return false;
1658             
1659     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent())    
1660         if (Node* node = curr->element())
1661             return EventTargetNodeCast(node)->dispatchEventForType(selectstartEvent, true, true);
1662     
1663     return true;
1664 }
1665
1666 bool EventHandler::canMouseDragExtendSelect(Node* node)
1667 {
1668     if (!node || !node->renderer())
1669         return true;
1670             
1671     for (RenderObject* curr = node->renderer(); curr; curr = curr->parent())    
1672         if (Node* node = curr->element())
1673             return EventTargetNodeCast(node)->dispatchEventForType(selectstartEvent, true, true);
1674     
1675     return true;
1676 }
1677
1678 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
1679 {
1680     m_frameSetBeingResized = frameSet;
1681 }
1682
1683 void EventHandler::resizeLayerDestroyed()
1684 {
1685     ASSERT(m_resizeLayer);
1686     m_resizeLayer = 0;
1687 }
1688
1689 void EventHandler::hoverTimerFired(Timer<EventHandler>*)
1690 {
1691     m_hoverTimer.stop();
1692
1693     ASSERT(m_frame);
1694     ASSERT(m_frame->document());
1695
1696     if (RenderObject* renderer = m_frame->contentRenderer()) {
1697         HitTestResult result(m_frame->view()->windowToContents(m_currentMousePosition));
1698         renderer->layer()->hitTest(HitTestRequest(false, false, true), result);
1699         m_frame->document()->updateRendering();
1700     }
1701 }
1702
1703 static EventTargetNode* eventTargetNodeForDocument(Document* doc)
1704 {
1705     if (!doc)
1706         return 0;
1707     Node* node = doc->focusedNode();
1708     if (!node) {
1709         if (doc->isHTMLDocument())
1710             node = doc->body();
1711         else
1712             node = doc->documentElement();
1713         if (!node)
1714             return 0;
1715     }
1716     return EventTargetNodeCast(node);
1717 }
1718
1719 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
1720 {
1721     if ((evt.modifiers() & s_accessKeyModifiers) != s_accessKeyModifiers)
1722         return false;
1723     String key = evt.unmodifiedText();
1724     Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
1725     if (!elem)
1726         return false;
1727     elem->accessKeyAction(false);
1728     return true;
1729 }
1730
1731 #if !PLATFORM(MAC)
1732 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
1733 {
1734     return false;
1735 }
1736 #endif
1737
1738 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
1739 {
1740 #if ENABLE(PAN_SCROLLING)
1741     if (m_frame->page()->mainFrame()->eventHandler()->panScrollInProgress() || m_autoscrollInProgress) {
1742         String escKeyId = "U+001B";
1743         // If a key is pressed while the autoscroll/panScroll is in progress then we want to stop
1744         if (initialKeyEvent.keyIdentifier() == escKeyId && initialKeyEvent.type() == PlatformKeyboardEvent::KeyUp) 
1745             stopAutoscrollTimer();
1746
1747         // If we were in autoscroll/panscroll mode, we swallow the key event
1748         return true;
1749     }
1750 #endif
1751
1752     // Check for cases where we are too early for events -- possible unmatched key up
1753     // from pressing return in the location bar.
1754     RefPtr<EventTargetNode> node = eventTargetNodeForDocument(m_frame->document());
1755     if (!node)
1756         return false;
1757
1758     // FIXME: what is this doing here, in keyboard event handler?
1759     m_frame->loader()->resetMultipleFormSubmissionProtection();
1760
1761     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
1762     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
1763     // with access keys. Then we dispatch keydown, but suppress its default handling.
1764     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
1765     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
1766     bool matchedAnAccessKey = false;
1767     if (initialKeyEvent.type() == PlatformKeyboardEvent::KeyDown)
1768         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
1769
1770     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
1771     if (initialKeyEvent.type() == PlatformKeyboardEvent::KeyUp || initialKeyEvent.type() == PlatformKeyboardEvent::Char)
1772         return !node->dispatchKeyEvent(initialKeyEvent);
1773
1774     bool backwardCompatibilityMode = needsKeyboardEventDisambiguationQuirks();
1775
1776     ExceptionCode ec;
1777     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;    
1778     if (keyDownEvent.type() != PlatformKeyboardEvent::RawKeyDown)
1779         keyDownEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown, backwardCompatibilityMode);
1780     RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
1781     if (matchedAnAccessKey)
1782         keydown->setDefaultPrevented(true);
1783     keydown->setTarget(node);
1784
1785     if (initialKeyEvent.type() == PlatformKeyboardEvent::RawKeyDown) {
1786         node->dispatchEvent(keydown, ec, true);
1787         return keydown->defaultHandled() || keydown->defaultPrevented();
1788     }
1789
1790     // Run input method in advance of DOM event handling.  This may result in the IM
1791     // modifying the page prior the keydown event, but this behaviour is necessary
1792     // in order to match IE:
1793     // 1. preventing default handling of keydown and keypress events has no effect on IM input;
1794     // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
1795     m_frame->editor()->handleInputMethodKeydown(keydown.get());
1796     
1797     bool handledByInputMethod = keydown->defaultHandled();
1798     
1799     if (handledByInputMethod) {
1800         keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
1801         keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->defaultView());
1802         keydown->setTarget(node);
1803         keydown->setDefaultHandled();
1804     }
1805
1806     node->dispatchEvent(keydown, ec, true);
1807     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented();
1808     if (handledByInputMethod || (keydownResult && !backwardCompatibilityMode))
1809         return keydownResult;
1810     
1811     // Focus may have changed during keydown handling, so refetch node.
1812     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original node.
1813     if (!keydownResult) {
1814         node = eventTargetNodeForDocument(m_frame->document());
1815         if (!node)
1816             return false;
1817     }
1818
1819     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
1820     keyPressEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::Char, backwardCompatibilityMode);
1821     if (keyPressEvent.text().isEmpty())
1822         return keydownResult;
1823     RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->defaultView());
1824     keypress->setTarget(node);
1825     if (keydownResult)
1826         keypress->setDefaultPrevented(true);
1827 #if PLATFORM(MAC)
1828     keypress->keypressCommands() = keydown->keypressCommands();
1829 #endif
1830     node->dispatchEvent(keypress, ec, true);
1831
1832     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
1833 }
1834
1835 void EventHandler::handleKeyboardSelectionMovement(KeyboardEvent* event)
1836 {
1837     if (!event)
1838         return;
1839     
1840     String key = event->keyIdentifier();           
1841     bool isShifted = event->getModifierState("Shift");
1842     bool isOptioned = event->getModifierState("Alt");
1843     
1844     if (key == "Up") {
1845         m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::BACKWARD, LineGranularity, true);
1846         event->setDefaultHandled();
1847     }
1848     else if (key == "Down") { 
1849         m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::FORWARD, LineGranularity, true);
1850         event->setDefaultHandled();
1851     }
1852     else if (key == "Left") {
1853         m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::LEFT, (isOptioned) ? WordGranularity : CharacterGranularity, true);
1854         event->setDefaultHandled();
1855     }
1856     else if (key == "Right") {
1857         m_frame->selection()->modify((isShifted) ? SelectionController::EXTEND : SelectionController::MOVE, SelectionController::RIGHT, (isOptioned) ? WordGranularity : CharacterGranularity, true);
1858         event->setDefaultHandled();
1859     }    
1860 }
1861     
1862 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
1863 {
1864    if (event->type() == keydownEvent) {
1865         m_frame->editor()->handleKeyboardEvent(event);
1866         if (event->defaultHandled())
1867             return;
1868         if (event->keyIdentifier() == "U+0009")
1869             defaultTabEventHandler(event);
1870
1871        // provides KB navigation and selection for enhanced accessibility users
1872        if (AXObjectCache::accessibilityEnhancedUserInterfaceEnabled())
1873            handleKeyboardSelectionMovement(event);       
1874    }
1875    if (event->type() == keypressEvent) {
1876         m_frame->editor()->handleKeyboardEvent(event);
1877         if (event->defaultHandled())
1878             return;
1879    }
1880 }
1881
1882 bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
1883 {
1884     IntPoint dragViewportLocation((int)floatDragViewportLocation.x(), (int)floatDragViewportLocation.y());
1885     return dragHysteresisExceeded(dragViewportLocation);
1886 }
1887     
1888 bool EventHandler::dragHysteresisExceeded(const IntPoint& dragViewportLocation) const
1889 {
1890     IntPoint dragLocation = m_frame->view()->windowToContents(dragViewportLocation);
1891     IntSize delta = dragLocation - m_mouseDownPos;
1892     
1893     int threshold = GeneralDragHysteresis;
1894     if (dragState().m_dragSrcIsImage)
1895         threshold = ImageDragHysteresis;
1896     else if (dragState().m_dragSrcIsLink)
1897         threshold = LinkDragHysteresis;
1898     else if (dragState().m_dragSrcInSelection)
1899         threshold = TextDragHysteresis;
1900     
1901     return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold;
1902 }
1903     
1904 void EventHandler::freeClipboard()
1905 {
1906     if (dragState().m_dragClipboard)
1907         dragState().m_dragClipboard->setAccessPolicy(ClipboardNumb);
1908 }
1909
1910 bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const
1911 {
1912     ASSERT(node);
1913     if (node->hasChildNodes() || !m_frame->view())
1914         return false;
1915     return m_frame->page() && m_frame->page()->dragController()->mayStartDragAtEventLocation(m_frame, point);
1916 }
1917     
1918 void EventHandler::dragSourceMovedTo(const PlatformMouseEvent& event)
1919 {
1920     if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML)
1921         // for now we don't care if event handler cancels default behavior, since there is none
1922         dispatchDragSrcEvent(dragEvent, event);
1923 }
1924     
1925 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
1926 {
1927     if (dragState().m_dragSrc && dragState().m_dragSrcMayBeDHTML) {
1928         dragState().m_dragClipboard->setDestinationOperation(operation);
1929         // for now we don't care if event handler cancels default behavior, since there is none
1930         dispatchDragSrcEvent(dragendEvent, event);
1931     }
1932     freeClipboard();
1933     dragState().m_dragSrc = 0;
1934 }
1935     
1936 // returns if we should continue "default processing", i.e., whether eventhandler canceled
1937 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
1938 {
1939     return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragClipboard.get());
1940 }
1941     
1942 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event)
1943 {
1944     if (event.event().button() != LeftButton || event.event().eventType() != MouseEventMoved) {
1945         // If we allowed the other side of the bridge to handle a drag
1946         // last time, then m_mousePressed might still be set. So we
1947         // clear it now to make sure the next move after a drag
1948         // doesn't look like a drag.
1949         m_mousePressed = false;
1950         return false;
1951     }
1952     
1953     if (eventLoopHandleMouseDragged(event))
1954         return true;
1955     
1956     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
1957     
1958     if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
1959         allowDHTMLDrag(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA);
1960         if (!dragState().m_dragSrcMayBeDHTML && !dragState().m_dragSrcMayBeUA)
1961             m_mouseDownMayStartDrag = false;     // no element is draggable
1962     }
1963
1964     if (m_mouseDownMayStartDrag && !dragState().m_dragSrc) {
1965         // try to find an element that wants to be dragged
1966         HitTestRequest request(true, false);
1967         HitTestResult result(m_mouseDownPos);
1968         m_frame->contentRenderer()->layer()->hitTest(request, result);
1969         Node* node = result.innerNode();
1970         if (node && node->renderer())
1971             dragState().m_dragSrc = node->renderer()->draggableNode(dragState().m_dragSrcMayBeDHTML, dragState().m_dragSrcMayBeUA,
1972                                                                     m_mouseDownPos.x(), m_mouseDownPos.y(), dragState().m_dragSrcIsDHTML);
1973         else
1974             dragState().m_dragSrc = 0;
1975         
1976         if (!dragState().m_dragSrc)
1977             m_mouseDownMayStartDrag = false;     // no element is draggable
1978         else {
1979             // remember some facts about this source, while we have a HitTestResult handy
1980             node = result.URLElement();
1981             dragState().m_dragSrcIsLink = node && node->isLink();
1982             
1983             node = result.innerNonSharedNode();
1984             dragState().m_dragSrcIsImage = node && node->renderer() && node->renderer()->isImage();
1985             
1986             dragState().m_dragSrcInSelection = m_frame->selection()->contains(m_mouseDownPos);
1987         }                
1988     }
1989     
1990     // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
1991     // or else we bail on the dragging stuff and allow selection to occur
1992     if (m_mouseDownMayStartDrag && !dragState().m_dragSrcIsImage && dragState().m_dragSrcInSelection && event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay) {
1993         m_mouseDownMayStartDrag = false;
1994         dragState().m_dragSrc = 0;
1995         // ...but if this was the first click in the window, we don't even want to start selection
1996         if (eventActivatedView(event.event()))
1997             m_mouseDownMayStartSelect = false;
1998     }
1999     
2000     if (!m_mouseDownMayStartDrag)
2001         return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
2002     
2003     // We are starting a text/image/url drag, so the cursor should be an arrow
2004     m_frame->view()->setCursor(pointerCursor());
2005     
2006     if (!dragHysteresisExceeded(event.event().pos())) 
2007         return true;
2008     
2009     // Once we're past the hysteresis point, we don't want to treat this gesture as a click
2010     invalidateClick();
2011     
2012     DragOperation srcOp = DragOperationNone;      
2013     
2014     freeClipboard();    // would only happen if we missed a dragEnd.  Do it anyway, just
2015                         // to make sure it gets numbified
2016     dragState().m_dragClipboard = createDraggingClipboard();  
2017     
2018     if (dragState().m_dragSrcMayBeDHTML) {
2019         // Check to see if the is a DOM based drag, if it is get the DOM specified drag 
2020         // image and offset
2021         if (dragState().m_dragSrcIsDHTML) {
2022             int srcX, srcY;
2023             if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
2024                 renderer->absolutePosition(srcX, srcY);
2025                 IntSize delta = m_mouseDownPos - IntPoint(srcX, srcY);
2026                 dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint() + delta);
2027             } else {
2028                 // The renderer has disappeared, this can happen if the onStartDrag handler has hidden
2029                 // the element in some way.  In this case we just kill the drag.
2030                 m_mouseDownMayStartDrag = false;
2031                 goto cleanupDrag;
2032             }
2033         } 
2034         
2035         m_mouseDownMayStartDrag = dispatchDragSrcEvent(dragstartEvent, m_mouseDown)
2036             && !m_frame->selection()->isInPasswordField();
2037         
2038         // Invalidate clipboard here against anymore pasteboard writing for security.  The drag
2039         // image can still be changed as we drag, but not the pasteboard data.
2040         dragState().m_dragClipboard->setAccessPolicy(ClipboardImageWritable);
2041         
2042         if (m_mouseDownMayStartDrag) {
2043             // gather values from DHTML element, if it set any
2044             dragState().m_dragClipboard->sourceOperation(srcOp);
2045             
2046             // Yuck, dragSourceMovedTo() can be called as a result of kicking off the drag with
2047             // dragImage!  Because of that dumb reentrancy, we may think we've not started the
2048             // drag when that happens.  So we have to assume it's started before we kick it off.
2049             dragState().m_dragClipboard->setDragHasStarted();
2050         }
2051     }
2052     
2053     if (m_mouseDownMayStartDrag) {
2054         DragController* dragController = m_frame->page() ? m_frame->page()->dragController() : 0;
2055         bool startedDrag = dragController && dragController->startDrag(m_frame, dragState().m_dragClipboard.get(), srcOp, event.event(), m_mouseDownPos, dragState().m_dragSrcIsDHTML);
2056         if (!startedDrag && dragState().m_dragSrcMayBeDHTML) {
2057             // Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event
2058             dispatchDragSrcEvent(dragendEvent, event.event());
2059             m_mouseDownMayStartDrag = false;
2060         }
2061     } 
2062
2063 cleanupDrag:
2064     if (!m_mouseDownMayStartDrag) {
2065         // something failed to start the drag, cleanup
2066         freeClipboard();
2067         dragState().m_dragSrc = 0;
2068     }
2069     
2070     // No more default handling (like selection), whether we're past the hysteresis bounds or not
2071     return true;
2072 }
2073   
2074 bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent,
2075                                         bool isLineBreak, bool isBackTab)
2076 {
2077     if (!m_frame)
2078         return false;
2079 #ifndef NDEBUG
2080     // Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
2081     // and avoid dispatching text input events from keydown default handlers.
2082     if (underlyingEvent && underlyingEvent->isKeyboardEvent())
2083         ASSERT(static_cast<KeyboardEvent*>(underlyingEvent)->type() == keypressEvent);
2084 #endif
2085     EventTarget* target;
2086     if (underlyingEvent)
2087         target = underlyingEvent->target();
2088     else
2089         target = eventTargetNodeForDocument(m_frame->document());
2090     if (!target)
2091         return false;
2092     RefPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text);
2093     event->setUnderlyingEvent(underlyingEvent);
2094     event->setIsLineBreak(isLineBreak);
2095     event->setIsBackTab(isBackTab);
2096     ExceptionCode ec;
2097     return target->dispatchEvent(event.release(), ec, true);
2098 }
2099     
2100     
2101 #if !PLATFORM(MAC) && !PLATFORM(QT)
2102 bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const
2103 {
2104     return false;
2105 }
2106 #endif
2107
2108 bool EventHandler::tabsToLinks(KeyboardEvent* event) const
2109 {
2110     Page* page = m_frame->page();
2111     if (!page)
2112         return false;
2113
2114     if (page->chrome()->client()->tabsToLinks())
2115         return !invertSenseOfTabsToLinks(event);
2116
2117     return invertSenseOfTabsToLinks(event);
2118 }
2119
2120 void EventHandler::defaultTextInputEventHandler(TextEvent* event)
2121 {
2122     String data = event->data();
2123     if (data == "\n") {
2124         if (event->isLineBreak()) {
2125             if (m_frame->editor()->insertLineBreak())
2126                 event->setDefaultHandled();
2127         } else {
2128             if (m_frame->editor()->insertParagraphSeparator())
2129                 event->setDefaultHandled();
2130         }
2131     } else {
2132         if (m_frame->editor()->insertTextWithoutSendingTextEvent(data, false, event))
2133             event->setDefaultHandled();
2134     }
2135 }
2136
2137 void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
2138 {
2139     // We should only advance focus on tabs if no special modifier keys are held down.
2140     if (event->ctrlKey() || event->metaKey() || event->altGraphKey())
2141         return;
2142
2143     Page* page = m_frame->page();
2144     if (!page)
2145         return;
2146     if (!page->tabKeyCyclesThroughElements())
2147         return;
2148
2149     FocusDirection focusDirection = event->shiftKey() ? FocusDirectionBackward : FocusDirectionForward;
2150
2151     // Tabs can be used in design mode editing.
2152     if (m_frame->document()->inDesignMode())
2153         return;
2154
2155     if (page->focusController()->advanceFocus(focusDirection, event))
2156         event->setDefaultHandled();
2157 }
2158
2159 void EventHandler::capsLockStateMayHaveChanged()
2160 {
2161     if (Document* d = m_frame->document())
2162         if (Node* node = d->focusedNode())
2163             if (RenderObject* r = node->renderer())
2164                 r->capsLockStateMayHaveChanged();
2165 }
2166
2167 unsigned EventHandler::pendingFrameUnloadEventCount()
2168 {
2169     return m_pendingFrameUnloadEventCount;
2170 }
2171
2172 void EventHandler::addPendingFrameUnloadEventCount() 
2173 {
2174     m_pendingFrameUnloadEventCount += 1;
2175     m_frame->page()->changePendingUnloadEventCount(1);
2176     return; 
2177 }
2178     
2179 void EventHandler::removePendingFrameUnloadEventCount() 
2180 {
2181     ASSERT( (-1 + (int)m_pendingFrameUnloadEventCount) >= 0 );
2182     m_pendingFrameUnloadEventCount -= 1;
2183     m_frame->page()->changePendingUnloadEventCount(-1);
2184     return; 
2185 }
2186     
2187 void EventHandler::clearPendingFrameUnloadEventCount() 
2188 {
2189     m_frame->page()->changePendingUnloadEventCount(-((int)m_pendingFrameUnloadEventCount));
2190     m_pendingFrameUnloadEventCount = 0;
2191     return; 
2192 }
2193
2194 unsigned EventHandler::pendingFrameBeforeUnloadEventCount()
2195 {
2196     return m_pendingFrameBeforeUnloadEventCount;
2197 }
2198
2199 void EventHandler::addPendingFrameBeforeUnloadEventCount() 
2200 {
2201     m_pendingFrameBeforeUnloadEventCount += 1;
2202     m_frame->page()->changePendingBeforeUnloadEventCount(1);
2203     return; 
2204 }
2205     
2206 void EventHandler::removePendingFrameBeforeUnloadEventCount() 
2207 {
2208     ASSERT( (-1 + (int)m_pendingFrameBeforeUnloadEventCount) >= 0 );
2209     m_pendingFrameBeforeUnloadEventCount -= 1;
2210     m_frame->page()->changePendingBeforeUnloadEventCount(-1);
2211     return; 
2212 }
2213
2214     void EventHandler::clearPendingFrameBeforeUnloadEventCount() 
2215 {
2216     m_frame->page()->changePendingBeforeUnloadEventCount(-((int)m_pendingFrameBeforeUnloadEventCount));
2217     m_pendingFrameBeforeUnloadEventCount = 0;
2218     return; 
2219 }
2220
2221 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
2222 {
2223     if (!scrollbar || !scrollbar->enabled())
2224         return false;
2225     return scrollbar->mouseDown(mev.event());
2226 }
2227
2228 }