2 * Copyright (C) 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef EventHandler_h
27 #define EventHandler_h
29 #include "core/CoreExport.h"
30 #include "core/events/PointerIdManager.h"
31 #include "core/events/TextEventInputType.h"
32 #include "core/layout/HitTestRequest.h"
33 #include "core/page/DragActions.h"
34 #include "core/page/EventWithHitTestResults.h"
35 #include "core/style/ComputedStyleConstants.h"
36 #include "platform/Cursor.h"
37 #include "platform/PlatformMouseEvent.h"
38 #include "platform/PlatformTouchPoint.h"
39 #include "platform/Timer.h"
40 #include "platform/UserGestureIndicator.h"
41 #include "platform/geometry/LayoutPoint.h"
42 #include "platform/heap/Handle.h"
43 #include "platform/scroll/ScrollTypes.h"
44 #include "public/platform/WebFocusType.h"
45 #include "wtf/Forward.h"
46 #include "wtf/HashMap.h"
47 #include "wtf/HashTraits.h"
48 #include "wtf/RefPtr.h"
52 class AutoscrollController
;
54 class DeprecatedPaintLayer
;
55 class DeprecatedPaintLayerScrollableArea
;
61 template <typename EventType
>
62 class EventWithHitTestResults
;
65 class HTMLFrameSetElement
;
73 class PlatformGestureEvent
;
74 class PlatformKeyboardEvent
;
75 class PlatformTouchEvent
;
76 class PlatformWheelEvent
;
80 class SelectionController
;
85 enum class DragInitiator
;
87 class CORE_EXPORT EventHandler final
: public NoBaseWillBeGarbageCollectedFinalized
<EventHandler
> {
88 WTF_MAKE_NONCOPYABLE(EventHandler
);
89 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED(EventHandler
);
91 explicit EventHandler(LocalFrame
*);
96 void nodeWillBeRemoved(Node
&);
98 void updateSelectionForMouseDrag();
101 void startPanScrolling(LayoutObject
*);
104 void stopAutoscroll();
106 void dispatchFakeMouseMoveEventSoon();
107 void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad
&);
109 HitTestResult
hitTestResultAtPoint(const LayoutPoint
&,
110 HitTestRequest::HitTestRequestType hitType
= HitTestRequest::ReadOnly
| HitTestRequest::Active
,
111 const LayoutSize
& padding
= LayoutSize());
113 bool mousePressed() const { return m_mousePressed
; }
115 void setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr
<Node
>); // A caller is responsible for resetting capturing node to 0.
117 bool updateDragAndDrop(const PlatformMouseEvent
&, DataTransfer
*);
118 void cancelDragAndDrop(const PlatformMouseEvent
&, DataTransfer
*);
119 bool performDragAndDrop(const PlatformMouseEvent
&, DataTransfer
*);
120 void updateDragStateAfterEditDragIfNeeded(Element
* rootEditableElement
);
122 void scheduleHoverStateUpdate();
123 void scheduleCursorUpdate();
125 // Return whether a mouse cursor update is currently pending. Used for testing.
126 bool cursorUpdatePending();
128 void setResizingFrameSet(HTMLFrameSetElement
*);
130 void resizeScrollableAreaDestroyed();
132 IntPoint
lastKnownMousePosition() const;
134 // Attempts to scroll the DOM tree. If that fails, scrolls the view.
135 // If the view can't be scrolled either, recursively bubble to the parent frame.
136 bool bubblingScroll(ScrollDirection
, ScrollGranularity
, Node
* startingNode
= nullptr);
138 bool handleMouseMoveEvent(const PlatformMouseEvent
&);
139 void handleMouseLeaveEvent(const PlatformMouseEvent
&);
141 bool handleMousePressEvent(const PlatformMouseEvent
&);
142 bool handleMouseReleaseEvent(const PlatformMouseEvent
&);
143 bool handleWheelEvent(const PlatformWheelEvent
&);
144 void defaultWheelEventHandler(Node
*, WheelEvent
*);
146 // Called on the local root frame exactly once per gesture event.
147 bool handleGestureEvent(const PlatformGestureEvent
&);
148 bool handleGestureEvent(const GestureEventWithHitTestResults
&);
150 // Clear the old hover/active state within frames before moving the hover state to the another frame
151 void updateGestureHoverActiveState(const HitTestRequest
&, Element
*);
153 // Hit-test the provided (non-scroll) gesture event, applying touch-adjustment and updating
154 // hover/active state across all frames if necessary. This should be called at most once
155 // per gesture event, and called on the local root frame.
156 // Note: This is similar to (the less clearly named) prepareMouseEvent.
157 // FIXME: Remove readOnly param when there is only ever a single call to this.
158 GestureEventWithHitTestResults
targetGestureEvent(const PlatformGestureEvent
&, bool readOnly
= false);
159 GestureEventWithHitTestResults
hitTestResultForGestureEvent(const PlatformGestureEvent
&, HitTestRequest::HitTestRequestType
);
160 // Handle the provided non-scroll gesture event. Should be called only on the inner frame.
161 bool handleGestureEventInFrame(const GestureEventWithHitTestResults
&);
163 // Handle the provided scroll gesture event, propagating down to child frames as necessary.
164 bool handleGestureScrollEvent(const PlatformGestureEvent
&);
165 bool handleGestureScrollEnd(const PlatformGestureEvent
&);
166 bool isScrollbarHandlingGestures() const;
168 bool bestClickableNodeForHitTestResult(const HitTestResult
&, IntPoint
& targetPoint
, Node
*& targetNode
);
169 bool bestContextMenuNodeForHitTestResult(const HitTestResult
&, IntPoint
& targetPoint
, Node
*& targetNode
);
170 // FIXME: This doesn't appear to be used outside tests anymore, what path are we using now and is it tested?
171 bool bestZoomableAreaForTouchPoint(const IntPoint
& touchCenter
, const IntSize
& touchRadius
, IntRect
& targetArea
, Node
*& targetNode
);
173 bool sendContextMenuEvent(const PlatformMouseEvent
&, Node
* overrideTargetNode
= nullptr);
174 bool sendContextMenuEventForKey(Element
* overrideTargetElement
= nullptr);
175 bool sendContextMenuEventForGesture(const GestureEventWithHitTestResults
&);
177 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll
= true; }
179 static unsigned accessKeyModifiers();
180 bool handleAccessKey(const PlatformKeyboardEvent
&);
181 bool keyEvent(const PlatformKeyboardEvent
&);
182 void defaultKeyboardEventHandler(KeyboardEvent
*);
184 bool handleTextInputEvent(const String
& text
, Event
* underlyingEvent
= nullptr, TextEventInputType
= TextEventInputKeyboard
);
185 void defaultTextInputEventHandler(TextEvent
*);
187 void dragSourceEndedAt(const PlatformMouseEvent
&, DragOperation
);
189 void focusDocumentView();
191 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
193 bool handleTouchEvent(const PlatformTouchEvent
&);
195 bool useHandCursor(Node
*, bool isOverLink
);
197 void notifyElementActivated();
199 PassRefPtr
<UserGestureToken
> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken
.release(); }
201 int clickCount() { return m_clickCount
; }
203 SelectionController
& selectionController() const { return *m_selectionController
; }
206 ALLOW_ONLY_INLINE_ALLOCATION();
208 DEFINE_INLINE_TRACE()
210 visitor
->trace(touchTarget
);
211 visitor
->trace(targetFrame
);
214 PlatformTouchPoint point
;
215 RefPtrWillBeMember
<EventTarget
> touchTarget
;
216 RefPtrWillBeMember
<LocalFrame
> targetFrame
;
217 FloatPoint adjustedPagePoint
;
218 FloatSize adjustedRadius
;
224 static DragState
& dragState();
226 DataTransfer
* createDraggingDataTransfer() const;
228 bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent
&, HitTestResult
* hoveredNode
= nullptr, bool onlyUpdateScrollbars
= false, bool forceLeave
= false);
229 bool handleMousePressEvent(const MouseEventWithHitTestResults
&);
230 bool handleMouseFocus(const MouseEventWithHitTestResults
&, InputDeviceCapabilities
* sourceCapabilities
);
231 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults
&);
232 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults
&);
234 HitTestRequest::HitTestRequestType
getHitTypeForGestureType(PlatformEvent::Type
);
235 void applyTouchAdjustment(PlatformGestureEvent
*, HitTestResult
*);
236 bool handleGestureTap(const GestureEventWithHitTestResults
&);
237 bool handleGestureLongPress(const GestureEventWithHitTestResults
&);
238 bool handleGestureLongTap(const GestureEventWithHitTestResults
&);
239 bool handleGestureScrollUpdate(const PlatformGestureEvent
&);
240 bool handleGestureScrollBegin(const PlatformGestureEvent
&);
241 void clearGestureScrollState();
243 void updateGestureTargetNodeForMouseEvent(const GestureEventWithHitTestResults
&);
245 bool shouldApplyTouchAdjustment(const PlatformGestureEvent
&) const;
247 OptionalCursor
selectCursor(const HitTestResult
&);
248 OptionalCursor
selectAutoCursor(const HitTestResult
&, Node
*, const Cursor
& iBeam
);
250 void hoverTimerFired(Timer
<EventHandler
>*);
251 void cursorUpdateTimerFired(Timer
<EventHandler
>*);
252 void activeIntervalTimerFired(Timer
<EventHandler
>*);
254 void fakeMouseMoveEventTimerFired(Timer
<EventHandler
>*);
255 void cancelFakeMouseMoveEvent();
256 bool isCursorVisible() const;
259 ScrollableArea
* associatedScrollableArea(const DeprecatedPaintLayer
*) const;
261 // Scrolls the elements of the DOM tree. Returns true if a node was scrolled.
262 // False if we reached the root and couldn't scroll anything.
263 // direction - The direction to scroll in. If this is a logical direction, it will be
264 // converted to the physical direction based on a node's writing mode.
265 // granularity - The units that the scroll delta parameter is in.
266 // startNode - The node to start bubbling the scroll from. If a node can't scroll,
267 // the scroll bubbles up to the containing block.
268 // stopNode - On input, if provided and non-null, the node at which we should stop bubbling on input.
269 // On output, if provided and a node was scrolled stopNode will point to that node.
270 // delta - The delta to scroll by, in the units of the granularity parameter. (e.g. pixels, lines, pages, etc.)
271 // absolutePoint - For wheel scrolls - the location, in absolute coordinates, where the event occured.
272 ScrollResultOneDimensional
scroll(ScrollDirection
, ScrollGranularity
, Node
* startNode
= nullptr, Node
** stopNode
= nullptr, float delta
= 1.0f
, IntPoint absolutePoint
= IntPoint());
274 void resetOverscroll(bool didScrollX
, bool didScrollY
);
275 void handleOverscroll(const ScrollResult
&, const FloatPoint
& position
= FloatPoint(), const FloatSize
& velocity
= FloatSize());
277 void customizedScroll(const Node
& startNode
, ScrollState
&);
279 HitTestResult
hitTestResultInFrame(LocalFrame
*, const LayoutPoint
&, HitTestRequest::HitTestRequestType hitType
= HitTestRequest::ReadOnly
| HitTestRequest::Active
);
281 void invalidateClick();
283 void updateMouseEventTargetNode(Node
*, const PlatformMouseEvent
&);
285 /* Dispatches mouseover, mouseout, mouseenter and mouseleave events to appropriate nodes when the mouse pointer moves from one node to another. */
286 void sendMouseEventsForNodeTransition(Node
*, Node
*, const PlatformMouseEvent
&);
288 MouseEventWithHitTestResults
prepareMouseEvent(const HitTestRequest
&, const PlatformMouseEvent
&);
290 bool dispatchMouseEvent(const AtomicString
& eventType
, Node
* target
, int clickCount
, const PlatformMouseEvent
&);
291 bool dispatchDragEvent(const AtomicString
& eventType
, Node
* target
, const PlatformMouseEvent
&, DataTransfer
*);
293 void clearDragDataTransfer();
295 bool handleDrag(const MouseEventWithHitTestResults
&, DragInitiator
);
296 bool tryStartDrag(const MouseEventWithHitTestResults
&);
297 void clearDragState();
299 bool dispatchDragSrcEvent(const AtomicString
& eventType
, const PlatformMouseEvent
&);
301 bool dragHysteresisExceeded(const IntPoint
&) const;
303 bool passMousePressEventToSubframe(MouseEventWithHitTestResults
&, LocalFrame
* subframe
);
304 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults
&, LocalFrame
* subframe
, HitTestResult
* hoveredNode
= nullptr);
305 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults
&, LocalFrame
* subframe
);
307 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults
&);
309 bool passWheelEventToWidget(const PlatformWheelEvent
&, Widget
&);
310 void defaultSpaceEventHandler(KeyboardEvent
*);
311 void defaultBackspaceEventHandler(KeyboardEvent
*);
312 void defaultTabEventHandler(KeyboardEvent
*);
313 void defaultEscapeEventHandler(KeyboardEvent
*);
314 void defaultArrowEventHandler(WebFocusType
, KeyboardEvent
*);
316 void updateLastScrollbarUnderMouse(Scrollbar
*, bool);
318 void setFrameWasScrolledByUser();
320 bool capturesDragging() const { return m_capturesDragging
; }
322 bool handleGestureShowPress();
324 bool handleScrollGestureOnResizer(Node
*, const PlatformGestureEvent
&);
326 bool passScrollGestureEventToWidget(const PlatformGestureEvent
&, LayoutObject
*);
328 AutoscrollController
* autoscrollController() const;
329 bool panScrollInProgress() const;
330 void setLastKnownMousePosition(const PlatformMouseEvent
&);
332 bool shouldTopControlsConsumeScroll(FloatSize
) const;
334 // If the given element is a shadow host and its root has delegatesFocus=false flag,
335 // slide focus to its inner element. Returns true if the resulting focus is different from
336 // the given element.
337 bool slideFocusOnShadowHostIfNecessary(const Element
&);
339 void dispatchPointerEventsForTouchEvent(const PlatformTouchEvent
&, WillBeHeapVector
<TouchInfo
>&);
340 void sendPointerCancels(WillBeHeapVector
<TouchInfo
>&);
342 bool dispatchTouchEvents(const PlatformTouchEvent
&, WillBeHeapVector
<TouchInfo
>&, bool, bool);
344 // NOTE: If adding a new field to this class please ensure that it is
345 // cleared in |EventHandler::clear()|.
347 const RawPtrWillBeMember
<LocalFrame
> m_frame
;
350 bool m_capturesDragging
;
351 RefPtrWillBeMember
<Node
> m_mousePressNode
;
353 bool m_mouseDownMayStartDrag
;
354 const OwnPtrWillBeMember
<SelectionController
> m_selectionController
;
356 LayoutPoint m_dragStartPos
;
358 Timer
<EventHandler
> m_hoverTimer
;
360 // TODO(rbyers): Mouse cursor update is page-wide, not per-frame. Page-wide state
361 // should move out of EventHandler to a new PageEventHandler class. crbug.com/449649
362 Timer
<EventHandler
> m_cursorUpdateTimer
;
364 bool m_mouseDownMayStartAutoscroll
;
366 Timer
<EventHandler
> m_fakeMouseMoveEventTimer
;
370 RawPtrWillBeMember
<DeprecatedPaintLayerScrollableArea
> m_resizeScrollableArea
;
372 RefPtrWillBeMember
<Node
> m_capturingMouseEventsNode
;
373 bool m_eventHandlerWillResetCapturingMouseEventsNode
;
375 RefPtrWillBeMember
<Node
> m_nodeUnderMouse
;
376 RefPtrWillBeMember
<LocalFrame
> m_lastMouseMoveEventSubframe
;
377 RefPtrWillBeMember
<Scrollbar
> m_lastScrollbarUnderMouse
;
380 RefPtrWillBeMember
<Node
> m_clickNode
;
382 RefPtrWillBeMember
<Node
> m_dragTarget
;
383 bool m_shouldOnlyFireDragOverEvent
;
385 RefPtrWillBeMember
<HTMLFrameSetElement
> m_frameSetBeingResized
;
387 LayoutSize m_offsetFromResizeCorner
; // In the coords of m_resizeScrollableArea.
389 FloatSize m_accumulatedRootOverscroll
;
391 bool m_mousePositionIsUnknown
;
392 // The last mouse movement position this frame has seen in root frame coordinates.
393 IntPoint m_lastKnownMousePosition
;
394 IntPoint m_lastKnownMouseGlobalPosition
;
395 IntPoint m_mouseDownPos
; // In our view's coords.
396 double m_mouseDownTimestamp
;
397 PlatformMouseEvent m_mouseDown
;
398 RefPtr
<UserGestureToken
> m_lastMouseDownUserGestureToken
;
400 RefPtrWillBeMember
<Node
> m_previousWheelScrolledNode
;
402 // The target of each active touch point indexed by the touch ID.
403 using TouchTargetMap
= WillBeHeapHashMap
<unsigned, RefPtrWillBeMember
<EventTarget
>, DefaultHash
<unsigned>::Hash
, WTF::UnsignedWithZeroKeyHashTraits
<unsigned>>;
404 TouchTargetMap m_targetForTouchID
;
406 // If set, the document of the active touch sequence. Unset if no touch sequence active.
407 RefPtrWillBeMember
<Document
> m_touchSequenceDocument
;
408 RefPtr
<UserGestureToken
> m_touchSequenceUserGestureToken
;
412 PointerIdManager m_pointerIdManager
;
414 // This is set upon sending a pointercancel for touch, prevents PE dispatches for touches until
415 // all touch-points become inactive.
416 // TODO(mustaq): Consider a state per pointerType, as in PointerIdManager? Exclude mouse?
417 bool m_inPointerCanceledState
;
419 RefPtrWillBeMember
<Node
> m_scrollGestureHandlingNode
;
420 bool m_lastGestureScrollOverWidget
;
421 // The most recent element to scroll natively during this scroll
422 // sequence. Null if no native element has scrolled this scroll
423 // sequence, or if the most recent element to scroll used scroll
425 RefPtrWillBeMember
<Node
> m_previousGestureScrolledNode
;
426 RefPtrWillBeMember
<Scrollbar
> m_scrollbarHandlingScrollGesture
;
428 double m_maxMouseMovedDuration
;
430 bool m_longTapShouldInvokeContextMenu
;
432 Timer
<EventHandler
> m_activeIntervalTimer
;
433 double m_lastShowPressTimestamp
;
434 RefPtrWillBeMember
<Element
> m_lastDeferredTapElement
;
436 // Only used with the ScrollCustomization runtime enabled feature.
437 WillBeHeapDeque
<RefPtrWillBeMember
<Element
>> m_currentScrollChain
;
438 // True iff some of the delta has been consumed for the current
439 // scroll sequence in this frame, or any child frames. Only used
440 // with ScrollCustomization. If some delta has been consumed, a
441 // scroll which shouldn't propagate can't cause any element to
442 // scroll other than the |m_previousGestureScrolledNode|.
443 bool m_deltaConsumedForScrollSequence
;
448 WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(blink::EventHandler::TouchInfo
);
450 #endif // EventHandler_h