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