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