Version: 3.5.4 (using KDE 3.5.4, Kubuntu Package 4:3.5.4-0ubuntu2~dapper1 ) Compiler: Target: i486-linux-gnu OS: Linux (i686) release 2.6.16.16-ath64 Dropdown menus are not updated after selections In order to trigger this bug, go for example to: http://www.lowcostcoach.com/london.html and try to purchase coach tickets (book online and save). When changing to oneway to return, page won't update
Testcase: <script> function doIt() { var opt = document.createElement("OPTION"); opt.text="Hi!"; var sel = document.getElementById("sel"); sel.options.add(opt); } </script> <body onload="doIt()"> <select id="sel"></select> </body>
SVN commit 590758 by orlovich: Implement the add(!) method the options collection has BUG:134914 M +75 -0 kjs_html.cpp M +9 -3 kjs_html.h --- branches/KDE/3.5/kdelibs/khtml/ecma/kjs_html.cpp #590757:590758 @@ -33,6 +33,7 @@ // ### HACK #include "html/html_baseimpl.h" #include "html/html_documentimpl.h" +#include "html/html_formimpl.h" #include "html/html_imageimpl.h" #include "html/html_miscimpl.h" #include "xml/dom2_eventsimpl.h" @@ -3089,6 +3090,9 @@ KJS::HTMLCollection::HTMLCollection(ExecState *exec, const DOM::HTMLCollection& c) : DOMObject(HTMLCollectionProto::self(exec)), collection(c), hidden(false) {} + +KJS::HTMLCollection::HTMLCollection(const KJS::Object& proto, const DOM::HTMLCollection& c) + : DOMObject(proto), collection(c), hidden(false) {} KJS::HTMLCollection::~HTMLCollection() { @@ -3330,6 +3334,22 @@ } } +// ------------------------------------------------------------------------- +/* Source for HTMLSelectCollectionProtoTable. +@begin HTMLSelectCollectionProtoTable 1 + add HTMLSelectCollection::Add DontDelete|Function 2 +@end +*/ +DEFINE_PROTOTYPE("HTMLOptionsCollection", HTMLSelectCollectionProto) +IMPLEMENT_PROTOFUNC_DOM(HTMLSelectCollectionProtoFunc) +IMPLEMENT_PROTOTYPE(HTMLSelectCollectionProto,HTMLSelectCollectionProtoFunc) + +const ClassInfo KJS::HTMLSelectCollection::info = { "HTMLOptionsCollection", &HTMLCollection::info, 0, 0 }; + +KJS::HTMLSelectCollection::HTMLSelectCollection(ExecState *exec, const DOM::HTMLCollection& c, + const DOM::HTMLSelectElement& e) + : HTMLCollection(HTMLSelectCollectionProto::self(exec), c), element(e) { } + Value KJS::HTMLSelectCollection::tryGet(ExecState *exec, const Identifier &p) const { if (p == "selectedIndex") @@ -3405,6 +3425,61 @@ element.add(option, before); } + +Value KJS::HTMLSelectCollectionProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args) +{ + KJS_CHECK_THIS( KJS::HTMLSelectCollection, thisObj ); + DOM::HTMLSelectElement element = static_cast<KJS::HTMLSelectCollection *>(thisObj.imp())->toElement(); + + switch (id) { + case KJS::HTMLSelectCollection::Add: + { + //Non-standard select.options.add. + //The first argument is the item, 2nd is offset. + //IE and Mozilla are both quite picky here, too... + DOM::Node node = KJS::toNode(args[0]); + if (node.isNull() || node.elementId() != ID_OPTION) { + Object err = Error::create(exec, GeneralError, "Invalid argument to HTMLOptionsCollection::add"); + exec->setException(err); + return Undefined(); + } + + DOM::HTMLOptionElement option = static_cast<DOM::HTMLOptionElement>(node); + if ( option.ownerDocument() != element.ownerDocument() ) //### remove this once auto-adopt works... + option = static_cast<DOM::HTMLOptionElement>(element.ownerDocument().importNode(option, true)); + + int pos = 0; + //By default append, if not specified or null.. + if (args[1].isA(UndefinedType)) + pos = element.length(); + else + pos = (int)args[1].toNumber(exec); + + if (pos < 0) { + Object err = Error::create(exec, GeneralError, "Invalid index argument to HTMLOptionsCollection::add"); + exec->setException(err); + return Undefined(); + } + + if (pos >= element.length()) { + //Append + element.add(option, DOM::Node()); + } else { + //Find what to prepend before.. + DOM::HTMLSelectElementImpl* impl = static_cast<HTMLSelectElementImpl*>(element.handle()); + QMemArray<HTMLGenericFormElementImpl*> items = impl->listItems(); + int dummy; + impl->insertBefore(option.handle(), items.at(pos), dummy); + } + return Undefined(); + break; + } + default: + return Undefined(); + } +} + + ////////////////////// Option Object //////////////////////// OptionConstructorImp::OptionConstructorImp(ExecState *exec, const DOM::Document &d) --- branches/KDE/3.5/kdelibs/khtml/ecma/kjs_html.h #590757:590758 @@ -171,7 +171,8 @@ class HTMLCollection : public DOMObject { public: - HTMLCollection(ExecState *exec, const DOM::HTMLCollection& c); + HTMLCollection(ExecState *exec, const DOM::HTMLCollection& c); + HTMLCollection(const KJS::Object& proto, const DOM::HTMLCollection& c); ~HTMLCollection(); virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const; virtual Value call(ExecState *exec, Object &thisObj, const List&args); @@ -193,10 +194,15 @@ class HTMLSelectCollection : public HTMLCollection { public: - HTMLSelectCollection(ExecState *exec, const DOM::HTMLCollection& c, const DOM::HTMLSelectElement& e) - : HTMLCollection(exec, c), element(e) { } + enum { Add }; + HTMLSelectCollection(ExecState *exec, const DOM::HTMLCollection& c, const DOM::HTMLSelectElement& e); virtual Value tryGet(ExecState *exec, const Identifier &propertyName) const; virtual void tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr = None); + + virtual const ClassInfo* classInfo() const { return &info; } + static const ClassInfo info; + + DOM::HTMLSelectElement toElement() const { return element; } private: DOM::HTMLSelectElement element; };