| /* |
| * Copyright (C) 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef EventHandler_h |
| #define EventHandler_h |
| |
| #include "core/CoreExport.h" |
| #include "core/events/TextEventInputType.h" |
| #include "core/input/GestureManager.h" |
| #include "core/input/KeyboardEventManager.h" |
| #include "core/input/MouseEventManager.h" |
| #include "core/input/PointerEventManager.h" |
| #include "core/input/ScrollManager.h" |
| #include "core/layout/HitTestRequest.h" |
| #include "core/page/DragActions.h" |
| #include "core/page/EventWithHitTestResults.h" |
| #include "core/style/ComputedStyleConstants.h" |
| #include "platform/Cursor.h" |
| #include "platform/PlatformMouseEvent.h" |
| #include "platform/PlatformTouchPoint.h" |
| #include "platform/UserGestureIndicator.h" |
| #include "platform/geometry/LayoutPoint.h" |
| #include "platform/heap/Handle.h" |
| #include "platform/scroll/ScrollTypes.h" |
| #include "public/platform/WebInputEvent.h" |
| #include "public/platform/WebInputEventResult.h" |
| #include "wtf/Forward.h" |
| #include "wtf/HashMap.h" |
| #include "wtf/HashTraits.h" |
| #include "wtf/RefPtr.h" |
| |
| namespace blink { |
| |
| class DataTransfer; |
| class PaintLayer; |
| class Document; |
| class Element; |
| class Event; |
| class EventTarget; |
| template <typename EventType> |
| class EventWithHitTestResults; |
| class FloatPoint; |
| class FloatQuad; |
| class FrameHost; |
| class HTMLFrameSetElement; |
| class HitTestRequest; |
| class HitTestResult; |
| class LayoutObject; |
| class LocalFrame; |
| class Node; |
| class OptionalCursor; |
| class PlatformGestureEvent; |
| class PlatformTouchEvent; |
| class PlatformWheelEvent; |
| class ScrollableArea; |
| class Scrollbar; |
| class SelectionController; |
| class TextEvent; |
| class WheelEvent; |
| class Widget; |
| |
| class CORE_EXPORT EventHandler final |
| : public GarbageCollectedFinalized<EventHandler> { |
| WTF_MAKE_NONCOPYABLE(EventHandler); |
| |
| public: |
| explicit EventHandler(LocalFrame*); |
| DECLARE_TRACE(); |
| |
| void clear(); |
| void nodeWillBeRemoved(Node&); |
| |
| void updateSelectionForMouseDrag(); |
| void startMiddleClickAutoscroll(LayoutObject*); |
| |
| // TODO(nzolghadr): Some of the APIs in this class only forward the action |
| // to the corresponding Manager class. We need to investigate whether it is |
| // better to expose the manager instance itself later or can the access to |
| // those APIs be more limited or removed. |
| |
| void stopAutoscroll(); |
| |
| void dispatchFakeMouseMoveEventSoon(); |
| void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&); |
| |
| HitTestResult hitTestResultAtPoint( |
| const LayoutPoint&, |
| HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | |
| HitTestRequest::Active, |
| const LayoutSize& padding = LayoutSize()); |
| |
| bool mousePressed() const { return m_mouseEventManager->mousePressed(); } |
| |
| void setCapturingMouseEventsNode( |
| Node*); // A caller is responsible for resetting capturing node to 0. |
| |
| WebInputEventResult updateDragAndDrop(const PlatformMouseEvent&, |
| DataTransfer*); |
| void cancelDragAndDrop(const PlatformMouseEvent&, DataTransfer*); |
| WebInputEventResult performDragAndDrop(const PlatformMouseEvent&, |
| DataTransfer*); |
| void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement); |
| |
| void scheduleHoverStateUpdate(); |
| void scheduleCursorUpdate(); |
| |
| // Return whether a mouse cursor update is currently pending. Used for |
| // testing. |
| bool cursorUpdatePending(); |
| |
| void setResizingFrameSet(HTMLFrameSetElement*); |
| |
| void resizeScrollableAreaDestroyed(); |
| |
| IntPoint lastKnownMousePosition() const; |
| |
| IntPoint dragDataTransferLocationForTesting(); |
| |
| // Performs a logical scroll that chains, crossing frames, starting from |
| // the given node or a reasonable default (focus/last clicked). |
| bool bubblingScroll(ScrollDirection, |
| ScrollGranularity, |
| Node* startingNode = nullptr); |
| |
| WebInputEventResult handleMouseMoveEvent(const PlatformMouseEvent&); |
| void handleMouseLeaveEvent(const PlatformMouseEvent&); |
| |
| WebInputEventResult handleMousePressEvent(const PlatformMouseEvent&); |
| WebInputEventResult handleMouseReleaseEvent(const PlatformMouseEvent&); |
| WebInputEventResult handleWheelEvent(const PlatformWheelEvent&); |
| |
| // Called on the local root frame exactly once per gesture event. |
| WebInputEventResult handleGestureEvent(const PlatformGestureEvent&); |
| WebInputEventResult handleGestureEvent(const GestureEventWithHitTestResults&); |
| |
| // Clear the old hover/active state within frames before moving the hover |
| // state to the another frame |
| void updateGestureHoverActiveState(const HitTestRequest&, Element*); |
| |
| // Hit-test the provided (non-scroll) gesture event, applying touch-adjustment |
| // and updating hover/active state across all frames if necessary. This should |
| // be called at most once per gesture event, and called on the local root |
| // frame. |
| // Note: This is similar to (the less clearly named) prepareMouseEvent. |
| // FIXME: Remove readOnly param when there is only ever a single call to this. |
| GestureEventWithHitTestResults targetGestureEvent(const PlatformGestureEvent&, |
| bool readOnly = false); |
| GestureEventWithHitTestResults hitTestResultForGestureEvent( |
| const PlatformGestureEvent&, |
| HitTestRequest::HitTestRequestType); |
| // Handle the provided non-scroll gesture event. Should be called only on the |
| // inner frame. |
| WebInputEventResult handleGestureEventInFrame( |
| const GestureEventWithHitTestResults&); |
| |
| // Handle the provided scroll gesture event, propagating down to child frames |
| // as necessary. |
| WebInputEventResult handleGestureScrollEvent(const PlatformGestureEvent&); |
| WebInputEventResult handleGestureScrollEnd(const PlatformGestureEvent&); |
| bool isScrollbarHandlingGestures() const; |
| |
| bool bestClickableNodeForHitTestResult(const HitTestResult&, |
| IntPoint& targetPoint, |
| Node*& targetNode); |
| bool bestContextMenuNodeForHitTestResult(const HitTestResult&, |
| IntPoint& targetPoint, |
| Node*& targetNode); |
| // FIXME: This doesn't appear to be used outside tests anymore, what path are |
| // we using now and is it tested? |
| bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, |
| const IntSize& touchRadius, |
| IntRect& targetArea, |
| Node*& targetNode); |
| |
| WebInputEventResult sendContextMenuEvent(const PlatformMouseEvent&, |
| Node* overrideTargetNode = nullptr); |
| WebInputEventResult sendContextMenuEventForKey( |
| Element* overrideTargetElement = nullptr); |
| |
| // Returns whether pointerId is active or not |
| bool isPointerEventActive(int); |
| |
| void setPointerCapture(int, EventTarget*); |
| void releasePointerCapture(int, EventTarget*); |
| bool hasPointerCapture(int, const EventTarget*) const; |
| bool hasProcessedPointerCapture(int, const EventTarget*) const; |
| |
| void elementRemoved(EventTarget*); |
| |
| void setMouseDownMayStartAutoscroll(); |
| |
| bool handleAccessKey(const WebKeyboardEvent&); |
| WebInputEventResult keyEvent(const WebKeyboardEvent&); |
| void defaultKeyboardEventHandler(KeyboardEvent*); |
| |
| bool handleTextInputEvent(const String& text, |
| Event* underlyingEvent = nullptr, |
| TextEventInputType = TextEventInputKeyboard); |
| void defaultTextInputEventHandler(TextEvent*); |
| |
| void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation); |
| |
| void capsLockStateMayHaveChanged(); // Only called by FrameSelection |
| |
| WebInputEventResult handleTouchEvent(const PlatformTouchEvent&); |
| |
| bool useHandCursor(Node*, bool isOverLink); |
| |
| void notifyElementActivated(); |
| |
| PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { |
| return m_lastMouseDownUserGestureToken.release(); |
| } |
| |
| SelectionController& selectionController() const { |
| return *m_selectionController; |
| } |
| |
| // FIXME(nzolghadr): This function is technically a private function of |
| // EventHandler class. Making it public temporary to make it possible to |
| // move some code around in the refactoring process. |
| // Performs a chaining logical scroll, within a *single* frame, starting |
| // from either a provided starting node or a default based on the focused or |
| // most recently clicked node, falling back to the frame. |
| // Returns true if the scroll was consumed. |
| // direction - The logical direction to scroll in. This will be converted to |
| // a physical direction for each LayoutBox we try to scroll |
| // based on that box's writing mode. |
| // granularity - The units that the scroll delta parameter is in. |
| // startNode - Optional. If provided, start chaining from the given node. |
| // If not, use the current focus or last clicked node. |
| bool logicalScroll(ScrollDirection, |
| ScrollGranularity, |
| Node* startNode = nullptr); |
| |
| private: |
| WebInputEventResult handleMouseMoveOrLeaveEvent( |
| const PlatformMouseEvent&, |
| HitTestResult* hoveredNode = nullptr, |
| bool onlyUpdateScrollbars = false, |
| bool forceLeave = false); |
| |
| HitTestRequest::HitTestRequestType getHitTypeForGestureType( |
| PlatformEvent::EventType); |
| void applyTouchAdjustment(PlatformGestureEvent*, HitTestResult*); |
| WebInputEventResult handleGestureTapDown( |
| const GestureEventWithHitTestResults&); |
| WebInputEventResult handleGestureTap(const GestureEventWithHitTestResults&); |
| WebInputEventResult handleGestureLongPress( |
| const GestureEventWithHitTestResults&); |
| WebInputEventResult handleGestureLongTap( |
| const GestureEventWithHitTestResults&); |
| |
| void updateGestureTargetNodeForMouseEvent( |
| const GestureEventWithHitTestResults&); |
| |
| bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const; |
| |
| OptionalCursor selectCursor(const HitTestResult&); |
| OptionalCursor selectAutoCursor(const HitTestResult&, |
| Node*, |
| const Cursor& iBeam); |
| |
| void hoverTimerFired(TimerBase*); |
| void cursorUpdateTimerFired(TimerBase*); |
| void activeIntervalTimerFired(TimerBase*); |
| |
| void updateCursor(); |
| |
| ScrollableArea* associatedScrollableArea(const PaintLayer*) const; |
| |
| Node* updateMouseEventTargetNode(Node*); |
| |
| // Dispatches ME after corresponding PE provided the PE has not been canceled. |
| // The eventType arg must be a mouse event that can be gated though a |
| // preventDefaulted pointerdown (i.e., one of |
| // {mousedown, mousemove, mouseup}). |
| // TODO(mustaq): Can we avoid the clickCount param, instead use |
| // PlatformMouseEvent's count? |
| // Same applied to dispatchMouseEvent() above. |
| WebInputEventResult updatePointerTargetAndDispatchEvents( |
| const AtomicString& mouseEventType, |
| Node* target, |
| const PlatformMouseEvent&); |
| |
| // Clears drag target and related states. It is called when drag is done or |
| // canceled. |
| void clearDragState(); |
| |
| WebInputEventResult passMousePressEventToSubframe( |
| MouseEventWithHitTestResults&, |
| LocalFrame* subframe); |
| WebInputEventResult passMouseMoveEventToSubframe( |
| MouseEventWithHitTestResults&, |
| LocalFrame* subframe, |
| HitTestResult* hoveredNode = nullptr); |
| WebInputEventResult passMouseReleaseEventToSubframe( |
| MouseEventWithHitTestResults&, |
| LocalFrame* subframe); |
| |
| bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&); |
| |
| void defaultSpaceEventHandler(KeyboardEvent*); |
| void defaultBackspaceEventHandler(KeyboardEvent*); |
| void defaultTabEventHandler(KeyboardEvent*); |
| void defaultEscapeEventHandler(KeyboardEvent*); |
| void defaultArrowEventHandler(WebFocusType, KeyboardEvent*); |
| |
| void updateLastScrollbarUnderMouse(Scrollbar*, bool); |
| |
| WebInputEventResult handleGestureShowPress(); |
| |
| bool shouldTopControlsConsumeScroll(FloatSize) const; |
| |
| FrameHost* frameHost() const; |
| |
| // NOTE: If adding a new field to this class please ensure that it is |
| // cleared in |EventHandler::clear()|. |
| |
| const Member<LocalFrame> m_frame; |
| |
| const Member<SelectionController> m_selectionController; |
| |
| Timer<EventHandler> m_hoverTimer; |
| |
| // TODO(rbyers): Mouse cursor update is page-wide, not per-frame. Page-wide |
| // state should move out of EventHandler to a new PageEventHandler class. |
| // crbug.com/449649 |
| Timer<EventHandler> m_cursorUpdateTimer; |
| |
| Member<Node> m_capturingMouseEventsNode; |
| bool m_eventHandlerWillResetCapturingMouseEventsNode; |
| |
| Member<LocalFrame> m_lastMouseMoveEventSubframe; |
| Member<Scrollbar> m_lastScrollbarUnderMouse; |
| |
| Member<Node> m_dragTarget; |
| bool m_shouldOnlyFireDragOverEvent; |
| |
| Member<HTMLFrameSetElement> m_frameSetBeingResized; |
| |
| RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken; |
| |
| Member<ScrollManager> m_scrollManager; |
| Member<MouseEventManager> m_mouseEventManager; |
| Member<KeyboardEventManager> m_keyboardEventManager; |
| Member<PointerEventManager> m_pointerEventManager; |
| Member<GestureManager> m_gestureManager; |
| |
| double m_maxMouseMovedDuration; |
| |
| bool m_longTapShouldInvokeContextMenu; |
| |
| Timer<EventHandler> m_activeIntervalTimer; |
| double m_lastShowPressTimestamp; |
| Member<Element> m_lastDeferredTapElement; |
| |
| // Set on GestureTapDown if the |pointerdown| event corresponding to the |
| // triggering |touchstart| event was canceled. This suppresses mouse event |
| // firing for the current gesture sequence (i.e. until next GestureTapDown). |
| bool m_suppressMouseEventsFromGestures; |
| }; |
| |
| } // namespace blink |
| |
| #endif // EventHandler_h |