X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fcore.js;h=8c623632daf3f4b51427ef7d66ad19e916d5f79c;hb=93adf60811524d6ef9ada12e826cb99cbf550663;hp=4949d6bf4e2a9de52eb0ca2683125e9be9433861;hpb=2b481b93cfca62f95aa7005e7db651456fa08e65;p=jquery.git diff --git a/src/core.js b/src/core.js index 4949d6b..8c62363 100644 --- a/src/core.js +++ b/src/core.js @@ -29,13 +29,19 @@ var jQuery = function( selector, context ) { rnotwhite = /\S/, // Used for trimming whitespace - rtrim = /(\s|\u00A0)+|(\s|\u00A0)+$/g, + rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, // Match a standalone tag rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, // Keep a UserAgent string for use with jQuery.browser userAgent = navigator.userAgent.toLowerCase(), + + // Has the ready events already been bound? + readyBound = false, + + // The functions to execute on DOM ready + readyList = [], // Save a reference to some core methods toString = Object.prototype.toString, @@ -225,6 +231,24 @@ jQuery.fn = jQuery.prototype = { 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 ) { + // Execute the function immediately + fn.call( document, jQuery ); + + // Otherwise, remember the function for later + } else { + // Add the function to the wait list + readyList.push( fn ); + } + + return this; + }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. @@ -273,9 +297,9 @@ jQuery.extend = jQuery.fn.extend = function() { } // Recurse if we're merging object literal values - if ( deep && copy && jQuery.isObjectLiteral(copy) ) { + if ( deep && copy && jQuery.isPlainObject(copy) ) { // Don't extend not object literals - var clone = src && jQuery.isObjectLiteral(src) ? src : {}; + var clone = src && jQuery.isPlainObject(src) ? src : {}; // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); @@ -302,6 +326,107 @@ jQuery.extend({ return jQuery; }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // Handle when the DOM is ready + ready: function() { + // Make sure that the DOM is not already loaded + if ( !jQuery.isReady ) { + if ( !document.body ) { + return setTimeout( jQuery.ready, 13 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If there are functions bound, to execute + if ( readyList ) { + // Execute all of them + var fn, i = 0; + while ( (fn = readyList[ i++ ]) ) { + fn.call( document, jQuery ); + } + + // Reset the list of functions + readyList = null; + } + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + } + } + }, + + bindReady: function() { + if ( readyBound ) { return; } + readyBound = true; + + // Catch cases where $(document).ready() is called after the + // browser event has already occurred. + if ( document.readyState === "complete" ) { + return jQuery.ready(); + } + + // Mozilla, Opera and webkit nightlies currently support this event + if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", function DOMContentLoaded() { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + }, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else if ( document.attachEvent ) { + // ensure firing before onload, + // maybe late but safe also for iframes + 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", onreadystatechange ); + jQuery.ready(); + } + }); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var toplevel = false; + + try { + toplevel = window.frameElement == null; + } catch(e){} + + if ( document.documentElement.doScroll && toplevel ) { + doScrollCheck(); + + function doScrollCheck() { + if ( jQuery.isReady ) { + return; + } + + try { + // If IE is used, use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + document.documentElement.doScroll("left"); + } catch( error ) { + setTimeout( doScrollCheck, 1 ); + return; + } + + // and execute any waiting functions + jQuery.ready(); + } + } + } + }, // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert @@ -314,7 +439,7 @@ jQuery.extend({ return toString.call(obj) === "[object Array]"; }, - isObjectLiteral: function( obj ) { + isPlainObject: function( obj ) { if ( toString.call(obj) !== "[object Object]" || typeof obj.nodeType === "number" ) { return false; } @@ -342,14 +467,6 @@ jQuery.extend({ return true; }, - // check if an element is in a (or is an) XML document - isXMLDoc: function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; - }, - // Evalulates a script in a global context globalEval: function( data ) { if ( data && rnotwhite.test(data) ) { @@ -425,7 +542,9 @@ jQuery.extend({ if ( array != null ) { // The window, strings (and functions) also have 'length' - if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval ) { + // The extra typeof function check is to prevent crashes + // in Safari 2 (See: #3039) + if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) { push.call( ret, array ); } else { jQuery.merge( ret, array );