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/AtomicString.h> |
34 | |
35 | namespace WebCore { |
36 | |
37 | class EventPath; |
38 | class EventTarget; |
39 | class ScriptExecutionContext; |
40 | |
41 | class Event : public ScriptWrappable, public RefCounted<Event> { |
42 | public: |
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 AtomicString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No); |
56 | static Ref<Event> createForBindings(); |
57 | static Ref<Event> create(const AtomicString& type, const EventInit&, IsTrusted = IsTrusted::No); |
58 | |
59 | virtual ~Event(); |
60 | |
61 | WEBCORE_EXPORT void initEvent(const AtomicString& type, bool canBubble, bool cancelable); |
62 | |
63 | bool isInitialized() const { return m_isInitialized; } |
64 | |
65 | const AtomicString& type() const { return m_type; } |
66 | void setType(const AtomicString& 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 | |
144 | protected: |
145 | explicit Event(IsTrusted = IsTrusted::No); |
146 | Event(const AtomicString& type, CanBubble, IsCancelable, IsComposed = IsComposed::No); |
147 | Event(const AtomicString& type, CanBubble, IsCancelable, IsComposed, MonotonicTime timestamp, IsTrusted isTrusted = IsTrusted::Yes); |
148 | Event(const AtomicString& type, const EventInit&, IsTrusted); |
149 | |
150 | virtual void receivedTarget() { } |
151 | |
152 | private: |
153 | explicit Event(MonotonicTime createTime, const AtomicString& 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 | AtomicString 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 | |
182 | inline void Event::preventDefault() |
183 | { |
184 | setCanceledFlagIfPossible(); |
185 | } |
186 | |
187 | inline void Event::setLegacyReturnValue(bool returnValue) |
188 | { |
189 | if (!returnValue) |
190 | setCanceledFlagIfPossible(); |
191 | } |
192 | |
193 | // https://dom.spec.whatwg.org/#set-the-canceled-flag |
194 | inline 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 | |
202 | inline 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) \ |
211 | SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ |
212 | static bool isType(const WebCore::Event& event) { return event.is##ToValueTypeName(); } \ |
213 | SPECIALIZE_TYPE_TRAITS_END() |
214 | |