1/*
2 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
3 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
4 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
5 * Copyright (C) 2003-2017 Apple Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 */
23
24#pragma once
25
26#include "DOMHighResTimeStamp.h"
27#include "EventInit.h"
28#include "EventInterfaces.h"
29#include "ExceptionOr.h"
30#include "ScriptWrappable.h"
31#include <wtf/MonotonicTime.h>
32#include <wtf/TypeCasts.h>
33#include <wtf/text/AtomString.h>
34
35namespace WebCore {
36
37class EventPath;
38class EventTarget;
39class ScriptExecutionContext;
40
41class Event : public ScriptWrappable, public RefCounted<Event> {
42public:
43 enum class IsTrusted : uint8_t { No, Yes };
44 enum class CanBubble : uint8_t { No, Yes };
45 enum class IsCancelable : uint8_t { No, Yes };
46 enum class IsComposed : uint8_t { No, Yes };
47
48 enum PhaseType : uint8_t {
49 NONE = 0,
50 CAPTURING_PHASE = 1,
51 AT_TARGET = 2,
52 BUBBLING_PHASE = 3
53 };
54
55 WEBCORE_EXPORT static Ref<Event> create(const AtomString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No);
56 static Ref<Event> createForBindings();
57 static Ref<Event> create(const AtomString& type, const EventInit&, IsTrusted = IsTrusted::No);
58
59 virtual ~Event();
60
61 WEBCORE_EXPORT void initEvent(const AtomString& type, bool canBubble, bool cancelable);
62
63 bool isInitialized() const { return m_isInitialized; }
64
65 const AtomString& type() const { return m_type; }
66 void setType(const AtomString& type) { m_type = type; }
67
68 EventTarget* target() const { return m_target.get(); }
69 void setTarget(RefPtr<EventTarget>&&);
70
71 EventTarget* currentTarget() const { return m_currentTarget.get(); }
72 void setCurrentTarget(EventTarget*);
73
74 unsigned short eventPhase() const { return m_eventPhase; }
75 void setEventPhase(PhaseType phase) { m_eventPhase = phase; }
76
77 bool bubbles() const { return m_canBubble; }
78 bool cancelable() const { return m_cancelable; }
79 bool composed() const { return m_composed; }
80
81 DOMHighResTimeStamp timeStampForBindings(ScriptExecutionContext&) const;
82 MonotonicTime timeStamp() const { return m_createTime; }
83
84 void setEventPath(const EventPath& path) { m_eventPath = &path; }
85 Vector<EventTarget*> composedPath() const;
86
87 void stopPropagation() { m_propagationStopped = true; }
88 void stopImmediatePropagation() { m_immediatePropagationStopped = true; }
89
90 bool isTrusted() const { return m_isTrusted; }
91 void setUntrusted() { m_isTrusted = false; }
92
93 bool legacyReturnValue() const { return !m_wasCanceled; }
94 void setLegacyReturnValue(bool);
95
96 virtual EventInterface eventInterface() const { return EventInterfaceType; }
97
98 virtual bool isBeforeTextInsertedEvent() const { return false; }
99 virtual bool isBeforeUnloadEvent() const { return false; }
100 virtual bool isClipboardEvent() const { return false; }
101 virtual bool isCompositionEvent() const { return false; }
102 virtual bool isErrorEvent() const { return false; }
103 virtual bool isFocusEvent() const { return false; }
104 virtual bool isInputEvent() const { return false; }
105 virtual bool isKeyboardEvent() const { return false; }
106 virtual bool isMouseEvent() const { return false; }
107 virtual bool isPointerEvent() const { return false; }
108 virtual bool isTextEvent() const { return false; }
109 virtual bool isTouchEvent() const { return false; }
110 virtual bool isUIEvent() const { return false; }
111 virtual bool isVersionChangeEvent() const { return false; }
112 virtual bool isWheelEvent() const { return false; }
113
114 bool propagationStopped() const { return m_propagationStopped || m_immediatePropagationStopped; }
115 bool immediatePropagationStopped() const { return m_immediatePropagationStopped; }
116
117 void resetBeforeDispatch();
118 void resetAfterDispatch();
119
120 bool defaultPrevented() const { return m_wasCanceled; }
121 void preventDefault();
122
123 bool defaultHandled() const { return m_defaultHandled; }
124 void setDefaultHandled() { m_defaultHandled = true; }
125
126 bool isDefaultEventHandlerIgnored() const { return m_isDefaultEventHandlerIgnored; }
127 void setIsDefaultEventHandlerIgnored() { m_isDefaultEventHandlerIgnored = true; }
128
129 void setInPassiveListener(bool value) { m_isExecutingPassiveEventListener = value; }
130
131 bool cancelBubble() const { return propagationStopped(); }
132 void setCancelBubble(bool);
133
134 Event* underlyingEvent() const { return m_underlyingEvent.get(); }
135 void setUnderlyingEvent(Event*);
136
137 // Returns true if the dispatch flag is set.
138 // https://dom.spec.whatwg.org/#dispatch-flag
139 bool isBeingDispatched() const { return eventPhase(); }
140
141 virtual EventTarget* relatedTarget() const { return nullptr; }
142 virtual void setRelatedTarget(EventTarget&) { }
143
144protected:
145 explicit Event(IsTrusted = IsTrusted::No);
146 Event(const AtomString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No);
147 Event(const AtomString& type, CanBubble, IsCancelable, IsComposed, MonotonicTime timestamp, IsTrusted isTrusted = IsTrusted::Yes);
148 Event(const AtomString& type, const EventInit&, IsTrusted);
149
150 virtual void receivedTarget() { }
151
152private:
153 explicit Event(MonotonicTime createTime, const AtomString& type, IsTrusted, CanBubble, IsCancelable, IsComposed);
154
155 void setCanceledFlagIfPossible();
156
157 unsigned m_isInitialized : 1;
158 unsigned m_canBubble : 1;
159 unsigned m_cancelable : 1;
160 unsigned m_composed : 1;
161
162 unsigned m_propagationStopped : 1;
163 unsigned m_immediatePropagationStopped : 1;
164 unsigned m_wasCanceled : 1;
165 unsigned m_defaultHandled : 1;
166 unsigned m_isDefaultEventHandlerIgnored : 1;
167 unsigned m_isTrusted : 1;
168 unsigned m_isExecutingPassiveEventListener : 1;
169
170 unsigned m_eventPhase : 2;
171
172 AtomString m_type;
173
174 RefPtr<EventTarget> m_currentTarget;
175 const EventPath* m_eventPath { nullptr };
176 RefPtr<EventTarget> m_target;
177 MonotonicTime m_createTime;
178
179 RefPtr<Event> m_underlyingEvent;
180};
181
182inline void Event::preventDefault()
183{
184 setCanceledFlagIfPossible();
185}
186
187inline void Event::setLegacyReturnValue(bool returnValue)
188{
189 if (!returnValue)
190 setCanceledFlagIfPossible();
191}
192
193// https://dom.spec.whatwg.org/#set-the-canceled-flag
194inline void Event::setCanceledFlagIfPossible()
195{
196 if (m_cancelable && !m_isExecutingPassiveEventListener)
197 m_wasCanceled = true;
198 // FIXME: Specification suggests we log something to the console when preventDefault is called but
199 // doesn't do anything because the event is not cancelable or is executing passive event listeners.
200}
201
202inline void Event::setCancelBubble(bool cancel)
203{
204 if (cancel)
205 m_propagationStopped = true;
206}
207
208} // namespace WebCore
209
210#define SPECIALIZE_TYPE_TRAITS_EVENT(ToValueTypeName) \
211SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
212 static bool isType(const WebCore::Event& event) { return event.is##ToValueTypeName(); } \
213SPECIALIZE_TYPE_TRAITS_END()
214