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