2 * Copyright (C) 2010 Google Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "core/events/DOMWindowEventQueue.h"
30 #include "core/events/Event.h"
31 #include "core/frame/LocalDOMWindow.h"
32 #include "core/frame/SuspendableTimer.h"
33 #include "core/inspector/InspectorInstrumentation.h"
37 class DOMWindowEventQueueTimer final
: public NoBaseWillBeGarbageCollectedFinalized
<DOMWindowEventQueueTimer
>, public SuspendableTimer
{
38 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DOMWindowEventQueueTimer
);
39 WTF_MAKE_NONCOPYABLE(DOMWindowEventQueueTimer
);
41 DOMWindowEventQueueTimer(DOMWindowEventQueue
* eventQueue
, ExecutionContext
* context
)
42 : SuspendableTimer(context
)
43 , m_eventQueue(eventQueue
) { }
44 DEFINE_INLINE_VIRTUAL_TRACE()
46 visitor
->trace(m_eventQueue
);
47 SuspendableTimer::trace(visitor
);
51 virtual void fired() { m_eventQueue
->pendingEventTimerFired(); }
53 RawPtrWillBeMember
<DOMWindowEventQueue
> m_eventQueue
;
56 PassRefPtrWillBeRawPtr
<DOMWindowEventQueue
> DOMWindowEventQueue::create(ExecutionContext
* context
)
58 return adoptRefWillBeNoop(new DOMWindowEventQueue(context
));
61 DOMWindowEventQueue::DOMWindowEventQueue(ExecutionContext
* context
)
62 : m_pendingEventTimer(adoptPtrWillBeNoop(new DOMWindowEventQueueTimer(this, context
)))
65 m_pendingEventTimer
->suspendIfNeeded();
68 DOMWindowEventQueue::~DOMWindowEventQueue()
72 DEFINE_TRACE(DOMWindowEventQueue
)
75 visitor
->trace(m_pendingEventTimer
);
76 visitor
->trace(m_queuedEvents
);
78 EventQueue::trace(visitor
);
81 bool DOMWindowEventQueue::enqueueEvent(PassRefPtrWillBeRawPtr
<Event
> event
)
86 ASSERT(event
->target());
87 InspectorInstrumentation::didEnqueueEvent(event
->target(), event
.get());
89 bool wasAdded
= m_queuedEvents
.add(event
).isNewEntry
;
90 ASSERT_UNUSED(wasAdded
, wasAdded
); // It should not have already been in the list.
92 if (!m_pendingEventTimer
->isActive())
93 m_pendingEventTimer
->startOneShot(0, FROM_HERE
);
98 bool DOMWindowEventQueue::cancelEvent(Event
* event
)
100 WillBeHeapListHashSet
<RefPtrWillBeMember
<Event
>, 16>::iterator it
= m_queuedEvents
.find(event
);
101 bool found
= it
!= m_queuedEvents
.end();
103 InspectorInstrumentation::didRemoveEvent(event
->target(), event
);
104 m_queuedEvents
.remove(it
);
106 if (m_queuedEvents
.isEmpty())
107 m_pendingEventTimer
->stop();
111 void DOMWindowEventQueue::close()
114 m_pendingEventTimer
->stop();
115 if (InspectorInstrumentation::hasFrontends()) {
116 for (const auto& queuedEvent
: m_queuedEvents
) {
117 RefPtrWillBeRawPtr
<Event
> event
= queuedEvent
;
119 InspectorInstrumentation::didRemoveEvent(event
->target(), event
.get());
122 m_queuedEvents
.clear();
125 void DOMWindowEventQueue::pendingEventTimerFired()
127 ASSERT(!m_pendingEventTimer
->isActive());
128 ASSERT(!m_queuedEvents
.isEmpty());
130 // Insert a marker for where we should stop.
131 ASSERT(!m_queuedEvents
.contains(nullptr));
132 bool wasAdded
= m_queuedEvents
.add(nullptr).isNewEntry
;
133 ASSERT_UNUSED(wasAdded
, wasAdded
); // It should not have already been in the list.
135 RefPtrWillBeRawPtr
<DOMWindowEventQueue
> protector(this);
137 while (!m_queuedEvents
.isEmpty()) {
138 WillBeHeapListHashSet
<RefPtrWillBeMember
<Event
>, 16>::iterator iter
= m_queuedEvents
.begin();
139 RefPtrWillBeRawPtr
<Event
> event
= *iter
;
140 m_queuedEvents
.remove(iter
);
143 dispatchEvent(event
.get());
144 InspectorInstrumentation::didRemoveEvent(event
->target(), event
.get());
148 void DOMWindowEventQueue::dispatchEvent(PassRefPtrWillBeRawPtr
<Event
> event
)
150 EventTarget
* eventTarget
= event
->target();
151 if (eventTarget
->toDOMWindow())
152 eventTarget
->toDOMWindow()->dispatchEvent(event
, nullptr);
154 eventTarget
->dispatchEvent(event
);