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