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