Bug 134914 - Dropdown menus are not updated after selections
Summary: Dropdown menus are not updated after selections
Status: RESOLVED FIXED
Alias: None
Product: konqueror
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: Konqueror Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-09-30 18:38 UTC by stubnitz
Modified: 2006-09-30 21:03 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description stubnitz 2006-09-30 18:38:47 UTC
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
Comment 1 Maksim Orlovich 2006-09-30 19:38:04 UTC
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>
Comment 2 Maksim Orlovich 2006-09-30 21:03:22 UTC
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;
   };