#ifndef EventHandler_h
#define EventHandler_h
#include "core/editing/TextGranularity.h"
#include "core/events/TextEventInputType.h"
#include "core/page/DragActions.h"
#include "core/page/FocusType.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "heap/Handle.h"
#include "platform/Cursor.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/Timer.h"
#include "platform/UserGestureIndicator.h"
#include "platform/geometry/LayoutPoint.h"
#include "platform/scroll/ScrollTypes.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/RefPtr.h"
namespace WebCore {
class AutoscrollController;
class Clipboard;
class Document;
class Element;
class Event;
class EventTarget;
class FloatPoint;
class FloatQuad;
class FullscreenElementStack;
class LocalFrame;
class HTMLFrameSetElement;
class HitTestRequest;
class HitTestResult;
class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
class OptionalCursor;
class PlatformGestureEvent;
class PlatformKeyboardEvent;
class PlatformTouchEvent;
class PlatformWheelEvent;
class RenderLayer;
class RenderLayerScrollableArea;
class RenderObject;
class RenderWidget;
class SVGElementInstance;
class ScrollableArea;
class Scrollbar;
class TextEvent;
class TouchEvent;
class VisibleSelection;
class WheelEvent;
class Widget;
class DragState;
enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
class EventHandler {
WTF_MAKE_NONCOPYABLE(EventHandler);
public:
explicit EventHandler(LocalFrame*);
~EventHandler();
void clear();
void nodeWillBeRemoved(Node&);
void updateSelectionForMouseDrag();
Node* mousePressNode() const;
#if OS(WIN)
void startPanScrolling(RenderObject*);
#endif
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_mousePressed; }
void setMousePressed(bool pressed) { m_mousePressed = pressed; }
void setCapturingMouseEventsNode(PassRefPtr<Node>);
bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
void scheduleHoverStateUpdate();
void scheduleCursorUpdate();
void setResizingFrameSet(HTMLFrameSetElement*);
void resizeScrollableAreaDestroyed();
IntPoint lastKnownMousePosition() const;
Cursor currentMouseCursor() const { return m_currentMouseCursor; }
bool bubblingScroll(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
bool handleMouseMoveEvent(const PlatformMouseEvent&);
void handleMouseLeaveEvent(const PlatformMouseEvent&);
bool handleMousePressEvent(const PlatformMouseEvent&);
bool handleMouseReleaseEvent(const PlatformMouseEvent&);
bool handleWheelEvent(const PlatformWheelEvent&);
void defaultWheelEventHandler(Node*, WheelEvent*);
bool handleGestureEvent(const PlatformGestureEvent&);
bool handleGestureScrollEnd(const PlatformGestureEvent&);
bool isScrollbarHandlingGestures() const;
bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
void adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
bool sendContextMenuEvent(const PlatformMouseEvent&);
bool sendContextMenuEventForKey();
bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
static unsigned accessKeyModifiers();
bool handleAccessKey(const PlatformKeyboardEvent&);
bool keyEvent(const PlatformKeyboardEvent&);
void defaultKeyboardEventHandler(KeyboardEvent*);
bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
void defaultTextInputEventHandler(TextEvent*);
void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
void focusDocumentView();
void capsLockStateMayHaveChanged();
bool handleTouchEvent(const PlatformTouchEvent&);
bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
void notifyElementActivated();
private:
static DragState& dragState();
PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard() const;
bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
void selectClosestMisspellingFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
void selectClosestMisspellingFromMouseEvent(const MouseEventWithHitTestResults&);
void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
bool handleMouseMoveOrLeaveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
bool handleMousePressEvent(const MouseEventWithHitTestResults&);
bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
bool handlePasteGlobalSelection(const PlatformMouseEvent&);
bool handleGestureTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
bool handleGestureLongPress(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
bool handleGestureLongTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
bool handleGestureTwoFingerTap(const PlatformGestureEvent&, const IntPoint& adjustedPoint);
bool handleGestureScrollUpdate(const PlatformGestureEvent&);
bool handleGestureScrollBegin(const PlatformGestureEvent&);
void clearGestureScrollNodes();
bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam, bool shiftKey);
void hoverTimerFired(Timer<EventHandler>*);
void cursorUpdateTimerFired(Timer<EventHandler>*);
void activeIntervalTimerFired(Timer<EventHandler>*);
bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
void cancelFakeMouseMoveEvent();
bool isCursorVisible() const;
void updateCursor();
bool isInsideScrollbar(const IntPoint&) const;
ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
bool scroll(ScrollDirection, ScrollGranularity, Node* startNode = 0, Node** stopNode = 0, float delta = 1.0f, IntPoint absolutePoint = IntPoint());
bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
TouchAction intersectTouchAction(const TouchAction, const TouchAction);
TouchAction computeEffectiveTouchAction(const LayoutPoint&);
bool handleMouseEventAsEmulatedGesture(const PlatformMouseEvent&);
bool handleWheelEventAsEmulatedGesture(const PlatformWheelEvent&);
HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
void invalidateClick();
Node* nodeUnderMouse() const;
void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
void freeClipboard();
bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
bool tryStartDrag(const MouseEventWithHitTestResults&);
void clearDragState();
bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
bool dragHysteresisExceeded(const FloatPoint&) const;
bool dragHysteresisExceeded(const IntPoint&) const;
bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
void defaultSpaceEventHandler(KeyboardEvent*);
void defaultBackspaceEventHandler(KeyboardEvent*);
void defaultTabEventHandler(KeyboardEvent*);
void defaultEscapeEventHandler(KeyboardEvent*);
void defaultArrowEventHandler(FocusType, KeyboardEvent*);
void updateSelectionForMouseDrag(const HitTestResult&);
void updateLastScrollbarUnderMouse(Scrollbar*, bool);
void setFrameWasScrolledByUser();
bool capturesDragging() const { return m_capturesDragging; }
bool isKeyEventAllowedInFullScreen(FullscreenElementStack*, const PlatformKeyboardEvent&) const;
bool handleGestureShowPress();
bool handleScrollGestureOnResizer(Node*, const PlatformGestureEvent&);
bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
LocalFrame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
AutoscrollController* autoscrollController() const;
bool panScrollInProgress() const;
void setLastKnownMousePosition(const PlatformMouseEvent&);
LocalFrame* const m_frame;
bool m_mousePressed;
bool m_capturesDragging;
RefPtr<Node> m_mousePressNode;
bool m_mouseDownMayStartSelect;
bool m_mouseDownMayStartDrag;
bool m_mouseDownWasSingleClickInSelection;
enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
SelectionInitiationState m_selectionInitiationState;
LayoutPoint m_dragStartPos;
Timer<EventHandler> m_hoverTimer;
Timer<EventHandler> m_cursorUpdateTimer;
bool m_mouseDownMayStartAutoscroll;
bool m_mouseDownWasInSubframe;
Timer<EventHandler> m_fakeMouseMoveEventTimer;
bool m_svgPan;
RefPtr<SVGElementInstance> m_instanceUnderMouse;
RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
RenderLayerScrollableArea* m_resizeScrollableArea;
RefPtr<Node> m_capturingMouseEventsNode;
bool m_eventHandlerWillResetCapturingMouseEventsNode;
RefPtr<Node> m_nodeUnderMouse;
RefPtr<Node> m_lastNodeUnderMouse;
RefPtr<LocalFrame> m_lastMouseMoveEventSubframe;
RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
Cursor m_currentMouseCursor;
int m_clickCount;
RefPtr<Node> m_clickNode;
RefPtr<Node> m_dragTarget;
bool m_shouldOnlyFireDragOverEvent;
RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
LayoutSize m_offsetFromResizeCorner;
bool m_mousePositionIsUnknown;
IntPoint m_lastKnownMousePosition;
IntPoint m_lastKnownMouseGlobalPosition;
IntPoint m_mouseDownPos;
double m_mouseDownTimestamp;
PlatformMouseEvent m_mouseDown;
RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
RefPtr<Node> m_latchedWheelEventNode;
bool m_widgetIsLatched;
RefPtr<Node> m_previousWheelScrolledNode;
typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
TouchTargetMap m_originatingTouchPointTargets;
RefPtr<Document> m_originatingTouchPointDocument;
unsigned m_originatingTouchPointTargetKey;
bool m_touchPressed;
RefPtr<Node> m_scrollGestureHandlingNode;
bool m_lastHitTestResultOverWidget;
RefPtr<Node> m_previousGestureScrolledNode;
RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
double m_maxMouseMovedDuration;
PlatformEvent::Type m_baseEventType;
bool m_didStartDrag;
bool m_longTapShouldInvokeContextMenu;
OwnPtr<IntPoint> m_lastSyntheticPinchAnchorCss;
OwnPtr<IntPoint> m_lastSyntheticPinchAnchorDip;
OwnPtr<IntPoint> m_lastSyntheticPanLocation;
float m_syntheticPageScaleFactor;
Timer<EventHandler> m_activeIntervalTimer;
double m_lastShowPressTimestamp;
RefPtr<Element> m_lastDeferredTapElement;
};
}
#endif