1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "V8EventListenerList.h"
33
34 #include "V8CustomEventListener.h"
35
36 namespace WebCore {
37
V8EventListenerListIterator(V8EventListenerList * list)38 V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list)
39 : m_list(list)
40 , m_vectorIndex(0)
41 , m_iter(list->m_table.begin())
42 {
43 }
44
V8EventListenerListIterator(V8EventListenerList * list,bool shouldSeekToEnd)45 V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* list, bool shouldSeekToEnd)
46 : m_list(list)
47 , m_vectorIndex(0)
48 , m_iter(list->m_table.begin())
49 {
50 if (shouldSeekToEnd)
51 seekToEnd();
52 }
53
~V8EventListenerListIterator()54 V8EventListenerListIterator::~V8EventListenerListIterator() { }
55
operator ++()56 void V8EventListenerListIterator::operator++()
57 {
58 if (m_iter != m_list->m_table.end()) {
59 Vector<V8EventListener*>* vector = m_iter->second;
60 if (m_vectorIndex + 1 < vector->size()) {
61 m_vectorIndex++;
62 return;
63 }
64 m_vectorIndex = 0;
65 ++m_iter;
66 }
67 }
68
operator ==(const V8EventListenerListIterator & other)69 bool V8EventListenerListIterator::operator==(const V8EventListenerListIterator& other)
70 {
71 return other.m_iter == m_iter && other.m_vectorIndex == m_vectorIndex && other.m_list == m_list;
72 }
73
operator !=(const V8EventListenerListIterator & other)74 bool V8EventListenerListIterator::operator!=(const V8EventListenerListIterator& other)
75 {
76 return !operator==(other);
77 }
78
operator *()79 V8EventListener* V8EventListenerListIterator::operator*()
80 {
81 if (m_iter != m_list->m_table.end()) {
82 Vector<V8EventListener*>* vector = m_iter->second;
83 if (m_vectorIndex < vector->size())
84 return vector->at(m_vectorIndex);
85 }
86 return 0;
87 }
88
seekToEnd()89 void V8EventListenerListIterator::seekToEnd()
90 {
91 m_iter = m_list->m_table.end();
92 m_vectorIndex = 0;
93 }
94
95
V8EventListenerList()96 V8EventListenerList::V8EventListenerList()
97 {
98 }
99
~V8EventListenerList()100 V8EventListenerList::~V8EventListenerList()
101 {
102 }
103
begin()104 V8EventListenerListIterator V8EventListenerList::begin()
105 {
106 return iterator(this);
107 }
108
end()109 V8EventListenerListIterator V8EventListenerList::end()
110 {
111 return iterator(this, true);
112 }
113
114
getKey(v8::Local<v8::Object> object)115 static int getKey(v8::Local<v8::Object> object)
116 {
117 // 0 is a sentinel value for the HashMap key, so we map it to 1.
118 int hash = object->GetIdentityHash();
119 if (!hash)
120 return 1;
121 return hash;
122 }
123
add(V8EventListener * listener)124 void V8EventListenerList::add(V8EventListener* listener)
125 {
126 ASSERT(v8::Context::InContext());
127 v8::HandleScope handleScope;
128
129 v8::Local<v8::Object> object = listener->getListenerObject();
130 int key = getKey(object);
131 Vector<V8EventListener*>* vector = m_table.get(key);
132 if (!vector) {
133 vector = new Vector<V8EventListener*>();
134 m_table.set(key, vector);
135 }
136 vector->append(listener);
137 m_reverseTable.set(listener, key);
138 }
139
remove(V8EventListener * listener)140 void V8EventListenerList::remove(V8EventListener* listener)
141 {
142 if (m_reverseTable.contains(listener)) {
143 int key = m_reverseTable.get(listener);
144 Vector<V8EventListener*>* vector = m_table.get(key);
145 if (!vector)
146 return;
147 for (size_t j = 0; j < vector->size(); j++) {
148 if (vector->at(j) == listener) {
149 vector->remove(j);
150 if (!vector->size()) {
151 m_table.remove(key);
152 delete vector;
153 vector = 0;
154 }
155 m_reverseTable.remove(listener);
156 return;
157 }
158 }
159 }
160 }
161
clear()162 void V8EventListenerList::clear()
163 {
164 m_table.clear();
165 m_reverseTable.clear();
166 }
167
find(v8::Local<v8::Object> object,bool isAttribute)168 V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool isAttribute)
169 {
170 ASSERT(v8::Context::InContext());
171 int key = getKey(object);
172
173 Vector<V8EventListener*>* vector = m_table.get(key);
174 if (!vector)
175 return 0;
176
177 for (size_t i = 0; i < vector->size(); i++) {
178 V8EventListener* element = vector->at(i);
179 if (isAttribute == element->isAttribute() && object == element->getListenerObject())
180 return element;
181 }
182 return 0;
183 }
184
findWrapper(v8::Local<v8::Value> object,bool isAttribute)185 PassRefPtr<V8EventListener> V8EventListenerList::findWrapper(v8::Local<v8::Value> object, bool isAttribute)
186 {
187 ASSERT(v8::Context::InContext());
188 if (!object->IsObject())
189 return 0;
190
191 // FIXME: Should this be v8::Local<v8::Object>::Cast instead?
192 return find(object->ToObject(), isAttribute);
193 }
194
195 } // namespace WebCore
196