18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/*
28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 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#include "config.h"
32d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "V8HTMLOptionsCollection.h"
338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
34d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "HTMLOptionsCollection.h"
358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "HTMLOptionElement.h"
368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "ExceptionCode.h"
378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8Binding.h"
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "V8Collection.h"
408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8HTMLOptionElement.h"
418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8HTMLSelectElementCustom.h"
425e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#include "V8Node.h"
438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "V8Proxy.h"
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace WebCore {
468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
47d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8HTMLOptionsCollection::removeCallback(const v8::Arguments& args)
488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    INC_STATS("DOM.HTMLOptionsCollection.remove()");
50d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(args.Holder());
518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    HTMLSelectElement* base = static_cast<HTMLSelectElement*>(imp->base());
528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return removeElement(base, args);
538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
55d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8HTMLOptionsCollection::addCallback(const v8::Arguments& args)
568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    INC_STATS("DOM.HTMLOptionsCollection.add()");
588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!V8HTMLOptionElement::HasInstance(args[0])) {
590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        return v8::Undefined();
618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
62d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(args.Holder());
63d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionElement* option = V8HTMLOptionElement::toNative(v8::Handle<v8::Object>(v8::Handle<v8::Object>::Cast(args[0])));
648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ExceptionCode ec = 0;
668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (args.Length() < 2)
678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        imp->add(option, ec);
688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    else {
698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        bool ok;
708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        v8::TryCatch try_catch;
710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int index = toInt32(args[1], ok);
728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (try_catch.HasCaught())
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            return v8::Undefined();
758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (!ok)
778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ec = TYPE_MISMATCH_ERR;
788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else
798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            imp->add(option, index, ec);
808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (ec != 0)
830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        V8Proxy::setDOMException(ec);
848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return v8::Undefined();
868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
88d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8HTMLOptionsCollection::lengthAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    INC_STATS("DOM.HTMLOptionsCollection.length._get");
91d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder());
928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    int v = imp->length();
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    return v8::Integer::New(v);
948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
96d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid V8HTMLOptionsCollection::lengthAccessorSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian{
988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    INC_STATS("DOM.HTMLOptionsCollection.length._set");
99d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionsCollection* imp = V8HTMLOptionsCollection::toNative(info.Holder());
1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    double v = value->NumberValue();
1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    unsigned newLength = 0;
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    ExceptionCode ec = 0;
1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!isnan(v) && !isinf(v)) {
1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        if (v < 0.0)
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            ec = INDEX_SIZE_ERR;
1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else if (v > static_cast<double>(UINT_MAX))
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            newLength = UINT_MAX;
1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        else
1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            newLength = static_cast<unsigned>(v);
1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    }
1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    if (!ec)
1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian        imp->setLength(value->Uint32Value(), ec);
1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    V8Proxy::setDOMException(ec);
1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian}
1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
117d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8HTMLOptionsCollection::indexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info)
1185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertyGetter");
120d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionsCollection* collection = V8HTMLOptionsCollection::toNative(info.Holder());
1215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RefPtr<Node> result = collection->item(index);
1235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    if (!result)
1245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return notHandledByInterceptor();
1255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1265e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block    return toV8(result.release());
1275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
129d0825bca7fe65beaee391d30da42e937db621564Steve Blockv8::Handle<v8::Value> V8HTMLOptionsCollection::indexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
1305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{
1315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    INC_STATS("DOM.HTMLOptionsCollection.IndexedPropertySetter");
132d0825bca7fe65beaee391d30da42e937db621564Steve Block    HTMLOptionsCollection* collection = V8HTMLOptionsCollection::toNative(info.Holder());
1335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    HTMLSelectElement* base = static_cast<HTMLSelectElement*>(collection->base());
1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    return toOptionsCollectionSetter(index, value, base);
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian}
1365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace WebCore
138