Just pushed some major speed improvements through for $.each() - we're now seeing...
[jquery.git] / src / jquery / jquery.js
index 440e20e..5ffccc5 100644 (file)
@@ -852,7 +852,7 @@ jQuery.fn = jQuery.prototype = {
         * @cat DOM/Manipulation
         */
        clone: function(deep) {
-               deep = deep != undefined ? deep : true
+               deep = deep != undefined ? deep : true;
                var $this = this.add(this.find("*"));
                if (jQuery.browser.msie) {
                        // Need to remove events on the element and its descendants
@@ -938,7 +938,7 @@ jQuery.fn = jQuery.prototype = {
                return this.pushStack(
                        jQuery.isFunction( t ) &&
                        jQuery.grep(this, function(el, index){
-                               return t.apply(el, [index])
+                               return t.apply(el, [index]);
                        }) ||
 
                        jQuery.multiFilter(t,this) );
@@ -1160,6 +1160,10 @@ jQuery.fn = jQuery.prototype = {
                        ( this.length ? this[0].innerHTML : null ) :
                        this.empty().append( val );
        },
+
+       slice: function() {
+               return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
+       },
        
        /**
         * @private
@@ -1252,17 +1256,33 @@ jQuery.fn = jQuery.prototype = {
  */
 jQuery.extend = jQuery.fn.extend = function() {
        // copy reference to target object
-       var target = arguments[0], a = 1;
+       var target = arguments[0] || {}, a = 1, al = arguments.length;
 
        // extend jQuery itself if only one argument is passed
-       if ( arguments.length == 1 ) {
+       if ( al == 1 ) {
                target = this;
                a = 0;
        }
+
        var prop;
-       while ( (prop = arguments[a++]) != null )
-               // Extend the base object
-               for ( var i in prop ) target[i] = prop[i];
+
+       for ( ; a < al; a++ )
+               // Only deal with non-null/undefined values
+               if ( (prop = arguments[a]) != null )
+                       // Extend the base object
+                       for ( var i in prop ) {
+                               // Prevent never-ending loop
+                               if ( target == prop[i] )
+                                       continue;
+
+                               // Recurse if we're merging object values
+                               if ( typeof prop[i] == 'object' && target[i] )
+                                       jQuery.extend( target[i], prop[i] );
+
+                               // Don't bring in undefined values
+                               else if ( prop[i] != undefined )
+                                       target[i] = prop[i];
+                       }
 
        // Return the modified object
        return target;
@@ -1374,9 +1394,15 @@ jQuery.extend({
                if ( obj.length == undefined )
                        for ( var i in obj )
                                fn.apply( obj[i], args || [i, obj[i]] );
-               else
+               else if ( args ) {
                        for ( var i = 0, ol = obj.length; i < ol; i++ )
-                               if ( fn.apply( obj[i], args || [i, obj[i]] ) === false ) break;
+                               if ( fn.apply( obj[i], args ) === false ) break;
+
+               // A special, fast, case for the most common use of each
+               } else
+                       for ( var i = 0, ol = obj.length, val = obj[0]; 
+                               i < ol && fn.call(val,i,val) !== false; val = obj[++i] );
+
                return obj;
        },
        
@@ -1509,7 +1535,7 @@ jQuery.extend({
                        // then some display: none elements are involved
                        else {
                                // Locate all of the parent display: none elements
-                               for ( var a = elem; color(a); a = a.parentNode )
+                               for ( var a = elem; a && color(a); a = a.parentNode )
                                        stack.unshift(a);
 
                                // Go through and make them visible, but in reverse
@@ -1566,7 +1592,7 @@ jQuery.extend({
                                        !s.indexOf("<leg") &&
                                        [1, "<fieldset>", "</fieldset>"] ||
                                        
-                                       (!s.indexOf("<thead") || !s.indexOf("<tbody") || !s.indexOf("<tfoot") || !s.indexOf("<colg")) &&
+                                       s.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
                                        [1, "<table>", "</table>"] ||
                                        
                                        !s.indexOf("<tr") &&
@@ -1577,7 +1603,11 @@ jQuery.extend({
                                        [3, "<table><tbody><tr>", "</tr></tbody></table>"] ||
                                        
                                        !s.indexOf("<col") &&
-                                       [2, "<table><colgroup>", "</colgroup></table>"] ||
+                                       [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"] ||
+
+                                       // IE can't serialize <link> and <script> tags normally
+                                       jQuery.browser.msie &&
+                                       [1, "div<div>", "</div>"] ||
                                        
                                        [0,"",""];
 
@@ -1586,7 +1616,7 @@ jQuery.extend({
                                
                                // Move to the right depth
                                while ( wrap[0]-- )
-                                       div = div.firstChild;
+                                       div = div.lastChild;
                                
                                // Remove IE's autoinserted <tbody> from table fragments
                                if ( jQuery.browser.msie ) {
@@ -1725,8 +1755,17 @@ jQuery.extend({
        merge: function(first, second) {
                // We have to loop this way because IE & Opera overwrite the length
                // expando of getElementsByTagName
-               for ( var i = 0; second[i]; i++ )
-                       first.push(second[i]);
+
+               // Also, we need to make sure that the correct elements are being returned
+               // (IE returns comment nodes in a '*' query)
+               if ( jQuery.browser.msie ) {
+                       for ( var i = 0; second[i]; i++ )
+                               if ( second[i].nodeType != 8 )
+                                       first.push(second[i]);
+               } else
+                       for ( var i = 0; second[i]; i++ )
+                               first.push(second[i]);
+
                return first;
        },
 
@@ -1904,7 +1943,7 @@ new function() {
        // Check to see if the W3C box model is being used
        jQuery.boxModel = !jQuery.browser.msie || document.compatMode == "CSS1Compat";
 
-       jQuery.styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat",
+       jQuery.styleFloat = jQuery.browser.msie ? "styleFloat" : "cssFloat";
 
        jQuery.props = {
                "for": "htmlFor",
@@ -2073,7 +2112,7 @@ jQuery.each({
                var ret = jQuery.map(this,n);
                if ( a && typeof a == "string" )
                        ret = jQuery.multiFilter(a,ret);
-               return this.pushStack( ret );
+               return this.pushStack( jQuery.unique(ret) );
        };
 });