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