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/editing/TextGranularity.h"
30 #include "core/events/TextEventInputType.h"
31 #include "core/page/DragActions.h"
32 #include "core/page/EventWithHitTestResults.h"
33 #include "core/page/FocusType.h"
34 #include "core/rendering/HitTestRequest.h"
35 #include "core/rendering/style/RenderStyleConstants.h"
36 #include "platform/Cursor.h"
37 #include "platform/PlatformMouseEvent.h"
38 #include "platform/Timer.h"
39 #include "platform/UserGestureIndicator.h"
40 #include "platform/geometry/LayoutPoint.h"
41 #include "platform/heap/Handle.h"
42 #include "platform/scroll/ScrollTypes.h"
43 #include "wtf/Forward.h"
44 #include "wtf/HashMap.h"
45 #include "wtf/HashTraits.h"
46 #include "wtf/RefPtr.h"
50 class AutoscrollController;
57 template <typename EventType>
58 class EventWithHitTestResults;
62 class HTMLFrameSetElement;
69 class PlatformGestureEvent;
70 class PlatformKeyboardEvent;
71 class PlatformTouchEvent;
72 class PlatformWheelEvent;
74 class RenderLayerScrollableArea;
79 class VisibleSelection;
83 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
84 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
86 class EventHandler : public NoBaseWillBeGarbageCollectedFinalized<EventHandler> {
87 WTF_MAKE_NONCOPYABLE(EventHandler);
89 explicit EventHandler(LocalFrame*);
94 void nodeWillBeRemoved(Node&);
96 void updateSelectionForMouseDrag();
98 Node* mousePressNode() const;
101 void startPanScrolling(RenderObject*);
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; }
114 void setMousePressed(bool pressed) { m_mousePressed = pressed; }
116 void setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node>); // A caller is responsible for resetting capturing node to 0.
118 bool updateDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
119 void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
120 bool performDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
121 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
123 void scheduleHoverStateUpdate();
124 void scheduleCursorUpdate();
126 void setResizingFrameSet(HTMLFrameSetElement*);
128 void resizeScrollableAreaDestroyed();
130 IntPoint lastKnownMousePosition() const;
131 Cursor currentMouseCursor() const { return m_currentMouseCursor; }
133 // Attempts to scroll the DOM tree. If that fails, scrolls the view.
134 // If the view can't be scrolled either, recursively bubble to the parent frame.
135 bool bubblingScroll(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
137 bool handleMouseMoveEvent(const PlatformMouseEvent&);
138 void handleMouseLeaveEvent(const PlatformMouseEvent&);
140 bool handleMousePressEvent(const PlatformMouseEvent&);
141 bool handleMouseReleaseEvent(const PlatformMouseEvent&);
142 bool handleWheelEvent(const PlatformWheelEvent&);
143 void defaultWheelEventHandler(Node*, WheelEvent*);
145 // Called on the local root frame exactly once per gesture event.
146 bool handleGestureEvent(const PlatformGestureEvent&);
147 bool handleGestureEvent(const GestureEventWithHitTestResults&);
149 // Hit-test the provided (non-scroll) gesture event, applying touch-adjustment and updating
150 // hover/active state across all frames if necessary. This should be called at most once
151 // per gesture event, and called on the local root frame.
152 // Note: This is similar to (the less clearly named) prepareMouseEvent.
153 // FIXME: Remove readOnly param when there is only ever a single call to this.
154 GestureEventWithHitTestResults targetGestureEvent(const PlatformGestureEvent&, bool readOnly = false);
156 // Handle the provided non-scroll gesture event. Should be called only on the inner frame.
157 bool handleGestureEventInFrame(const GestureEventWithHitTestResults&);
159 // Handle the provided scroll gesture event, propagating down to child frames as necessary.
160 bool handleGestureScrollEvent(const PlatformGestureEvent&);
161 bool handleGestureScrollEnd(const PlatformGestureEvent&);
162 bool isScrollbarHandlingGestures() const;
164 bool bestClickableNodeForHitTestResult(const HitTestResult&, IntPoint& targetPoint, Node*& targetNode);
165 bool bestContextMenuNodeForHitTestResult(const HitTestResult&, IntPoint& targetPoint, Node*& targetNode);
166 // FIXME: This doesn't appear to be used outside tests anymore, what path are we using now and is it tested?
167 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
169 bool sendContextMenuEvent(const PlatformMouseEvent&);
170 bool sendContextMenuEventForKey();
171 bool sendContextMenuEventForGesture(const GestureEventWithHitTestResults&);
173 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
175 static unsigned accessKeyModifiers();
176 bool handleAccessKey(const PlatformKeyboardEvent&);
177 bool keyEvent(const PlatformKeyboardEvent&);
178 void defaultKeyboardEventHandler(KeyboardEvent*);
180 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
181 void defaultTextInputEventHandler(TextEvent*);
183 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
185 void focusDocumentView();
187 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
189 bool handleTouchEvent(const PlatformTouchEvent&);
191 bool useHandCursor(Node*, bool isOverLink);
193 void notifyElementActivated();
194 void notifySelectionChanged();
196 PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken.release(); }
198 int clickCount() { return m_clickCount; }
199 bool mouseDownWasSingleClickInSelection() { return m_mouseDownWasSingleClickInSelection; }
202 static DragState& dragState();
204 PassRefPtrWillBeRawPtr<DataTransfer> createDraggingDataTransfer() const;
206 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
207 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
208 void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
209 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
210 void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&);
211 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
213 bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
214 bool handleMousePressEvent(const MouseEventWithHitTestResults&);
215 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
216 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
217 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
218 bool handleMouseFocus(const PlatformMouseEvent&);
219 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
220 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
222 bool handlePasteGlobalSelection(const PlatformMouseEvent&);
224 HitTestRequest::HitTestRequestType getHitTypeForGestureType(PlatformEvent::Type);
225 void applyTouchAdjustment(PlatformGestureEvent*, HitTestResult*);
226 bool handleGestureTap(const GestureEventWithHitTestResults&);
227 bool handleGestureLongPress(const GestureEventWithHitTestResults&);
228 bool handleGestureLongTap(const GestureEventWithHitTestResults&);
229 bool handleGestureScrollUpdate(const PlatformGestureEvent&);
230 bool handleGestureScrollBegin(const PlatformGestureEvent&);
231 void clearGestureScrollNodes();
233 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
235 OptionalCursor selectCursor(const HitTestResult&);
236 OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam);
238 void hoverTimerFired(Timer<EventHandler>*);
239 void cursorUpdateTimerFired(Timer<EventHandler>*);
240 void activeIntervalTimerFired(Timer<EventHandler>*);
242 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
244 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
245 void cancelFakeMouseMoveEvent();
246 bool isCursorVisible() const;
249 bool isInsideScrollbar(const IntPoint&) const;
251 ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
253 // Scrolls the elements of the DOM tree. Returns true if a node was scrolled.
254 // False if we reached the root and couldn't scroll anything.
255 // direction - The direction to scroll in. If this is a logicl direction, it will be
256 // converted to the physical direction based on a node's writing mode.
257 // granularity - The units that the scroll delta parameter is in.
258 // startNode - The node to start bubbling the scroll from. If a node can't scroll,
259 // the scroll bubbles up to the containing block.
260 // stopNode - On input, if provided and non-null, the node at which we should stop bubbling on input.
261 // On output, if provided and a node was scrolled stopNode will point to that node.
262 // delta - The delta to scroll by, in the units of the granularity parameter. (e.g. pixels, lines, pages, etc.)
263 // absolutePoint - For wheel scrolls - the location, in absolute coordinates, where the event occured.
264 bool scroll(ScrollDirection, ScrollGranularity, Node* startNode = 0, Node** stopNode = 0, float delta = 1.0f, IntPoint absolutePoint = IntPoint());
266 TouchAction intersectTouchAction(const TouchAction, const TouchAction);
267 TouchAction computeEffectiveTouchAction(const Node&);
269 HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
271 void invalidateClick();
273 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
275 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
277 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, int clickCount, const PlatformMouseEvent&, bool setUnder);
278 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, DataTransfer*);
280 void clearDragDataTransfer();
282 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
283 bool tryStartDrag(const MouseEventWithHitTestResults&);
284 void clearDragState();
286 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
288 bool dragHysteresisExceeded(const FloatPoint&) const;
289 bool dragHysteresisExceeded(const IntPoint&) const;
291 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
292 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
293 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
295 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&);
297 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
299 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
300 void defaultSpaceEventHandler(KeyboardEvent*);
301 void defaultBackspaceEventHandler(KeyboardEvent*);
302 void defaultTabEventHandler(KeyboardEvent*);
303 void defaultEscapeEventHandler(KeyboardEvent*);
304 void defaultArrowEventHandler(FocusType, KeyboardEvent*);
306 void updateSelectionForMouseDrag(const HitTestResult&);
308 void updateLastScrollbarUnderMouse(Scrollbar*, bool);
310 void setFrameWasScrolledByUser();
312 bool capturesDragging() const { return m_capturesDragging; }
314 bool isKeyEventAllowedInFullScreen(Fullscreen*, const PlatformKeyboardEvent&) const;
316 bool handleGestureShowPress();
318 bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&);
320 bool passScrollGestureEventToWidget(const PlatformGestureEvent&, RenderObject*);
321 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
323 AutoscrollController* autoscrollController() const;
324 bool panScrollInProgress() const;
325 void setLastKnownMousePosition(const PlatformMouseEvent&);
327 LocalFrame* const m_frame;
330 bool m_capturesDragging;
331 RefPtrWillBeMember<Node> m_mousePressNode;
333 bool m_mouseDownMayStartSelect;
334 bool m_mouseDownMayStartDrag;
335 bool m_mouseDownWasSingleClickInSelection;
336 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
337 SelectionInitiationState m_selectionInitiationState;
339 LayoutPoint m_dragStartPos;
341 Timer<EventHandler> m_hoverTimer;
342 Timer<EventHandler> m_cursorUpdateTimer;
344 bool m_mouseDownMayStartAutoscroll;
345 bool m_mouseDownWasInSubframe;
347 Timer<EventHandler> m_fakeMouseMoveEventTimer;
351 RenderLayerScrollableArea* m_resizeScrollableArea;
353 RefPtrWillBeMember<Node> m_capturingMouseEventsNode;
354 bool m_eventHandlerWillResetCapturingMouseEventsNode;
356 RefPtrWillBeMember<Node> m_nodeUnderMouse;
357 RefPtrWillBeMember<Node> m_lastNodeUnderMouse;
358 RefPtrWillBeMember<LocalFrame> m_lastMouseMoveEventSubframe;
359 RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
360 Cursor m_currentMouseCursor;
363 RefPtrWillBeMember<Node> m_clickNode;
365 RefPtrWillBeMember<Node> m_dragTarget;
366 bool m_shouldOnlyFireDragOverEvent;
368 RefPtrWillBeMember<HTMLFrameSetElement> m_frameSetBeingResized;
370 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeScrollableArea.
372 bool m_mousePositionIsUnknown;
373 IntPoint m_lastKnownMousePosition;
374 IntPoint m_lastKnownMouseGlobalPosition;
375 IntPoint m_mouseDownPos; // In our view's coords.
376 double m_mouseDownTimestamp;
377 PlatformMouseEvent m_mouseDown;
378 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
380 RefPtrWillBeMember<Node> m_latchedWheelEventNode;
381 bool m_widgetIsLatched;
383 RefPtrWillBeMember<Node> m_previousWheelScrolledNode;
385 // The target of each active touch point indexed by the touch ID.
386 typedef WillBeHeapHashMap<unsigned, RefPtrWillBeMember<EventTarget>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > TouchTargetMap;
387 TouchTargetMap m_targetForTouchID;
389 // If set, the document of the active touch sequence. Unset if no touch sequence active.
390 RefPtrWillBeMember<Document> m_touchSequenceDocument;
391 RefPtr<UserGestureToken> m_touchSequenceUserGestureToken;
395 RefPtrWillBeMember<Node> m_scrollGestureHandlingNode;
396 bool m_lastGestureScrollOverWidget;
397 RefPtrWillBeMember<Node> m_previousGestureScrolledNode;
398 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
400 double m_maxMouseMovedDuration;
403 bool m_longTapShouldInvokeContextMenu;
405 Timer<EventHandler> m_activeIntervalTimer;
406 double m_lastShowPressTimestamp;
407 RefPtrWillBeMember<Element> m_lastDeferredTapElement;
412 #endif // EventHandler_h