OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 17 matching lines...) Expand all Loading... |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "V8EventListenerList.h" | 32 #include "V8EventListenerList.h" |
33 | 33 |
34 #include "V8CustomEventListener.h" | 34 #include "V8CustomEventListener.h" |
35 | 35 |
36 namespace WebCore { | 36 namespace WebCore { |
37 | 37 |
38 V8EventListenerList::V8EventListenerList(const char* name) | 38 V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* li
st) |
| 39 : m_list(list) |
| 40 , m_vectorIndex(0) |
| 41 , m_iter(list->m_table.begin()) |
39 { | 42 { |
40 ASSERT(strlen(name) <= maxKeyNameLength); | 43 } |
41 v8::HandleScope handleScope; | |
42 | 44 |
43 // Write the name into a temporary buffer, leaving 1 space at the beginning | 45 V8EventListenerListIterator::V8EventListenerListIterator(V8EventListenerList* li
st, bool shouldSeekToEnd) |
44 // for a prefix we'll vary between the inline and non-inline keys. | 46 : m_list(list) |
45 char keyBuffer[maxKeyNameLength + 2] = { 0 }; | 47 , m_vectorIndex(0) |
46 strncpy(keyBuffer + 1, name, maxKeyNameLength); | 48 , m_iter(list->m_table.begin()) |
47 keyBuffer[0] = '1'; | 49 { |
48 m_inlineKey = v8::Persistent<v8::String>::New(v8::String::New(keyBuffer)); | 50 if (shouldSeekToEnd) |
49 keyBuffer[0] = '2'; | 51 seekToEnd(); |
50 m_nonInlineKey = v8::Persistent<v8::String>::New(v8::String::New(keyBuffer))
; | 52 } |
| 53 |
| 54 V8EventListenerListIterator::~V8EventListenerListIterator() { } |
| 55 |
| 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 |
| 69 bool V8EventListenerListIterator::operator==(const V8EventListenerListIterator&
other) |
| 70 { |
| 71 return other.m_iter == m_iter && other.m_vectorIndex == m_vectorIndex && oth
er.m_list == m_list; |
| 72 } |
| 73 |
| 74 bool V8EventListenerListIterator::operator!=(const V8EventListenerListIterator&
other) |
| 75 { |
| 76 return !operator==(other); |
| 77 } |
| 78 |
| 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 |
| 89 void V8EventListenerListIterator::seekToEnd() |
| 90 { |
| 91 m_iter = m_list->m_table.end(); |
| 92 m_vectorIndex = 0; |
| 93 } |
| 94 |
| 95 |
| 96 V8EventListenerList::V8EventListenerList() |
| 97 { |
51 } | 98 } |
52 | 99 |
53 V8EventListenerList::~V8EventListenerList() | 100 V8EventListenerList::~V8EventListenerList() |
54 { | 101 { |
55 m_inlineKey.Dispose(); | |
56 m_nonInlineKey.Dispose(); | |
57 } | 102 } |
58 | 103 |
59 V8EventListenerList::iterator V8EventListenerList::begin() | 104 V8EventListenerListIterator V8EventListenerList::begin() |
60 { | 105 { |
61 return m_list.begin(); | 106 return iterator(this); |
62 } | 107 } |
63 | 108 |
64 V8EventListenerList::iterator V8EventListenerList::end() | 109 V8EventListenerListIterator V8EventListenerList::end() |
65 { | 110 { |
66 return m_list.end(); | 111 return iterator(this, true); |
67 } | 112 } |
68 | 113 |
69 v8::Handle<v8::String> V8EventListenerList::getKey(bool isInline) | 114 |
| 115 int getKey(v8::Local<v8::Object> object) |
70 { | 116 { |
71 return isInline ? m_inlineKey : m_nonInlineKey; | 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; |
72 } | 122 } |
73 | 123 |
74 // See comment in .h file for this function, and update accordingly if implement
ation details change here. | |
75 void V8EventListenerList::add(V8EventListener* listener) | 124 void V8EventListenerList::add(V8EventListener* listener) |
76 { | 125 { |
77 // FIXME: http://crbug.com/10562 | 126 ASSERT(v8::Context::InContext()); |
78 //ASSERT(v8::Context::InContext()); | 127 v8::HandleScope handleScope; |
79 m_list.append(listener); | |
80 | 128 |
81 v8::HandleScope handleScope; | |
82 v8::Local<v8::Object> object = listener->getListenerObject(); | 129 v8::Local<v8::Object> object = listener->getListenerObject(); |
83 v8::Local<v8::Value> value = v8::External::Wrap(listener); | 130 int key = getKey(object); |
84 object->SetHiddenValue(getKey(listener->isAttribute()), value); | 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); |
85 } | 138 } |
86 | 139 |
87 void V8EventListenerList::remove(V8EventListener* listener) | 140 void V8EventListenerList::remove(V8EventListener* listener) |
88 { | 141 { |
89 // FIXME: http://crbug.com/10562 | 142 if (m_reverseTable.contains(listener)) { |
90 //ASSERT(v8::Context::InContext()); | 143 int key = m_reverseTable.get(listener); |
91 v8::HandleScope handleScope; | 144 Vector<V8EventListener*>* vector = m_table.get(key); |
92 v8::Handle<v8::String> key = getKey(listener->isAttribute()); | 145 if (!vector) |
93 for (size_t i = 0; i < m_list.size(); i++) { | 146 return; |
94 V8EventListener* element = m_list.at(i); | 147 for (size_t j = 0; j < vector->size(); j++) { |
95 if (element->isAttribute() == listener->isAttribute() && element == list
ener) { | 148 if (vector->at(j) == listener) { |
96 v8::Local<v8::Object> object = listener->getListenerObject(); | 149 vector->remove(j); |
| 150 if (!vector->size()) |
| 151 m_table.remove(key); |
97 | 152 |
98 // FIXME(asargent) this check for hidden value being !empty is a wor
karound for | 153 m_reverseTable.remove(listener); |
99 // http://code.google.com/p/v8/issues/detail?id=300 | 154 return; |
100 // Once the fix for that is pulled into chromium we can remove the c
heck here. | 155 } |
101 if (!object->GetHiddenValue(key).IsEmpty()) | |
102 object->DeleteHiddenValue(getKey(listener->isAttribute())); | |
103 m_list.remove(i); | |
104 break; | |
105 } | 156 } |
106 } | 157 } |
107 } | 158 } |
108 | 159 |
109 void V8EventListenerList::clear() | 160 void V8EventListenerList::clear() |
110 { | 161 { |
111 // FIXME: http://crbug.com/10562 | 162 m_table.clear(); |
112 //ASSERT(v8::Context::InContext()); | 163 m_reverseTable.clear(); |
113 v8::HandleScope handleScope; | |
114 for (size_t i = 0; i < m_list.size(); i++) { | |
115 V8EventListener* element = m_list.at(i); | |
116 v8::Local<v8::Object> object = element->getListenerObject(); | |
117 object->DeleteHiddenValue(getKey(element->isAttribute())); | |
118 } | |
119 m_list.clear(); | |
120 } | 164 } |
121 | 165 |
122 V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool is
Inline) | 166 V8EventListener* V8EventListenerList::find(v8::Local<v8::Object> object, bool is
Attribute) |
123 { | 167 { |
124 v8::Local<v8::Value> value = object->GetHiddenValue(getKey(isInline)); | 168 ASSERT(v8::Context::InContext()); |
125 if (value.IsEmpty()) | 169 int key = getKey(object); |
| 170 |
| 171 Vector<V8EventListener*>* vector = m_table.get(key); |
| 172 if (!vector) |
126 return 0; | 173 return 0; |
127 return reinterpret_cast<V8EventListener*>(v8::External::Unwrap(value)); | 174 |
| 175 for (size_t i = 0; i < vector->size(); i++) { |
| 176 V8EventListener* element = vector->at(i); |
| 177 if (isAttribute == element->isAttribute() && object == element->getListe
nerObject()) |
| 178 return element; |
| 179 } |
| 180 return 0; |
128 } | 181 } |
129 | 182 |
130 } // namespace WebCore | 183 } // namespace WebCore |
OLD | NEW |