blob: bc2206b3dd8959989abe57fd6d8826fb5f15d5c4 [file] [log] [blame]
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +01001/*
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
Ben Murdoch02772c62013-07-26 10:21:05 +010023 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010024 */
25
26#ifndef EventHandler_h
27#define EventHandler_h
28
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010029#include "core/editing/TextGranularity.h"
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010030#include "core/events/TextEventInputType.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010031#include "core/page/DragActions.h"
32#include "core/page/FocusDirection.h"
33#include "core/platform/Cursor.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010034#include "core/rendering/HitTestRequest.h"
Torne (Richard Coles)1e202182013-10-18 15:46:42 +010035#include "platform/PlatformMouseEvent.h"
36#include "platform/Timer.h"
37#include "platform/UserGestureIndicator.h"
38#include "platform/geometry/LayoutPoint.h"
39#include "platform/scroll/ScrollTypes.h"
Ben Murdoch591b9582013-07-10 11:41:44 +010040#include "wtf/Forward.h"
41#include "wtf/HashMap.h"
42#include "wtf/RefPtr.h"
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010043
44namespace WebCore {
45
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010046class Clipboard;
47class Document;
48class Element;
49class Event;
50class EventTarget;
51class FloatPoint;
52class FloatQuad;
Torne (Richard Coles)f5e4ad52013-08-05 13:57:57 +010053class FullscreenElementStack;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010054class Frame;
55class HTMLFrameSetElement;
56class HitTestRequest;
57class HitTestResult;
58class KeyboardEvent;
59class MouseEventWithHitTestResults;
60class Node;
61class OptionalCursor;
62class PlatformGestureEvent;
63class PlatformKeyboardEvent;
64class PlatformTouchEvent;
65class PlatformWheelEvent;
66class RenderLayer;
67class RenderObject;
68class RenderWidget;
69class SVGElementInstance;
Torne (Richard Coles)e1f1df52013-08-23 16:39:30 +010070class ScrollableArea;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010071class Scrollbar;
72class TextEvent;
73class TouchEvent;
74class VisibleSelection;
75class WheelEvent;
76class Widget;
77
78struct DragState;
79
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010080enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
81enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
82
83class EventHandler {
84 WTF_MAKE_NONCOPYABLE(EventHandler);
85public:
86 explicit EventHandler(Frame*);
87 ~EventHandler();
88
89 void clear();
90 void nodeWillBeRemoved(Node*);
91
92 void updateSelectionForMouseDrag();
93
94 Node* mousePressNode() const;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010095
Torne (Richard Coles)8abfc582013-09-12 12:10:38 +010096#if OS(WIN)
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +010097 void startPanScrolling(RenderObject*);
98#endif
99
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100100 void stopAutoscrollTimer();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100101
102 void dispatchFakeMouseMoveEventSoon();
103 void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
104
105 HitTestResult hitTestResultAtPoint(const LayoutPoint&,
Ben Murdoch591b9582013-07-10 11:41:44 +0100106 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100107 const LayoutSize& padding = LayoutSize());
108
109 bool mousePressed() const { return m_mousePressed; }
110 void setMousePressed(bool pressed) { m_mousePressed = pressed; }
111
112 void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
113
114 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
115 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
116 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
117 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
118
119 void scheduleHoverStateUpdate();
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100120 void scheduleCursorUpdate();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100121
122 void setResizingFrameSet(HTMLFrameSetElement*);
123
124 void resizeLayerDestroyed();
125
126 IntPoint lastKnownMousePosition() const;
127 Cursor currentMouseCursor() const { return m_currentMouseCursor; }
128
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100129 bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
130 bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
131 bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
132
Torne (Richard Coles)c0e19a62013-08-30 15:15:11 +0100133 bool handleMouseMoveEvent(const PlatformMouseEvent&);
134 void handleMouseLeaveEvent(const PlatformMouseEvent&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100135
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100136 bool handleMousePressEvent(const PlatformMouseEvent&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100137 bool handleMouseReleaseEvent(const PlatformMouseEvent&);
138 bool handleWheelEvent(const PlatformWheelEvent&);
139 void defaultWheelEventHandler(Node*, WheelEvent*);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100140
141 bool handleGestureEvent(const PlatformGestureEvent&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100142 bool handleGestureScrollEnd(const PlatformGestureEvent&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100143 bool isScrollbarHandlingGestures() const;
144
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100145 bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
146 bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
147 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
148
149 bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
150
151 bool sendContextMenuEvent(const PlatformMouseEvent&);
152 bool sendContextMenuEventForKey();
153 bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
154
155 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
156
157 static unsigned accessKeyModifiers();
158 bool handleAccessKey(const PlatformKeyboardEvent&);
159 bool keyEvent(const PlatformKeyboardEvent&);
160 void defaultKeyboardEventHandler(KeyboardEvent*);
161
162 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
163 void defaultTextInputEventHandler(TextEvent*);
164
165 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
166
167 void focusDocumentView();
168
169 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
170
171 void sendResizeEvent(); // Only called in FrameView
172 void sendScrollEvent(); // Ditto
173
174 bool handleTouchEvent(const PlatformTouchEvent&);
175
176 bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
177
178private:
179 static DragState& dragState();
Ben Murdoch02772c62013-07-26 10:21:05 +0100180
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100181 PassRefPtr<Clipboard> createDraggingClipboard() const;
182
183 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
184 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100185 void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100186 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100187 void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100188 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
189
Torne (Richard Coles)c0e19a62013-08-30 15:15:11 +0100190 bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100191 bool handleMousePressEvent(const MouseEventWithHitTestResults&);
192 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
193 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
194 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
195 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
196 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
197
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100198 bool handlePasteGlobalSelection(const PlatformMouseEvent&);
199
200 bool handleGestureTap(const PlatformGestureEvent&);
201 bool handleGestureLongPress(const PlatformGestureEvent&);
202 bool handleGestureLongTap(const PlatformGestureEvent&);
203 bool handleGestureTwoFingerTap(const PlatformGestureEvent&);
204 bool handleGestureScrollUpdate(const PlatformGestureEvent&);
205 bool handleGestureScrollBegin(const PlatformGestureEvent&);
206 void clearGestureScrollNodes();
207
208 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
209
210 OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
Torne (Richard Coles)bfe35902013-10-22 16:41:51 +0100211 OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam, bool shiftKey);
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100212
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100213 void hoverTimerFired(Timer<EventHandler>*);
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100214 void cursorUpdateTimerFired(Timer<EventHandler>*);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100215
216 bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
Ben Murdoch02772c62013-07-26 10:21:05 +0100217
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100218 bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
219 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
220
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100221 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
222 void cancelFakeMouseMoveEvent();
223 bool isCursorVisible() const;
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100224 void updateCursor();
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100225
226 bool isInsideScrollbar(const IntPoint&) const;
227
Torne (Richard Coles)e1f1df52013-08-23 16:39:30 +0100228 ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
229
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100230 bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
231 HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
232
233 void invalidateClick();
234
235 Node* nodeUnderMouse() const;
Ben Murdoch02772c62013-07-26 10:21:05 +0100236
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100237 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
Ben Murdoch02772c62013-07-26 10:21:05 +0100238
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100239 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
240
241 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
242 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
243
244 void freeClipboard();
245
246 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
Ben Murdoche69819b2013-07-17 14:56:49 +0100247 bool tryStartDrag(const MouseEventWithHitTestResults&);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100248 void clearDragState();
249
250 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
251
252 bool dragHysteresisExceeded(const FloatPoint&) const;
253 bool dragHysteresisExceeded(const IntPoint&) const;
254
255 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
256 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
257 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
258
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100259 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
260
261 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
262
263 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
264
265 void defaultSpaceEventHandler(KeyboardEvent*);
266 void defaultBackspaceEventHandler(KeyboardEvent*);
267 void defaultTabEventHandler(KeyboardEvent*);
Torne (Richard Coles)c0e19a62013-08-30 15:15:11 +0100268 void defaultEscapeEventHandler(KeyboardEvent*);
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100269 void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
270
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100271 void updateSelectionForMouseDrag(const HitTestResult&);
272
273 void updateLastScrollbarUnderMouse(Scrollbar*, bool);
Ben Murdoch02772c62013-07-26 10:21:05 +0100274
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100275 void setFrameWasScrolledByUser();
276
277 bool capturesDragging() const { return m_capturesDragging; }
278
Torne (Richard Coles)f5e4ad52013-08-05 13:57:57 +0100279 bool isKeyEventAllowedInFullScreen(FullscreenElementStack*, const PlatformKeyboardEvent&) const;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100280
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100281 bool handleGestureShowPress();
Torne (Richard Coles)81a51572013-05-13 16:52:28 +0100282
283 bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&);
284
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100285 bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
286 bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
287 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
288 Frame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
289
Torne (Richard Coles)5267f702013-06-11 10:57:24 +0100290 bool panScrollInProgress() const;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100291 void setLastKnownMousePosition(const PlatformMouseEvent&);
292
Ben Murdoche69819b2013-07-17 14:56:49 +0100293 Frame* const m_frame;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100294
295 bool m_mousePressed;
296 bool m_capturesDragging;
297 RefPtr<Node> m_mousePressNode;
298
299 bool m_mouseDownMayStartSelect;
300 bool m_mouseDownMayStartDrag;
301 bool m_dragMayStartSelectionInstead;
302 bool m_mouseDownWasSingleClickInSelection;
303 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
304 SelectionInitiationState m_selectionInitiationState;
305
306 LayoutPoint m_dragStartPos;
307
308 bool m_panScrollButtonPressed;
309
310 Timer<EventHandler> m_hoverTimer;
Torne (Richard Coles)1e202182013-10-18 15:46:42 +0100311 Timer<EventHandler> m_cursorUpdateTimer;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100312
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100313 bool m_mouseDownMayStartAutoscroll;
314 bool m_mouseDownWasInSubframe;
315
316 Timer<EventHandler> m_fakeMouseMoveEventTimer;
317
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100318 bool m_svgPan;
319 RefPtr<SVGElementInstance> m_instanceUnderMouse;
320 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100321
322 RenderLayer* m_resizeLayer;
323
324 RefPtr<Node> m_capturingMouseEventsNode;
325 bool m_eventHandlerWillResetCapturingMouseEventsNode;
Ben Murdoch02772c62013-07-26 10:21:05 +0100326
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100327 RefPtr<Node> m_nodeUnderMouse;
328 RefPtr<Node> m_lastNodeUnderMouse;
329 RefPtr<Frame> m_lastMouseMoveEventSubframe;
330 RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
331 Cursor m_currentMouseCursor;
332
333 int m_clickCount;
334 RefPtr<Node> m_clickNode;
335
336 RefPtr<Node> m_dragTarget;
337 bool m_shouldOnlyFireDragOverEvent;
Ben Murdoch02772c62013-07-26 10:21:05 +0100338
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100339 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
340
341 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
Ben Murdoch02772c62013-07-26 10:21:05 +0100342
Torne (Richard Coles)53e740f2013-05-09 18:38:43 +0100343 bool m_mousePositionIsUnknown;
344 IntPoint m_lastKnownMousePosition;
345 IntPoint m_lastKnownMouseGlobalPosition;
346 IntPoint m_mouseDownPos; // In our view's coords.
347 double m_mouseDownTimestamp;
348 PlatformMouseEvent m_mouseDown;
349 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
350
351 RefPtr<Node> m_latchedWheelEventNode;
352 bool m_widgetIsLatched;
353
354 RefPtr<Node> m_previousWheelScrolledNode;
355
356 typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
357 TouchTargetMap m_originatingTouchPointTargets;
358 RefPtr<Document> m_originatingTouchPointDocument;
359 unsigned m_originatingTouchPointTargetKey;
360 bool m_touchPressed;
361
362 RefPtr<Node> m_scrollGestureHandlingNode;
363 bool m_lastHitTestResultOverWidget;
364 RefPtr<Node> m_previousGestureScrolledNode;
365 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
366
367 double m_maxMouseMovedDuration;
368 PlatformEvent::Type m_baseEventType;
369 bool m_didStartDrag;
370
371 bool m_longTapShouldInvokeContextMenu;
372};
373
374} // namespace WebCore
375
376#endif // EventHandler_h