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 "core/dom/TextEventInputType.h" 30 #include "core/dom/UserGestureIndicator.h" 31 #include "core/editing/TextGranularity.h" 32 #include "core/page/DragActions.h" 33 #include "core/page/FocusDirection.h" 34 #include "core/platform/Cursor.h" 35 #include "core/platform/PlatformMouseEvent.h" 36 #include "core/platform/ScrollTypes.h" 37 #include "core/platform/Timer.h" 38 #include "core/platform/graphics/LayoutPoint.h" 39 #include "core/rendering/HitTestRequest.h" 40 #include "wtf/Forward.h" 41 #include "wtf/HashMap.h" 42 #include "wtf/RefPtr.h" 43 44 namespace WebCore { 45 46 class Clipboard; 47 class Document; 48 class Element; 49 class Event; 50 class EventTarget; 51 class FloatPoint; 52 class FloatQuad; 53 class FullscreenElementStack; 54 class Frame; 55 class HTMLFrameSetElement; 56 class HitTestRequest; 57 class HitTestResult; 58 class KeyboardEvent; 59 class MouseEventWithHitTestResults; 60 class Node; 61 class OptionalCursor; 62 class PlatformGestureEvent; 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 VisibleSelection; 74 class WheelEvent; 75 class Widget; 76 77 struct DragState; 78 79 extern const int LinkDragHysteresis; 80 extern const int ImageDragHysteresis; 81 extern const int TextDragHysteresis; 82 extern const int GeneralDragHysteresis; 83 84 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace }; 85 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis }; 86 87 class EventHandler { 88 WTF_MAKE_NONCOPYABLE(EventHandler); 89 public: 90 explicit EventHandler(Frame*); 91 ~EventHandler(); 92 93 void clear(); 94 void nodeWillBeRemoved(Node*); 95 96 void updateSelectionForMouseDrag(); 97 98 Node* mousePressNode() const; 99 void setMousePressNode(PassRefPtr<Node>); 100 101 #if OS(WINDOWS) 102 void startPanScrolling(RenderObject*); 103 #endif 104 105 void stopAutoscrollTimer(); 106 bool mouseDownWasInSubframe() const { return m_mouseDownWasInSubframe; } 107 108 void dispatchFakeMouseMoveEventSoon(); 109 void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&); 110 111 HitTestResult hitTestResultAtPoint(const LayoutPoint&, 112 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active, 113 const LayoutSize& padding = LayoutSize()); 114 115 bool mousePressed() const { return m_mousePressed; } 116 void setMousePressed(bool pressed) { m_mousePressed = pressed; } 117 118 void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0. 119 120 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*); 121 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*); 122 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*); 123 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement); 124 125 void scheduleHoverStateUpdate(); 126 127 void setResizingFrameSet(HTMLFrameSetElement*); 128 129 void resizeLayerDestroyed(); 130 131 IntPoint lastKnownMousePosition() const; 132 Cursor currentMouseCursor() const { return m_currentMouseCursor; } 133 134 static Frame* subframeForTargetNode(Node*); 135 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&); 136 137 bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0); 138 bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0); 139 bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0); 140 141 bool mouseMoved(const PlatformMouseEvent&); 142 143 void lostMouseCapture(); 144 145 bool handleMousePressEvent(const PlatformMouseEvent&); 146 bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false); 147 bool handleMouseReleaseEvent(const PlatformMouseEvent&); 148 bool handleWheelEvent(const PlatformWheelEvent&); 149 void defaultWheelEventHandler(Node*, WheelEvent*); 150 bool handlePasteGlobalSelection(const PlatformMouseEvent&); 151 152 bool handleGestureEvent(const PlatformGestureEvent&); 153 bool handleGestureTap(const PlatformGestureEvent&); 154 bool handleGestureLongPress(const PlatformGestureEvent&); 155 bool handleGestureLongTap(const PlatformGestureEvent&); 156 bool handleGestureTwoFingerTap(const PlatformGestureEvent&); 157 bool handleGestureScrollUpdate(const PlatformGestureEvent&); 158 bool handleGestureScrollBegin(const PlatformGestureEvent&); 159 bool handleGestureScrollEnd(const PlatformGestureEvent&); 160 void clearGestureScrollNodes(); 161 bool isScrollbarHandlingGestures() const; 162 163 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const; 164 165 bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode); 166 bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode); 167 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode); 168 169 bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint); 170 171 bool sendContextMenuEvent(const PlatformMouseEvent&); 172 bool sendContextMenuEventForKey(); 173 bool sendContextMenuEventForGesture(const PlatformGestureEvent&); 174 175 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; } 176 177 static unsigned accessKeyModifiers(); 178 bool handleAccessKey(const PlatformKeyboardEvent&); 179 bool keyEvent(const PlatformKeyboardEvent&); 180 void defaultKeyboardEventHandler(KeyboardEvent*); 181 182 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard); 183 void defaultTextInputEventHandler(TextEvent*); 184 185 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation); 186 187 void focusDocumentView(); 188 189 void capsLockStateMayHaveChanged(); // Only called by FrameSelection 190 191 void sendResizeEvent(); // Only called in FrameView 192 void sendScrollEvent(); // Ditto 193 194 bool handleTouchEvent(const PlatformTouchEvent&); 195 196 bool useHandCursor(Node*, bool isOverLink, bool shiftKey); 197 198 private: 199 static DragState& dragState(); 200 static const double TextDragDelay; 201 202 PassRefPtr<Clipboard> createDraggingClipboard() const; 203 204 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity); 205 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace); 206 void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace); 207 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&); 208 void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&); 209 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&); 210 211 bool handleMousePressEvent(const MouseEventWithHitTestResults&); 212 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&); 213 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&); 214 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&); 215 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&); 216 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&); 217 218 OptionalCursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*); 219 void hoverTimerFired(Timer<EventHandler>*); 220 221 bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0); 222 223 bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const; 224 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; } 225 226 static bool isKeyboardOptionTab(KeyboardEvent*); 227 228 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*); 229 void cancelFakeMouseMoveEvent(); 230 bool isCursorVisible() const; 231 232 bool isInsideScrollbar(const IntPoint&) const; 233 234 bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&); 235 HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent); 236 237 void invalidateClick(); 238 239 Node* nodeUnderMouse() const; 240 241 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut); 242 void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true); 243 244 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&); 245 246 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder); 247 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*); 248 249 void freeClipboard(); 250 251 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis); 252 bool tryStartDrag(const MouseEventWithHitTestResults&); 253 bool handleMouseUp(const MouseEventWithHitTestResults&); 254 void clearDragState(); 255 256 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&); 257 258 bool dragHysteresisExceeded(const FloatPoint&) const; 259 bool dragHysteresisExceeded(const IntPoint&) const; 260 261 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe); 262 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0); 263 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe); 264 265 bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0); 266 267 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*); 268 269 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&); 270 271 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*); 272 273 void defaultSpaceEventHandler(KeyboardEvent*); 274 void defaultBackspaceEventHandler(KeyboardEvent*); 275 void defaultTabEventHandler(KeyboardEvent*); 276 void defaultArrowEventHandler(FocusDirection, KeyboardEvent*); 277 278 DragSourceAction updateDragSourceActionsAllowed() const; 279 280 void updateSelectionForMouseDrag(const HitTestResult&); 281 282 void updateLastScrollbarUnderMouse(Scrollbar*, bool); 283 284 void setFrameWasScrolledByUser(); 285 286 bool capturesDragging() const { return m_capturesDragging; } 287 288 bool isKeyEventAllowedInFullScreen(FullscreenElementStack*, const PlatformKeyboardEvent&) const; 289 290 bool handleGestureTapDown(); 291 292 bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&); 293 294 bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*); 295 bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*); 296 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&); 297 Frame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&); 298 299 bool panScrollInProgress() const; 300 void setLastKnownMousePosition(const PlatformMouseEvent&); 301 302 Frame* const m_frame; 303 304 bool m_mousePressed; 305 bool m_capturesDragging; 306 RefPtr<Node> m_mousePressNode; 307 308 bool m_mouseDownMayStartSelect; 309 bool m_mouseDownMayStartDrag; 310 bool m_dragMayStartSelectionInstead; 311 bool m_mouseDownWasSingleClickInSelection; 312 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection }; 313 SelectionInitiationState m_selectionInitiationState; 314 315 LayoutPoint m_dragStartPos; 316 317 bool m_panScrollButtonPressed; 318 319 Timer<EventHandler> m_hoverTimer; 320 321 bool m_mouseDownMayStartAutoscroll; 322 bool m_mouseDownWasInSubframe; 323 324 Timer<EventHandler> m_fakeMouseMoveEventTimer; 325 326 bool m_svgPan; 327 RefPtr<SVGElementInstance> m_instanceUnderMouse; 328 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse; 329 330 RenderLayer* m_resizeLayer; 331 332 RefPtr<Node> m_capturingMouseEventsNode; 333 bool m_eventHandlerWillResetCapturingMouseEventsNode; 334 335 RefPtr<Node> m_nodeUnderMouse; 336 RefPtr<Node> m_lastNodeUnderMouse; 337 RefPtr<Frame> m_lastMouseMoveEventSubframe; 338 RefPtr<Scrollbar> m_lastScrollbarUnderMouse; 339 Cursor m_currentMouseCursor; 340 341 int m_clickCount; 342 RefPtr<Node> m_clickNode; 343 344 RefPtr<Node> m_dragTarget; 345 bool m_shouldOnlyFireDragOverEvent; 346 347 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized; 348 349 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer. 350 351 bool m_mousePositionIsUnknown; 352 IntPoint m_lastKnownMousePosition; 353 IntPoint m_lastKnownMouseGlobalPosition; 354 IntPoint m_mouseDownPos; // In our view's coords. 355 double m_mouseDownTimestamp; 356 PlatformMouseEvent m_mouseDown; 357 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken; 358 359 RefPtr<Node> m_latchedWheelEventNode; 360 bool m_widgetIsLatched; 361 362 RefPtr<Node> m_previousWheelScrolledNode; 363 364 typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap; 365 TouchTargetMap m_originatingTouchPointTargets; 366 RefPtr<Document> m_originatingTouchPointDocument; 367 unsigned m_originatingTouchPointTargetKey; 368 bool m_touchPressed; 369 370 RefPtr<Node> m_scrollGestureHandlingNode; 371 bool m_lastHitTestResultOverWidget; 372 RefPtr<Node> m_previousGestureScrolledNode; 373 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture; 374 375 double m_maxMouseMovedDuration; 376 PlatformEvent::Type m_baseEventType; 377 bool m_didStartDrag; 378 379 bool m_longTapShouldInvokeContextMenu; 380 }; 381 382 } // namespace WebCore 383 384 #endif // EventHandler_h 385