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