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