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