18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details. 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB. If not, write to 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA. 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSHTMLCollection.h" 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLCollection.h" 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLOptionsCollection.h" 25cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block#include "HTMLAllCollection.h" 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "JSDOMBinding.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSHTMLAllCollection.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSHTMLOptionsCollection.h" 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSNode.h" 30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "JSNodeList.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Node.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "StaticNodeList.h" 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/Vector.h> 34f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/AtomicString.h> 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC; 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic JSValue getNamedItems(ExecState* exec, JSHTMLCollection* collection, const Identifier& propertyName) 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<RefPtr<Node> > namedItems; 43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block collection->impl()->namedItems(identifierToAtomicString(propertyName), namedItems); 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (namedItems.isEmpty()) 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsUndefined(); 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (namedItems.size() == 1) 480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return toJS(exec, collection->globalObject(), namedItems[0].get()); 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: HTML5 specifies that this should be a DynamicNodeList. 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: HTML5 specifies that non-HTMLOptionsCollection collections should return 52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // the first matching item instead of a NodeList. 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return toJS(exec, collection->globalObject(), StaticNodeList::adopt(namedItems).get()); 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// HTMLCollections are strange objects, they support both get and call, 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// so that document.forms.item(0) and document.forms(0) both work. 58545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdochstatic EncodedJSValue JSC_HOST_CALL callHTMLCollection(ExecState* exec) 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 605af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (exec->argumentCount() < 1) 61545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return JSValue::encode(jsUndefined()); 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Do not use thisObj here. It can be the JSHTMLDocument, in the document.forms(i) case. 645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke JSHTMLCollection* jsCollection = static_cast<JSHTMLCollection*>(exec->callee()); 650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch HTMLCollection* collection = jsCollection->impl(); 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Also, do we need the TypeError test here ? 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (exec->argumentCount() == 1) { 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Support for document.all(<index>) etc. 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ok; 725af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke UString string = exec->argument(0).toString(exec); 73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned index = Identifier::toUInt32(string, ok); 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ok) 75545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return JSValue::encode(toJS(exec, jsCollection->globalObject(), collection->item(index))); 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Support for document.images('<name>') etc. 78545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return JSValue::encode(getNamedItems(exec, jsCollection, Identifier(exec, string))); 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // The second arg, if set, is the index of the item we want 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ok; 835af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke UString string = exec->argument(0).toString(exec); 84f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick unsigned index = Identifier::toUInt32(exec->argument(1).toString(exec), ok); 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ok) { 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block String pstr = ustringToString(string); 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Node* node = collection->namedItem(pstr); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (node) { 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!index) 90545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return JSValue::encode(toJS(exec, jsCollection->globalObject(), node)); 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project node = collection->nextNamedItem(pstr); 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project --index; 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 96545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch return JSValue::encode(jsUndefined()); 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCallType JSHTMLCollection::getCallData(CallData& callData) 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project callData.native.function = callHTMLCollection; 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return CallTypeHost; 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochbool JSHTMLCollection::canGetItemsForName(ExecState*, HTMLCollection* collection, const Identifier& propertyName) 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Vector<RefPtr<Node> > namedItems; 108dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block collection->namedItems(identifierToAtomicString(propertyName), namedItems); 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return !namedItems.isEmpty(); 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue JSHTMLCollection::nameGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block JSHTMLCollection* thisObj = static_cast<JSHTMLCollection*>(asObject(slotBase)); 1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return getNamedItems(exec, thisObj, propertyName); 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1185af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue JSHTMLCollection::item(ExecState* exec) 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool ok; 121f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick uint32_t index = Identifier::toUInt32(exec->argument(0).toString(exec), ok); 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ok) 1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return toJS(exec, globalObject(), impl()->item(index)); 1245af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return getNamedItems(exec, this, Identifier(exec, exec->argument(0).toString(exec))); 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1275af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue JSHTMLCollection::namedItem(ExecState* exec) 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return getNamedItems(exec, this, Identifier(exec, exec->argument(0).toString(exec))); 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochJSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, HTMLCollection* collection) 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!collection) 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch JSDOMWrapper* wrapper = getCachedWrapper(currentWorld(exec), collection); 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (wrapper) 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return wrapper; 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project switch (collection->type()) { 1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian case SelectOptions: 1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLOptionsCollection, collection); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian case DocAll: 1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLAllCollection, collection); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project default: 1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch wrapper = CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, HTMLCollection, collection); 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project break; 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return wrapper; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 158