18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/* 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. 38f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 48f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Redistribution and use in source and binary forms, with or without 58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * modification, are permitted provided that the following conditions are 68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * met: 78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * * Redistributions of source code must retain the above copyright 98f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * notice, this list of conditions and the following disclaimer. 108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * * Redistributions in binary form must reproduce the above 118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * copyright notice, this list of conditions and the following disclaimer 128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * in the documentation and/or other materials provided with the 138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * distribution. 148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * * Neither the name of Google Inc. nor the names of its 158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * contributors may be used to endorse or promote products derived from 168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * this software without specific prior written permission. 178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */ 308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifndef V8Collection_h 328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define V8Collection_h 338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLFormElement.h" 355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "HTMLSelectElement.h" 368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8Binding.h" 37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "V8Node.h" 388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8Proxy.h" 398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include <v8.h> 408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore { 425e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// FIXME: These functions should be named using to* since they return the item (get* is used for method that take a ref param). 435e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// See https://bugs.webkit.org/show_bug.cgi?id=24664. 445e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 455e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class T> static v8::Handle<v8::Value> getV8Object(T* implementation) 465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 475e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (!implementation) 485e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return v8::Handle<v8::Value>(); 495e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return toV8(implementation); 505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 515e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 525e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static Collection* toNativeCollection(v8::Local<v8::Object> object) 535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 545e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return reinterpret_cast<Collection*>(object->GetPointerFromInternalField(v8DOMWrapperObjectIndex)); 555e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 565e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 575e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class T> static v8::Handle<v8::Value> getV8Object(PassRefPtr<T> implementation) 585e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return getV8Object(implementation.get()); 605e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 615e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Returns named property of a collection. 635e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection, class ItemType> static v8::Handle<v8::Value> getNamedPropertyOfCollection(v8::Local<v8::String> name, v8::Local<v8::Object> object) 645e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 655e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: assert object is a collection type 665e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); 67dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info); 685e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block Collection* collection = toNativeCollection<Collection>(object); 695e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block AtomicString propertyName = toAtomicWebCoreStringWithNullCheck(name); 705e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return getV8Object<ItemType>(collection->namedItem(propertyName)); 715e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 725e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 735e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// A template of named property accessor of collections. 745e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection, class ItemType> static v8::Handle<v8::Value> collectionNamedPropertyGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) 755e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 765e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block v8::Handle<v8::Value> value = info.Holder()->GetRealNamedPropertyInPrototypeChain(name); 775e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 785e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (!value.IsEmpty()) 795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return value; 805e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 815e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // Search local callback properties next to find IDL defined 825e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // properties. 835e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (info.Holder()->HasRealNamedCallbackProperty(name)) 845e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return notHandledByInterceptor(); 855e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return getNamedPropertyOfCollection<Collection, ItemType>(name, info.Holder()); 865e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 875e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Returns the property at the index of a collection. 895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection, class ItemType> static v8::Handle<v8::Value> getIndexedPropertyOfCollection(uint32_t index, v8::Local<v8::Object> object) 905e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 915e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: Assert that object must be a collection type. 925e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block ASSERT(V8DOMWrapper::maybeDOMWrapper(object)); 93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block ASSERT(V8DOMWrapper::domWrapperType(object) != &V8Node::info); 945e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block Collection* collection = toNativeCollection<Collection>(object); 955e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return getV8Object<ItemType>(collection->item(index)); 965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 975e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 985e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// A template of index interceptor of collections. 995e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection, class ItemType> static v8::Handle<v8::Value> collectionIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) 1005e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1015e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return getIndexedPropertyOfCollection<Collection, ItemType>(index, info.Holder()); 1025e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1035e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1045e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Get an array containing the names of indexed properties of HTMLSelectElement and HTMLFormElement. 1055e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static v8::Handle<v8::Array> nodeCollectionIndexedPropertyEnumerator(const v8::AccessorInfo& info) 1065e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1075e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 1085e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block Collection* collection = toNativeCollection<Collection>(info.Holder()); 1095e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block int length = collection->length(); 1105e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block v8::Handle<v8::Array> properties = v8::Array::New(length); 1115e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block for (int i = 0; i < length; ++i) { 1125e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: Do we need to check that the item function returns a non-null value for this index? 1135e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block v8::Handle<v8::Integer> integer = v8::Integer::New(i); 1145e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block properties->Set(integer, integer); 1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1165e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return properties; 1175e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1185e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1195e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Get an array containing the names of indexed properties in a collection. 1205e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static v8::Handle<v8::Array> collectionIndexedPropertyEnumerator(const v8::AccessorInfo& info) 1215e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1225e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 1235e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block Collection* collection = toNativeCollection<Collection>(info.Holder()); 1245e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block int length = collection->length(); 1255e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block v8::Handle<v8::Array> properties = v8::Array::New(length); 1265e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block for (int i = 0; i < length; ++i) { 1275e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: Do we need to check that the item function returns a non-null value for this index? 1285e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block v8::Handle<v8::Integer> integer = v8::Integer::New(i); 1295e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block properties->Set(integer, integer); 1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1315e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return properties; 1325e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1335e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1345e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1355e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// A template for indexed getters on collections of strings that should return null if the resulting string is a null string. 1365e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static v8::Handle<v8::Value> collectionStringOrNullIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) 1375e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1385e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: assert that object must be a collection type 1395e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 1405e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block Collection* collection = toNativeCollection<Collection>(info.Holder()); 1415e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block String result = collection->item(index); 1425e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return v8StringOrNull(result); 1435e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1445e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1455e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// A template for indexed getters on collections of strings. 1475e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static v8::Handle<v8::Value> collectionStringIndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) 1485e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1495e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: assert that object must be a collection type 1505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block ASSERT(V8DOMWrapper::maybeDOMWrapper(info.Holder())); 1515e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block Collection* collection = toNativeCollection<Collection>(info.Holder()); 1525e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block String result = collection->item(index); 1535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return v8String(result); 1545e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1555e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1565e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1575e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Add indexed getter to the function template for a collection. 158dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktemplate<class Collection, class ItemType> static void setCollectionIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 1595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionIndexedPropertyGetter<Collection, ItemType>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 1615e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1635e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1645e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Add named getter to the function template for a collection. 165dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blocktemplate<class Collection, class ItemType> static void setCollectionNamedGetter(v8::Handle<v8::FunctionTemplate> desc) 1665e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 167dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block desc->InstanceTemplate()->SetNamedPropertyHandler(collectionNamedPropertyGetter<Collection, ItemType>, 0, 0, 0, 0); 1685e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1695e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1705e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Add indexed getter returning a string or null to a function template for a collection. 1715e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static void setCollectionStringOrNullIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 1725e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1735e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringOrNullIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 1745e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1755e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1765e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1775e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block// Add indexed getter returning a string to a function template for a collection. 1785e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blocktemplate<class Collection> static void setCollectionStringIndexedGetter(v8::Handle<v8::FunctionTemplate> desc) 1795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 1805e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block desc->InstanceTemplate()->SetIndexedPropertyHandler(collectionStringIndexedPropertyGetter<Collection>, 0, 0, 0, collectionIndexedPropertyEnumerator<Collection>); 1815e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 1825e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 1835e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockv8::Handle<v8::Value> toOptionsCollectionSetter(uint32_t index, v8::Handle<v8::Value>, HTMLSelectElement*); 1845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore 1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // V8Collection_h 188