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