c9f8e6dbf4ccb51baad3f9c313c8158886994cb4
[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 <wtf/Forward.h>
41 #include <wtf/OwnPtr.h>
42 #include <wtf/RefPtr.h>
43
44 #if PLATFORM(MAC) && !defined(__OBJC__)
45 class NSView;
46 #endif
47
48 #if ENABLE(TOUCH_EVENTS)
49 #include <wtf/HashMap.h>
50 #endif
51
52 namespace WebCore {
53
54 class Clipboard;
55 class Event;
56 class EventTarget;
57 class FloatPoint;
58 class FloatQuad;
59 class Frame;
60 class HTMLFrameSetElement;
61 class HitTestRequest;
62 class HitTestResult;
63 class KeyboardEvent;
64 class MouseEventWithHitTestResults;
65 class Node;
66 class OptionalCursor;
67 class PlatformKeyboardEvent;
68 class PlatformTouchEvent;
69 class PlatformWheelEvent;
70 class RenderLayer;
71 class RenderObject;
72 class RenderWidget;
73 class SVGElementInstance;
74 class Scrollbar;
75 class TextEvent;
76 class TouchEvent;
77 class VisibleSelection;
78 class WheelEvent;
79 class Widget;
80
81 #if ENABLE(GESTURE_EVENTS)
82 class PlatformGestureEvent;
83 #endif
84
85 #if ENABLE(DRAG_SUPPORT)
86 extern const int LinkDragHysteresis;
87 extern const int ImageDragHysteresis;
88 extern const int TextDragHysteresis;
89 extern const int GeneralDragHysteresis;
90 #endif // ENABLE(DRAG_SUPPORT)
91
92 enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
93 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
94 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
95
96 class EventHandler {
97     WTF_MAKE_NONCOPYABLE(EventHandler);
98 public:
99     explicit EventHandler(Frame*);
100     ~EventHandler();
101
102     void clear();
103     void nodeWillBeRemoved(Node*);
104
105 #if ENABLE(DRAG_SUPPORT)
106     void updateSelectionForMouseDrag();
107 #endif
108
109     Node* mousePressNode() const;
110     void setMousePressNode(PassRefPtr<Node>);
111
112     void startPanScrolling(RenderObject*);
113
114     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
115     RenderObject* autoscrollRenderer() const;
116     void updateAutoscrollRenderer();
117     bool autoscrollInProgress() const { return m_autoscrollInProgress; }
118
119     void dispatchFakeMouseMoveEventSoon();
120     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
121
122     HitTestResult hitTestResultAtPoint(const LayoutPoint&, bool allowShadowContent, bool ignoreClipping = false,
123                                        HitTestScrollbars scrollbars = DontHitTestScrollbars,
124                                        HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
125                                        const LayoutSize& padding = LayoutSize());
126
127     bool mousePressed() const { return m_mousePressed; }
128     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
129
130     void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
131
132 #if ENABLE(DRAG_SUPPORT)
133     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
134     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
135     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
136     void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
137 #endif
138
139     void scheduleHoverStateUpdate();
140
141     void setResizingFrameSet(HTMLFrameSetElement*);
142
143     void resizeLayerDestroyed();
144
145     IntPoint currentMousePosition() const;
146     Cursor currentMouseCursor() const { return m_currentMouseCursor; }
147
148     static Frame* subframeForTargetNode(Node*);
149     static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
150
151     bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
152     bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
153     bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
154
155     bool tabsToLinks(KeyboardEvent*) const;
156     bool tabsToAllFormControls(KeyboardEvent*) const;
157
158     bool mouseMoved(const PlatformMouseEvent&);
159     bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
160
161     void lostMouseCapture();
162
163     bool handleMousePressEvent(const PlatformMouseEvent&);
164     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
165     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
166     bool handleWheelEvent(const PlatformWheelEvent&);
167     void defaultWheelEventHandler(Node*, WheelEvent*);
168     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
169
170 #if ENABLE(GESTURE_EVENTS)
171     bool handleGestureEvent(const PlatformGestureEvent&);
172     bool handleGestureTap(const PlatformGestureEvent&);
173     bool handleGestureLongPress(const PlatformGestureEvent&);
174     bool handleGestureLongTap(const PlatformGestureEvent&);
175     bool handleGestureTwoFingerTap(const PlatformGestureEvent&);
176     bool handleGestureScrollUpdate(const PlatformGestureEvent&);
177     bool isScrollbarHandlingGestures() const;
178 #endif
179
180 #if ENABLE(TOUCH_ADJUSTMENT)
181     bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
182
183     bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
184     bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
185     bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
186
187     bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
188 #endif
189
190 #if ENABLE(CONTEXT_MENUS)
191     bool sendContextMenuEvent(const PlatformMouseEvent&);
192     bool sendContextMenuEventForKey();
193 #if ENABLE(GESTURE_EVENTS)
194     bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
195 #endif
196 #endif
197
198     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
199
200     bool needsKeyboardEventDisambiguationQuirks() const;
201
202     static unsigned accessKeyModifiers();
203     bool handleAccessKey(const PlatformKeyboardEvent&);
204     bool keyEvent(const PlatformKeyboardEvent&);
205     void defaultKeyboardEventHandler(KeyboardEvent*);
206
207     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
208     void defaultTextInputEventHandler(TextEvent*);
209
210 #if ENABLE(DRAG_SUPPORT)
211     bool eventMayStartDrag(const PlatformMouseEvent&) const;
212     
213     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
214 #endif
215
216     void focusDocumentView();
217
218     void capsLockStateMayHaveChanged(); // Only called by FrameSelection
219     
220     void sendResizeEvent(); // Only called in FrameView
221     void sendScrollEvent(); // Ditto
222
223 #if PLATFORM(MAC) && defined(__OBJC__)
224     void mouseDown(NSEvent *);
225     void mouseDragged(NSEvent *);
226     void mouseUp(NSEvent *);
227     void mouseMoved(NSEvent *);
228     bool keyEvent(NSEvent *);
229     bool wheelEvent(NSEvent *);
230
231     void passMouseMovedEventToScrollbars(NSEvent *);
232
233     void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
234
235     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
236
237     static NSEvent *currentNSEvent();
238 #endif
239
240 #if ENABLE(TOUCH_EVENTS)
241     bool handleTouchEvent(const PlatformTouchEvent&);
242 #endif
243
244     bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
245
246 private:
247 #if ENABLE(DRAG_SUPPORT)
248     static DragState& dragState();
249     static const double TextDragDelay;
250     
251     PassRefPtr<Clipboard> createDraggingClipboard() const;
252 #endif // ENABLE(DRAG_SUPPORT)
253
254     bool eventActivatedView(const PlatformMouseEvent&) const;
255     bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
256     void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
257     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
258     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
259
260     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
261
262     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
263     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
264     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
265     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
266 #if ENABLE(DRAG_SUPPORT)
267     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
268 #endif
269     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
270
271     OptionalCursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
272 #if ENABLE(PAN_SCROLLING)
273     void updatePanScrollState();
274 #endif
275
276     void hoverTimerFired(Timer<EventHandler>*);
277
278     void handleAutoscroll(RenderObject*);
279     void startAutoscrollTimer();
280     void setAutoscrollRenderer(RenderObject*);
281     void autoscrollTimerFired(Timer<EventHandler>*);
282     bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
283     
284     bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
285     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
286
287     static bool isKeyboardOptionTab(KeyboardEvent*);
288     static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
289
290     void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
291     void cancelFakeMouseMoveEvent();
292
293     bool isInsideScrollbar(const IntPoint&) const;
294
295 #if ENABLE(TOUCH_EVENTS)
296     bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
297     HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
298 #endif
299
300     void invalidateClick();
301
302     Node* nodeUnderMouse() const;
303     
304     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
305     void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
306     
307     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
308
309     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
310 #if ENABLE(DRAG_SUPPORT)
311     bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
312
313     void freeClipboard();
314
315     bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
316 #endif
317     bool handleMouseUp(const MouseEventWithHitTestResults&);
318 #if ENABLE(DRAG_SUPPORT)
319     void clearDragState();
320
321     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
322
323     bool dragHysteresisExceeded(const FloatPoint&) const;
324     bool dragHysteresisExceeded(const IntPoint&) const;
325 #endif // ENABLE(DRAG_SUPPORT)
326
327     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
328     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
329     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
330
331     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
332
333     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
334
335     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
336     bool passWidgetMouseDownEventToWidget(RenderWidget*);
337
338     bool passMouseDownEventToWidget(Widget*);
339     bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
340
341     void defaultSpaceEventHandler(KeyboardEvent*);
342     void defaultBackspaceEventHandler(KeyboardEvent*);
343     void defaultTabEventHandler(KeyboardEvent*);
344     void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
345
346 #if ENABLE(DRAG_SUPPORT)
347     DragSourceAction updateDragSourceActionsAllowed() const;
348 #endif
349
350     // The following are called at the beginning of handleMouseUp and handleDrag.  
351     // If they return true it indicates that they have consumed the event.
352     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
353 #if ENABLE(DRAG_SUPPORT)
354     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
355 #endif
356
357 #if ENABLE(DRAG_SUPPORT)
358     void updateSelectionForMouseDrag(const HitTestResult&);
359 #endif
360
361     void updateLastScrollbarUnderMouse(Scrollbar*, bool);
362     
363     void setFrameWasScrolledByUser();
364
365     bool capturesDragging() const { return m_capturesDragging; }
366
367 #if PLATFORM(MAC) && defined(__OBJC__)
368     NSView *mouseDownViewIfStillGood();
369
370     PlatformMouseEvent currentPlatformMouseEvent() const;
371 #endif
372
373 #if ENABLE(FULLSCREEN_API)
374     bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
375 #endif
376
377 #if ENABLE(GESTURE_EVENTS)
378     bool handleGestureScrollCore(const PlatformGestureEvent&, PlatformWheelEventGranularity, bool latchedWheel);
379     bool handleGestureTapDown();
380     bool handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent&);
381 #endif
382
383     Frame* m_frame;
384
385     bool m_mousePressed;
386     bool m_capturesDragging;
387     RefPtr<Node> m_mousePressNode;
388
389     bool m_mouseDownMayStartSelect;
390 #if ENABLE(DRAG_SUPPORT)
391     bool m_mouseDownMayStartDrag;
392     bool m_dragMayStartSelectionInstead;
393 #endif
394     bool m_mouseDownWasSingleClickInSelection;
395     enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
396     SelectionInitiationState m_selectionInitiationState;
397
398 #if ENABLE(DRAG_SUPPORT)
399     LayoutPoint m_dragStartPos;
400 #endif
401
402     IntPoint m_panScrollStartPos;
403     bool m_panScrollInProgress;
404
405     bool m_panScrollButtonPressed;
406     bool m_springLoadedPanScrollInProgress;
407
408     Timer<EventHandler> m_hoverTimer;
409     
410     Timer<EventHandler> m_autoscrollTimer;
411     RenderObject* m_autoscrollRenderer;
412     bool m_autoscrollInProgress;
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     IntPoint m_currentMousePosition;
448     IntPoint m_currentMouseGlobalPosition;
449     IntPoint m_mouseDownPos; // In our view's coords.
450     double m_mouseDownTimestamp;
451     PlatformMouseEvent m_mouseDown;
452
453     RefPtr<Node> m_latchedWheelEventNode;
454     bool m_widgetIsLatched;
455
456     RefPtr<Node> m_previousWheelScrolledNode;
457
458 #if PLATFORM(MAC)
459     NSView *m_mouseDownView;
460     bool m_sendingEventToSubview;
461     int m_activationEventNumber;
462 #endif
463 #if ENABLE(TOUCH_EVENTS)
464     typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
465     TouchTargetMap m_originatingTouchPointTargets;
466     RefPtr<Document> m_originatingTouchPointDocument;
467     unsigned m_originatingTouchPointTargetKey;
468     bool m_touchPressed;
469 #endif
470
471 #if ENABLE(GESTURE_EVENTS)
472     RefPtr<Node> m_scrollGestureHandlingNode;
473     RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
474 #endif
475
476     double m_maxMouseMovedDuration;
477     PlatformEvent::Type m_baseEventType;
478     bool m_didStartDrag;
479     bool m_didLongPressInvokeContextMenu;
480 };
481
482 } // namespace WebCore
483
484 #endif // EventHandler_h