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/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