#pragma once
#include "Node.h"
namespace WebCore {
class TouchList;
class EventContext {
WTF_MAKE_FAST_ALLOCATED;
public:
EventContext(Node*, EventTarget* currentTarget, EventTarget*);
virtual ~EventContext();
Node* node() const { return m_node.get(); }
EventTarget* currentTarget() const { return m_currentTarget.get(); }
EventTarget* target() const { return m_target.get(); }
virtual void handleLocalEvents(Event&) const;
virtual bool isMouseOrFocusEventContext() const;
virtual bool isTouchEventContext() const;
protected:
#if !ASSERT_DISABLED
bool isUnreachableNode(EventTarget*) const;
#endif
RefPtr<Node> m_node;
RefPtr<EventTarget> m_currentTarget;
RefPtr<EventTarget> m_target;
};
class MouseOrFocusEventContext final : public EventContext {
public:
MouseOrFocusEventContext(Node&, EventTarget* currentTarget, EventTarget*);
virtual ~MouseOrFocusEventContext();
Node* relatedTarget() const { return m_relatedTarget.get(); }
void setRelatedTarget(Node*);
private:
void handleLocalEvents(Event&) const final;
bool isMouseOrFocusEventContext() const final;
RefPtr<Node> m_relatedTarget;
};
#if ENABLE(TOUCH_EVENTS)
class TouchEventContext final : public EventContext {
public:
TouchEventContext(Node&, EventTarget* currentTarget, EventTarget*);
virtual ~TouchEventContext();
enum TouchListType { Touches, TargetTouches, ChangedTouches };
TouchList& touchList(TouchListType);
private:
void handleLocalEvents(Event&) const final;
bool isTouchEventContext() const final;
void checkReachability(const Ref<TouchList>&) const;
Ref<TouchList> m_touches;
Ref<TouchList> m_targetTouches;
Ref<TouchList> m_changedTouches;
};
#endif // ENABLE(TOUCH_EVENTS)
#if !ASSERT_DISABLED
inline bool EventContext::isUnreachableNode(EventTarget* target) const
{
return is<Node>(target) && !downcast<Node>(*target).isSVGElement() && m_node->isClosedShadowHidden(downcast<Node>(*target));
}
#endif
inline void MouseOrFocusEventContext::setRelatedTarget(Node* relatedTarget)
{
ASSERT(!isUnreachableNode(relatedTarget));
m_relatedTarget = relatedTarget;
}
#if ENABLE(TOUCH_EVENTS)
inline TouchList& TouchEventContext::touchList(TouchListType type)
{
switch (type) {
case Touches:
return m_touches.get();
case TargetTouches:
return m_targetTouches.get();
case ChangedTouches:
return m_changedTouches.get();
}
ASSERT_NOT_REACHED();
return m_touches.get();
}
#endif
#if ENABLE(TOUCH_EVENTS) && ASSERT_DISABLED
inline void TouchEventContext::checkReachability(const Ref<TouchList>&) const
{
}
#endif
}
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::MouseOrFocusEventContext)
static bool isType(const WebCore::EventContext& context) { return context.isMouseOrFocusEventContext(); }
SPECIALIZE_TYPE_TRAITS_END()
#if ENABLE(TOUCH_EVENTS)
SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TouchEventContext)
static bool isType(const WebCore::EventContext& context) { return context.isTouchEventContext(); }
SPECIALIZE_TYPE_TRAITS_END()
#endif