Skip to content

Commit

Permalink
Generic jQuery.merge and safer jQuery.makeArray(nodeList).
Browse files Browse the repository at this point in the history
* Made jQuery.marge more generic supporting null and undefined values, and supporting array like objects as results. Fixes #5527.

* Made jQuery.makeArray(nodeList) more safer using jQuery.merge internally. Fixes #5528.

* Added a second "results" argument to jQuery.makeArray for internal usage to avoid intermediary arrays in init.
  • Loading branch information
rkatic authored and jeresig committed Nov 25, 2009
1 parent b30af34 commit ac00fe5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 19 deletions.
40 changes: 23 additions & 17 deletions src/core.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ jQuery.fn = jQuery.prototype = {
this.context = selector.context; this.context = selector.context;
} }


return this.setArray(jQuery.isArray( selector ) ? return jQuery.isArray( selector ) ?
selector : this.setArray( selector ) :
jQuery.makeArray(selector)); jQuery.makeArray( selector, this );
}, },


// Start with an empty selector // Start with an empty selector
Expand Down Expand Up @@ -419,19 +419,16 @@ jQuery.extend({
return (text || "").replace( rtrim, "" ); return (text || "").replace( rtrim, "" );
}, },


makeArray: function( array ) { // results is for internal usage only
var ret = [], i; makeArray: function( array, results ) {
var ret = results || [];


if ( array != null ) { if ( array != null ) {
i = array.length;

// The window, strings (and functions) also have 'length' // The window, strings (and functions) also have 'length'
if ( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval ) { if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval ) {
ret[0] = array; push.call( ret, array );
} else { } else {
while ( i ) { jQuery.merge( ret, array );
ret[--i] = array[i];
}
} }
} }


Expand All @@ -453,12 +450,21 @@ jQuery.extend({
}, },


merge: function( first, second ) { merge: function( first, second ) {
// We have to loop this way because IE & Opera overwrite the length var pos, i = second.length;
// expando of getElementsByTagName
var i = 0, elem, pos = first.length;


while ( (elem = second[ i++ ]) != null ) { // We have to get length this way when IE & Opera overwrite the length
first[ pos++ ] = elem; // expando of getElementsByTagName
if ( i && i.nodeType ) {
for ( i = 0; second[i]; ++i ) {}
}

pos = i + first.length;

// Correct length for non Arrays
first.length = pos;

while ( i ) {
first[ --pos ] = second[ --i ];
} }


return first; return first;
Expand Down
8 changes: 6 additions & 2 deletions test/unit/core.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ test("index(Object|String|undefined)", function() {
}); });


test("jQuery.merge()", function() { test("jQuery.merge()", function() {
expect(6); expect(8);


var parse = jQuery.merge; var parse = jQuery.merge;


Expand All @@ -514,6 +514,10 @@ test("jQuery.merge()", function() {


// Fixed at [5998], #3641 // Fixed at [5998], #3641
same( parse([-2,-1], [0,1,2]), [-2,-1,0,1,2], "Second array including a zero (falsy)"); same( parse([-2,-1], [0,1,2]), [-2,-1,0,1,2], "Second array including a zero (falsy)");

// After fixing #5527
same( parse([], [null, undefined]), [null, undefined], "Second array including null and undefined values");
same( parse({length:0}, [1,2]), {length:2, 0:1, 1:2}, "First array like");
}); });


test("jQuery.extend(Object, Object)", function() { test("jQuery.extend(Object, Object)", function() {
Expand Down Expand Up @@ -554,7 +558,7 @@ test("jQuery.extend(Object, Object)", function() {


var myKlass = function() {}; var myKlass = function() {};
var customObject = new myKlass(); var customObject = new myKlass();
var optionsWithCustomObject = { foo: { date: new customObject } }; var optionsWithCustomObject = { foo: { date: customObject } };
empty = {}; empty = {};
jQuery.extend(true, empty, optionsWithCustomObject); jQuery.extend(true, empty, optionsWithCustomObject);
ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly (no methods)" ); ok( empty.foo && empty.foo.date === customObject, "Custom objects copy correctly (no methods)" );
Expand Down

0 comments on commit ac00fe5

Please sign in to comment.