#14 ✓resolved
thatcher.christopher (at gmail)

Nodelist : Function.prototype.apply must take an array

Reported by thatcher.christopher (at gmail) | January 31st, 2009 @ 06:22 AM | in 1.0 Release

All, I just upgraded from jQuery 1.2.6 to 1.3.1 and I'm seeing this while using Chris Thatcher's latest (as of Jan 20, 2009):

js: "../..//vendor/plugins/javascript_testing/lib/env.rhino.js", line
615: uncaught JavaScript runtime exception: TypeError: second argument
to Function.prototype.apply must be an array
       at ../..//vendor/plugins/javascript_testing/lib/env.rhino.js:615
       at ../..//vendor/plugins/javascript_testing/lib/env.rhino.js:1323
       at ../..//vendor/plugins/javascript_testing/lib/jquery-1.3.1.js:253
       at ../..//vendor/plugins/javascript_testing/lib/jquery-1.3.1.js:515
       at ../..//vendor/plugins/javascript_testing/lib/jquery-1.3.1.js:251
       at ../..//vendor/plugins/javascript_testing/lib/screw.builder.js:70
       at ../..//vendor/plugins/javascript_testing/lib/jquery-1.3.1.js:2912
       at ../..//vendor/plugins/javascript_testing/lib/jquery-1.3.1.js:685
       at ../..//vendor/plugins/javascript_testing/lib/jquery-1.3.1.js:2911

To fix it, I used the following patch to nodelist.js:


 var __appendChild__ = function(nodelist, newChild) {
    if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {  //
node is a DocumentFragment
        // append the children of DocumentFragment
-        Array.prototype.push.apply(nodelist, newChild.childNodes);
+        var nodes = (newChild.childNodes instanceof Array) ?
newChild.childNodes : [newChild.childNodes];
+        Array.prototype.push.apply(nodelist, nodes);
    } else {
        // simply add node to array (links between Nodes are made at
higher level)
        Array.prototype.push.apply(nodelist, [newChild]);

Anyone know why this would be happening?

Thanks so much, Larry

Comments and changes to this ticket

  • Thatcher

    Thatcher February 1st, 2009 @ 05:51 PM

    • State changed from “new” to “open”

    can you describe an example which produces this error?

  • Larry Karnowski

    Larry Karnowski February 2nd, 2009 @ 01:49 AM

    It's happening somewhere deep inside Screw.Unit every time I run a test suite. I'll dig in and see if I can find out where to give us a better idea.

  • Thatcher

    Thatcher February 17th, 2009 @ 04:27 AM

    • State changed from “open” to “resolved”

    I applied the patch but put a comment referencing back to this ticket. Still haven't figured out why this can happen since .childNodes should always be an array.

  • vtdoylem

    vtdoylem April 29th, 2009 @ 09:04 AM

    • Assigned user cleared.

    I ran into a related problem with DocumentFragments and nodeList's with the latest build ( downloaded April 28, 2009 ) and using the jQuery UI plugin.

    It seems that rhino is treating the childNodes(nodeList) object as an object, not as an array.

    A simple scenario to reproduce:

    
    var div = document.createElement ( 'div' );
    var df = document.createDocumentFragment();
    df.appendChild ( document.createElement ( 'p' ) );
    div.appendChild ( df );
    
    // at this point, div.childNodes is corrupted, with childNodes[0] being a nodeList, not a node
    
    div.childNodes 
    [ [ Element #3 P ] ]
    

    Patch to fix:

    diff --git a/src/dom/nodelist.js b/src/dom/nodelist.js index 04473ef..701060e 100644 --- a/src/dom/nodelist.js +++ b/src/dom/nodelist.js @@ -53,6 +53,13 @@ extend(DOMNodeList.prototype, {

         return ret;
     },
    
    
    • toArray: function () {
      
      
    •         var children = [];
      
      
    •         for ( var i=0; i < this.length; i++) {
      
      
    •                 children.push (this[i]);
      
      
    •         }
      
      
    •         return children;
      
      
    • },
      
      

      toString: function(){ return "[ "+(this.length > 0?Array.prototype.join.apply(this, [", "]):"Empty NodeList")+" ]"; } @@ -96,7 +103,7 @@ var insertBefore = function(nodelist, newChild, refChildIndex) {

       if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {  // node is a DocumentFragment
           // append the children of DocumentFragment
      
      
    •      Array.prototype.splice.apply(nodelist,[refChildIndex, 0].concat(newChild.childNodes));
      
      
    •      Array.prototype.splice.apply(nodelist,[refChildIndex, 0].concat(newChild.childNodes.toArray()));
       }
       else {
           // append the newChild
      
      

      @@ -122,7 +129,7 @@ var replaceChild = function(nodelist, newChild, refChildIndex) {

       if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {  // node is a DocumentFragment
           // get array containing children prior to refChild
      
      
    •      Array.prototype.splice.apply(nodelist,[refChildIndex, 1].concat(newChild.childNodes));
      
      
    •      Array.prototype.splice.apply(nodelist,[refChildIndex, 1].concat(newChild.childNodes.toArray()));
       }
       else {
           // simply replace node in array (links between Nodes are made at higher level)
      
      
      @@ -164,12 +171,7 @@ var removeChild = function(nodelist, refChildIndex) { */ var appendChild = function(nodelist, newChild) { if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
    •  // append the children of DocumentFragment
      
      
    •  //TODO : see [#14](/projects/21590/tickets/14 "Ticket #14") - http://envjs.lighthouseapp.com/p...
      
      
    •  //not sure why this could happen, .childNodes should always be an array
      
      
    •  Array.prototype.push.apply(nodelist,
      
      
    •      (newChild.childNodes instanceof Array) ?
      
      
    •          newChild.childNodes : [newChild.childNodes]);
      
      
    •  Array.prototype.push.apply(nodelist, newChild.childNodes.toArray() );
      
      
      } else {
       // simply add node to array (links between Nodes are made at higher level)
       Array.prototype.push.apply(nodelist, [newChild]);
      
      
    • Mike Doyle

  • vtdoylem

    vtdoylem April 29th, 2009 @ 09:07 AM

    That didnt format very well...posting patch as an attachment as well

    • Mike Doyle
  • Thatcher

    Thatcher April 29th, 2009 @ 10:09 AM

    Nice Mike, I was just tracking this one down and you saved me hours. Thanks!

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile ยป

a javascript browser environment

People watching this ticket

Attachments

Referenced by

Pages