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