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