| 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 |