~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/webkit/WebCore/dom/EventTarget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "config.h"
35
35
#include "EventTarget.h"
36
36
 
 
37
#include "Event.h"
 
38
#include "EventException.h"
 
39
#include <wtf/StdLibExtras.h>
 
40
 
 
41
using namespace WTF;
 
42
 
37
43
namespace WebCore {
38
44
 
39
45
#ifndef NDEBUG
40
46
static int gEventDispatchForbidden = 0;
41
 
#endif
 
47
 
 
48
void forbidEventDispatch()
 
49
{
 
50
    if (!isMainThread())
 
51
        return;
 
52
    ++gEventDispatchForbidden;
 
53
}
 
54
 
 
55
void allowEventDispatch()
 
56
{
 
57
    if (!isMainThread())
 
58
        return;
 
59
    if (gEventDispatchForbidden > 0)
 
60
        --gEventDispatchForbidden;
 
61
}
 
62
 
 
63
bool eventDispatchForbidden()
 
64
{
 
65
    if (!isMainThread())
 
66
        return false;
 
67
    return gEventDispatchForbidden > 0;
 
68
}
 
69
#endif // NDEBUG
42
70
 
43
71
EventTarget::~EventTarget()
44
72
{
45
73
}
46
74
 
47
 
EventTargetNode* EventTarget::toNode()
 
75
EventSource* EventTarget::toEventSource()
 
76
{
 
77
    return 0;
 
78
}
 
79
 
 
80
Node* EventTarget::toNode()
 
81
{
 
82
    return 0;
 
83
}
 
84
 
 
85
DOMWindow* EventTarget::toDOMWindow()
48
86
{
49
87
    return 0;
50
88
}
73
111
}
74
112
#endif
75
113
 
 
114
#if ENABLE(WEB_SOCKETS)
 
115
WebSocket* EventTarget::toWebSocket()
 
116
{
 
117
    return 0;
 
118
}
 
119
#endif
 
120
 
76
121
MessagePort* EventTarget::toMessagePort()
77
122
{
78
123
    return 0;
84
129
    return 0;
85
130
}
86
131
 
87
 
WorkerContext* EventTarget::toWorkerContext()
88
 
{
89
 
    return 0;
90
 
}
91
 
#endif
92
 
 
93
 
#ifndef NDEBUG
94
 
void forbidEventDispatch()
95
 
{
96
 
    ++gEventDispatchForbidden;
97
 
}
98
 
 
99
 
void allowEventDispatch()
100
 
{
101
 
    if (gEventDispatchForbidden > 0)
102
 
        --gEventDispatchForbidden;
103
 
}
104
 
 
105
 
bool eventDispatchForbidden()
106
 
{
107
 
    return gEventDispatchForbidden > 0;
108
 
}
109
 
#endif // NDEBUG
110
 
 
111
 
} // end namespace
 
132
DedicatedWorkerContext* EventTarget::toDedicatedWorkerContext()
 
133
{
 
134
    return 0;
 
135
}
 
136
#endif
 
137
 
 
138
#if ENABLE(SHARED_WORKERS)
 
139
SharedWorker* EventTarget::toSharedWorker()
 
140
{
 
141
    return 0;
 
142
}
 
143
SharedWorkerContext* EventTarget::toSharedWorkerContext()
 
144
{
 
145
    return 0;
 
146
}
 
147
#endif
 
148
 
 
149
#if ENABLE(NOTIFICATIONS)
 
150
Notification* EventTarget::toNotification()
 
151
{
 
152
    return 0;
 
153
}
 
154
#endif
 
155
 
 
156
bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 
157
{
 
158
    EventTargetData* d = ensureEventTargetData();
 
159
 
 
160
    pair<EventListenerMap::iterator, bool> result = d->eventListenerMap.add(eventType, EventListenerVector());
 
161
    EventListenerVector& entry = result.first->second;
 
162
 
 
163
    RegisteredEventListener registeredListener(listener, useCapture);
 
164
    if (!result.second) { // pre-existing entry
 
165
        if (entry.find(registeredListener) != notFound) // duplicate listener
 
166
            return false;
 
167
    }
 
168
 
 
169
    entry.append(registeredListener);
 
170
    return true;
 
171
}
 
172
 
 
173
bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 
174
{
 
175
    EventTargetData* d = eventTargetData();
 
176
    if (!d)
 
177
        return false;
 
178
 
 
179
    EventListenerMap::iterator result = d->eventListenerMap.find(eventType);
 
180
    if (result == d->eventListenerMap.end())
 
181
        return false;
 
182
    EventListenerVector& entry = result->second;
 
183
 
 
184
    RegisteredEventListener registeredListener(listener, useCapture);
 
185
    size_t index = entry.find(registeredListener);
 
186
    if (index == notFound)
 
187
        return false;
 
188
 
 
189
    entry.remove(index);
 
190
    if (!entry.size())
 
191
        d->eventListenerMap.remove(result);
 
192
 
 
193
    // Notify firing events planning to invoke the listener at 'index' that
 
194
    // they have one less listener to invoke.
 
195
    for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i) {
 
196
        if (eventType == *d->firingEventEndIterators[i].eventType && index < *d->firingEventEndIterators[i].value)
 
197
            --*d->firingEventEndIterators[i].value;
 
198
    }
 
199
 
 
200
    return true;
 
201
}
 
202
 
 
203
bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
 
204
{
 
205
    clearAttributeEventListener(eventType);
 
206
    if (!listener)
 
207
        return false;
 
208
    return addEventListener(eventType, listener, false);
 
209
}
 
210
 
 
211
EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
 
212
{
 
213
    const EventListenerVector& entry = getEventListeners(eventType);
 
214
    for (size_t i = 0; i < entry.size(); ++i) {
 
215
        if (entry[i].listener->isAttribute())
 
216
            return entry[i].listener.get();
 
217
    }
 
218
    return 0;
 
219
}
 
220
 
 
221
bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
 
222
{
 
223
    EventListener* listener = getAttributeEventListener(eventType);
 
224
    if (!listener)
 
225
        return false;
 
226
    return removeEventListener(eventType, listener, false);
 
227
}
 
228
 
 
229
bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec)
 
230
{
 
231
    if (!event || event->type().isEmpty()) {
 
232
        ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR;
 
233
        return false;
 
234
    }
 
235
    return dispatchEvent(event);
 
236
}
 
237
 
 
238
bool EventTarget::dispatchEvent(PassRefPtr<Event> event)
 
239
{
 
240
    event->setTarget(this);
 
241
    event->setCurrentTarget(this);
 
242
    event->setEventPhase(Event::AT_TARGET);
 
243
    return fireEventListeners(event.get());
 
244
}
 
245
 
 
246
bool EventTarget::fireEventListeners(Event* event)
 
247
{
 
248
    ASSERT(!eventDispatchForbidden());
 
249
    ASSERT(event && !event->type().isEmpty());
 
250
 
 
251
    EventTargetData* d = eventTargetData();
 
252
    if (!d)
 
253
        return true;
 
254
 
 
255
    EventListenerMap::iterator result = d->eventListenerMap.find(event->type());
 
256
    if (result == d->eventListenerMap.end())
 
257
        return false;
 
258
    EventListenerVector& entry = result->second;
 
259
 
 
260
    RefPtr<EventTarget> protect = this;
 
261
 
 
262
    size_t end = entry.size();
 
263
    d->firingEventEndIterators.append(FiringEventEndIterator(&event->type(), &end));
 
264
    for (size_t i = 0; i < end; ++i) {
 
265
        RegisteredEventListener& registeredListener = entry[i];
 
266
        if (event->eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture)
 
267
            continue;
 
268
        if (event->eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture)
 
269
            continue;
 
270
        // To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
 
271
        // event listeners, even though that violates some versions of the DOM spec.
 
272
        registeredListener.listener->handleEvent(scriptExecutionContext(), event);
 
273
    }
 
274
    d->firingEventEndIterators.removeLast();
 
275
 
 
276
    return !event->defaultPrevented();
 
277
}
 
278
 
 
279
const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType)
 
280
{
 
281
    DEFINE_STATIC_LOCAL(EventListenerVector, emptyVector, ());
 
282
 
 
283
    EventTargetData* d = eventTargetData();
 
284
    if (!d)
 
285
        return emptyVector;
 
286
    EventListenerMap::iterator it = d->eventListenerMap.find(eventType);
 
287
    if (it == d->eventListenerMap.end())
 
288
        return emptyVector;
 
289
    return it->second;
 
290
}
 
291
 
 
292
void EventTarget::removeAllEventListeners()
 
293
{
 
294
    EventTargetData* d = eventTargetData();
 
295
    if (!d)
 
296
        return;
 
297
    d->eventListenerMap.clear();
 
298
 
 
299
    // Notify firing events planning to invoke the listener at 'index' that
 
300
    // they have one less listener to invoke.
 
301
    for (size_t i = 0; i < d->firingEventEndIterators.size(); ++i)
 
302
        *d->firingEventEndIterators[i].value = 0;
 
303
}
 
304
 
 
305
} // namespace WebCore