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