Simplified the isXML function, no need to use recursion.
[jquery.git] / src / core.js
index ba796bc..55e6236 100644 (file)
@@ -10,7 +10,9 @@ var
 
        jQuery = window.jQuery = window.$ = function( selector, context ) {
                // The jQuery object is actually just the init constructor 'enhanced'
-               return new jQuery.fn.init( selector, context );
+               return selector === undefined ?
+                       rootjQuery :
+                       new jQuery.fn.init( selector, context );
        },
 
        // A simple way to check for HTML strings or ID strings
@@ -21,8 +23,11 @@ var
 
 jQuery.fn = jQuery.prototype = {
        init: function( selector, context ) {
-               // Make sure that a selection was provided
-               selector = selector || document;
+               // Handle $("") or $(null)
+               if ( !selector ) {
+                       this.length = 0;
+                       return this;
+               }
 
                // Handle $(DOMElement)
                if ( selector.nodeType ) {
@@ -31,6 +36,7 @@ jQuery.fn = jQuery.prototype = {
                        this.context = selector;
                        return this;
                }
+
                // Handle HTML strings
                if ( typeof selector === "string" ) {
                        // Are we dealing with HTML string or an ID?
@@ -40,34 +46,41 @@ jQuery.fn = jQuery.prototype = {
                        if ( match && (match[1] || !context) ) {
 
                                // HANDLE: $(html) -> $(array)
-                               if ( match[1] )
+                               if ( match[1] ) {
                                        selector = jQuery.clean( [ match[1] ], context );
 
                                // HANDLE: $("#id")
-                               else {
+                               } else {
                                        var elem = document.getElementById( match[3] );
 
                                        // Handle the case where IE and Opera return items
                                        // by name instead of ID
-                                       if ( elem && elem.id != match[3] )
-                                               return jQuery().find( selector );
+                                       if ( elem && elem.id != match[3] ) {
+                                               return rootjQuery.find( selector );
+                                       }
 
                                        // Otherwise, we inject the element directly into the jQuery object
-                                       var ret = jQuery( elem || [] );
+                                       var ret = jQuery( elem || null );
                                        ret.context = document;
                                        ret.selector = selector;
                                        return ret;
                                }
 
-                       // HANDLE: $(expr, [context])
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return (context || rootjQuery).find( selector );
+
+                       // HANDLE: $(expr, context)
                        // (which is just equivalent to: $(content).find(expr)
-                       } else
+                       } else {
                                return jQuery( context ).find( selector );
+                       }
 
                // HANDLE: $(function)
                // Shortcut for document ready
-               } else if ( jQuery.isFunction( selector ) )
-                       return jQuery( document ).ready( selector );
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return rootjQuery.ready( selector );
+               }
 
                // Make sure that old selector state is passed along
                if ( selector.selector && selector.context ) {
@@ -107,7 +120,7 @@ jQuery.fn = jQuery.prototype = {
        // (returning the new matched element set)
        pushStack: function( elems, name, selector ) {
                // Build a new jQuery matched element set
-               var ret = jQuery( elems );
+               var ret = jQuery( elems || null );
 
                // Add the old object onto the stack (as a reference)
                ret.prevObject = this;
@@ -263,7 +276,7 @@ jQuery.fn = jQuery.prototype = {
        },
 
        end: function() {
-               return this.prevObject || jQuery( [] );
+               return this.prevObject || jQuery(null);
        },
 
        // For internal use only.
@@ -274,14 +287,16 @@ jQuery.fn = jQuery.prototype = {
 
        find: function( selector ) {
                if ( this.length === 1 ) {
-                       var ret = this.pushStack( [], "find", selector );
-                       ret.length = 0;
+                       var ret = this.pushStack( "", "find", selector );
                        jQuery.find( selector, this[0], ret );
                        return ret;
                } else {
-                       return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
-                               return jQuery.find( selector, elem );
-                       })), "find", selector );
+                       var ret = this.pushStack( "", "find", selector );
+                       for ( var i = 0, l = this.length; i < l; i++ ) {
+                               jQuery.find( selector, this[i], ret );
+                       }
+                       //jQuery.find.uniqueSort( ret );
+                       return ret;
                }
        },
 
@@ -1146,6 +1161,9 @@ jQuery.extend({
        }
 });
 
+// All jQuery objects should point back to these
+var rootjQuery = jQuery(document);
+
 // Use of jQuery.browser is deprecated.
 // It's included for backwards compatibility and plugins,
 // although they should work to migrate away.
@@ -1224,24 +1242,28 @@ jQuery.each({
        },
 
        remove: function( selector ) {
-               if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
-                       // Prevent memory leaks
-                       jQuery( "*", this ).add([this]).each(function(){
-                               jQuery.event.remove(this);
-                               jQuery.removeData(this);
-                       });
-                       if (this.parentNode)
+               if ( !selector || jQuery.multiFilter( selector, [ this ] ).length ) {
+                       if ( this.nodeType === 1 ) {
+                               cleanData( this.getElementsByTagName("*") );
+                               cleanData( [this] );
+                       }
+
+                       if ( this.parentNode ) {
                                this.parentNode.removeChild( this );
+                       }
                }
        },
 
        empty: function() {
                // Remove element nodes and prevent memory leaks
-               jQuery(this).children().remove();
+               if ( this.nodeType === 1 ) {
+                       cleanData( this.getElementsByTagName("*") );
+               }
 
                // Remove any remaining nodes
-               while ( this.firstChild )
+               while ( this.firstChild ) {
                        this.removeChild( this.firstChild );
+               }
        }
 }, function(name, fn){
        jQuery.fn[ name ] = function(){
@@ -1249,6 +1271,15 @@ jQuery.each({
        };
 });
 
+function cleanData( elems ) {
+       for ( var i = 0, l = elems.length; i < l; i++ ) {
+               var id = elems[i][expando];
+               if ( id ) {
+                       delete jQuery.cache[ id ];
+               }
+       }
+}
+
 // Helper function used by the dimensions and offset modules
 function num(elem, prop) {
        return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;