// Check for non-word characters
rnonword = /\W/,
+ // Check for digits
+ rdigit = /\d/,
+
// Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
// 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,
slice = Array.prototype.slice,
trim = String.prototype.trim,
indexOf = Array.prototype.indexOf,
-
+
// [[Class]] -> type pairs
- class2type = {};
+ class2type = {},
+
+ // Marker for deferred
+ deferredMarker = [];
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {
this.length = 1;
return this;
}
-
+
// The body element only exists once, optimize finding it
- if ( selector === "body" && !context ) {
+ if ( selector === "body" && !context && document.body ) {
this.context = document;
this[0] = document.body;
this.selector = "body";
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
-
+
return jQuery.merge( this, selector );
-
+
// HANDLE: $("#id")
} else {
elem = document.getElementById( match[2] );
this.toArray() :
// Return just the object
- ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
},
// Take an array of elements and push it onto the stack
if ( jQuery.isArray( elems ) ) {
push.apply( ret, elems );
-
+
} else {
jQuery.merge( ret, elems );
}
return jQuery.each( this, callback, args );
},
- ready: function( fn ) {
+ ready: function() {
// 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 );
- }
-
- return this;
+
+ // Change ready & apply
+ return ( jQuery.fn.ready = readyList.then ).apply( this , arguments );
},
-
+
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
return callback.call( elem, i, elem );
}));
},
-
+
end: function() {
return this.prevObject || jQuery(null);
},
jQuery.fn.init.prototype = jQuery.fn;
jQuery.extend = jQuery.fn.extend = function() {
- // copy reference to target object
- var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
return jQuery;
},
-
+
// 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( wait ) {
// A third-party is pushing the ready event forwards
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 );
+ return setTimeout( jQuery.ready, 1 );
}
// Remember that the DOM is ready
}
// 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;
- }
-
+ readyList.fire( document , [ jQuery ] );
+
// Trigger any bound ready events
- if ( jQuery.fn.triggerHandler ) {
- jQuery( document ).triggerHandler( "ready" );
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
}
}
},
-
+
bindReady: function() {
if ( readyBound ) {
return;
// 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, 1 );
}
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-
+
// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent("onreadystatechange", DOMContentLoaded);
-
+
// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );
return obj && typeof obj === "object" && "setInterval" in obj;
},
+ isNaN: function( obj ) {
+ return obj == null || !rdigit.test( obj ) || isNaN( obj );
+ },
+
type: function( obj ) {
return obj == null ?
String( obj ) :
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
return false;
}
-
+
// Not own constructor property must be Object
if ( obj.constructor &&
!hasOwn.call(obj, "constructor") &&
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
return false;
}
-
+
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
-
+
var key;
for ( key in obj ) {}
-
+
return key === undefined || hasOwn.call( obj, key );
},
}
return true;
},
-
+
error: function( msg ) {
throw msg;
},
-
+
parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = jQuery.trim( data );
-
+
// Make sure the incoming data is actual JSON
// Logic borrowed from http://json.org/json2.js
if ( rvalidchars.test(data.replace(rvalidescape, "@")
},
merge: function( first, second ) {
- var i = first.length, j = 0;
+ var i = first.length,
+ j = 0;
if ( typeof second.length === "number" ) {
for ( var l = second.length; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
-
+
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
+ // Flatten any nested arrays
return ret.concat.apply( [], ret );
},
// The value/s can be optionally by executed if its a function
access: function( elems, key, value, exec, fn, pass ) {
var length = elems.length;
-
+
// Setting many attributes
if ( typeof key === "object" ) {
for ( var k in key ) {
}
return elems;
}
-
+
// Setting one attribute
if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
exec = !pass && exec && jQuery.isFunction(value);
-
+
for ( var i = 0; i < length; i++ ) {
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}
-
+
return elems;
}
-
+
// Getting an attribute
return length ? fn( elems[0], key ) : undefined;
},
now: function() {
return (new Date()).getTime();
},
+
+ // Create a simple deferred (one callbacks list)
+ _deferred: function( cancellable ) {
+
+ // cancellable by default
+ cancellable = cancellable !== false;
+
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // then( f1, f2, ...)
+ then: function then() {
+
+ if ( ! cancelled ) {
+
+ var args = arguments,
+ i,
+ length,
+ elem,
+ type,
+ _fired;
+
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+
+ for ( i = 0, length = args.length ; i < length ; i++ ) {
+ elem = args[ i ];
+ type = jQuery.type( elem );
+ if ( type === "array" ) {
+ then.apply( this , elem );
+ } else if ( type === "function" ) {
+ callbacks.push( elem );
+ }
+ }
+
+ if ( _fired ) {
+ deferred.fire( _fired[ 0 ] , _fired[ 1 ] );
+ }
+ }
+ return this;
+ },
+
+ // resolve with given context and args
+ // (i is used internally)
+ fire: function( context , args , i ) {
+ if ( ! cancelled && ! fired && ! firing ) {
+ firing = 1;
+ try {
+ for( i = 0 ; ! cancelled && callbacks[ i ] ; i++ ) {
+ cancelled = ( callbacks[ i ].apply( context , args ) === false ) && cancellable;
+ }
+ } catch( e ) {
+ cancelled = cancellable;
+ jQuery.error( e );
+ } finally {
+ fired = [ context , args ];
+ callbacks = cancelled ? [] : callbacks.slice( i + 1 );
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.fire( this , arguments );
+ return this;
+ },
+
+ // cancelling further callbacks
+ cancel: function() {
+ if ( cancellable ) {
+ callbacks = [];
+ cancelled = 1;
+ }
+ return this;
+ }
+
+ };
+
+ // Add the deferred marker
+ deferred.then._ = deferredMarker;
+
+ return deferred;
+ },
+
+ // Full fledged deferred (two callbacks list)
+ // Typical success/error system
+ deferred: function( func , cancellable ) {
+
+ // Handle varargs
+ if ( arguments.length === 1 ) {
+
+ if ( typeof func === "boolean" ) {
+ cancellable = func;
+ func = 0;
+ }
+ }
+
+ var errorDeferred = jQuery._deferred( cancellable ),
+ deferred = jQuery._deferred( cancellable ),
+ // Keep reference of the cancel method since we'll redefine it
+ cancelThen = deferred.cancel;
+
+ // Add errorDeferred methods and redefine cancel
+ jQuery.extend( deferred , {
+
+ fail: errorDeferred.then,
+ fireReject: errorDeferred.fire,
+ reject: errorDeferred.resolve,
+ cancel: function() {
+ cancelThen();
+ errorDeferred.cancel();
+ return this;
+ }
+
+ } );
+
+ // Make sure only one callback list will be used
+ deferred.then( errorDeferred.cancel ).fail( cancelThen );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred , deferred );
+ }
+
+ return deferred;
+ },
+
+ // Check if an object is a deferred
+ isDeferred: function( object , method ) {
+ method = method || "then";
+ return !!( object && object[ method ] && object[ method ]._ === deferredMarker );
+ },
+
+ // Deferred helper
+ when: function( object , method ) {
+ method = method || "then";
+ object = jQuery.isDeferred( object , method ) ?
+ object :
+ jQuery.deferred().resolve( object );
+ object.fail = object.fail || function() { return this; };
+ object[ method ] = object[ method ] || object.then;
+ object.then = object.then || object[ method ];
+ return object;
+ },
// Use of jQuery.browser is frowned upon.
// More details: http://docs.jquery.com/Utilities/jQuery.browser
browser: {}
});
+// Create readyList deferred
+// also force $.fn.ready to be recognized as a defer
+readyList = jQuery._deferred( false );
+jQuery.fn.ready._ = deferredMarker;
+
// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
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);