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