1/*
2 * Copyright (C) 2010 Google Inc. All Rights Reserved.
3 * Copyright (C) 2017 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27
28#include "config.h"
29#include "EventContext.h"
30
31#include "Document.h"
32#include "FocusEvent.h"
33#include "MouseEvent.h"
34#include "TouchEvent.h"
35
36namespace WebCore {
37
38EventContext::EventContext(Node* node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)
39 : m_node { node }
40 , m_currentTarget { currentTarget }
41 , m_target { target }
42 , m_closedShadowDepth { closedShadowDepth }
43{
44 ASSERT(!isUnreachableNode(m_target.get()));
45}
46
47EventContext::~EventContext() = default;
48
49void EventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
50{
51 event.setTarget(m_target.get());
52 event.setCurrentTarget(m_currentTarget.get());
53 // FIXME: Consider merging handleLocalEvents and fireEventListeners.
54 if (m_node)
55 m_node->handleLocalEvents(event, phase);
56 else
57 m_currentTarget->fireEventListeners(event, phase);
58}
59
60bool EventContext::isMouseOrFocusEventContext() const
61{
62 return false;
63}
64
65bool EventContext::isTouchEventContext() const
66{
67 return false;
68}
69
70MouseOrFocusEventContext::MouseOrFocusEventContext(Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)
71 : EventContext(&node, currentTarget, target, closedShadowDepth)
72{
73}
74
75MouseOrFocusEventContext::~MouseOrFocusEventContext() = default;
76
77void MouseOrFocusEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
78{
79 if (m_relatedTarget)
80 event.setRelatedTarget(*m_relatedTarget);
81 EventContext::handleLocalEvents(event, phase);
82}
83
84bool MouseOrFocusEventContext::isMouseOrFocusEventContext() const
85{
86 return true;
87}
88
89#if ENABLE(TOUCH_EVENTS)
90
91TouchEventContext::TouchEventContext(Node& node, EventTarget* currentTarget, EventTarget* target, int closedShadowDepth)
92 : EventContext(&node, currentTarget, target, closedShadowDepth)
93 , m_touches(TouchList::create())
94 , m_targetTouches(TouchList::create())
95 , m_changedTouches(TouchList::create())
96{
97}
98
99TouchEventContext::~TouchEventContext() = default;
100
101void TouchEventContext::handleLocalEvents(Event& event, EventInvokePhase phase) const
102{
103 checkReachability(m_touches);
104 checkReachability(m_targetTouches);
105 checkReachability(m_changedTouches);
106 auto& touchEvent = downcast<TouchEvent>(event);
107 touchEvent.setTouches(m_touches.ptr());
108 touchEvent.setTargetTouches(m_targetTouches.ptr());
109 touchEvent.setChangedTouches(m_changedTouches.ptr());
110 EventContext::handleLocalEvents(event, phase);
111}
112
113bool TouchEventContext::isTouchEventContext() const
114{
115 return true;
116}
117
118#if !ASSERT_DISABLED
119
120void TouchEventContext::checkReachability(const Ref<TouchList>& touchList) const
121{
122 size_t length = touchList->length();
123 for (size_t i = 0; i < length; ++i)
124 ASSERT(!isUnreachableNode(downcast<Node>(touchList->item(i)->target())));
125}
126
127#endif
128
129#endif // ENABLE(TOUCH_EVENTS)
130
131}
132