30a3f72bea989edf035e3b010819b6936502ff82
[WebKit-https.git] / Source / WebCore / page / EventHandler.h
1 /*
2  * Copyright (C) 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef EventHandler_h
27 #define EventHandler_h
28
29 #include "Cursor.h"
30 #include "DragActions.h"
31 #include "DragState.h"
32 #include "FocusDirection.h"
33 #include "HitTestRequest.h"
34 #include "PlatformMouseEvent.h"
35 #include "PlatformWheelEvent.h"
36 #include "ScrollTypes.h"
37 #include "TextEventInputType.h"
38 #include "TextGranularity.h"
39 #include "Timer.h"
40 #include "UserGestureIndicator.h"
41 #include <wtf/Forward.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/RefPtr.h>
44
45 #if PLATFORM(MAC) && !defined(__OBJC__)
46 class NSView;
47 #endif
48
49 #if ENABLE(TOUCH_EVENTS)
50 #include <wtf/HashMap.h>
51 #endif
52
53 namespace WebCore {
54
55 class AutoscrollController;
56 class Clipboard;
57 class Event;
58 class EventTarget;
59 class FloatPoint;
60 class FloatQuad;
61 class Frame;
62 class HTMLFrameSetElement;
63 class HitTestRequest;
64 class HitTestResult;
65 class KeyboardEvent;
66 class MouseEventWithHitTestResults;
67 class Node;
68 class OptionalCursor;
69 class PlatformKeyboardEvent;
70 class PlatformTouchEvent;
71 class PlatformWheelEvent;
72 class RenderLayer;
73 class RenderObject;
74 class RenderWidget;
75 class SVGElementInstance;
76 class Scrollbar;
77 class TextEvent;
78 class TouchEvent;
79 class VisibleSelection;
80 class WheelEvent;
81 class Widget;
82
83 #if ENABLE(GESTURE_EVENTS)
84 class PlatformGestureEvent;
85 #endif
86
87 #if ENABLE(DRAG_SUPPORT)
88 extern const int LinkDragHysteresis;
89 extern const int ImageDragHysteresis;
90 extern const int TextDragHysteresis;
91 extern const int GeneralDragHysteresis;
92 #endif // ENABLE(DRAG_SUPPORT)
93
94 enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
95 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
96 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
97
98 class EventHandler {
99     WTF_MAKE_NONCOPYABLE(EventHandler);
100 public:
101     explicit EventHandler(Frame*);
102     ~EventHandler();
103
104     void clear();
105     void nodeWillBeRemoved(Node*);
106
107 #if ENABLE(DRAG_SUPPORT)
108     void updateSelectionForMouseDrag();
109 #endif
110
111     Node* mousePressNode() const;
112     void setMousePressNode(PassRefPtr<Node>);
113
114 #if ENABLE(PAN_SCROLLING)
115     void didPanScrollStart();
116     void didPanScrollStop();
117     void startPanScrolling(RenderObject*);
118 #endif
119
120     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
121     RenderObject* autoscrollRenderer() const;
122     void updateAutoscrollRenderer();
123     bool autoscrollInProgress() const;
124     bool mouseDownWasInSubframe() const { return m_mouseDownWasInSubframe; }
125     bool panScrollInProgress() const;
126
127     void dispatchFakeMouseMoveEventSoon();
128     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
129
130     HitTestResult hitTestResultAtPoint(const LayoutPoint&, bool allowShadowContent, bool ignoreClipping = false,
131                                        HitTestScrollbars scrollbars = DontHitTestScrollbars,
132                                        HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
133                                        const LayoutSize& padding = LayoutSize());
134
135     bool mousePressed() const { return m_mousePressed; }
136     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
137
138     void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
139
140 #if ENABLE(DRAG_SUPPORT)
141     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
142     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
143     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
144     void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
145 #endif
146
147     void scheduleHoverStateUpdate();
148
149     void setResizingFrameSet(HTMLFrameSetElement*);
150
151     void resizeLayerDestroyed();
152
153     IntPoint lastKnownMousePosition() const;
154     Cursor currentMouseCursor() const { return m_currentMouseCursor; }
155
156     static Frame* subframeForTargetNode(Node*);
157     static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
158
159     bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
160     bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
161     bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
162
163     bool tabsToLinks(KeyboardEvent*) const;
164     bool tabsToAllFormControls(KeyboardEvent*) const;
165
166     bool mouseMoved(const PlatformMouseEvent&);
167     bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
168
169     void lostMouseCapture();
170
171     bool handleMousePressEvent(const PlatformMouseEvent&);
172     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
173     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
174     bool handleWheelEvent(const PlatformWheelEvent&);
175     void defaultWheelEventHandler(Node*, WheelEvent*);
176     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
177
178 #if ENABLE(GESTURE_EVENTS)
179     bool handleGestureEvent(const PlatformGestureEvent&);
180     bool handleGestureTap(const PlatformGestureEvent&);
181     bool handleGestureLongPress(const PlatformGestureEvent&);
182     bool handleGestureLongTap(const PlatformGestureEvent&);
183     bool handleGestureTwoFingerTap(const PlatformGestureEvent&);
184     bool handleGestureScrollUpdate(const PlatformGestureEvent&);
185     bool handleGestureScrollBegin(const PlatformGestureEvent&);
186     bool isScrollbarHandlingGestures() const;
187 #endif
188
189 #if ENABLE(TOUCH_ADJUSTMENT)
190     bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
191
192     bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
193     bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
194     bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
195
196     bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
197 #endif
198
199 #if ENABLE(CONTEXT_MENUS)
200     bool sendContextMenuEvent(const PlatformMouseEvent&);
201     bool sendContextMenuEventForKey();
202 #if ENABLE(GESTURE_EVENTS)
203     bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
204 #endif
205 #endif
206
207     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
208
209     bool needsKeyboardEventDisambiguationQuirks() const;
210
211     static unsigned accessKeyModifiers();
212     bool handleAccessKey(const PlatformKeyboardEvent&);
213     bool keyEvent(const PlatformKeyboardEvent&);
214     void defaultKeyboardEventHandler(KeyboardEvent*);
215
216     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
217     void defaultTextInputEventHandler(TextEvent*);
218
219 #if ENABLE(DRAG_SUPPORT)
220     bool eventMayStartDrag(const PlatformMouseEvent&) const;
221     
222     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
223 #endif
224
225     void focusDocumentView();
226
227     void capsLockStateMayHaveChanged(); // Only called by FrameSelection
228     
229     void sendResizeEvent(); // Only called in FrameView
230     void sendScrollEvent(); // Ditto
231
232 #if PLATFORM(MAC) && defined(__OBJC__)
233     void mouseDown(NSEvent *);
234     void mouseDragged(NSEvent *);
235     void mouseUp(NSEvent *);
236     void mouseMoved(NSEvent *);
237     bool keyEvent(NSEvent *);
238     bool wheelEvent(NSEvent *);
239
240     void passMouseMovedEventToScrollbars(NSEvent *);
241
242     void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
243
244     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
245
246     static NSEvent *currentNSEvent();
247 #endif
248
249 #if ENABLE(TOUCH_EVENTS)
250     bool handleTouchEvent(const PlatformTouchEvent&);
251 #endif
252
253     bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
254     void updateCursor();
255
256 private:
257 #if ENABLE(DRAG_SUPPORT)
258     static DragState& dragState();
259     static const double TextDragDelay;
260     
261     PassRefPtr<Clipboard> createDraggingClipboard() const;
262 #endif // ENABLE(DRAG_SUPPORT)
263
264     bool eventActivatedView(const PlatformMouseEvent&) const;
265     bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
266     void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
267     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
268     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
269
270     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
271
272     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
273     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
274     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
275     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
276 #if ENABLE(DRAG_SUPPORT)
277     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
278 #endif
279     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
280
281     OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
282
283     void hoverTimerFired(Timer<EventHandler>*);
284
285     bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
286     
287     bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
288     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
289
290     static bool isKeyboardOptionTab(KeyboardEvent*);
291     static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
292
293     void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
294     void cancelFakeMouseMoveEvent();
295
296     bool isInsideScrollbar(const IntPoint&) const;
297
298 #if ENABLE(TOUCH_EVENTS)
299     bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
300     HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
301 #endif
302
303     void invalidateClick();
304
305     Node* nodeUnderMouse() const;
306     
307     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
308     void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
309     
310     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
311
312     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
313 #if ENABLE(DRAG_SUPPORT)
314     bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
315
316     void freeClipboard();
317
318     bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
319 #endif
320     bool handleMouseUp(const MouseEventWithHitTestResults&);
321 #if ENABLE(DRAG_SUPPORT)
322     void clearDragState();
323
324     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
325
326     bool dragHysteresisExceeded(const FloatPoint&) const;
327     bool dragHysteresisExceeded(const IntPoint&) const;
328 #endif // ENABLE(DRAG_SUPPORT)
329
330     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
331     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
332     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
333
334     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
335
336     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
337
338     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
339     bool passWidgetMouseDownEventToWidget(RenderWidget*);
340
341     bool passMouseDownEventToWidget(Widget*);
342     bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
343
344     void defaultSpaceEventHandler(KeyboardEvent*);
345     void defaultBackspaceEventHandler(KeyboardEvent*);
346     void defaultTabEventHandler(KeyboardEvent*);
347     void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
348
349 #if ENABLE(DRAG_SUPPORT)
350     DragSourceAction updateDragSourceActionsAllowed() const;
351 #endif
352
353     // The following are called at the beginning of handleMouseUp and handleDrag.  
354     // If they return true it indicates that they have consumed the event.
355     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
356 #if ENABLE(DRAG_SUPPORT)
357     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
358 #endif
359
360 #if ENABLE(DRAG_SUPPORT)
361     void updateSelectionForMouseDrag(const HitTestResult&);
362 #endif
363
364     void updateLastScrollbarUnderMouse(Scrollbar*, bool);
365     
366     void setFrameWasScrolledByUser();
367
368     bool capturesDragging() const { return m_capturesDragging; }
369
370 #if PLATFORM(MAC) && defined(__OBJC__)
371     NSView *mouseDownViewIfStillGood();
372
373     PlatformMouseEvent currentPlatformMouseEvent() const;
374 #endif
375
376 #if ENABLE(FULLSCREEN_API)
377     bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
378 #endif
379
380 #if ENABLE(GESTURE_EVENTS)
381     bool handleGestureTapDown();
382     bool handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent&);
383     bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
384     bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
385 #endif
386
387     void setLastKnownMousePosition(const PlatformMouseEvent&);
388
389     Frame* m_frame;
390
391     bool m_mousePressed;
392     bool m_capturesDragging;
393     RefPtr<Node> m_mousePressNode;
394
395     bool m_mouseDownMayStartSelect;
396 #if ENABLE(DRAG_SUPPORT)
397     bool m_mouseDownMayStartDrag;
398     bool m_dragMayStartSelectionInstead;
399 #endif
400     bool m_mouseDownWasSingleClickInSelection;
401     enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
402     SelectionInitiationState m_selectionInitiationState;
403
404 #if ENABLE(DRAG_SUPPORT)
405     LayoutPoint m_dragStartPos;
406 #endif
407
408     bool m_panScrollButtonPressed;
409
410     Timer<EventHandler> m_hoverTimer;
411
412     OwnPtr<AutoscrollController> m_autoscrollController;
413     bool m_mouseDownMayStartAutoscroll;
414     bool m_mouseDownWasInSubframe;
415
416     Timer<EventHandler> m_fakeMouseMoveEventTimer;
417
418 #if ENABLE(SVG)
419     bool m_svgPan;
420     RefPtr<SVGElementInstance> m_instanceUnderMouse;
421     RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
422 #endif
423
424     RenderLayer* m_resizeLayer;
425
426     RefPtr<Node> m_capturingMouseEventsNode;
427     bool m_eventHandlerWillResetCapturingMouseEventsNode;
428     
429     RefPtr<Node> m_nodeUnderMouse;
430     RefPtr<Node> m_lastNodeUnderMouse;
431     RefPtr<Frame> m_lastMouseMoveEventSubframe;
432     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
433     Cursor m_currentMouseCursor;
434
435     int m_clickCount;
436     RefPtr<Node> m_clickNode;
437
438 #if ENABLE(DRAG_SUPPORT)
439     RefPtr<Node> m_dragTarget;
440     bool m_shouldOnlyFireDragOverEvent;
441 #endif
442     
443     RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
444
445     LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
446     
447     bool m_mousePositionIsUnknown;
448     IntPoint m_lastKnownMousePosition;
449     IntPoint m_lastKnownMouseGlobalPosition;
450     IntPoint m_mouseDownPos; // In our view's coords.
451     double m_mouseDownTimestamp;
452     PlatformMouseEvent m_mouseDown;
453     RefPtr<UserGestureIndicator::Token> m_lastMouseDownUserGestureToken;
454
455     RefPtr<Node> m_latchedWheelEventNode;
456     bool m_widgetIsLatched;
457
458     RefPtr<Node> m_previousWheelScrolledNode;
459
460 #if PLATFORM(MAC)
461     NSView *m_mouseDownView;
462     bool m_sendingEventToSubview;
463     int m_activationEventNumber;
464 #endif
465 #if ENABLE(TOUCH_EVENTS)
466     typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
467     TouchTargetMap m_originatingTouchPointTargets;
468     RefPtr<Document> m_originatingTouchPointDocument;
469     unsigned m_originatingTouchPointTargetKey;
470     bool m_touchPressed;
471 #endif
472
473 #if ENABLE(GESTURE_EVENTS)
474     RefPtr<Node> m_scrollGestureHandlingNode;
475     bool m_lastHitTestResultOverWidget;
476     RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
477 #endif
478
479     double m_maxMouseMovedDuration;
480     PlatformEvent::Type m_baseEventType;
481     bool m_didStartDrag;
482     bool m_didLongPressInvokeContextMenu;
483 };
484
485 } // namespace WebCore
486
487 #endif // EventHandler_h