A follow-up to [6578] (which stopped adding expandos to elements that didn't have...
authorJohn Resig <jeresig@gmail.com>
Fri, 25 Sep 2009 17:55:20 +0000 (17:55 +0000)
committerJohn Resig <jeresig@gmail.com>
Fri, 25 Sep 2009 17:55:20 +0000 (17:55 +0000)
$("<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)

src/core.js
src/data.js
src/manipulation.js
src/selector.js
src/traversing.js
test/unit/core.js
test/unit/data.js
test/unit/manipulation.js
test/unit/traversing.js

index 3b11ed8..ed1f7d5 100644 (file)
@@ -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 = [];
 
index 085db0b..500f7ea 100644 (file)
@@ -14,8 +14,8 @@ jQuery.extend({
                var id = elem[ expando ], cache = jQuery.cache, thisCache;\r
 \r
                // Handle the case where there's no name immediately\r
-               if ( !name ) {\r
-                       return id;\r
+               if ( !name && !id ) {\r
+                       return null;\r
                }\r
 \r
                // Compute a unique ID for the element\r
@@ -39,7 +39,7 @@ jQuery.extend({
                        thisCache[ name ] = data;\r
                }\r
                \r
-               return name === true ? thisCache : thisCache[ name ];\r
+               return name ? thisCache[ name ] : thisCache;\r
        },\r
 \r
        removeData: function( elem, name ) {\r
@@ -116,7 +116,9 @@ jQuery.extend({
 \r
 jQuery.fn.extend({\r
        data: function( key, value ){\r
-               if(typeof key === "undefined" && this.length) return jQuery.data(this[0], true);\r
+               if ( typeof key === "undefined" && this.length ) {\r
+                       return jQuery.data( this[0] );\r
+               }\r
 \r
                var parts = key.split(".");\r
                parts[1] = parts[1] ? "." + parts[1] : "";\r
@@ -165,4 +167,4 @@ jQuery.fn.extend({
        clearQueue: function(type){\r
                return this.queue( type || "fx", [] );\r
        }\r
-});
\ No newline at end of file
+});\r
index 2a1e923..547acc1 100644 (file)
@@ -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 );
                }
        },
 
@@ -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;
                }
        },
 
index 64222c3..de8830a 100644 (file)
@@ -144,6 +144,8 @@ Sizzle.uniqueSort = function(results){
                        }
                }
        }
+
+       return results;
 };
 
 Sizzle.matches = function(expr, set){
@@ -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;
@@ -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;
@@ -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);
@@ -1036,6 +1059,8 @@ jQuery.sibling = function(n, elem){
        return r;
 };
 
+jQuery.unique = Sizzle.uniqueSort;
+
 return;
 
 window.Sizzle = Sizzle;
index 0e379c7..8f1e5eb 100644 (file)
@@ -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 ) {
@@ -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 );
        };
 });
index d3e0a44..3a3b42f 100644 (file)
@@ -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" );
@@ -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" );
index 6a367f7..8401fce 100644 (file)
@@ -32,7 +32,7 @@ test("jQuery.data", function() {
        jQuery.data(div, "test", "success");\r
        equals( jQuery.data(div, "test"), "success", "Check for added data" );\r
        \r
-       var data = jQuery.data(div, true);\r
+       var data = jQuery.data(div);\r
        same( data, { "test": "success" }, "Return complete data set" );\r
        \r
        jQuery.data(div, "test", "overwritten");\r
index 541776c..1b99b66 100644 (file)
@@ -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." );
 }
@@ -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." );
 };
index 46a49bb..2793f2f 100644 (file)
@@ -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" );
 });
@@ -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" );
 });