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