Delay the result of the readyState check to give scripts the opportunity to delay...
[jquery.git] / src / core.js
index 7bc0fb9..f6a07eb 100644 (file)
@@ -17,21 +17,37 @@ var jQuery = function( selector, context ) {
 
        // A simple way to check for HTML strings or ID strings
        // (both of which we optimize for)
-       quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w\-]+)$/,
+       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/,
+
        // Match a standalone tag
        rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
 
+       // JSON RegExp
+       rvalidchars = /^[\],:{}\s]*$/,
+       rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+       rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+       rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+       // Useragent RegExp
+       rwebkit = /(webkit)[ \/]([\w.]+)/,
+       ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+       rmsie = /(msie) ([\w.]+)/,
+       rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
        // Keep a UserAgent string for use with jQuery.browser
        userAgent = navigator.userAgent,
 
@@ -136,7 +152,7 @@ jQuery.fn = jQuery.prototype = {
                                }
 
                        // HANDLE: $("TAG")
-                       } else if ( !context && /^\w+$/.test( selector ) ) {
+                       } else if ( !context && !rnonword.test( selector ) ) {
                                this.selector = selector;
                                this.context = document;
                                selector = document.getElementsByTagName( selector );
@@ -413,7 +429,8 @@ jQuery.extend({
                // Catch cases where $(document).ready() is called after the
                // browser event has already occurred.
                if ( document.readyState === "complete" ) {
-                       return jQuery.ready();
+                       // Handle it asynchronously to allow scripts the opportunity to delay ready
+                       return setTimeout( jQuery.ready, 13 );
                }
 
                // Mozilla, Opera and webkit nightlies currently support this event
@@ -458,6 +475,11 @@ jQuery.extend({
                return jQuery.type(obj) === "array";
        },
 
+       // A crude way of determining if an object is a window
+       isWindow: function( obj ) {
+               return obj && typeof obj === "object" && "setInterval" in obj;
+       },
+
        type: function( obj ) {
                return obj == null ?
                        String( obj ) :
@@ -468,7 +490,7 @@ jQuery.extend({
                // Must be an Object.
                // Because of IE, we also have to check the presence of the constructor property.
                // Make sure that DOM nodes and window objects don't pass through, as well
-               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || obj.setInterval ) {
+               if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
                        return false;
                }
                
@@ -509,9 +531,9 @@ jQuery.extend({
                
                // Make sure the incoming data is actual JSON
                // Logic borrowed from http://json.org/json2.js
-               if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
-                       .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
-                       .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+               if ( rvalidchars.test(data.replace(rvalidescape, "@")
+                       .replace(rvalidtokens, "]")
+                       .replace(rvalidbraces, "")) ) {
 
                        // Try to use the native JSON parser first
                        return window.JSON && window.JSON.parse ?
@@ -616,7 +638,7 @@ jQuery.extend({
                        // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
                        var type = jQuery.type(array);
 
-                       if ( array.length == null || type === "string" || type === "function" || type === "regexp" || "setInterval" in array ) {
+                       if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
                                push.call( ret, array );
                        } else {
                                jQuery.merge( ret, array );
@@ -761,10 +783,10 @@ jQuery.extend({
        uaMatch: function( ua ) {
                ua = ua.toLowerCase();
 
-               var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
-                       /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
-                       /(msie) ([\w.]+)/.exec( ua ) ||
-                       !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+               var match = rwebkit.exec( ua ) ||
+                       ropera.exec( ua ) ||
+                       rmsie.exec( ua ) ||
+                       ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
                        [];
 
                return { browser: match[1] || "", version: match[2] || "0" };
@@ -792,7 +814,7 @@ if ( indexOf ) {
 
 // Verify that \s matches non-breaking spaces
 // (IE fails on this test)
-if ( !/\s/.test( "\xA0" ) ) {
+if ( !rwhite.test( "\xA0" ) ) {
        trimLeft = /^[\s\xA0]+/;
        trimRight = /[\s\xA0]+$/;
 }