Make sure that dynamically-created elements don't have a parent. Fixes #5638.
[jquery.git] / src / core.js
index 26f6e92..7be1512 100644 (file)
@@ -1,9 +1,7 @@
 // Define a local copy of jQuery
 var jQuery = function( selector, context ) {
                // The jQuery object is actually just the init constructor 'enhanced'
-               return arguments.length === 0 ?
-                       rootjQuery :
-                       new jQuery.fn.init( selector, context );
+               return new jQuery.fn.init( selector, context );
        },
 
        // Map over jQuery in case of overwrite
@@ -52,7 +50,7 @@ var jQuery = function( selector, context ) {
 
 jQuery.fn = jQuery.prototype = {
        init: function( selector, context ) {
-               var match, elem, ret, doc;
+               var match, elem, ret, doc, parent;
 
                // Handle $(""), $(null), or $(undefined)
                if ( !selector ) {
@@ -87,7 +85,12 @@ jQuery.fn = jQuery.prototype = {
 
                                        } else {
                                                ret = buildFragment( [ match[1] ], [ doc ] );
-                                               selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+                                               parent = ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment;
+                                               selector = [];
+
+                                               while ( parent.firstChild ) {
+                                                       selector.push( parent.removeChild( parent.firstChild ) );
+                                               }
                                        }
 
                                // HANDLE: $("#id")
@@ -212,32 +215,13 @@ jQuery.fn = jQuery.prototype = {
        each: function( callback, args ) {
                return jQuery.each( this, callback, args );
        },
-
-       // Determine the position of an element within
-       // the matched set of elements
-       index: function( elem ) {
-               if ( !elem || typeof elem === "string" ) {
-                       return jQuery.inArray( this[0],
-                               // If it receives a string, the selector is used
-                               // If it receives nothing, the siblings are used
-                               elem ? jQuery( elem ) : this.parent().children() );
-               }
-               // Locate the position of the desired element
-               return jQuery.inArray(
-                       // If it receives a jQuery object, the first element is used
-                       elem.jquery ? elem[0] : elem, this );
-       },
-
-       is: function( selector ) {
-               return !!selector && jQuery.filter( selector, this ).length > 0;
-       },
        
        ready: function( fn ) {
                // Attach the listeners
                jQuery.bindReady();
 
                // If the DOM is already ready
-               if ( jQuery.isReady ) {
+               if ( jQuery.isReady && !readyList ) {
                        // Execute the function immediately
                        fn.call( document, jQuery );
 
@@ -249,6 +233,35 @@ jQuery.fn = jQuery.prototype = {
 
                return this;
        },
+       
+       eq: function( i ) {
+               return i === -1 ?
+                       this.slice( i ) :
+                       this.slice( i, +i + 1 );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       slice: function() {
+               return this.pushStack( slice.apply( this, arguments ),
+                       "slice", slice.call(arguments).join(",") );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map(this, function(elem, i){
+                       return callback.call( elem, i, elem );
+               }));
+       },
+       
+       end: function() {
+               return this.prevObject || jQuery(null);
+       },
 
        // For internal use only.
        // Behaves like an Array's method, not like a jQuery method.
@@ -373,8 +386,8 @@ jQuery.extend({
                // Mozilla, Opera and webkit nightlies currently support this event
                if ( document.addEventListener ) {
                        // Use the handy event callback
-                       document.addEventListener( "DOMContentLoaded", function() {
-                               document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
+                       document.addEventListener( "DOMContentLoaded", function DOMContentLoaded() {
+                               document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                                jQuery.ready();
                        }, false );
                        
@@ -385,10 +398,10 @@ jQuery.extend({
                } else if ( document.attachEvent ) {
                        // ensure firing before onload,
                        // maybe late but safe also for iframes
-                       document.attachEvent("onreadystatechange", function() {
+                       document.attachEvent("onreadystatechange", function onreadystatechange() {
                                // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
                                if ( document.readyState === "complete" ) {
-                                       document.detachEvent( "onreadystatechange", arguments.callee );
+                                       document.detachEvent( "onreadystatechange", onreadystatechange );
                                        jQuery.ready();
                                }
                        });
@@ -405,7 +418,9 @@ jQuery.extend({
                        } catch(e){}
 
                        if ( document.documentElement.doScroll && toplevel ) {
-                               (function() {
+                               doScrollCheck();
+
+                               function doScrollCheck() {
                                        if ( jQuery.isReady ) {
                                                return;
                                        }
@@ -415,13 +430,13 @@ jQuery.extend({
                                                // http://javascript.nwbox.com/IEContentLoaded/
                                                document.documentElement.doScroll("left");
                                        } catch( error ) {
-                                               setTimeout( arguments.callee, 0 );
+                                               setTimeout( doScrollCheck, 1 );
                                                return;
                                        }
 
                                        // and execute any waiting functions
                                        jQuery.ready();
-                               })();
+                               }
                        }
                }
        },
@@ -444,8 +459,8 @@ jQuery.extend({
                
                // not own constructor property must be Object
                if ( obj.constructor
-                 && !hasOwnProperty.call(obj, "constructor")
-                 && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+                       && !hasOwnProperty.call(obj, "constructor")
+                       && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
                        return false;
                }
                
@@ -481,7 +496,7 @@ jQuery.extend({
                                script.text = data;
                        }
 
-                       // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+                       // Use insertBefore instead of appendChild to circumvent an IE6 bug.
                        // This arises when a base node is used (#2709).
                        head.insertBefore( script, head.firstChild );
                        head.removeChild( script );
@@ -567,23 +582,20 @@ jQuery.extend({
        },
 
        merge: function( first, second ) {
-               var pos, i = second.length;
+               var i = first.length, j = 0;
 
-               // We have to get length this way when IE & Opera overwrite the length
-               // 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 ];
+               if ( typeof second.length === "number" ) {
+                       for ( var l = second.length; j < l; j++ ) {
+                               first[ i++ ] = second[ j ];
+                       }
+               } else {
+                       while ( second[j] !== undefined ) {
+                               first[ i++ ] = second[ j++ ];
+                       }
                }
 
+               first.length = i;
+
                return first;
        },
 
@@ -618,18 +630,20 @@ jQuery.extend({
                return ret.concat.apply( [], ret );
        },
 
-       // Use of jQuery.browser is deprecated.
-       // It's included for backwards compatibility and plugins,
-       // although they should work to migrate away.
+       // Use of jQuery.browser is frowned upon.
+       // More details: http://docs.jquery.com/Utilities/jQuery.browser
        browser: {
-               version: (/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/.exec(userAgent) || [0,'0'])[1],
-               safari: /webkit/.test( userAgent ),
+               version: (/.*?(?:firefox|safari|opera|msie)[\/ ]([\d.]+)/.exec(userAgent) || [0,'0'])[1],
+               safari: /safari/.test( userAgent ),
                opera: /opera/.test( userAgent ),
                msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
-               mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+               firefox: /firefox/.test( userAgent )
        }
 });
 
+// Deprecated
+jQuery.browser.mozilla = /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent );
+
 if ( indexOf ) {
        jQuery.inArray = function( elem, array ) {
                return indexOf.call( array, elem );
@@ -658,31 +672,30 @@ function evalScript( i, elem ) {
 // Mutifunctional method to get and set values to a collection
 // The value/s can be optionally by executed if its a function
 function access( elems, key, value, exec, fn ) {
-       var l = elems.length;
+       var length = elems.length;
        
        // Setting many attributes
        if ( typeof key === "object" ) {
-                       for (var k in key) {
-                               access(elems, k, key[k], exec, fn);
-                       }
+               for ( var k in key ) {
+                       access( elems, k, key[k], exec, fn );
+               }
                return elems;
        }
        
        // Setting one attribute
-       if (value !== undefined) {
+       if ( value !== undefined ) {
                // Optionally, function values get executed if exec is true
                exec = exec && jQuery.isFunction(value);
                
-               for (var i = 0; i < l; i++) {
-                       var elem = elems[i],
-                               val = exec ? value.call(elem, i) : value;
-                       fn(elem, key, val);
+               for ( var i = 0; i < length; i++ ) {
+                       fn( elems[i], key, exec ? value.call( elems[i], i ) : value );
                }
+               
                return elems;
        }
        
        // Getting an attribute
-       return l ? fn(elems[0], key) : null;
+       return length ? fn( elems[0], key ) : null;
 }
 
 function now() {