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 #ifndef V8EventListenerList_h 32 #define V8EventListenerList_h 33 34 #include <v8.h> 35 #include <wtf/Vector.h> 36 #include <wtf/HashMap.h> 37 38 #include "PassRefPtr.h" 39 40 namespace WebCore { 41 class Frame; 42 class V8EventListener; 43 class V8EventListenerListIterator; 44 45 // This is a container for V8EventListener objects that uses the identity hash of the v8::Object to 46 // speed up lookups 47 class V8EventListenerList { 48 public: 49 // Because v8::Object identity hashes are not guaranteed to be unique, we unfortunately can't just map 50 // an int to V8EventListener. Instead we define a HashMap of int to Vector of V8EventListener 51 // called a ListenerMultiMap. 52 typedef Vector<V8EventListener*>* Values; 53 struct ValuesTraits : HashTraits<Values> { 54 static const bool needsDestruction = true; 55 }; 56 typedef HashMap<int, Values, DefaultHash<int>::Hash, HashTraits<int>, ValuesTraits> ListenerMultiMap; 57 58 V8EventListenerList(); 59 ~V8EventListenerList(); 60 61 friend class V8EventListenerListIterator; 62 typedef V8EventListenerListIterator iterator; 63 64 iterator begin(); 65 iterator end(); 66 67 void add(V8EventListener*); 68 void remove(V8EventListener*); 69 V8EventListener* find(v8::Local<v8::Object>, bool isAttribute); 70 void clear(); size()71 size_t size() { return m_table.size(); } 72 73 PassRefPtr<V8EventListener> findWrapper(v8::Local<v8::Value>, bool isAttribute); 74 template<typename WrapperType> 75 PassRefPtr<V8EventListener> findOrCreateWrapper(Frame*, v8::Local<v8::Value>, bool isAttribute); 76 77 private: 78 ListenerMultiMap m_table; 79 80 // we also keep a reverse mapping of V8EventListener to v8::Object identity hash, 81 // in order to speed up removal by V8EventListener 82 HashMap<V8EventListener*, int> m_reverseTable; 83 }; 84 85 class V8EventListenerListIterator { 86 public: 87 ~V8EventListenerListIterator(); 88 void operator++(); 89 bool operator==(const V8EventListenerListIterator&); 90 bool operator!=(const V8EventListenerListIterator&); 91 V8EventListener* operator*(); 92 private: 93 friend class V8EventListenerList; 94 explicit V8EventListenerListIterator(V8EventListenerList*); 95 V8EventListenerListIterator(V8EventListenerList*, bool shouldSeekToEnd); 96 void seekToEnd(); 97 98 V8EventListenerList* m_list; 99 V8EventListenerList::ListenerMultiMap::iterator m_iter; 100 size_t m_vectorIndex; 101 }; 102 103 template<typename WrapperType> findOrCreateWrapper(Frame * frame,v8::Local<v8::Value> object,bool isAttribute)104 PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(Frame* frame, v8::Local<v8::Value> object, bool isAttribute) 105 { 106 ASSERT(v8::Context::InContext()); 107 if (!object->IsObject()) 108 return 0; 109 110 // FIXME: Should this be v8::Local<v8::Object>::Cast instead? 111 V8EventListener* wrapper = find(object->ToObject(), isAttribute); 112 if (wrapper) 113 return wrapper; 114 115 // Create a new one, and add to cache. 116 RefPtr<WrapperType> newListener = WrapperType::create(frame, v8::Local<v8::Object>::Cast(object), isAttribute); 117 add(newListener.get()); 118 119 return newListener; 120 }; 121 122 } // namespace WebCore 123 124 #endif // V8EventListenerList_h 125