Merge branch 'master' of git://github.com/jquery/jquery into fixedbuild
[jquery.git] / src / core.js
index e463ade..9312ee2 100644 (file)
@@ -3,7 +3,7 @@ var jQuery = (function() {
 // Define a local copy of jQuery
 var jQuery = function( selector, context ) {
                // The jQuery object is actually just the init constructor 'enhanced'
-               return new jQuery.fn.init( selector, context );
+               return new jQuery.fn.init( selector, context, rootjQuery );
        },
 
        // Map over jQuery in case of overwrite
@@ -19,20 +19,13 @@ var jQuery = function( selector, context ) {
        // (both of which we optimize for)
        quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
 
-       // Is it a simple selector
-       isSimple = /^.[^:#\[\.,]*$/,
-
        // Check if a string has a non-whitespace character in it
        rnotwhite = /\S/,
-       rwhite = /\s/,
 
        // Used for trimming whitespace
        trimLeft = /^\s+/,
        trimRight = /\s+$/,
 
-       // Check for non-word characters
-       rnonword = /\W/,
-
        // Check for digits
        rdigit = /\d/,
 
@@ -57,11 +50,8 @@ var jQuery = function( selector, context ) {
        // For matching the engine and version of the browser
        browserMatch,
 
-       // Has the ready events already been bound?
-       readyBound = false,
-
-       // The functions to execute on DOM ready
-       readyList = [],
+       // The deferred used on DOM ready
+       readyList,
 
        // The ready event handler
        DOMContentLoaded,
@@ -78,7 +68,8 @@ var jQuery = function( selector, context ) {
        class2type = {};
 
 jQuery.fn = jQuery.prototype = {
-       init: function( selector, context ) {
+       constructor: jQuery,
+       init: function( selector, context, rootjQuery ) {
                var match, elem, ret, doc;
 
                // Handle $(""), $(null), or $(undefined)
@@ -112,6 +103,7 @@ jQuery.fn = jQuery.prototype = {
 
                                // HANDLE: $(html) -> $(array)
                                if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
                                        doc = (context ? context.ownerDocument || context : document);
 
                                        // If a single string is passed in and it's a single tag
@@ -129,7 +121,7 @@ jQuery.fn = jQuery.prototype = {
 
                                        } else {
                                                ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
-                                               selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+                                               selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
                                        }
 
                                        return jQuery.merge( this, selector );
@@ -157,13 +149,6 @@ jQuery.fn = jQuery.prototype = {
                                        return this;
                                }
 
-                       // HANDLE: $("TAG")
-                       } else if ( !context && !rnonword.test( selector ) ) {
-                               this.selector = selector;
-                               this.context = document;
-                               selector = document.getElementsByTagName( selector );
-                               return jQuery.merge( this, selector );
-
                        // HANDLE: $(expr, $(...))
                        } else if ( !context || context.jquery ) {
                                return (context || rootjQuery).find( selector );
@@ -171,7 +156,7 @@ jQuery.fn = jQuery.prototype = {
                        // HANDLE: $(expr, context)
                        // (which is just equivalent to: $(context).find(expr)
                        } else {
-                               return jQuery( context ).find( selector );
+                               return this.constructor( context ).find( selector );
                        }
 
                // HANDLE: $(function)
@@ -222,7 +207,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();
+               var ret = this.constructor();
 
                if ( jQuery.isArray( elems ) ) {
                        push.apply( ret, elems );
@@ -257,16 +242,8 @@ jQuery.fn = jQuery.prototype = {
                // Attach the listeners
                jQuery.bindReady();
 
-               // If the DOM is already ready
-               if ( jQuery.isReady ) {
-                       // Execute the function immediately
-                       fn.call( document, jQuery );
-
-               // Otherwise, remember the function for later
-               } else if ( readyList ) {
-                       // Add the function to the wait list
-                       readyList.push( fn );
-               }
+               // Add the callback
+               readyList.done( fn );
 
                return this;
        },
@@ -297,7 +274,7 @@ jQuery.fn = jQuery.prototype = {
        },
 
        end: function() {
-               return this.prevObject || jQuery(null);
+               return this.prevObject || this.constructor(null);
        },
 
        // For internal use only.
@@ -311,7 +288,7 @@ jQuery.fn = jQuery.prototype = {
 jQuery.fn.init.prototype = jQuery.fn;
 
 jQuery.extend = jQuery.fn.extend = function() {
-        var options, name, src, copy, copyIsArray, clone,
+       var options, name, src, copy, copyIsArray, clone,
                target = arguments[0] || {},
                i = 1,
                length = arguments.length,
@@ -415,33 +392,21 @@ jQuery.extend({
                        }
 
                        // If there are functions bound, to execute
-                       if ( readyList ) {
-                               // Execute all of them
-                               var fn,
-                                       i = 0,
-                                       ready = readyList;
-
-                               // Reset the list of functions
-                               readyList = null;
+                       readyList.resolveWith( document, [ jQuery ] );
 
-                               while ( (fn = ready[ i++ ]) ) {
-                                       fn.call( document, jQuery );
-                               }
-
-                               // Trigger any bound ready events
-                               if ( jQuery.fn.trigger ) {
-                                       jQuery( document ).trigger( "ready" ).unbind( "ready" );
-                               }
+                       // Trigger any bound ready events
+                       if ( jQuery.fn.trigger ) {
+                               jQuery( document ).trigger( "ready" ).unbind( "ready" );
                        }
                }
        },
 
        bindReady: function() {
-               if ( readyBound ) {
+               if ( readyList ) {
                        return;
                }
 
-               readyBound = true;
+               readyList = jQuery._Deferred();
 
                // Catch cases where $(document).ready() is called after the
                // browser event has already occurred.
@@ -566,6 +531,28 @@ jQuery.extend({
                }
        },
 
+       // Cross-browser xml parsing
+       // (xml & tmp used internally)
+       parseXML: function( data , xml , tmp ) {
+
+               if ( window.DOMParser ) { // Standard
+                       tmp = new DOMParser();
+                       xml = tmp.parseFromString( data , "text/xml" );
+               } else { // IE
+                       xml = new ActiveXObject( "Microsoft.XMLDOM" );
+                       xml.async = "false";
+                       xml.loadXML( data );
+               }
+
+               tmp = xml.documentElement;
+
+               if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+                       jQuery.error( "Invalid XML: " + data );
+               }
+
+               return xml;
+       },
+
        noop: function() {},
 
        // Evalulates a script in a global context
@@ -573,12 +560,10 @@ jQuery.extend({
                if ( data && rnotwhite.test(data) ) {
                        // Inspired by code by Andrea Giammarchi
                        // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
-                       var head = document.getElementsByTagName("head")[0] || document.documentElement,
-                               script = document.createElement("script");
-
-                       script.type = "text/javascript";
+                       var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
+                               script = document.createElement( "script" );
 
-                       if ( jQuery.support.scriptEval ) {
+                       if ( jQuery.support.scriptEval() ) {
                                script.appendChild( document.createTextNode( data ) );
                        } else {
                                script.text = data;
@@ -815,6 +800,27 @@ jQuery.extend({
                return { browser: match[1] || "", version: match[2] || "0" };
        },
 
+       sub: function() {
+               function jQuerySubclass( selector, context ) {
+                       return new jQuerySubclass.fn.init( selector, context );
+               }
+               jQuery.extend( true, jQuerySubclass, this );
+               jQuerySubclass.superclass = this;
+               jQuerySubclass.fn = jQuerySubclass.prototype = this();
+               jQuerySubclass.fn.constructor = jQuerySubclass;
+               jQuerySubclass.subclass = this.subclass;
+               jQuerySubclass.fn.init = function init( selector, context ) {
+                       if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) {
+                               context = jQuerySubclass(context);
+                       }
+
+                       return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass );
+               };
+               jQuerySubclass.fn.init.prototype = jQuerySubclass.fn;
+               var rootjQuerySubclass = jQuerySubclass(document);
+               return jQuerySubclass;
+       },
+
        browser: {}
 });
 
@@ -840,9 +846,8 @@ if ( indexOf ) {
        };
 }
 
-// Verify that \s matches non-breaking spaces
-// (IE fails on this test)
-if ( !rwhite.test( "\xA0" ) ) {
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
        trimLeft = /^[\s\xA0]+/;
        trimRight = /[\s\xA0]+$/;
 }
@@ -886,12 +891,7 @@ function doScrollCheck() {
        jQuery.ready();
 }
 
-// Expose jQuery as an Asynchronous Module
-if ( typeof define === "function" ) {
-       define( "jquery", [], function () { return jQuery; } );
-}
-
 // Expose jQuery to the global object
-return (window.jQuery = window.$ = jQuery);
+return jQuery;
 
 })();