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