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, 2005, 2006, 2008 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#include "config.h"
24#include "core/events/Event.h"
25
26#include "core/dom/StaticNodeList.h"
27#include "core/events/EventTarget.h"
28#include "core/frame/UseCounter.h"
29#include "core/svg/SVGElement.h"
30#include "wtf/CurrentTime.h"
31
32namespace blink {
33
34EventInit::EventInit()
35    : bubbles(false)
36    , cancelable(false)
37{
38}
39
40
41Event::Event()
42    : m_canBubble(false)
43    , m_cancelable(false)
44    , m_propagationStopped(false)
45    , m_immediatePropagationStopped(false)
46    , m_defaultPrevented(false)
47    , m_defaultHandled(false)
48    , m_cancelBubble(false)
49    , m_eventPhase(0)
50    , m_currentTarget(nullptr)
51    , m_createTime(convertSecondsToDOMTimeStamp(currentTime()))
52{
53}
54
55Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg)
56    : m_type(eventType)
57    , m_canBubble(canBubbleArg)
58    , m_cancelable(cancelableArg)
59    , m_propagationStopped(false)
60    , m_immediatePropagationStopped(false)
61    , m_defaultPrevented(false)
62    , m_defaultHandled(false)
63    , m_cancelBubble(false)
64    , m_eventPhase(0)
65    , m_currentTarget(nullptr)
66    , m_createTime(convertSecondsToDOMTimeStamp(currentTime()))
67{
68}
69
70Event::Event(const AtomicString& eventType, const EventInit& initializer)
71    : m_type(eventType)
72    , m_canBubble(initializer.bubbles)
73    , m_cancelable(initializer.cancelable)
74    , m_propagationStopped(false)
75    , m_immediatePropagationStopped(false)
76    , m_defaultPrevented(false)
77    , m_defaultHandled(false)
78    , m_cancelBubble(false)
79    , m_eventPhase(0)
80    , m_currentTarget(nullptr)
81    , m_createTime(convertSecondsToDOMTimeStamp(currentTime()))
82{
83}
84
85Event::~Event()
86{
87}
88
89void Event::initEvent(const AtomicString& eventTypeArg, bool canBubbleArg, bool cancelableArg)
90{
91    if (dispatched())
92        return;
93
94    m_propagationStopped = false;
95    m_immediatePropagationStopped = false;
96    m_defaultPrevented = false;
97
98    m_type = eventTypeArg;
99    m_canBubble = canBubbleArg;
100    m_cancelable = cancelableArg;
101}
102
103bool Event::legacyReturnValue(ExecutionContext* executionContext) const
104{
105    bool returnValue = !defaultPrevented();
106    if (returnValue)
107        UseCounter::count(executionContext, UseCounter::EventGetReturnValueTrue);
108    else
109        UseCounter::count(executionContext, UseCounter::EventGetReturnValueFalse);
110    return returnValue;
111}
112
113void Event::setLegacyReturnValue(ExecutionContext* executionContext, bool returnValue)
114{
115    if (returnValue)
116        UseCounter::count(executionContext, UseCounter::EventSetReturnValueTrue);
117    else
118        UseCounter::count(executionContext, UseCounter::EventSetReturnValueFalse);
119    setDefaultPrevented(!returnValue);
120}
121
122const AtomicString& Event::interfaceName() const
123{
124    return EventNames::Event;
125}
126
127bool Event::hasInterface(const AtomicString& name) const
128{
129    return interfaceName() == name;
130}
131
132bool Event::isUIEvent() const
133{
134    return false;
135}
136
137bool Event::isMouseEvent() const
138{
139    return false;
140}
141
142bool Event::isFocusEvent() const
143{
144    return false;
145}
146
147bool Event::isKeyboardEvent() const
148{
149    return false;
150}
151
152bool Event::isTouchEvent() const
153{
154    return false;
155}
156
157bool Event::isGestureEvent() const
158{
159    return false;
160}
161
162bool Event::isWheelEvent() const
163{
164    return false;
165}
166
167bool Event::isRelatedEvent() const
168{
169    return false;
170}
171
172bool Event::isDragEvent() const
173{
174    return false;
175}
176
177bool Event::isClipboardEvent() const
178{
179    return false;
180}
181
182bool Event::isBeforeTextInsertedEvent() const
183{
184    return false;
185}
186
187bool Event::isBeforeUnloadEvent() const
188{
189    return false;
190}
191
192void Event::setTarget(PassRefPtrWillBeRawPtr<EventTarget> target)
193{
194    if (m_target == target)
195        return;
196
197    m_target = target;
198    if (m_target)
199        receivedTarget();
200}
201
202void Event::receivedTarget()
203{
204}
205
206void Event::setUnderlyingEvent(PassRefPtrWillBeRawPtr<Event> ue)
207{
208    // Prohibit creation of a cycle -- just do nothing in that case.
209    for (Event* e = ue.get(); e; e = e->underlyingEvent())
210        if (e == this)
211            return;
212    m_underlyingEvent = ue;
213}
214
215EventPath& Event::ensureEventPath()
216{
217    if (!m_eventPath)
218        m_eventPath = adoptPtrWillBeNoop(new EventPath(this));
219    return *m_eventPath;
220}
221
222PassRefPtrWillBeRawPtr<StaticNodeList> Event::path() const
223{
224    if (!m_currentTarget) {
225        ASSERT(m_eventPhase == Event::NONE);
226        if (!m_eventPath) {
227            // Before dispatching the event
228            return StaticNodeList::createEmpty();
229        }
230        ASSERT(!m_eventPath->isEmpty());
231        // After dispatching the event
232        return m_eventPath->last().treeScopeEventContext().ensureEventPath(*m_eventPath);
233    }
234    if (!m_currentTarget->toNode())
235        return StaticNodeList::createEmpty();
236    Node* node = m_currentTarget->toNode();
237    size_t eventPathSize = m_eventPath->size();
238    for (size_t i = 0; i < eventPathSize; ++i) {
239        if (node == (*m_eventPath)[i].node()) {
240            return (*m_eventPath)[i].treeScopeEventContext().ensureEventPath(*m_eventPath);
241        }
242    }
243    return StaticNodeList::createEmpty();
244}
245
246EventTarget* Event::currentTarget() const
247{
248    if (!m_currentTarget)
249        return 0;
250    Node* node = m_currentTarget->toNode();
251    if (node && node->isSVGElement()) {
252        if (SVGElement* svgElement = toSVGElement(node)->correspondingElement())
253            return svgElement;
254    }
255    return m_currentTarget.get();
256}
257
258void Event::trace(Visitor* visitor)
259{
260    visitor->trace(m_currentTarget);
261    visitor->trace(m_target);
262    visitor->trace(m_underlyingEvent);
263    visitor->trace(m_eventPath);
264}
265
266} // namespace blink
267