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