Added haptics implementation that is based on the haptics CSS properties and uses...
[webkit:kimgronholms-webkit.git] / WebCore / page / EventHandler.h
1 /*
2  * Copyright (C) 2006, 2007, 2009, 2010 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 "DragActions.h"
30 #include "FocusDirection.h"
31 #include "HitTestRequest.h"
32 #include "PlatformMouseEvent.h"
33 #include "ScrollTypes.h"
34 #include "Timer.h"
35 #include <wtf/Forward.h>
36 #include <wtf/RefPtr.h>
37
38 #if PLATFORM(MAC) && !defined(__OBJC__)
39 class NSView;
40 #endif
41
42 #if ENABLE(TOUCH_EVENTS)
43 #include <wtf/HashMap.h>
44 #endif
45
46 namespace WebCore {
47
48 class AtomicString;
49 class Clipboard;
50 class Cursor;
51 class Event;
52 class EventTarget;
53 class FloatPoint;
54 class FloatQuad;
55 class Frame;
56 class HitTestRequest;
57 class HitTestResult;
58 class HTMLFrameSetElement;
59 class KeyboardEvent;
60 class MouseEventWithHitTestResults;
61 class Node;
62 class PlatformKeyboardEvent;
63 class PlatformTouchEvent;
64 class PlatformWheelEvent;
65 class RenderLayer;
66 class RenderObject;
67 class RenderWidget;
68 class Scrollbar;
69 class String;
70 class SVGElementInstance;
71 class TextEvent;
72 class TouchEvent;
73 class WheelEvent;
74 class Widget;
75     
76 #if ENABLE(DRAG_SUPPORT)
77 extern const int LinkDragHysteresis;
78 extern const int ImageDragHysteresis;
79 extern const int TextDragHysteresis;
80 extern const int GeneralDragHysteresis;
81 #endif // ENABLE(DRAG_SUPPORT)
82
83 enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
84
85 class EventHandler : public Noncopyable {
86 public:
87     EventHandler(Frame*);
88     ~EventHandler();
89
90     void clear();
91
92 #if ENABLE(DRAG_SUPPORT)
93     void updateSelectionForMouseDrag();
94 #endif
95
96     Node* mousePressNode() const;
97     void setMousePressNode(PassRefPtr<Node>);
98
99     void startPanScrolling(RenderObject*);
100     bool panScrollInProgress() { return m_panScrollInProgress; }
101     void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; }
102
103     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
104     RenderObject* autoscrollRenderer() const;
105     void updateAutoscrollRenderer();
106
107     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
108
109     HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars, int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
110
111     bool mousePressed() const { return m_mousePressed; }
112     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
113
114     void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
115
116 #if ENABLE(DRAG_SUPPORT)
117     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
118     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
119     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
120 #endif
121
122     void scheduleHoverStateUpdate();
123
124     void setResizingFrameSet(HTMLFrameSetElement*);
125
126     void resizeLayerDestroyed();
127
128     IntPoint currentMousePosition() const;
129
130     void setIgnoreWheelEvents(bool);
131
132     static Frame* subframeForTargetNode(Node*);
133
134     bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
135
136     bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
137
138 #if ENABLE(DRAG_SUPPORT)
139     bool shouldDragAutoNode(Node*, const IntPoint&) const; // -webkit-user-drag == auto
140 #endif
141
142     bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&) const;
143
144     bool tabsToLinks(KeyboardEvent*) const;
145     bool tabsToAllControls(KeyboardEvent*) const;
146
147     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
148
149     bool mouseMoved(const PlatformMouseEvent&);
150
151     void lostMouseCapture();
152
153     bool handleMousePressEvent(const PlatformMouseEvent&);
154     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0);
155     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
156     bool handleWheelEvent(PlatformWheelEvent&);
157     void defaultWheelEventHandler(Node*, WheelEvent*);
158
159 #if ENABLE(CONTEXT_MENUS)
160     bool sendContextMenuEvent(const PlatformMouseEvent&);
161     bool sendContextMenuEventForKey();
162 #endif
163
164     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
165
166     bool needsKeyboardEventDisambiguationQuirks() const;
167
168     static unsigned accessKeyModifiers();
169     bool handleAccessKey(const PlatformKeyboardEvent&);
170     bool keyEvent(const PlatformKeyboardEvent&);
171     void defaultKeyboardEventHandler(KeyboardEvent*);
172
173     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0,
174         bool isLineBreak = false, bool isBackTab = false);
175     void defaultTextInputEventHandler(TextEvent*);
176
177 #if ENABLE(DRAG_SUPPORT)
178     bool eventMayStartDrag(const PlatformMouseEvent&) const;
179     
180     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
181 #endif
182
183     void focusDocumentView();
184
185     void capsLockStateMayHaveChanged();
186     
187     void sendResizeEvent();
188     void sendScrollEvent();
189     
190 #if PLATFORM(MAC) && defined(__OBJC__)
191     PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;
192
193     void mouseDown(NSEvent *);
194     void mouseDragged(NSEvent *);
195     void mouseUp(NSEvent *);
196     void mouseMoved(NSEvent *);
197     bool keyEvent(NSEvent *);
198     bool wheelEvent(NSEvent *);
199
200 #if ENABLE(CONTEXT_MENUS)
201     bool sendContextMenuEvent(NSEvent *);
202 #endif
203     bool eventMayStartDrag(NSEvent *);
204
205     void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
206
207     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
208
209     static NSEvent *currentNSEvent();
210 #endif
211
212 #if ENABLE(TOUCH_EVENTS)
213     bool handleTouchEvent(const PlatformTouchEvent&);
214 #endif
215
216 private:
217 #if ENABLE(DRAG_SUPPORT)
218     enum DragAndDropHandleType {
219         UpdateDragAndDrop,
220         CancelDragAndDrop,
221         PerformDragAndDrop
222     };
223
224     struct EventHandlerDragState : Noncopyable {
225         RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
226         bool m_dragSrcIsLink;
227         bool m_dragSrcIsImage;
228         bool m_dragSrcInSelection;
229         bool m_dragSrcMayBeDHTML;
230         bool m_dragSrcMayBeUA; // Are DHTML and/or the UserAgent allowed to drag out?
231         bool m_dragSrcIsDHTML;
232         RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
233     };
234     static EventHandlerDragState& dragState();
235     static const double TextDragDelay;
236
237     bool canHandleDragAndDropForTarget(DragAndDropHandleType, Node* target, const PlatformMouseEvent&, Clipboard*, bool* accepted = 0);
238     
239     PassRefPtr<Clipboard> createDraggingClipboard() const;
240 #endif // ENABLE(DRAG_SUPPORT)
241     
242     bool eventActivatedView(const PlatformMouseEvent&) const;
243     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
244     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
245
246     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
247
248     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
249     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
250     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
251     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
252 #if ENABLE(DRAG_SUPPORT)
253     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
254 #endif
255     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
256
257     void handleKeyboardSelectionMovement(KeyboardEvent*);
258     
259     Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
260 #if ENABLE(PAN_SCROLLING)
261     void updatePanScrollState();
262 #endif
263
264     void hoverTimerFired(Timer<EventHandler>*);
265
266     static bool canMouseDownStartSelect(Node*);
267 #if ENABLE(DRAG_SUPPORT)
268     static bool canMouseDragExtendSelect(Node*);
269 #endif
270
271     void handleAutoscroll(RenderObject*);
272     void startAutoscrollTimer();
273     void setAutoscrollRenderer(RenderObject*);
274     void autoscrollTimerFired(Timer<EventHandler>*);
275
276     void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
277     void cancelFakeMouseMoveEvent();
278
279     void invalidateClick();
280
281     Node* nodeUnderMouse() const;
282     
283     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
284     void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
285     
286     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
287
288     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
289 #if ENABLE(DRAG_SUPPORT)
290     bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
291
292     void freeClipboard();
293
294     bool handleDrag(const MouseEventWithHitTestResults&);
295 #endif
296     bool handleMouseUp(const MouseEventWithHitTestResults&);
297 #if ENABLE(DRAG_SUPPORT)
298     void clearDragState();
299
300     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
301
302     bool dragHysteresisExceeded(const FloatPoint&) const;
303     bool dragHysteresisExceeded(const IntPoint&) const;
304 #endif // ENABLE(DRAG_SUPPORT)
305
306     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
307     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
308     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
309
310     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
311
312     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
313
314     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
315     bool passWidgetMouseDownEventToWidget(RenderWidget*);
316
317     bool passMouseDownEventToWidget(Widget*);
318     bool passWheelEventToWidget(PlatformWheelEvent&, Widget*);
319
320     void defaultSpaceEventHandler(KeyboardEvent*);
321     void defaultTabEventHandler(KeyboardEvent*);
322     void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
323
324 #if ENABLE(DRAG_SUPPORT)
325     void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
326 #endif
327
328     // The following are called at the beginning of handleMouseUp and handleDrag.  
329     // If they return true it indicates that they have consumed the event.
330     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
331 #if ENABLE(DRAG_SUPPORT)
332     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
333 #endif
334
335     bool invertSenseOfTabsToLinks(KeyboardEvent*) const;
336
337 #if ENABLE(DRAG_SUPPORT)
338     void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint);
339 #endif
340
341     void updateLastScrollbarUnderMouse(Scrollbar*, bool);
342     
343     void setFrameWasScrolledByUser();
344
345     FocusDirection focusDirectionForKey(const AtomicString&) const;
346
347     bool capturesDragging() const { return m_capturesDragging; }
348
349 #if PLATFORM(MAC) && defined(__OBJC__)
350     NSView *mouseDownViewIfStillGood();
351
352     PlatformMouseEvent currentPlatformMouseEvent() const;
353 #endif
354
355     Frame* m_frame;
356
357     bool m_mousePressed;
358     bool m_capturesDragging;
359     RefPtr<Node> m_mousePressNode;
360
361     bool m_mouseDownMayStartSelect;
362 #if ENABLE(DRAG_SUPPORT)
363     bool m_mouseDownMayStartDrag;
364 #endif
365     bool m_mouseDownWasSingleClickInSelection;
366     bool m_beganSelectingText;
367
368 #if ENABLE(DRAG_SUPPORT)
369     IntPoint m_dragStartPos;
370 #endif
371
372     IntPoint m_panScrollStartPos;
373     bool m_panScrollInProgress;
374
375     bool m_panScrollButtonPressed;
376     bool m_springLoadedPanScrollInProgress;
377
378     Timer<EventHandler> m_hoverTimer;
379     
380     Timer<EventHandler> m_autoscrollTimer;
381     RenderObject* m_autoscrollRenderer;
382     bool m_autoscrollInProgress;
383     bool m_mouseDownMayStartAutoscroll;
384     bool m_mouseDownWasInSubframe;
385
386     Timer<EventHandler> m_fakeMouseMoveEventTimer;
387
388 #if ENABLE(SVG)
389     bool m_svgPan;
390     RefPtr<SVGElementInstance> m_instanceUnderMouse;
391     RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
392 #endif
393
394     RenderLayer* m_resizeLayer;
395
396     RefPtr<Node> m_capturingMouseEventsNode;
397     bool m_eventHandlerWillResetCapturingMouseEventsNode;
398     
399     RefPtr<Node> m_nodeUnderMouse;
400     RefPtr<Node> m_lastNodeUnderMouse;
401     RefPtr<Frame> m_lastMouseMoveEventSubframe;
402     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
403
404     int m_clickCount;
405     RefPtr<Node> m_clickNode;
406
407 #if ENABLE(DRAG_SUPPORT)
408     RefPtr<Node> m_dragTarget;
409     bool m_shouldOnlyFireDragOverEvent;
410 #endif
411     
412     RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
413
414     IntSize m_offsetFromResizeCorner;   // in the coords of m_resizeLayer
415     
416     IntPoint m_currentMousePosition;
417     IntPoint m_mouseDownPos; // in our view's coords
418     double m_mouseDownTimestamp;
419     PlatformMouseEvent m_mouseDown;
420
421     bool m_useLatchedWheelEventNode;
422     RefPtr<Node> m_latchedWheelEventNode;
423     bool m_widgetIsLatched;
424
425     RefPtr<Node> m_previousWheelScrolledNode;
426
427 #if PLATFORM(MAC)
428     NSView *m_mouseDownView;
429     bool m_sendingEventToSubview;
430     int m_activationEventNumber;
431 #endif
432 #if ENABLE(TOUCH_EVENTS)
433     typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
434     TouchTargetMap m_originatingTouchPointTargets;
435     bool m_touchPressed;
436 #endif
437 #if ENABLE(HAPTICS)
438     RefPtr<Node> m_firstTouchedNode;
439     bool m_hapticFeedbackCancelled;
440 #endif
441 };
442
443 } // namespace WebCore
444
445 #endif // EventHandler_h