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