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