Objective-C API: Rename JSValue.h/APIJSValue.h to JSCJSValue.h/JSValue.h
[WebKit-https.git] / Source / WebCore / bindings / js / JSHTMLAllCollectionCustom.cpp
1 /*
2  * Copyright (C) 2009 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "JSHTMLAllCollection.h"
28
29 #include "HTMLAllCollection.h"
30 #include "JSDOMBinding.h"
31 #include "JSNode.h"
32 #include "JSNodeList.h"
33 #include "Node.h"
34 #include "StaticNodeList.h"
35 #include <runtime/JSCJSValue.h>
36 #include <wtf/Vector.h>
37 #include <wtf/text/AtomicString.h>
38
39 using namespace JSC;
40
41 namespace WebCore {
42
43 static JSValue getNamedItems(ExecState* exec, JSHTMLAllCollection* collection, PropertyName propertyName)
44 {
45     Vector<RefPtr<Node> > namedItems;
46     collection->impl()->namedItems(propertyNameToAtomicString(propertyName), namedItems);
47
48     if (namedItems.isEmpty())
49         return jsUndefined();
50     if (namedItems.size() == 1)
51         return toJS(exec, collection->globalObject(), namedItems[0].get());
52
53     // FIXME: HTML5 specification says this should be a HTMLCollection.
54     // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlallcollection
55     return toJS(exec, collection->globalObject(), StaticNodeList::adopt(namedItems).get());
56 }
57
58 // HTMLAllCollections are strange objects, they support both get and call.
59 static EncodedJSValue JSC_HOST_CALL callHTMLAllCollection(ExecState* exec)
60 {
61     if (exec->argumentCount() < 1)
62         return JSValue::encode(jsUndefined());
63
64     // Do not use thisObj here. It can be the JSHTMLDocument, in the document.forms(i) case.
65     JSHTMLAllCollection* jsCollection = jsCast<JSHTMLAllCollection*>(exec->callee());
66     HTMLAllCollection* collection = static_cast<HTMLAllCollection*>(jsCollection->impl());
67
68     // Also, do we need the TypeError test here ?
69
70     if (exec->argumentCount() == 1) {
71         // Support for document.all(<index>) etc.
72         String string = exec->argument(0).toString(exec)->value(exec);
73         unsigned index = toUInt32FromStringImpl(string.impl());
74         if (index != PropertyName::NotAnIndex)
75             return JSValue::encode(toJS(exec, jsCollection->globalObject(), collection->item(index)));
76
77         // Support for document.images('<name>') etc.
78         return JSValue::encode(getNamedItems(exec, jsCollection, Identifier(exec, string)));
79     }
80
81     // The second arg, if set, is the index of the item we want
82     String string = exec->argument(0).toString(exec)->value(exec);
83     unsigned index = toUInt32FromStringImpl(exec->argument(1).toWTFString(exec).impl());
84     if (index != PropertyName::NotAnIndex) {
85         if (Node* node = collection->namedItemWithIndex(string, index))
86             return JSValue::encode(toJS(exec, jsCollection->globalObject(), node));
87     }
88
89     return JSValue::encode(jsUndefined());
90 }
91
92 CallType JSHTMLAllCollection::getCallData(JSCell*, CallData& callData)
93 {
94     callData.native.function = callHTMLAllCollection;
95     return CallTypeHost;
96 }
97
98 bool JSHTMLAllCollection::canGetItemsForName(ExecState*, HTMLAllCollection* collection, PropertyName propertyName)
99 {
100     return collection->hasNamedItem(propertyNameToAtomicString(propertyName));
101 }
102
103 JSValue JSHTMLAllCollection::nameGetter(ExecState* exec, JSValue slotBase, PropertyName propertyName)
104 {
105     JSHTMLAllCollection* thisObj = jsCast<JSHTMLAllCollection*>(asObject(slotBase));
106     return getNamedItems(exec, thisObj, propertyName);
107 }
108
109 JSValue JSHTMLAllCollection::item(ExecState* exec)
110 {
111     uint32_t index = toUInt32FromStringImpl(exec->argument(0).toString(exec)->value(exec).impl());
112     if (index != PropertyName::NotAnIndex)
113         return toJS(exec, globalObject(), impl()->item(index));
114     return getNamedItems(exec, this, Identifier(exec, exec->argument(0).toString(exec)->value(exec)));
115 }
116
117 JSValue JSHTMLAllCollection::namedItem(ExecState* exec)
118 {
119     return getNamedItems(exec, this, Identifier(exec, exec->argument(0).toString(exec)->value(exec)));
120 }
121
122 } // namespace WebCore