Home | History | Annotate | Download | only in page
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2006 Alexey Proskuryakov (ap (at) 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 
     88 namespace WebCore {
     89 
     90 using 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.
     96 const int LinkDragHysteresis = 40;
     97 const int ImageDragHysteresis = 5;
     98 const int TextDragHysteresis = 3;
     99 const 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;
    104 const int CompositionEventKeyCode = 229;
    105 
    106 #if ENABLE(SVG)
    107 using 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
    111 const double autoscrollInterval = 0.05;
    112 
    113 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
    114 
    115 static 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 
    136 inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
    137 {
    138     return false;
    139 }
    140 
    141 #if ENABLE(DRAG_SUPPORT)
    142 inline bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&)
    143 {
    144     return false;
    145 }
    146 #endif
    147 
    148 #endif
    149 
    150 EventHandler::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 
    186 EventHandler::~EventHandler()
    187 {
    188 }
    189 
    190 #if ENABLE(DRAG_SUPPORT)
    191 EventHandler::EventHandlerDragState& EventHandler::dragState()
    192 {
    193     DEFINE_STATIC_LOCAL(EventHandlerDragState, state, ());
    194     return state;
    195 }
    196 #endif // ENABLE(DRAG_SUPPORT)
    197 
    198 void 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     m_frameSetBeingResized = 0;
    213 #if ENABLE(DRAG_SUPPORT)
    214     m_dragTarget = 0;
    215     m_shouldOnlyFireDragOverEvent = false;
    216 #endif
    217     m_currentMousePosition = IntPoint();
    218     m_mousePressNode = 0;
    219     m_mousePressed = false;
    220     m_capturesDragging = false;
    221     m_capturingMouseEventsNode = 0;
    222     m_latchedWheelEventNode = 0;
    223     m_previousWheelScrolledNode = 0;
    224 #if ENABLE(TOUCH_EVENTS)
    225     m_originatingTouchPointTargets.clear();
    226 #endif
    227 }
    228 
    229 void 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 
    253 void 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 
    277 bool 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 
    295 bool 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 
    321 bool 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 
    372 bool 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)
    444 bool 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 
    485 bool 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 
    514 void 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 
    534 void 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 
    585 bool 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 
    598 bool 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 
    650 void 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 
    675 void 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 
    706 void EventHandler::startPanScrolling(RenderObject* renderer)
    707 {
    708     m_panScrollInProgress = true;
    709     m_panScrollButtonPressed = true;
    710     handleAutoscroll(renderer);
    711     invalidateClick();
    712 }
    713 
    714 void 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 
    754 RenderObject* EventHandler::autoscrollRenderer() const
    755 {
    756     return m_autoscrollRenderer;
    757 }
    758 
    759 void 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 
    773 void EventHandler::setAutoscrollRenderer(RenderObject* renderer)
    774 {
    775     m_autoscrollRenderer = renderer;
    776 }
    777 
    778 #if ENABLE(DRAG_SUPPORT)
    779 void 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 
    801 HitTestResult 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 
    859 void EventHandler::startAutoscrollTimer()
    860 {
    861     m_autoscrollTimer.startRepeating(autoscrollInterval);
    862 }
    863 
    864 void 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 
    904 Node* EventHandler::mousePressNode() const
    905 {
    906     return m_mousePressNode.get();
    907 }
    908 
    909 void EventHandler::setMousePressNode(PassRefPtr<Node> node)
    910 {
    911     m_mousePressNode = node;
    912 }
    913 
    914 bool 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 
    931 bool 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 
    946 IntPoint EventHandler::currentMousePosition() const
    947 {
    948     return m_currentMousePosition;
    949 }
    950 
    951 Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
    952 {
    953     if (!hitTestResult.isOverWidget())
    954         return 0;
    955     return EventHandler::subframeForTargetNode(hitTestResult.targetNode());
    956 }
    957 
    958 Frame* 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 
    974 static 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
    981 static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
    982 {
    983     return frame->selection()->rootEditableElement() != node->rootEditableElement();
    984 }
    985 
    986 Cursor 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 
   1142 static 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 
   1150 bool 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
   1278 bool 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 
   1314 bool 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 
   1329 bool 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 
   1427 void EventHandler::invalidateClick()
   1428 {
   1429     m_clickCount = 0;
   1430     m_clickNode = 0;
   1431 }
   1432 
   1433 bool 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)
   1493 bool 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 
   1515 bool 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 
   1544 bool 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 
   1600 void 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 
   1610 bool 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 
   1619 void 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 
   1630 void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n)
   1631 {
   1632     m_capturingMouseEventsNode = n;
   1633 }
   1634 
   1635 MouseEventWithHitTestResults 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)
   1644 static 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 
   1662 void 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 
   1737 bool 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))
   1798 bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const
   1799 {
   1800     return false;
   1801 }
   1802 #endif
   1803 
   1804 bool 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)
   1895 bool 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 
   1927 void 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.
   1934 bool 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)
   1952 bool 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 
   1966 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
   1967 {
   1968     m_frameSetBeingResized = frameSet;
   1969 }
   1970 
   1971 void EventHandler::resizeLayerDestroyed()
   1972 {
   1973     ASSERT(m_resizeLayer);
   1974     m_resizeLayer = 0;
   1975 }
   1976 
   1977 void 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 
   1994 static 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 
   2013 bool 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)
   2031 bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
   2032 {
   2033     return false;
   2034 }
   2035 #endif
   2036 
   2037 bool 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 
   2138 void 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 
   2166 void 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)
   2189 bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
   2190 {
   2191     IntPoint dragViewportLocation((int)floatDragViewportLocation.x(), (int)floatDragViewportLocation.y());
   2192     return dragHysteresisExceeded(dragViewportLocation);
   2193 }
   2194 
   2195 bool 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 
   2214 void EventHandler::freeClipboard()
   2215 {
   2216     if (dragState().m_dragClipboard)
   2217         dragState().m_dragClipboard->setAccessPolicy(ClipboardNumb);
   2218 }
   2219 
   2220 bool 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 
   2228 void 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
   2243 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
   2244 {
   2245     return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragClipboard.get());
   2246 }
   2247 
   2248 bool 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 
   2374 cleanupDrag:
   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 
   2386 bool 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)
   2417 bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent*) const
   2418 {
   2419     return false;
   2420 }
   2421 #endif
   2422 
   2423 bool 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 
   2435 void 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.
   2458 void EventHandler::defaultSpaceEventHandler(KeyboardEvent*)
   2459 {
   2460 }
   2461 
   2462 #else
   2463 
   2464 void 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 
   2482 void 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 
   2504 void 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 
   2515 void EventHandler::sendResizeEvent()
   2516 {
   2517     m_frame->document()->dispatchWindowEvent(Event::create(eventNames().resizeEvent, false, false));
   2518 }
   2519 
   2520 void EventHandler::sendScrollEvent()
   2521 {
   2522     setFrameWasScrolledByUser();
   2523     if (m_frame->view())
   2524         m_frame->document()->dispatchEvent(Event::create(eventNames().scrollEvent, true, false));
   2525 }
   2526 
   2527 void EventHandler::setFrameWasScrolledByUser()
   2528 {
   2529     FrameView* v = m_frame->view();
   2530     if (v)
   2531         v->setWasScrolledByUser(true);
   2532 }
   2533 
   2534 bool 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.
   2544 void 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 
   2556 static PassRefPtr<TouchList> assembleTargetTouches(Touch* touchTarget, TouchList* touches)
   2557 {
   2558     RefPtr<TouchList> targetTouches = TouchList::create();
   2559 
   2560     for (unsigned i = 0; i < touches->length(); ++i) {
   2561         if (touches->item(i)->target()->toNode()->isSameNode(touchTarget->target()->toNode()))
   2562             targetTouches->append(touches->item(i));
   2563     }
   2564 
   2565     return targetTouches.release();
   2566 }
   2567 
   2568 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
   2569 {
   2570     RefPtr<TouchList> touches = TouchList::create();
   2571     RefPtr<TouchList> pressedTouches = TouchList::create();
   2572     RefPtr<TouchList> releasedTouches = TouchList::create();
   2573     RefPtr<TouchList> movedTouches = TouchList::create();
   2574     RefPtr<TouchList> cancelTouches = TouchList::create();
   2575 
   2576     const Vector<PlatformTouchPoint>& points = event.touchPoints();
   2577     AtomicString* eventName = 0;
   2578 
   2579     for (unsigned i = 0; i < points.size(); ++i) {
   2580         const PlatformTouchPoint& point = points[i];
   2581         IntPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
   2582         HitTestResult result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false);
   2583         Node* target = result.innerNode();
   2584 
   2585         // Touch events should not go to text nodes
   2586         if (target && target->isTextNode())
   2587             target = target->parentNode();
   2588 
   2589         Document* doc = target->document();
   2590         if (!doc)
   2591             continue;
   2592         if (!doc->hasListenerType(Document::TOUCH_LISTENER))
   2593             continue;
   2594 
   2595         if (m_frame != doc->frame()) {
   2596             // pagePoint should always be relative to the target elements containing frame.
   2597             pagePoint = documentPointForWindowPoint(doc->frame(), point.pos());
   2598         }
   2599 
   2600         int adjustedPageX = lroundf(pagePoint.x() / m_frame->pageZoomFactor());
   2601         int adjustedPageY = lroundf(pagePoint.y() / m_frame->pageZoomFactor());
   2602 
   2603         // Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
   2604         unsigned touchPointTargetKey = point.id() + 1;
   2605         RefPtr<EventTarget> touchTarget;
   2606         if (point.state() == PlatformTouchPoint::TouchPressed) {
   2607             m_originatingTouchPointTargets.set(touchPointTargetKey, target);
   2608             touchTarget = target;
   2609         } else if (point.state() == PlatformTouchPoint::TouchReleased || point.state() == PlatformTouchPoint::TouchCancelled) {
   2610             // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
   2611             // we also remove it from the map.
   2612             touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
   2613         } else
   2614             touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
   2615 
   2616         if (!touchTarget.get())
   2617             continue;
   2618 
   2619         RefPtr<Touch> touch = Touch::create(doc->frame(), touchTarget.get(), point.id(),
   2620                                             point.screenPos().x(), point.screenPos().y(),
   2621                                             adjustedPageX, adjustedPageY);
   2622 
   2623         // touches should contain information about every touch currently on the screen.
   2624         if (point.state() != PlatformTouchPoint::TouchReleased)
   2625             touches->append(touch);
   2626 
   2627         // Now build up the correct list for changedTouches.
   2628         if (point.state() == PlatformTouchPoint::TouchReleased)
   2629             releasedTouches->append(touch);
   2630         else if (point.state() == PlatformTouchPoint::TouchCancelled)
   2631             cancelTouches->append(touch);
   2632         else if (point.state() == PlatformTouchPoint::TouchPressed)
   2633             pressedTouches->append(touch);
   2634         else if (point.state() == PlatformTouchPoint::TouchMoved)
   2635             movedTouches->append(touch);
   2636     }
   2637 
   2638     bool defaultPrevented = false;
   2639     Touch* changedTouch = 0;
   2640     EventTarget* touchEventTarget = 0;
   2641 
   2642     if (cancelTouches->length() > 0) {
   2643         // We dispatch the event to the target of the touch that caused this touch event to be generated, i.e.
   2644         // we take it from the list that will be used as the changedTouches property of the event.
   2645         // The choice to use the touch at index 0 guarantees that there is a target (as we checked the length
   2646         // above). In the case that there are multiple touches in what becomes the changedTouches list, it is
   2647         // difficult to say how we should prioritise touches and as such, item 0 is an arbitrary choice.
   2648         changedTouch = cancelTouches->item(0);
   2649         ASSERT(changedTouch);
   2650         touchEventTarget = changedTouch->target();
   2651         ASSERT(touchEventTarget);
   2652 
   2653         eventName = &eventNames().touchcancelEvent;
   2654         RefPtr<TouchEvent> cancelEv =
   2655             TouchEvent::create(TouchList::create().get(), TouchList::create().get(), cancelTouches.get(),
   2656                                                    *eventName, touchEventTarget->toNode()->document()->defaultView(),
   2657                                                    0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
   2658                                                    event.metaKey());
   2659         ExceptionCode ec = 0;
   2660         touchEventTarget->dispatchEvent(cancelEv.get(), ec);
   2661         defaultPrevented |= cancelEv->defaultPrevented();
   2662     }
   2663 
   2664     if (releasedTouches->length() > 0) {
   2665         Touch* changedTouch = releasedTouches->item(0);
   2666         ASSERT(changedTouch);
   2667         touchEventTarget = changedTouch->target();
   2668         ASSERT(touchEventTarget);
   2669 
   2670         RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
   2671 
   2672         eventName = &eventNames().touchendEvent;
   2673         RefPtr<TouchEvent> endEv =
   2674             TouchEvent::create(touches.get(), targetTouches.get(), releasedTouches.get(),
   2675                                                    *eventName, touchEventTarget->toNode()->document()->defaultView(),
   2676                                                    0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
   2677                                                    event.metaKey());
   2678         ExceptionCode ec = 0;
   2679         touchEventTarget->dispatchEvent(endEv.get(), ec);
   2680         defaultPrevented |= endEv->defaultPrevented();
   2681     }
   2682     if (pressedTouches->length() > 0) {
   2683         Touch* changedTouch = pressedTouches->item(0);
   2684         ASSERT(changedTouch);
   2685         touchEventTarget = changedTouch->target();
   2686         ASSERT(touchEventTarget);
   2687 
   2688         RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
   2689 
   2690 #if PLATFORM(ANDROID)
   2691         if (event.type() == TouchLongPress) {
   2692             eventName = &eventNames().touchlongpressEvent;
   2693             RefPtr<TouchEvent> longpressEv =
   2694                 TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
   2695                                                        *eventName, touchEventTarget->toNode()->document()->defaultView(),
   2696                                                        0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
   2697                                                        event.metaKey());
   2698             ExceptionCode ec = 0;
   2699             touchEventTarget->dispatchEvent(longpressEv.get(), ec);
   2700             defaultPrevented |= longpressEv->defaultPrevented();
   2701         } else if (event.type() == TouchDoubleTap) {
   2702             eventName = &eventNames().touchdoubletapEvent;
   2703             RefPtr<TouchEvent> doubleTapEv =
   2704                 TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
   2705                                                        *eventName, touchEventTarget->toNode()->document()->defaultView(),
   2706                                                        0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
   2707                                                        event.metaKey());
   2708             ExceptionCode ec = 0;
   2709             touchEventTarget->dispatchEvent(doubleTapEv.get(), ec);
   2710             defaultPrevented |= doubleTapEv->defaultPrevented();
   2711         } else {
   2712 #endif
   2713         eventName = &eventNames().touchstartEvent;
   2714         RefPtr<TouchEvent> startEv =
   2715             TouchEvent::create(touches.get(), targetTouches.get(), pressedTouches.get(),
   2716                                                    *eventName, touchEventTarget->toNode()->document()->defaultView(),
   2717                                                    0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
   2718                                                    event.metaKey());
   2719         ExceptionCode ec = 0;
   2720         touchEventTarget->dispatchEvent(startEv.get(), ec);
   2721         defaultPrevented |= startEv->defaultPrevented();
   2722 #if PLATFORM(ANDROID)
   2723     }
   2724 #endif
   2725     }
   2726 
   2727     if (movedTouches->length() > 0) {
   2728         Touch* changedTouch = movedTouches->item(0);
   2729         ASSERT(changedTouch);
   2730         touchEventTarget = changedTouch->target();
   2731         ASSERT(touchEventTarget);
   2732 
   2733         RefPtr<TouchList> targetTouches = assembleTargetTouches(changedTouch, touches.get());
   2734 
   2735         eventName = &eventNames().touchmoveEvent;
   2736         RefPtr<TouchEvent> moveEv =
   2737             TouchEvent::create(touches.get(), targetTouches.get(), movedTouches.get(),
   2738                                                    *eventName, touchEventTarget->toNode()->document()->defaultView(),
   2739                                                    0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(),
   2740                                                    event.metaKey());
   2741         ExceptionCode ec = 0;
   2742         touchEventTarget->dispatchEvent(moveEv.get(), ec);
   2743         defaultPrevented |= moveEv->defaultPrevented();
   2744     }
   2745 
   2746     return defaultPrevented;
   2747 }
   2748 #endif
   2749 
   2750 }
   2751