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