]> Dogcows Code - chaz/website/blob - static/lib/jquery/jquery-1.9.1.js
remove link to mormon.org
[chaz/website] / static / lib / jquery / jquery-1.9.1.js
1 /*!
2 * jQuery JavaScript Library v1.9.1
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2013-2-4
13 */
14 (function( window, undefined ) {
15
16 // Can't do this because several apps including ASP.NET trace
17 // the stack via arguments.caller.callee and Firefox dies if
18 // you try to trace through "use strict" call chains. (#13335)
19 // Support: Firefox 18+
20 //"use strict";
21 var
22 // The deferred used on DOM ready
23 readyList,
24
25 // A central reference to the root jQuery(document)
26 rootjQuery,
27
28 // Support: IE<9
29 // For `typeof node.method` instead of `node.method !== undefined`
30 core_strundefined = typeof undefined,
31
32 // Use the correct document accordingly with window argument (sandbox)
33 document = window.document,
34 location = window.location,
35
36 // Map over jQuery in case of overwrite
37 _jQuery = window.jQuery,
38
39 // Map over the $ in case of overwrite
40 _$ = window.$,
41
42 // [[Class]] -> type pairs
43 class2type = {},
44
45 // List of deleted data cache ids, so we can reuse them
46 core_deletedIds = [],
47
48 core_version = "1.9.1",
49
50 // Save a reference to some core methods
51 core_concat = core_deletedIds.concat,
52 core_push = core_deletedIds.push,
53 core_slice = core_deletedIds.slice,
54 core_indexOf = core_deletedIds.indexOf,
55 core_toString = class2type.toString,
56 core_hasOwn = class2type.hasOwnProperty,
57 core_trim = core_version.trim,
58
59 // Define a local copy of jQuery
60 jQuery = function( selector, context ) {
61 // The jQuery object is actually just the init constructor 'enhanced'
62 return new jQuery.fn.init( selector, context, rootjQuery );
63 },
64
65 // Used for matching numbers
66 core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
67
68 // Used for splitting on whitespace
69 core_rnotwhite = /\S+/g,
70
71 // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
72 rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
73
74 // A simple way to check for HTML strings
75 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
76 // Strict HTML recognition (#11290: must start with <)
77 rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,
78
79 // Match a standalone tag
80 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
81
82 // JSON RegExp
83 rvalidchars = /^[\],:{}\s]*$/,
84 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
85 rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
86 rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
87
88 // Matches dashed string for camelizing
89 rmsPrefix = /^-ms-/,
90 rdashAlpha = /-([\da-z])/gi,
91
92 // Used by jQuery.camelCase as callback to replace()
93 fcamelCase = function( all, letter ) {
94 return letter.toUpperCase();
95 },
96
97 // The ready event handler
98 completed = function( event ) {
99
100 // readyState === "complete" is good enough for us to call the dom ready in oldIE
101 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
102 detach();
103 jQuery.ready();
104 }
105 },
106 // Clean-up method for dom ready events
107 detach = function() {
108 if ( document.addEventListener ) {
109 document.removeEventListener( "DOMContentLoaded", completed, false );
110 window.removeEventListener( "load", completed, false );
111
112 } else {
113 document.detachEvent( "onreadystatechange", completed );
114 window.detachEvent( "onload", completed );
115 }
116 };
117
118 jQuery.fn = jQuery.prototype = {
119 // The current version of jQuery being used
120 jquery: core_version,
121
122 constructor: jQuery,
123 init: function( selector, context, rootjQuery ) {
124 var match, elem;
125
126 // HANDLE: $(""), $(null), $(undefined), $(false)
127 if ( !selector ) {
128 return this;
129 }
130
131 // Handle HTML strings
132 if ( typeof selector === "string" ) {
133 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
134 // Assume that strings that start and end with <> are HTML and skip the regex check
135 match = [ null, selector, null ];
136
137 } else {
138 match = rquickExpr.exec( selector );
139 }
140
141 // Match html or make sure no context is specified for #id
142 if ( match && (match[1] || !context) ) {
143
144 // HANDLE: $(html) -> $(array)
145 if ( match[1] ) {
146 context = context instanceof jQuery ? context[0] : context;
147
148 // scripts is true for back-compat
149 jQuery.merge( this, jQuery.parseHTML(
150 match[1],
151 context && context.nodeType ? context.ownerDocument || context : document,
152 true
153 ) );
154
155 // HANDLE: $(html, props)
156 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
157 for ( match in context ) {
158 // Properties of context are called as methods if possible
159 if ( jQuery.isFunction( this[ match ] ) ) {
160 this[ match ]( context[ match ] );
161
162 // ...and otherwise set as attributes
163 } else {
164 this.attr( match, context[ match ] );
165 }
166 }
167 }
168
169 return this;
170
171 // HANDLE: $(#id)
172 } else {
173 elem = document.getElementById( match[2] );
174
175 // Check parentNode to catch when Blackberry 4.6 returns
176 // nodes that are no longer in the document #6963
177 if ( elem && elem.parentNode ) {
178 // Handle the case where IE and Opera return items
179 // by name instead of ID
180 if ( elem.id !== match[2] ) {
181 return rootjQuery.find( selector );
182 }
183
184 // Otherwise, we inject the element directly into the jQuery object
185 this.length = 1;
186 this[0] = elem;
187 }
188
189 this.context = document;
190 this.selector = selector;
191 return this;
192 }
193
194 // HANDLE: $(expr, $(...))
195 } else if ( !context || context.jquery ) {
196 return ( context || rootjQuery ).find( selector );
197
198 // HANDLE: $(expr, context)
199 // (which is just equivalent to: $(context).find(expr)
200 } else {
201 return this.constructor( context ).find( selector );
202 }
203
204 // HANDLE: $(DOMElement)
205 } else if ( selector.nodeType ) {
206 this.context = this[0] = selector;
207 this.length = 1;
208 return this;
209
210 // HANDLE: $(function)
211 // Shortcut for document ready
212 } else if ( jQuery.isFunction( selector ) ) {
213 return rootjQuery.ready( selector );
214 }
215
216 if ( selector.selector !== undefined ) {
217 this.selector = selector.selector;
218 this.context = selector.context;
219 }
220
221 return jQuery.makeArray( selector, this );
222 },
223
224 // Start with an empty selector
225 selector: "",
226
227 // The default length of a jQuery object is 0
228 length: 0,
229
230 // The number of elements contained in the matched element set
231 size: function() {
232 return this.length;
233 },
234
235 toArray: function() {
236 return core_slice.call( this );
237 },
238
239 // Get the Nth element in the matched element set OR
240 // Get the whole matched element set as a clean array
241 get: function( num ) {
242 return num == null ?
243
244 // Return a 'clean' array
245 this.toArray() :
246
247 // Return just the object
248 ( num < 0 ? this[ this.length + num ] : this[ num ] );
249 },
250
251 // Take an array of elements and push it onto the stack
252 // (returning the new matched element set)
253 pushStack: function( elems ) {
254
255 // Build a new jQuery matched element set
256 var ret = jQuery.merge( this.constructor(), elems );
257
258 // Add the old object onto the stack (as a reference)
259 ret.prevObject = this;
260 ret.context = this.context;
261
262 // Return the newly-formed element set
263 return ret;
264 },
265
266 // Execute a callback for every element in the matched set.
267 // (You can seed the arguments with an array of args, but this is
268 // only used internally.)
269 each: function( callback, args ) {
270 return jQuery.each( this, callback, args );
271 },
272
273 ready: function( fn ) {
274 // Add the callback
275 jQuery.ready.promise().done( fn );
276
277 return this;
278 },
279
280 slice: function() {
281 return this.pushStack( core_slice.apply( this, arguments ) );
282 },
283
284 first: function() {
285 return this.eq( 0 );
286 },
287
288 last: function() {
289 return this.eq( -1 );
290 },
291
292 eq: function( i ) {
293 var len = this.length,
294 j = +i + ( i < 0 ? len : 0 );
295 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
296 },
297
298 map: function( callback ) {
299 return this.pushStack( jQuery.map(this, function( elem, i ) {
300 return callback.call( elem, i, elem );
301 }));
302 },
303
304 end: function() {
305 return this.prevObject || this.constructor(null);
306 },
307
308 // For internal use only.
309 // Behaves like an Array's method, not like a jQuery method.
310 push: core_push,
311 sort: [].sort,
312 splice: [].splice
313 };
314
315 // Give the init function the jQuery prototype for later instantiation
316 jQuery.fn.init.prototype = jQuery.fn;
317
318 jQuery.extend = jQuery.fn.extend = function() {
319 var src, copyIsArray, copy, name, options, clone,
320 target = arguments[0] || {},
321 i = 1,
322 length = arguments.length,
323 deep = false;
324
325 // Handle a deep copy situation
326 if ( typeof target === "boolean" ) {
327 deep = target;
328 target = arguments[1] || {};
329 // skip the boolean and the target
330 i = 2;
331 }
332
333 // Handle case when target is a string or something (possible in deep copy)
334 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
335 target = {};
336 }
337
338 // extend jQuery itself if only one argument is passed
339 if ( length === i ) {
340 target = this;
341 --i;
342 }
343
344 for ( ; i < length; i++ ) {
345 // Only deal with non-null/undefined values
346 if ( (options = arguments[ i ]) != null ) {
347 // Extend the base object
348 for ( name in options ) {
349 src = target[ name ];
350 copy = options[ name ];
351
352 // Prevent never-ending loop
353 if ( target === copy ) {
354 continue;
355 }
356
357 // Recurse if we're merging plain objects or arrays
358 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
359 if ( copyIsArray ) {
360 copyIsArray = false;
361 clone = src && jQuery.isArray(src) ? src : [];
362
363 } else {
364 clone = src && jQuery.isPlainObject(src) ? src : {};
365 }
366
367 // Never move original objects, clone them
368 target[ name ] = jQuery.extend( deep, clone, copy );
369
370 // Don't bring in undefined values
371 } else if ( copy !== undefined ) {
372 target[ name ] = copy;
373 }
374 }
375 }
376 }
377
378 // Return the modified object
379 return target;
380 };
381
382 jQuery.extend({
383 noConflict: function( deep ) {
384 if ( window.$ === jQuery ) {
385 window.$ = _$;
386 }
387
388 if ( deep && window.jQuery === jQuery ) {
389 window.jQuery = _jQuery;
390 }
391
392 return jQuery;
393 },
394
395 // Is the DOM ready to be used? Set to true once it occurs.
396 isReady: false,
397
398 // A counter to track how many items to wait for before
399 // the ready event fires. See #6781
400 readyWait: 1,
401
402 // Hold (or release) the ready event
403 holdReady: function( hold ) {
404 if ( hold ) {
405 jQuery.readyWait++;
406 } else {
407 jQuery.ready( true );
408 }
409 },
410
411 // Handle when the DOM is ready
412 ready: function( wait ) {
413
414 // Abort if there are pending holds or we're already ready
415 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
416 return;
417 }
418
419 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
420 if ( !document.body ) {
421 return setTimeout( jQuery.ready );
422 }
423
424 // Remember that the DOM is ready
425 jQuery.isReady = true;
426
427 // If a normal DOM Ready event fired, decrement, and wait if need be
428 if ( wait !== true && --jQuery.readyWait > 0 ) {
429 return;
430 }
431
432 // If there are functions bound, to execute
433 readyList.resolveWith( document, [ jQuery ] );
434
435 // Trigger any bound ready events
436 if ( jQuery.fn.trigger ) {
437 jQuery( document ).trigger("ready").off("ready");
438 }
439 },
440
441 // See test/unit/core.js for details concerning isFunction.
442 // Since version 1.3, DOM methods and functions like alert
443 // aren't supported. They return false on IE (#2968).
444 isFunction: function( obj ) {
445 return jQuery.type(obj) === "function";
446 },
447
448 isArray: Array.isArray || function( obj ) {
449 return jQuery.type(obj) === "array";
450 },
451
452 isWindow: function( obj ) {
453 return obj != null && obj == obj.window;
454 },
455
456 isNumeric: function( obj ) {
457 return !isNaN( parseFloat(obj) ) && isFinite( obj );
458 },
459
460 type: function( obj ) {
461 if ( obj == null ) {
462 return String( obj );
463 }
464 return typeof obj === "object" || typeof obj === "function" ?
465 class2type[ core_toString.call(obj) ] || "object" :
466 typeof obj;
467 },
468
469 isPlainObject: function( obj ) {
470 // Must be an Object.
471 // Because of IE, we also have to check the presence of the constructor property.
472 // Make sure that DOM nodes and window objects don't pass through, as well
473 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
474 return false;
475 }
476
477 try {
478 // Not own constructor property must be Object
479 if ( obj.constructor &&
480 !core_hasOwn.call(obj, "constructor") &&
481 !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
482 return false;
483 }
484 } catch ( e ) {
485 // IE8,9 Will throw exceptions on certain host objects #9897
486 return false;
487 }
488
489 // Own properties are enumerated firstly, so to speed up,
490 // if last one is own, then all properties are own.
491
492 var key;
493 for ( key in obj ) {}
494
495 return key === undefined || core_hasOwn.call( obj, key );
496 },
497
498 isEmptyObject: function( obj ) {
499 var name;
500 for ( name in obj ) {
501 return false;
502 }
503 return true;
504 },
505
506 error: function( msg ) {
507 throw new Error( msg );
508 },
509
510 // data: string of html
511 // context (optional): If specified, the fragment will be created in this context, defaults to document
512 // keepScripts (optional): If true, will include scripts passed in the html string
513 parseHTML: function( data, context, keepScripts ) {
514 if ( !data || typeof data !== "string" ) {
515 return null;
516 }
517 if ( typeof context === "boolean" ) {
518 keepScripts = context;
519 context = false;
520 }
521 context = context || document;
522
523 var parsed = rsingleTag.exec( data ),
524 scripts = !keepScripts && [];
525
526 // Single tag
527 if ( parsed ) {
528 return [ context.createElement( parsed[1] ) ];
529 }
530
531 parsed = jQuery.buildFragment( [ data ], context, scripts );
532 if ( scripts ) {
533 jQuery( scripts ).remove();
534 }
535 return jQuery.merge( [], parsed.childNodes );
536 },
537
538 parseJSON: function( data ) {
539 // Attempt to parse using the native JSON parser first
540 if ( window.JSON && window.JSON.parse ) {
541 return window.JSON.parse( data );
542 }
543
544 if ( data === null ) {
545 return data;
546 }
547
548 if ( typeof data === "string" ) {
549
550 // Make sure leading/trailing whitespace is removed (IE can't handle it)
551 data = jQuery.trim( data );
552
553 if ( data ) {
554 // Make sure the incoming data is actual JSON
555 // Logic borrowed from http://json.org/json2.js
556 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
557 .replace( rvalidtokens, "]" )
558 .replace( rvalidbraces, "")) ) {
559
560 return ( new Function( "return " + data ) )();
561 }
562 }
563 }
564
565 jQuery.error( "Invalid JSON: " + data );
566 },
567
568 // Cross-browser xml parsing
569 parseXML: function( data ) {
570 var xml, tmp;
571 if ( !data || typeof data !== "string" ) {
572 return null;
573 }
574 try {
575 if ( window.DOMParser ) { // Standard
576 tmp = new DOMParser();
577 xml = tmp.parseFromString( data , "text/xml" );
578 } else { // IE
579 xml = new ActiveXObject( "Microsoft.XMLDOM" );
580 xml.async = "false";
581 xml.loadXML( data );
582 }
583 } catch( e ) {
584 xml = undefined;
585 }
586 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
587 jQuery.error( "Invalid XML: " + data );
588 }
589 return xml;
590 },
591
592 noop: function() {},
593
594 // Evaluates a script in a global context
595 // Workarounds based on findings by Jim Driscoll
596 // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
597 globalEval: function( data ) {
598 if ( data && jQuery.trim( data ) ) {
599 // We use execScript on Internet Explorer
600 // We use an anonymous function so that context is window
601 // rather than jQuery in Firefox
602 ( window.execScript || function( data ) {
603 window[ "eval" ].call( window, data );
604 } )( data );
605 }
606 },
607
608 // Convert dashed to camelCase; used by the css and data modules
609 // Microsoft forgot to hump their vendor prefix (#9572)
610 camelCase: function( string ) {
611 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
612 },
613
614 nodeName: function( elem, name ) {
615 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
616 },
617
618 // args is for internal usage only
619 each: function( obj, callback, args ) {
620 var value,
621 i = 0,
622 length = obj.length,
623 isArray = isArraylike( obj );
624
625 if ( args ) {
626 if ( isArray ) {
627 for ( ; i < length; i++ ) {
628 value = callback.apply( obj[ i ], args );
629
630 if ( value === false ) {
631 break;
632 }
633 }
634 } else {
635 for ( i in obj ) {
636 value = callback.apply( obj[ i ], args );
637
638 if ( value === false ) {
639 break;
640 }
641 }
642 }
643
644 // A special, fast, case for the most common use of each
645 } else {
646 if ( isArray ) {
647 for ( ; i < length; i++ ) {
648 value = callback.call( obj[ i ], i, obj[ i ] );
649
650 if ( value === false ) {
651 break;
652 }
653 }
654 } else {
655 for ( i in obj ) {
656 value = callback.call( obj[ i ], i, obj[ i ] );
657
658 if ( value === false ) {
659 break;
660 }
661 }
662 }
663 }
664
665 return obj;
666 },
667
668 // Use native String.trim function wherever possible
669 trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
670 function( text ) {
671 return text == null ?
672 "" :
673 core_trim.call( text );
674 } :
675
676 // Otherwise use our own trimming functionality
677 function( text ) {
678 return text == null ?
679 "" :
680 ( text + "" ).replace( rtrim, "" );
681 },
682
683 // results is for internal usage only
684 makeArray: function( arr, results ) {
685 var ret = results || [];
686
687 if ( arr != null ) {
688 if ( isArraylike( Object(arr) ) ) {
689 jQuery.merge( ret,
690 typeof arr === "string" ?
691 [ arr ] : arr
692 );
693 } else {
694 core_push.call( ret, arr );
695 }
696 }
697
698 return ret;
699 },
700
701 inArray: function( elem, arr, i ) {
702 var len;
703
704 if ( arr ) {
705 if ( core_indexOf ) {
706 return core_indexOf.call( arr, elem, i );
707 }
708
709 len = arr.length;
710 i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
711
712 for ( ; i < len; i++ ) {
713 // Skip accessing in sparse arrays
714 if ( i in arr && arr[ i ] === elem ) {
715 return i;
716 }
717 }
718 }
719
720 return -1;
721 },
722
723 merge: function( first, second ) {
724 var l = second.length,
725 i = first.length,
726 j = 0;
727
728 if ( typeof l === "number" ) {
729 for ( ; j < l; j++ ) {
730 first[ i++ ] = second[ j ];
731 }
732 } else {
733 while ( second[j] !== undefined ) {
734 first[ i++ ] = second[ j++ ];
735 }
736 }
737
738 first.length = i;
739
740 return first;
741 },
742
743 grep: function( elems, callback, inv ) {
744 var retVal,
745 ret = [],
746 i = 0,
747 length = elems.length;
748 inv = !!inv;
749
750 // Go through the array, only saving the items
751 // that pass the validator function
752 for ( ; i < length; i++ ) {
753 retVal = !!callback( elems[ i ], i );
754 if ( inv !== retVal ) {
755 ret.push( elems[ i ] );
756 }
757 }
758
759 return ret;
760 },
761
762 // arg is for internal usage only
763 map: function( elems, callback, arg ) {
764 var value,
765 i = 0,
766 length = elems.length,
767 isArray = isArraylike( elems ),
768 ret = [];
769
770 // Go through the array, translating each of the items to their
771 if ( isArray ) {
772 for ( ; i < length; i++ ) {
773 value = callback( elems[ i ], i, arg );
774
775 if ( value != null ) {
776 ret[ ret.length ] = value;
777 }
778 }
779
780 // Go through every key on the object,
781 } else {
782 for ( i in elems ) {
783 value = callback( elems[ i ], i, arg );
784
785 if ( value != null ) {
786 ret[ ret.length ] = value;
787 }
788 }
789 }
790
791 // Flatten any nested arrays
792 return core_concat.apply( [], ret );
793 },
794
795 // A global GUID counter for objects
796 guid: 1,
797
798 // Bind a function to a context, optionally partially applying any
799 // arguments.
800 proxy: function( fn, context ) {
801 var args, proxy, tmp;
802
803 if ( typeof context === "string" ) {
804 tmp = fn[ context ];
805 context = fn;
806 fn = tmp;
807 }
808
809 // Quick check to determine if target is callable, in the spec
810 // this throws a TypeError, but we will just return undefined.
811 if ( !jQuery.isFunction( fn ) ) {
812 return undefined;
813 }
814
815 // Simulated bind
816 args = core_slice.call( arguments, 2 );
817 proxy = function() {
818 return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
819 };
820
821 // Set the guid of unique handler to the same of original handler, so it can be removed
822 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
823
824 return proxy;
825 },
826
827 // Multifunctional method to get and set values of a collection
828 // The value/s can optionally be executed if it's a function
829 access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
830 var i = 0,
831 length = elems.length,
832 bulk = key == null;
833
834 // Sets many values
835 if ( jQuery.type( key ) === "object" ) {
836 chainable = true;
837 for ( i in key ) {
838 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
839 }
840
841 // Sets one value
842 } else if ( value !== undefined ) {
843 chainable = true;
844
845 if ( !jQuery.isFunction( value ) ) {
846 raw = true;
847 }
848
849 if ( bulk ) {
850 // Bulk operations run against the entire set
851 if ( raw ) {
852 fn.call( elems, value );
853 fn = null;
854
855 // ...except when executing function values
856 } else {
857 bulk = fn;
858 fn = function( elem, key, value ) {
859 return bulk.call( jQuery( elem ), value );
860 };
861 }
862 }
863
864 if ( fn ) {
865 for ( ; i < length; i++ ) {
866 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
867 }
868 }
869 }
870
871 return chainable ?
872 elems :
873
874 // Gets
875 bulk ?
876 fn.call( elems ) :
877 length ? fn( elems[0], key ) : emptyGet;
878 },
879
880 now: function() {
881 return ( new Date() ).getTime();
882 }
883 });
884
885 jQuery.ready.promise = function( obj ) {
886 if ( !readyList ) {
887
888 readyList = jQuery.Deferred();
889
890 // Catch cases where $(document).ready() is called after the browser event has already occurred.
891 // we once tried to use readyState "interactive" here, but it caused issues like the one
892 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
893 if ( document.readyState === "complete" ) {
894 // Handle it asynchronously to allow scripts the opportunity to delay ready
895 setTimeout( jQuery.ready );
896
897 // Standards-based browsers support DOMContentLoaded
898 } else if ( document.addEventListener ) {
899 // Use the handy event callback
900 document.addEventListener( "DOMContentLoaded", completed, false );
901
902 // A fallback to window.onload, that will always work
903 window.addEventListener( "load", completed, false );
904
905 // If IE event model is used
906 } else {
907 // Ensure firing before onload, maybe late but safe also for iframes
908 document.attachEvent( "onreadystatechange", completed );
909
910 // A fallback to window.onload, that will always work
911 window.attachEvent( "onload", completed );
912
913 // If IE and not a frame
914 // continually check to see if the document is ready
915 var top = false;
916
917 try {
918 top = window.frameElement == null && document.documentElement;
919 } catch(e) {}
920
921 if ( top && top.doScroll ) {
922 (function doScrollCheck() {
923 if ( !jQuery.isReady ) {
924
925 try {
926 // Use the trick by Diego Perini
927 // http://javascript.nwbox.com/IEContentLoaded/
928 top.doScroll("left");
929 } catch(e) {
930 return setTimeout( doScrollCheck, 50 );
931 }
932
933 // detach all dom ready events
934 detach();
935
936 // and execute any waiting functions
937 jQuery.ready();
938 }
939 })();
940 }
941 }
942 }
943 return readyList.promise( obj );
944 };
945
946 // Populate the class2type map
947 jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
948 class2type[ "[object " + name + "]" ] = name.toLowerCase();
949 });
950
951 function isArraylike( obj ) {
952 var length = obj.length,
953 type = jQuery.type( obj );
954
955 if ( jQuery.isWindow( obj ) ) {
956 return false;
957 }
958
959 if ( obj.nodeType === 1 && length ) {
960 return true;
961 }
962
963 return type === "array" || type !== "function" &&
964 ( length === 0 ||
965 typeof length === "number" && length > 0 && ( length - 1 ) in obj );
966 }
967
968 // All jQuery objects should point back to these
969 rootjQuery = jQuery(document);
970 // String to Object options format cache
971 var optionsCache = {};
972
973 // Convert String-formatted options into Object-formatted ones and store in cache
974 function createOptions( options ) {
975 var object = optionsCache[ options ] = {};
976 jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
977 object[ flag ] = true;
978 });
979 return object;
980 }
981
982 /*
983 * Create a callback list using the following parameters:
984 *
985 * options: an optional list of space-separated options that will change how
986 * the callback list behaves or a more traditional option object
987 *
988 * By default a callback list will act like an event callback list and can be
989 * "fired" multiple times.
990 *
991 * Possible options:
992 *
993 * once: will ensure the callback list can only be fired once (like a Deferred)
994 *
995 * memory: will keep track of previous values and will call any callback added
996 * after the list has been fired right away with the latest "memorized"
997 * values (like a Deferred)
998 *
999 * unique: will ensure a callback can only be added once (no duplicate in the list)
1000 *
1001 * stopOnFalse: interrupt callings when a callback returns false
1002 *
1003 */
1004 jQuery.Callbacks = function( options ) {
1005
1006 // Convert options from String-formatted to Object-formatted if needed
1007 // (we check in cache first)
1008 options = typeof options === "string" ?
1009 ( optionsCache[ options ] || createOptions( options ) ) :
1010 jQuery.extend( {}, options );
1011
1012 var // Flag to know if list is currently firing
1013 firing,
1014 // Last fire value (for non-forgettable lists)
1015 memory,
1016 // Flag to know if list was already fired
1017 fired,
1018 // End of the loop when firing
1019 firingLength,
1020 // Index of currently firing callback (modified by remove if needed)
1021 firingIndex,
1022 // First callback to fire (used internally by add and fireWith)
1023 firingStart,
1024 // Actual callback list
1025 list = [],
1026 // Stack of fire calls for repeatable lists
1027 stack = !options.once && [],
1028 // Fire callbacks
1029 fire = function( data ) {
1030 memory = options.memory && data;
1031 fired = true;
1032 firingIndex = firingStart || 0;
1033 firingStart = 0;
1034 firingLength = list.length;
1035 firing = true;
1036 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1037 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
1038 memory = false; // To prevent further calls using add
1039 break;
1040 }
1041 }
1042 firing = false;
1043 if ( list ) {
1044 if ( stack ) {
1045 if ( stack.length ) {
1046 fire( stack.shift() );
1047 }
1048 } else if ( memory ) {
1049 list = [];
1050 } else {
1051 self.disable();
1052 }
1053 }
1054 },
1055 // Actual Callbacks object
1056 self = {
1057 // Add a callback or a collection of callbacks to the list
1058 add: function() {
1059 if ( list ) {
1060 // First, we save the current length
1061 var start = list.length;
1062 (function add( args ) {
1063 jQuery.each( args, function( _, arg ) {
1064 var type = jQuery.type( arg );
1065 if ( type === "function" ) {
1066 if ( !options.unique || !self.has( arg ) ) {
1067 list.push( arg );
1068 }
1069 } else if ( arg && arg.length && type !== "string" ) {
1070 // Inspect recursively
1071 add( arg );
1072 }
1073 });
1074 })( arguments );
1075 // Do we need to add the callbacks to the
1076 // current firing batch?
1077 if ( firing ) {
1078 firingLength = list.length;
1079 // With memory, if we're not firing then
1080 // we should call right away
1081 } else if ( memory ) {
1082 firingStart = start;
1083 fire( memory );
1084 }
1085 }
1086 return this;
1087 },
1088 // Remove a callback from the list
1089 remove: function() {
1090 if ( list ) {
1091 jQuery.each( arguments, function( _, arg ) {
1092 var index;
1093 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
1094 list.splice( index, 1 );
1095 // Handle firing indexes
1096 if ( firing ) {
1097 if ( index <= firingLength ) {
1098 firingLength--;
1099 }
1100 if ( index <= firingIndex ) {
1101 firingIndex--;
1102 }
1103 }
1104 }
1105 });
1106 }
1107 return this;
1108 },
1109 // Check if a given callback is in the list.
1110 // If no argument is given, return whether or not list has callbacks attached.
1111 has: function( fn ) {
1112 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
1113 },
1114 // Remove all callbacks from the list
1115 empty: function() {
1116 list = [];
1117 return this;
1118 },
1119 // Have the list do nothing anymore
1120 disable: function() {
1121 list = stack = memory = undefined;
1122 return this;
1123 },
1124 // Is it disabled?
1125 disabled: function() {
1126 return !list;
1127 },
1128 // Lock the list in its current state
1129 lock: function() {
1130 stack = undefined;
1131 if ( !memory ) {
1132 self.disable();
1133 }
1134 return this;
1135 },
1136 // Is it locked?
1137 locked: function() {
1138 return !stack;
1139 },
1140 // Call all callbacks with the given context and arguments
1141 fireWith: function( context, args ) {
1142 args = args || [];
1143 args = [ context, args.slice ? args.slice() : args ];
1144 if ( list && ( !fired || stack ) ) {
1145 if ( firing ) {
1146 stack.push( args );
1147 } else {
1148 fire( args );
1149 }
1150 }
1151 return this;
1152 },
1153 // Call all the callbacks with the given arguments
1154 fire: function() {
1155 self.fireWith( this, arguments );
1156 return this;
1157 },
1158 // To know if the callbacks have already been called at least once
1159 fired: function() {
1160 return !!fired;
1161 }
1162 };
1163
1164 return self;
1165 };
1166 jQuery.extend({
1167
1168 Deferred: function( func ) {
1169 var tuples = [
1170 // action, add listener, listener list, final state
1171 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
1172 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
1173 [ "notify", "progress", jQuery.Callbacks("memory") ]
1174 ],
1175 state = "pending",
1176 promise = {
1177 state: function() {
1178 return state;
1179 },
1180 always: function() {
1181 deferred.done( arguments ).fail( arguments );
1182 return this;
1183 },
1184 then: function( /* fnDone, fnFail, fnProgress */ ) {
1185 var fns = arguments;
1186 return jQuery.Deferred(function( newDefer ) {
1187 jQuery.each( tuples, function( i, tuple ) {
1188 var action = tuple[ 0 ],
1189 fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
1190 // deferred[ done | fail | progress ] for forwarding actions to newDefer
1191 deferred[ tuple[1] ](function() {
1192 var returned = fn && fn.apply( this, arguments );
1193 if ( returned && jQuery.isFunction( returned.promise ) ) {
1194 returned.promise()
1195 .done( newDefer.resolve )
1196 .fail( newDefer.reject )
1197 .progress( newDefer.notify );
1198 } else {
1199 newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
1200 }
1201 });
1202 });
1203 fns = null;
1204 }).promise();
1205 },
1206 // Get a promise for this deferred
1207 // If obj is provided, the promise aspect is added to the object
1208 promise: function( obj ) {
1209 return obj != null ? jQuery.extend( obj, promise ) : promise;
1210 }
1211 },
1212 deferred = {};
1213
1214 // Keep pipe for back-compat
1215 promise.pipe = promise.then;
1216
1217 // Add list-specific methods
1218 jQuery.each( tuples, function( i, tuple ) {
1219 var list = tuple[ 2 ],
1220 stateString = tuple[ 3 ];
1221
1222 // promise[ done | fail | progress ] = list.add
1223 promise[ tuple[1] ] = list.add;
1224
1225 // Handle state
1226 if ( stateString ) {
1227 list.add(function() {
1228 // state = [ resolved | rejected ]
1229 state = stateString;
1230
1231 // [ reject_list | resolve_list ].disable; progress_list.lock
1232 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
1233 }
1234
1235 // deferred[ resolve | reject | notify ]
1236 deferred[ tuple[0] ] = function() {
1237 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
1238 return this;
1239 };
1240 deferred[ tuple[0] + "With" ] = list.fireWith;
1241 });
1242
1243 // Make the deferred a promise
1244 promise.promise( deferred );
1245
1246 // Call given func if any
1247 if ( func ) {
1248 func.call( deferred, deferred );
1249 }
1250
1251 // All done!
1252 return deferred;
1253 },
1254
1255 // Deferred helper
1256 when: function( subordinate /* , ..., subordinateN */ ) {
1257 var i = 0,
1258 resolveValues = core_slice.call( arguments ),
1259 length = resolveValues.length,
1260
1261 // the count of uncompleted subordinates
1262 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
1263
1264 // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
1265 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
1266
1267 // Update function for both resolve and progress values
1268 updateFunc = function( i, contexts, values ) {
1269 return function( value ) {
1270 contexts[ i ] = this;
1271 values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
1272 if( values === progressValues ) {
1273 deferred.notifyWith( contexts, values );
1274 } else if ( !( --remaining ) ) {
1275 deferred.resolveWith( contexts, values );
1276 }
1277 };
1278 },
1279
1280 progressValues, progressContexts, resolveContexts;
1281
1282 // add listeners to Deferred subordinates; treat others as resolved
1283 if ( length > 1 ) {
1284 progressValues = new Array( length );
1285 progressContexts = new Array( length );
1286 resolveContexts = new Array( length );
1287 for ( ; i < length; i++ ) {
1288 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
1289 resolveValues[ i ].promise()
1290 .done( updateFunc( i, resolveContexts, resolveValues ) )
1291 .fail( deferred.reject )
1292 .progress( updateFunc( i, progressContexts, progressValues ) );
1293 } else {
1294 --remaining;
1295 }
1296 }
1297 }
1298
1299 // if we're not waiting on anything, resolve the master
1300 if ( !remaining ) {
1301 deferred.resolveWith( resolveContexts, resolveValues );
1302 }
1303
1304 return deferred.promise();
1305 }
1306 });
1307 jQuery.support = (function() {
1308
1309 var support, all, a,
1310 input, select, fragment,
1311 opt, eventName, isSupported, i,
1312 div = document.createElement("div");
1313
1314 // Setup
1315 div.setAttribute( "className", "t" );
1316 div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
1317
1318 // Support tests won't run in some limited or non-browser environments
1319 all = div.getElementsByTagName("*");
1320 a = div.getElementsByTagName("a")[ 0 ];
1321 if ( !all || !a || !all.length ) {
1322 return {};
1323 }
1324
1325 // First batch of tests
1326 select = document.createElement("select");
1327 opt = select.appendChild( document.createElement("option") );
1328 input = div.getElementsByTagName("input")[ 0 ];
1329
1330 a.style.cssText = "top:1px;float:left;opacity:.5";
1331 support = {
1332 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1333 getSetAttribute: div.className !== "t",
1334
1335 // IE strips leading whitespace when .innerHTML is used
1336 leadingWhitespace: div.firstChild.nodeType === 3,
1337
1338 // Make sure that tbody elements aren't automatically inserted
1339 // IE will insert them into empty tables
1340 tbody: !div.getElementsByTagName("tbody").length,
1341
1342 // Make sure that link elements get serialized correctly by innerHTML
1343 // This requires a wrapper element in IE
1344 htmlSerialize: !!div.getElementsByTagName("link").length,
1345
1346 // Get the style information from getAttribute
1347 // (IE uses .cssText instead)
1348 style: /top/.test( a.getAttribute("style") ),
1349
1350 // Make sure that URLs aren't manipulated
1351 // (IE normalizes it by default)
1352 hrefNormalized: a.getAttribute("href") === "/a",
1353
1354 // Make sure that element opacity exists
1355 // (IE uses filter instead)
1356 // Use a regex to work around a WebKit issue. See #5145
1357 opacity: /^0.5/.test( a.style.opacity ),
1358
1359 // Verify style float existence
1360 // (IE uses styleFloat instead of cssFloat)
1361 cssFloat: !!a.style.cssFloat,
1362
1363 // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
1364 checkOn: !!input.value,
1365
1366 // Make sure that a selected-by-default option has a working selected property.
1367 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1368 optSelected: opt.selected,
1369
1370 // Tests for enctype support on a form (#6743)
1371 enctype: !!document.createElement("form").enctype,
1372
1373 // Makes sure cloning an html5 element does not cause problems
1374 // Where outerHTML is undefined, this still works
1375 html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
1376
1377 // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
1378 boxModel: document.compatMode === "CSS1Compat",
1379
1380 // Will be defined later
1381 deleteExpando: true,
1382 noCloneEvent: true,
1383 inlineBlockNeedsLayout: false,
1384 shrinkWrapBlocks: false,
1385 reliableMarginRight: true,
1386 boxSizingReliable: true,
1387 pixelPosition: false
1388 };
1389
1390 // Make sure checked status is properly cloned
1391 input.checked = true;
1392 support.noCloneChecked = input.cloneNode( true ).checked;
1393
1394 // Make sure that the options inside disabled selects aren't marked as disabled
1395 // (WebKit marks them as disabled)
1396 select.disabled = true;
1397 support.optDisabled = !opt.disabled;
1398
1399 // Support: IE<9
1400 try {
1401 delete div.test;
1402 } catch( e ) {
1403 support.deleteExpando = false;
1404 }
1405
1406 // Check if we can trust getAttribute("value")
1407 input = document.createElement("input");
1408 input.setAttribute( "value", "" );
1409 support.input = input.getAttribute( "value" ) === "";
1410
1411 // Check if an input maintains its value after becoming a radio
1412 input.value = "t";
1413 input.setAttribute( "type", "radio" );
1414 support.radioValue = input.value === "t";
1415
1416 // #11217 - WebKit loses check when the name is after the checked attribute
1417 input.setAttribute( "checked", "t" );
1418 input.setAttribute( "name", "t" );
1419
1420 fragment = document.createDocumentFragment();
1421 fragment.appendChild( input );
1422
1423 // Check if a disconnected checkbox will retain its checked
1424 // value of true after appended to the DOM (IE6/7)
1425 support.appendChecked = input.checked;
1426
1427 // WebKit doesn't clone checked state correctly in fragments
1428 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1429
1430 // Support: IE<9
1431 // Opera does not clone events (and typeof div.attachEvent === undefined).
1432 // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
1433 if ( div.attachEvent ) {
1434 div.attachEvent( "onclick", function() {
1435 support.noCloneEvent = false;
1436 });
1437
1438 div.cloneNode( true ).click();
1439 }
1440
1441 // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
1442 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
1443 for ( i in { submit: true, change: true, focusin: true }) {
1444 div.setAttribute( eventName = "on" + i, "t" );
1445
1446 support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
1447 }
1448
1449 div.style.backgroundClip = "content-box";
1450 div.cloneNode( true ).style.backgroundClip = "";
1451 support.clearCloneStyle = div.style.backgroundClip === "content-box";
1452
1453 // Run tests that need a body at doc ready
1454 jQuery(function() {
1455 var container, marginDiv, tds,
1456 divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
1457 body = document.getElementsByTagName("body")[0];
1458
1459 if ( !body ) {
1460 // Return for frameset docs that don't have a body
1461 return;
1462 }
1463
1464 container = document.createElement("div");
1465 container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
1466
1467 body.appendChild( container ).appendChild( div );
1468
1469 // Support: IE8
1470 // Check if table cells still have offsetWidth/Height when they are set
1471 // to display:none and there are still other visible table cells in a
1472 // table row; if so, offsetWidth/Height are not reliable for use when
1473 // determining if an element has been hidden directly using
1474 // display:none (it is still safe to use offsets if a parent element is
1475 // hidden; don safety goggles and see bug #4512 for more information).
1476 div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
1477 tds = div.getElementsByTagName("td");
1478 tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
1479 isSupported = ( tds[ 0 ].offsetHeight === 0 );
1480
1481 tds[ 0 ].style.display = "";
1482 tds[ 1 ].style.display = "none";
1483
1484 // Support: IE8
1485 // Check if empty table cells still have offsetWidth/Height
1486 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1487
1488 // Check box-sizing and margin behavior
1489 div.innerHTML = "";
1490 div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
1491 support.boxSizing = ( div.offsetWidth === 4 );
1492 support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
1493
1494 // Use window.getComputedStyle because jsdom on node.js will break without it.
1495 if ( window.getComputedStyle ) {
1496 support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
1497 support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
1498
1499 // Check if div with explicit width and no margin-right incorrectly
1500 // gets computed margin-right based on width of container. (#3333)
1501 // Fails in WebKit before Feb 2011 nightlies
1502 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1503 marginDiv = div.appendChild( document.createElement("div") );
1504 marginDiv.style.cssText = div.style.cssText = divReset;
1505 marginDiv.style.marginRight = marginDiv.style.width = "0";
1506 div.style.width = "1px";
1507
1508 support.reliableMarginRight =
1509 !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
1510 }
1511
1512 if ( typeof div.style.zoom !== core_strundefined ) {
1513 // Support: IE<8
1514 // Check if natively block-level elements act like inline-block
1515 // elements when setting their display to 'inline' and giving
1516 // them layout
1517 div.innerHTML = "";
1518 div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
1519 support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
1520
1521 // Support: IE6
1522 // Check if elements with layout shrink-wrap their children
1523 div.style.display = "block";
1524 div.innerHTML = "<div></div>";
1525 div.firstChild.style.width = "5px";
1526 support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
1527
1528 if ( support.inlineBlockNeedsLayout ) {
1529 // Prevent IE 6 from affecting layout for positioned elements #11048
1530 // Prevent IE from shrinking the body in IE 7 mode #12869
1531 // Support: IE<8
1532 body.style.zoom = 1;
1533 }
1534 }
1535
1536 body.removeChild( container );
1537
1538 // Null elements to avoid leaks in IE
1539 container = div = tds = marginDiv = null;
1540 });
1541
1542 // Null elements to avoid leaks in IE
1543 all = select = fragment = opt = a = input = null;
1544
1545 return support;
1546 })();
1547
1548 var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
1549 rmultiDash = /([A-Z])/g;
1550
1551 function internalData( elem, name, data, pvt /* Internal Use Only */ ){
1552 if ( !jQuery.acceptData( elem ) ) {
1553 return;
1554 }
1555
1556 var thisCache, ret,
1557 internalKey = jQuery.expando,
1558 getByName = typeof name === "string",
1559
1560 // We have to handle DOM nodes and JS objects differently because IE6-7
1561 // can't GC object references properly across the DOM-JS boundary
1562 isNode = elem.nodeType,
1563
1564 // Only DOM nodes need the global jQuery cache; JS object data is
1565 // attached directly to the object so GC can occur automatically
1566 cache = isNode ? jQuery.cache : elem,
1567
1568 // Only defining an ID for JS objects if its cache already exists allows
1569 // the code to shortcut on the same path as a DOM node with no cache
1570 id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
1571
1572 // Avoid doing any more work than we need to when trying to get data on an
1573 // object that has no data at all
1574 if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) {
1575 return;
1576 }
1577
1578 if ( !id ) {
1579 // Only DOM nodes need a new unique ID for each element since their data
1580 // ends up in the global cache
1581 if ( isNode ) {
1582 elem[ internalKey ] = id = core_deletedIds.pop() || jQuery.guid++;
1583 } else {
1584 id = internalKey;
1585 }
1586 }
1587
1588 if ( !cache[ id ] ) {
1589 cache[ id ] = {};
1590
1591 // Avoids exposing jQuery metadata on plain JS objects when the object
1592 // is serialized using JSON.stringify
1593 if ( !isNode ) {
1594 cache[ id ].toJSON = jQuery.noop;
1595 }
1596 }
1597
1598 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1599 // shallow copied over onto the existing cache
1600 if ( typeof name === "object" || typeof name === "function" ) {
1601 if ( pvt ) {
1602 cache[ id ] = jQuery.extend( cache[ id ], name );
1603 } else {
1604 cache[ id ].data = jQuery.extend( cache[ id ].data, name );
1605 }
1606 }
1607
1608 thisCache = cache[ id ];
1609
1610 // jQuery data() is stored in a separate object inside the object's internal data
1611 // cache in order to avoid key collisions between internal data and user-defined
1612 // data.
1613 if ( !pvt ) {
1614 if ( !thisCache.data ) {
1615 thisCache.data = {};
1616 }
1617
1618 thisCache = thisCache.data;
1619 }
1620
1621 if ( data !== undefined ) {
1622 thisCache[ jQuery.camelCase( name ) ] = data;
1623 }
1624
1625 // Check for both converted-to-camel and non-converted data property names
1626 // If a data property was specified
1627 if ( getByName ) {
1628
1629 // First Try to find as-is property data
1630 ret = thisCache[ name ];
1631
1632 // Test for null|undefined property data
1633 if ( ret == null ) {
1634
1635 // Try to find the camelCased property
1636 ret = thisCache[ jQuery.camelCase( name ) ];
1637 }
1638 } else {
1639 ret = thisCache;
1640 }
1641
1642 return ret;
1643 }
1644
1645 function internalRemoveData( elem, name, pvt ) {
1646 if ( !jQuery.acceptData( elem ) ) {
1647 return;
1648 }
1649
1650 var i, l, thisCache,
1651 isNode = elem.nodeType,
1652
1653 // See jQuery.data for more information
1654 cache = isNode ? jQuery.cache : elem,
1655 id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1656
1657 // If there is already no cache entry for this object, there is no
1658 // purpose in continuing
1659 if ( !cache[ id ] ) {
1660 return;
1661 }
1662
1663 if ( name ) {
1664
1665 thisCache = pvt ? cache[ id ] : cache[ id ].data;
1666
1667 if ( thisCache ) {
1668
1669 // Support array or space separated string names for data keys
1670 if ( !jQuery.isArray( name ) ) {
1671
1672 // try the string as a key before any manipulation
1673 if ( name in thisCache ) {
1674 name = [ name ];
1675 } else {
1676
1677 // split the camel cased version by spaces unless a key with the spaces exists
1678 name = jQuery.camelCase( name );
1679 if ( name in thisCache ) {
1680 name = [ name ];
1681 } else {
1682 name = name.split(" ");
1683 }
1684 }
1685 } else {
1686 // If "name" is an array of keys...
1687 // When data is initially created, via ("key", "val") signature,
1688 // keys will be converted to camelCase.
1689 // Since there is no way to tell _how_ a key was added, remove
1690 // both plain key and camelCase key. #12786
1691 // This will only penalize the array argument path.
1692 name = name.concat( jQuery.map( name, jQuery.camelCase ) );
1693 }
1694
1695 for ( i = 0, l = name.length; i < l; i++ ) {
1696 delete thisCache[ name[i] ];
1697 }
1698
1699 // If there is no data left in the cache, we want to continue
1700 // and let the cache object itself get destroyed
1701 if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
1702 return;
1703 }
1704 }
1705 }
1706
1707 // See jQuery.data for more information
1708 if ( !pvt ) {
1709 delete cache[ id ].data;
1710
1711 // Don't destroy the parent cache unless the internal data object
1712 // had been the only thing left in it
1713 if ( !isEmptyDataObject( cache[ id ] ) ) {
1714 return;
1715 }
1716 }
1717
1718 // Destroy the cache
1719 if ( isNode ) {
1720 jQuery.cleanData( [ elem ], true );
1721
1722 // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
1723 } else if ( jQuery.support.deleteExpando || cache != cache.window ) {
1724 delete cache[ id ];
1725
1726 // When all else fails, null
1727 } else {
1728 cache[ id ] = null;
1729 }
1730 }
1731
1732 jQuery.extend({
1733 cache: {},
1734
1735 // Unique for each copy of jQuery on the page
1736 // Non-digits removed to match rinlinejQuery
1737 expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
1738
1739 // The following elements throw uncatchable exceptions if you
1740 // attempt to add expando properties to them.
1741 noData: {
1742 "embed": true,
1743 // Ban all objects except for Flash (which handle expandos)
1744 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1745 "applet": true
1746 },
1747
1748 hasData: function( elem ) {
1749 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1750 return !!elem && !isEmptyDataObject( elem );
1751 },
1752
1753 data: function( elem, name, data ) {
1754 return internalData( elem, name, data );
1755 },
1756
1757 removeData: function( elem, name ) {
1758 return internalRemoveData( elem, name );
1759 },
1760
1761 // For internal use only.
1762 _data: function( elem, name, data ) {
1763 return internalData( elem, name, data, true );
1764 },
1765
1766 _removeData: function( elem, name ) {
1767 return internalRemoveData( elem, name, true );
1768 },
1769
1770 // A method for determining if a DOM node can handle the data expando
1771 acceptData: function( elem ) {
1772 // Do not set data on non-element because it will not be cleared (#8335).
1773 if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
1774 return false;
1775 }
1776
1777 var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
1778
1779 // nodes accept data unless otherwise specified; rejection can be conditional
1780 return !noData || noData !== true && elem.getAttribute("classid") === noData;
1781 }
1782 });
1783
1784 jQuery.fn.extend({
1785 data: function( key, value ) {
1786 var attrs, name,
1787 elem = this[0],
1788 i = 0,
1789 data = null;
1790
1791 // Gets all values
1792 if ( key === undefined ) {
1793 if ( this.length ) {
1794 data = jQuery.data( elem );
1795
1796 if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
1797 attrs = elem.attributes;
1798 for ( ; i < attrs.length; i++ ) {
1799 name = attrs[i].name;
1800
1801 if ( !name.indexOf( "data-" ) ) {
1802 name = jQuery.camelCase( name.slice(5) );
1803
1804 dataAttr( elem, name, data[ name ] );
1805 }
1806 }
1807 jQuery._data( elem, "parsedAttrs", true );
1808 }
1809 }
1810
1811 return data;
1812 }
1813
1814 // Sets multiple values
1815 if ( typeof key === "object" ) {
1816 return this.each(function() {
1817 jQuery.data( this, key );
1818 });
1819 }
1820
1821 return jQuery.access( this, function( value ) {
1822
1823 if ( value === undefined ) {
1824 // Try to fetch any internally stored data first
1825 return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
1826 }
1827
1828 this.each(function() {
1829 jQuery.data( this, key, value );
1830 });
1831 }, null, value, arguments.length > 1, null, true );
1832 },
1833
1834 removeData: function( key ) {
1835 return this.each(function() {
1836 jQuery.removeData( this, key );
1837 });
1838 }
1839 });
1840
1841 function dataAttr( elem, key, data ) {
1842 // If nothing was found internally, try to fetch any
1843 // data from the HTML5 data-* attribute
1844 if ( data === undefined && elem.nodeType === 1 ) {
1845
1846 var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
1847
1848 data = elem.getAttribute( name );
1849
1850 if ( typeof data === "string" ) {
1851 try {
1852 data = data === "true" ? true :
1853 data === "false" ? false :
1854 data === "null" ? null :
1855 // Only convert to a number if it doesn't change the string
1856 +data + "" === data ? +data :
1857 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1858 data;
1859 } catch( e ) {}
1860
1861 // Make sure we set the data so it isn't changed later
1862 jQuery.data( elem, key, data );
1863
1864 } else {
1865 data = undefined;
1866 }
1867 }
1868
1869 return data;
1870 }
1871
1872 // checks a cache object for emptiness
1873 function isEmptyDataObject( obj ) {
1874 var name;
1875 for ( name in obj ) {
1876
1877 // if the public data object is empty, the private is still empty
1878 if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
1879 continue;
1880 }
1881 if ( name !== "toJSON" ) {
1882 return false;
1883 }
1884 }
1885
1886 return true;
1887 }
1888 jQuery.extend({
1889 queue: function( elem, type, data ) {
1890 var queue;
1891
1892 if ( elem ) {
1893 type = ( type || "fx" ) + "queue";
1894 queue = jQuery._data( elem, type );
1895
1896 // Speed up dequeue by getting out quickly if this is just a lookup
1897 if ( data ) {
1898 if ( !queue || jQuery.isArray(data) ) {
1899 queue = jQuery._data( elem, type, jQuery.makeArray(data) );
1900 } else {
1901 queue.push( data );
1902 }
1903 }
1904 return queue || [];
1905 }
1906 },
1907
1908 dequeue: function( elem, type ) {
1909 type = type || "fx";
1910
1911 var queue = jQuery.queue( elem, type ),
1912 startLength = queue.length,
1913 fn = queue.shift(),
1914 hooks = jQuery._queueHooks( elem, type ),
1915 next = function() {
1916 jQuery.dequeue( elem, type );
1917 };
1918
1919 // If the fx queue is dequeued, always remove the progress sentinel
1920 if ( fn === "inprogress" ) {
1921 fn = queue.shift();
1922 startLength--;
1923 }
1924
1925 hooks.cur = fn;
1926 if ( fn ) {
1927
1928 // Add a progress sentinel to prevent the fx queue from being
1929 // automatically dequeued
1930 if ( type === "fx" ) {
1931 queue.unshift( "inprogress" );
1932 }
1933
1934 // clear up the last queue stop function
1935 delete hooks.stop;
1936 fn.call( elem, next, hooks );
1937 }
1938
1939 if ( !startLength && hooks ) {
1940 hooks.empty.fire();
1941 }
1942 },
1943
1944 // not intended for public consumption - generates a queueHooks object, or returns the current one
1945 _queueHooks: function( elem, type ) {
1946 var key = type + "queueHooks";
1947 return jQuery._data( elem, key ) || jQuery._data( elem, key, {
1948 empty: jQuery.Callbacks("once memory").add(function() {
1949 jQuery._removeData( elem, type + "queue" );
1950 jQuery._removeData( elem, key );
1951 })
1952 });
1953 }
1954 });
1955
1956 jQuery.fn.extend({
1957 queue: function( type, data ) {
1958 var setter = 2;
1959
1960 if ( typeof type !== "string" ) {
1961 data = type;
1962 type = "fx";
1963 setter--;
1964 }
1965
1966 if ( arguments.length < setter ) {
1967 return jQuery.queue( this[0], type );
1968 }
1969
1970 return data === undefined ?
1971 this :
1972 this.each(function() {
1973 var queue = jQuery.queue( this, type, data );
1974
1975 // ensure a hooks for this queue
1976 jQuery._queueHooks( this, type );
1977
1978 if ( type === "fx" && queue[0] !== "inprogress" ) {
1979 jQuery.dequeue( this, type );
1980 }
1981 });
1982 },
1983 dequeue: function( type ) {
1984 return this.each(function() {
1985 jQuery.dequeue( this, type );
1986 });
1987 },
1988 // Based off of the plugin by Clint Helfers, with permission.
1989 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1990 delay: function( time, type ) {
1991 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
1992 type = type || "fx";
1993
1994 return this.queue( type, function( next, hooks ) {
1995 var timeout = setTimeout( next, time );
1996 hooks.stop = function() {
1997 clearTimeout( timeout );
1998 };
1999 });
2000 },
2001 clearQueue: function( type ) {
2002 return this.queue( type || "fx", [] );
2003 },
2004 // Get a promise resolved when queues of a certain type
2005 // are emptied (fx is the type by default)
2006 promise: function( type, obj ) {
2007 var tmp,
2008 count = 1,
2009 defer = jQuery.Deferred(),
2010 elements = this,
2011 i = this.length,
2012 resolve = function() {
2013 if ( !( --count ) ) {
2014 defer.resolveWith( elements, [ elements ] );
2015 }
2016 };
2017
2018 if ( typeof type !== "string" ) {
2019 obj = type;
2020 type = undefined;
2021 }
2022 type = type || "fx";
2023
2024 while( i-- ) {
2025 tmp = jQuery._data( elements[ i ], type + "queueHooks" );
2026 if ( tmp && tmp.empty ) {
2027 count++;
2028 tmp.empty.add( resolve );
2029 }
2030 }
2031 resolve();
2032 return defer.promise( obj );
2033 }
2034 });
2035 var nodeHook, boolHook,
2036 rclass = /[\t\r\n]/g,
2037 rreturn = /\r/g,
2038 rfocusable = /^(?:input|select|textarea|button|object)$/i,
2039 rclickable = /^(?:a|area)$/i,
2040 rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
2041 ruseDefault = /^(?:checked|selected)$/i,
2042 getSetAttribute = jQuery.support.getSetAttribute,
2043 getSetInput = jQuery.support.input;
2044
2045 jQuery.fn.extend({
2046 attr: function( name, value ) {
2047 return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
2048 },
2049
2050 removeAttr: function( name ) {
2051 return this.each(function() {
2052 jQuery.removeAttr( this, name );
2053 });
2054 },
2055
2056 prop: function( name, value ) {
2057 return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
2058 },
2059
2060 removeProp: function( name ) {
2061 name = jQuery.propFix[ name ] || name;
2062 return this.each(function() {
2063 // try/catch handles cases where IE balks (such as removing a property on window)
2064 try {
2065 this[ name ] = undefined;
2066 delete this[ name ];
2067 } catch( e ) {}
2068 });
2069 },
2070
2071 addClass: function( value ) {
2072 var classes, elem, cur, clazz, j,
2073 i = 0,
2074 len = this.length,
2075 proceed = typeof value === "string" && value;
2076
2077 if ( jQuery.isFunction( value ) ) {
2078 return this.each(function( j ) {
2079 jQuery( this ).addClass( value.call( this, j, this.className ) );
2080 });
2081 }
2082
2083 if ( proceed ) {
2084 // The disjunction here is for better compressibility (see removeClass)
2085 classes = ( value || "" ).match( core_rnotwhite ) || [];
2086
2087 for ( ; i < len; i++ ) {
2088 elem = this[ i ];
2089 cur = elem.nodeType === 1 && ( elem.className ?
2090 ( " " + elem.className + " " ).replace( rclass, " " ) :
2091 " "
2092 );
2093
2094 if ( cur ) {
2095 j = 0;
2096 while ( (clazz = classes[j++]) ) {
2097 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
2098 cur += clazz + " ";
2099 }
2100 }
2101 elem.className = jQuery.trim( cur );
2102
2103 }
2104 }
2105 }
2106
2107 return this;
2108 },
2109
2110 removeClass: function( value ) {
2111 var classes, elem, cur, clazz, j,
2112 i = 0,
2113 len = this.length,
2114 proceed = arguments.length === 0 || typeof value === "string" && value;
2115
2116 if ( jQuery.isFunction( value ) ) {
2117 return this.each(function( j ) {
2118 jQuery( this ).removeClass( value.call( this, j, this.className ) );
2119 });
2120 }
2121 if ( proceed ) {
2122 classes = ( value || "" ).match( core_rnotwhite ) || [];
2123
2124 for ( ; i < len; i++ ) {
2125 elem = this[ i ];
2126 // This expression is here for better compressibility (see addClass)
2127 cur = elem.nodeType === 1 && ( elem.className ?
2128 ( " " + elem.className + " " ).replace( rclass, " " ) :
2129 ""
2130 );
2131
2132 if ( cur ) {
2133 j = 0;
2134 while ( (clazz = classes[j++]) ) {
2135 // Remove *all* instances
2136 while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
2137 cur = cur.replace( " " + clazz + " ", " " );
2138 }
2139 }
2140 elem.className = value ? jQuery.trim( cur ) : "";
2141 }
2142 }
2143 }
2144
2145 return this;
2146 },
2147
2148 toggleClass: function( value, stateVal ) {
2149 var type = typeof value,
2150 isBool = typeof stateVal === "boolean";
2151
2152 if ( jQuery.isFunction( value ) ) {
2153 return this.each(function( i ) {
2154 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2155 });
2156 }
2157
2158 return this.each(function() {
2159 if ( type === "string" ) {
2160 // toggle individual class names
2161 var className,
2162 i = 0,
2163 self = jQuery( this ),
2164 state = stateVal,
2165 classNames = value.match( core_rnotwhite ) || [];
2166
2167 while ( (className = classNames[ i++ ]) ) {
2168 // check each className given, space separated list
2169 state = isBool ? state : !self.hasClass( className );
2170 self[ state ? "addClass" : "removeClass" ]( className );
2171 }
2172
2173 // Toggle whole class name
2174 } else if ( type === core_strundefined || type === "boolean" ) {
2175 if ( this.className ) {
2176 // store className if set
2177 jQuery._data( this, "__className__", this.className );
2178 }
2179
2180 // If the element has a class name or if we're passed "false",
2181 // then remove the whole classname (if there was one, the above saved it).
2182 // Otherwise bring back whatever was previously saved (if anything),
2183 // falling back to the empty string if nothing was stored.
2184 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2185 }
2186 });
2187 },
2188
2189 hasClass: function( selector ) {
2190 var className = " " + selector + " ",
2191 i = 0,
2192 l = this.length;
2193 for ( ; i < l; i++ ) {
2194 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
2195 return true;
2196 }
2197 }
2198
2199 return false;
2200 },
2201
2202 val: function( value ) {
2203 var ret, hooks, isFunction,
2204 elem = this[0];
2205
2206 if ( !arguments.length ) {
2207 if ( elem ) {
2208 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
2209
2210 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2211 return ret;
2212 }
2213
2214 ret = elem.value;
2215
2216 return typeof ret === "string" ?
2217 // handle most common string cases
2218 ret.replace(rreturn, "") :
2219 // handle cases where value is null/undef or number
2220 ret == null ? "" : ret;
2221 }
2222
2223 return;
2224 }
2225
2226 isFunction = jQuery.isFunction( value );
2227
2228 return this.each(function( i ) {
2229 var val,
2230 self = jQuery(this);
2231
2232 if ( this.nodeType !== 1 ) {
2233 return;
2234 }
2235
2236 if ( isFunction ) {
2237 val = value.call( this, i, self.val() );
2238 } else {
2239 val = value;
2240 }
2241
2242 // Treat null/undefined as ""; convert numbers to string
2243 if ( val == null ) {
2244 val = "";
2245 } else if ( typeof val === "number" ) {
2246 val += "";
2247 } else if ( jQuery.isArray( val ) ) {
2248 val = jQuery.map(val, function ( value ) {
2249 return value == null ? "" : value + "";
2250 });
2251 }
2252
2253 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
2254
2255 // If set returns undefined, fall back to normal setting
2256 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2257 this.value = val;
2258 }
2259 });
2260 }
2261 });
2262
2263 jQuery.extend({
2264 valHooks: {
2265 option: {
2266 get: function( elem ) {
2267 // attributes.value is undefined in Blackberry 4.7 but
2268 // uses .value. See #6932
2269 var val = elem.attributes.value;
2270 return !val || val.specified ? elem.value : elem.text;
2271 }
2272 },
2273 select: {
2274 get: function( elem ) {
2275 var value, option,
2276 options = elem.options,
2277 index = elem.selectedIndex,
2278 one = elem.type === "select-one" || index < 0,
2279 values = one ? null : [],
2280 max = one ? index + 1 : options.length,
2281 i = index < 0 ?
2282 max :
2283 one ? index : 0;
2284
2285 // Loop through all the selected options
2286 for ( ; i < max; i++ ) {
2287 option = options[ i ];
2288
2289 // oldIE doesn't update selected after form reset (#2551)
2290 if ( ( option.selected || i === index ) &&
2291 // Don't return options that are disabled or in a disabled optgroup
2292 ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
2293 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
2294
2295 // Get the specific value for the option
2296 value = jQuery( option ).val();
2297
2298 // We don't need an array for one selects
2299 if ( one ) {
2300 return value;
2301 }
2302
2303 // Multi-Selects return an array
2304 values.push( value );
2305 }
2306 }
2307
2308 return values;
2309 },
2310
2311 set: function( elem, value ) {
2312 var values = jQuery.makeArray( value );
2313
2314 jQuery(elem).find("option").each(function() {
2315 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2316 });
2317
2318 if ( !values.length ) {
2319 elem.selectedIndex = -1;
2320 }
2321 return values;
2322 }
2323 }
2324 },
2325
2326 attr: function( elem, name, value ) {
2327 var hooks, notxml, ret,
2328 nType = elem.nodeType;
2329
2330 // don't get/set attributes on text, comment and attribute nodes
2331 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2332 return;
2333 }
2334
2335 // Fallback to prop when attributes are not supported
2336 if ( typeof elem.getAttribute === core_strundefined ) {
2337 return jQuery.prop( elem, name, value );
2338 }
2339
2340 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2341
2342 // All attributes are lowercase
2343 // Grab necessary hook if one is defined
2344 if ( notxml ) {
2345 name = name.toLowerCase();
2346 hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
2347 }
2348
2349 if ( value !== undefined ) {
2350
2351 if ( value === null ) {
2352 jQuery.removeAttr( elem, name );
2353
2354 } else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2355 return ret;
2356
2357 } else {
2358 elem.setAttribute( name, value + "" );
2359 return value;
2360 }
2361
2362 } else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2363 return ret;
2364
2365 } else {
2366
2367 // In IE9+, Flash objects don't have .getAttribute (#12945)
2368 // Support: IE9+
2369 if ( typeof elem.getAttribute !== core_strundefined ) {
2370 ret = elem.getAttribute( name );
2371 }
2372
2373 // Non-existent attributes return null, we normalize to undefined
2374 return ret == null ?
2375 undefined :
2376 ret;
2377 }
2378 },
2379
2380 removeAttr: function( elem, value ) {
2381 var name, propName,
2382 i = 0,
2383 attrNames = value && value.match( core_rnotwhite );
2384
2385 if ( attrNames && elem.nodeType === 1 ) {
2386 while ( (name = attrNames[i++]) ) {
2387 propName = jQuery.propFix[ name ] || name;
2388
2389 // Boolean attributes get special treatment (#10870)
2390 if ( rboolean.test( name ) ) {
2391 // Set corresponding property to false for boolean attributes
2392 // Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
2393 if ( !getSetAttribute && ruseDefault.test( name ) ) {
2394 elem[ jQuery.camelCase( "default-" + name ) ] =
2395 elem[ propName ] = false;
2396 } else {
2397 elem[ propName ] = false;
2398 }
2399
2400 // See #9699 for explanation of this approach (setting first, then removal)
2401 } else {
2402 jQuery.attr( elem, name, "" );
2403 }
2404
2405 elem.removeAttribute( getSetAttribute ? name : propName );
2406 }
2407 }
2408 },
2409
2410 attrHooks: {
2411 type: {
2412 set: function( elem, value ) {
2413 if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2414 // Setting the type on a radio button after the value resets the value in IE6-9
2415 // Reset value to default in case type is set after value during creation
2416 var val = elem.value;
2417 elem.setAttribute( "type", value );
2418 if ( val ) {
2419 elem.value = val;
2420 }
2421 return value;
2422 }
2423 }
2424 }
2425 },
2426
2427 propFix: {
2428 tabindex: "tabIndex",
2429 readonly: "readOnly",
2430 "for": "htmlFor",
2431 "class": "className",
2432 maxlength: "maxLength",
2433 cellspacing: "cellSpacing",
2434 cellpadding: "cellPadding",
2435 rowspan: "rowSpan",
2436 colspan: "colSpan",
2437 usemap: "useMap",
2438 frameborder: "frameBorder",
2439 contenteditable: "contentEditable"
2440 },
2441
2442 prop: function( elem, name, value ) {
2443 var ret, hooks, notxml,
2444 nType = elem.nodeType;
2445
2446 // don't get/set properties on text, comment and attribute nodes
2447 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2448 return;
2449 }
2450
2451 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2452
2453 if ( notxml ) {
2454 // Fix name and attach hooks
2455 name = jQuery.propFix[ name ] || name;
2456 hooks = jQuery.propHooks[ name ];
2457 }
2458
2459 if ( value !== undefined ) {
2460 if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2461 return ret;
2462
2463 } else {
2464 return ( elem[ name ] = value );
2465 }
2466
2467 } else {
2468 if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2469 return ret;
2470
2471 } else {
2472 return elem[ name ];
2473 }
2474 }
2475 },
2476
2477 propHooks: {
2478 tabIndex: {
2479 get: function( elem ) {
2480 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2481 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2482 var attributeNode = elem.getAttributeNode("tabindex");
2483
2484 return attributeNode && attributeNode.specified ?
2485 parseInt( attributeNode.value, 10 ) :
2486 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2487 0 :
2488 undefined;
2489 }
2490 }
2491 }
2492 });
2493
2494 // Hook for boolean attributes
2495 boolHook = {
2496 get: function( elem, name ) {
2497 var
2498 // Use .prop to determine if this attribute is understood as boolean
2499 prop = jQuery.prop( elem, name ),
2500
2501 // Fetch it accordingly
2502 attr = typeof prop === "boolean" && elem.getAttribute( name ),
2503 detail = typeof prop === "boolean" ?
2504
2505 getSetInput && getSetAttribute ?
2506 attr != null :
2507 // oldIE fabricates an empty string for missing boolean attributes
2508 // and conflates checked/selected into attroperties
2509 ruseDefault.test( name ) ?
2510 elem[ jQuery.camelCase( "default-" + name ) ] :
2511 !!attr :
2512
2513 // fetch an attribute node for properties not recognized as boolean
2514 elem.getAttributeNode( name );
2515
2516 return detail && detail.value !== false ?
2517 name.toLowerCase() :
2518 undefined;
2519 },
2520 set: function( elem, value, name ) {
2521 if ( value === false ) {
2522 // Remove boolean attributes when set to false
2523 jQuery.removeAttr( elem, name );
2524 } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
2525 // IE<8 needs the *property* name
2526 elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
2527
2528 // Use defaultChecked and defaultSelected for oldIE
2529 } else {
2530 elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
2531 }
2532
2533 return name;
2534 }
2535 };
2536
2537 // fix oldIE value attroperty
2538 if ( !getSetInput || !getSetAttribute ) {
2539 jQuery.attrHooks.value = {
2540 get: function( elem, name ) {
2541 var ret = elem.getAttributeNode( name );
2542 return jQuery.nodeName( elem, "input" ) ?
2543
2544 // Ignore the value *property* by using defaultValue
2545 elem.defaultValue :
2546
2547 ret && ret.specified ? ret.value : undefined;
2548 },
2549 set: function( elem, value, name ) {
2550 if ( jQuery.nodeName( elem, "input" ) ) {
2551 // Does not return so that setAttribute is also used
2552 elem.defaultValue = value;
2553 } else {
2554 // Use nodeHook if defined (#1954); otherwise setAttribute is fine
2555 return nodeHook && nodeHook.set( elem, value, name );
2556 }
2557 }
2558 };
2559 }
2560
2561 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2562 if ( !getSetAttribute ) {
2563
2564 // Use this for any attribute in IE6/7
2565 // This fixes almost every IE6/7 issue
2566 nodeHook = jQuery.valHooks.button = {
2567 get: function( elem, name ) {
2568 var ret = elem.getAttributeNode( name );
2569 return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?
2570 ret.value :
2571 undefined;
2572 },
2573 set: function( elem, value, name ) {
2574 // Set the existing or create a new attribute node
2575 var ret = elem.getAttributeNode( name );
2576 if ( !ret ) {
2577 elem.setAttributeNode(
2578 (ret = elem.ownerDocument.createAttribute( name ))
2579 );
2580 }
2581
2582 ret.value = value += "";
2583
2584 // Break association with cloned elements by also using setAttribute (#9646)
2585 return name === "value" || value === elem.getAttribute( name ) ?
2586 value :
2587 undefined;
2588 }
2589 };
2590
2591 // Set contenteditable to false on removals(#10429)
2592 // Setting to empty string throws an error as an invalid value
2593 jQuery.attrHooks.contenteditable = {
2594 get: nodeHook.get,
2595 set: function( elem, value, name ) {
2596 nodeHook.set( elem, value === "" ? false : value, name );
2597 }
2598 };
2599
2600 // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2601 // This is for removals
2602 jQuery.each([ "width", "height" ], function( i, name ) {
2603 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2604 set: function( elem, value ) {
2605 if ( value === "" ) {
2606 elem.setAttribute( name, "auto" );
2607 return value;
2608 }
2609 }
2610 });
2611 });
2612 }
2613
2614
2615 // Some attributes require a special call on IE
2616 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2617 if ( !jQuery.support.hrefNormalized ) {
2618 jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2619 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2620 get: function( elem ) {
2621 var ret = elem.getAttribute( name, 2 );
2622 return ret == null ? undefined : ret;
2623 }
2624 });
2625 });
2626
2627 // href/src property should get the full normalized URL (#10299/#12915)
2628 jQuery.each([ "href", "src" ], function( i, name ) {
2629 jQuery.propHooks[ name ] = {
2630 get: function( elem ) {
2631 return elem.getAttribute( name, 4 );
2632 }
2633 };
2634 });
2635 }
2636
2637 if ( !jQuery.support.style ) {
2638 jQuery.attrHooks.style = {
2639 get: function( elem ) {
2640 // Return undefined in the case of empty string
2641 // Note: IE uppercases css property names, but if we were to .toLowerCase()
2642 // .cssText, that would destroy case senstitivity in URL's, like in "background"
2643 return elem.style.cssText || undefined;
2644 },
2645 set: function( elem, value ) {
2646 return ( elem.style.cssText = value + "" );
2647 }
2648 };
2649 }
2650
2651 // Safari mis-reports the default selected property of an option
2652 // Accessing the parent's selectedIndex property fixes it
2653 if ( !jQuery.support.optSelected ) {
2654 jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2655 get: function( elem ) {
2656 var parent = elem.parentNode;
2657
2658 if ( parent ) {
2659 parent.selectedIndex;
2660
2661 // Make sure that it also works with optgroups, see #5701
2662 if ( parent.parentNode ) {
2663 parent.parentNode.selectedIndex;
2664 }
2665 }
2666 return null;
2667 }
2668 });
2669 }
2670
2671 // IE6/7 call enctype encoding
2672 if ( !jQuery.support.enctype ) {
2673 jQuery.propFix.enctype = "encoding";
2674 }
2675
2676 // Radios and checkboxes getter/setter
2677 if ( !jQuery.support.checkOn ) {
2678 jQuery.each([ "radio", "checkbox" ], function() {
2679 jQuery.valHooks[ this ] = {
2680 get: function( elem ) {
2681 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2682 return elem.getAttribute("value") === null ? "on" : elem.value;
2683 }
2684 };
2685 });
2686 }
2687 jQuery.each([ "radio", "checkbox" ], function() {
2688 jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2689 set: function( elem, value ) {
2690 if ( jQuery.isArray( value ) ) {
2691 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
2692 }
2693 }
2694 });
2695 });
2696 var rformElems = /^(?:input|select|textarea)$/i,
2697 rkeyEvent = /^key/,
2698 rmouseEvent = /^(?:mouse|contextmenu)|click/,
2699 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2700 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
2701
2702 function returnTrue() {
2703 return true;
2704 }
2705
2706 function returnFalse() {
2707 return false;
2708 }
2709
2710 /*
2711 * Helper functions for managing events -- not part of the public interface.
2712 * Props to Dean Edwards' addEvent library for many of the ideas.
2713 */
2714 jQuery.event = {
2715
2716 global: {},
2717
2718 add: function( elem, types, handler, data, selector ) {
2719 var tmp, events, t, handleObjIn,
2720 special, eventHandle, handleObj,
2721 handlers, type, namespaces, origType,
2722 elemData = jQuery._data( elem );
2723
2724 // Don't attach events to noData or text/comment nodes (but allow plain objects)
2725 if ( !elemData ) {
2726 return;
2727 }
2728
2729 // Caller can pass in an object of custom data in lieu of the handler
2730 if ( handler.handler ) {
2731 handleObjIn = handler;
2732 handler = handleObjIn.handler;
2733 selector = handleObjIn.selector;
2734 }
2735
2736 // Make sure that the handler has a unique ID, used to find/remove it later
2737 if ( !handler.guid ) {
2738 handler.guid = jQuery.guid++;
2739 }
2740
2741 // Init the element's event structure and main handler, if this is the first
2742 if ( !(events = elemData.events) ) {
2743 events = elemData.events = {};
2744 }
2745 if ( !(eventHandle = elemData.handle) ) {
2746 eventHandle = elemData.handle = function( e ) {
2747 // Discard the second event of a jQuery.event.trigger() and
2748 // when an event is called after a page has unloaded
2749 return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
2750 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2751 undefined;
2752 };
2753 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2754 eventHandle.elem = elem;
2755 }
2756
2757 // Handle multiple events separated by a space
2758 // jQuery(...).bind("mouseover mouseout", fn);
2759 types = ( types || "" ).match( core_rnotwhite ) || [""];
2760 t = types.length;
2761 while ( t-- ) {
2762 tmp = rtypenamespace.exec( types[t] ) || [];
2763 type = origType = tmp[1];
2764 namespaces = ( tmp[2] || "" ).split( "." ).sort();
2765
2766 // If event changes its type, use the special event handlers for the changed type
2767 special = jQuery.event.special[ type ] || {};
2768
2769 // If selector defined, determine special event api type, otherwise given type
2770 type = ( selector ? special.delegateType : special.bindType ) || type;
2771
2772 // Update special based on newly reset type
2773 special = jQuery.event.special[ type ] || {};
2774
2775 // handleObj is passed to all event handlers
2776 handleObj = jQuery.extend({
2777 type: type,
2778 origType: origType,
2779 data: data,
2780 handler: handler,
2781 guid: handler.guid,
2782 selector: selector,
2783 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
2784 namespace: namespaces.join(".")
2785 }, handleObjIn );
2786
2787 // Init the event handler queue if we're the first
2788 if ( !(handlers = events[ type ]) ) {
2789 handlers = events[ type ] = [];
2790 handlers.delegateCount = 0;
2791
2792 // Only use addEventListener/attachEvent if the special events handler returns false
2793 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2794 // Bind the global event handler to the element
2795 if ( elem.addEventListener ) {
2796 elem.addEventListener( type, eventHandle, false );
2797
2798 } else if ( elem.attachEvent ) {
2799 elem.attachEvent( "on" + type, eventHandle );
2800 }
2801 }
2802 }
2803
2804 if ( special.add ) {
2805 special.add.call( elem, handleObj );
2806
2807 if ( !handleObj.handler.guid ) {
2808 handleObj.handler.guid = handler.guid;
2809 }
2810 }
2811
2812 // Add to the element's handler list, delegates in front
2813 if ( selector ) {
2814 handlers.splice( handlers.delegateCount++, 0, handleObj );
2815 } else {
2816 handlers.push( handleObj );
2817 }
2818
2819 // Keep track of which events have ever been used, for event optimization
2820 jQuery.event.global[ type ] = true;
2821 }
2822
2823 // Nullify elem to prevent memory leaks in IE
2824 elem = null;
2825 },
2826
2827 // Detach an event or set of events from an element
2828 remove: function( elem, types, handler, selector, mappedTypes ) {
2829 var j, handleObj, tmp,
2830 origCount, t, events,
2831 special, handlers, type,
2832 namespaces, origType,
2833 elemData = jQuery.hasData( elem ) && jQuery._data( elem );
2834
2835 if ( !elemData || !(events = elemData.events) ) {
2836 return;
2837 }
2838
2839 // Once for each type.namespace in types; type may be omitted
2840 types = ( types || "" ).match( core_rnotwhite ) || [""];
2841 t = types.length;
2842 while ( t-- ) {
2843 tmp = rtypenamespace.exec( types[t] ) || [];
2844 type = origType = tmp[1];
2845 namespaces = ( tmp[2] || "" ).split( "." ).sort();
2846
2847 // Unbind all events (on this namespace, if provided) for the element
2848 if ( !type ) {
2849 for ( type in events ) {
2850 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2851 }
2852 continue;
2853 }
2854
2855 special = jQuery.event.special[ type ] || {};
2856 type = ( selector ? special.delegateType : special.bindType ) || type;
2857 handlers = events[ type ] || [];
2858 tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
2859
2860 // Remove matching events
2861 origCount = j = handlers.length;
2862 while ( j-- ) {
2863 handleObj = handlers[ j ];
2864
2865 if ( ( mappedTypes || origType === handleObj.origType ) &&
2866 ( !handler || handler.guid === handleObj.guid ) &&
2867 ( !tmp || tmp.test( handleObj.namespace ) ) &&
2868 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2869 handlers.splice( j, 1 );
2870
2871 if ( handleObj.selector ) {
2872 handlers.delegateCount--;
2873 }
2874 if ( special.remove ) {
2875 special.remove.call( elem, handleObj );
2876 }
2877 }
2878 }
2879
2880 // Remove generic event handler if we removed something and no more handlers exist
2881 // (avoids potential for endless recursion during removal of special event handlers)
2882 if ( origCount && !handlers.length ) {
2883 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
2884 jQuery.removeEvent( elem, type, elemData.handle );
2885 }
2886
2887 delete events[ type ];
2888 }
2889 }
2890
2891 // Remove the expando if it's no longer used
2892 if ( jQuery.isEmptyObject( events ) ) {
2893 delete elemData.handle;
2894
2895 // removeData also checks for emptiness and clears the expando if empty
2896 // so use it instead of delete
2897 jQuery._removeData( elem, "events" );
2898 }
2899 },
2900
2901 trigger: function( event, data, elem, onlyHandlers ) {
2902 var handle, ontype, cur,
2903 bubbleType, special, tmp, i,
2904 eventPath = [ elem || document ],
2905 type = core_hasOwn.call( event, "type" ) ? event.type : event,
2906 namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
2907
2908 cur = tmp = elem = elem || document;
2909
2910 // Don't do events on text and comment nodes
2911 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2912 return;
2913 }
2914
2915 // focus/blur morphs to focusin/out; ensure we're not firing them right now
2916 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
2917 return;
2918 }
2919
2920 if ( type.indexOf(".") >= 0 ) {
2921 // Namespaced trigger; create a regexp to match event type in handle()
2922 namespaces = type.split(".");
2923 type = namespaces.shift();
2924 namespaces.sort();
2925 }
2926 ontype = type.indexOf(":") < 0 && "on" + type;
2927
2928 // Caller can pass in a jQuery.Event object, Object, or just an event type string
2929 event = event[ jQuery.expando ] ?
2930 event :
2931 new jQuery.Event( type, typeof event === "object" && event );
2932
2933 event.isTrigger = true;
2934 event.namespace = namespaces.join(".");
2935 event.namespace_re = event.namespace ?
2936 new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
2937 null;
2938
2939 // Clean up the event in case it is being reused
2940 event.result = undefined;
2941 if ( !event.target ) {
2942 event.target = elem;
2943 }
2944
2945 // Clone any incoming data and prepend the event, creating the handler arg list
2946 data = data == null ?
2947 [ event ] :
2948 jQuery.makeArray( data, [ event ] );
2949
2950 // Allow special events to draw outside the lines
2951 special = jQuery.event.special[ type ] || {};
2952 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
2953 return;
2954 }
2955
2956 // Determine event propagation path in advance, per W3C events spec (#9951)
2957 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
2958 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
2959
2960 bubbleType = special.delegateType || type;
2961 if ( !rfocusMorph.test( bubbleType + type ) ) {
2962 cur = cur.parentNode;
2963 }
2964 for ( ; cur; cur = cur.parentNode ) {
2965 eventPath.push( cur );
2966 tmp = cur;
2967 }
2968
2969 // Only add window if we got to document (e.g., not plain obj or detached DOM)
2970 if ( tmp === (elem.ownerDocument || document) ) {
2971 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
2972 }
2973 }
2974
2975 // Fire handlers on the event path
2976 i = 0;
2977 while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
2978
2979 event.type = i > 1 ?
2980 bubbleType :
2981 special.bindType || type;
2982
2983 // jQuery handler
2984 handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
2985 if ( handle ) {
2986 handle.apply( cur, data );
2987 }
2988
2989 // Native handler
2990 handle = ontype && cur[ ontype ];
2991 if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
2992 event.preventDefault();
2993 }
2994 }
2995 event.type = type;
2996
2997 // If nobody prevented the default action, do it now
2998 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
2999
3000 if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
3001 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
3002
3003 // Call a native DOM method on the target with the same name name as the event.
3004 // Can't use an .isFunction() check here because IE6/7 fails that test.
3005 // Don't do default actions on window, that's where global variables be (#6170)
3006 if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
3007
3008 // Don't re-trigger an onFOO event when we call its FOO() method
3009 tmp = elem[ ontype ];
3010
3011 if ( tmp ) {
3012 elem[ ontype ] = null;
3013 }
3014
3015 // Prevent re-triggering of the same event, since we already bubbled it above
3016 jQuery.event.triggered = type;
3017 try {
3018 elem[ type ]();
3019 } catch ( e ) {
3020 // IE<9 dies on focus/blur to hidden element (#1486,#12518)
3021 // only reproducible on winXP IE8 native, not IE9 in IE8 mode
3022 }
3023 jQuery.event.triggered = undefined;
3024
3025 if ( tmp ) {
3026 elem[ ontype ] = tmp;
3027 }
3028 }
3029 }
3030 }
3031
3032 return event.result;
3033 },
3034
3035 dispatch: function( event ) {
3036
3037 // Make a writable jQuery.Event from the native event object
3038 event = jQuery.event.fix( event );
3039
3040 var i, ret, handleObj, matched, j,
3041 handlerQueue = [],
3042 args = core_slice.call( arguments ),
3043 handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
3044 special = jQuery.event.special[ event.type ] || {};
3045
3046 // Use the fix-ed jQuery.Event rather than the (read-only) native event
3047 args[0] = event;
3048 event.delegateTarget = this;
3049
3050 // Call the preDispatch hook for the mapped type, and let it bail if desired
3051 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
3052 return;
3053 }
3054
3055 // Determine handlers
3056 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
3057
3058 // Run delegates first; they may want to stop propagation beneath us
3059 i = 0;
3060 while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
3061 event.currentTarget = matched.elem;
3062
3063 j = 0;
3064 while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
3065
3066 // Triggered event must either 1) have no namespace, or
3067 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3068 if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
3069
3070 event.handleObj = handleObj;
3071 event.data = handleObj.data;
3072
3073 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3074 .apply( matched.elem, args );
3075
3076 if ( ret !== undefined ) {
3077 if ( (event.result = ret) === false ) {
3078 event.preventDefault();
3079 event.stopPropagation();
3080 }
3081 }
3082 }
3083 }
3084 }
3085
3086 // Call the postDispatch hook for the mapped type
3087 if ( special.postDispatch ) {
3088 special.postDispatch.call( this, event );
3089 }
3090
3091 return event.result;
3092 },
3093
3094 handlers: function( event, handlers ) {
3095 var sel, handleObj, matches, i,
3096 handlerQueue = [],
3097 delegateCount = handlers.delegateCount,
3098 cur = event.target;
3099
3100 // Find delegate handlers
3101 // Black-hole SVG <use> instance trees (#13180)
3102 // Avoid non-left-click bubbling in Firefox (#3861)
3103 if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
3104
3105 for ( ; cur != this; cur = cur.parentNode || this ) {
3106
3107 // Don't check non-elements (#13208)
3108 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
3109 if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
3110 matches = [];
3111 for ( i = 0; i < delegateCount; i++ ) {
3112 handleObj = handlers[ i ];
3113
3114 // Don't conflict with Object.prototype properties (#13203)
3115 sel = handleObj.selector + " ";
3116
3117 if ( matches[ sel ] === undefined ) {
3118 matches[ sel ] = handleObj.needsContext ?
3119 jQuery( sel, this ).index( cur ) >= 0 :
3120 jQuery.find( sel, this, null, [ cur ] ).length;
3121 }
3122 if ( matches[ sel ] ) {
3123 matches.push( handleObj );
3124 }
3125 }
3126 if ( matches.length ) {
3127 handlerQueue.push({ elem: cur, handlers: matches });
3128 }
3129 }
3130 }
3131 }
3132
3133 // Add the remaining (directly-bound) handlers
3134 if ( delegateCount < handlers.length ) {
3135 handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
3136 }
3137
3138 return handlerQueue;
3139 },
3140
3141 fix: function( event ) {
3142 if ( event[ jQuery.expando ] ) {
3143 return event;
3144 }
3145
3146 // Create a writable copy of the event object and normalize some properties
3147 var i, prop, copy,
3148 type = event.type,
3149 originalEvent = event,
3150 fixHook = this.fixHooks[ type ];
3151
3152 if ( !fixHook ) {
3153 this.fixHooks[ type ] = fixHook =
3154 rmouseEvent.test( type ) ? this.mouseHooks :
3155 rkeyEvent.test( type ) ? this.keyHooks :
3156 {};
3157 }
3158 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3159
3160 event = new jQuery.Event( originalEvent );
3161
3162 i = copy.length;
3163 while ( i-- ) {
3164 prop = copy[ i ];
3165 event[ prop ] = originalEvent[ prop ];
3166 }
3167
3168 // Support: IE<9
3169 // Fix target property (#1925)
3170 if ( !event.target ) {
3171 event.target = originalEvent.srcElement || document;
3172 }
3173
3174 // Support: Chrome 23+, Safari?
3175 // Target should not be a text node (#504, #13143)
3176 if ( event.target.nodeType === 3 ) {
3177 event.target = event.target.parentNode;
3178 }
3179
3180 // Support: IE<9
3181 // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
3182 event.metaKey = !!event.metaKey;
3183
3184 return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
3185 },
3186
3187 // Includes some event props shared by KeyEvent and MouseEvent
3188 props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3189
3190 fixHooks: {},
3191
3192 keyHooks: {
3193 props: "char charCode key keyCode".split(" "),
3194 filter: function( event, original ) {
3195
3196 // Add which for key events
3197 if ( event.which == null ) {
3198 event.which = original.charCode != null ? original.charCode : original.keyCode;
3199 }
3200
3201 return event;
3202 }
3203 },
3204
3205 mouseHooks: {
3206 props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3207 filter: function( event, original ) {
3208 var body, eventDoc, doc,
3209 button = original.button,
3210 fromElement = original.fromElement;
3211
3212 // Calculate pageX/Y if missing and clientX/Y available
3213 if ( event.pageX == null && original.clientX != null ) {
3214 eventDoc = event.target.ownerDocument || document;
3215 doc = eventDoc.documentElement;
3216 body = eventDoc.body;
3217
3218 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3219 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
3220 }
3221
3222 // Add relatedTarget, if necessary
3223 if ( !event.relatedTarget && fromElement ) {
3224 event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3225 }
3226
3227 // Add which for click: 1 === left; 2 === middle; 3 === right
3228 // Note: button is not normalized, so don't use it
3229 if ( !event.which && button !== undefined ) {
3230 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3231 }
3232
3233 return event;
3234 }
3235 },
3236
3237 special: {
3238 load: {
3239 // Prevent triggered image.load events from bubbling to window.load
3240 noBubble: true
3241 },
3242 click: {
3243 // For checkbox, fire native event so checked state will be right
3244 trigger: function() {
3245 if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
3246 this.click();
3247 return false;
3248 }
3249 }
3250 },
3251 focus: {
3252 // Fire native event if possible so blur/focus sequence is correct
3253 trigger: function() {
3254 if ( this !== document.activeElement && this.focus ) {
3255 try {
3256 this.focus();
3257 return false;
3258 } catch ( e ) {
3259 // Support: IE<9
3260 // If we error on focus to hidden element (#1486, #12518),
3261 // let .trigger() run the handlers
3262 }
3263 }
3264 },
3265 delegateType: "focusin"
3266 },
3267 blur: {
3268 trigger: function() {
3269 if ( this === document.activeElement && this.blur ) {
3270 this.blur();
3271 return false;
3272 }
3273 },
3274 delegateType: "focusout"
3275 },
3276
3277 beforeunload: {
3278 postDispatch: function( event ) {
3279
3280 // Even when returnValue equals to undefined Firefox will still show alert
3281 if ( event.result !== undefined ) {
3282 event.originalEvent.returnValue = event.result;
3283 }
3284 }