Skip to content

Commit

Permalink
A follow-up to [6578] (which stopped adding expandos to elements that…
Browse files Browse the repository at this point in the history
… didn't have data). That broke jQuery.unique() (so we're now using the unique from Sizzle). Using Sizzle's unique (which also sorts in document order) changed how add, andSelf, parents, nextAll, prevAll, and siblings work. after and before were changed to not use .add() (in order to guarantee their position in the jQuery set). Also, jQuery.data(elem) was updated to return that element's data object (instead of its ID).

$("<div/>").after("<span/>")
=> [ div, span ]
(calling after on a disconnected DOM node adds the nodes to the end of the jQuery set)

$("<div/>").before("<span/>")
=> [ span, div ]
(calling before on a disconnected DOM node adds the nodes to the beginning of the jQuery set)

$("div").add("span")
=> [ div, span, span, div, span ]
(results now come out in document order)

$("div").find("code").andSelf();
=> [ div, code, code ]
(results now come out in document order)

Same goes for .parents(), .nextAll(), .prevAll(), and .siblings().

Exception: .parents() will still return the results in reverse document order.

jQuery.data(elem)
=> { object of data }
(no longer returns the unique ID assigned to the node)
  • Loading branch information
jeresig committed Sep 25, 2009
1 parent 67089ee commit 67d445a
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 48 deletions.
19 changes: 0 additions & 19 deletions src/core.js
Expand Up @@ -462,25 +462,6 @@ jQuery.extend({
return first;
},

unique: function( array ) {
var ret = [], done = {}, id;

try {
for ( var i = 0, length = array.length; i < length; i++ ) {
id = jQuery.data( array[ i ] );

if ( !done[ id ] ) {
done[ id ] = true;
ret.push( array[ i ] );
}
}
} catch( e ) {
ret = array;
}

return ret;
},

grep: function( elems, callback, inv ) {
var ret = [];

Expand Down
12 changes: 7 additions & 5 deletions src/data.js
Expand Up @@ -14,8 +14,8 @@ jQuery.extend({
var id = elem[ expando ], cache = jQuery.cache, thisCache;

// Handle the case where there's no name immediately
if ( !name ) {
return id;
if ( !name && !id ) {
return null;
}

// Compute a unique ID for the element
Expand All @@ -39,7 +39,7 @@ jQuery.extend({
thisCache[ name ] = data;
}

return name === true ? thisCache : thisCache[ name ];
return name ? thisCache[ name ] : thisCache;
},

removeData: function( elem, name ) {
Expand Down Expand Up @@ -116,7 +116,9 @@ jQuery.extend({

jQuery.fn.extend({
data: function( key, value ){
if(typeof key === "undefined" && this.length) return jQuery.data(this[0], true);
if ( typeof key === "undefined" && this.length ) {
return jQuery.data( this[0] );
}

var parts = key.split(".");
parts[1] = parts[1] ? "." + parts[1] : "";
Expand Down Expand Up @@ -165,4 +167,4 @@ jQuery.fn.extend({
clearQueue: function(type){
return this.queue( type || "fx", [] );
}
});
});
18 changes: 8 additions & 10 deletions src/manipulation.js
Expand Up @@ -111,12 +111,10 @@ jQuery.fn.extend({
return this.domManip(arguments, false, function(elem){
this.parentNode.insertBefore( elem, this );
});
} else {
var set = jQuery.isFunction(arguments[0]) ?
jQuery( arguments[0]() ) :
jQuery.apply(jQuery, arguments);

return this.pushStack( set.add( this ), "before", arguments );
} else if ( arguments.length ) {
var set = jQuery(arguments[0]);
set.push.apply( set, this.toArray() );
return this.pushStack( set, "before", arguments );
}
},

Expand All @@ -125,10 +123,10 @@ jQuery.fn.extend({
return this.domManip(arguments, false, function(elem){
this.parentNode.insertBefore( elem, this.nextSibling );
});
} else {
return jQuery.isFunction(arguments[0]) ?
this.add( arguments[0]() ) :
this.add.apply( this, arguments );
} else if ( arguments.length ) {
var set = this.pushStack( this, "after", arguments );
set.push.apply( set, jQuery(arguments[0]).toArray() );
return set;
}
},

Expand Down
25 changes: 25 additions & 0 deletions src/selector.js
Expand Up @@ -144,6 +144,8 @@ Sizzle.uniqueSort = function(results){
}
}
}

return results;
};

Sizzle.matches = function(expr, set){
Expand Down Expand Up @@ -703,6 +705,13 @@ var sortOrder;

if ( document.documentElement.compareDocumentPosition ) {
sortOrder = function( a, b ) {
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
if ( a == b ) {
hasDuplicate = true;
}
return 0;
}

var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
if ( ret === 0 ) {
hasDuplicate = true;
Expand All @@ -711,6 +720,13 @@ if ( document.documentElement.compareDocumentPosition ) {
};
} else if ( "sourceIndex" in document.documentElement ) {
sortOrder = function( a, b ) {
if ( !a.sourceIndex || !b.sourceIndex ) {
if ( a == b ) {
hasDuplicate = true;
}
return 0;
}

var ret = a.sourceIndex - b.sourceIndex;
if ( ret === 0 ) {
hasDuplicate = true;
Expand All @@ -719,6 +735,13 @@ if ( document.documentElement.compareDocumentPosition ) {
};
} else if ( document.createRange ) {
sortOrder = function( a, b ) {
if ( !a.ownerDocument || !b.ownerDocument ) {
if ( a == b ) {
hasDuplicate = true;
}
return 0;
}

var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
aRange.selectNode(a);
aRange.collapse(true);
Expand Down Expand Up @@ -1036,6 +1059,8 @@ jQuery.sibling = function(n, elem){
return r;
};

jQuery.unique = Sizzle.uniqueSort;

return;

window.Sizzle = Sizzle;
Expand Down
23 changes: 16 additions & 7 deletions src/traversing.js
Expand Up @@ -69,12 +69,14 @@ jQuery.fn.extend({
},

add: function( selector ) {
return this.pushStack( jQuery.unique( jQuery.merge(
this.get(),
typeof selector === "string" ?
var set = typeof selector === "string" ?
jQuery( selector ) :
jQuery.makeArray( selector )
)));
jQuery.makeArray( selector ),
all = jQuery.merge( this.get(), set );

return this.pushStack( set[0] && (set[0].setInterval || set[0].nodeType === 9 || (set[0].parentNode && set[0].parentNode.nodeType !== 11)) ?
jQuery.unique( all ) :
all );
},

eq: function( i ) {
Expand Down Expand Up @@ -125,9 +127,16 @@ jQuery.each({
jQuery.fn[ name ] = function( selector ) {
var ret = jQuery.map( this, fn );

if ( selector && typeof selector == "string" )
if ( selector && typeof selector === "string" ) {
ret = jQuery.multiFilter( selector, ret );
}

ret = this.length > 1 ? jQuery.unique( ret ) : ret;

if ( name === "parents" && this.length > 1 ) {
ret = ret.reverse();
}

return this.pushStack( jQuery.unique( ret ), name, selector );
return this.pushStack( ret, name, selector );
};
});
12 changes: 11 additions & 1 deletion test/unit/core.js
Expand Up @@ -399,7 +399,7 @@ test("get(-Number)",function() {
})

test("add(String|Element|Array|undefined)", function() {
expect(12);
expect(16);
isSet( jQuery("#sndp").add("#en").add("#sap").get(), q("sndp", "en", "sap"), "Check elements from document" );
isSet( jQuery("#sndp").add( jQuery("#en")[0] ).add( jQuery("#sap") ).get(), q("sndp", "en", "sap"), "Check elements from document" );
ok( jQuery([]).add(jQuery("#form")[0].elements).length >= 13, "Check elements from array" );
Expand All @@ -408,6 +408,16 @@ test("add(String|Element|Array|undefined)", function() {
// use jQuery([]).add(form.elements) instead.
//equals( jQuery([]).add(jQuery("#form")[0].elements).length, jQuery(jQuery("#form")[0].elements).length, "Array in constructor must equals array in add()" );

var tmp = jQuery("<div/>");

var x = jQuery([]).add(jQuery("<p id='x1'>xxx</p>").appendTo(tmp)).add(jQuery("<p id='x2'>xxx</p>").appendTo(tmp));
equals( x[0].id, "x1", "Check on-the-fly element1" );
equals( x[1].id, "x2", "Check on-the-fly element2" );

var x = jQuery([]).add(jQuery("<p id='x1'>xxx</p>").appendTo(tmp)[0]).add(jQuery("<p id='x2'>xxx</p>").appendTo(tmp)[0]);
equals( x[0].id, "x1", "Check on-the-fly element1" );
equals( x[1].id, "x2", "Check on-the-fly element2" );

var x = jQuery([]).add(jQuery("<p id='x1'>xxx</p>")).add(jQuery("<p id='x2'>xxx</p>"));
equals( x[0].id, "x1", "Check on-the-fly element1" );
equals( x[1].id, "x2", "Check on-the-fly element2" );
Expand Down
2 changes: 1 addition & 1 deletion test/unit/data.js
Expand Up @@ -32,7 +32,7 @@ test("jQuery.data", function() {
jQuery.data(div, "test", "success");
equals( jQuery.data(div, "test"), "success", "Check for added data" );

var data = jQuery.data(div, true);
var data = jQuery.data(div);
same( data, { "test": "success" }, "Return complete data set" );

jQuery.data(div, "test", "overwritten");
Expand Down
4 changes: 2 additions & 2 deletions test/unit/manipulation.js
Expand Up @@ -340,7 +340,7 @@ var testBefore = function(val) {
jQuery('#yahoo').before(val( jQuery("#first, #mark") ));
equals( expected, jQuery('#en').text(), "Insert jQuery before" );

var set = jQuery("<div/>").before(val("<span>test</span>"));
var set = jQuery("<div/>").before("<span>test</span>");
equals( set[0].nodeName.toLowerCase(), "span", "Insert the element before the disconnected node." );
equals( set.length, 2, "Insert the element before the disconnected node." );
}
Expand Down Expand Up @@ -396,7 +396,7 @@ var testAfter = function(val) {
jQuery('#yahoo').after(val( jQuery("#first, #mark") ));
equals( expected, jQuery('#en').text(), "Insert jQuery after" );

var set = jQuery("<div/>").after(val("<span>test</span>"));
var set = jQuery("<div/>").after("<span>test</span>");
equals( set[1].nodeName.toLowerCase(), "span", "Insert the element after the disconnected node." );
equals( set.length, 2, "Insert the element after the disconnected node." );
};
Expand Down
6 changes: 3 additions & 3 deletions test/unit/traversing.js
Expand Up @@ -145,8 +145,8 @@ test("not(jQuery)", function() {

test("andSelf()", function() {
expect(4);
isSet( jQuery("#en").siblings().andSelf().get(), q("sndp", "sap","en"), "Check for siblings and self" );
isSet( jQuery("#foo").children().andSelf().get(), q("sndp", "en", "sap", "foo"), "Check for children and self" );
isSet( jQuery("#en").siblings().andSelf().get(), q("sndp", "en", "sap"), "Check for siblings and self" );
isSet( jQuery("#foo").children().andSelf().get(), q("foo", "sndp", "en", "sap"), "Check for children and self" );
isSet( jQuery("#sndp, #en").parent().andSelf().get(), q("foo","sndp","en"), "Check for parent and self" );
isSet( jQuery("#groups").parents("p, div").andSelf().get(), q("main", "ap", "groups"), "Check for parents and self" );
});
Expand All @@ -157,7 +157,7 @@ test("siblings([String])", function() {
isSet( jQuery("#sndp").siblings(":has(code)").get(), q("sap"), "Check for filtered siblings (has code child element)" );
isSet( jQuery("#sndp").siblings(":has(a)").get(), q("en", "sap"), "Check for filtered siblings (has anchor child element)" );
isSet( jQuery("#foo").siblings("form, b").get(), q("form", "floatTest", "lengthtest", "name-tests", "testForm"), "Check for multiple filters" );
var set = q("en", "sap", "sndp");
var set = q("sndp", "en", "sap");
isSet( jQuery("#en, #sndp").siblings().get(), set, "Check for unique results from siblings" );
});

Expand Down

0 comments on commit 67d445a

Please sign in to comment.