X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fcore.js;h=f6a07eb8baef66002f3cc8bb2b63d3e2ed434796;hb=e270d804b4cee58dbf438251e9becb6f0f2ac123;hp=81a920b874e74fd2c395341c46e69bbbc5ab5fb7;hpb=5d2be7e299131a31cffbd73edea59cde30445608;p=jquery.git diff --git a/src/core.js b/src/core.js index 81a920b..f6a07eb 100644 --- a/src/core.js +++ b/src/core.js @@ -1,4 +1,4 @@ -(function() { +var jQuery = (function() { // Define a local copy of jQuery var jQuery = function( selector, context ) { @@ -12,29 +12,42 @@ var jQuery = function( selector, context ) { // Map over the $ in case of overwrite _$ = window.$, - // Use the correct document accordingly with window argument (sandbox) - //document = window.document, - // A central reference to the root jQuery(document) rootjQuery, // 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, @@ -109,7 +122,7 @@ jQuery.fn = jQuery.prototype = { } } else { - ret = buildFragment( [ match[1] ], [ doc ] ); + ret = jQuery.buildFragment( [ match[1] ], [ doc ] ); selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; } @@ -119,7 +132,9 @@ jQuery.fn = jQuery.prototype = { } else { elem = document.getElementById( match[2] ); - if ( elem ) { + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { // Handle the case where IE and Opera return items // by name instead of ID if ( elem.id !== match[2] ) { @@ -137,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 ); @@ -358,11 +373,20 @@ jQuery.extend({ // Is the DOM ready to be used? Set to true once it occurs. isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, // Handle when the DOM is ready - ready: function() { + ready: function( wait ) { + // A third-party is pushing the ready event forwards + if ( wait === true ) { + jQuery.readyWait--; + } + // Make sure that the DOM is not already loaded - if ( !jQuery.isReady ) { + if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready, 13 ); @@ -371,6 +395,11 @@ jQuery.extend({ // Remember that the DOM is ready jQuery.isReady = true; + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + // If there are functions bound, to execute if ( readyList ) { // Execute all of them @@ -400,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 @@ -441,15 +471,18 @@ jQuery.extend({ return jQuery.type(obj) === "function"; }, - isArray: function( obj ) { + isArray: Array.isArray || function( obj ) { 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 ? - "null" : - obj === undefined ? - "undefined" : + return obj == null ? + String( obj ) : toString.call(obj).slice(8, -1).toLowerCase(); }, @@ -457,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; } @@ -498,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 ? @@ -605,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" || (typeof type !== "function" && array.setInterval) ) { + if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { push.call( ret, array ); } else { jQuery.merge( ret, array ); @@ -750,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" }; @@ -781,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]+$/; } @@ -826,6 +859,6 @@ function doScrollCheck() { } // Expose jQuery to the global object -window.jQuery = window.$ = jQuery; +return (window.jQuery = window.$ = jQuery); })();