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 41namespace 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 45template<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 52template<class Collection> static Collection* toNativeCollection(v8::Local<v8::Object> object) 53{ 54 return reinterpret_cast<Collection*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex)); 55} 56 57template<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. 63template<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. 74template<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. 89template<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. 99template<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. 105template<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. 120template<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. 136template<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. 147template<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. 158template<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. 165template<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. 171template<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. 178template<class Collection> static void setCollectionStringIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 179{ 180 desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 181} 182 183v8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value>, HTMLSelectElement*); 184 185} // namespace WebCore 186 187#endif // V8Collection_h 188