Reverting r142861. Hit testing inside of style recalc is fundamentally wrong
[WebKit-https.git] / Source / WebCore / page / EventHandler.h
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 "Cursor.h"
30 #include "DragActions.h"
31 #include "DragState.h"
32 #include "FocusDirection.h"
33 #include "HitTestRequest.h"
34 #include "PlatformMouseEvent.h"
35 #include "PlatformWheelEvent.h"
36 #include "ScrollTypes.h"
37 #include "TextEventInputType.h"
38 #include "TextGranularity.h"
39 #include "Timer.h"
40 #include "UserGestureIndicator.h"
41 #include <wtf/Forward.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/RefPtr.h>
44
45 #if PLATFORM(MAC) && !defined(__OBJC__)
46 class NSView;
47 #endif
48
49 #if ENABLE(TOUCH_EVENTS)
50 #include <wtf/HashMap.h>
51 #endif
52
53 namespace WebCore {
54
55 class AutoscrollController;
56 class Clipboard;
57 class Event;
58 class EventTarget;
59 class FloatPoint;
60 class FloatQuad;
61 class Frame;
62 class HTMLFrameSetElement;
63 class HitTestRequest;
64 class HitTestResult;
65 class KeyboardEvent;
66 class MouseEventWithHitTestResults;
67 class Node;
68 class OptionalCursor;
69 class PlatformKeyboardEvent;
70 class PlatformTouchEvent;
71 class PlatformWheelEvent;
72 class RenderLayer;
73 class RenderObject;
74 class RenderWidget;
75 class SVGElementInstance;
76 class Scrollbar;
77 class TextEvent;
78 class TouchEvent;
79 class VisibleSelection;
80 class WheelEvent;
81 class Widget;
82
83 #if ENABLE(GESTURE_EVENTS)
84 class PlatformGestureEvent;
85 #endif
86
87 #if ENABLE(DRAG_SUPPORT)
88 extern const int LinkDragHysteresis;
89 extern const int ImageDragHysteresis;
90 extern const int TextDragHysteresis;
91 extern const int GeneralDragHysteresis;
92 #endif // ENABLE(DRAG_SUPPORT)
93
94 enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
95 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
96 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
97
98 class EventHandler {
99     WTF_MAKE_NONCOPYABLE(EventHandler);
100 public:
101     explicit EventHandler(Frame*);
102     ~EventHandler();
103
104     void clear();
105     void nodeWillBeRemoved(Node*);
106
107 #if ENABLE(DRAG_SUPPORT)
108     void updateSelectionForMouseDrag();
109 #endif
110
111     Node* mousePressNode() const;
112     void setMousePressNode(PassRefPtr<Node>);
113
114 #if ENABLE(PAN_SCROLLING)
115     void didPanScrollStart();
116     void didPanScrollStop();
117     void startPanScrolling(RenderObject*);
118 #endif
119
120     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
121     RenderObject* autoscrollRenderer() const;
122     void updateAutoscrollRenderer();
123     bool autoscrollInProgress() const;
124     bool mouseDownWasInSubframe() const { return m_mouseDownWasInSubframe; }
125     bool panScrollInProgress() const;
126
127     void dispatchFakeMouseMoveEventSoon();
128     void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
129
130     HitTestResult hitTestResultAtPoint(const LayoutPoint&, bool allowShadowContent, bool ignoreClipping = false,
131                                        HitTestScrollbars scrollbars = DontHitTestScrollbars,
132                                        HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
133                                        const LayoutSize& padding = LayoutSize());
134
135     bool mousePressed() const { return m_mousePressed; }
136     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
137
138     void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
139
140 #if ENABLE(DRAG_SUPPORT)
141     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
142     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
143     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
144     void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
145 #endif
146
147     void scheduleHoverStateUpdate();
148
149     void setResizingFrameSet(HTMLFrameSetElement*);
150
151     void resizeLayerDestroyed();
152
153     IntPoint lastKnownMousePosition() const;
154     Cursor currentMouseCursor() const { return m_currentMouseCursor; }
155
156     static Frame* subframeForTargetNode(Node*);
157     static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
158
159     bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
160     bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
161     bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
162
163     bool tabsToLinks(KeyboardEvent*) const;
164     bool tabsToAllFormControls(KeyboardEvent*) const;
165
166     bool mouseMoved(const PlatformMouseEvent&);
167     bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
168
169     void lostMouseCapture();
170
171     bool handleMousePressEvent(const PlatformMouseEvent&);
172     bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
173     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
174     bool handleWheelEvent(const PlatformWheelEvent&);
175     void defaultWheelEventHandler(Node*, WheelEvent*);
176     bool handlePasteGlobalSelection(const PlatformMouseEvent&);
177
178 #if ENABLE(GESTURE_EVENTS)
179     bool handleGestureEvent(const PlatformGestureEvent&);
180     bool handleGestureTap(const PlatformGestureEvent&);
181     bool handleGestureLongPress(const PlatformGestureEvent&);
182     bool handleGestureLongTap(const PlatformGestureEvent&);
183     bool handleGestureTwoFingerTap(const PlatformGestureEvent&);
184     bool handleGestureScrollUpdate(const PlatformGestureEvent&);
185     bool handleGestureScrollBegin(const PlatformGestureEvent&);
186     bool isScrollbarHandlingGestures() const;
187 #endif
188
189 #if ENABLE(TOUCH_ADJUSTMENT)
190     bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
191
192     bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
193     bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
194     bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
195
196     bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
197 #endif
198
199 #if ENABLE(CONTEXT_MENUS)
200     bool sendContextMenuEvent(const PlatformMouseEvent&);
201     bool sendContextMenuEventForKey();
202 #if ENABLE(GESTURE_EVENTS)
203     bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
204 #endif
205 #endif
206
207     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
208
209     bool needsKeyboardEventDisambiguationQuirks() const;
210
211     static unsigned accessKeyModifiers();
212     bool handleAccessKey(const PlatformKeyboardEvent&);
213     bool keyEvent(const PlatformKeyboardEvent&);
214     void defaultKeyboardEventHandler(KeyboardEvent*);
215
216     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
217     void defaultTextInputEventHandler(TextEvent*);
218
219 #if ENABLE(DRAG_SUPPORT)
220     bool eventMayStartDrag(const PlatformMouseEvent&) const;
221     
222     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
223 #endif
224
225     void focusDocumentView();
226
227     void capsLockStateMayHaveChanged(); // Only called by FrameSelection
228     
229     void sendResizeEvent(); // Only called in FrameView
230     void sendScrollEvent(); // Ditto
231
232 #if PLATFORM(MAC) && defined(__OBJC__)
233     void mouseDown(NSEvent *);
234     void mouseDragged(NSEvent *);
235     void mouseUp(NSEvent *);
236     void mouseMoved(NSEvent *);
237     bool keyEvent(NSEvent *);
238     bool wheelEvent(NSEvent *);
239
240     void passMouseMovedEventToScrollbars(NSEvent *);
241
242     void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
243
244     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
245
246     static NSEvent *currentNSEvent();
247 #endif
248
249 #if ENABLE(TOUCH_EVENTS)
250     bool handleTouchEvent(const PlatformTouchEvent&);
251 #endif
252
253     bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
254
255 private:
256 #if ENABLE(DRAG_SUPPORT)
257     static DragState& dragState();
258     static const double TextDragDelay;
259     
260     PassRefPtr<Clipboard> createDraggingClipboard() const;
261 #endif // ENABLE(DRAG_SUPPORT)
262
263     bool eventActivatedView(const PlatformMouseEvent&) const;
264     bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
265     void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
266     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
267     void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
268
269     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
270
271     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
272     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
273     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
274     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
275 #if ENABLE(DRAG_SUPPORT)
276     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
277 #endif
278     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
279
280     OptionalCursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
281     void hoverTimerFired(Timer<EventHandler>*);
282
283     bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
284     
285     bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
286     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
287
288     static bool isKeyboardOptionTab(KeyboardEvent*);
289     static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
290
291     void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
292     void cancelFakeMouseMoveEvent();
293
294     bool isInsideScrollbar(const IntPoint&) const;
295
296 #if ENABLE(TOUCH_EVENTS)
297     bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
298     HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
299 #endif
300
301     void invalidateClick();
302
303     Node* nodeUnderMouse() const;
304     
305     void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
306     void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
307     
308     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
309
310     bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
311 #if ENABLE(DRAG_SUPPORT)
312     bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
313
314     void freeClipboard();
315
316     bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
317 #endif
318     bool handleMouseUp(const MouseEventWithHitTestResults&);
319 #if ENABLE(DRAG_SUPPORT)
320     void clearDragState();
321
322     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
323
324     bool dragHysteresisExceeded(const FloatPoint&) const;
325     bool dragHysteresisExceeded(const IntPoint&) const;
326 #endif // ENABLE(DRAG_SUPPORT)
327
328     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
329     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
330     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
331
332     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
333
334     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
335
336     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
337     bool passWidgetMouseDownEventToWidget(RenderWidget*);
338
339     bool passMouseDownEventToWidget(Widget*);
340     bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
341
342     void defaultSpaceEventHandler(KeyboardEvent*);
343     void defaultBackspaceEventHandler(KeyboardEvent*);
344     void defaultTabEventHandler(KeyboardEvent*);
345     void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
346
347 #if ENABLE(DRAG_SUPPORT)
348     DragSourceAction updateDragSourceActionsAllowed() const;
349 #endif
350
351     // The following are called at the beginning of handleMouseUp and handleDrag.  
352     // If they return true it indicates that they have consumed the event.
353     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
354 #if ENABLE(DRAG_SUPPORT)
355     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
356 #endif
357
358 #if ENABLE(DRAG_SUPPORT)
359     void updateSelectionForMouseDrag(const HitTestResult&);
360 #endif
361
362     void updateLastScrollbarUnderMouse(Scrollbar*, bool);
363     
364     void setFrameWasScrolledByUser();
365
366     bool capturesDragging() const { return m_capturesDragging; }
367
368 #if PLATFORM(MAC) && defined(__OBJC__)
369     NSView *mouseDownViewIfStillGood();
370
371     PlatformMouseEvent currentPlatformMouseEvent() const;
372 #endif
373
374 #if ENABLE(FULLSCREEN_API)
375     bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
376 #endif
377
378 #if ENABLE(GESTURE_EVENTS)
379     bool handleGestureTapDown();
380     bool handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent&);
381     bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
382     bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
383 #endif
384
385     void setLastKnownMousePosition(const PlatformMouseEvent&);
386
387     Frame* m_frame;
388
389     bool m_mousePressed;
390     bool m_capturesDragging;
391     RefPtr<Node> m_mousePressNode;
392
393     bool m_mouseDownMayStartSelect;
394 #if ENABLE(DRAG_SUPPORT)
395     bool m_mouseDownMayStartDrag;
396     bool m_dragMayStartSelectionInstead;
397 #endif
398     bool m_mouseDownWasSingleClickInSelection;
399     enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
400     SelectionInitiationState m_selectionInitiationState;
401
402 #if ENABLE(DRAG_SUPPORT)
403     LayoutPoint m_dragStartPos;
404 #endif
405
406     bool m_panScrollButtonPressed;
407
408     Timer<EventHandler> m_hoverTimer;
409
410     OwnPtr<AutoscrollController> m_autoscrollController;
411     bool m_mouseDownMayStartAutoscroll;
412     bool m_mouseDownWasInSubframe;
413
414     Timer<EventHandler> m_fakeMouseMoveEventTimer;
415
416 #if ENABLE(SVG)
417     bool m_svgPan;
418     RefPtr<SVGElementInstance> m_instanceUnderMouse;
419     RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
420 #endif
421
422     RenderLayer* m_resizeLayer;
423
424     RefPtr<Node> m_capturingMouseEventsNode;
425     bool m_eventHandlerWillResetCapturingMouseEventsNode;
426     
427     RefPtr<Node> m_nodeUnderMouse;
428     RefPtr<Node> m_lastNodeUnderMouse;
429     RefPtr<Frame> m_lastMouseMoveEventSubframe;
430     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
431     Cursor m_currentMouseCursor;
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     LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
444     
445     bool m_mousePositionIsUnknown;
446     IntPoint m_lastKnownMousePosition;
447     IntPoint m_lastKnownMouseGlobalPosition;
448     IntPoint m_mouseDownPos; // In our view's coords.
449     double m_mouseDownTimestamp;
450     PlatformMouseEvent m_mouseDown;
451     RefPtr<UserGestureIndicator::Token> m_lastMouseDownUserGestureToken;
452
453     RefPtr<Node> m_latchedWheelEventNode;
454     bool m_widgetIsLatched;
455
456     RefPtr<Node> m_previousWheelScrolledNode;
457
458 #if PLATFORM(MAC)
459     NSView *m_mouseDownView;
460     bool m_sendingEventToSubview;
461     int m_activationEventNumber;
462 #endif
463 #if ENABLE(TOUCH_EVENTS)
464     typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
465     TouchTargetMap m_originatingTouchPointTargets;
466     RefPtr<Document> m_originatingTouchPointDocument;
467     unsigned m_originatingTouchPointTargetKey;
468     bool m_touchPressed;
469 #endif
470
471 #if ENABLE(GESTURE_EVENTS)
472     RefPtr<Node> m_scrollGestureHandlingNode;
473     bool m_lastHitTestResultOverWidget;
474     RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
475 #endif
476
477     double m_maxMouseMovedDuration;
478     PlatformEvent::Type m_baseEventType;
479     bool m_didStartDrag;
480     bool m_didLongPressInvokeContextMenu;
481 };
482
483 } // namespace WebCore
484
485 #endif // EventHandler_h