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