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  * Copyright (C) 2012 Digia Plc. and/or its subsidiary(-ies)
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "config.h"
     29 #include "core/page/EventHandler.h"
     30 
     31 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
     32 #include "core/HTMLNames.h"
     33 #include "core/InputTypeNames.h"
     34 #include "core/SVGNames.h"
     35 #include "core/clipboard/DataObject.h"
     36 #include "core/clipboard/DataTransfer.h"
     37 #include "core/dom/Document.h"
     38 #include "core/dom/DocumentMarkerController.h"
     39 #include "core/dom/Fullscreen.h"
     40 #include "core/dom/NodeRenderingTraversal.h"
     41 #include "core/dom/TouchList.h"
     42 #include "core/dom/shadow/ShadowRoot.h"
     43 #include "core/editing/Editor.h"
     44 #include "core/editing/FrameSelection.h"
     45 #include "core/editing/TextIterator.h"
     46 #include "core/editing/htmlediting.h"
     47 #include "core/events/DOMWindowEventQueue.h"
     48 #include "core/events/EventPath.h"
     49 #include "core/events/KeyboardEvent.h"
     50 #include "core/events/MouseEvent.h"
     51 #include "core/events/TextEvent.h"
     52 #include "core/events/TouchEvent.h"
     53 #include "core/events/WheelEvent.h"
     54 #include "core/fetch/ImageResource.h"
     55 #include "core/frame/EventHandlerRegistry.h"
     56 #include "core/frame/FrameView.h"
     57 #include "core/frame/LocalFrame.h"
     58 #include "core/frame/Settings.h"
     59 #include "core/html/HTMLDialogElement.h"
     60 #include "core/html/HTMLFrameElementBase.h"
     61 #include "core/html/HTMLFrameSetElement.h"
     62 #include "core/html/HTMLInputElement.h"
     63 #include "core/inspector/InspectorController.h"
     64 #include "core/loader/FrameLoader.h"
     65 #include "core/loader/FrameLoaderClient.h"
     66 #include "core/page/AutoscrollController.h"
     67 #include "core/page/BackForwardClient.h"
     68 #include "core/page/Chrome.h"
     69 #include "core/page/ChromeClient.h"
     70 #include "core/page/DragController.h"
     71 #include "core/page/DragState.h"
     72 #include "core/page/EditorClient.h"
     73 #include "core/page/FocusController.h"
     74 #include "core/page/FrameTree.h"
     75 #include "core/page/Page.h"
     76 #include "core/page/SpatialNavigation.h"
     77 #include "core/page/TouchAdjustment.h"
     78 #include "core/rendering/HitTestRequest.h"
     79 #include "core/rendering/HitTestResult.h"
     80 #include "core/rendering/RenderFlowThread.h"
     81 #include "core/rendering/RenderLayer.h"
     82 #include "core/rendering/RenderTextControlSingleLine.h"
     83 #include "core/rendering/RenderView.h"
     84 #include "core/rendering/RenderWidget.h"
     85 #include "core/rendering/style/RenderStyle.h"
     86 #include "core/svg/SVGDocumentExtensions.h"
     87 #include "platform/PlatformGestureEvent.h"
     88 #include "platform/PlatformKeyboardEvent.h"
     89 #include "platform/PlatformTouchEvent.h"
     90 #include "platform/PlatformWheelEvent.h"
     91 #include "platform/RuntimeEnabledFeatures.h"
     92 #include "platform/TraceEvent.h"
     93 #include "platform/WindowsKeyboardCodes.h"
     94 #include "platform/geometry/FloatPoint.h"
     95 #include "platform/graphics/Image.h"
     96 #include "platform/heap/Handle.h"
     97 #include "platform/scroll/ScrollAnimator.h"
     98 #include "platform/scroll/Scrollbar.h"
     99 #include "wtf/Assertions.h"
    100 #include "wtf/CurrentTime.h"
    101 #include "wtf/StdLibExtras.h"
    102 #include "wtf/TemporaryChange.h"
    103 
    104 namespace blink {
    105 
    106 using namespace HTMLNames;
    107 
    108 // The link drag hysteresis is much larger than the others because there
    109 // needs to be enough space to cancel the link press without starting a link drag,
    110 // and because dragging links is rare.
    111 static const int LinkDragHysteresis = 40;
    112 static const int ImageDragHysteresis = 5;
    113 static const int TextDragHysteresis = 3;
    114 static const int GeneralDragHysteresis = 3;
    115 
    116 // The amount of time to wait before sending a fake mouse event, triggered
    117 // during a scroll. The short interval is used if the content responds to the mouse events quickly enough,
    118 // otherwise the long interval is used.
    119 static const double fakeMouseMoveShortInterval = 0.1;
    120 static const double fakeMouseMoveLongInterval = 0.250;
    121 
    122 // The amount of time to wait for a cursor update on style and layout changes
    123 // Set to 50Hz, no need to be faster than common screen refresh rate
    124 static const double cursorUpdateInterval = 0.02;
    125 
    126 static const int maximumCursorSize = 128;
    127 
    128 // It's pretty unlikely that a scale of less than one would ever be used. But all we really
    129 // need to ensure here is that the scale isn't so small that integer overflow can occur when
    130 // dividing cursor sizes (limited above) by the scale.
    131 static const double minimumCursorScale = 0.001;
    132 
    133 // The minimum amount of time an element stays active after a ShowPress
    134 // This is roughly 9 frames, which should be long enough to be noticeable.
    135 static const double minimumActiveInterval = 0.15;
    136 
    137 #if OS(MACOSX)
    138 static const double TextDragDelay = 0.15;
    139 #else
    140 static const double TextDragDelay = 0.0;
    141 #endif
    142 
    143 enum NoCursorChangeType { NoCursorChange };
    144 
    145 class OptionalCursor {
    146 public:
    147     OptionalCursor(NoCursorChangeType) : m_isCursorChange(false) { }
    148     OptionalCursor(const Cursor& cursor) : m_isCursorChange(true), m_cursor(cursor) { }
    149 
    150     bool isCursorChange() const { return m_isCursorChange; }
    151     const Cursor& cursor() const { ASSERT(m_isCursorChange); return m_cursor; }
    152 
    153 private:
    154     bool m_isCursorChange;
    155     Cursor m_cursor;
    156 };
    157 
    158 class MaximumDurationTracker {
    159 public:
    160     explicit MaximumDurationTracker(double *maxDuration)
    161         : m_maxDuration(maxDuration)
    162         , m_start(monotonicallyIncreasingTime())
    163     {
    164     }
    165 
    166     ~MaximumDurationTracker()
    167     {
    168         *m_maxDuration = max(*m_maxDuration, monotonicallyIncreasingTime() - m_start);
    169     }
    170 
    171 private:
    172     double* m_maxDuration;
    173     double m_start;
    174 };
    175 
    176 static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned deltaMode)
    177 {
    178     switch (deltaMode) {
    179     case WheelEvent::DOM_DELTA_PAGE:
    180         return ScrollByPage;
    181     case WheelEvent::DOM_DELTA_LINE:
    182         return ScrollByLine;
    183     case WheelEvent::DOM_DELTA_PIXEL:
    184         return ScrollByPixel;
    185     default:
    186         return ScrollByPixel;
    187     }
    188 }
    189 
    190 // Refetch the event target node if it is removed or currently is the shadow node inside an <input> element.
    191 // If a mouse event handler changes the input element type to one that has a widget associated,
    192 // we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
    193 // event target node can't still be the shadow node.
    194 static inline bool shouldRefetchEventTarget(const MouseEventWithHitTestResults& mev)
    195 {
    196     Node* targetNode = mev.innerNode();
    197     if (!targetNode || !targetNode->parentNode())
    198         return true;
    199     return targetNode->isShadowRoot() && isHTMLInputElement(*toShadowRoot(targetNode)->host());
    200 }
    201 
    202 EventHandler::EventHandler(LocalFrame* frame)
    203     : m_frame(frame)
    204     , m_mousePressed(false)
    205     , m_capturesDragging(false)
    206     , m_mouseDownMayStartSelect(false)
    207     , m_mouseDownMayStartDrag(false)
    208     , m_mouseDownWasSingleClickInSelection(false)
    209     , m_selectionInitiationState(HaveNotStartedSelection)
    210     , m_hoverTimer(this, &EventHandler::hoverTimerFired)
    211     , m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired)
    212     , m_mouseDownMayStartAutoscroll(false)
    213     , m_mouseDownWasInSubframe(false)
    214     , m_fakeMouseMoveEventTimer(this, &EventHandler::fakeMouseMoveEventTimerFired)
    215     , m_svgPan(false)
    216     , m_resizeScrollableArea(0)
    217     , m_eventHandlerWillResetCapturingMouseEventsNode(0)
    218     , m_clickCount(0)
    219     , m_shouldOnlyFireDragOverEvent(false)
    220     , m_mousePositionIsUnknown(true)
    221     , m_mouseDownTimestamp(0)
    222     , m_widgetIsLatched(false)
    223     , m_touchPressed(false)
    224     , m_scrollGestureHandlingNode(nullptr)
    225     , m_lastGestureScrollOverWidget(false)
    226     , m_maxMouseMovedDuration(0)
    227     , m_didStartDrag(false)
    228     , m_longTapShouldInvokeContextMenu(false)
    229     , m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
    230     , m_lastShowPressTimestamp(0)
    231 {
    232 }
    233 
    234 EventHandler::~EventHandler()
    235 {
    236     ASSERT(!m_fakeMouseMoveEventTimer.isActive());
    237 }
    238 
    239 void EventHandler::trace(Visitor* visitor)
    240 {
    241 #if ENABLE(OILPAN)
    242     visitor->trace(m_mousePressNode);
    243     visitor->trace(m_capturingMouseEventsNode);
    244     visitor->trace(m_nodeUnderMouse);
    245     visitor->trace(m_lastNodeUnderMouse);
    246     visitor->trace(m_lastMouseMoveEventSubframe);
    247     visitor->trace(m_clickNode);
    248     visitor->trace(m_dragTarget);
    249     visitor->trace(m_frameSetBeingResized);
    250     visitor->trace(m_latchedWheelEventNode);
    251     visitor->trace(m_previousWheelScrolledNode);
    252     visitor->trace(m_targetForTouchID);
    253     visitor->trace(m_touchSequenceDocument);
    254     visitor->trace(m_scrollGestureHandlingNode);
    255     visitor->trace(m_previousGestureScrolledNode);
    256     visitor->trace(m_lastDeferredTapElement);
    257 #endif
    258 }
    259 
    260 DragState& EventHandler::dragState()
    261 {
    262     DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<DragState>, state, (adoptPtrWillBeNoop(new DragState())));
    263     return *state;
    264 }
    265 
    266 void EventHandler::clear()
    267 {
    268     m_hoverTimer.stop();
    269     m_cursorUpdateTimer.stop();
    270     m_fakeMouseMoveEventTimer.stop();
    271     m_activeIntervalTimer.stop();
    272     m_resizeScrollableArea = 0;
    273     m_nodeUnderMouse = nullptr;
    274     m_lastNodeUnderMouse = nullptr;
    275     m_lastMouseMoveEventSubframe = nullptr;
    276     m_lastScrollbarUnderMouse = nullptr;
    277     m_clickCount = 0;
    278     m_clickNode = nullptr;
    279     m_frameSetBeingResized = nullptr;
    280     m_dragTarget = nullptr;
    281     m_shouldOnlyFireDragOverEvent = false;
    282     m_mousePositionIsUnknown = true;
    283     m_lastKnownMousePosition = IntPoint();
    284     m_lastKnownMouseGlobalPosition = IntPoint();
    285     m_lastMouseDownUserGestureToken.clear();
    286     m_mousePressNode = nullptr;
    287     m_mousePressed = false;
    288     m_capturesDragging = false;
    289     m_capturingMouseEventsNode = nullptr;
    290     m_latchedWheelEventNode = nullptr;
    291     m_previousWheelScrolledNode = nullptr;
    292     m_targetForTouchID.clear();
    293     m_touchSequenceDocument.clear();
    294     m_touchSequenceUserGestureToken.clear();
    295     m_scrollGestureHandlingNode = nullptr;
    296     m_lastGestureScrollOverWidget = false;
    297     m_previousGestureScrolledNode = nullptr;
    298     m_scrollbarHandlingScrollGesture = nullptr;
    299     m_maxMouseMovedDuration = 0;
    300     m_didStartDrag = false;
    301     m_touchPressed = false;
    302     m_mouseDownMayStartSelect = false;
    303     m_mouseDownMayStartDrag = false;
    304     m_lastShowPressTimestamp = 0;
    305     m_lastDeferredTapElement = nullptr;
    306 }
    307 
    308 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
    309 {
    310     if (!nodeToBeRemoved.containsIncludingShadowDOM(m_clickNode.get()))
    311         return;
    312     if (nodeToBeRemoved.isInShadowTree()) {
    313         m_clickNode = nodeToBeRemoved.parentOrShadowHostNode();
    314     } else {
    315         // We don't dispatch click events if the mousedown node is removed
    316         // before a mouseup event. It is compatible with IE and Firefox.
    317         m_clickNode = nullptr;
    318     }
    319 }
    320 
    321 static void setSelectionIfNeeded(FrameSelection& selection, const VisibleSelection& newSelection)
    322 {
    323     if (selection.selection() != newSelection)
    324         selection.setSelection(newSelection);
    325 }
    326 
    327 static inline bool dispatchSelectStart(Node* node)
    328 {
    329     if (!node || !node->renderer())
    330         return true;
    331 
    332     return node->dispatchEvent(Event::createCancelableBubble(EventTypeNames::selectstart));
    333 }
    334 
    335 static VisibleSelection expandSelectionToRespectUserSelectAll(Node* targetNode, const VisibleSelection& selection)
    336 {
    337     Node* rootUserSelectAll = Position::rootUserSelectAllForNode(targetNode);
    338     if (!rootUserSelectAll)
    339         return selection;
    340 
    341     VisibleSelection newSelection(selection);
    342     newSelection.setBase(positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
    343     newSelection.setExtent(positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary));
    344 
    345     return newSelection;
    346 }
    347 
    348 bool EventHandler::updateSelectionForMouseDownDispatchingSelectStart(Node* targetNode, const VisibleSelection& selection, TextGranularity granularity)
    349 {
    350     if (Position::nodeIsUserSelectNone(targetNode))
    351         return false;
    352 
    353     if (!dispatchSelectStart(targetNode))
    354         return false;
    355 
    356     if (selection.isRange())
    357         m_selectionInitiationState = ExtendedSelection;
    358     else {
    359         granularity = CharacterGranularity;
    360         m_selectionInitiationState = PlacedCaret;
    361     }
    362 
    363     m_frame->selection().setNonDirectionalSelectionIfNeeded(selection, granularity);
    364 
    365     return true;
    366 }
    367 
    368 void EventHandler::selectClosestWordFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
    369 {
    370     Node* innerNode = result.innerNode();
    371     VisibleSelection newSelection;
    372 
    373     if (innerNode && innerNode->renderer()) {
    374         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
    375         if (pos.isNotNull()) {
    376             newSelection = VisibleSelection(pos);
    377             newSelection.expandUsingGranularity(WordGranularity);
    378         }
    379 
    380         if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
    381             newSelection.appendTrailingWhitespace();
    382 
    383         updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
    384     }
    385 }
    386 
    387 void EventHandler::selectClosestMisspellingFromHitTestResult(const HitTestResult& result, AppendTrailingWhitespace appendTrailingWhitespace)
    388 {
    389     Node* innerNode = result.innerNode();
    390     VisibleSelection newSelection;
    391 
    392     if (innerNode && innerNode->renderer()) {
    393         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
    394         Position start = pos.deepEquivalent();
    395         Position end = pos.deepEquivalent();
    396         if (pos.isNotNull()) {
    397             DocumentMarkerVector markers = innerNode->document().markers().markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
    398             if (markers.size() == 1) {
    399                 start.moveToOffset(markers[0]->startOffset());
    400                 end.moveToOffset(markers[0]->endOffset());
    401                 newSelection = VisibleSelection(start, end);
    402             }
    403         }
    404 
    405         if (appendTrailingWhitespace == ShouldAppendTrailingWhitespace && newSelection.isRange())
    406             newSelection.appendTrailingWhitespace();
    407 
    408         updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
    409     }
    410 }
    411 
    412 void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& result)
    413 {
    414     if (m_mouseDownMayStartSelect) {
    415         selectClosestWordFromHitTestResult(result.hitTestResult(),
    416             (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
    417     }
    418 }
    419 
    420 void EventHandler::selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults& result)
    421 {
    422     if (m_mouseDownMayStartSelect) {
    423         selectClosestMisspellingFromHitTestResult(result.hitTestResult(),
    424             (result.event().clickCount() == 2 && m_frame->editor().isSelectTrailingWhitespaceEnabled()) ? ShouldAppendTrailingWhitespace : DontAppendTrailingWhitespace);
    425     }
    426 }
    427 
    428 void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& result)
    429 {
    430     if (!result.hitTestResult().isLiveLink())
    431         return selectClosestWordFromMouseEvent(result);
    432 
    433     Node* innerNode = result.innerNode();
    434 
    435     if (innerNode && innerNode->renderer() && m_mouseDownMayStartSelect) {
    436         VisibleSelection newSelection;
    437         Element* URLElement = result.hitTestResult().URLElement();
    438         VisiblePosition pos(innerNode->renderer()->positionForPoint(result.localPoint()));
    439         if (pos.isNotNull() && pos.deepEquivalent().deprecatedNode()->isDescendantOf(URLElement))
    440             newSelection = VisibleSelection::selectionFromContentsOfNode(URLElement);
    441 
    442         updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), WordGranularity);
    443     }
    444 }
    445 
    446 bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
    447 {
    448     TRACE_EVENT0("blink", "EventHandler::handleMousePressEventDoubleClick");
    449 
    450     if (event.event().button() != LeftButton)
    451         return false;
    452 
    453     if (m_frame->selection().isRange()) {
    454         // A double-click when range is already selected
    455         // should not change the selection.  So, do not call
    456         // selectClosestWordFromMouseEvent, but do set
    457         // m_beganSelectingText to prevent handleMouseReleaseEvent
    458         // from setting caret selection.
    459         m_selectionInitiationState = ExtendedSelection;
    460     } else {
    461         selectClosestWordFromMouseEvent(event);
    462     }
    463     return true;
    464 }
    465 
    466 bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
    467 {
    468     TRACE_EVENT0("blink", "EventHandler::handleMousePressEventTripleClick");
    469 
    470     if (event.event().button() != LeftButton)
    471         return false;
    472 
    473     Node* innerNode = event.innerNode();
    474     if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
    475         return false;
    476 
    477     VisibleSelection newSelection;
    478     VisiblePosition pos(innerNode->renderer()->positionForPoint(event.localPoint()));
    479     if (pos.isNotNull()) {
    480         newSelection = VisibleSelection(pos);
    481         newSelection.expandUsingGranularity(ParagraphGranularity);
    482     }
    483 
    484     return updateSelectionForMouseDownDispatchingSelectStart(innerNode, expandSelectionToRespectUserSelectAll(innerNode, newSelection), ParagraphGranularity);
    485 }
    486 
    487 static int textDistance(const Position& start, const Position& end)
    488 {
    489     RefPtrWillBeRawPtr<Range> range = Range::create(*start.document(), start, end);
    490     return TextIterator::rangeLength(range.get(), true);
    491 }
    492 
    493 bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
    494 {
    495     TRACE_EVENT0("blink", "EventHandler::handleMousePressEventSingleClick");
    496 
    497     m_frame->document()->updateLayoutIgnorePendingStylesheets();
    498     Node* innerNode = event.innerNode();
    499     if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
    500         return false;
    501 
    502     // Extend the selection if the Shift key is down, unless the click is in a link.
    503     bool extendSelection = event.event().shiftKey() && !event.isOverLink();
    504 
    505     // Don't restart the selection when the mouse is pressed on an
    506     // existing selection so we can allow for text dragging.
    507     if (FrameView* view = m_frame->view()) {
    508         LayoutPoint vPoint = view->windowToContents(event.event().position());
    509         if (!extendSelection && m_frame->selection().contains(vPoint)) {
    510             m_mouseDownWasSingleClickInSelection = true;
    511             return false;
    512         }
    513     }
    514 
    515     VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(event.localPoint()));
    516     if (visiblePos.isNull())
    517         visiblePos = VisiblePosition(firstPositionInOrBeforeNode(innerNode), DOWNSTREAM);
    518     Position pos = visiblePos.deepEquivalent();
    519 
    520     VisibleSelection newSelection = m_frame->selection().selection();
    521     TextGranularity granularity = CharacterGranularity;
    522 
    523     if (extendSelection && newSelection.isCaretOrRange()) {
    524         VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(VisiblePosition(pos))));
    525         if (selectionInUserSelectAll.isRange()) {
    526             if (comparePositions(selectionInUserSelectAll.start(), newSelection.start()) < 0)
    527                 pos = selectionInUserSelectAll.start();
    528             else if (comparePositions(newSelection.end(), selectionInUserSelectAll.end()) < 0)
    529                 pos = selectionInUserSelectAll.end();
    530         }
    531 
    532         if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) {
    533             if (pos.isNotNull()) {
    534                 // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
    535                 // was created right-to-left
    536                 Position start = newSelection.start();
    537                 Position end = newSelection.end();
    538                 int distanceToStart = textDistance(start, pos);
    539                 int distanceToEnd = textDistance(pos, end);
    540                 if (distanceToStart <= distanceToEnd)
    541                     newSelection = VisibleSelection(end, pos);
    542                 else
    543                     newSelection = VisibleSelection(start, pos);
    544             }
    545         } else
    546             newSelection.setExtent(pos);
    547 
    548         if (m_frame->selection().granularity() != CharacterGranularity) {
    549             granularity = m_frame->selection().granularity();
    550             newSelection.expandUsingGranularity(m_frame->selection().granularity());
    551         }
    552     } else {
    553         newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(visiblePos));
    554     }
    555 
    556     // Updating the selection is considered side-effect of the event and so it doesn't impact the handled state.
    557     updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, granularity);
    558     return false;
    559 }
    560 
    561 static inline bool canMouseDownStartSelect(Node* node)
    562 {
    563     if (!node || !node->renderer())
    564         return true;
    565 
    566     if (!node->canStartSelection())
    567         return false;
    568 
    569     return true;
    570 }
    571 
    572 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
    573 {
    574     TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent");
    575 
    576     // Reset drag state.
    577     dragState().m_dragSrc = nullptr;
    578 
    579     cancelFakeMouseMoveEvent();
    580 
    581     m_frame->document()->updateLayoutIgnorePendingStylesheets();
    582 
    583     if (ScrollView* scrollView = m_frame->view()) {
    584         if (scrollView->isPointInScrollbarCorner(event.event().position()))
    585             return false;
    586     }
    587 
    588     bool singleClick = event.event().clickCount() <= 1;
    589 
    590     // If we got the event back, that must mean it wasn't prevented,
    591     // so it's allowed to start a drag or selection if it wasn't in a scrollbar.
    592     m_mouseDownMayStartSelect = canMouseDownStartSelect(event.innerNode()) && !event.scrollbar();
    593 
    594     m_mouseDownMayStartDrag = singleClick;
    595 
    596     m_mouseDownWasSingleClickInSelection = false;
    597 
    598     m_mouseDown = event.event();
    599 
    600     if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
    601         return true;
    602 
    603     if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGExtensions().zoomAndPanEnabled()) {
    604         if (event.event().shiftKey() && singleClick) {
    605             m_svgPan = true;
    606             m_frame->document()->accessSVGExtensions().startPan(m_frame->view()->windowToContents(event.event().position()));
    607             return true;
    608         }
    609     }
    610 
    611     // We don't do this at the start of mouse down handling,
    612     // because we don't want to do it until we know we didn't hit a widget.
    613     if (singleClick)
    614         focusDocumentView();
    615 
    616     Node* innerNode = event.innerNode();
    617 
    618     m_mousePressNode = innerNode;
    619     m_dragStartPos = event.event().position();
    620 
    621     bool swallowEvent = false;
    622     m_mousePressed = true;
    623 
    624     if (event.event().clickCount() == 2)
    625         swallowEvent = handleMousePressEventDoubleClick(event);
    626     else if (event.event().clickCount() >= 3)
    627         swallowEvent = handleMousePressEventTripleClick(event);
    628     else
    629         swallowEvent = handleMousePressEventSingleClick(event);
    630 
    631     m_mouseDownMayStartAutoscroll = m_mouseDownMayStartSelect
    632         || (m_mousePressNode && m_mousePressNode->renderBox() && m_mousePressNode->renderBox()->canBeProgramaticallyScrolled());
    633 
    634     return swallowEvent;
    635 }
    636 
    637 bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event)
    638 {
    639     TRACE_EVENT0("blink", "EventHandler::handleMouseDraggedEvent");
    640 
    641     if (!m_mousePressed)
    642         return false;
    643 
    644     if (handleDrag(event, ShouldCheckDragHysteresis))
    645         return true;
    646 
    647     Node* targetNode = event.innerNode();
    648     if (event.event().button() != LeftButton || !targetNode)
    649         return false;
    650 
    651     RenderObject* renderer = targetNode->renderer();
    652     if (!renderer) {
    653         Node* parent = NodeRenderingTraversal::parent(targetNode);
    654         if (!parent)
    655             return false;
    656 
    657         renderer = parent->renderer();
    658         if (!renderer || !renderer->isListBox())
    659             return false;
    660     }
    661 
    662     m_mouseDownMayStartDrag = false;
    663 
    664     if (m_mouseDownMayStartAutoscroll && !panScrollInProgress()) {
    665         if (AutoscrollController* controller = autoscrollController()) {
    666             controller->startAutoscrollForSelection(renderer);
    667             m_mouseDownMayStartAutoscroll = false;
    668         }
    669     }
    670 
    671     if (m_selectionInitiationState != ExtendedSelection) {
    672         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
    673         HitTestResult result(m_mouseDownPos);
    674         m_frame->document()->renderView()->hitTest(request, result);
    675 
    676         updateSelectionForMouseDrag(result);
    677     }
    678     updateSelectionForMouseDrag(event.hitTestResult());
    679     return true;
    680 }
    681 
    682 void EventHandler::updateSelectionForMouseDrag()
    683 {
    684     FrameView* view = m_frame->view();
    685     if (!view)
    686         return;
    687     RenderView* renderer = m_frame->contentRenderer();
    688     if (!renderer)
    689         return;
    690 
    691     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::Move);
    692     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
    693     renderer->hitTest(request, result);
    694     updateSelectionForMouseDrag(result);
    695 }
    696 
    697 void EventHandler::updateSelectionForMouseDrag(const HitTestResult& hitTestResult)
    698 {
    699     if (!m_mouseDownMayStartSelect)
    700         return;
    701 
    702     Node* target = hitTestResult.innerNode();
    703     if (!target)
    704         return;
    705 
    706     VisiblePosition targetPosition = m_frame->selection().selection().visiblePositionRespectingEditingBoundary(hitTestResult.localPoint(), target);
    707     // Don't modify the selection if we're not on a node.
    708     if (targetPosition.isNull())
    709         return;
    710 
    711     // Restart the selection if this is the first mouse move. This work is usually
    712     // done in handleMousePressEvent, but not if the mouse press was on an existing selection.
    713     VisibleSelection newSelection = m_frame->selection().selection();
    714 
    715     // Special case to limit selection to the containing block for SVG text.
    716     // FIXME: Isn't there a better non-SVG-specific way to do this?
    717     if (Node* selectionBaseNode = newSelection.base().deprecatedNode())
    718         if (RenderObject* selectionBaseRenderer = selectionBaseNode->renderer())
    719             if (selectionBaseRenderer->isSVGText())
    720                 if (target->renderer()->containingBlock() != selectionBaseRenderer->containingBlock())
    721                     return;
    722 
    723     if (m_selectionInitiationState == HaveNotStartedSelection && !dispatchSelectStart(target))
    724         return;
    725 
    726     if (m_selectionInitiationState != ExtendedSelection) {
    727         // Always extend selection here because it's caused by a mouse drag
    728         m_selectionInitiationState = ExtendedSelection;
    729         newSelection = VisibleSelection(targetPosition);
    730     }
    731 
    732     if (RuntimeEnabledFeatures::userSelectAllEnabled()) {
    733         Node* rootUserSelectAllForMousePressNode = Position::rootUserSelectAllForNode(m_mousePressNode.get());
    734         if (rootUserSelectAllForMousePressNode && rootUserSelectAllForMousePressNode == Position::rootUserSelectAllForNode(target)) {
    735             newSelection.setBase(positionBeforeNode(rootUserSelectAllForMousePressNode).upstream(CanCrossEditingBoundary));
    736             newSelection.setExtent(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
    737         } else {
    738             // Reset base for user select all when base is inside user-select-all area and extent < base.
    739             if (rootUserSelectAllForMousePressNode && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
    740                 newSelection.setBase(positionAfterNode(rootUserSelectAllForMousePressNode).downstream(CanCrossEditingBoundary));
    741 
    742             Node* rootUserSelectAllForTarget = Position::rootUserSelectAllForNode(target);
    743             if (rootUserSelectAllForTarget && m_mousePressNode->renderer() && comparePositions(target->renderer()->positionForPoint(hitTestResult.localPoint()), m_mousePressNode->renderer()->positionForPoint(m_dragStartPos)) < 0)
    744                 newSelection.setExtent(positionBeforeNode(rootUserSelectAllForTarget).upstream(CanCrossEditingBoundary));
    745             else if (rootUserSelectAllForTarget && m_mousePressNode->renderer())
    746                 newSelection.setExtent(positionAfterNode(rootUserSelectAllForTarget).downstream(CanCrossEditingBoundary));
    747             else
    748                 newSelection.setExtent(targetPosition);
    749         }
    750     } else {
    751         newSelection.setExtent(targetPosition);
    752     }
    753 
    754     if (m_frame->selection().granularity() != CharacterGranularity)
    755         newSelection.expandUsingGranularity(m_frame->selection().granularity());
    756 
    757     m_frame->selection().setNonDirectionalSelectionIfNeeded(newSelection, m_frame->selection().granularity(),
    758         FrameSelection::AdjustEndpointsAtBidiBoundary);
    759 }
    760 
    761 bool EventHandler::handleMouseReleaseEvent(const MouseEventWithHitTestResults& event)
    762 {
    763     AutoscrollController* controller = autoscrollController();
    764     if (controller && controller->autoscrollInProgress())
    765         stopAutoscroll();
    766 
    767     // Used to prevent mouseMoveEvent from initiating a drag before
    768     // the mouse is pressed again.
    769     m_mousePressed = false;
    770     m_capturesDragging = false;
    771     m_mouseDownMayStartDrag = false;
    772     m_mouseDownMayStartSelect = false;
    773     m_mouseDownMayStartAutoscroll = false;
    774     m_mouseDownWasInSubframe = false;
    775 
    776     bool handled = false;
    777 
    778     // Clear the selection if the mouse didn't move after the last mouse
    779     // press and it's not a context menu click.  We do this so when clicking
    780     // on the selection, the selection goes away.  However, if we are
    781     // editing, place the caret.
    782     if (m_mouseDownWasSingleClickInSelection && m_selectionInitiationState != ExtendedSelection
    783             && m_dragStartPos == event.event().position()
    784             && m_frame->selection().isRange()
    785             && event.event().button() != RightButton) {
    786         VisibleSelection newSelection;
    787         Node* node = event.innerNode();
    788         bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
    789         if (node && node->renderer() && (caretBrowsing || node->hasEditableStyle())) {
    790             VisiblePosition pos = VisiblePosition(node->renderer()->positionForPoint(event.localPoint()));
    791             newSelection = VisibleSelection(pos);
    792         }
    793 
    794         setSelectionIfNeeded(m_frame->selection(), newSelection);
    795 
    796         handled = true;
    797     }
    798 
    799     m_frame->selection().notifyRendererOfSelectionChange(UserTriggered);
    800 
    801     m_frame->selection().selectFrameElementInParentIfFullySelected();
    802 
    803     if (event.event().button() == MiddleButton && !event.isOverLink()) {
    804         // Ignore handled, since we want to paste to where the caret was placed anyway.
    805         handled = handlePasteGlobalSelection(event.event()) || handled;
    806     }
    807 
    808     return handled;
    809 }
    810 
    811 #if OS(WIN)
    812 
    813 void EventHandler::startPanScrolling(RenderObject* renderer)
    814 {
    815     if (!renderer->isBox())
    816         return;
    817     AutoscrollController* controller = autoscrollController();
    818     if (!controller)
    819         return;
    820     controller->startPanScrolling(toRenderBox(renderer), lastKnownMousePosition());
    821     invalidateClick();
    822 }
    823 
    824 #endif // OS(WIN)
    825 
    826 AutoscrollController* EventHandler::autoscrollController() const
    827 {
    828     if (Page* page = m_frame->page())
    829         return &page->autoscrollController();
    830     return 0;
    831 }
    832 
    833 bool EventHandler::panScrollInProgress() const
    834 {
    835     return autoscrollController() && autoscrollController()->panScrollInProgress();
    836 }
    837 
    838 HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding)
    839 {
    840     TRACE_EVENT0("blink", "EventHandler::hitTestResultAtPoint");
    841 
    842     // We always send hitTestResultAtPoint to the main frame if we have one,
    843     // otherwise we might hit areas that are obscured by higher frames.
    844     if (m_frame->page()) {
    845         LocalFrame* mainFrame = m_frame->localFrameRoot();
    846         if (mainFrame && m_frame != mainFrame) {
    847             FrameView* frameView = m_frame->view();
    848             FrameView* mainView = mainFrame->view();
    849             if (frameView && mainView) {
    850                 IntPoint mainFramePoint = mainView->rootViewToContents(frameView->contentsToRootView(roundedIntPoint(point)));
    851                 return mainFrame->eventHandler().hitTestResultAtPoint(mainFramePoint, hitType, padding);
    852             }
    853         }
    854     }
    855 
    856     HitTestResult result(point, padding.height(), padding.width(), padding.height(), padding.width());
    857 
    858     // RenderView::hitTest causes a layout, and we don't want to hit that until the first
    859     // layout because until then, there is nothing shown on the screen - the user can't
    860     // have intentionally clicked on something belonging to this page. Furthermore,
    861     // mousemove events before the first layout should not lead to a premature layout()
    862     // happening, which could show a flash of white.
    863     // See also the similar code in Document::prepareMouseEvent.
    864     if (!m_frame->contentRenderer() || !m_frame->view() || !m_frame->view()->didFirstLayout())
    865         return result;
    866 
    867     // hitTestResultAtPoint is specifically used to hitTest into all frames, thus it always allows child frame content.
    868     HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
    869     m_frame->contentRenderer()->hitTest(request, result);
    870     if (!request.readOnly())
    871         m_frame->document()->updateHoverActiveState(request, result.innerElement());
    872 
    873     return result;
    874 }
    875 
    876 void EventHandler::stopAutoscroll()
    877 {
    878     if (AutoscrollController* controller = autoscrollController())
    879         controller->stopAutoscroll();
    880 }
    881 
    882 Node* EventHandler::mousePressNode() const
    883 {
    884     return m_mousePressNode.get();
    885 }
    886 
    887 bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granularity, Node* startNode, Node** stopNode, float delta, IntPoint absolutePoint)
    888 {
    889     if (!delta)
    890         return false;
    891 
    892     Node* node = startNode;
    893 
    894     if (!node)
    895         node = m_frame->document()->focusedElement();
    896 
    897     if (!node)
    898         node = m_mousePressNode.get();
    899 
    900     if (!node || !node->renderer())
    901         return false;
    902 
    903     RenderBox* curBox = node->renderer()->enclosingBox();
    904     while (curBox && !curBox->isRenderView()) {
    905         ScrollDirection physicalDirection = toPhysicalDirection(
    906             direction, curBox->isHorizontalWritingMode(), curBox->style()->isFlippedBlocksWritingMode());
    907 
    908         // If we're at the stopNode, we should try to scroll it but we shouldn't bubble past it
    909         bool shouldStopBubbling = stopNode && *stopNode && curBox->node() == *stopNode;
    910         bool didScroll = curBox->scroll(physicalDirection, granularity, delta);
    911 
    912         if (didScroll && stopNode)
    913             *stopNode = curBox->node();
    914 
    915         if (didScroll || shouldStopBubbling) {
    916             setFrameWasScrolledByUser();
    917             return true;
    918         }
    919 
    920         curBox = curBox->containingBlock();
    921     }
    922 
    923     return false;
    924 }
    925 
    926 bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
    927 {
    928     // The layout needs to be up to date to determine if we can scroll. We may be
    929     // here because of an onLoad event, in which case the final layout hasn't been performed yet.
    930     m_frame->document()->updateLayoutIgnorePendingStylesheets();
    931     if (scroll(direction, granularity, startingNode))
    932         return true;
    933     LocalFrame* frame = m_frame;
    934     FrameView* view = frame->view();
    935     if (view && view->scroll(direction, granularity))
    936         return true;
    937     Frame* parentFrame = frame->tree().parent();
    938     if (!parentFrame || !parentFrame->isLocalFrame())
    939         return false;
    940     // FIXME: Broken for OOPI.
    941     return toLocalFrame(parentFrame)->eventHandler().bubblingScroll(direction, granularity, m_frame->deprecatedLocalOwner());
    942 }
    943 
    944 IntPoint EventHandler::lastKnownMousePosition() const
    945 {
    946     return m_lastKnownMousePosition;
    947 }
    948 
    949 static LocalFrame* subframeForTargetNode(Node* node)
    950 {
    951     if (!node)
    952         return 0;
    953 
    954     RenderObject* renderer = node->renderer();
    955     if (!renderer || !renderer->isWidget())
    956         return 0;
    957 
    958     // FIXME: This explicit check is needed only until RemoteFrames have RemoteFrameViews.
    959     if (isHTMLFrameElementBase(node) && toHTMLFrameElementBase(node)->contentFrame() && toHTMLFrameElementBase(node)->contentFrame()->isRemoteFrameTemporary())
    960         return 0;
    961 
    962     Widget* widget = toRenderWidget(renderer)->widget();
    963     if (!widget || !widget->isFrameView())
    964         return 0;
    965 
    966     return &toFrameView(widget)->frame();
    967 }
    968 
    969 static LocalFrame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
    970 {
    971     if (!hitTestResult.isOverWidget())
    972         return 0;
    973     return subframeForTargetNode(hitTestResult.innerNode());
    974 }
    975 
    976 static bool isSubmitImage(Node* node)
    977 {
    978     return isHTMLInputElement(node) && toHTMLInputElement(node)->type() == InputTypeNames::image;
    979 }
    980 
    981 bool EventHandler::useHandCursor(Node* node, bool isOverLink)
    982 {
    983     if (!node)
    984         return false;
    985 
    986     return ((isOverLink || isSubmitImage(node)) && !node->hasEditableStyle());
    987 }
    988 
    989 void EventHandler::cursorUpdateTimerFired(Timer<EventHandler>*)
    990 {
    991     ASSERT(m_frame);
    992     ASSERT(m_frame->document());
    993 
    994     updateCursor();
    995 }
    996 
    997 void EventHandler::updateCursor()
    998 {
    999     if (m_mousePositionIsUnknown)
   1000         return;
   1001 
   1002     FrameView* view = m_frame->view();
   1003     if (!view || !view->shouldSetCursor())
   1004         return;
   1005 
   1006     RenderView* renderView = view->renderView();
   1007     if (!renderView)
   1008         return;
   1009 
   1010     m_frame->document()->updateLayout();
   1011 
   1012     HitTestRequest request(HitTestRequest::ReadOnly);
   1013     HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
   1014     renderView->hitTest(request, result);
   1015 
   1016     OptionalCursor optionalCursor = selectCursor(result);
   1017     if (optionalCursor.isCursorChange()) {
   1018         m_currentMouseCursor = optionalCursor.cursor();
   1019         view->setCursor(m_currentMouseCursor);
   1020     }
   1021 }
   1022 
   1023 OptionalCursor EventHandler::selectCursor(const HitTestResult& result)
   1024 {
   1025     if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode())
   1026         return NoCursorChange;
   1027 
   1028     Page* page = m_frame->page();
   1029     if (!page)
   1030         return NoCursorChange;
   1031 #if OS(WIN)
   1032     if (panScrollInProgress())
   1033         return NoCursorChange;
   1034 #endif
   1035 
   1036     Node* node = result.innerPossiblyPseudoNode();
   1037     if (!node)
   1038         return selectAutoCursor(result, node, iBeamCursor());
   1039 
   1040     RenderObject* renderer = node->renderer();
   1041     RenderStyle* style = renderer ? renderer->style() : 0;
   1042 
   1043     if (renderer) {
   1044         Cursor overrideCursor;
   1045         switch (renderer->getCursor(roundedIntPoint(result.localPoint()), overrideCursor)) {
   1046         case SetCursorBasedOnStyle:
   1047             break;
   1048         case SetCursor:
   1049             return overrideCursor;
   1050         case DoNotSetCursor:
   1051             return NoCursorChange;
   1052         }
   1053     }
   1054 
   1055     if (style && style->cursors()) {
   1056         const CursorList* cursors = style->cursors();
   1057         for (unsigned i = 0; i < cursors->size(); ++i) {
   1058             StyleImage* styleImage = (*cursors)[i].image();
   1059             if (!styleImage)
   1060                 continue;
   1061             ImageResource* cachedImage = styleImage->cachedImage();
   1062             if (!cachedImage)
   1063                 continue;
   1064             float scale = styleImage->imageScaleFactor();
   1065             // Get hotspot and convert from logical pixels to physical pixels.
   1066             IntPoint hotSpot = (*cursors)[i].hotSpot();
   1067             hotSpot.scale(scale, scale);
   1068             IntSize size = cachedImage->imageForRenderer(renderer)->size();
   1069             if (cachedImage->errorOccurred())
   1070                 continue;
   1071             // Limit the size of cursors (in UI pixels) so that they cannot be
   1072             // used to cover UI elements in chrome.
   1073             size.scale(1 / scale);
   1074             if (size.width() > maximumCursorSize || size.height() > maximumCursorSize)
   1075                 continue;
   1076 
   1077             Image* image = cachedImage->imageForRenderer(renderer);
   1078             // Ensure no overflow possible in calculations above.
   1079             if (scale < minimumCursorScale)
   1080                 continue;
   1081             return Cursor(image, hotSpot, scale);
   1082         }
   1083     }
   1084 
   1085     switch (style ? style->cursor() : CURSOR_AUTO) {
   1086     case CURSOR_AUTO: {
   1087         bool horizontalText = !style || style->isHorizontalWritingMode();
   1088         const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
   1089         return selectAutoCursor(result, node, iBeam);
   1090     }
   1091     case CURSOR_CROSS:
   1092         return crossCursor();
   1093     case CURSOR_POINTER:
   1094         return handCursor();
   1095     case CURSOR_MOVE:
   1096         return moveCursor();
   1097     case CURSOR_ALL_SCROLL:
   1098         return moveCursor();
   1099     case CURSOR_E_RESIZE:
   1100         return eastResizeCursor();
   1101     case CURSOR_W_RESIZE:
   1102         return westResizeCursor();
   1103     case CURSOR_N_RESIZE:
   1104         return northResizeCursor();
   1105     case CURSOR_S_RESIZE:
   1106         return southResizeCursor();
   1107     case CURSOR_NE_RESIZE:
   1108         return northEastResizeCursor();
   1109     case CURSOR_SW_RESIZE:
   1110         return southWestResizeCursor();
   1111     case CURSOR_NW_RESIZE:
   1112         return northWestResizeCursor();
   1113     case CURSOR_SE_RESIZE:
   1114         return southEastResizeCursor();
   1115     case CURSOR_NS_RESIZE:
   1116         return northSouthResizeCursor();
   1117     case CURSOR_EW_RESIZE:
   1118         return eastWestResizeCursor();
   1119     case CURSOR_NESW_RESIZE:
   1120         return northEastSouthWestResizeCursor();
   1121     case CURSOR_NWSE_RESIZE:
   1122         return northWestSouthEastResizeCursor();
   1123     case CURSOR_COL_RESIZE:
   1124         return columnResizeCursor();
   1125     case CURSOR_ROW_RESIZE:
   1126         return rowResizeCursor();
   1127     case CURSOR_TEXT:
   1128         return iBeamCursor();
   1129     case CURSOR_WAIT:
   1130         return waitCursor();
   1131     case CURSOR_HELP:
   1132         return helpCursor();
   1133     case CURSOR_VERTICAL_TEXT:
   1134         return verticalTextCursor();
   1135     case CURSOR_CELL:
   1136         return cellCursor();
   1137     case CURSOR_CONTEXT_MENU:
   1138         return contextMenuCursor();
   1139     case CURSOR_PROGRESS:
   1140         return progressCursor();
   1141     case CURSOR_NO_DROP:
   1142         return noDropCursor();
   1143     case CURSOR_ALIAS:
   1144         return aliasCursor();
   1145     case CURSOR_COPY:
   1146         return copyCursor();
   1147     case CURSOR_NONE:
   1148         return noneCursor();
   1149     case CURSOR_NOT_ALLOWED:
   1150         return notAllowedCursor();
   1151     case CURSOR_DEFAULT:
   1152         return pointerCursor();
   1153     case CURSOR_ZOOM_IN:
   1154         return zoomInCursor();
   1155     case CURSOR_ZOOM_OUT:
   1156         return zoomOutCursor();
   1157     case CURSOR_WEBKIT_GRAB:
   1158         return grabCursor();
   1159     case CURSOR_WEBKIT_GRABBING:
   1160         return grabbingCursor();
   1161     }
   1162     return pointerCursor();
   1163 }
   1164 
   1165 OptionalCursor EventHandler::selectAutoCursor(const HitTestResult& result, Node* node, const Cursor& iBeam)
   1166 {
   1167     bool editable = (node && node->hasEditableStyle());
   1168 
   1169     if (useHandCursor(node, result.isOverLink()))
   1170         return handCursor();
   1171 
   1172     bool inResizer = false;
   1173     RenderObject* renderer = node ? node->renderer() : 0;
   1174     if (renderer && m_frame->view()) {
   1175         RenderLayer* layer = renderer->enclosingLayer();
   1176         inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
   1177     }
   1178 
   1179     // During selection, use an I-beam no matter what we're over.
   1180     // If a drag may be starting or we're capturing mouse events for a particular node, don't treat this as a selection.
   1181     if (m_mousePressed && m_mouseDownMayStartSelect
   1182         && !m_mouseDownMayStartDrag
   1183         && m_frame->selection().isCaretOrRange()
   1184         && !m_capturingMouseEventsNode) {
   1185         return iBeam;
   1186     }
   1187 
   1188     if ((editable || (renderer && renderer->isText() && node->canStartSelection())) && !inResizer && !result.scrollbar())
   1189         return iBeam;
   1190     return pointerCursor();
   1191 }
   1192 
   1193 static LayoutPoint documentPointForWindowPoint(LocalFrame* frame, const IntPoint& windowPoint)
   1194 {
   1195     FrameView* view = frame->view();
   1196     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
   1197     // Historically the code would just crash; this is clearly no worse than that.
   1198     return view ? view->windowToContents(windowPoint) : windowPoint;
   1199 }
   1200 
   1201 bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
   1202 {
   1203     TRACE_EVENT0("blink", "EventHandler::handleMousePressEvent");
   1204 
   1205     RefPtr<FrameView> protector(m_frame->view());
   1206 
   1207     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
   1208     m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken();
   1209 
   1210     cancelFakeMouseMoveEvent();
   1211     if (m_eventHandlerWillResetCapturingMouseEventsNode)
   1212         m_capturingMouseEventsNode = nullptr;
   1213     m_mousePressed = true;
   1214     m_capturesDragging = true;
   1215     setLastKnownMousePosition(mouseEvent);
   1216     m_mouseDownTimestamp = mouseEvent.timestamp();
   1217     m_mouseDownMayStartDrag = false;
   1218     m_mouseDownMayStartSelect = false;
   1219     m_mouseDownMayStartAutoscroll = false;
   1220     if (FrameView* view = m_frame->view())
   1221         m_mouseDownPos = view->windowToContents(mouseEvent.position());
   1222     else {
   1223         invalidateClick();
   1224         return false;
   1225     }
   1226     m_mouseDownWasInSubframe = false;
   1227 
   1228     HitTestRequest request(HitTestRequest::Active);
   1229     // Save the document point we generate in case the window coordinate is invalidated by what happens
   1230     // when we dispatch the event.
   1231     LayoutPoint documentPoint = documentPointForWindowPoint(m_frame, mouseEvent.position());
   1232     MouseEventWithHitTestResults mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
   1233 
   1234     if (!mev.innerNode()) {
   1235         invalidateClick();
   1236         return false;
   1237     }
   1238 
   1239     m_mousePressNode = mev.innerNode();
   1240 
   1241     RefPtrWillBeRawPtr<LocalFrame> subframe = subframeForHitTestResult(mev);
   1242     if (subframe && passMousePressEventToSubframe(mev, subframe.get())) {
   1243         // Start capturing future events for this frame.  We only do this if we didn't clear
   1244         // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
   1245         m_capturesDragging = subframe->eventHandler().capturesDragging();
   1246         if (m_mousePressed && m_capturesDragging) {
   1247             m_capturingMouseEventsNode = mev.innerNode();
   1248             m_eventHandlerWillResetCapturingMouseEventsNode = true;
   1249         }
   1250         invalidateClick();
   1251         return true;
   1252     }
   1253 
   1254 #if OS(WIN)
   1255     // We store whether pan scrolling is in progress before calling stopAutoscroll()
   1256     // because it will set m_autoscrollType to NoAutoscroll on return.
   1257     bool isPanScrollInProgress = panScrollInProgress();
   1258     stopAutoscroll();
   1259     if (isPanScrollInProgress) {
   1260         // We invalidate the click when exiting pan scrolling so that we don't inadvertently navigate
   1261         // away from the current page (e.g. the click was on a hyperlink). See <rdar://problem/6095023>.
   1262         invalidateClick();
   1263         return true;
   1264     }
   1265 #endif
   1266 
   1267     m_clickCount = mouseEvent.clickCount();
   1268     m_clickNode = mev.innerNode()->isTextNode() ?  NodeRenderingTraversal::parent(mev.innerNode()) : mev.innerNode();
   1269 
   1270     if (FrameView* view = m_frame->view()) {
   1271         RenderLayer* layer = mev.innerNode()->renderer() ? mev.innerNode()->renderer()->enclosingLayer() : 0;
   1272         IntPoint p = view->windowToContents(mouseEvent.position());
   1273         if (layer && layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(p, ResizerForPointer)) {
   1274             m_resizeScrollableArea = layer->scrollableArea();
   1275             m_resizeScrollableArea->setInResizeMode(true);
   1276             m_offsetFromResizeCorner = m_resizeScrollableArea->offsetFromResizeCorner(p);
   1277             invalidateClick();
   1278             return true;
   1279         }
   1280     }
   1281 
   1282     m_frame->selection().setCaretBlinkingSuspended(true);
   1283 
   1284     bool swallowEvent = !dispatchMouseEvent(EventTypeNames::mousedown, mev.innerNode(), m_clickCount, mouseEvent, true);
   1285     // m_selectionInitiationState is initialized after dispatching mousedown event in order not to keep the selection by DOM APIs
   1286     // Because we can't give the user the chance to handle the selection by user action like dragging if we keep the selection in case of mousedown.
   1287     // FireFox also has the same behavior and it's more compatible with other browsers.
   1288     m_selectionInitiationState = HaveNotStartedSelection;
   1289     swallowEvent = swallowEvent || handleMouseFocus(mouseEvent);
   1290     m_capturesDragging = !swallowEvent || mev.scrollbar();
   1291 
   1292     // If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
   1293     // in case the scrollbar widget was destroyed when the mouse event was handled.
   1294     if (mev.scrollbar()) {
   1295         const bool wasLastScrollBar = mev.scrollbar() == m_lastScrollbarUnderMouse.get();
   1296         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
   1297         mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
   1298         if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
   1299             m_lastScrollbarUnderMouse = nullptr;
   1300     }
   1301 
   1302     if (swallowEvent) {
   1303         // scrollbars should get events anyway, even disabled controls might be scrollable
   1304         passMousePressEventToScrollbar(mev);
   1305     } else {
   1306         if (shouldRefetchEventTarget(mev)) {
   1307             HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
   1308             mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
   1309         }
   1310 
   1311         if (passMousePressEventToScrollbar(mev))
   1312             swallowEvent = true;
   1313         else
   1314             swallowEvent = handleMousePressEvent(mev);
   1315     }
   1316 
   1317     return swallowEvent;
   1318 }
   1319 
   1320 static RenderLayer* layerForNode(Node* node)
   1321 {
   1322     if (!node)
   1323         return 0;
   1324 
   1325     RenderObject* renderer = node->renderer();
   1326     if (!renderer)
   1327         return 0;
   1328 
   1329     RenderLayer* layer = renderer->enclosingLayer();
   1330     if (!layer)
   1331         return 0;
   1332 
   1333     return layer;
   1334 }
   1335 
   1336 ScrollableArea* EventHandler::associatedScrollableArea(const RenderLayer* layer) const
   1337 {
   1338     if (RenderLayerScrollableArea* scrollableArea = layer->scrollableArea()) {
   1339         if (scrollableArea->scrollsOverflow())
   1340             return scrollableArea;
   1341     }
   1342 
   1343     return 0;
   1344 }
   1345 
   1346 bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event)
   1347 {
   1348     TRACE_EVENT0("blink", "EventHandler::handleMouseMoveEvent");
   1349 
   1350     RefPtr<FrameView> protector(m_frame->view());
   1351     MaximumDurationTracker maxDurationTracker(&m_maxMouseMovedDuration);
   1352 
   1353     HitTestResult hoveredNode = HitTestResult(LayoutPoint());
   1354     bool result = handleMouseMoveOrLeaveEvent(event, &hoveredNode);
   1355 
   1356     Page* page = m_frame->page();
   1357     if (!page)
   1358         return result;
   1359 
   1360     if (RenderLayer* layer = layerForNode(hoveredNode.innerNode())) {
   1361         if (ScrollableArea* layerScrollableArea = associatedScrollableArea(layer))
   1362             layerScrollableArea->mouseMovedInContentArea();
   1363     }
   1364 
   1365     if (FrameView* frameView = m_frame->view())
   1366         frameView->mouseMovedInContentArea();
   1367 
   1368     hoveredNode.setToShadowHostIfInUserAgentShadowRoot();
   1369     page->chrome().mouseDidMoveOverElement(hoveredNode, event.modifierFlags());
   1370     page->chrome().setToolTip(hoveredNode);
   1371 
   1372     return result;
   1373 }
   1374 
   1375 void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event)
   1376 {
   1377     TRACE_EVENT0("blink", "EventHandler::handleMouseLeaveEvent");
   1378 
   1379     RefPtr<FrameView> protector(m_frame->view());
   1380     handleMouseMoveOrLeaveEvent(event);
   1381 }
   1382 
   1383 bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
   1384 {
   1385     ASSERT(m_frame);
   1386     ASSERT(m_frame->view());
   1387 
   1388     setLastKnownMousePosition(mouseEvent);
   1389 
   1390     if (m_hoverTimer.isActive())
   1391         m_hoverTimer.stop();
   1392 
   1393     m_cursorUpdateTimer.stop();
   1394 
   1395     cancelFakeMouseMoveEvent();
   1396 
   1397     if (m_svgPan) {
   1398         m_frame->document()->accessSVGExtensions().updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
   1399         return true;
   1400     }
   1401 
   1402     if (m_frameSetBeingResized)
   1403         return !dispatchMouseEvent(EventTypeNames::mousemove, m_frameSetBeingResized.get(), 0, mouseEvent, false);
   1404 
   1405     // Send events right to a scrollbar if the mouse is pressed.
   1406     if (m_lastScrollbarUnderMouse && m_mousePressed) {
   1407         m_lastScrollbarUnderMouse->mouseMoved(mouseEvent);
   1408         return true;
   1409     }
   1410 
   1411     // Mouse events simulated from touch should not hit-test again.
   1412     ASSERT(!mouseEvent.fromTouch());
   1413 
   1414     HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move;
   1415     if (m_mousePressed)
   1416         hitType |= HitTestRequest::Active;
   1417     else if (onlyUpdateScrollbars) {
   1418         // Mouse events should be treated as "read-only" if we're updating only scrollbars. This
   1419         // means that :hover and :active freeze in the state they were in, rather than updating
   1420         // for nodes the mouse moves while the window is not key (which will be the case if
   1421         // onlyUpdateScrollbars is true).
   1422         hitType |= HitTestRequest::ReadOnly;
   1423     }
   1424 
   1425     // Treat any mouse move events as readonly if the user is currently touching the screen.
   1426     if (m_touchPressed)
   1427         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
   1428     HitTestRequest request(hitType);
   1429     MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
   1430     if (hoveredNode)
   1431         *hoveredNode = mev.hitTestResult();
   1432 
   1433     Scrollbar* scrollbar = 0;
   1434 
   1435     if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode())
   1436         m_resizeScrollableArea->resize(mouseEvent, m_offsetFromResizeCorner);
   1437     else {
   1438         if (!scrollbar)
   1439             scrollbar = mev.scrollbar();
   1440 
   1441         updateLastScrollbarUnderMouse(scrollbar, !m_mousePressed);
   1442         if (onlyUpdateScrollbars)
   1443             return true;
   1444     }
   1445 
   1446     bool swallowEvent = false;
   1447     RefPtrWillBeRawPtr<LocalFrame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
   1448 
   1449     // 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.
   1450     if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
   1451         passMouseMoveEventToSubframe(mev, m_lastMouseMoveEventSubframe.get());
   1452 
   1453     if (newSubframe) {
   1454         // Update over/out state before passing the event to the subframe.
   1455         updateMouseEventTargetNode(mev.innerNode(), mouseEvent, true);
   1456 
   1457         // Event dispatch in updateMouseEventTargetNode may have caused the subframe of the target
   1458         // node to be detached from its FrameView, in which case the event should not be passed.
   1459         if (newSubframe->view())
   1460             swallowEvent |= passMouseMoveEventToSubframe(mev, newSubframe.get(), hoveredNode);
   1461     } else {
   1462         if (scrollbar && !m_mousePressed)
   1463             scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
   1464         if (FrameView* view = m_frame->view()) {
   1465             OptionalCursor optionalCursor = selectCursor(mev.hitTestResult());
   1466             if (optionalCursor.isCursorChange()) {
   1467                 m_currentMouseCursor = optionalCursor.cursor();
   1468                 view->setCursor(m_currentMouseCursor);
   1469             }
   1470         }
   1471     }
   1472 
   1473     m_lastMouseMoveEventSubframe = newSubframe;
   1474 
   1475     if (swallowEvent)
   1476         return true;
   1477 
   1478     swallowEvent = !dispatchMouseEvent(EventTypeNames::mousemove, mev.innerNode(), 0, mouseEvent, true);
   1479     if (!swallowEvent)
   1480         swallowEvent = handleMouseDraggedEvent(mev);
   1481 
   1482     return swallowEvent;
   1483 }
   1484 
   1485 void EventHandler::invalidateClick()
   1486 {
   1487     m_clickCount = 0;
   1488     m_clickNode = nullptr;
   1489 }
   1490 
   1491 static Node* parentForClickEvent(const Node& node)
   1492 {
   1493     // IE doesn't dispatch click events for mousedown/mouseup events across form
   1494     // controls.
   1495     if (node.isHTMLElement() && toHTMLElement(node).isInteractiveContent())
   1496         return 0;
   1497     return NodeRenderingTraversal::parent(&node);
   1498 }
   1499 
   1500 bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
   1501 {
   1502     TRACE_EVENT0("blink", "EventHandler::handleMouseReleaseEvent");
   1503 
   1504     RefPtr<FrameView> protector(m_frame->view());
   1505 
   1506     m_frame->selection().setCaretBlinkingSuspended(false);
   1507 
   1508     OwnPtr<UserGestureIndicator> gestureIndicator;
   1509 
   1510     if (m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken)
   1511         gestureIndicator = adoptPtr(new UserGestureIndicator(m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken.release()));
   1512     else
   1513         gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingUserGesture));
   1514 
   1515 #if OS(WIN)
   1516     if (Page* page = m_frame->page())
   1517         page->autoscrollController().handleMouseReleaseForPanScrolling(m_frame, mouseEvent);
   1518 #endif
   1519 
   1520     m_mousePressed = false;
   1521     setLastKnownMousePosition(mouseEvent);
   1522 
   1523     if (m_svgPan) {
   1524         m_svgPan = false;
   1525         m_frame->document()->accessSVGExtensions().updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
   1526         return true;
   1527     }
   1528 
   1529     if (m_frameSetBeingResized)
   1530         return !dispatchMouseEvent(EventTypeNames::mouseup, m_frameSetBeingResized.get(), m_clickCount, mouseEvent, false);
   1531 
   1532     if (m_lastScrollbarUnderMouse) {
   1533         invalidateClick();
   1534         m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
   1535         bool setUnder = false;
   1536         return !dispatchMouseEvent(EventTypeNames::mouseup, m_lastNodeUnderMouse.get(), m_clickCount, mouseEvent, setUnder);
   1537     }
   1538 
   1539     // Mouse events simulated from touch should not hit-test again.
   1540     ASSERT(!mouseEvent.fromTouch());
   1541 
   1542     HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release;
   1543     HitTestRequest request(hitType);
   1544     MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
   1545     LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
   1546     if (m_eventHandlerWillResetCapturingMouseEventsNode)
   1547         m_capturingMouseEventsNode = nullptr;
   1548     if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
   1549         return true;
   1550 
   1551     bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.innerNode(), m_clickCount, mouseEvent, false);
   1552 
   1553     bool contextMenuEvent = mouseEvent.button() == RightButton;
   1554 #if OS(MACOSX)
   1555     // FIXME: The Mac port achieves the same behavior by checking whether the context menu is currently open in WebPage::mouseEvent(). Consider merging the implementations.
   1556     if (mouseEvent.button() == LeftButton && mouseEvent.modifiers() & PlatformEvent::CtrlKey)
   1557         contextMenuEvent = true;
   1558 #endif
   1559 
   1560     bool swallowClickEvent = false;
   1561     if (m_clickCount > 0 && !contextMenuEvent && mev.innerNode() && m_clickNode) {
   1562         if (Node* clickTargetNode = mev.innerNode()->commonAncestor(*m_clickNode, parentForClickEvent))
   1563             swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, clickTargetNode, m_clickCount, mouseEvent, true);
   1564     }
   1565 
   1566     if (m_resizeScrollableArea) {
   1567         m_resizeScrollableArea->setInResizeMode(false);
   1568         m_resizeScrollableArea = 0;
   1569     }
   1570 
   1571     bool swallowMouseReleaseEvent = false;
   1572     if (!swallowMouseUpEvent)
   1573         swallowMouseReleaseEvent = handleMouseReleaseEvent(mev);
   1574 
   1575     invalidateClick();
   1576 
   1577     return swallowMouseUpEvent || swallowClickEvent || swallowMouseReleaseEvent;
   1578 }
   1579 
   1580 bool EventHandler::handlePasteGlobalSelection(const PlatformMouseEvent& mouseEvent)
   1581 {
   1582     // If the event was a middle click, attempt to copy global selection in after
   1583     // the newly set caret position.
   1584     //
   1585     // This code is called from either the mouse up or mouse down handling. There
   1586     // is some debate about when the global selection is pasted:
   1587     //   xterm: pastes on up.
   1588     //   GTK: pastes on down.
   1589     //   Qt: pastes on up.
   1590     //   Firefox: pastes on up.
   1591     //   Chromium: pastes on up.
   1592     //
   1593     // There is something of a webcompat angle to this well, as highlighted by
   1594     // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on
   1595     // down then the text is pasted just before the onclick handler runs and
   1596     // clears the text box. So it's important this happens after the event
   1597     // handlers have been fired.
   1598     if (mouseEvent.type() != PlatformEvent::MouseReleased)
   1599         return false;
   1600 
   1601     if (!m_frame->page())
   1602         return false;
   1603     Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame();
   1604     // Do not paste here if the focus was moved somewhere else.
   1605     if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSelection())
   1606         return m_frame->editor().command("PasteGlobalSelection").execute();
   1607 
   1608     return false;
   1609 }
   1610 
   1611 
   1612 bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTarget, const PlatformMouseEvent& event, DataTransfer* dataTransfer)
   1613 {
   1614     FrameView* view = m_frame->view();
   1615 
   1616     // FIXME: We might want to dispatch a dragleave even if the view is gone.
   1617     if (!view)
   1618         return false;
   1619 
   1620     RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType,
   1621         true, true, m_frame->document()->domWindow(),
   1622         0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
   1623         event.movementDelta().x(), event.movementDelta().y(),
   1624         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
   1625         0, nullptr, dataTransfer);
   1626 
   1627     dragTarget->dispatchEvent(me.get(), IGNORE_EXCEPTION);
   1628     return me->defaultPrevented();
   1629 }
   1630 
   1631 static bool targetIsFrame(Node* target, LocalFrame*& frame)
   1632 {
   1633     if (!isHTMLFrameElementBase(target))
   1634         return false;
   1635 
   1636     // Cross-process drag and drop is not yet supported.
   1637     if (toHTMLFrameElementBase(target)->contentFrame() && !toHTMLFrameElementBase(target)->contentFrame()->isLocalFrame())
   1638         return false;
   1639 
   1640     frame = toLocalFrame(toHTMLFrameElementBase(target)->contentFrame());
   1641     return true;
   1642 }
   1643 
   1644 static bool findDropZone(Node* target, DataTransfer* dataTransfer)
   1645 {
   1646     Element* element = target->isElementNode() ? toElement(target) : target->parentElement();
   1647     for (; element; element = element->parentElement()) {
   1648         bool matched = false;
   1649         AtomicString dropZoneStr = element->fastGetAttribute(webkitdropzoneAttr);
   1650 
   1651         if (dropZoneStr.isEmpty())
   1652             continue;
   1653 
   1654         UseCounter::count(element->document(), UseCounter::PrefixedHTMLElementDropzone);
   1655 
   1656         dropZoneStr = dropZoneStr.lower();
   1657 
   1658         SpaceSplitString keywords(dropZoneStr, false);
   1659         if (keywords.isNull())
   1660             continue;
   1661 
   1662         DragOperation dragOperation = DragOperationNone;
   1663         for (unsigned i = 0; i < keywords.size(); i++) {
   1664             DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
   1665             if (op != DragOperationNone) {
   1666                 if (dragOperation == DragOperationNone)
   1667                     dragOperation = op;
   1668             } else {
   1669                 matched = matched || dataTransfer->hasDropZoneType(keywords[i].string());
   1670             }
   1671 
   1672             if (matched && dragOperation != DragOperationNone)
   1673                 break;
   1674         }
   1675         if (matched) {
   1676             dataTransfer->setDropEffect(convertDragOperationToDropZoneOperation(dragOperation));
   1677             return true;
   1678         }
   1679     }
   1680     return false;
   1681 }
   1682 
   1683 bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
   1684 {
   1685     bool accept = false;
   1686 
   1687     if (!m_frame->view())
   1688         return false;
   1689 
   1690     HitTestRequest request(HitTestRequest::ReadOnly);
   1691     MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
   1692 
   1693     // Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
   1694     RefPtrWillBeRawPtr<Node> newTarget = mev.innerNode();
   1695     if (newTarget && newTarget->isTextNode())
   1696         newTarget = NodeRenderingTraversal::parent(newTarget.get());
   1697 
   1698     if (AutoscrollController* controller = autoscrollController())
   1699         controller->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
   1700 
   1701     if (m_dragTarget != newTarget) {
   1702         // FIXME: this ordering was explicitly chosen to match WinIE. However,
   1703         // it is sometimes incorrect when dragging within subframes, as seen with
   1704         // LayoutTests/fast/events/drag-in-frames.html.
   1705         //
   1706         // 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>.
   1707         LocalFrame* targetFrame;
   1708         if (targetIsFrame(newTarget.get(), targetFrame)) {
   1709             if (targetFrame)
   1710                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
   1711         } else if (newTarget) {
   1712             // 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.
   1713             if (dragState().m_dragSrc) {
   1714                 // for now we don't care if event handler cancels default behavior, since there is none
   1715                 dispatchDragSrcEvent(EventTypeNames::drag, event);
   1716             }
   1717             accept = dispatchDragEvent(EventTypeNames::dragenter, newTarget.get(), event, dataTransfer);
   1718             if (!accept)
   1719                 accept = findDropZone(newTarget.get(), dataTransfer);
   1720         }
   1721 
   1722         if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
   1723             if (targetFrame)
   1724                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
   1725         } else if (m_dragTarget) {
   1726             dispatchDragEvent(EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer);
   1727         }
   1728 
   1729         if (newTarget) {
   1730             // We do not explicitly call dispatchDragEvent here because it could ultimately result in the appearance that
   1731             // two dragover events fired. So, we mark that we should only fire a dragover event on the next call to this function.
   1732             m_shouldOnlyFireDragOverEvent = true;
   1733         }
   1734     } else {
   1735         LocalFrame* targetFrame;
   1736         if (targetIsFrame(newTarget.get(), targetFrame)) {
   1737             if (targetFrame)
   1738                 accept = targetFrame->eventHandler().updateDragAndDrop(event, dataTransfer);
   1739         } else if (newTarget) {
   1740             // Note, when dealing with sub-frames, we may need to fire only a dragover event as a drag event may have been fired earlier.
   1741             if (!m_shouldOnlyFireDragOverEvent && dragState().m_dragSrc) {
   1742                 // for now we don't care if event handler cancels default behavior, since there is none
   1743                 dispatchDragSrcEvent(EventTypeNames::drag, event);
   1744             }
   1745             accept = dispatchDragEvent(EventTypeNames::dragover, newTarget.get(), event, dataTransfer);
   1746             if (!accept)
   1747                 accept = findDropZone(newTarget.get(), dataTransfer);
   1748             m_shouldOnlyFireDragOverEvent = false;
   1749         }
   1750     }
   1751     m_dragTarget = newTarget;
   1752 
   1753     return accept;
   1754 }
   1755 
   1756 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
   1757 {
   1758     LocalFrame* targetFrame;
   1759     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
   1760         if (targetFrame)
   1761             targetFrame->eventHandler().cancelDragAndDrop(event, dataTransfer);
   1762     } else if (m_dragTarget.get()) {
   1763         if (dragState().m_dragSrc)
   1764             dispatchDragSrcEvent(EventTypeNames::drag, event);
   1765         dispatchDragEvent(EventTypeNames::dragleave, m_dragTarget.get(), event, dataTransfer);
   1766     }
   1767     clearDragState();
   1768 }
   1769 
   1770 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, DataTransfer* dataTransfer)
   1771 {
   1772     LocalFrame* targetFrame;
   1773     bool preventedDefault = false;
   1774     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
   1775         if (targetFrame)
   1776             preventedDefault = targetFrame->eventHandler().performDragAndDrop(event, dataTransfer);
   1777     } else if (m_dragTarget.get()) {
   1778         preventedDefault = dispatchDragEvent(EventTypeNames::drop, m_dragTarget.get(), event, dataTransfer);
   1779     }
   1780     clearDragState();
   1781     return preventedDefault;
   1782 }
   1783 
   1784 void EventHandler::clearDragState()
   1785 {
   1786     stopAutoscroll();
   1787     m_dragTarget = nullptr;
   1788     m_capturingMouseEventsNode = nullptr;
   1789     m_shouldOnlyFireDragOverEvent = false;
   1790 }
   1791 
   1792 void EventHandler::setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node> n)
   1793 {
   1794     m_capturingMouseEventsNode = n;
   1795     m_eventHandlerWillResetCapturingMouseEventsNode = false;
   1796 }
   1797 
   1798 MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestRequest& request, const PlatformMouseEvent& mev)
   1799 {
   1800     ASSERT(m_frame);
   1801     ASSERT(m_frame->document());
   1802 
   1803     return m_frame->document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mev.position()), mev);
   1804 }
   1805 
   1806 void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut)
   1807 {
   1808     Node* result = targetNode;
   1809 
   1810     // If we're capturing, we always go right to that node.
   1811     if (m_capturingMouseEventsNode)
   1812         result = m_capturingMouseEventsNode.get();
   1813     else {
   1814         // If the target node is a text node, dispatch on the parent node - rdar://4196646
   1815         if (result && result->isTextNode())
   1816             result = NodeRenderingTraversal::parent(result);
   1817     }
   1818     m_nodeUnderMouse = result;
   1819 
   1820     // Fire mouseout/mouseover if the mouse has shifted to a different node.
   1821     if (fireMouseOverOut) {
   1822         RenderLayer* layerForLastNode = layerForNode(m_lastNodeUnderMouse.get());
   1823         RenderLayer* layerForNodeUnderMouse = layerForNode(m_nodeUnderMouse.get());
   1824         Page* page = m_frame->page();
   1825 
   1826         if (m_lastNodeUnderMouse && (!m_nodeUnderMouse || m_nodeUnderMouse->document() != m_frame->document())) {
   1827             // The mouse has moved between frames.
   1828             if (LocalFrame* frame = m_lastNodeUnderMouse->document().frame()) {
   1829                 if (FrameView* frameView = frame->view())
   1830                     frameView->mouseExitedContentArea();
   1831             }
   1832         } else if (page && (layerForLastNode && (!layerForNodeUnderMouse || layerForNodeUnderMouse != layerForLastNode))) {
   1833             // The mouse has moved between layers.
   1834             if (ScrollableArea* scrollableAreaForLastNode = associatedScrollableArea(layerForLastNode))
   1835                 scrollableAreaForLastNode->mouseExitedContentArea();
   1836         }
   1837 
   1838         if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
   1839             // The mouse has moved between frames.
   1840             if (LocalFrame* frame = m_nodeUnderMouse->document().frame()) {
   1841                 if (FrameView* frameView = frame->view())
   1842                     frameView->mouseEnteredContentArea();
   1843             }
   1844         } else if (page && (layerForNodeUnderMouse && (!layerForLastNode || layerForNodeUnderMouse != layerForLastNode))) {
   1845             // The mouse has moved between layers.
   1846             if (ScrollableArea* scrollableAreaForNodeUnderMouse = associatedScrollableArea(layerForNodeUnderMouse))
   1847                 scrollableAreaForNodeUnderMouse->mouseEnteredContentArea();
   1848         }
   1849 
   1850         if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
   1851             m_lastNodeUnderMouse = nullptr;
   1852             m_lastScrollbarUnderMouse = nullptr;
   1853         }
   1854 
   1855         if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
   1856             // send mouseout event to the old node
   1857             if (m_lastNodeUnderMouse)
   1858                 m_lastNodeUnderMouse->dispatchMouseEvent(mouseEvent, EventTypeNames::mouseout, 0, m_nodeUnderMouse.get());
   1859             // send mouseover event to the new node
   1860             if (m_nodeUnderMouse)
   1861                 m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, EventTypeNames::mouseover, 0, m_lastNodeUnderMouse.get());
   1862         }
   1863         m_lastNodeUnderMouse = m_nodeUnderMouse;
   1864     }
   1865 }
   1866 
   1867 // The return value means 'continue default handling.'
   1868 bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
   1869 {
   1870     updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
   1871     return !m_nodeUnderMouse || m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);
   1872 }
   1873 
   1874 // The return value means 'swallow event' (was handled), as for other handle* functions.
   1875 bool EventHandler::handleMouseFocus(const PlatformMouseEvent& mouseEvent)
   1876 {
   1877     // If clicking on a frame scrollbar, do not mess up with content focus.
   1878     if (FrameView* view = m_frame->view()) {
   1879         if (view->scrollbarAtWindowPoint(mouseEvent.position()))
   1880             return false;
   1881     }
   1882 
   1883     // The layout needs to be up to date to determine if an element is focusable.
   1884     m_frame->document()->updateLayoutIgnorePendingStylesheets();
   1885 
   1886     Element* element = 0;
   1887     if (m_nodeUnderMouse)
   1888         element = m_nodeUnderMouse->isElementNode() ? toElement(m_nodeUnderMouse) : m_nodeUnderMouse->parentOrShadowHostElement();
   1889     for (; element; element = element->parentOrShadowHostElement()) {
   1890         if (element->isFocusable() && element->focused())
   1891             return false;
   1892         if (element->isMouseFocusable())
   1893             break;
   1894     }
   1895     ASSERT(!element || element->isMouseFocusable());
   1896 
   1897     // To fix <rdar://problem/4895428> Can't drag selected ToDo, we don't focus
   1898     // a node on mouse down if it's selected and inside a focused node. It will
   1899     // be focused if the user does a mouseup over it, however, because the
   1900     // mouseup will set a selection inside it, which will call
   1901     // FrameSelection::setFocusedNodeIfNeeded.
   1902     if (element
   1903         && m_frame->selection().isRange()
   1904         && m_frame->selection().toNormalizedRange()->compareNode(element, IGNORE_EXCEPTION) == Range::NODE_INSIDE
   1905         && element->isDescendantOf(m_frame->document()->focusedElement()))
   1906         return false;
   1907 
   1908     // Only change the focus when clicking scrollbars if it can transfered to a
   1909     // mouse focusable node.
   1910     if (!element && isInsideScrollbar(mouseEvent.position()))
   1911         return true;
   1912 
   1913     if (Page* page = m_frame->page()) {
   1914         // If focus shift is blocked, we eat the event. Note we should never
   1915         // clear swallowEvent if the page already set it (e.g., by canceling
   1916         // default behavior).
   1917         if (element) {
   1918             if (!page->focusController().setFocusedElement(element, m_frame, FocusTypeMouse))
   1919                 return true;
   1920         } else {
   1921             // We call setFocusedElement even with !element in order to blur
   1922             // current focus element when a link is clicked; this is expected by
   1923             // some sites that rely on onChange handlers running from form
   1924             // fields before the button click is processed.
   1925             if (!page->focusController().setFocusedElement(0, m_frame))
   1926                 return true;
   1927         }
   1928     }
   1929 
   1930     return false;
   1931 }
   1932 
   1933 bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
   1934 {
   1935     if (RenderView* renderView = m_frame->contentRenderer()) {
   1936         HitTestRequest request(HitTestRequest::ReadOnly);
   1937         HitTestResult result(windowPoint);
   1938         renderView->hitTest(request, result);
   1939         return result.scrollbar();
   1940     }
   1941 
   1942     return false;
   1943 }
   1944 
   1945 bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
   1946 {
   1947 #define RETURN_WHEEL_EVENT_HANDLED() \
   1948     { \
   1949         setFrameWasScrolledByUser(); \
   1950         return true; \
   1951     }
   1952 
   1953     Document* doc = m_frame->document();
   1954 
   1955     if (!doc->renderView())
   1956         return false;
   1957 
   1958     RefPtr<FrameView> protector(m_frame->view());
   1959 
   1960     FrameView* view = m_frame->view();
   1961     if (!view)
   1962         return false;
   1963 
   1964     LayoutPoint vPoint = view->windowToContents(event.position());
   1965 
   1966     HitTestRequest request(HitTestRequest::ReadOnly);
   1967     HitTestResult result(vPoint);
   1968     doc->renderView()->hitTest(request, result);
   1969 
   1970     Node* node = result.innerNode();
   1971     // Wheel events should not dispatch to text nodes.
   1972     if (node && node->isTextNode())
   1973         node = NodeRenderingTraversal::parent(node);
   1974 
   1975     bool isOverWidget;
   1976     if (event.useLatchedEventNode()) {
   1977         if (!m_latchedWheelEventNode) {
   1978             m_latchedWheelEventNode = node;
   1979             m_widgetIsLatched = result.isOverWidget();
   1980         } else
   1981             node = m_latchedWheelEventNode.get();
   1982 
   1983         isOverWidget = m_widgetIsLatched;
   1984     } else {
   1985         if (m_latchedWheelEventNode)
   1986             m_latchedWheelEventNode = nullptr;
   1987         if (m_previousWheelScrolledNode)
   1988             m_previousWheelScrolledNode = nullptr;
   1989 
   1990         isOverWidget = result.isOverWidget();
   1991     }
   1992 
   1993     if (node) {
   1994         // Figure out which view to send the event to.
   1995         RenderObject* target = node->renderer();
   1996 
   1997         if (isOverWidget && target && target->isWidget()) {
   1998             Widget* widget = toRenderWidget(target)->widget();
   1999             if (widget && passWheelEventToWidget(event, widget))
   2000                 RETURN_WHEEL_EVENT_HANDLED();
   2001         }
   2002 
   2003         if (node && !node->dispatchWheelEvent(event))
   2004             RETURN_WHEEL_EVENT_HANDLED();
   2005     }
   2006 
   2007     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
   2008     view = m_frame->view();
   2009     if (!view || !view->wheelEvent(event))
   2010         return false;
   2011 
   2012     RETURN_WHEEL_EVENT_HANDLED();
   2013 
   2014 #undef RETURN_WHEEL_EVENT_HANDLED
   2015 }
   2016 
   2017 void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEvent)
   2018 {
   2019     if (!startNode || !wheelEvent)
   2020         return;
   2021 
   2022     // Ctrl + scrollwheel is reserved for triggering zoom in/out actions in Chromium.
   2023     if (wheelEvent->ctrlKey())
   2024         return;
   2025 
   2026     Node* stopNode = m_previousWheelScrolledNode.get();
   2027     ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
   2028 
   2029     // Break up into two scrolls if we need to.  Diagonal movement on
   2030     // a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
   2031     if (scroll(ScrollRight, granularity, startNode, &stopNode, wheelEvent->deltaX(), roundedIntPoint(wheelEvent->absoluteLocation())))
   2032         wheelEvent->setDefaultHandled();
   2033 
   2034     if (scroll(ScrollDown, granularity, startNode, &stopNode, wheelEvent->deltaY(), roundedIntPoint(wheelEvent->absoluteLocation())))
   2035         wheelEvent->setDefaultHandled();
   2036 
   2037     if (!m_latchedWheelEventNode)
   2038         m_previousWheelScrolledNode = stopNode;
   2039 }
   2040 
   2041 bool EventHandler::handleGestureShowPress()
   2042 {
   2043     m_lastShowPressTimestamp = WTF::currentTime();
   2044 
   2045     FrameView* view = m_frame->view();
   2046     if (!view)
   2047         return false;
   2048     if (ScrollAnimator* scrollAnimator = view->existingScrollAnimator())
   2049         scrollAnimator->cancelAnimations();
   2050     const FrameView::ScrollableAreaSet* areas = view->scrollableAreas();
   2051     if (!areas)
   2052         return false;
   2053     for (FrameView::ScrollableAreaSet::const_iterator it = areas->begin(); it != areas->end(); ++it) {
   2054         ScrollableArea* sa = *it;
   2055         ScrollAnimator* animator = sa->existingScrollAnimator();
   2056         if (animator)
   2057             animator->cancelAnimations();
   2058     }
   2059     return false;
   2060 }
   2061 
   2062 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
   2063 {
   2064     // Propagation to inner frames is handled below this function.
   2065     ASSERT(m_frame == m_frame->localFrameRoot());
   2066 
   2067     // Scrolling-related gesture events invoke EventHandler recursively for each frame down
   2068     // the chain, doing a single-frame hit-test per frame. This matches handleWheelEvent.
   2069     // FIXME: Add a test that traverses this path, e.g. for devtools overlay.
   2070     if (gestureEvent.isScrollEvent())
   2071         return handleGestureScrollEvent(gestureEvent);
   2072 
   2073     // Hit test across all frames and do touch adjustment as necessary for the event type.
   2074     GestureEventWithHitTestResults targetedEvent = targetGestureEvent(gestureEvent);
   2075 
   2076     return handleGestureEvent(targetedEvent);
   2077 }
   2078 
   2079 bool EventHandler::handleGestureEvent(const GestureEventWithHitTestResults& targetedEvent)
   2080 {
   2081     TRACE_EVENT0("input", "EventHandler::handleGestureEvent");
   2082 
   2083     // Propagation to inner frames is handled below this function.
   2084     ASSERT(m_frame == m_frame->localFrameRoot());
   2085 
   2086     // Non-scrolling related gesture events do a single cross-frame hit-test and jump
   2087     // directly to the inner most frame. This matches handleMousePressEvent etc.
   2088     ASSERT(!targetedEvent.event().isScrollEvent());
   2089 
   2090     // Route to the correct frame.
   2091     if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame())
   2092         return innerFrame->eventHandler().handleGestureEventInFrame(targetedEvent);
   2093 
   2094     // No hit test result, handle in root instance. Perhaps we should just return false instead?
   2095     return handleGestureEventInFrame(targetedEvent);
   2096 }
   2097 
   2098 bool EventHandler::handleGestureEventInFrame(const GestureEventWithHitTestResults& targetedEvent)
   2099 {
   2100     ASSERT(!targetedEvent.event().isScrollEvent());
   2101 
   2102     RefPtrWillBeRawPtr<Node> eventTarget = targetedEvent.hitTestResult().innerNode();
   2103     RefPtr<Scrollbar> scrollbar = targetedEvent.hitTestResult().scrollbar();
   2104     const PlatformGestureEvent& gestureEvent = targetedEvent.event();
   2105 
   2106     if (scrollbar) {
   2107         bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
   2108         if (gestureEvent.type() == PlatformEvent::GestureTapDown && eventSwallowed)
   2109             m_scrollbarHandlingScrollGesture = scrollbar;
   2110         if (eventSwallowed)
   2111             return true;
   2112     }
   2113 
   2114     if (eventTarget && eventTarget->dispatchGestureEvent(gestureEvent))
   2115         return true;
   2116 
   2117     switch (gestureEvent.type()) {
   2118     case PlatformEvent::GestureTap:
   2119         return handleGestureTap(targetedEvent);
   2120     case PlatformEvent::GestureShowPress:
   2121         return handleGestureShowPress();
   2122     case PlatformEvent::GestureLongPress:
   2123         return handleGestureLongPress(targetedEvent);
   2124     case PlatformEvent::GestureLongTap:
   2125         return handleGestureLongTap(targetedEvent);
   2126     case PlatformEvent::GestureTwoFingerTap:
   2127         return sendContextMenuEventForGesture(targetedEvent);
   2128     case PlatformEvent::GestureTapDown:
   2129     case PlatformEvent::GesturePinchBegin:
   2130     case PlatformEvent::GesturePinchEnd:
   2131     case PlatformEvent::GesturePinchUpdate:
   2132     case PlatformEvent::GestureTapDownCancel:
   2133     case PlatformEvent::GestureTapUnconfirmed:
   2134         break;
   2135     default:
   2136         ASSERT_NOT_REACHED();
   2137     }
   2138 
   2139     return false;
   2140 }
   2141 
   2142 bool EventHandler::handleGestureScrollEvent(const PlatformGestureEvent& gestureEvent)
   2143 {
   2144     TRACE_EVENT0("input", "EventHandler::handleGestureScrollEvent");
   2145 
   2146     RefPtrWillBeRawPtr<Node> eventTarget = nullptr;
   2147     RefPtr<Scrollbar> scrollbar;
   2148     if (gestureEvent.type() != PlatformEvent::GestureScrollBegin) {
   2149         scrollbar = m_scrollbarHandlingScrollGesture.get();
   2150         eventTarget = m_scrollGestureHandlingNode.get();
   2151     }
   2152 
   2153     if (!eventTarget) {
   2154         Document* document = m_frame->document();
   2155         if (!document->renderView())
   2156             return false;
   2157 
   2158         FrameView* view = m_frame->view();
   2159         LayoutPoint viewPoint = view->windowToContents(gestureEvent.position());
   2160         HitTestRequest request(HitTestRequest::ReadOnly);
   2161         HitTestResult result(viewPoint);
   2162         document->renderView()->hitTest(request, result);
   2163 
   2164         eventTarget = result.innerNode();
   2165 
   2166         m_lastGestureScrollOverWidget = result.isOverWidget();
   2167         m_scrollGestureHandlingNode = eventTarget;
   2168         m_previousGestureScrolledNode = nullptr;
   2169 
   2170         if (!scrollbar)
   2171             scrollbar = result.scrollbar();
   2172     }
   2173 
   2174     if (scrollbar) {
   2175         bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
   2176         if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
   2177             || gestureEvent.type() == PlatformEvent::GestureFlingStart
   2178             || !eventSwallowed) {
   2179             m_scrollbarHandlingScrollGesture = nullptr;
   2180         }
   2181         if (eventSwallowed)
   2182             return true;
   2183     }
   2184 
   2185     if (eventTarget) {
   2186         bool eventSwallowed = handleScrollGestureOnResizer(eventTarget.get(), gestureEvent);
   2187         if (!eventSwallowed)
   2188             eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
   2189         if (eventSwallowed)
   2190             return true;
   2191     }
   2192 
   2193     switch (gestureEvent.type()) {
   2194     case PlatformEvent::GestureScrollBegin:
   2195         return handleGestureScrollBegin(gestureEvent);
   2196     case PlatformEvent::GestureScrollUpdate:
   2197     case PlatformEvent::GestureScrollUpdateWithoutPropagation:
   2198         return handleGestureScrollUpdate(gestureEvent);
   2199     case PlatformEvent::GestureScrollEnd:
   2200         return handleGestureScrollEnd(gestureEvent);
   2201     case PlatformEvent::GestureFlingStart:
   2202     case PlatformEvent::GesturePinchBegin:
   2203     case PlatformEvent::GesturePinchEnd:
   2204     case PlatformEvent::GesturePinchUpdate:
   2205         return false;
   2206     default:
   2207         ASSERT_NOT_REACHED();
   2208         return false;
   2209     }
   2210 }
   2211 
   2212 bool EventHandler::handleGestureTap(const GestureEventWithHitTestResults& targetedEvent)
   2213 {
   2214     RefPtr<FrameView> protector(m_frame->view());
   2215     const PlatformGestureEvent& gestureEvent = targetedEvent.event();
   2216     HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestureEvent.type());
   2217 
   2218     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
   2219 
   2220     unsigned modifierFlags = 0;
   2221     if (gestureEvent.altKey())
   2222         modifierFlags |= PlatformEvent::AltKey;
   2223     if (gestureEvent.ctrlKey())
   2224         modifierFlags |= PlatformEvent::CtrlKey;
   2225     if (gestureEvent.metaKey())
   2226         modifierFlags |= PlatformEvent::MetaKey;
   2227     if (gestureEvent.shiftKey())
   2228         modifierFlags |= PlatformEvent::ShiftKey;
   2229     PlatformEvent::Modifiers modifiers = static_cast<PlatformEvent::Modifiers>(modifierFlags);
   2230 
   2231     HitTestResult currentHitTest = targetedEvent.hitTestResult();
   2232 
   2233     // We use the adjusted position so the application isn't surprised to see a event with
   2234     // co-ordinates outside the target's bounds.
   2235     IntPoint adjustedPoint = m_frame->view()->windowToContents(gestureEvent.position());
   2236 
   2237     PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.globalPosition(),
   2238         NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
   2239         modifiers, PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
   2240     dispatchMouseEvent(EventTypeNames::mousemove, currentHitTest.innerNode(), 0, fakeMouseMove, true);
   2241 
   2242     // Do a new hit-test in case the mousemove event changed the DOM.
   2243     // Note that if the original hit test wasn't over an element (eg. was over a scrollbar) we
   2244     // don't want to re-hit-test because it may be in the wrong frame (and there's no way the page
   2245     // could have seen the event anyway).
   2246     // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.com/398920
   2247     if (currentHitTest.innerNode())
   2248         currentHitTest = hitTestResultInFrame(m_frame, adjustedPoint, hitType);
   2249     m_clickNode = currentHitTest.innerNode();
   2250     if (m_clickNode && m_clickNode->isTextNode())
   2251         m_clickNode = NodeRenderingTraversal::parent(m_clickNode.get());
   2252 
   2253     PlatformMouseEvent fakeMouseDown(gestureEvent.position(), gestureEvent.globalPosition(),
   2254         LeftButton, PlatformEvent::MousePressed, gestureEvent.tapCount(),
   2255         modifiers, PlatformMouseEvent::FromTouch,  gestureEvent.timestamp());
   2256     bool swallowMouseDownEvent = !dispatchMouseEvent(EventTypeNames::mousedown, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseDown, true);
   2257     if (!swallowMouseDownEvent)
   2258         swallowMouseDownEvent = handleMouseFocus(fakeMouseDown);
   2259     if (!swallowMouseDownEvent)
   2260         swallowMouseDownEvent = handleMousePressEvent(MouseEventWithHitTestResults(fakeMouseDown, currentHitTest));
   2261 
   2262     // FIXME: Use a hit-test cache to avoid unnecessary hit tests. http://crbug.com/398920
   2263     if (currentHitTest.innerNode())
   2264         currentHitTest = hitTestResultInFrame(m_frame, adjustedPoint, hitType);
   2265     PlatformMouseEvent fakeMouseUp(gestureEvent.position(), gestureEvent.globalPosition(),
   2266         LeftButton, PlatformEvent::MouseReleased, gestureEvent.tapCount(),
   2267         modifiers, PlatformMouseEvent::FromTouch,  gestureEvent.timestamp());
   2268     bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, currentHitTest.innerNode(), gestureEvent.tapCount(), fakeMouseUp, false);
   2269 
   2270     bool swallowClickEvent = false;
   2271     if (m_clickNode) {
   2272         if (currentHitTest.innerNode()) {
   2273             Node* clickTargetNode = currentHitTest.innerNode()->commonAncestor(*m_clickNode, parentForClickEvent);
   2274             swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, clickTargetNode, gestureEvent.tapCount(), fakeMouseUp, true);
   2275         }
   2276         m_clickNode = nullptr;
   2277     }
   2278 
   2279     if (!swallowMouseUpEvent)
   2280         swallowMouseUpEvent = handleMouseReleaseEvent(MouseEventWithHitTestResults(fakeMouseUp, currentHitTest));
   2281 
   2282     return swallowMouseDownEvent | swallowMouseUpEvent | swallowClickEvent;
   2283 }
   2284 
   2285 bool EventHandler::handleGestureLongPress(const GestureEventWithHitTestResults& targetedEvent)
   2286 {
   2287     const PlatformGestureEvent& gestureEvent = targetedEvent.event();
   2288     IntPoint adjustedPoint = gestureEvent.position();
   2289 
   2290     // FIXME: Ideally we should try to remove the extra mouse-specific hit-tests here (re-using the
   2291     // supplied HitTestResult), but that will require some overhaul of the touch drag-and-drop code
   2292     // and LongPress is such a special scenario that it's unlikely to matter much in practice.
   2293 
   2294     m_longTapShouldInvokeContextMenu = false;
   2295     if (m_frame->settings() && m_frame->settings()->touchDragDropEnabled() && m_frame->view()) {
   2296         PlatformMouseEvent mouseDownEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1,
   2297             gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), PlatformMouseEvent::FromTouch, WTF::currentTime());
   2298         m_mouseDown = mouseDownEvent;
   2299 
   2300         PlatformMouseEvent mouseDragEvent(adjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MouseMoved, 1,
   2301             gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), PlatformMouseEvent::FromTouch, WTF::currentTime());
   2302         HitTestRequest request(HitTestRequest::ReadOnly);
   2303         MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragEvent);
   2304         m_didStartDrag = false;
   2305         m_mouseDownMayStartDrag = true;
   2306         dragState().m_dragSrc = nullptr;
   2307         m_mouseDownPos = m_frame->view()->windowToContents(mouseDragEvent.position());
   2308         RefPtr<FrameView> protector(m_frame->view());
   2309         handleDrag(mev, DontCheckDragHysteresis);
   2310         if (m_didStartDrag) {
   2311             m_longTapShouldInvokeContextMenu = true;
   2312             return true;
   2313         }
   2314     }
   2315 #if OS(ANDROID)
   2316     bool shouldLongPressSelectWord = true;
   2317 #else
   2318     bool shouldLongPressSelectWord = m_frame->settings() && m_frame->settings()->touchEditingEnabled();
   2319 #endif
   2320     if (shouldLongPressSelectWord) {
   2321         IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.position());
   2322         HitTestResult result = hitTestResultAtPoint(hitTestPoint);
   2323         Node* innerNode = result.innerNode();
   2324         if (!result.isLiveLink() && innerNode && (innerNode->isContentEditable() || innerNode->isTextNode())) {
   2325             selectClosestWordFromHitTestResult(result, DontAppendTrailingWhitespace);
   2326             if (m_frame->selection().isRange()) {
   2327                 focusDocumentView();
   2328                 return true;
   2329             }
   2330         }
   2331     }
   2332     return sendContextMenuEventForGesture(targetedEvent);
   2333 }
   2334 
   2335 bool EventHandler::handleGestureLongTap(const GestureEventWithHitTestResults& targetedEvent)
   2336 {
   2337 #if !OS(ANDROID)
   2338     if (m_longTapShouldInvokeContextMenu) {
   2339         m_longTapShouldInvokeContextMenu = false;
   2340         return sendContextMenuEventForGesture(targetedEvent);
   2341     }
   2342 #endif
   2343     return false;
   2344 }
   2345 
   2346 bool EventHandler::handleScrollGestureOnResizer(Node* eventTarget, const PlatformGestureEvent& gestureEvent) {
   2347     if (gestureEvent.type() == PlatformEvent::GestureScrollBegin) {
   2348         RenderLayer* layer = eventTarget->renderer() ? eventTarget->renderer()->enclosingLayer() : 0;
   2349         IntPoint p = m_frame->view()->windowToContents(gestureEvent.position());
   2350         if (layer && layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(p, ResizerForTouch)) {
   2351             m_resizeScrollableArea = layer->scrollableArea();
   2352             m_resizeScrollableArea->setInResizeMode(true);
   2353             m_offsetFromResizeCorner = m_resizeScrollableArea->offsetFromResizeCorner(p);
   2354             return true;
   2355         }
   2356     } else if (gestureEvent.type() == PlatformEvent::GestureScrollUpdate ||
   2357                gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropagation) {
   2358         if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
   2359             m_resizeScrollableArea->resize(gestureEvent, m_offsetFromResizeCorner);
   2360             return true;
   2361         }
   2362     } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd) {
   2363         if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode()) {
   2364             m_resizeScrollableArea->setInResizeMode(false);
   2365             m_resizeScrollableArea = 0;
   2366             return false;
   2367         }
   2368     }
   2369 
   2370     return false;
   2371 }
   2372 
   2373 bool EventHandler::passScrollGestureEventToWidget(const PlatformGestureEvent& gestureEvent, RenderObject* renderer)
   2374 {
   2375     ASSERT(gestureEvent.isScrollEvent());
   2376 
   2377     if (!m_lastGestureScrollOverWidget)
   2378         return false;
   2379 
   2380     if (!renderer || !renderer->isWidget())
   2381         return false;
   2382 
   2383     Widget* widget = toRenderWidget(renderer)->widget();
   2384 
   2385     if (!widget || !widget->isFrameView())
   2386         return false;
   2387 
   2388     return toFrameView(widget)->frame().eventHandler().handleGestureScrollEvent(gestureEvent);
   2389 }
   2390 
   2391 bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEvent) {
   2392     RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
   2393     clearGestureScrollNodes();
   2394 
   2395     if (node)
   2396         passScrollGestureEventToWidget(gestureEvent, node->renderer());
   2397 
   2398     return false;
   2399 }
   2400 
   2401 bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureEvent)
   2402 {
   2403     Document* document = m_frame->document();
   2404     if (!document->renderView())
   2405         return false;
   2406 
   2407     FrameView* view = m_frame->view();
   2408     if (!view)
   2409         return false;
   2410 
   2411     // If there's no renderer on the node, send the event to the nearest ancestor with a renderer.
   2412     // Needed for <option> and <optgroup> elements so we can touch scroll <select>s
   2413     while (m_scrollGestureHandlingNode && !m_scrollGestureHandlingNode->renderer())
   2414         m_scrollGestureHandlingNode = m_scrollGestureHandlingNode->parentOrShadowHostNode();
   2415 
   2416     if (!m_scrollGestureHandlingNode)
   2417         return false;
   2418 
   2419     passScrollGestureEventToWidget(gestureEvent, m_scrollGestureHandlingNode->renderer());
   2420 
   2421     return true;
   2422 }
   2423 
   2424 bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gestureEvent)
   2425 {
   2426     FloatSize delta(gestureEvent.deltaX(), gestureEvent.deltaY());
   2427     if (delta.isZero())
   2428         return false;
   2429 
   2430     const float scaleFactor = m_frame->pageZoomFactor();
   2431     delta.scale(1 / scaleFactor, 1 / scaleFactor);
   2432 
   2433     Node* node = m_scrollGestureHandlingNode.get();
   2434     if (!node)
   2435         return sendScrollEventToView(gestureEvent, delta);
   2436 
   2437     // Ignore this event if the targeted node does not have a valid renderer.
   2438     RenderObject* renderer = node->renderer();
   2439     if (!renderer)
   2440         return false;
   2441 
   2442     RefPtr<FrameView> protector(m_frame->view());
   2443 
   2444     Node* stopNode = 0;
   2445     bool scrollShouldNotPropagate = gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropagation;
   2446 
   2447     // Try to send the event to the correct view.
   2448     if (passScrollGestureEventToWidget(gestureEvent, renderer)) {
   2449         if(scrollShouldNotPropagate)
   2450               m_previousGestureScrolledNode = m_scrollGestureHandlingNode;
   2451 
   2452         return true;
   2453     }
   2454 
   2455     if (scrollShouldNotPropagate)
   2456         stopNode = m_previousGestureScrolledNode.get();
   2457 
   2458     // First try to scroll the closest scrollable RenderBox ancestor of |node|.
   2459     ScrollGranularity granularity = ScrollByPixel;
   2460     bool horizontalScroll = scroll(ScrollLeft, granularity, node, &stopNode, delta.width());
   2461     bool verticalScroll = scroll(ScrollUp, granularity, node, &stopNode, delta.height());
   2462 
   2463     if (scrollShouldNotPropagate)
   2464         m_previousGestureScrolledNode = stopNode;
   2465 
   2466     if (horizontalScroll || verticalScroll) {
   2467         setFrameWasScrolledByUser();
   2468         return true;
   2469     }
   2470 
   2471     // Otherwise try to scroll the view.
   2472     return sendScrollEventToView(gestureEvent, delta);
   2473 }
   2474 
   2475 bool EventHandler::sendScrollEventToView(const PlatformGestureEvent& gestureEvent, const FloatSize& scaledDelta)
   2476 {
   2477     FrameView* view = m_frame->view();
   2478     if (!view)
   2479         return false;
   2480 
   2481     const float tickDivisor = static_cast<float>(WheelEvent::TickMultiplier);
   2482     IntPoint point(gestureEvent.position().x(), gestureEvent.position().y());
   2483     IntPoint globalPoint(gestureEvent.globalPosition().x(), gestureEvent.globalPosition().y());
   2484     PlatformWheelEvent syntheticWheelEvent(point, globalPoint,
   2485         scaledDelta.width(), scaledDelta.height(),
   2486         scaledDelta.width() / tickDivisor, scaledDelta.height() / tickDivisor,
   2487         ScrollByPixelWheelEvent,
   2488         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey());
   2489     syntheticWheelEvent.setHasPreciseScrollingDeltas(true);
   2490 
   2491     bool scrolledFrame = view->wheelEvent(syntheticWheelEvent);
   2492     if (scrolledFrame)
   2493         setFrameWasScrolledByUser();
   2494 
   2495     return scrolledFrame;
   2496 }
   2497 
   2498 void EventHandler::clearGestureScrollNodes()
   2499 {
   2500     m_scrollGestureHandlingNode = nullptr;
   2501     m_previousGestureScrolledNode = nullptr;
   2502 }
   2503 
   2504 bool EventHandler::isScrollbarHandlingGestures() const
   2505 {
   2506     return m_scrollbarHandlingScrollGesture.get();
   2507 }
   2508 
   2509 bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const
   2510 {
   2511     if (m_frame->settings() && !m_frame->settings()->touchAdjustmentEnabled())
   2512         return false;
   2513     return !event.area().isEmpty();
   2514 }
   2515 
   2516 bool EventHandler::bestClickableNodeForHitTestResult(const HitTestResult& result, IntPoint& targetPoint, Node*& targetNode)
   2517 {
   2518     // FIXME: Unify this with the other best* functions which are very similar.
   2519 
   2520     TRACE_EVENT0("input", "EventHandler::bestClickableNodeForHitTestResult");
   2521     ASSERT(result.isRectBasedTest());
   2522 
   2523     // If the touch is over a scrollbar, don't adjust the touch point since touch adjustment only takes into account
   2524     // DOM nodes so a touch over a scrollbar will be adjusted towards nearby nodes. This leads to things like textarea
   2525     // scrollbars being untouchable.
   2526     if (result.scrollbar())
   2527         return false;
   2528 
   2529     IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPointInMainFrame());
   2530     IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation().boundingBox());
   2531 
   2532     WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
   2533     copyToVector(result.rectBasedTestResult(), nodes);
   2534 
   2535     // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
   2536     return findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes));
   2537 }
   2538 
   2539 bool EventHandler::bestContextMenuNodeForHitTestResult(const HitTestResult& result, IntPoint& targetPoint, Node*& targetNode)
   2540 {
   2541     ASSERT(result.isRectBasedTest());
   2542     IntPoint touchCenter = m_frame->view()->contentsToWindow(result.roundedPointInMainFrame());
   2543     IntRect touchRect = m_frame->view()->contentsToWindow(result.hitTestLocation().boundingBox());
   2544     WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
   2545     copyToVector(result.rectBasedTestResult(), nodes);
   2546 
   2547     // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
   2548     return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
   2549 }
   2550 
   2551 bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
   2552 {
   2553     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
   2554     HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, touchRadius);
   2555 
   2556     IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
   2557     WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
   2558     copyToVector(result.rectBasedTestResult(), nodes);
   2559 
   2560     // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
   2561     return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
   2562 }
   2563 
   2564 GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGestureEvent& gestureEvent, bool readOnly)
   2565 {
   2566     TRACE_EVENT0("input", "EventHandler::targetGestureEvent");
   2567 
   2568     ASSERT(m_frame == m_frame->localFrameRoot());
   2569     // Scrolling events get hit tested per frame (like wheel events do).
   2570     ASSERT(!gestureEvent.isScrollEvent());
   2571 
   2572     HitTestRequest::HitTestRequestType hitType = getHitTypeForGestureType(gestureEvent.type());
   2573     double activeInterval = 0;
   2574     bool shouldKeepActiveForMinInterval = false;
   2575     if (readOnly) {
   2576         hitType |= HitTestRequest::ReadOnly;
   2577     } else if (gestureEvent.type() == PlatformEvent::GestureTap) {
   2578         // If the Tap is received very shortly after ShowPress, we want to
   2579         // delay clearing of the active state so that it's visible to the user
   2580         // for at least a couple of frames.
   2581         activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
   2582         shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInterval < minimumActiveInterval;
   2583         if (shouldKeepActiveForMinInterval)
   2584             hitType |= HitTestRequest::ReadOnly;
   2585     }
   2586 
   2587     // Perform the rect-based hit-test (or point-based if adjustment is disabled). Note that
   2588     // we don't yet apply hover/active state here because we need to resolve touch adjustment
   2589     // first so that we apply hover/active it to the final adjusted node.
   2590     IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.position());
   2591     LayoutSize padding;
   2592     if (shouldApplyTouchAdjustment(gestureEvent)) {
   2593         padding = gestureEvent.area();
   2594         padding.scale(1.f / 2);
   2595     }
   2596     HitTestResult hitTestResult = hitTestResultAtPoint(hitTestPoint, hitType | HitTestRequest::ReadOnly, padding);
   2597 
   2598     // Adjust the location of the gesture to the most likely nearby node, as appropriate for the
   2599     // type of event.
   2600     PlatformGestureEvent adjustedEvent = gestureEvent;
   2601     applyTouchAdjustment(&adjustedEvent, &hitTestResult);
   2602 
   2603     // Do a new hit-test at the (adjusted) gesture co-ordinates. This is necessary because
   2604     // rect-based hit testing and touch adjustment sometimes return a different node than
   2605     // what a point-based hit test would return for the same point.
   2606     // FIXME: Fix touch adjustment to avoid the need for a redundant hit test. http://crbug.com/398914
   2607     if (shouldApplyTouchAdjustment(gestureEvent)) {
   2608         LocalFrame* hitFrame = hitTestResult.innerNodeFrame();
   2609         if (!hitFrame)
   2610             hitFrame = m_frame;
   2611         hitTestResult = hitTestResultInFrame(hitFrame, hitFrame->view()->windowToContents(adjustedEvent.position()), hitType | HitTestRequest::ReadOnly);
   2612     }
   2613 
   2614     // If we did a rect-based hit test it must be resolved to the best single node by now to
   2615     // ensure consumers don't accidentally use one of the other candidates.
   2616     ASSERT(!hitTestResult.isRectBasedTest());
   2617 
   2618     // Now apply hover/active state to the final target.
   2619     // FIXME: This is supposed to send mouseenter/mouseleave events, but doesn't because we
   2620     // aren't passing a PlatformMouseEvent.
   2621     HitTestRequest request(hitType | HitTestRequest::AllowChildFrameContent);
   2622     if (!request.readOnly())
   2623         m_frame->document()->updateHoverActiveState(request, hitTestResult.innerElement());
   2624 
   2625     if (shouldKeepActiveForMinInterval) {
   2626         m_lastDeferredTapElement = hitTestResult.innerElement();
   2627         m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval, FROM_HERE);
   2628     }
   2629 
   2630     return GestureEventWithHitTestResults(adjustedEvent, hitTestResult);
   2631 }
   2632 
   2633 HitTestRequest::HitTestRequestType EventHandler::getHitTypeForGestureType(PlatformEvent::Type type)
   2634 {
   2635     HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
   2636     switch (type) {
   2637     case PlatformEvent::GestureShowPress:
   2638     case PlatformEvent::GestureTapUnconfirmed:
   2639         return hitType | HitTestRequest::Active;
   2640     case PlatformEvent::GestureTapDownCancel:
   2641         // A TapDownCancel received when no element is active shouldn't really be changing hover state.
   2642         if (!m_frame->document()->activeHoverElement())
   2643             hitType |= HitTestRequest::ReadOnly;
   2644         return hitType | HitTestRequest::Release;
   2645     case PlatformEvent::GestureTap:
   2646         return hitType | HitTestRequest::Release;
   2647     case PlatformEvent::GestureTapDown:
   2648     case PlatformEvent::GestureLongPress:
   2649     case PlatformEvent::GestureLongTap:
   2650     case PlatformEvent::GestureTwoFingerTap:
   2651         // FIXME: Shouldn't LongTap and TwoFingerTap clear the Active state?
   2652         return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
   2653     default:
   2654         ASSERT_NOT_REACHED();
   2655         return hitType | HitTestRequest::Active | HitTestRequest::ReadOnly;
   2656     }
   2657 }
   2658 
   2659 void EventHandler::applyTouchAdjustment(PlatformGestureEvent* gestureEvent, HitTestResult* hitTestResult)
   2660 {
   2661     if (!shouldApplyTouchAdjustment(*gestureEvent))
   2662         return;
   2663 
   2664     Node* adjustedNode = 0;
   2665     IntPoint adjustedPoint = gestureEvent->position();
   2666     IntSize radius = gestureEvent->area();
   2667     radius.scale(1.f / 2);
   2668     bool adjusted = false;
   2669     switch (gestureEvent->type()) {
   2670     case PlatformEvent::GestureTap:
   2671     case PlatformEvent::GestureTapUnconfirmed:
   2672     case PlatformEvent::GestureTapDown:
   2673     case PlatformEvent::GestureShowPress:
   2674         adjusted = bestClickableNodeForHitTestResult(*hitTestResult, adjustedPoint, adjustedNode);
   2675         break;
   2676     case PlatformEvent::GestureLongPress:
   2677     case PlatformEvent::GestureLongTap:
   2678     case PlatformEvent::GestureTwoFingerTap:
   2679         adjusted = bestContextMenuNodeForHitTestResult(*hitTestResult, adjustedPoint, adjustedNode);
   2680         break;
   2681     default:
   2682         ASSERT_NOT_REACHED();
   2683     }
   2684 
   2685     // Update the hit-test result to be a point-based result instead of a rect-based result.
   2686     // FIXME: We should do this even when no candidate matches the node filter. crbug.com/398914
   2687     if (adjusted) {
   2688         hitTestResult->resolveRectBasedTest(adjustedNode, m_frame->view()->windowToContents(adjustedPoint));
   2689         gestureEvent->applyTouchAdjustment(adjustedPoint);
   2690     }
   2691 }
   2692 
   2693 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
   2694 {
   2695     Document* doc = m_frame->document();
   2696     FrameView* v = m_frame->view();
   2697     if (!v)
   2698         return false;
   2699 
   2700     // Clear mouse press state to avoid initiating a drag while context menu is up.
   2701     m_mousePressed = false;
   2702     LayoutPoint viewportPos = v->windowToContents(event.position());
   2703     HitTestRequest request(HitTestRequest::Active);
   2704     MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
   2705 
   2706     if (!m_frame->selection().contains(viewportPos)
   2707         && !mev.scrollbar()
   2708         // FIXME: In the editable case, word selection sometimes selects content that isn't underneath the mouse.
   2709         // If the selection is non-editable, we do word selection to make it easier to use the contextual menu items
   2710         // available for text selections.  But only if we're above text.
   2711         && (m_frame->selection().isContentEditable() || (mev.innerNode() && mev.innerNode()->isTextNode()))) {
   2712         m_mouseDownMayStartSelect = true; // context menu events are always allowed to perform a selection
   2713 
   2714         if (mev.hitTestResult().isMisspelled())
   2715             selectClosestMisspellingFromMouseEvent(mev);
   2716         else if (m_frame->editor().behavior().shouldSelectOnContextualMenuClick())
   2717             selectClosestWordOrLinkFromMouseEvent(mev);
   2718     }
   2719 
   2720     return !dispatchMouseEvent(EventTypeNames::contextmenu, mev.innerNode(), 0, event, false);
   2721 }
   2722 
   2723 bool EventHandler::sendContextMenuEventForKey()
   2724 {
   2725     FrameView* view = m_frame->view();
   2726     if (!view)
   2727         return false;
   2728 
   2729     Document* doc = m_frame->document();
   2730     if (!doc)
   2731         return false;
   2732 
   2733     // Clear mouse press state to avoid initiating a drag while context menu is up.
   2734     m_mousePressed = false;
   2735 
   2736     static const int kContextMenuMargin = 1;
   2737 
   2738 #if OS(WIN)
   2739     int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);
   2740 #else
   2741     int rightAligned = 0;
   2742 #endif
   2743     IntPoint location;
   2744 
   2745     Element* focusedElement = doc->focusedElement();
   2746     FrameSelection& selection = m_frame->selection();
   2747     Position start = selection.selection().start();
   2748     bool shouldTranslateToRootView = true;
   2749 
   2750     if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
   2751         RefPtrWillBeRawPtr<Range> selectionRange = selection.toNormalizedRange();
   2752         IntRect firstRect = m_frame->editor().firstRectForRange(selectionRange.get());
   2753 
   2754         int x = rightAligned ? firstRect.maxX() : firstRect.x();
   2755         // In a multiline edit, firstRect.maxY() would endup on the next line, so -1.
   2756         int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
   2757         location = IntPoint(x, y);
   2758     } else if (focusedElement) {
   2759         IntRect clippedRect = focusedElement->boundsInRootViewSpace();
   2760         location = IntPoint(clippedRect.center());
   2761     } else {
   2762         location = IntPoint(
   2763             rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
   2764             kContextMenuMargin);
   2765         shouldTranslateToRootView = false;
   2766     }
   2767 
   2768     m_frame->view()->setCursor(pointerCursor());
   2769 
   2770     IntPoint position = shouldTranslateToRootView ? view->contentsToRootView(location) : location;
   2771     IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
   2772 
   2773     Node* targetNode = doc->focusedElement();
   2774     if (!targetNode)
   2775         targetNode = doc;
   2776 
   2777     // Use the focused node as the target for hover and active.
   2778     HitTestResult result(position);
   2779     result.setInnerNode(targetNode);
   2780     doc->updateHoverActiveState(HitTestRequest::Active, result.innerElement());
   2781 
   2782     // The contextmenu event is a mouse event even when invoked using the keyboard.
   2783     // This is required for web compatibility.
   2784 
   2785 #if OS(WIN)
   2786     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
   2787 #else
   2788     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
   2789 #endif
   2790 
   2791     PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable, WTF::currentTime());
   2792 
   2793     handleMousePressEvent(mouseEvent);
   2794     return sendContextMenuEvent(mouseEvent);
   2795 }
   2796 
   2797 bool EventHandler::sendContextMenuEventForGesture(const GestureEventWithHitTestResults& targetedEvent)
   2798 {
   2799 #if OS(WIN)
   2800     PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
   2801 #else
   2802     PlatformEvent::Type eventType = PlatformEvent::MousePressed;
   2803 #endif
   2804 
   2805     PlatformMouseEvent mouseEvent(targetedEvent.event().position(), targetedEvent.event().globalPosition(), RightButton, eventType, 1, false, false, false, false, PlatformMouseEvent::FromTouch, WTF::currentTime());
   2806     // To simulate right-click behavior, we send a right mouse down and then
   2807     // context menu event.
   2808     // FIXME: Send HitTestResults to avoid redundant hit tests.
   2809     handleMousePressEvent(mouseEvent);
   2810     return sendContextMenuEvent(mouseEvent);
   2811     // We do not need to send a corresponding mouse release because in case of
   2812     // right-click, the context menu takes capture and consumes all events.
   2813 }
   2814 
   2815 void EventHandler::scheduleHoverStateUpdate()
   2816 {
   2817     if (!m_hoverTimer.isActive())
   2818         m_hoverTimer.startOneShot(0, FROM_HERE);
   2819 }
   2820 
   2821 void EventHandler::scheduleCursorUpdate()
   2822 {
   2823     if (!m_cursorUpdateTimer.isActive())
   2824         m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, FROM_HERE);
   2825 }
   2826 
   2827 void EventHandler::dispatchFakeMouseMoveEventSoon()
   2828 {
   2829     if (m_mousePressed)
   2830         return;
   2831 
   2832     if (m_mousePositionIsUnknown)
   2833         return;
   2834 
   2835     Settings* settings = m_frame->settings();
   2836     if (settings && !settings->deviceSupportsMouse())
   2837         return;
   2838 
   2839     // If the content has ever taken longer than fakeMouseMoveShortInterval we
   2840     // reschedule the timer and use a longer time. This will cause the content
   2841     // to receive these moves only after the user is done scrolling, reducing
   2842     // pauses during the scroll.
   2843     if (m_maxMouseMovedDuration > fakeMouseMoveShortInterval) {
   2844         if (m_fakeMouseMoveEventTimer.isActive())
   2845             m_fakeMouseMoveEventTimer.stop();
   2846         m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval, FROM_HERE);
   2847     } else {
   2848         if (!m_fakeMouseMoveEventTimer.isActive())
   2849             m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval, FROM_HERE);
   2850     }
   2851 }
   2852 
   2853 void EventHandler::dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad& quad)
   2854 {
   2855     FrameView* view = m_frame->view();
   2856     if (!view)
   2857         return;
   2858 
   2859     if (!quad.containsPoint(view->windowToContents(m_lastKnownMousePosition)))
   2860         return;
   2861 
   2862     dispatchFakeMouseMoveEventSoon();
   2863 }
   2864 
   2865 void EventHandler::fakeMouseMoveEventTimerFired(Timer<EventHandler>* timer)
   2866 {
   2867     ASSERT_UNUSED(timer, timer == &m_fakeMouseMoveEventTimer);
   2868     ASSERT(!m_mousePressed);
   2869 
   2870     Settings* settings = m_frame->settings();
   2871     if (settings && !settings->deviceSupportsMouse())
   2872         return;
   2873 
   2874     FrameView* view = m_frame->view();
   2875     if (!view)
   2876         return;
   2877 
   2878     if (!m_frame->page() || !m_frame->page()->focusController().isActive())
   2879         return;
   2880 
   2881     // Don't dispatch a synthetic mouse move event if the mouse cursor is not visible to the user.
   2882     if (!isCursorVisible())
   2883         return;
   2884 
   2885     bool shiftKey;
   2886     bool ctrlKey;
   2887     bool altKey;
   2888     bool metaKey;
   2889     PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
   2890     PlatformMouseEvent fakeMouseMoveEvent(m_lastKnownMousePosition, m_lastKnownMouseGlobalPosition, NoButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey, metaKey, PlatformMouseEvent::RealOrIndistinguishable, currentTime());
   2891     handleMouseMoveEvent(fakeMouseMoveEvent);
   2892 }
   2893 
   2894 void EventHandler::cancelFakeMouseMoveEvent()
   2895 {
   2896     m_fakeMouseMoveEventTimer.stop();
   2897 }
   2898 
   2899 bool EventHandler::isCursorVisible() const
   2900 {
   2901     return m_frame->page()->isCursorVisible();
   2902 }
   2903 
   2904 void EventHandler::setResizingFrameSet(HTMLFrameSetElement* frameSet)
   2905 {
   2906     m_frameSetBeingResized = frameSet;
   2907 }
   2908 
   2909 void EventHandler::resizeScrollableAreaDestroyed()
   2910 {
   2911     ASSERT(m_resizeScrollableArea);
   2912     m_resizeScrollableArea = 0;
   2913 }
   2914 
   2915 void EventHandler::hoverTimerFired(Timer<EventHandler>*)
   2916 {
   2917     m_hoverTimer.stop();
   2918 
   2919     ASSERT(m_frame);
   2920     ASSERT(m_frame->document());
   2921 
   2922     if (RenderView* renderer = m_frame->contentRenderer()) {
   2923         if (FrameView* view = m_frame->view()) {
   2924             HitTestRequest request(HitTestRequest::Move);
   2925             HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
   2926             renderer->hitTest(request, result);
   2927             m_frame->document()->updateHoverActiveState(request, result.innerElement());
   2928         }
   2929     }
   2930 }
   2931 
   2932 void EventHandler::activeIntervalTimerFired(Timer<EventHandler>*)
   2933 {
   2934     m_activeIntervalTimer.stop();
   2935 
   2936     if (m_frame
   2937         && m_frame->document()
   2938         && m_lastDeferredTapElement) {
   2939         // FIXME: Enable condition when http://crbug.com/226842 lands
   2940         // m_lastDeferredTapElement.get() == m_frame->document()->activeElement()
   2941         HitTestRequest request(HitTestRequest::TouchEvent | HitTestRequest::Release);
   2942         m_frame->document()->updateHoverActiveState(request, m_lastDeferredTapElement.get());
   2943     }
   2944     m_lastDeferredTapElement = nullptr;
   2945 }
   2946 
   2947 void EventHandler::notifyElementActivated()
   2948 {
   2949     // Since another element has been set to active, stop current timer and clear reference.
   2950     if (m_activeIntervalTimer.isActive())
   2951         m_activeIntervalTimer.stop();
   2952     m_lastDeferredTapElement = nullptr;
   2953 }
   2954 
   2955 void EventHandler::notifySelectionChanged()
   2956 {
   2957     m_selectionInitiationState = ExtendedSelection;
   2958 }
   2959 
   2960 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
   2961 {
   2962     // FIXME: Ignoring the state of Shift key is what neither IE nor Firefox do.
   2963     // IE matches lower and upper case access keys regardless of Shift key state - but if both upper and
   2964     // lower case variants are present in a document, the correct element is matched based on Shift key state.
   2965     // Firefox only matches an access key if Shift is not pressed, and does that case-insensitively.
   2966     ASSERT(!(accessKeyModifiers() & PlatformEvent::ShiftKey));
   2967     if ((evt.modifiers() & ~PlatformEvent::ShiftKey) != accessKeyModifiers())
   2968         return false;
   2969     String key = evt.unmodifiedText();
   2970     Element* elem = m_frame->document()->getElementByAccessKey(key.lower());
   2971     if (!elem)
   2972         return false;
   2973     elem->accessKeyAction(false);
   2974     return true;
   2975 }
   2976 
   2977 bool EventHandler::isKeyEventAllowedInFullScreen(Fullscreen* fullscreen, const PlatformKeyboardEvent& keyEvent) const
   2978 {
   2979     if (fullscreen->webkitFullScreenKeyboardInputAllowed())
   2980         return true;
   2981 
   2982     if (keyEvent.type() == PlatformKeyboardEvent::Char) {
   2983         if (keyEvent.text().length() != 1)
   2984             return false;
   2985         UChar character = keyEvent.text()[0];
   2986         return character == ' ';
   2987     }
   2988 
   2989     int keyCode = keyEvent.windowsVirtualKeyCode();
   2990     return (keyCode >= VK_BACK && keyCode <= VK_CAPITAL)
   2991         || (keyCode >= VK_SPACE && keyCode <= VK_DELETE)
   2992         || (keyCode >= VK_OEM_1 && keyCode <= VK_OEM_PLUS)
   2993         || (keyCode >= VK_MULTIPLY && keyCode <= VK_OEM_8);
   2994 }
   2995 
   2996 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
   2997 {
   2998     RefPtr<FrameView> protector(m_frame->view());
   2999 
   3000     ASSERT(m_frame->document());
   3001     if (Fullscreen* fullscreen = Fullscreen::fromIfExists(*m_frame->document())) {
   3002         if (fullscreen->webkitCurrentFullScreenElement() && !isKeyEventAllowedInFullScreen(fullscreen, initialKeyEvent)) {
   3003             UseCounter::count(*m_frame->document(), UseCounter::KeyEventNotAllowedInFullScreen);
   3004             return false;
   3005         }
   3006     }
   3007 
   3008     if (initialKeyEvent.windowsVirtualKeyCode() == VK_CAPITAL)
   3009         capsLockStateMayHaveChanged();
   3010 
   3011 #if OS(WIN)
   3012     if (panScrollInProgress()) {
   3013         // If a key is pressed while the panScroll is in progress then we want to stop
   3014         if (initialKeyEvent.type() == PlatformEvent::KeyDown || initialKeyEvent.type() == PlatformEvent::RawKeyDown)
   3015             stopAutoscroll();
   3016 
   3017         // If we were in panscroll mode, we swallow the key event
   3018         return true;
   3019     }
   3020 #endif
   3021 
   3022     // Check for cases where we are too early for events -- possible unmatched key up
   3023     // from pressing return in the location bar.
   3024     RefPtrWillBeRawPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
   3025     if (!node)
   3026         return false;
   3027 
   3028     UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
   3029 
   3030     // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
   3031     // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
   3032     // with access keys. Then we dispatch keydown, but suppress its default handling.
   3033     // On Windows, WebKit explicitly calls handleAccessKey() instead of dispatching a keypress event for WM_SYSCHAR messages.
   3034     // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
   3035     bool matchedAnAccessKey = false;
   3036     if (initialKeyEvent.type() == PlatformEvent::KeyDown)
   3037         matchedAnAccessKey = handleAccessKey(initialKeyEvent);
   3038 
   3039     // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
   3040     if (initialKeyEvent.type() == PlatformEvent::KeyUp || initialKeyEvent.type() == PlatformEvent::Char)
   3041         return !node->dispatchKeyEvent(initialKeyEvent);
   3042 
   3043     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;
   3044     if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
   3045         keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
   3046     RefPtrWillBeRawPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->domWindow());
   3047     if (matchedAnAccessKey)
   3048         keydown->setDefaultPrevented(true);
   3049     keydown->setTarget(node);
   3050 
   3051     if (initialKeyEvent.type() == PlatformEvent::RawKeyDown) {
   3052         node->dispatchEvent(keydown, IGNORE_EXCEPTION);
   3053         // If frame changed as a result of keydown dispatch, then return true to avoid sending a subsequent keypress message to the new frame.
   3054         bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController().focusedOrMainFrame();
   3055         return keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
   3056     }
   3057 
   3058     node->dispatchEvent(keydown, IGNORE_EXCEPTION);
   3059     // If frame changed as a result of keydown dispatch, then return early to avoid sending a subsequent keypress message to the new frame.
   3060     bool changedFocusedFrame = m_frame->page() && m_frame != m_frame->page()->focusController().focusedOrMainFrame();
   3061     bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented() || changedFocusedFrame;
   3062     if (keydownResult)
   3063         return keydownResult;
   3064 
   3065     // Focus may have changed during keydown handling, so refetch node.
   3066     // But if we are dispatching a fake backward compatibility keypress, then we pretend that the keypress happened on the original node.
   3067     node = eventTargetNodeForDocument(m_frame->document());
   3068     if (!node)
   3069         return false;
   3070 
   3071     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
   3072     keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char);
   3073     if (keyPressEvent.text().isEmpty())
   3074         return keydownResult;
   3075     RefPtrWillBeRawPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->domWindow());
   3076     keypress->setTarget(node);
   3077     if (keydownResult)
   3078         keypress->setDefaultPrevented(true);
   3079     node->dispatchEvent(keypress, IGNORE_EXCEPTION);
   3080 
   3081     return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
   3082 }
   3083 
   3084 static FocusType focusDirectionForKey(const AtomicString& keyIdentifier)
   3085 {
   3086     DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down", AtomicString::ConstructFromLiteral));
   3087     DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up", AtomicString::ConstructFromLiteral));
   3088     DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left", AtomicString::ConstructFromLiteral));
   3089     DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right", AtomicString::ConstructFromLiteral));
   3090 
   3091     FocusType retVal = FocusTypeNone;
   3092 
   3093     if (keyIdentifier == Down)
   3094         retVal = FocusTypeDown;
   3095     else if (keyIdentifier == Up)
   3096         retVal = FocusTypeUp;
   3097     else if (keyIdentifier == Left)
   3098         retVal = FocusTypeLeft;
   3099     else if (keyIdentifier == Right)
   3100         retVal = FocusTypeRight;
   3101 
   3102     return retVal;
   3103 }
   3104 
   3105 void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
   3106 {
   3107     if (event->type() == EventTypeNames::keydown) {
   3108         // Clear caret blinking suspended state to make sure that caret blinks
   3109         // when we type again after long pressing on an empty input field.
   3110         if (m_frame && m_frame->selection().isCaretBlinkingSuspended())
   3111             m_frame->selection().setCaretBlinkingSuspended(false);
   3112 
   3113         m_frame->editor().handleKeyboardEvent(event);
   3114         if (event->defaultHandled())
   3115             return;
   3116         if (event->keyIdentifier() == "U+0009")
   3117             defaultTabEventHandler(event);
   3118         else if (event->keyIdentifier() == "U+0008")
   3119             defaultBackspaceEventHandler(event);
   3120         else if (event->keyIdentifier() == "U+001B")
   3121             defaultEscapeEventHandler(event);
   3122         else {
   3123             FocusType type = focusDirectionForKey(AtomicString(event->keyIdentifier()));
   3124             if (type != FocusTypeNone)
   3125                 defaultArrowEventHandler(type, event);
   3126         }
   3127     }
   3128     if (event->type() == EventTypeNames::keypress) {
   3129         m_frame->editor().handleKeyboardEvent(event);
   3130         if (event->defaultHandled())
   3131             return;
   3132         if (event->charCode() == ' ')
   3133             defaultSpaceEventHandler(event);
   3134     }
   3135 }
   3136 
   3137 bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
   3138 {
   3139     return dragHysteresisExceeded(flooredIntPoint(floatDragViewportLocation));
   3140 }
   3141 
   3142 bool EventHandler::dragHysteresisExceeded(const IntPoint& dragViewportLocation) const
   3143 {
   3144     FrameView* view = m_frame->view();
   3145     if (!view)
   3146         return false;
   3147     IntPoint dragLocation = view->windowToContents(dragViewportLocation);
   3148     IntSize delta = dragLocation - m_mouseDownPos;
   3149 
   3150     int threshold = GeneralDragHysteresis;
   3151     switch (dragState().m_dragType) {
   3152     case DragSourceActionSelection:
   3153         threshold = TextDragHysteresis;
   3154         break;
   3155     case DragSourceActionImage:
   3156         threshold = ImageDragHysteresis;
   3157         break;
   3158     case DragSourceActionLink:
   3159         threshold = LinkDragHysteresis;
   3160         break;
   3161     case DragSourceActionDHTML:
   3162         break;
   3163     case DragSourceActionNone:
   3164         ASSERT_NOT_REACHED();
   3165     }
   3166 
   3167     return abs(delta.width()) >= threshold || abs(delta.height()) >= threshold;
   3168 }
   3169 
   3170 void EventHandler::clearDragDataTransfer()
   3171 {
   3172     if (dragState().m_dragDataTransfer) {
   3173         dragState().m_dragDataTransfer->clearDragImage();
   3174         dragState().m_dragDataTransfer->setAccessPolicy(DataTransferNumb);
   3175     }
   3176 }
   3177 
   3178 void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
   3179 {
   3180     // Send a hit test request so that RenderLayer gets a chance to update the :hover and :active pseudoclasses.
   3181     HitTestRequest request(HitTestRequest::Release);
   3182     prepareMouseEvent(request, event);
   3183 
   3184     if (dragState().m_dragSrc) {
   3185         dragState().m_dragDataTransfer->setDestinationOperation(operation);
   3186         // for now we don't care if event handler cancels default behavior, since there is none
   3187         dispatchDragSrcEvent(EventTypeNames::dragend, event);
   3188     }
   3189     clearDragDataTransfer();
   3190     dragState().m_dragSrc = nullptr;
   3191     // In case the drag was ended due to an escape key press we need to ensure
   3192     // that consecutive mousemove events don't reinitiate the drag and drop.
   3193     m_mouseDownMayStartDrag = false;
   3194 }
   3195 
   3196 void EventHandler::updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement)
   3197 {
   3198     // If inserting the dragged contents removed the drag source, we still want to fire dragend at the root editble element.
   3199     if (dragState().m_dragSrc && !dragState().m_dragSrc->inDocument())
   3200         dragState().m_dragSrc = rootEditableElement;
   3201 }
   3202 
   3203 // returns if we should continue "default processing", i.e., whether eventhandler canceled
   3204 bool EventHandler::dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent& event)
   3205 {
   3206     return !dispatchDragEvent(eventType, dragState().m_dragSrc.get(), event, dragState().m_dragDataTransfer.get());
   3207 }
   3208 
   3209 bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDragHysteresis checkDragHysteresis)
   3210 {
   3211     ASSERT(event.event().type() == PlatformEvent::MouseMoved);
   3212     // Callers must protect the reference to FrameView, since this function may dispatch DOM
   3213     // events, causing page/FrameView to go away.
   3214     ASSERT(m_frame);
   3215     ASSERT(m_frame->view());
   3216     if (!m_frame->page())
   3217         return false;
   3218 
   3219     if (event.event().button() != LeftButton || event.event().type() != PlatformEvent::MouseMoved) {
   3220         // If we allowed the other side of the bridge to handle a drag
   3221         // last time, then m_mousePressed might still be set. So we
   3222         // clear it now to make sure the next move after a drag
   3223         // doesn't look like a drag.
   3224         m_mousePressed = false;
   3225         return false;
   3226     }
   3227 
   3228     if (m_mouseDownMayStartDrag) {
   3229         HitTestRequest request(HitTestRequest::ReadOnly);
   3230         HitTestResult result(m_mouseDownPos);
   3231         m_frame->contentRenderer()->hitTest(request, result);
   3232         Node* node = result.innerNode();
   3233         if (node) {
   3234             DragController::SelectionDragPolicy selectionDragPolicy = event.event().timestamp() - m_mouseDownTimestamp < TextDragDelay
   3235                 ? DragController::DelayedSelectionDragResolution
   3236                 : DragController::ImmediateSelectionDragResolution;
   3237             dragState().m_dragSrc = m_frame->page()->dragController().draggableNode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType);
   3238         } else {
   3239             dragState().m_dragSrc = nullptr;
   3240         }
   3241 
   3242         if (!dragState().m_dragSrc)
   3243             m_mouseDownMayStartDrag = false; // no element is draggable
   3244     }
   3245 
   3246     if (!m_mouseDownMayStartDrag)
   3247         return !mouseDownMayStartSelect() && !m_mouseDownMayStartAutoscroll;
   3248 
   3249     // We are starting a text/image/url drag, so the cursor should be an arrow
   3250     // FIXME <rdar://7577595>: Custom cursors aren't supported during drag and drop (default to pointer).
   3251     m_frame->view()->setCursor(pointerCursor());
   3252 
   3253     if (checkDragHysteresis == ShouldCheckDragHysteresis && !dragHysteresisExceeded(event.event().position()))
   3254         return true;
   3255 
   3256     // Once we're past the hysteresis point, we don't want to treat this gesture as a click
   3257     invalidateClick();
   3258 
   3259     if (!tryStartDrag(event)) {
   3260         // Something failed to start the drag, clean up.
   3261         clearDragDataTransfer();
   3262         dragState().m_dragSrc = nullptr;
   3263     }
   3264 
   3265     m_mouseDownMayStartDrag = false;
   3266     // Whether or not the drag actually started, no more default handling (like selection).
   3267     return true;
   3268 }
   3269 
   3270 bool EventHandler::tryStartDrag(const MouseEventWithHitTestResults& event)
   3271 {
   3272     // The DataTransfer would only be non-empty if we missed a dragEnd.
   3273     // Clear it anyway, just to make sure it gets numbified.
   3274     clearDragDataTransfer();
   3275 
   3276     dragState().m_dragDataTransfer = createDraggingDataTransfer();
   3277 
   3278     // Check to see if this a DOM based drag, if it is get the DOM specified drag
   3279     // image and offset
   3280     if (dragState().m_dragType == DragSourceActionDHTML) {
   3281         if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
   3282             FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), UseTransforms);
   3283             IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
   3284             dragState().m_dragDataTransfer->setDragImageElement(dragState().m_dragSrc.get(), IntPoint(delta));
   3285         } else {
   3286             // The renderer has disappeared, this can happen if the onStartDrag handler has hidden
   3287             // the element in some way. In this case we just kill the drag.
   3288             return false;
   3289         }
   3290     }
   3291 
   3292     DragController& dragController = m_frame->page()->dragController();
   3293     if (!dragController.populateDragDataTransfer(m_frame, dragState(), m_mouseDownPos))
   3294         return false;
   3295 
   3296     // If dispatching dragstart brings about another mouse down -- one way
   3297     // this will happen is if a DevTools user breaks within a dragstart
   3298     // handler and then clicks on the suspended page -- the drag state is
   3299     // reset. Hence, need to check if this particular drag operation can
   3300     // continue even if dispatchEvent() indicates no (direct) cancellation.
   3301     // Do that by checking if m_dragSrc is still set.
   3302     m_mouseDownMayStartDrag = dispatchDragSrcEvent(EventTypeNames::dragstart, m_mouseDown)
   3303         && !m_frame->selection().isInPasswordField() && dragState().m_dragSrc;
   3304 
   3305     // Invalidate clipboard here against anymore pasteboard writing for security. The drag
   3306     // image can still be changed as we drag, but not the pasteboard data.
   3307     dragState().m_dragDataTransfer->setAccessPolicy(DataTransferImageWritable);
   3308 
   3309     if (m_mouseDownMayStartDrag) {
   3310         // Dispatching the event could cause Page to go away. Make sure it's still valid before trying to use DragController.
   3311         m_didStartDrag = m_frame->page() && dragController.startDrag(m_frame, dragState(), event.event(), m_mouseDownPos);
   3312         // FIXME: This seems pretty useless now. The gesture code uses this as a signal for
   3313         // whether or not the drag started, but perhaps it can simply use the return value from
   3314         // handleDrag(), even though it doesn't mean exactly the same thing.
   3315         if (m_didStartDrag)
   3316             return true;
   3317         // Drag was canned at the last minute - we owe m_dragSrc a DRAGEND event
   3318         dispatchDragSrcEvent(EventTypeNames::dragend, event.event());
   3319     }
   3320 
   3321     return false;
   3322 }
   3323 
   3324 bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEvent, TextEventInputType inputType)
   3325 {
   3326     // Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
   3327     // and avoid dispatching text input events from keydown default handlers.
   3328     ASSERT(!underlyingEvent || !underlyingEvent->isKeyboardEvent() || toKeyboardEvent(underlyingEvent)->type() == EventTypeNames::keypress);
   3329 
   3330     if (!m_frame)
   3331         return false;
   3332 
   3333     EventTarget* target;
   3334     if (underlyingEvent)
   3335         target = underlyingEvent->target();
   3336     else
   3337         target = eventTargetNodeForDocument(m_frame->document());
   3338     if (!target)
   3339         return false;
   3340 
   3341     RefPtrWillBeRawPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text, inputType);
   3342     event->setUnderlyingEvent(underlyingEvent);
   3343 
   3344     target->dispatchEvent(event, IGNORE_EXCEPTION);
   3345     return event->defaultHandled();
   3346 }
   3347 
   3348 void EventHandler::defaultTextInputEventHandler(TextEvent* event)
   3349 {
   3350     if (m_frame->editor().handleTextEvent(event))
   3351         event->setDefaultHandled();
   3352 }
   3353 
   3354 void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
   3355 {
   3356     ASSERT(event->type() == EventTypeNames::keypress);
   3357 
   3358     if (event->ctrlKey() || event->metaKey() || event->altKey())
   3359         return;
   3360 
   3361     ScrollDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward;
   3362     if (scroll(direction, ScrollByPage)) {
   3363         event->setDefaultHandled();
   3364         return;
   3365     }
   3366 
   3367     FrameView* view = m_frame->view();
   3368     if (!view)
   3369         return;
   3370 
   3371     if (view->scroll(direction, ScrollByPage))
   3372         event->setDefaultHandled();
   3373 }
   3374 
   3375 void EventHandler::defaultBackspaceEventHandler(KeyboardEvent* event)
   3376 {
   3377     ASSERT(event->type() == EventTypeNames::keydown);
   3378 
   3379     if (event->ctrlKey() || event->metaKey() || event->altKey())
   3380         return;
   3381 
   3382     if (!m_frame->editor().behavior().shouldNavigateBackOnBackspace())
   3383         return;
   3384 
   3385     Page* page = m_frame->page();
   3386     if (!page || !page->mainFrame()->isLocalFrame())
   3387         return;
   3388     bool handledEvent = page->deprecatedLocalMainFrame()->loader().client()->navigateBackForward(event->shiftKey() ? 1 : -1);
   3389     if (handledEvent)
   3390         event->setDefaultHandled();
   3391 }
   3392 
   3393 void EventHandler::defaultArrowEventHandler(FocusType focusType, KeyboardEvent* event)
   3394 {
   3395     ASSERT(event->type() == EventTypeNames::keydown);
   3396 
   3397     if (event->ctrlKey() || event->metaKey() || event->shiftKey())
   3398         return;
   3399 
   3400     Page* page = m_frame->page();
   3401     if (!page)
   3402         return;
   3403 
   3404     if (!isSpatialNavigationEnabled(m_frame))
   3405         return;
   3406 
   3407     // Arrows and other possible directional navigation keys can be used in design
   3408     // mode editing.
   3409     if (m_frame->document()->inDesignMode())
   3410         return;
   3411 
   3412     if (page->focusController().advanceFocus(focusType))
   3413         event->setDefaultHandled();
   3414 }
   3415 
   3416 void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
   3417 {
   3418     ASSERT(event->type() == EventTypeNames::keydown);
   3419 
   3420     // We should only advance focus on tabs if no special modifier keys are held down.
   3421     if (event->ctrlKey() || event->metaKey())
   3422         return;
   3423 
   3424     Page* page = m_frame->page();
   3425     if (!page)
   3426         return;
   3427     if (!page->tabKeyCyclesThroughElements())
   3428         return;
   3429 
   3430     FocusType focusType = event->shiftKey() ? FocusTypeBackward : FocusTypeForward;
   3431 
   3432     // Tabs can be used in design mode editing.
   3433     if (m_frame->document()->inDesignMode())
   3434         return;
   3435 
   3436     if (page->focusController().advanceFocus(focusType))
   3437         event->setDefaultHandled();
   3438 }
   3439 
   3440 void EventHandler::defaultEscapeEventHandler(KeyboardEvent* event)
   3441 {
   3442     if (HTMLDialogElement* dialog = m_frame->document()->activeModalDialog())
   3443         dialog->dispatchEvent(Event::createCancelable(EventTypeNames::cancel));
   3444 }
   3445 
   3446 void EventHandler::capsLockStateMayHaveChanged()
   3447 {
   3448     if (Element* element = m_frame->document()->focusedElement()) {
   3449         if (RenderObject* r = element->renderer()) {
   3450             if (r->isTextField())
   3451                 toRenderTextControlSingleLine(r)->capsLockStateMayHaveChanged();
   3452         }
   3453     }
   3454 }
   3455 
   3456 void EventHandler::setFrameWasScrolledByUser()
   3457 {
   3458     if (FrameView* view = m_frame->view())
   3459         view->setWasScrolledByUser(true);
   3460 }
   3461 
   3462 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev)
   3463 {
   3464     Scrollbar* scrollbar = mev.scrollbar();
   3465     updateLastScrollbarUnderMouse(scrollbar, true);
   3466 
   3467     if (!scrollbar || !scrollbar->enabled())
   3468         return false;
   3469     setFrameWasScrolledByUser();
   3470     scrollbar->mouseDown(mev.event());
   3471     return true;
   3472 }
   3473 
   3474 // If scrollbar (under mouse) is different from last, send a mouse exited. Set
   3475 // last to scrollbar if setLast is true; else set last to 0.
   3476 void EventHandler::updateLastScrollbarUnderMouse(Scrollbar* scrollbar, bool setLast)
   3477 {
   3478     if (m_lastScrollbarUnderMouse != scrollbar) {
   3479         // Send mouse exited to the old scrollbar.
   3480         if (m_lastScrollbarUnderMouse)
   3481             m_lastScrollbarUnderMouse->mouseExited();
   3482 
   3483         // Send mouse entered if we're setting a new scrollbar.
   3484         if (scrollbar && setLast)
   3485             scrollbar->mouseEntered();
   3486 
   3487         m_lastScrollbarUnderMouse = setLast ? scrollbar : 0;
   3488     }
   3489 }
   3490 
   3491 static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State state)
   3492 {
   3493     switch (state) {
   3494     case PlatformTouchPoint::TouchReleased:
   3495         return EventTypeNames::touchend;
   3496     case PlatformTouchPoint::TouchCancelled:
   3497         return EventTypeNames::touchcancel;
   3498     case PlatformTouchPoint::TouchPressed:
   3499         return EventTypeNames::touchstart;
   3500     case PlatformTouchPoint::TouchMoved:
   3501         return EventTypeNames::touchmove;
   3502     case PlatformTouchPoint::TouchStationary:
   3503         // TouchStationary state is not converted to touch events, so fall through to assert.
   3504     default:
   3505         ASSERT_NOT_REACHED();
   3506         return emptyAtom;
   3507     }
   3508 }
   3509 
   3510 HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
   3511 {
   3512     HitTestResult result(point);
   3513 
   3514     if (!frame || !frame->contentRenderer())
   3515         return result;
   3516     if (frame->view()) {
   3517         IntRect rect = frame->view()->visibleContentRect(IncludeScrollbars);
   3518         if (!rect.contains(roundedIntPoint(point)))
   3519             return result;
   3520     }
   3521     frame->contentRenderer()->hitTest(HitTestRequest(hitType), result);
   3522     return result;
   3523 }
   3524 
   3525 bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
   3526 {
   3527     TRACE_EVENT0("blink", "EventHandler::handleTouchEvent");
   3528 
   3529     const Vector<PlatformTouchPoint>& points = event.touchPoints();
   3530 
   3531     unsigned i;
   3532     bool freshTouchEvents = true;
   3533     bool allTouchReleased = true;
   3534     for (i = 0; i < points.size(); ++i) {
   3535         const PlatformTouchPoint& point = points[i];
   3536         if (point.state() != PlatformTouchPoint::TouchPressed)
   3537             freshTouchEvents = false;
   3538         if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
   3539             allTouchReleased = false;
   3540     }
   3541     if (freshTouchEvents) {
   3542         // Ideally we'd ASSERT !m_touchSequenceDocument here since we should
   3543         // have cleared the active document when we saw the last release. But we
   3544         // have some tests that violate this, ClusterFuzz could trigger it, and
   3545         // there may be cases where the browser doesn't reliably release all
   3546         // touches. http://crbug.com/345372 tracks this.
   3547         m_touchSequenceDocument.clear();
   3548         m_touchSequenceUserGestureToken.clear();
   3549     }
   3550 
   3551     OwnPtr<UserGestureIndicator> gestureIndicator;
   3552 
   3553     if (m_touchSequenceUserGestureToken)
   3554         gestureIndicator = adoptPtr(new UserGestureIndicator(m_touchSequenceUserGestureToken.release()));
   3555     else
   3556         gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingUserGesture));
   3557 
   3558     m_touchSequenceUserGestureToken = gestureIndicator->currentToken();
   3559 
   3560     ASSERT(m_frame->view());
   3561     if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touchSequenceDocument->frame()->view())) {
   3562         // If the active touch document has no frame or view, it's probably being destroyed
   3563         // so we can't dispatch events.
   3564         return false;
   3565     }
   3566 
   3567     // First do hit tests for any new touch points.
   3568     for (i = 0; i < points.size(); ++i) {
   3569         const PlatformTouchPoint& point = points[i];
   3570 
   3571         // Touch events implicitly capture to the touched node, and don't change
   3572         // active/hover states themselves (Gesture events do). So we only need
   3573         // to hit-test on touchstart, and it can be read-only.
   3574         if (point.state() == PlatformTouchPoint::TouchPressed) {
   3575             HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | HitTestRequest::ReadOnly | HitTestRequest::Active;
   3576             LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->windowToContents(point.pos()));
   3577             HitTestResult result;
   3578             if (!m_touchSequenceDocument) {
   3579                 result = hitTestResultAtPoint(pagePoint, hitType);
   3580             } else if (m_touchSequenceDocument->frame()) {
   3581                 LayoutPoint framePoint = roundedLayoutPoint(m_touchSequenceDocument->frame()->view()->windowToContents(point.pos()));
   3582                 result = hitTestResultInFrame(m_touchSequenceDocument->frame(), framePoint, hitType);
   3583             } else
   3584                 continue;
   3585 
   3586             Node* node = result.innerNode();
   3587             if (!node)
   3588                 continue;
   3589 
   3590             // Touch events should not go to text nodes
   3591             if (node->isTextNode())
   3592                 node = NodeRenderingTraversal::parent(node);
   3593 
   3594             if (!m_touchSequenceDocument) {
   3595                 // Keep track of which document should receive all touch events
   3596                 // in the active sequence. This must be a single document to
   3597                 // ensure we don't leak Nodes between documents.
   3598                 m_touchSequenceDocument = &(result.innerNode()->document());
   3599                 ASSERT(m_touchSequenceDocument->frame()->view());
   3600             }
   3601 
   3602             // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
   3603             // since we shouldn't get a touchstart for a touch that's already
   3604             // down. However EventSender allows this to be violated and there's
   3605             // some tests that take advantage of it. There may also be edge
   3606             // cases in the browser where this happens.
   3607             // See http://crbug.com/345372.
   3608             m_targetForTouchID.set(point.id(), node);
   3609 
   3610             TouchAction effectiveTouchAction = computeEffectiveTouchAction(*node);
   3611             if (effectiveTouchAction != TouchActionAuto)
   3612                 m_frame->page()->chrome().client().setTouchAction(effectiveTouchAction);
   3613         }
   3614     }
   3615 
   3616     m_touchPressed = !allTouchReleased;
   3617 
   3618     // If there's no document receiving touch events, or no handlers on the
   3619     // document set to receive the events, then we can skip all the rest of
   3620     // this work.
   3621     if (!m_touchSequenceDocument || !m_touchSequenceDocument->frameHost() || !m_touchSequenceDocument->frameHost()->eventHandlerRegistry().hasEventHandlers(EventHandlerRegistry::TouchEvent) || !m_touchSequenceDocument->frame()) {
   3622         if (allTouchReleased) {
   3623             m_touchSequenceDocument.clear();
   3624             m_touchSequenceUserGestureToken.clear();
   3625         }
   3626         return false;
   3627     }
   3628 
   3629     // Build up the lists to use for the 'touches', 'targetTouches' and
   3630     // 'changedTouches' attributes in the JS event. See
   3631     // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
   3632     // lists fit together.
   3633 
   3634     // Holds the complete set of touches on the screen.
   3635     RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
   3636 
   3637     // A different view on the 'touches' list above, filtered and grouped by
   3638     // event target. Used for the 'targetTouches' list in the JS event.
   3639     typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > TargetTouchesHeapMap;
   3640     TargetTouchesHeapMap touchesByTarget;
   3641 
   3642     // Array of touches per state, used to assemble the 'changedTouches' list.
   3643     typedef WillBeHeapHashSet<RefPtrWillBeMember<EventTarget> > EventTargetSet;
   3644     struct {
   3645         // The touches corresponding to the particular change state this struct
   3646         // instance represents.
   3647         RefPtrWillBeMember<TouchList> m_touches;
   3648         // Set of targets involved in m_touches.
   3649         EventTargetSet m_targets;
   3650     } changedTouches[PlatformTouchPoint::TouchStateEnd];
   3651 
   3652     for (i = 0; i < points.size(); ++i) {
   3653         const PlatformTouchPoint& point = points[i];
   3654         PlatformTouchPoint::State pointState = point.state();
   3655         RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr;
   3656 
   3657         if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
   3658             // The target should be the original target for this touch, so get
   3659             // it from the hashmap. As it's a release or cancel we also remove
   3660             // it from the map.
   3661             touchTarget = m_targetForTouchID.take(point.id());
   3662         } else {
   3663             // No hittest is performed on move or stationary, since the target
   3664             // is not allowed to change anyway.
   3665             touchTarget = m_targetForTouchID.get(point.id());
   3666         }
   3667 
   3668         LocalFrame* targetFrame = 0;
   3669         bool knownTarget = false;
   3670         if (touchTarget) {
   3671             Document& doc = touchTarget->toNode()->document();
   3672             // If the target node has moved to a new document while it was being touched,
   3673             // we can't send events to the new document because that could leak nodes
   3674             // from one document to another. See http://crbug.com/394339.
   3675             if (&doc == m_touchSequenceDocument.get()) {
   3676                 targetFrame = doc.frame();
   3677                 knownTarget = true;
   3678             }
   3679         }
   3680         if (!knownTarget) {
   3681             // If we don't have a target registered for the point it means we've
   3682             // missed our opportunity to do a hit test for it (due to some
   3683             // optimization that prevented blink from ever seeing the
   3684             // touchstart), or that the touch started outside the active touch
   3685             // sequence document. We should still include the touch in the
   3686             // Touches list reported to the application (eg. so it can
   3687             // differentiate between a one and two finger gesture), but we won't
   3688             // actually dispatch any events for it. Set the target to the
   3689             // Document so that there's some valid node here. Perhaps this
   3690             // should really be LocalDOMWindow, but in all other cases the target of
   3691             // a Touch is a Node so using the window could be a breaking change.
   3692             // Since we know there was no handler invoked, the specific target
   3693             // should be completely irrelevant to the application.
   3694             touchTarget = m_touchSequenceDocument;
   3695             targetFrame = m_touchSequenceDocument->frame();
   3696         }
   3697         ASSERT(targetFrame);
   3698 
   3699         // pagePoint should always be relative to the target elements
   3700         // containing frame.
   3701         FloatPoint pagePoint = targetFrame->view()->windowToContents(point.pos());
   3702 
   3703         float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
   3704 
   3705         FloatPoint adjustedPagePoint = pagePoint.scaledBy(scaleFactor);
   3706         FloatSize adjustedRadius = point.radius().scaledBy(scaleFactor);
   3707 
   3708         RefPtrWillBeRawPtr<Touch> touch = Touch::create(
   3709             targetFrame, touchTarget.get(), point.id(), point.screenPos(), adjustedPagePoint, adjustedRadius, point.rotationAngle(), point.force());
   3710 
   3711         // Ensure this target's touch list exists, even if it ends up empty, so
   3712         // it can always be passed to TouchEvent::Create below.
   3713         TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
   3714         if (targetTouchesIterator == touchesByTarget.end()) {
   3715             touchesByTarget.set(touchTarget.get(), TouchList::create());
   3716             targetTouchesIterator = touchesByTarget.find(touchTarget.get());
   3717         }
   3718 
   3719         // touches and targetTouches should only contain information about
   3720         // touches still on the screen, so if this point is released or
   3721         // cancelled it will only appear in the changedTouches list.
   3722         if (pointState != PlatformTouchPoint::TouchReleased && pointState != PlatformTouchPoint::TouchCancelled) {
   3723             touches->append(touch);
   3724             targetTouchesIterator->value->append(touch);
   3725         }
   3726 
   3727         // Now build up the correct list for changedTouches.
   3728         // Note that  any touches that are in the TouchStationary state (e.g. if
   3729         // the user had several points touched but did not move them all) should
   3730         // never be in the changedTouches list so we do not handle them
   3731         // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
   3732         // for further discussion about the TouchStationary state.
   3733         if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) {
   3734             ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
   3735             if (!changedTouches[pointState].m_touches)
   3736                 changedTouches[pointState].m_touches = TouchList::create();
   3737             changedTouches[pointState].m_touches->append(touch);
   3738             changedTouches[pointState].m_targets.add(touchTarget);
   3739         }
   3740     }
   3741     if (allTouchReleased) {
   3742         m_touchSequenceDocument.clear();
   3743         m_touchSequenceUserGestureToken.clear();
   3744     }
   3745 
   3746     // Now iterate the changedTouches list and m_targets within it, sending
   3747     // events to the targets as required.
   3748     bool swallowedEvent = false;
   3749     for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
   3750         if (!changedTouches[state].m_touches)
   3751             continue;
   3752 
   3753         const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
   3754         const EventTargetSet& targetsForState = changedTouches[state].m_targets;
   3755         for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
   3756             EventTarget* touchEventTarget = it->get();
   3757             RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create(
   3758                 touches.get(), touchesByTarget.get(touchEventTarget), changedTouches[state].m_touches.get(),
   3759                 stateName, touchEventTarget->toNode()->document().domWindow(),
   3760                 event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.cancelable());
   3761             touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
   3762             swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
   3763         }
   3764     }
   3765 
   3766     return swallowedEvent;
   3767 }
   3768 
   3769 TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
   3770 {
   3771     if (action1 == TouchActionNone || action2 == TouchActionNone)
   3772         return TouchActionNone;
   3773     if (action1 == TouchActionAuto)
   3774         return action2;
   3775     if (action2 == TouchActionAuto)
   3776         return action1;
   3777     if (!(action1 & action2))
   3778         return TouchActionNone;
   3779     return action1 & action2;
   3780 }
   3781 
   3782 TouchAction EventHandler::computeEffectiveTouchAction(const Node& node)
   3783 {
   3784     // Start by permitting all actions, then walk the elements supporting
   3785     // touch-action from the target node up to the nearest scrollable ancestor
   3786     // and exclude any prohibited actions.
   3787     TouchAction effectiveTouchAction = TouchActionAuto;
   3788     for (const Node* curNode = &node; curNode; curNode = NodeRenderingTraversal::parent(curNode)) {
   3789         if (RenderObject* renderer = curNode->renderer()) {
   3790             if (renderer->supportsTouchAction()) {
   3791                 TouchAction action = renderer->style()->touchAction();
   3792                 effectiveTouchAction = intersectTouchAction(action, effectiveTouchAction);
   3793                 if (effectiveTouchAction == TouchActionNone)
   3794                     break;
   3795             }
   3796 
   3797             // If we've reached an ancestor that supports a touch action, search no further.
   3798             if (renderer->isBox() && toRenderBox(renderer)->scrollsOverflow())
   3799                 break;
   3800         }
   3801     }
   3802     return effectiveTouchAction;
   3803 }
   3804 
   3805 void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
   3806 {
   3807     m_mousePositionIsUnknown = false;
   3808     m_lastKnownMousePosition = event.position();
   3809     m_lastKnownMouseGlobalPosition = event.globalPosition();
   3810 }
   3811 
   3812 bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
   3813 {
   3814     // If we're clicking into a frame that is selected, the frame will appear
   3815     // greyed out even though we're clicking on the selection.  This looks
   3816     // really strange (having the whole frame be greyed out), so we deselect the
   3817     // selection.
   3818     IntPoint p = m_frame->view()->windowToContents(mev.event().position());
   3819     if (m_frame->selection().contains(p)) {
   3820         VisiblePosition visiblePos(
   3821             mev.innerNode()->renderer()->positionForPoint(mev.localPoint()));
   3822         VisibleSelection newSelection(visiblePos);
   3823         m_frame->selection().setSelection(newSelection);
   3824     }
   3825 
   3826     subframe->eventHandler().handleMousePressEvent(mev.event());
   3827     return true;
   3828 }
   3829 
   3830 bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode)
   3831 {
   3832     if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe)
   3833         return false;
   3834     subframe->eventHandler().handleMouseMoveOrLeaveEvent(mev.event(), hoveredNode);
   3835     return true;
   3836 }
   3837 
   3838 bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
   3839 {
   3840     subframe->eventHandler().handleMouseReleaseEvent(mev.event());
   3841     return true;
   3842 }
   3843 
   3844 bool EventHandler::passWheelEventToWidget(const PlatformWheelEvent& wheelEvent, Widget* widget)
   3845 {
   3846     // We can sometimes get a null widget!  EventHandlerMac handles a null
   3847     // widget by returning false, so we do the same.
   3848     if (!widget)
   3849         return false;
   3850 
   3851     // If not a FrameView, then probably a plugin widget.  Those will receive
   3852     // the event via an EventTargetNode dispatch when this returns false.
   3853     if (!widget->isFrameView())
   3854         return false;
   3855 
   3856     return toFrameView(widget)->frame().eventHandler().handleWheelEvent(wheelEvent);
   3857 }
   3858 
   3859 bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults& event)
   3860 {
   3861     // Figure out which view to send the event to.
   3862     if (!event.innerNode() || !event.innerNode()->renderer() || !event.innerNode()->renderer()->isWidget())
   3863         return false;
   3864     return false;
   3865 }
   3866 
   3867 PassRefPtrWillBeRawPtr<DataTransfer> EventHandler::createDraggingDataTransfer() const
   3868 {
   3869     return DataTransfer::create(DataTransfer::DragAndDrop, DataTransferWritable, DataObject::create());
   3870 }
   3871 
   3872 void EventHandler::focusDocumentView()
   3873 {
   3874     Page* page = m_frame->page();
   3875     if (!page)
   3876         return;
   3877     page->focusController().focusDocumentView(m_frame);
   3878 }
   3879 
   3880 unsigned EventHandler::accessKeyModifiers()
   3881 {
   3882 #if OS(MACOSX)
   3883     return PlatformEvent::CtrlKey | PlatformEvent::AltKey;
   3884 #else
   3885     return PlatformEvent::AltKey;
   3886 #endif
   3887 }
   3888 
   3889 } // namespace blink
   3890