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