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