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/FocusType.h"
33 #include "core/rendering/HitTestRequest.h"
34 #include "core/rendering/style/RenderStyleConstants.h"
35 #include "heap/Handle.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/scroll/ScrollTypes.h"
42 #include "wtf/Forward.h"
43 #include "wtf/HashMap.h"
44 #include "wtf/RefPtr.h"
48 class AutoscrollController;
56 class FullscreenElementStack;
58 class HTMLFrameSetElement;
62 class MouseEventWithHitTestResults;
65 class PlatformGestureEvent;
66 class PlatformKeyboardEvent;
67 class PlatformTouchEvent;
68 class PlatformWheelEvent;
70 class RenderLayerScrollableArea;
73 class SVGElementInstance;
78 class VisibleSelection;
84 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
85 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
88 WTF_MAKE_NONCOPYABLE(EventHandler);
90 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(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
118 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
119 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
120 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
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 bool handleGestureEvent(const PlatformGestureEvent&);
146 bool handleGestureScrollEnd(const PlatformGestureEvent&);
147 bool isScrollbarHandlingGestures() const;
149 bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
150 bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
151 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
153 void adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
155 bool sendContextMenuEvent(const PlatformMouseEvent&);
156 bool sendContextMenuEventForKey();
157 bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
159 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
161 static unsigned accessKeyModifiers();
162 bool handleAccessKey(const PlatformKeyboardEvent&);
163 bool keyEvent(const PlatformKeyboardEvent&);
164 void defaultKeyboardEventHandler(KeyboardEvent*);
166 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
167 void defaultTextInputEventHandler(TextEvent*);
169 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
171 void focusDocumentView();
173 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
175 bool handleTouchEvent(const PlatformTouchEvent&);
177 bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
179 void notifyElementActivated();
181 PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken.release(); }
184 static DragState& dragState();
186 PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard() const;
188 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
189 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
190 void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
191 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
192 void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&);
193 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
195 bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
196 bool handleMousePressEvent(const MouseEventWithHitTestResults&);
197 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
198 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
199 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
200 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
201 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
203 bool handlePasteGlobalSelection(const PlatformMouseEvent&);
205 bool handleGestureTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
206 bool handleGestureLongPress(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
207 bool handleGestureLongTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
208 bool handleGestureTwoFingerTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
209 bool handleGestureScrollUpdate(const PlatformGestureEvent&);
210 bool handleGestureScrollBegin(const PlatformGestureEvent&);
211 void clearGestureScrollNodes();
213 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
215 OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
216 OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam, bool shiftKey);
218 void hoverTimerFired(Timer<EventHandler>*);
219 void cursorUpdateTimerFired(Timer<EventHandler>*);
220 void activeIntervalTimerFired(Timer<EventHandler>*);
222 bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
223 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
225 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
226 void cancelFakeMouseMoveEvent();
227 bool isCursorVisible() const;
230 bool isInsideScrollbar(const IntPoint&) const;
232 ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
234 // Scrolls the elements of the DOM tree. Returns true if a node was scrolled.
235 // False if we reached the root and couldn't scroll anything.
236 // direction - The direction to scroll in. If this is a logicl direction, it will be
237 // converted to the physical direction based on a node's writing mode.
238 // granularity - The units that the scroll delta parameter is in.
239 // startNode - The node to start bubbling the scroll from. If a node can't scroll,
240 // the scroll bubbles up to the containing block.
241 // stopNode - On input, if provided and non-null, the node at which we should stop bubbling on input.
242 // On output, if provided and a node was scrolled stopNode will point to that node.
243 // delta - The delta to scroll by, in the units of the granularity parameter. (e.g. pixels, lines, pages, etc.)
244 // absolutePoint - For wheel scrolls - the location, in absolute coordinates, where the event occured.
245 bool scroll(ScrollDirection, ScrollGranularity, Node* startNode = 0, Node** stopNode = 0, float delta = 1.0f, IntPoint absolutePoint = IntPoint());
247 bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
249 TouchAction intersectTouchAction(const TouchAction, const TouchAction);
250 TouchAction computeEffectiveTouchAction(const LayoutPoint&);
252 bool handleMouseEventAsEmulatedGesture(const PlatformMouseEvent&);
253 bool handleWheelEventAsEmulatedGesture(const PlatformWheelEvent&);
254 HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
256 void invalidateClick();
258 Node* nodeUnderMouse() const;
260 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
262 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
264 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
265 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
267 void freeClipboard();
269 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
270 bool tryStartDrag(const MouseEventWithHitTestResults&);
271 void clearDragState();
273 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
275 bool dragHysteresisExceeded(const FloatPoint&) const;
276 bool dragHysteresisExceeded(const IntPoint&) const;
278 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
279 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
280 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
282 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
284 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
286 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
288 void defaultSpaceEventHandler(KeyboardEvent*);
289 void defaultBackspaceEventHandler(KeyboardEvent*);
290 void defaultTabEventHandler(KeyboardEvent*);
291 void defaultEscapeEventHandler(KeyboardEvent*);
292 void defaultArrowEventHandler(FocusType, KeyboardEvent*);
294 void updateSelectionForMouseDrag(const HitTestResult&);
296 void updateLastScrollbarUnderMouse(Scrollbar*, bool);
298 void setFrameWasScrolledByUser();
300 bool capturesDragging() const { return m_capturesDragging; }
302 bool isKeyEventAllowedInFullScreen(FullscreenElementStack*, const PlatformKeyboardEvent&) const;
304 bool handleGestureShowPress();
306 bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&);
308 bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
309 bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
310 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
311 LocalFrame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
313 AutoscrollController* autoscrollController() const;
314 bool panScrollInProgress() const;
315 void setLastKnownMousePosition(const PlatformMouseEvent&);
317 LocalFrame* const m_frame;
320 bool m_capturesDragging;
321 RefPtr<Node> m_mousePressNode;
323 bool m_mouseDownMayStartSelect;
324 bool m_mouseDownMayStartDrag;
325 bool m_mouseDownWasSingleClickInSelection;
326 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
327 SelectionInitiationState m_selectionInitiationState;
329 LayoutPoint m_dragStartPos;
331 Timer<EventHandler> m_hoverTimer;
332 Timer<EventHandler> m_cursorUpdateTimer;
334 bool m_mouseDownMayStartAutoscroll;
335 bool m_mouseDownWasInSubframe;
337 Timer<EventHandler> m_fakeMouseMoveEventTimer;
340 RefPtr<SVGElementInstance> m_instanceUnderMouse;
341 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
343 RenderLayerScrollableArea* m_resizeScrollableArea;
345 RefPtr<Node> m_capturingMouseEventsNode;
346 bool m_eventHandlerWillResetCapturingMouseEventsNode;
348 RefPtr<Node> m_nodeUnderMouse;
349 RefPtr<Node> m_lastNodeUnderMouse;
350 RefPtr<LocalFrame> m_lastMouseMoveEventSubframe;
351 RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
352 Cursor m_currentMouseCursor;
355 RefPtr<Node> m_clickNode;
357 RefPtr<Node> m_dragTarget;
358 bool m_shouldOnlyFireDragOverEvent;
360 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
362 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeScrollableArea.
364 bool m_mousePositionIsUnknown;
365 IntPoint m_lastKnownMousePosition;
366 IntPoint m_lastKnownMouseGlobalPosition;
367 IntPoint m_mouseDownPos; // In our view's coords.
368 double m_mouseDownTimestamp;
369 PlatformMouseEvent m_mouseDown;
370 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
372 RefPtr<Node> m_latchedWheelEventNode;
373 bool m_widgetIsLatched;
375 RefPtr<Node> m_previousWheelScrolledNode;
377 typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
378 TouchTargetMap m_originatingTouchPointTargets;
379 RefPtr<Document> m_originatingTouchPointDocument;
380 unsigned m_originatingTouchPointTargetKey;
383 RefPtr<Node> m_scrollGestureHandlingNode;
384 bool m_lastHitTestResultOverWidget;
385 RefPtr<Node> m_previousGestureScrolledNode;
386 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
388 double m_maxMouseMovedDuration;
389 PlatformEvent::Type m_baseEventType;
392 bool m_longTapShouldInvokeContextMenu;
393 OwnPtr<IntPoint> m_lastSyntheticPinchAnchorCss;
394 OwnPtr<IntPoint> m_lastSyntheticPinchAnchorDip;
395 OwnPtr<IntPoint> m_lastSyntheticPanLocation;
396 float m_syntheticPageScaleFactor;
398 Timer<EventHandler> m_activeIntervalTimer;
399 double m_lastShowPressTimestamp;
400 RefPtr<Element> m_lastDeferredTapElement;
403 } // namespace WebCore
405 #endif // EventHandler_h