Remove forever-alone regexps in event.js
[jquery.git] / src / core.js
blob9e5a5523d5aa425aa9f3cb4c28a1f72ef8bad471
1 var jQuery = (function() {
3 // Define a local copy of jQuery
4 var jQuery = function( selector, context ) {
5                 // The jQuery object is actually just the init constructor 'enhanced'
6                 return new jQuery.fn.init( selector, context, rootjQuery );
7         },
9         // Map over jQuery in case of overwrite
10         _jQuery = window.jQuery,
12         // Map over the $ in case of overwrite
13         _$ = window.$,
15         // A central reference to the root jQuery(document)
16         rootjQuery,
18         // A simple way to check for HTML strings or ID strings
19         // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
20         quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
22         // Check if a string has a non-whitespace character in it
23         rnotwhite = /\S/,
25         // Used for trimming whitespace
26         trimLeft = /^\s+/,
27         trimRight = /\s+$/,
29         // Check for digits
30         rdigit = /\d/,
32         // Match a standalone tag
33         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
35         // JSON RegExp
36         rvalidchars = /^[\],:{}\s]*$/,
37         rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
38         rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
39         rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
41         // Useragent RegExp
42         rwebkit = /(webkit)[ \/]([\w.]+)/,
43         ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
44         rmsie = /(msie) ([\w.]+)/,
45         rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
47         // Matches dashed string for camelizing
48         rdashAlpha = /-([a-z]|[0-9])/ig,
49         rmsPrefix = /^-ms-/,
51         // Used by jQuery.camelCase as callback to replace()
52         fcamelCase = function( all, letter ) {
53                 return ( letter + "" ).toUpperCase();
54         },
56         // Keep a UserAgent string for use with jQuery.browser
57         userAgent = navigator.userAgent,
59         // For matching the engine and version of the browser
60         browserMatch,
62         // The deferred used on DOM ready
63         readyList,
65         // The ready event handler
66         DOMContentLoaded,
68         // Save a reference to some core methods
69         toString = Object.prototype.toString,
70         hasOwn = Object.prototype.hasOwnProperty,
71         push = Array.prototype.push,
72         slice = Array.prototype.slice,
73         trim = String.prototype.trim,
74         indexOf = Array.prototype.indexOf,
76         // [[Class]] -> type pairs
77         class2type = {};
79 jQuery.fn = jQuery.prototype = {
80         constructor: jQuery,
81         init: function( selector, context, rootjQuery ) {
82                 var match, elem, ret, doc;
84                 // Handle $(""), $(null), or $(undefined)
85                 if ( !selector ) {
86                         return this;
87                 }
89                 // Handle $(DOMElement)
90                 if ( selector.nodeType ) {
91                         this.context = this[0] = selector;
92                         this.length = 1;
93                         return this;
94                 }
96                 // The body element only exists once, optimize finding it
97                 if ( selector === "body" && !context && document.body ) {
98                         this.context = document;
99                         this[0] = document.body;
100                         this.selector = selector;
101                         this.length = 1;
102                         return this;
103                 }
105                 // Handle HTML strings
106                 if ( typeof selector === "string" ) {
107                         // Are we dealing with HTML string or an ID?
108                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
109                                 // Assume that strings that start and end with <> are HTML and skip the regex check
110                                 match = [ null, selector, null ];
112                         } else {
113                                 match = quickExpr.exec( selector );
114                         }
116                         // Verify a match, and that no context was specified for #id
117                         if ( match && (match[1] || !context) ) {
119                                 // HANDLE: $(html) -> $(array)
120                                 if ( match[1] ) {
121                                         context = context instanceof jQuery ? context[0] : context;
122                                         doc = ( context ? context.ownerDocument || context : document );
124                                         // If a single string is passed in and it's a single tag
125                                         // just do a createElement and skip the rest
126                                         ret = rsingleTag.exec( selector );
128                                         if ( ret ) {
129                                                 if ( jQuery.isPlainObject( context ) ) {
130                                                         selector = [ document.createElement( ret[1] ) ];
131                                                         jQuery.fn.attr.call( selector, context, true );
133                                                 } else {
134                                                         selector = [ doc.createElement( ret[1] ) ];
135                                                 }
137                                         } else {
138                                                 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
139                                                 selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
140                                         }
142                                         return jQuery.merge( this, selector );
144                                 // HANDLE: $("#id")
145                                 } else {
146                                         elem = document.getElementById( match[2] );
148                                         // Check parentNode to catch when Blackberry 4.6 returns
149                                         // nodes that are no longer in the document #6963
150                                         if ( elem && elem.parentNode ) {
151                                                 // Handle the case where IE and Opera return items
152                                                 // by name instead of ID
153                                                 if ( elem.id !== match[2] ) {
154                                                         return rootjQuery.find( selector );
155                                                 }
157                                                 // Otherwise, we inject the element directly into the jQuery object
158                                                 this.length = 1;
159                                                 this[0] = elem;
160                                         }
162                                         this.context = document;
163                                         this.selector = selector;
164                                         return this;
165                                 }
167                         // HANDLE: $(expr, $(...))
168                         } else if ( !context || context.jquery ) {
169                                 return ( context || rootjQuery ).find( selector );
171                         // HANDLE: $(expr, context)
172                         // (which is just equivalent to: $(context).find(expr)
173                         } else {
174                                 return this.constructor( context ).find( selector );
175                         }
177                 // HANDLE: $(function)
178                 // Shortcut for document ready
179                 } else if ( jQuery.isFunction( selector ) ) {
180                         return rootjQuery.ready( selector );
181                 }
183                 if ( selector.selector !== undefined ) {
184                         this.selector = selector.selector;
185                         this.context = selector.context;
186                 }
188                 return jQuery.makeArray( selector, this );
189         },
191         // Start with an empty selector
192         selector: "",
194         // The current version of jQuery being used
195         jquery: "@VERSION",
197         // The default length of a jQuery object is 0
198         length: 0,
200         // The number of elements contained in the matched element set
201         size: function() {
202                 return this.length;
203         },
205         toArray: function() {
206                 return slice.call( this, 0 );
207         },
209         // Get the Nth element in the matched element set OR
210         // Get the whole matched element set as a clean array
211         get: function( num ) {
212                 return num == null ?
214                         // Return a 'clean' array
215                         this.toArray() :
217                         // Return just the object
218                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
219         },
221         // Take an array of elements and push it onto the stack
222         // (returning the new matched element set)
223         pushStack: function( elems, name, selector ) {
224                 // Build a new jQuery matched element set
225                 var ret = this.constructor();
227                 if ( jQuery.isArray( elems ) ) {
228                         push.apply( ret, elems );
230                 } else {
231                         jQuery.merge( ret, elems );
232                 }
234                 // Add the old object onto the stack (as a reference)
235                 ret.prevObject = this;
237                 ret.context = this.context;
239                 if ( name === "find" ) {
240                         ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
241                 } else if ( name ) {
242                         ret.selector = this.selector + "." + name + "(" + selector + ")";
243                 }
245                 // Return the newly-formed element set
246                 return ret;
247         },
249         // Execute a callback for every element in the matched set.
250         // (You can seed the arguments with an array of args, but this is
251         // only used internally.)
252         each: function( callback, args ) {
253                 return jQuery.each( this, callback, args );
254         },
256         ready: function( fn ) {
257                 // Attach the listeners
258                 jQuery.bindReady();
260                 // Add the callback
261                 readyList.add( fn );
263                 return this;
264         },
266         eq: function( i ) {
267                 return i === -1 ?
268                         this.slice( i ) :
269                         this.slice( i, +i + 1 );
270         },
272         first: function() {
273                 return this.eq( 0 );
274         },
276         last: function() {
277                 return this.eq( -1 );
278         },
280         slice: function() {
281                 return this.pushStack( slice.apply( this, arguments ),
282                         "slice", slice.call(arguments).join(",") );
283         },
285         map: function( callback ) {
286                 return this.pushStack( jQuery.map(this, function( elem, i ) {
287                         return callback.call( elem, i, elem );
288                 }));
289         },
291         end: function() {
292                 return this.prevObject || this.constructor(null);
293         },
295         // For internal use only.
296         // Behaves like an Array's method, not like a jQuery method.
297         push: push,
298         sort: [].sort,
299         splice: [].splice
302 // Give the init function the jQuery prototype for later instantiation
303 jQuery.fn.init.prototype = jQuery.fn;
305 jQuery.extend = jQuery.fn.extend = function() {
306         var options, name, src, copy, copyIsArray, clone,
307                 target = arguments[0] || {},
308                 i = 1,
309                 length = arguments.length,
310                 deep = false;
312         // Handle a deep copy situation
313         if ( typeof target === "boolean" ) {
314                 deep = target;
315                 target = arguments[1] || {};
316                 // skip the boolean and the target
317                 i = 2;
318         }
320         // Handle case when target is a string or something (possible in deep copy)
321         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
322                 target = {};
323         }
325         // extend jQuery itself if only one argument is passed
326         if ( length === i ) {
327                 target = this;
328                 --i;
329         }
331         for ( ; i < length; i++ ) {
332                 // Only deal with non-null/undefined values
333                 if ( (options = arguments[ i ]) != null ) {
334                         // Extend the base object
335                         for ( name in options ) {
336                                 src = target[ name ];
337                                 copy = options[ name ];
339                                 // Prevent never-ending loop
340                                 if ( target === copy ) {
341                                         continue;
342                                 }
344                                 // Recurse if we're merging plain objects or arrays
345                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
346                                         if ( copyIsArray ) {
347                                                 copyIsArray = false;
348                                                 clone = src && jQuery.isArray(src) ? src : [];
350                                         } else {
351                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
352                                         }
354                                         // Never move original objects, clone them
355                                         target[ name ] = jQuery.extend( deep, clone, copy );
357                                 // Don't bring in undefined values
358                                 } else if ( copy !== undefined ) {
359                                         target[ name ] = copy;
360                                 }
361                         }
362                 }
363         }
365         // Return the modified object
366         return target;
369 jQuery.extend({
370         noConflict: function( deep ) {
371                 if ( window.$ === jQuery ) {
372                         window.$ = _$;
373                 }
375                 if ( deep && window.jQuery === jQuery ) {
376                         window.jQuery = _jQuery;
377                 }
379                 return jQuery;
380         },
382         // Is the DOM ready to be used? Set to true once it occurs.
383         isReady: false,
385         // A counter to track how many items to wait for before
386         // the ready event fires. See #6781
387         readyWait: 1,
389         // Hold (or release) the ready event
390         holdReady: function( hold ) {
391                 if ( hold ) {
392                         jQuery.readyWait++;
393                 } else {
394                         jQuery.ready( true );
395                 }
396         },
398         // Handle when the DOM is ready
399         ready: function( wait ) {
400                 // Either a released hold or an DOMready/load event and not yet ready
401                 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
402                         // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
403                         if ( !document.body ) {
404                                 return setTimeout( jQuery.ready, 1 );
405                         }
407                         // Remember that the DOM is ready
408                         jQuery.isReady = true;
410                         // If a normal DOM Ready event fired, decrement, and wait if need be
411                         if ( wait !== true && --jQuery.readyWait > 0 ) {
412                                 return;
413                         }
415                         // If there are functions bound, to execute
416                         readyList.fireWith( document, [ jQuery ] );
418                         // Trigger any bound ready events
419                         if ( jQuery.fn.trigger ) {
420                                 jQuery( document ).trigger( "ready" ).unbind( "ready" );
421                         }
422                 }
423         },
425         bindReady: function() {
426                 if ( readyList ) {
427                         return;
428                 }
430                 readyList = jQuery.Callbacks( "once memory" );
432                 // Catch cases where $(document).ready() is called after the
433                 // browser event has already occurred.
434                 if ( document.readyState === "complete" ) {
435                         // Handle it asynchronously to allow scripts the opportunity to delay ready
436                         return setTimeout( jQuery.ready, 1 );
437                 }
439                 // Mozilla, Opera and webkit nightlies currently support this event
440                 if ( document.addEventListener ) {
441                         // Use the handy event callback
442                         document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
444                         // A fallback to window.onload, that will always work
445                         window.addEventListener( "load", jQuery.ready, false );
447                 // If IE event model is used
448                 } else if ( document.attachEvent ) {
449                         // ensure firing before onload,
450                         // maybe late but safe also for iframes
451                         document.attachEvent( "onreadystatechange", DOMContentLoaded );
453                         // A fallback to window.onload, that will always work
454                         window.attachEvent( "onload", jQuery.ready );
456                         // If IE and not a frame
457                         // continually check to see if the document is ready
458                         var toplevel = false;
460                         try {
461                                 toplevel = window.frameElement == null;
462                         } catch(e) {}
464                         if ( document.documentElement.doScroll && toplevel ) {
465                                 doScrollCheck();
466                         }
467                 }
468         },
470         // See test/unit/core.js for details concerning isFunction.
471         // Since version 1.3, DOM methods and functions like alert
472         // aren't supported. They return false on IE (#2968).
473         isFunction: function( obj ) {
474                 return jQuery.type(obj) === "function";
475         },
477         isArray: Array.isArray || function( obj ) {
478                 return jQuery.type(obj) === "array";
479         },
481         // A crude way of determining if an object is a window
482         isWindow: function( obj ) {
483                 return obj && typeof obj === "object" && "setInterval" in obj;
484         },
486         isNumeric: function( obj ) {
487                 return obj != null && rdigit.test( obj ) && !isNaN( obj );
488         },
490         type: function( obj ) {
491                 return obj == null ?
492                         String( obj ) :
493                         class2type[ toString.call(obj) ] || "object";
494         },
496         isPlainObject: function( obj ) {
497                 // Must be an Object.
498                 // Because of IE, we also have to check the presence of the constructor property.
499                 // Make sure that DOM nodes and window objects don't pass through, as well
500                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
501                         return false;
502                 }
504                 try {
505                         // Not own constructor property must be Object
506                         if ( obj.constructor &&
507                                 !hasOwn.call(obj, "constructor") &&
508                                 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
509                                 return false;
510                         }
511                 } catch ( e ) {
512                         // IE8,9 Will throw exceptions on certain host objects #9897
513                         return false;
514                 }
516                 // Own properties are enumerated firstly, so to speed up,
517                 // if last one is own, then all properties are own.
519                 var key;
520                 for ( key in obj ) {}
522                 return key === undefined || hasOwn.call( obj, key );
523         },
525         isEmptyObject: function( obj ) {
526                 for ( var name in obj ) {
527                         return false;
528                 }
529                 return true;
530         },
532         error: function( msg ) {
533                 throw msg;
534         },
536         parseJSON: function( data ) {
537                 if ( typeof data !== "string" || !data ) {
538                         return null;
539                 }
541                 // Make sure leading/trailing whitespace is removed (IE can't handle it)
542                 data = jQuery.trim( data );
544                 // Attempt to parse using the native JSON parser first
545                 if ( window.JSON && window.JSON.parse ) {
546                         return window.JSON.parse( data );
547                 }
549                 // Make sure the incoming data is actual JSON
550                 // Logic borrowed from http://json.org/json2.js
551                 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
552                         .replace( rvalidtokens, "]" )
553                         .replace( rvalidbraces, "")) ) {
555                         return ( new Function( "return " + data ) )();
557                 }
558                 jQuery.error( "Invalid JSON: " + data );
559         },
561         // Cross-browser xml parsing
562         parseXML: function( data ) {
563                 var xml, tmp;
564                 try {
565                         if ( window.DOMParser ) { // Standard
566                                 tmp = new DOMParser();
567                                 xml = tmp.parseFromString( data , "text/xml" );
568                         } else { // IE
569                                 xml = new ActiveXObject( "Microsoft.XMLDOM" );
570                                 xml.async = "false";
571                                 xml.loadXML( data );
572                         }
573                 } catch( e ) {
574                         xml = undefined;
575                 }
576                 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
577                         jQuery.error( "Invalid XML: " + data );
578                 }
579                 return xml;
580         },
582         noop: function() {},
584         // Evaluates a script in a global context
585         // Workarounds based on findings by Jim Driscoll
586         // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
587         globalEval: function( data ) {
588                 if ( data && rnotwhite.test( data ) ) {
589                         // We use execScript on Internet Explorer
590                         // We use an anonymous function so that context is window
591                         // rather than jQuery in Firefox
592                         ( window.execScript || function( data ) {
593                                 window[ "eval" ].call( window, data );
594                         } )( data );
595                 }
596         },
598         // Convert dashed to camelCase; used by the css and data modules
599         // Microsoft forgot to hump their vendor prefix (#9572)
600         camelCase: function( string ) {
601                 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
602         },
604         nodeName: function( elem, name ) {
605                 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
606         },
608         // args is for internal usage only
609         each: function( object, callback, args ) {
610                 var name, i = 0,
611                         length = object.length,
612                         isObj = length === undefined || jQuery.isFunction( object );
614                 if ( args ) {
615                         if ( isObj ) {
616                                 for ( name in object ) {
617                                         if ( callback.apply( object[ name ], args ) === false ) {
618                                                 break;
619                                         }
620                                 }
621                         } else {
622                                 for ( ; i < length; ) {
623                                         if ( callback.apply( object[ i++ ], args ) === false ) {
624                                                 break;
625                                         }
626                                 }
627                         }
629                 // A special, fast, case for the most common use of each
630                 } else {
631                         if ( isObj ) {
632                                 for ( name in object ) {
633                                         if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
634                                                 break;
635                                         }
636                                 }
637                         } else {
638                                 for ( ; i < length; ) {
639                                         if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
640                                                 break;
641                                         }
642                                 }
643                         }
644                 }
646                 return object;
647         },
649         // Use native String.trim function wherever possible
650         trim: trim ?
651                 function( text ) {
652                         return text == null ?
653                                 "" :
654                                 trim.call( text );
655                 } :
657                 // Otherwise use our own trimming functionality
658                 function( text ) {
659                         return text == null ?
660                                 "" :
661                                 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
662                 },
664         // results is for internal usage only
665         makeArray: function( array, results ) {
666                 var ret = results || [];
668                 if ( array != null ) {
669                         // The window, strings (and functions) also have 'length'
670                         // The extra typeof function check is to prevent crashes
671                         // in Safari 2 (See: #3039)
672                         // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
673                         var type = jQuery.type( array );
675                         if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
676                                 push.call( ret, array );
677                         } else {
678                                 jQuery.merge( ret, array );
679                         }
680                 }
682                 return ret;
683         },
685         inArray: function( elem, array, i ) {
686                 var len;
688                 if ( array ) {
689                         if ( indexOf ) {
690                                 return indexOf.call( array, elem, i );
691                         }
693                         len = array.length;
694                         i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
696                         for ( ; i < len; i++ ) {
697                                 // Skip accessing in sparse arrays
698                                 if ( i in array && array[ i ] === elem ) {
699                                         return i;
700                                 }
701                         }
702                 }
704                 return -1;
705         },
707         merge: function( first, second ) {
708                 var i = first.length,
709                         j = 0;
711                 if ( typeof second.length === "number" ) {
712                         for ( var l = second.length; j < l; j++ ) {
713                                 first[ i++ ] = second[ j ];
714                         }
716                 } else {
717                         while ( second[j] !== undefined ) {
718                                 first[ i++ ] = second[ j++ ];
719                         }
720                 }
722                 first.length = i;
724                 return first;
725         },
727         grep: function( elems, callback, inv ) {
728                 var ret = [], retVal;
729                 inv = !!inv;
731                 // Go through the array, only saving the items
732                 // that pass the validator function
733                 for ( var i = 0, length = elems.length; i < length; i++ ) {
734                         retVal = !!callback( elems[ i ], i );
735                         if ( inv !== retVal ) {
736                                 ret.push( elems[ i ] );
737                         }
738                 }
740                 return ret;
741         },
743         // arg is for internal usage only
744         map: function( elems, callback, arg ) {
745                 var value, key, ret = [],
746                         i = 0,
747                         length = elems.length,
748                         // jquery objects are treated as arrays
749                         isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
751                 // Go through the array, translating each of the items to their
752                 if ( isArray ) {
753                         for ( ; i < length; i++ ) {
754                                 value = callback( elems[ i ], i, arg );
756                                 if ( value != null ) {
757                                         ret[ ret.length ] = value;
758                                 }
759                         }
761                 // Go through every key on the object,
762                 } else {
763                         for ( key in elems ) {
764                                 value = callback( elems[ key ], key, arg );
766                                 if ( value != null ) {
767                                         ret[ ret.length ] = value;
768                                 }
769                         }
770                 }
772                 // Flatten any nested arrays
773                 return ret.concat.apply( [], ret );
774         },
776         // A global GUID counter for objects
777         guid: 1,
779         // Bind a function to a context, optionally partially applying any
780         // arguments.
781         proxy: function( fn, context ) {
782                 if ( typeof context === "string" ) {
783                         var tmp = fn[ context ];
784                         context = fn;
785                         fn = tmp;
786                 }
788                 // Quick check to determine if target is callable, in the spec
789                 // this throws a TypeError, but we will just return undefined.
790                 if ( !jQuery.isFunction( fn ) ) {
791                         return undefined;
792                 }
794                 // Simulated bind
795                 var args = slice.call( arguments, 2 ),
796                         proxy = function() {
797                                 return fn.apply( context, args.concat( slice.call( arguments ) ) );
798                         };
800                 // Set the guid of unique handler to the same of original handler, so it can be removed
801                 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
803                 return proxy;
804         },
806         // Mutifunctional method to get and set values to a collection
807         // The value/s can optionally be executed if it's a function
808         access: function( elems, key, value, exec, fn, pass ) {
809                 var length = elems.length;
811                 // Setting many attributes
812                 if ( typeof key === "object" ) {
813                         for ( var k in key ) {
814                                 jQuery.access( elems, k, key[k], exec, fn, value );
815                         }
816                         return elems;
817                 }
819                 // Setting one attribute
820                 if ( value !== undefined ) {
821                         // Optionally, function values get executed if exec is true
822                         exec = !pass && exec && jQuery.isFunction(value);
824                         for ( var i = 0; i < length; i++ ) {
825                                 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
826                         }
828                         return elems;
829                 }
831                 // Getting an attribute
832                 return length ? fn( elems[0], key ) : undefined;
833         },
835         now: function() {
836                 return ( new Date() ).getTime();
837         },
839         // Use of jQuery.browser is frowned upon.
840         // More details: http://docs.jquery.com/Utilities/jQuery.browser
841         uaMatch: function( ua ) {
842                 ua = ua.toLowerCase();
844                 var match = rwebkit.exec( ua ) ||
845                         ropera.exec( ua ) ||
846                         rmsie.exec( ua ) ||
847                         ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
848                         [];
850                 return { browser: match[1] || "", version: match[2] || "0" };
851         },
853         sub: function() {
854                 function jQuerySub( selector, context ) {
855                         return new jQuerySub.fn.init( selector, context );
856                 }
857                 jQuery.extend( true, jQuerySub, this );
858                 jQuerySub.superclass = this;
859                 jQuerySub.fn = jQuerySub.prototype = this();
860                 jQuerySub.fn.constructor = jQuerySub;
861                 jQuerySub.sub = this.sub;
862                 jQuerySub.fn.init = function init( selector, context ) {
863                         if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
864                                 context = jQuerySub( context );
865                         }
867                         return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
868                 };
869                 jQuerySub.fn.init.prototype = jQuerySub.fn;
870                 var rootjQuerySub = jQuerySub(document);
871                 return jQuerySub;
872         },
874         browser: {}
877 // Populate the class2type map
878 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
879         class2type[ "[object " + name + "]" ] = name.toLowerCase();
882 browserMatch = jQuery.uaMatch( userAgent );
883 if ( browserMatch.browser ) {
884         jQuery.browser[ browserMatch.browser ] = true;
885         jQuery.browser.version = browserMatch.version;
888 // Deprecated, use jQuery.browser.webkit instead
889 if ( jQuery.browser.webkit ) {
890         jQuery.browser.safari = true;
893 // IE doesn't match non-breaking spaces with \s
894 if ( rnotwhite.test( "\xA0" ) ) {
895         trimLeft = /^[\s\xA0]+/;
896         trimRight = /[\s\xA0]+$/;
899 // All jQuery objects should point back to these
900 rootjQuery = jQuery(document);
902 // Cleanup functions for the document ready method
903 if ( document.addEventListener ) {
904         DOMContentLoaded = function() {
905                 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
906                 jQuery.ready();
907         };
909 } else if ( document.attachEvent ) {
910         DOMContentLoaded = function() {
911                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
912                 if ( document.readyState === "complete" ) {
913                         document.detachEvent( "onreadystatechange", DOMContentLoaded );
914                         jQuery.ready();
915                 }
916         };
919 // The DOM ready check for Internet Explorer
920 function doScrollCheck() {
921         if ( jQuery.isReady ) {
922                 return;
923         }
925         try {
926                 // If IE is used, use the trick by Diego Perini
927                 // http://javascript.nwbox.com/IEContentLoaded/
928                 document.documentElement.doScroll("left");
929         } catch(e) {
930                 setTimeout( doScrollCheck, 1 );
931                 return;
932         }
934         // and execute any waiting functions
935         jQuery.ready();
938 // Expose jQuery as an AMD module, but only for AMD loaders that
939 // understand the issues with loading multiple versions of jQuery
940 // in a page that all might call define(). The loader will indicate
941 // they have special allowances for multiple jQuery versions by
942 // specifying define.amd.jQuery = true. Register as a named module,
943 // since jQuery can be concatenated with other files that may use define,
944 // but not use a proper concatenation script that understands anonymous
945 // AMD modules. A named AMD is safest and most robust way to register.
946 // Lowercase jquery is used because AMD module names are derived from
947 // file names, and jQuery is normally delivered in a lowercase file name.
948 if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
949         define( "jquery", [], function () { return jQuery; } );
952 return jQuery;
954 })();