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/EventWithHitTestResults.h" 33 #include "core/page/FocusType.h" 34 #include "core/rendering/HitTestRequest.h" 35 #include "core/rendering/style/RenderStyleConstants.h" 36 #include "platform/Cursor.h" 37 #include "platform/PlatformMouseEvent.h" 38 #include "platform/Timer.h" 39 #include "platform/UserGestureIndicator.h" 40 #include "platform/geometry/LayoutPoint.h" 41 #include "platform/heap/Handle.h" 42 #include "platform/scroll/ScrollTypes.h" 43 #include "wtf/Forward.h" 44 #include "wtf/HashMap.h" 45 #include "wtf/HashTraits.h" 46 #include "wtf/RefPtr.h" 47 48 namespace blink { 49 50 class AutoscrollController; 51 class DataTransfer; 52 class Document; 53 class DragState; 54 class Element; 55 class Event; 56 class EventTarget; 57 template <typename EventType> 58 class EventWithHitTestResults; 59 class FloatPoint; 60 class FloatQuad; 61 class Fullscreen; 62 class HTMLFrameSetElement; 63 class HitTestRequest; 64 class HitTestResult; 65 class KeyboardEvent; 66 class LocalFrame; 67 class Node; 68 class OptionalCursor; 69 class PlatformGestureEvent; 70 class PlatformKeyboardEvent; 71 class PlatformTouchEvent; 72 class PlatformWheelEvent; 73 class RenderLayer; 74 class RenderLayerScrollableArea; 75 class RenderObject; 76 class ScrollableArea; 77 class Scrollbar; 78 class TextEvent; 79 class VisibleSelection; 80 class WheelEvent; 81 class Widget; 82 83 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace }; 84 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis }; 85 86 class EventHandler : public NoBaseWillBeGarbageCollectedFinalized<EventHandler> { 87 WTF_MAKE_NONCOPYABLE(EventHandler); 88 public: 89 explicit EventHandler(LocalFrame*); 90 ~EventHandler(); 91 void trace(Visitor*); 92 93 void clear(); 94 void nodeWillBeRemoved(Node&); 95 96 void updateSelectionForMouseDrag(); 97 98 Node* mousePressNode() const; 99 100 #if OS(WIN) 101 void startPanScrolling(RenderObject*); 102 #endif 103 104 void stopAutoscroll(); 105 106 void dispatchFakeMouseMoveEventSoon(); 107 void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&); 108 109 HitTestResult hitTestResultAtPoint(const LayoutPoint&, 110 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active, 111 const LayoutSize& padding = LayoutSize()); 112 113 bool mousePressed() const { return m_mousePressed; } 114 void setMousePressed(bool pressed) { m_mousePressed = pressed; } 115 116 void setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node>); // A caller is responsible for resetting capturing node to 0. 117 118 bool updateDragAndDrop(const PlatformMouseEvent&, DataTransfer*); 119 void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*); 120 bool performDragAndDrop(const PlatformMouseEvent&, DataTransfer*); 121 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement); 122 123 void scheduleHoverStateUpdate(); 124 void scheduleCursorUpdate(); 125 126 void setResizingFrameSet(HTMLFrameSetElement*); 127 128 void resizeScrollableAreaDestroyed(); 129 130 IntPoint lastKnownMousePosition() const; 131 Cursor currentMouseCursor() const { return m_currentMouseCursor; } 132 133 // Attempts to scroll the DOM tree. If that fails, scrolls the view. 134 // If the view can't be scrolled either, recursively bubble to the parent frame. 135 bool bubblingScroll(ScrollDirection, ScrollGranularity, Node* startingNode = 0); 136 137 bool handleMouseMoveEvent(const PlatformMouseEvent&); 138 void handleMouseLeaveEvent(const PlatformMouseEvent&); 139 140 bool handleMousePressEvent(const PlatformMouseEvent&); 141 bool handleMouseReleaseEvent(const PlatformMouseEvent&); 142 bool handleWheelEvent(const PlatformWheelEvent&); 143 void defaultWheelEventHandler(Node*, WheelEvent*); 144 145 // Called on the local root frame exactly once per gesture event. 146 bool handleGestureEvent(const PlatformGestureEvent&); 147 bool handleGestureEvent(const GestureEventWithHitTestResults&); 148 149 // Hit-test the provided (non-scroll) gesture event, applying touch-adjustment and updating 150 // hover/active state across all frames if necessary. This should be called at most once 151 // per gesture event, and called on the local root frame. 152 // Note: This is similar to (the less clearly named) prepareMouseEvent. 153 // FIXME: Remove readOnly param when there is only ever a single call to this. 154 GestureEventWithHitTestResults targetGestureEvent(const PlatformGestureEvent&, bool readOnly = false); 155 156 // Handle the provided non-scroll gesture event. Should be called only on the inner frame. 157 bool handleGestureEventInFrame(const GestureEventWithHitTestResults&); 158 159 // Handle the provided scroll gesture event, propagating down to child frames as necessary. 160 bool handleGestureScrollEvent(const PlatformGestureEvent&); 161 bool handleGestureScrollEnd(const PlatformGestureEvent&); 162 bool isScrollbarHandlingGestures() const; 163 164 bool bestClickableNodeForHitTestResult(const HitTestResult&, IntPoint& targetPoint, Node*& targetNode); 165 bool bestContextMenuNodeForHitTestResult(const HitTestResult&, IntPoint& targetPoint, Node*& targetNode); 166 // FIXME: This doesn't appear to be used outside tests anymore, what path are we using now and is it tested? 167 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode); 168 169 bool sendContextMenuEvent(const PlatformMouseEvent&); 170 bool sendContextMenuEventForKey(); 171 bool sendContextMenuEventForGesture(const GestureEventWithHitTestResults&); 172 173 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; } 174 175 static unsigned accessKeyModifiers(); 176 bool handleAccessKey(const PlatformKeyboardEvent&); 177 bool keyEvent(const PlatformKeyboardEvent&); 178 void defaultKeyboardEventHandler(KeyboardEvent*); 179 180 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard); 181 void defaultTextInputEventHandler(TextEvent*); 182 183 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation); 184 185 void focusDocumentView(); 186 187 void capsLockStateMayHaveChanged(); // Only called by FrameSelection 188 189 bool handleTouchEvent(const PlatformTouchEvent&); 190 191 bool useHandCursor(Node*, bool isOverLink); 192 193 void notifyElementActivated(); 194 void notifySelectionChanged(); 195 196 PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken.release(); } 197 198 int clickCount() { return m_clickCount; } 199 bool mouseDownWasSingleClickInSelection() { return m_mouseDownWasSingleClickInSelection; } 200 201 private: 202 static DragState& dragState(); 203 204 PassRefPtrWillBeRawPtr<DataTransfer> createDraggingDataTransfer() const; 205 206 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity); 207 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace); 208 void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace); 209 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&); 210 void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&); 211 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&); 212 213 bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false); 214 bool handleMousePressEvent(const MouseEventWithHitTestResults&); 215 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&); 216 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&); 217 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&); 218 bool handleMouseFocus(const PlatformMouseEvent&); 219 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&); 220 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&); 221 222 bool handlePasteGlobalSelection(const PlatformMouseEvent&); 223 224 HitTestRequest::HitTestRequestType getHitTypeForGestureType(PlatformEvent::Type); 225 void applyTouchAdjustment(PlatformGestureEvent*, HitTestResult*); 226 bool handleGestureTap(const GestureEventWithHitTestResults&); 227 bool handleGestureLongPress(const GestureEventWithHitTestResults&); 228 bool handleGestureLongTap(const GestureEventWithHitTestResults&); 229 bool handleGestureScrollUpdate(const PlatformGestureEvent&); 230 bool handleGestureScrollBegin(const PlatformGestureEvent&); 231 void clearGestureScrollNodes(); 232 233 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const; 234 235 OptionalCursor selectCursor(const HitTestResult&); 236 OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam); 237 238 void hoverTimerFired(Timer<EventHandler>*); 239 void cursorUpdateTimerFired(Timer<EventHandler>*); 240 void activeIntervalTimerFired(Timer<EventHandler>*); 241 242 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; } 243 244 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*); 245 void cancelFakeMouseMoveEvent(); 246 bool isCursorVisible() const; 247 void updateCursor(); 248 249 bool isInsideScrollbar(const IntPoint&) const; 250 251 ScrollableArea* associatedScrollableArea(const RenderLayer*) const; 252 253 // Scrolls the elements of the DOM tree. Returns true if a node was scrolled. 254 // False if we reached the root and couldn't scroll anything. 255 // direction - The direction to scroll in. If this is a logicl direction, it will be 256 // converted to the physical direction based on a node's writing mode. 257 // granularity - The units that the scroll delta parameter is in. 258 // startNode - The node to start bubbling the scroll from. If a node can't scroll, 259 // the scroll bubbles up to the containing block. 260 // stopNode - On input, if provided and non-null, the node at which we should stop bubbling on input. 261 // On output, if provided and a node was scrolled stopNode will point to that node. 262 // delta - The delta to scroll by, in the units of the granularity parameter. (e.g. pixels, lines, pages, etc.) 263 // absolutePoint - For wheel scrolls - the location, in absolute coordinates, where the event occured. 264 bool scroll(ScrollDirection, ScrollGranularity, Node* startNode = 0, Node** stopNode = 0, float delta = 1.0f, IntPoint absolutePoint = IntPoint()); 265 266 TouchAction intersectTouchAction(const TouchAction, const TouchAction); 267 TouchAction computeEffectiveTouchAction(const Node&); 268 269 HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active); 270 271 void invalidateClick(); 272 273 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut); 274 275 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&); 276 277 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, int clickCount, const PlatformMouseEvent&, bool setUnder); 278 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, DataTransfer*); 279 280 void clearDragDataTransfer(); 281 282 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis); 283 bool tryStartDrag(const MouseEventWithHitTestResults&); 284 void clearDragState(); 285 286 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&); 287 288 bool dragHysteresisExceeded(const FloatPoint&) const; 289 bool dragHysteresisExceeded(const IntPoint&) const; 290 291 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe); 292 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0); 293 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe); 294 295 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&); 296 297 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&); 298 299 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*); 300 void defaultSpaceEventHandler(KeyboardEvent*); 301 void defaultBackspaceEventHandler(KeyboardEvent*); 302 void defaultTabEventHandler(KeyboardEvent*); 303 void defaultEscapeEventHandler(KeyboardEvent*); 304 void defaultArrowEventHandler(FocusType, KeyboardEvent*); 305 306 void updateSelectionForMouseDrag(const HitTestResult&); 307 308 void updateLastScrollbarUnderMouse(Scrollbar*, bool); 309 310 void setFrameWasScrolledByUser(); 311 312 bool capturesDragging() const { return m_capturesDragging; } 313 314 bool isKeyEventAllowedInFullScreen(Fullscreen*, const PlatformKeyboardEvent&) const; 315 316 bool handleGestureShowPress(); 317 318 bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&); 319 320 bool passScrollGestureEventToWidget(const PlatformGestureEvent&, RenderObject*); 321 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&); 322 323 AutoscrollController* autoscrollController() const; 324 bool panScrollInProgress() const; 325 void setLastKnownMousePosition(const PlatformMouseEvent&); 326 327 LocalFrame* const m_frame; 328 329 bool m_mousePressed; 330 bool m_capturesDragging; 331 RefPtrWillBeMember<Node> m_mousePressNode; 332 333 bool m_mouseDownMayStartSelect; 334 bool m_mouseDownMayStartDrag; 335 bool m_mouseDownWasSingleClickInSelection; 336 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection }; 337 SelectionInitiationState m_selectionInitiationState; 338 339 LayoutPoint m_dragStartPos; 340 341 Timer<EventHandler> m_hoverTimer; 342 Timer<EventHandler> m_cursorUpdateTimer; 343 344 bool m_mouseDownMayStartAutoscroll; 345 bool m_mouseDownWasInSubframe; 346 347 Timer<EventHandler> m_fakeMouseMoveEventTimer; 348 349 bool m_svgPan; 350 351 RenderLayerScrollableArea* m_resizeScrollableArea; 352 353 RefPtrWillBeMember<Node> m_capturingMouseEventsNode; 354 bool m_eventHandlerWillResetCapturingMouseEventsNode; 355 356 RefPtrWillBeMember<Node> m_nodeUnderMouse; 357 RefPtrWillBeMember<Node> m_lastNodeUnderMouse; 358 RefPtrWillBeMember<LocalFrame> m_lastMouseMoveEventSubframe; 359 RefPtr<Scrollbar> m_lastScrollbarUnderMouse; 360 Cursor m_currentMouseCursor; 361 362 int m_clickCount; 363 RefPtrWillBeMember<Node> m_clickNode; 364 365 RefPtrWillBeMember<Node> m_dragTarget; 366 bool m_shouldOnlyFireDragOverEvent; 367 368 RefPtrWillBeMember<HTMLFrameSetElement> m_frameSetBeingResized; 369 370 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeScrollableArea. 371 372 bool m_mousePositionIsUnknown; 373 IntPoint m_lastKnownMousePosition; 374 IntPoint m_lastKnownMouseGlobalPosition; 375 IntPoint m_mouseDownPos; // In our view's coords. 376 double m_mouseDownTimestamp; 377 PlatformMouseEvent m_mouseDown; 378 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken; 379 380 RefPtrWillBeMember<Node> m_latchedWheelEventNode; 381 bool m_widgetIsLatched; 382 383 RefPtrWillBeMember<Node> m_previousWheelScrolledNode; 384 385 // The target of each active touch point indexed by the touch ID. 386 typedef WillBeHeapHashMap<unsigned, RefPtrWillBeMember<EventTarget>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > TouchTargetMap; 387 TouchTargetMap m_targetForTouchID; 388 389 // If set, the document of the active touch sequence. Unset if no touch sequence active. 390 RefPtrWillBeMember<Document> m_touchSequenceDocument; 391 RefPtr<UserGestureToken> m_touchSequenceUserGestureToken; 392 393 bool m_touchPressed; 394 395 RefPtrWillBeMember<Node> m_scrollGestureHandlingNode; 396 bool m_lastGestureScrollOverWidget; 397 RefPtrWillBeMember<Node> m_previousGestureScrolledNode; 398 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture; 399 400 double m_maxMouseMovedDuration; 401 bool m_didStartDrag; 402 403 bool m_longTapShouldInvokeContextMenu; 404 405 Timer<EventHandler> m_activeIntervalTimer; 406 double m_lastShowPressTimestamp; 407 RefPtrWillBeMember<Element> m_lastDeferredTapElement; 408 }; 409 410 } // namespace blink 411 412 #endif // EventHandler_h 413