Fixed #2027 - make sure that cloned elements (within appendTo, etc.) have their event...
[jquery.git] / src / core.js
index 53d5f4a..c2f94d2 100644 (file)
@@ -29,6 +29,9 @@ window.$ = jQuery;
 // (both of which we optimize for)
 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;
 
+// Is it a simple selector
+var isSimple = /^.[^:#\[\.]*$/;
+
 jQuery.fn = jQuery.prototype = {
        init: function( selector, context ) {
                // Make sure that a selection was provided
@@ -342,15 +345,17 @@ jQuery.fn = jQuery.prototype = {
        },
 
        not: function( selector ) {
-               return this.pushStack(
-                       selector.constructor == String &&
-                       jQuery.multiFilter( selector, this, true ) ||
-
-                       jQuery.grep(this, function(elem) {
-                               return selector.constructor == Array || selector.jquery ?
-                                       jQuery.inArray( elem, selector ) < 0 :
-                                       elem != selector;
-                       }) );
+               if ( selector.constructor == String )
+                       // test special case where just one selector is passed in
+                       if ( isSimple.test( selector ) )
+                               return this.pushStack( jQuery.multiFilter( selector, this, true ) );
+                       else
+                               selector = jQuery.multiFilter( selector, this );
+
+               var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+               return this.filter(function() {
+                       return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+               });
        },
 
        add: function( selector ) {
@@ -414,31 +419,33 @@ jQuery.fn = jQuery.prototype = {
 
                        }
 
-               } else
-                       return this.each(function(){
-                               if ( this.nodeType != 1 )
-                                       return;
+                       return undefined;
+               }
+
+               return this.each(function(){
+                       if ( this.nodeType != 1 )
+                               return;
 
-                               if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
-                                       this.checked = (jQuery.inArray(this.value, value) >= 0 ||
-                                               jQuery.inArray(this.name, value) >= 0);
+                       if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
+                               this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+                                       jQuery.inArray(this.name, value) >= 0);
 
-                               else if ( jQuery.nodeName( this, "select" ) ) {
-                                       var values = value.constructor == Array ?
-                                               value :
-                                               [ value ];
+                       else if ( jQuery.nodeName( this, "select" ) ) {
+                               var values = value.constructor == Array ?
+                                       value :
+                                       [ value ];
 
-                                       jQuery( "option", this ).each(function(){
-                                               this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
-                                                       jQuery.inArray( this.text, values ) >= 0);
-                                       });
+                               jQuery( "option", this ).each(function(){
+                                       this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+                                               jQuery.inArray( this.text, values ) >= 0);
+                               });
 
-                                       if ( !values.length )
-                                               this.selectedIndex = -1;
+                               if ( !values.length )
+                                       this.selectedIndex = -1;
 
-                               } else
-                                       this.value = value;
-                       });
+                       } else
+                               this.value = value;
+               });
        },
        
        html: function( value ) {
@@ -491,7 +498,7 @@ jQuery.fn = jQuery.prototype = {
 
                        jQuery.each(elems, function(){
                                var elem = clone ?
-                                       this.cloneNode( true ) :
+                                       jQuery( this ).clone( true )[0] :
                                        this;
 
                                // execute all scripts after the elements have been injected
@@ -758,9 +765,10 @@ jQuery.extend({
 
        // A method for quickly swapping in/out CSS properties to get correct calculations
        swap: function( elem, options, callback ) {
+               var old = {};
                // Remember the old values, and insert the new ones
                for ( var name in options ) {
-                       elem.style[ "old" + name ] = elem.style[ name ];
+                       old[ name ] = elem.style[ name ];
                        elem.style[ name ] = options[ name ];
                }
 
@@ -768,24 +776,29 @@ jQuery.extend({
 
                // Revert the old values
                for ( var name in options )
-                       elem.style[ name ] = elem.style[ "old" + name ];
+                       elem.style[ name ] = old[ name ];
        },
 
        css: function( elem, name, force ) {
                if ( name == "width" || name == "height" ) {
-                       var width, height, props = { position: "absolute", visibility: "hidden", display:"block" };
+                       var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
                
                        function getWH() {
-                               width = elem.clientWidth;
-                               height = elem.clientHeight;
+                               val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+                               var padding = 0, border = 0;
+                               jQuery.each( which, function() {
+                                       padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+                                       border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+                               });
+                               val -= Math.round(padding + border);
                        }
                
                        if ( jQuery(elem).is(":visible") )
                                getWH();
                        else
                                jQuery.swap( elem, props, getWH );
-
-                       return name == "width" ? width : height;
+                       
+                       return Math.max(0, val);
                }
                
                return jQuery.curCSS( elem, name, force );
@@ -811,6 +824,12 @@ jQuery.extend({
                                "1" :
                                ret;
                }
+               // Opera sometimes will give the wrong display answer, this fixes it, see #2037
+               if ( jQuery.browser.opera && name == "display" ) {
+                       var save = elem.style.display;
+                       elem.style.display = "block";
+                       elem.style.display = save;
+               }
                
                // Make sure we're using the right name for getting the float value
                if ( name.match( /float/i ) )
@@ -967,9 +986,9 @@ jQuery.extend({
                                                        div.childNodes :
                                                        [];
                                
-                                       for ( var i = tbody.length - 1; i >= 0 ; --i )
-                                               if ( jQuery.nodeName( tbody[ i ], "tbody" ) && !tbody[ i ].childNodes.length )
-                                                       tbody[ i ].parentNode.removeChild( tbody[ i ] );
+                                       for ( var j = tbody.length - 1; j >= 0 ; --j )
+                                               if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+                                                       tbody[ j ].parentNode.removeChild( tbody[ j ] );
                                        
                                        // IE completely kills leading whitespace when innerHTML is used        
                                        if ( /^\s/.test( elem ) )