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 February 1st, 2009 @ 05:51 PM
- State changed from new to open
can you describe an example which produces this error?
-
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 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 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)
-
// 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() );
// simply add node to array (links between Nodes are made at higher level) Array.prototype.push.apply(nodelist, [newChild]);
-
Mike Doyle
-
vtdoylem April 29th, 2009 @ 09:07 AM
That didnt format very well...posting patch as an attachment as well
- Mike Doyle
-
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.
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
- 27 pulling to github/jeresig You opened tickets #14 & #15 to cover the jQuery 1.3.1 pr...
- 27 pulling to github/jeresig You opened tickets #14 & #15 to cover the jQuery 1.3.1 pr...
- 14 Nodelist : Function.prototype.apply must take an array //TODO : see [#14](/projects/21590/tickets/14 "Ticket #1...