• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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