90e3f14a7a5830ee7d2e84207af83222f3c3f24c
[WebKit-https.git] / Source / WebCore / page / EventHandler.h
1 /*
2  * Copyright (C) 2006-2014 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 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 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 "WheelEventDeltaTracker.h"
41 #include <wtf/Forward.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/RefPtr.h>
44
45 #if PLATFORM(IOS)
46 #ifdef __OBJC__
47 @class WebEvent;
48 @class WAKView;
49 #include "WAKAppKitStubs.h"
50 #else
51 class WebEvent;
52 #endif
53 #endif // PLATFORM(IOS)
54
55 #if PLATFORM(COCOA) && !defined(__OBJC__)
56 class NSView;
57 #endif
58
59 #if ENABLE(TOUCH_EVENTS)
60 #include <wtf/HashMap.h>
61 #endif
62
63 #if ENABLE(IOS_TOUCH_EVENTS)
64 #include <wtf/HashSet.h>
65 #include <wtf/Vector.h>
66 #endif
67
68 namespace WebCore {
69
70 class AutoscrollController;
71 class ContainerNode;
72 class DataTransfer;
73 class Document;
74 class Element;
75 class Event;
76 class EventTarget;
77 class FloatPoint;
78 class FloatQuad;
79 class Frame;
80 class HTMLFrameSetElement;
81 class HitTestRequest;
82 class HitTestResult;
83 class KeyboardEvent;
84 class MouseEventWithHitTestResults;
85 class Node;
86 class OptionalCursor;
87 class PlatformKeyboardEvent;
88 class PlatformTouchEvent;
89 class PlatformWheelEvent;
90 class RenderBox;
91 class RenderElement;
92 class RenderLayer;
93 class RenderWidget;
94 class ScrollableArea;
95 class SVGElementInstance;
96 class Scrollbar;
97 class TextEvent;
98 class Touch;
99 class TouchEvent;
100 class VisibleSelection;
101 class WheelEvent;
102 class Widget;
103
104 struct DragState;
105
106 #if ENABLE(DRAG_SUPPORT)
107 extern const int LinkDragHysteresis;
108 extern const int ImageDragHysteresis;
109 extern const int TextDragHysteresis;
110 extern const int GeneralDragHysteresis;
111 #endif // ENABLE(DRAG_SUPPORT)
112
113 #if ENABLE(IOS_GESTURE_EVENTS)
114 extern const float GestureUnknown;
115 #endif
116
117 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
118 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
119
120 class EventHandler {
121     WTF_MAKE_NONCOPYABLE(EventHandler);
122 public:
123     explicit EventHandler(Frame&);
124     ~EventHandler();
125
126     void clear();
127     void nodeWillBeRemoved(Node*);
128
129 #if ENABLE(DRAG_SUPPORT)
130     void updateSelectionForMouseDrag();
131 #endif
132
133 #if ENABLE(PAN_SCROLLING)
134     void didPanScrollStart();
135     void didPanScrollStop();
136     void startPanScrolling(RenderElement*);
137 #endif
138
139     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
140     RenderBox* autoscrollRenderer() const;
141     void updateAutoscrollRenderer();
142     bool autoscrollInProgress() const;
143     bool mouseDownWasInSubframe() const { return m_mouseDownWasInSubframe; }
144     bool panScrollInProgress() const;
145
146     void dispatchFakeMouseMoveEventSoon();
147     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
148
149     HitTestResult hitTestResultAtPoint(const LayoutPoint&,
150         HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent,
151         const LayoutSize& padding = LayoutSize());
152
153     bool mousePressed() const { return m_mousePressed; }
154     Node* mousePressNode() const { return m_mousePressNode.get(); }
155
156     void setCapturingMouseEventsElement(PassRefPtr<Element>); // A caller is responsible for resetting capturing element to 0.
157
158 #if ENABLE(DRAG_SUPPORT)
159     bool updateDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
160     void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
161     bool performDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
162     void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
163 #endif
164
165     void scheduleHoverStateUpdate();
166 #if ENABLE(CURSOR_SUPPORT)
167     void scheduleCursorUpdate();
168 #endif
169
170     void setResizingFrameSet(HTMLFrameSetElement*);
171
172     void resizeLayerDestroyed();
173
174     IntPoint lastKnownMousePosition() const;
175     Cursor currentMouseCursor() const { return m_currentMouseCursor; }
176
177     static Frame* subframeForTargetNode(Node*);
178     static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
179
180     bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
181     bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
182     bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
183
184     bool tabsToLinks(KeyboardEvent*) const;
185     bool tabsToAllFormControls(KeyboardEvent*) const;
186
187     bool mouseMoved(const PlatformMouseEvent&);
188     bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
189
190     void lostMouseCapture();
191
192     bool handleMousePressEvent(const PlatformMouseEvent&);
193     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
194     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
195     bool handleWheelEvent(const PlatformWheelEvent&);
196     void defaultWheelEventHandler(Node*, WheelEvent*);
197     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
198
199     void platformPrepareForWheelEvents(const PlatformWheelEvent& wheelEvent, const HitTestResult& result, Element*& wheelEventTarget, ContainerNode*& scrollableContainer, ScrollableArea*& scrollableArea, bool& isOverWidget);
200     void platformRecordWheelEvent(const PlatformWheelEvent&);
201     bool platformCompleteWheelEvent(const PlatformWheelEvent&, ContainerNode* scrollableContainer, ScrollableArea* scrollableArea);
202
203 #if ENABLE(IOS_TOUCH_EVENTS) || ENABLE(IOS_GESTURE_EVENTS)
204     typedef Vector<RefPtr<Touch>> TouchArray;
205     typedef HashMap<EventTarget*, TouchArray*> EventTargetTouchMap;
206     typedef HashSet<RefPtr<EventTarget>> EventTargetSet;
207 #endif
208
209 #if ENABLE(IOS_TOUCH_EVENTS)
210     bool dispatchTouchEvent(const PlatformTouchEvent&, const AtomicString&, const EventTargetTouchMap&, float, float);
211 #endif
212
213 #if ENABLE(IOS_GESTURE_EVENTS)
214     bool dispatchGestureEvent(const PlatformTouchEvent&, const AtomicString&, const EventTargetSet&, float, float);
215 #endif
216
217 #if PLATFORM(IOS)
218     void defaultTouchEventHandler(Node*, TouchEvent*);
219 #endif
220
221 #if ENABLE(CONTEXT_MENUS)
222     bool sendContextMenuEvent(const PlatformMouseEvent&);
223     bool sendContextMenuEventForKey();
224 #endif
225
226     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
227
228     bool needsKeyboardEventDisambiguationQuirks() const;
229
230     static unsigned accessKeyModifiers();
231     bool handleAccessKey(const PlatformKeyboardEvent&);
232     bool keyEvent(const PlatformKeyboardEvent&);
233     void defaultKeyboardEventHandler(KeyboardEvent*);
234
235     void handleKeyboardSelectionMovementForAccessibility(KeyboardEvent*);
236
237     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
238     void defaultTextInputEventHandler(TextEvent*);
239
240 #if ENABLE(DRAG_SUPPORT)
241     bool eventMayStartDrag(const PlatformMouseEvent&) const;
242     
243     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
244 #endif
245
246     void focusDocumentView();
247
248     void capsLockStateMayHaveChanged(); // Only called by FrameSelection
249     
250     void sendScrollEvent(); // Ditto
251
252 #if PLATFORM(COCOA) && defined(__OBJC__)
253 #if !PLATFORM(IOS)
254     void mouseDown(NSEvent *);
255     void mouseDragged(NSEvent *);
256     void mouseUp(NSEvent *);
257     void mouseMoved(NSEvent *);
258     bool keyEvent(NSEvent *);
259     bool wheelEvent(NSEvent *);
260 #else
261     void mouseDown(WebEvent *);
262     void mouseUp(WebEvent *);
263     void mouseMoved(WebEvent *);
264     bool keyEvent(WebEvent *);
265     bool wheelEvent(WebEvent *);
266 #endif
267
268 #if ENABLE(IOS_TOUCH_EVENTS)
269     void touchEvent(WebEvent *);
270 #endif
271
272 #if !PLATFORM(IOS)
273     void passMouseMovedEventToScrollbars(NSEvent *);
274
275     void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
276 #endif
277
278 #if !PLATFORM(IOS)
279     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
280
281     static NSEvent *currentNSEvent();
282 #else
283     static WebEvent *currentEvent();
284 #endif // !PLATFORM(IOS)
285 #endif // PLATFORM(COCOA) && defined(__OBJC__)
286
287 #if PLATFORM(IOS)
288     void invalidateClick();
289 #endif
290
291 #if ENABLE(TOUCH_EVENTS)
292     bool handleTouchEvent(const PlatformTouchEvent&);
293 #endif
294
295     bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
296     void updateCursor();
297
298     bool isHandlingWheelEvent() const { return m_isHandlingWheelEvent; }
299
300 private:
301 #if ENABLE(DRAG_SUPPORT)
302     static DragState& dragState();
303     static const double TextDragDelay;
304     
305     PassRefPtr<DataTransfer> createDraggingDataTransfer() const;
306 #endif // ENABLE(DRAG_SUPPORT)
307
308     bool eventActivatedView(const PlatformMouseEvent&) const;
309     bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
310     void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
311     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
312     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
313
314     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
315
316     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
317     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
318     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
319     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
320 #if ENABLE(DRAG_SUPPORT)
321     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
322 #endif
323     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
324
325     OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
326
327     void hoverTimerFired(Timer<EventHandler>&);
328 #if ENABLE(CURSOR_SUPPORT)
329     void cursorUpdateTimerFired(Timer<EventHandler>&);
330 #endif
331
332     bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
333     
334     bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
335     
336     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
337
338     static bool isKeyboardOptionTab(KeyboardEvent*);
339     static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
340
341 #if !ENABLE(IOS_TOUCH_EVENTS)
342     void fakeMouseMoveEventTimerFired(Timer<EventHandler>&);
343     void cancelFakeMouseMoveEvent();
344 #endif
345
346     bool isInsideScrollbar(const IntPoint&) const;
347
348 #if ENABLE(TOUCH_EVENTS)
349     bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
350 #endif
351
352 #if !PLATFORM(IOS)
353     void invalidateClick();
354 #endif
355
356     Node* nodeUnderMouse() const;
357     
358     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
359     void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
360     
361     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
362
363     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
364 #if ENABLE(DRAG_SUPPORT)
365     bool dispatchDragEvent(const AtomicString& eventType, Element& target, const PlatformMouseEvent&, DataTransfer*);
366
367     void freeDataTransfer();
368
369     bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
370 #endif
371     bool handleMouseUp(const MouseEventWithHitTestResults&);
372 #if ENABLE(DRAG_SUPPORT)
373     void clearDragState();
374
375     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
376
377     bool dragHysteresisExceeded(const FloatPoint&) const;
378     bool dragHysteresisExceeded(const IntPoint&) const;
379 #endif // ENABLE(DRAG_SUPPORT)
380
381     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
382     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
383     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
384
385     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
386
387     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
388
389     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
390     bool passWidgetMouseDownEventToWidget(RenderWidget*);
391
392     bool passMouseDownEventToWidget(Widget*);
393     bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
394
395     void defaultSpaceEventHandler(KeyboardEvent*);
396     void defaultBackspaceEventHandler(KeyboardEvent*);
397     void defaultTabEventHandler(KeyboardEvent*);
398     void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
399
400 #if ENABLE(DRAG_SUPPORT)
401     DragSourceAction updateDragSourceActionsAllowed() const;
402 #endif
403
404     // The following are called at the beginning of handleMouseUp and handleDrag.  
405     // If they return true it indicates that they have consumed the event.
406     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
407 #if ENABLE(DRAG_SUPPORT)
408     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
409 #endif
410
411 #if ENABLE(DRAG_SUPPORT)
412     void updateSelectionForMouseDrag(const HitTestResult&);
413 #endif
414
415     void updateLastScrollbarUnderMouse(Scrollbar*, bool);
416     
417     void setFrameWasScrolledByUser();
418
419     bool capturesDragging() const { return m_capturesDragging; }
420
421 #if PLATFORM(COCOA) && defined(__OBJC__)
422     NSView *mouseDownViewIfStillGood();
423
424     PlatformMouseEvent currentPlatformMouseEvent() const;
425 #endif
426
427 #if ENABLE(FULLSCREEN_API)
428     bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
429 #endif
430
431     void setLastKnownMousePosition(const PlatformMouseEvent&);
432
433 #if ENABLE(CURSOR_VISIBILITY)
434     void startAutoHideCursorTimer();
435     void cancelAutoHideCursorTimer();
436     void autoHideCursorTimerFired(Timer<EventHandler>&);
437 #endif
438
439     void clearLatchedState();
440
441     Frame& m_frame;
442
443     bool m_mousePressed;
444     bool m_capturesDragging;
445     RefPtr<Node> m_mousePressNode;
446
447     bool m_mouseDownMayStartSelect;
448 #if ENABLE(DRAG_SUPPORT)
449     bool m_mouseDownMayStartDrag;
450     bool m_dragMayStartSelectionInstead;
451 #endif
452     bool m_mouseDownWasSingleClickInSelection;
453     enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
454     SelectionInitiationState m_selectionInitiationState;
455
456 #if ENABLE(DRAG_SUPPORT)
457     LayoutPoint m_dragStartPos;
458 #endif
459
460     bool m_panScrollButtonPressed;
461
462     Timer<EventHandler> m_hoverTimer;
463 #if ENABLE(CURSOR_SUPPORT)
464     Timer<EventHandler> m_cursorUpdateTimer;
465 #endif
466
467     OwnPtr<AutoscrollController> m_autoscrollController;
468     bool m_mouseDownMayStartAutoscroll;
469     bool m_mouseDownWasInSubframe;
470
471 #if !ENABLE(IOS_TOUCH_EVENTS)
472     Timer<EventHandler> m_fakeMouseMoveEventTimer;
473 #endif
474
475     bool m_svgPan;
476     RefPtr<SVGElementInstance> m_instanceUnderMouse;
477     RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
478
479     RenderLayer* m_resizeLayer;
480
481     RefPtr<Element> m_capturingMouseEventsElement;
482     bool m_eventHandlerWillResetCapturingMouseEventsElement;
483     
484     RefPtr<Element> m_elementUnderMouse;
485     RefPtr<Element> m_lastElementUnderMouse;
486     RefPtr<Frame> m_lastMouseMoveEventSubframe;
487     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
488     Cursor m_currentMouseCursor;
489
490     int m_clickCount;
491     RefPtr<Node> m_clickNode;
492
493 #if ENABLE(IOS_GESTURE_EVENTS)
494     float m_gestureInitialDiameter;
495     float m_gestureLastDiameter;
496     float m_gestureInitialRotation;
497     float m_gestureLastRotation;
498 #endif
499
500 #if ENABLE(IOS_TOUCH_EVENTS)
501     unsigned m_firstTouchID;
502
503     TouchArray m_touches;
504     EventTargetSet m_gestureTargets;
505     RefPtr<Frame> m_touchEventTargetSubframe;
506 #endif
507
508 #if ENABLE(DRAG_SUPPORT)
509     RefPtr<Element> m_dragTarget;
510     bool m_shouldOnlyFireDragOverEvent;
511 #endif
512     
513     RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
514
515     LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
516     
517     bool m_mousePositionIsUnknown;
518     IntPoint m_lastKnownMousePosition;
519     IntPoint m_lastKnownMouseGlobalPosition;
520     IntPoint m_mouseDownPos; // In our view's coords.
521     double m_mouseDownTimestamp;
522     PlatformMouseEvent m_mouseDown;
523
524     OwnPtr<WheelEventDeltaTracker> m_recentWheelEventDeltaTracker;
525     RefPtr<Element> m_latchedWheelEventElement;
526     bool m_widgetIsLatched;
527
528     RefPtr<Element> m_previousWheelScrolledElement;
529
530 #if PLATFORM(COCOA)
531     NSView *m_mouseDownView;
532     RefPtr<ContainerNode> m_latchedScrollableContainer;
533     bool m_sendingEventToSubview;
534     bool m_startedGestureAtScrollLimit;
535 #if !PLATFORM(IOS)
536     int m_activationEventNumber;
537 #endif
538 #endif
539 #if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
540     typedef HashMap<int, RefPtr<EventTarget>> TouchTargetMap;
541     TouchTargetMap m_originatingTouchPointTargets;
542     RefPtr<Document> m_originatingTouchPointDocument;
543     unsigned m_originatingTouchPointTargetKey;
544     bool m_touchPressed;
545 #endif
546
547     double m_maxMouseMovedDuration;
548     PlatformEvent::Type m_baseEventType;
549     bool m_didStartDrag;
550     bool m_didLongPressInvokeContextMenu;
551     bool m_isHandlingWheelEvent;
552
553 #if ENABLE(CURSOR_VISIBILITY)
554     Timer<EventHandler> m_autoHideCursorTimer;
555 #endif
556 };
557
558 } // namespace WebCore
559
560 #endif // EventHandler_h