• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/FocusType.h"
33 #include "core/rendering/HitTestRequest.h"
34 #include "core/rendering/style/RenderStyleConstants.h"
35 #include "platform/Cursor.h"
36 #include "platform/PlatformMouseEvent.h"
37 #include "platform/Timer.h"
38 #include "platform/UserGestureIndicator.h"
39 #include "platform/geometry/LayoutPoint.h"
40 #include "platform/heap/Handle.h"
41 #include "platform/scroll/ScrollTypes.h"
42 #include "wtf/Forward.h"
43 #include "wtf/HashMap.h"
44 #include "wtf/HashTraits.h"
45 #include "wtf/RefPtr.h"
46 
47 namespace WebCore {
48 
49 class AutoscrollController;
50 class Clipboard;
51 class Document;
52 class Element;
53 class Event;
54 class EventTarget;
55 class FloatPoint;
56 class FloatQuad;
57 class FullscreenElementStack;
58 class LocalFrame;
59 class HTMLFrameSetElement;
60 class HitTestRequest;
61 class HitTestResult;
62 class KeyboardEvent;
63 class MouseEventWithHitTestResults;
64 class Node;
65 class OptionalCursor;
66 class PlatformGestureEvent;
67 class PlatformKeyboardEvent;
68 class PlatformTouchEvent;
69 class PlatformWheelEvent;
70 class RenderLayer;
71 class RenderLayerScrollableArea;
72 class RenderObject;
73 class RenderWidget;
74 class ScrollableArea;
75 class Scrollbar;
76 class TextEvent;
77 class TouchEvent;
78 class VisibleSelection;
79 class WheelEvent;
80 class Widget;
81 
82 class DragState;
83 
84 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
85 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
86 
87 class EventHandler : public NoBaseWillBeGarbageCollectedFinalized<EventHandler> {
88     WTF_MAKE_NONCOPYABLE(EventHandler);
89 public:
90     explicit EventHandler(LocalFrame*);
91     ~EventHandler();
92     void trace(Visitor*);
93 
94     void clear();
95     void nodeWillBeRemoved(Node&);
96 
97     void updateSelectionForMouseDrag();
98 
99     Node* mousePressNode() const;
100 
101 #if OS(WIN)
102     void startPanScrolling(RenderObject*);
103 #endif
104 
105     void stopAutoscroll();
106 
107     void dispatchFakeMouseMoveEventSoon();
108     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
109 
110     HitTestResult hitTestResultAtPoint(const LayoutPoint&,
111         HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
112         const LayoutSize& padding = LayoutSize());
113 
mousePressed()114     bool mousePressed() const { return m_mousePressed; }
setMousePressed(bool pressed)115     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
116 
117     void setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node>); // A caller is responsible for resetting capturing node to 0.
118 
119     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
120     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
121     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
122     void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
123 
124     void scheduleHoverStateUpdate();
125     void scheduleCursorUpdate();
126 
127     void setResizingFrameSet(HTMLFrameSetElement*);
128 
129     void resizeScrollableAreaDestroyed();
130 
131     IntPoint lastKnownMousePosition() const;
currentMouseCursor()132     Cursor currentMouseCursor() const { return m_currentMouseCursor; }
133 
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 = 0);
137 
138     bool handleMouseMoveEvent(const PlatformMouseEvent&);
139     void handleMouseLeaveEvent(const PlatformMouseEvent&);
140 
141     bool handleMousePressEvent(const PlatformMouseEvent&);
142     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
143     bool handleWheelEvent(const PlatformWheelEvent&);
144     void defaultWheelEventHandler(Node*, WheelEvent*);
145 
146     bool handleGestureEvent(const PlatformGestureEvent&);
147     bool handleGestureScrollEnd(const PlatformGestureEvent&);
148     bool isScrollbarHandlingGestures() const;
149 
150     bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
151     bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
152     bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
153 
154     void adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
155 
156     bool sendContextMenuEvent(const PlatformMouseEvent&);
157     bool sendContextMenuEventForKey();
158     bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
159 
setMouseDownMayStartAutoscroll()160     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
161 
162     static unsigned accessKeyModifiers();
163     bool handleAccessKey(const PlatformKeyboardEvent&);
164     bool keyEvent(const PlatformKeyboardEvent&);
165     void defaultKeyboardEventHandler(KeyboardEvent*);
166 
167     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
168     void defaultTextInputEventHandler(TextEvent*);
169 
170     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
171 
172     void focusDocumentView();
173 
174     void capsLockStateMayHaveChanged(); // Only called by FrameSelection
175 
176     bool handleTouchEvent(const PlatformTouchEvent&);
177 
178     bool useHandCursor(Node*, bool isOverLink);
179 
180     void notifyElementActivated();
181 
takeLastMouseDownGestureToken()182     PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken.release(); }
183 
184 private:
185     static DragState& dragState();
186 
187     PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard() const;
188 
189     bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
190     void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
191     void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
192     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
193     void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&);
194     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
195 
196     bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
197     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
198     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
199     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
200     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
201     bool handleMouseFocus(const PlatformMouseEvent&);
202     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
203     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
204 
205     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
206 
207     bool handleGestureTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
208     bool handleGestureLongPress(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
209     bool handleGestureLongTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
210     bool handleGestureTwoFingerTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
211     bool handleGestureScrollUpdate(const PlatformGestureEvent&);
212     bool handleGestureScrollBegin(const PlatformGestureEvent&);
213     void clearGestureScrollNodes();
214 
215     bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
216 
217     OptionalCursor selectCursor(const HitTestResult&);
218     OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam);
219 
220     void hoverTimerFired(Timer<EventHandler>*);
221     void cursorUpdateTimerFired(Timer<EventHandler>*);
222     void activeIntervalTimerFired(Timer<EventHandler>*);
223 
mouseDownMayStartSelect()224     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
225 
226     void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
227     void cancelFakeMouseMoveEvent();
228     bool isCursorVisible() const;
229     void updateCursor();
230 
231     bool isInsideScrollbar(const IntPoint&) const;
232 
233     ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
234 
235     // Scrolls the elements of the DOM tree. Returns true if a node was scrolled.
236     // False if we reached the root and couldn't scroll anything.
237     // direction - The direction to scroll in. If this is a logicl direction, it will be
238     //             converted to the physical direction based on a node's writing mode.
239     // granularity - The units that the  scroll delta parameter is in.
240     // startNode - The node to start bubbling the scroll from. If a node can't scroll,
241     //             the scroll bubbles up to the containing block.
242     // stopNode - On input, if provided and non-null, the node at which we should stop bubbling on input.
243     //            On output, if provided and a node was scrolled stopNode will point to that node.
244     // delta - The delta to scroll by, in the units of the granularity parameter. (e.g. pixels, lines, pages, etc.)
245     // absolutePoint - For wheel scrolls - the location, in absolute coordinates, where the event occured.
246     bool scroll(ScrollDirection, ScrollGranularity, Node* startNode = 0, Node** stopNode = 0, float delta = 1.0f, IntPoint absolutePoint = IntPoint());
247 
248     TouchAction intersectTouchAction(const TouchAction, const TouchAction);
249     TouchAction computeEffectiveTouchAction(const Node&);
250 
251     HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
252 
253     void invalidateClick();
254 
255     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
256 
257     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
258 
259     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, int clickCount, const PlatformMouseEvent&, bool setUnder);
260     bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
261 
262     void freeClipboard();
263 
264     bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
265     bool tryStartDrag(const MouseEventWithHitTestResults&);
266     void clearDragState();
267 
268     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
269 
270     bool dragHysteresisExceeded(const FloatPoint&) const;
271     bool dragHysteresisExceeded(const IntPoint&) const;
272 
273     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
274     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
275     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
276 
277     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&);
278 
279     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
280 
281     bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
282 
283     void defaultSpaceEventHandler(KeyboardEvent*);
284     void defaultBackspaceEventHandler(KeyboardEvent*);
285     void defaultTabEventHandler(KeyboardEvent*);
286     void defaultEscapeEventHandler(KeyboardEvent*);
287     void defaultArrowEventHandler(FocusType, KeyboardEvent*);
288 
289     void updateSelectionForMouseDrag(const HitTestResult&);
290 
291     void updateLastScrollbarUnderMouse(Scrollbar*, bool);
292 
293     void setFrameWasScrolledByUser();
294 
capturesDragging()295     bool capturesDragging() const { return m_capturesDragging; }
296 
297     bool isKeyEventAllowedInFullScreen(FullscreenElementStack*, const PlatformKeyboardEvent&) const;
298 
299     bool handleGestureShowPress();
300 
301     bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&);
302 
303     bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
304     bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
305     bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
306     LocalFrame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
307 
308     AutoscrollController* autoscrollController() const;
309     bool panScrollInProgress() const;
310     void setLastKnownMousePosition(const PlatformMouseEvent&);
311 
312     LocalFrame* const m_frame;
313 
314     bool m_mousePressed;
315     bool m_capturesDragging;
316     RefPtrWillBeMember<Node> m_mousePressNode;
317 
318     bool m_mouseDownMayStartSelect;
319     bool m_mouseDownMayStartDrag;
320     bool m_mouseDownWasSingleClickInSelection;
321     enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
322     SelectionInitiationState m_selectionInitiationState;
323 
324     LayoutPoint m_dragStartPos;
325 
326     Timer<EventHandler> m_hoverTimer;
327     Timer<EventHandler> m_cursorUpdateTimer;
328 
329     bool m_mouseDownMayStartAutoscroll;
330     bool m_mouseDownWasInSubframe;
331 
332     Timer<EventHandler> m_fakeMouseMoveEventTimer;
333 
334     bool m_svgPan;
335 
336     RenderLayerScrollableArea* m_resizeScrollableArea;
337 
338     RefPtrWillBeMember<Node> m_capturingMouseEventsNode;
339     bool m_eventHandlerWillResetCapturingMouseEventsNode;
340 
341     RefPtrWillBeMember<Node> m_nodeUnderMouse;
342     RefPtrWillBeMember<Node> m_lastNodeUnderMouse;
343     RefPtr<LocalFrame> m_lastMouseMoveEventSubframe;
344     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
345     Cursor m_currentMouseCursor;
346 
347     int m_clickCount;
348     RefPtrWillBeMember<Node> m_clickNode;
349 
350     RefPtrWillBeMember<Node> m_dragTarget;
351     bool m_shouldOnlyFireDragOverEvent;
352 
353     RefPtrWillBeMember<HTMLFrameSetElement> m_frameSetBeingResized;
354 
355     LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeScrollableArea.
356 
357     bool m_mousePositionIsUnknown;
358     IntPoint m_lastKnownMousePosition;
359     IntPoint m_lastKnownMouseGlobalPosition;
360     IntPoint m_mouseDownPos; // In our view's coords.
361     double m_mouseDownTimestamp;
362     PlatformMouseEvent m_mouseDown;
363     RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
364 
365     RefPtrWillBeMember<Node> m_latchedWheelEventNode;
366     bool m_widgetIsLatched;
367 
368     RefPtrWillBeMember<Node> m_previousWheelScrolledNode;
369 
370     // The target of each active touch point indexed by the touch ID.
371     typedef WillBeHeapHashMap<unsigned, RefPtrWillBeMember<EventTarget>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > TouchTargetMap;
372     TouchTargetMap m_targetForTouchID;
373 
374     // If set, the document of the active touch sequence. Unset if no touch sequence active.
375     RefPtrWillBeMember<Document> m_touchSequenceDocument;
376     RefPtr<UserGestureToken> m_touchSequenceUserGestureToken;
377 
378     bool m_touchPressed;
379 
380     RefPtrWillBeMember<Node> m_scrollGestureHandlingNode;
381     bool m_lastHitTestResultOverWidget;
382     RefPtrWillBeMember<Node> m_previousGestureScrolledNode;
383     RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
384 
385     double m_maxMouseMovedDuration;
386     PlatformEvent::Type m_baseEventType;
387     bool m_didStartDrag;
388 
389     bool m_longTapShouldInvokeContextMenu;
390 
391     Timer<EventHandler> m_activeIntervalTimer;
392     double m_lastShowPressTimestamp;
393     RefPtrWillBeMember<Element> m_lastDeferredTapElement;
394 };
395 
396 } // namespace WebCore
397 
398 #endif // EventHandler_h
399