1/*
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
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 "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"
47
48namespace blink {
49
50class AutoscrollController;
51class DataTransfer;
52class Document;
53class DragState;
54class Element;
55class Event;
56class EventTarget;
57template <typename EventType>
58class EventWithHitTestResults;
59class FloatPoint;
60class FloatQuad;
61class Fullscreen;
62class HTMLFrameSetElement;
63class HitTestRequest;
64class HitTestResult;
65class KeyboardEvent;
66class LocalFrame;
67class Node;
68class OptionalCursor;
69class PlatformGestureEvent;
70class PlatformKeyboardEvent;
71class PlatformTouchEvent;
72class PlatformWheelEvent;
73class RenderLayer;
74class RenderLayerScrollableArea;
75class RenderObject;
76class ScrollableArea;
77class Scrollbar;
78class TextEvent;
79class VisibleSelection;
80class WheelEvent;
81class Widget;
82
83enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
84enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
85
86class EventHandler : public NoBaseWillBeGarbageCollectedFinalized<EventHandler> {
87    WTF_MAKE_NONCOPYABLE(EventHandler);
88public:
89    explicit EventHandler(LocalFrame*);
90    ~EventHandler();
91    void trace(Visitor*);
92
93    void clear();
94    void nodeWillBeRemoved(Node&);
95
96    void updateSelectionForMouseDrag();
97
98    Node* mousePressNode() const;
99
100#if OS(WIN)
101    void startPanScrolling(RenderObject*);
102#endif
103
104    void stopAutoscroll();
105
106    void dispatchFakeMouseMoveEventSoon();
107    void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
108
109    HitTestResult hitTestResultAtPoint(const LayoutPoint&,
110        HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
111        const LayoutSize& padding = LayoutSize());
112
113    bool mousePressed() const { return m_mousePressed; }
114    void setMousePressed(bool pressed) { m_mousePressed = pressed; }
115
116    void setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node>); // A caller is responsible for resetting capturing node to 0.
117
118    bool updateDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
119    void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
120    bool performDragAndDrop(const PlatformMouseEvent&, DataTransfer*);
121    void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
122
123    void scheduleHoverStateUpdate();
124    void scheduleCursorUpdate();
125
126    void setResizingFrameSet(HTMLFrameSetElement*);
127
128    void resizeScrollableAreaDestroyed();
129
130    IntPoint lastKnownMousePosition() const;
131    Cursor currentMouseCursor() const { return m_currentMouseCursor; }
132
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);
136
137    bool handleMouseMoveEvent(const PlatformMouseEvent&);
138    void handleMouseLeaveEvent(const PlatformMouseEvent&);
139
140    bool handleMousePressEvent(const PlatformMouseEvent&);
141    bool handleMouseReleaseEvent(const PlatformMouseEvent&);
142    bool handleWheelEvent(const PlatformWheelEvent&);
143    void defaultWheelEventHandler(Node*, WheelEvent*);
144
145    // Called on the local root frame exactly once per gesture event.
146    bool handleGestureEvent(const PlatformGestureEvent&);
147    bool handleGestureEvent(const GestureEventWithHitTestResults&);
148
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);
155
156    // Handle the provided non-scroll gesture event. Should be called only on the inner frame.
157    bool handleGestureEventInFrame(const GestureEventWithHitTestResults&);
158
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;
163
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);
168
169    bool sendContextMenuEvent(const PlatformMouseEvent&);
170    bool sendContextMenuEventForKey();
171    bool sendContextMenuEventForGesture(const GestureEventWithHitTestResults&);
172
173    void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
174
175    static unsigned accessKeyModifiers();
176    bool handleAccessKey(const PlatformKeyboardEvent&);
177    bool keyEvent(const PlatformKeyboardEvent&);
178    void defaultKeyboardEventHandler(KeyboardEvent*);
179
180    bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
181    void defaultTextInputEventHandler(TextEvent*);
182
183    void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
184
185    void focusDocumentView();
186
187    void capsLockStateMayHaveChanged(); // Only called by FrameSelection
188
189    bool handleTouchEvent(const PlatformTouchEvent&);
190
191    bool useHandCursor(Node*, bool isOverLink);
192
193    void notifyElementActivated();
194    void notifySelectionChanged();
195
196    PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken.release(); }
197
198    int clickCount() { return m_clickCount; }
199    bool mouseDownWasSingleClickInSelection() { return m_mouseDownWasSingleClickInSelection; }
200
201private:
202    static DragState& dragState();
203
204    PassRefPtrWillBeRawPtr<DataTransfer> createDraggingDataTransfer() const;
205
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&);
212
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&);
221
222    bool handlePasteGlobalSelection(const PlatformMouseEvent&);
223
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();
232
233    bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
234
235    OptionalCursor selectCursor(const HitTestResult&);
236    OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam);
237
238    void hoverTimerFired(Timer<EventHandler>*);
239    void cursorUpdateTimerFired(Timer<EventHandler>*);
240    void activeIntervalTimerFired(Timer<EventHandler>*);
241
242    bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
243
244    void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
245    void cancelFakeMouseMoveEvent();
246    bool isCursorVisible() const;
247    void updateCursor();
248
249    bool isInsideScrollbar(const IntPoint&) const;
250
251    ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
252
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());
265
266    TouchAction intersectTouchAction(const TouchAction, const TouchAction);
267    TouchAction computeEffectiveTouchAction(const Node&);
268
269    HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
270
271    void invalidateClick();
272
273    void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
274
275    MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
276
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*);
279
280    void clearDragDataTransfer();
281
282    bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
283    bool tryStartDrag(const MouseEventWithHitTestResults&);
284    void clearDragState();
285
286    bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
287
288    bool dragHysteresisExceeded(const FloatPoint&) const;
289    bool dragHysteresisExceeded(const IntPoint&) const;
290
291    bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
292    bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
293    bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
294
295    bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&);
296
297    bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
298
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*);
305
306    void updateSelectionForMouseDrag(const HitTestResult&);
307
308    void updateLastScrollbarUnderMouse(Scrollbar*, bool);
309
310    void setFrameWasScrolledByUser();
311
312    bool capturesDragging() const { return m_capturesDragging; }
313
314    bool isKeyEventAllowedInFullScreen(Fullscreen*, const PlatformKeyboardEvent&) const;
315
316    bool handleGestureShowPress();
317
318    bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&);
319
320    bool passScrollGestureEventToWidget(const PlatformGestureEvent&, RenderObject*);
321    bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
322
323    AutoscrollController* autoscrollController() const;
324    bool panScrollInProgress() const;
325    void setLastKnownMousePosition(const PlatformMouseEvent&);
326
327    LocalFrame* const m_frame;
328
329    bool m_mousePressed;
330    bool m_capturesDragging;
331    RefPtrWillBeMember<Node> m_mousePressNode;
332
333    bool m_mouseDownMayStartSelect;
334    bool m_mouseDownMayStartDrag;
335    bool m_mouseDownWasSingleClickInSelection;
336    enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
337    SelectionInitiationState m_selectionInitiationState;
338
339    LayoutPoint m_dragStartPos;
340
341    Timer<EventHandler> m_hoverTimer;
342    Timer<EventHandler> m_cursorUpdateTimer;
343
344    bool m_mouseDownMayStartAutoscroll;
345    bool m_mouseDownWasInSubframe;
346
347    Timer<EventHandler> m_fakeMouseMoveEventTimer;
348
349    bool m_svgPan;
350
351    RenderLayerScrollableArea* m_resizeScrollableArea;
352
353    RefPtrWillBeMember<Node> m_capturingMouseEventsNode;
354    bool m_eventHandlerWillResetCapturingMouseEventsNode;
355
356    RefPtrWillBeMember<Node> m_nodeUnderMouse;
357    RefPtrWillBeMember<Node> m_lastNodeUnderMouse;
358    RefPtrWillBeMember<LocalFrame> m_lastMouseMoveEventSubframe;
359    RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
360    Cursor m_currentMouseCursor;
361
362    int m_clickCount;
363    RefPtrWillBeMember<Node> m_clickNode;
364
365    RefPtrWillBeMember<Node> m_dragTarget;
366    bool m_shouldOnlyFireDragOverEvent;
367
368    RefPtrWillBeMember<HTMLFrameSetElement> m_frameSetBeingResized;
369
370    LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeScrollableArea.
371
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;
379
380    RefPtrWillBeMember<Node> m_latchedWheelEventNode;
381    bool m_widgetIsLatched;
382
383    RefPtrWillBeMember<Node> m_previousWheelScrolledNode;
384
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;
388
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;
392
393    bool m_touchPressed;
394
395    RefPtrWillBeMember<Node> m_scrollGestureHandlingNode;
396    bool m_lastGestureScrollOverWidget;
397    RefPtrWillBeMember<Node> m_previousGestureScrolledNode;
398    RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
399
400    double m_maxMouseMovedDuration;
401    bool m_didStartDrag;
402
403    bool m_longTapShouldInvokeContextMenu;
404
405    Timer<EventHandler> m_activeIntervalTimer;
406    double m_lastShowPressTimestamp;
407    RefPtrWillBeMember<Element> m_lastDeferredTapElement;
408};
409
410} // namespace blink
411
412#endif // EventHandler_h
413