• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007 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 "DragActions.h"
30 #include "FocusDirection.h"
31 #include "PlatformMouseEvent.h"
32 #include "ScrollTypes.h"
33 #include "Timer.h"
34 #include <wtf/Forward.h>
35 #include <wtf/Noncopyable.h>
36 #include <wtf/Platform.h>
37 #include <wtf/RefPtr.h>
38 
39 #if PLATFORM(MAC)
40 #include "WebCoreKeyboardUIMode.h"
41 #ifndef __OBJC__
42 class NSEvent;
43 class NSView;
44 #endif
45 #endif
46 
47 namespace WebCore {
48 
49 class AtomicString;
50 class Clipboard;
51 class Cursor;
52 class EventTargetNode;
53 class Event;
54 class FloatPoint;
55 class FloatRect;
56 class Frame;
57 class HitTestResult;
58 class HTMLFrameSetElement;
59 class KeyboardEvent;
60 class MouseEventWithHitTestResults;
61 class Node;
62 class PlatformKeyboardEvent;
63 class PlatformWheelEvent;
64 class RenderLayer;
65 class RenderObject;
66 class RenderWidget;
67 class Scrollbar;
68 class String;
69 class SVGElementInstance;
70 class TextEvent;
71 class VisiblePosition;
72 class Widget;
73 #if ENABLE(TOUCH_EVENTS) // Android
74 class PlatformTouchEvent;
75 class Touch;
76 #endif
77 
78 struct HitTestRequest;
79 
80 extern const int LinkDragHysteresis;
81 extern const int ImageDragHysteresis;
82 extern const int TextDragHysteresis;
83 extern const int GeneralDragHysteresis;
84 
85 class EventHandler : Noncopyable {
86 public:
87     EventHandler(Frame*);
88     ~EventHandler();
89 
90     void clear();
91 
92     void updateSelectionForMouseDrag();
93 
94     Node* mousePressNode() const;
95     void setMousePressNode(PassRefPtr<Node>);
96 
panScrollInProgress()97     bool panScrollInProgress() { return m_panScrollInProgress; }
setPanScrollInProgress(bool inProgress)98     void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; }
99 
100     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
101     RenderObject* autoscrollRenderer() const;
102     void updateAutoscrollRenderer();
103 
104     HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent);
105 
mousePressed()106     bool mousePressed() const { return m_mousePressed; }
setMousePressed(bool pressed)107     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
108 
109     void setCapturingMouseEventsNode(PassRefPtr<Node>);
110 
111     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
112     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
113     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
114 
115     void scheduleHoverStateUpdate();
116 
117     void setResizingFrameSet(HTMLFrameSetElement*);
118 
119     void resizeLayerDestroyed();
120 
121     IntPoint currentMousePosition() const;
122 
123     void setIgnoreWheelEvents(bool);
124 
125     bool scrollOverflow(ScrollDirection, ScrollGranularity);
126 
127     bool shouldDragAutoNode(Node*, const IntPoint&) const; // -webkit-user-drag == auto
128 
129     bool tabsToLinks(KeyboardEvent*) const;
130     bool tabsToAllControls(KeyboardEvent*) const;
131 
mouseDownMayStartSelect()132     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
133 
134     bool mouseMoved(const PlatformMouseEvent&);
135 
136     bool handleMousePressEvent(const PlatformMouseEvent&);
137     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0);
138     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
139     bool handleWheelEvent(PlatformWheelEvent&);
140 
141 #if ENABLE(TOUCH_EVENTS) // Android
142     bool handleTouchEvent(const PlatformTouchEvent&);
143 #endif
144 
145     bool sendContextMenuEvent(const PlatformMouseEvent&);
146 
setMouseDownMayStartAutoscroll()147     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
148 
149     bool needsKeyboardEventDisambiguationQuirks() const;
150 
151     static unsigned accessKeyModifiers();
152     bool handleAccessKey(const PlatformKeyboardEvent&);
153     bool keyEvent(const PlatformKeyboardEvent&);
154     void defaultKeyboardEventHandler(KeyboardEvent*);
155 
156     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0,
157         bool isLineBreak = false, bool isBackTab = false);
158     void defaultTextInputEventHandler(TextEvent*);
159 
160     bool eventMayStartDrag(const PlatformMouseEvent&) const;
161 
162     void dragSourceMovedTo(const PlatformMouseEvent&);
163     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
164 
165     void focusDocumentView();
166 
167     void capsLockStateMayHaveChanged();
168 
169     unsigned pendingFrameUnloadEventCount();
170     void addPendingFrameUnloadEventCount();
171     void removePendingFrameUnloadEventCount();
172     void clearPendingFrameUnloadEventCount();
173     unsigned pendingFrameBeforeUnloadEventCount();
174     void addPendingFrameBeforeUnloadEventCount();
175     void removePendingFrameBeforeUnloadEventCount();
176     void clearPendingFrameBeforeUnloadEventCount();
177 
178 #if PLATFORM(MAC)
179     PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;
180 
181     void mouseDown(NSEvent*);
182     void mouseDragged(NSEvent*);
183     void mouseUp(NSEvent*);
184     void mouseMoved(NSEvent*);
185     bool keyEvent(NSEvent*);
186     bool wheelEvent(NSEvent*);
187 
188     void sendFakeEventsAfterWidgetTracking(NSEvent* initiatingEvent);
189 
setActivationEventNumber(int num)190     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
191 
192     NSEvent *currentNSEvent();
193 #endif
194 
195 private:
196     struct EventHandlerDragState {
197         RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
198         bool m_dragSrcIsLink;
199         bool m_dragSrcIsImage;
200         bool m_dragSrcInSelection;
201         bool m_dragSrcMayBeDHTML;
202         bool m_dragSrcMayBeUA; // Are DHTML and/or the UserAgent allowed to drag out?
203         bool m_dragSrcIsDHTML;
204         RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
205     };
206     static EventHandlerDragState& dragState();
207     static const double TextDragDelay;
208 
209     PassRefPtr<Clipboard> createDraggingClipboard() const;
210 
211     bool eventActivatedView(const PlatformMouseEvent&) const;
212     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& event);
213     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& event);
214 
215     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
216 
217     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
218     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
219     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
220     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
221     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
222     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
223 
224     void handleKeyboardSelectionMovement(KeyboardEvent*);
225 
226     Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
227     void setPanScrollCursor();
228 
229     void hoverTimerFired(Timer<EventHandler>*);
230 
231     static bool canMouseDownStartSelect(Node*);
232     static bool canMouseDragExtendSelect(Node*);
233 
234     void handleAutoscroll(RenderObject*);
235     void startAutoscrollTimer();
236     void setAutoscrollRenderer(RenderObject*);
237     void autoscrollTimerFired(Timer<EventHandler>*);
238 
239     void invalidateClick();
240 
241     Node* nodeUnderMouse() const;
242 
243     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
244     void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
245 
246     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
247 
248     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
249     bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
250 
251     void freeClipboard();
252 
253     bool handleDrag(const MouseEventWithHitTestResults&);
254     bool handleMouseUp(const MouseEventWithHitTestResults&);
255     void clearDragState();
256 
257     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
258 
259     bool dragHysteresisExceeded(const FloatPoint&) const;
260     bool dragHysteresisExceeded(const IntPoint&) const;
261 
262     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
263     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
264     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
265 
266     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
267 
268     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
269 
270     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
271     bool passWidgetMouseDownEventToWidget(RenderWidget*);
272 
273     bool passMouseDownEventToWidget(Widget*);
274     bool passWheelEventToWidget(PlatformWheelEvent&, Widget*);
275 
276     void defaultSpaceEventHandler(KeyboardEvent*);
277     void defaultTabEventHandler(KeyboardEvent*);
278 
279     void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
280 
281     // The following are called at the beginning of handleMouseUp and handleDrag.
282     // If they return true it indicates that they have consumed the event.
283 #if PLATFORM(MAC)
284     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
285     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
286     NSView *mouseDownViewIfStillGood();
287 #else
eventLoopHandleMouseUp(const MouseEventWithHitTestResults &)288     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) { return false; }
eventLoopHandleMouseDragged(const MouseEventWithHitTestResults &)289     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { return false; }
290 #endif
291 
292     bool invertSenseOfTabsToLinks(KeyboardEvent*) const;
293 
294     void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint);
295 
296     Frame* m_frame;
297 
298     bool m_mousePressed;
299     RefPtr<Node> m_mousePressNode;
300 
301     bool m_mouseDownMayStartSelect;
302     bool m_mouseDownMayStartDrag;
303     bool m_mouseDownWasSingleClickInSelection;
304     bool m_beganSelectingText;
305 
306     IntPoint m_dragStartPos;
307 
308     IntPoint m_panScrollStartPos;
309     bool m_panScrollInProgress;
310 
311     Timer<EventHandler> m_hoverTimer;
312 
313     Timer<EventHandler> m_autoscrollTimer;
314     RenderObject* m_autoscrollRenderer;
315     bool m_autoscrollInProgress;
316     bool m_mouseDownMayStartAutoscroll;
317     bool m_mouseDownWasInSubframe;
318 #if ENABLE(SVG)
319     bool m_svgPan;
320     RefPtr<SVGElementInstance> m_instanceUnderMouse;
321     RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
322 #endif
323 
324     RenderLayer* m_resizeLayer;
325 
326     RefPtr<Node> m_capturingMouseEventsNode;
327 
328     RefPtr<Node> m_nodeUnderMouse;
329     RefPtr<Node> m_lastNodeUnderMouse;
330     RefPtr<Frame> m_lastMouseMoveEventSubframe;
331     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
332 
333     int m_clickCount;
334     RefPtr<Node> m_clickNode;
335 #if ENABLE(TOUCH_EVENTS) // Android
336     RefPtr<Touch> m_touch;
337 #endif
338 
339     RefPtr<Node> m_dragTarget;
340 
341     RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
342 
343     IntSize m_offsetFromResizeCorner;   // in the coords of m_resizeLayer
344 
345     IntPoint m_currentMousePosition;
346     IntPoint m_mouseDownPos; // in our view's coords
347     double m_mouseDownTimestamp;
348     PlatformMouseEvent m_mouseDown;
349 
350     unsigned m_pendingFrameUnloadEventCount;
351     unsigned m_pendingFrameBeforeUnloadEventCount;
352 
353 #if PLATFORM(MAC)
354     NSView *m_mouseDownView;
355     bool m_sendingEventToSubview;
356     int m_activationEventNumber;
357 #endif
358 
359 };
360 
361 } // namespace WebCore
362 
363 #endif // EventHandler_h
364