Home | History | Annotate | Download | only in page
      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