1 /* 2 * Copyright (C) 2006, 2007, 2008, 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 V8Collection_h 32 #define V8Collection_h 33 34 #include "HTMLFormElement.h" 35 #include "HTMLSelectElement.h" 36 #include "V8Binding.h" 37 #include "V8Node.h" 38 #include "V8Proxy.h" 39 #include <v8.h> 40 41 namespace WebCore { 42 // FIXME: These functions should be named using to* since they return the item (get* is used for method that take a ref param). 43 // See https://bugs.webkit.org/show_bug.cgi?id=24664. 44 45 template<class T> static v8::Handle<v8::Value> getV8Object(T* implementation) 46 { 47 if (!implementation) 48 return v8::Handle<v8::Value>(); 49 return toV8(implementation); 50 } 51 52 template<class Collection> static Collection* toNativeCollection(v8::Local<v8::Object> object) 53 { 54 return reinterpret_cast<Collection*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex)); 55 } 56 57 template<class T> static v8::Handle<v8::Value> getV8Object(PassRefPtr<T> implementation) 58 { 59 return getV8Object(implementation.get()); 60 } 61 62 // Returns named property of a collection. 63 template<class Collection, class ItemType> static v8::Handle<v8::Value> getNamedPropertyOfCollection(v8::Local<v8::String> name, v8::Local<v8::Object> object) 64 { 65 // FIXME: assert object is a collection type 66 ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); 67 ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info); 68 Collection* collection = toNativeCollection<Collection>(object); 69 AtomicString propertyName = toAtomicWebCoreStringWithNullCheck(name); 70 return getV8Object<ItemType>(collection->namedItem(propertyName)); 71 } 72 73 // A template of named property accessor of collections. 74 template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 75 { 76 v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); 77 78 if (!value.IsEmpty()) 79 return value; 80 81 // Search local callback properties next to find IDL defined 82 // properties. 83 if (info.Holder()->HasRealNamedCallbackProperty(name)) 84 return notHandledByInterceptor(); 85 return getNamedPropertyOfCollection<Collection, ItemType>(name, info.Holder()); 86 } 87 88 // Returns the property at the index of a collection. 89 template<class Collection, class ItemType> static v8::Handle<v8::Value> getIndexedPropertyOfCollection(uint32_t index, v8::Local<v8::Object> object) 90 { 91 // FIXME: Assert that object must be a collection type. 92 ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); 93 ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info); 94 Collection* collection = toNativeCollection<Collection>(object); 95 return getV8Object<ItemType>(collection->item(index)); 96 } 97 98 // A template of index interceptor of collections. 99 template<class Collection, class ItemType> static v8::Handle<v8::Value> collectionIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) 100 { 101 return getIndexedPropertyOfCollection<Collection, ItemType>(index, info.Holder()); 102 } 103 104 // Get an array containing the names of indexed properties of HTMLSelectElement and HTMLFormElement. 105 template<class Collection> static v8::Handle<v8::Array> nodeCollectionIndexedPropertyEnumerator(const v8::AccessorInfo& info) 106 { 107 ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 108 Collection* collection = toNativeCollection<Collection>(info.Holder()); 109 int length = collection->length(); 110 v8::Handle<v8::Array> properties = v8::Array::New(length); 111 for (int i = 0; i < length; ++i) { 112 // FIXME: Do we need to check that the item function returns a non-null value for this index? 113 v8::Handle<v8::Integer> integer = v8::Integer::New(i); 114 properties->Set(integer, integer); 115 } 116 return properties; 117 } 118 119 // Get an array containing the names of indexed properties in a collection. 120 template<class Collection> static v8::Handle<v8::Array> collectionIndexedPropertyEnumerator(const v8::AccessorInfo& info) 121 { 122 ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 123 Collection* collection = toNativeCollection<Collection>(info.Holder()); 124 int length = collection->length(); 125 v8::Handle<v8::Array> properties = v8::Array::New(length); 126 for (int i = 0; i < length; ++i) { 127 // FIXME: Do we need to check that the item function returns a non-null value for this index? 128 v8::Handle<v8::Integer> integer = v8::Integer::New(i); 129 properties->Set(integer, integer); 130 } 131 return properties; 132 } 133 134 135 // A template for indexed getters on collections of strings that should return null if the resulting string is a null string. 136 template<class Collection> static v8::Handle<v8::Value> collectionStringOrNullIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) 137 { 138 // FIXME: assert that object must be a collection type 139 ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 140 Collection* collection = toNativeCollection<Collection>(info.Holder()); 141 String result = collection->item(index); 142 return v8StringOrNull(result); 143 } 144 145 146 // A template for indexed getters on collections of strings. 147 template<class Collection> static v8::Handle<v8::Value> collectionStringIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) 148 { 149 // FIXME: assert that object must be a collection type 150 ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 151 Collection* collection = toNativeCollection<Collection>(info.Holder()); 152 String result = collection->item(index); 153 return v8String(result); 154 } 155 156 157 // Add indexed getter to the function template for a collection. 158 template<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 159 { 160 desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 161 } 162 163 164 // Add named getter to the function template for a collection. 165 template<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc) 166 { 167 desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0); 168 } 169 170 // Add indexed getter returning a string or null to a function template for a collection. 171 template<class Collection> static void setCollectionStringOrNullIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 172 { 173 desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 174 } 175 176 177 // Add indexed getter returning a string to a function template for a collection. 178 template<class Collection> static void setCollectionStringIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 179 { 180 desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 181 } 182 183 v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value>, HTMLSelectElement*); 184 185 } // namespace WebCore 186 187 #endif // V8Collection_h 188