[webkit-dev] Re: What data structure is used to store multiple input controls sharing the same name?

Marco Wise marco.wise at stanford.edu
Tue Mar 21 17:01:37 PST 2006


Hi,

I did a little more digging in the WebKit source code so let me see  
if I can answer my own question... :)

Are items sharing the same name stored in a DOMNamedNodesCollection?  
If so, isn't DOMNamedNodesCollection a DOMObject and shouldn't it be  
possible to put and get its properties?

Thanks,

- marco


 From kjs_dom.h:

   // Internal class, used for the collection return by e.g.  
document.forms.myinput
   // when multiple nodes have the same name.
   class DOMNamedNodesCollection : public DOMObject {
   public:
     DOMNamedNodesCollection(ExecState *exec, const  
QValueList<DOM::Node>& nodes );
     virtual Value tryGet(ExecState *exec, const Identifier  
&propertyName) const;
   private:
     QValueList<DOM::Node> m_nodes;
   };


 From kjs_dom.cpp:

// Such a collection is usually very short-lived, it only exists
// for constructs like document.forms.<name>[1],
// so it shouldn't be a problem that it's storing all the nodes (with  
the same name). (David)
DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *, const  
QValueList<DOM::Node>& nodes )
   : m_nodes(nodes)
{
   // Maybe we should ref (and deref in the dtor) the nodes, though ?
}

Value DOMNamedNodesCollection::tryGet(ExecState *exec, const  
Identifier &propertyName) const
{
   if (propertyName == lengthPropertyName)
     return Number(m_nodes.count());
   // index?
   bool ok;
   unsigned int u = propertyName.toULong(&ok);
   if (ok && u < m_nodes.count()) {
     DOM::Node node = m_nodes[u];
     return getDOMNode(exec,node);
   }
   // For IE compatibility, we need to be able to look up elements in a
   // document.formName.name result by id as well as be index.

   if (!ok) {
     for (QValueListConstIterator<DOM::Node> it = m_nodes.begin();  
it != m_nodes.end(); it++) {
       DOM::Node node = *it;
       DOM::NamedNodeMap attributes = node.attributes();
       if (attributes.isNull()) {
	continue;
       }

       DOM::Node idAttr = attributes.getNamedItem("id");
       if (idAttr.isNull()) {
	continue;
       }

       if (idAttr.nodeValue() == propertyName.string()) {
	return getDOMNode(exec,node);
       }
     }
   }

   return DOMObject::tryGet(exec,propertyName);
}


On Mar 20, 2006, at 10:13 AM, Marco Wise wrote:

> Hi,
>
> What kind of data structure/object is used internally by Safari /  
> Konqueror to store multiple inputs with the same name? Is it a  
> NodeList as in IE/Firefox, or something different? Can properties  
> be assigned to this object using Javascript?
>
> Using the code below it looks like Firefox, IE and Safari create an  
> HTMLInputElement the first time a control named _submit is  
> encountered.
> The second time a control named _submit is encountered, it seems  
> that a data structure is created to hold the HTMLInputElements and  
> these can then be accessed using array notation.
>
> Firefox/IE report that this new structure is a Nodelist, but Safari  
> only reports that it's an "object". When I try using toString() to  
> get more information but then Safari reports an error that it's not  
> an object.
>
> Finally,
> In Firefox/IE you can assign new properties to this new Nodelist as  
> in _submit.foo = "bar" and you can retrieve their value.
> In Safari (I'm using 2.0.3) doing so will fail silently and  
> retrieving them will return "undefined".
>
> The code I'm using to try to sort this out:
>
> <html>
> <form name="test_form" onsubmit="test(this);">	
> 	<input type="submit" name="_submit" value="One">
> 	<script>
> 	  alert("_submit is a " + document.forms[0]._submit);
> 	  alert("_submit's value is " + document.forms[0]._submit.value);
> 	</script>
> 	<input type="submit" name="_submit" value="Two">
> 	<script>
> 	  alert("_submit is now a " + document.forms[0]._submit);
> 	  alert("_submit's value is now " + document.forms[0]._submit.value);
> 	  alert("Assigning a value to _submit...");
> 	  document.forms[0]._submit.value = "New Value";
> 	  alert("_submit's value is now " + document.forms[0]._submit.value);
> 	  alert("The original _submit's value can still be reached as an  
> item: " + document.forms[0]._submit[0].value);
> 	</script>
> </form>
> </html>
>
> I've looked at the webkit source code but I'm not an expert at C++  
> so I am not quite sure where to find this information. I've also  
> tried calling functions that should work on Nodelists and arrays on  
> this object and they fail. The only property that seems to work is  
> "length".
>
> To recap, my question is: how does Safari store multiple input  
> controls that share the same name? Can this object have its own  
> properties (besides "length")?
>
> Thanks in advance for any help you can provide,
>
> - marco




More information about the webkit-dev mailing list