2 * jQuery JavaScript Library v1.4
5 * Copyright 2010, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://docs.jquery.com/License
10 * http://sizzlejs.com/
11 * Copyright 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
14 * Date: Wed Jan 13 15:23:05 2010 -0500
16 (function( window, undefined ) {
18 // Define a local copy of jQuery
19 var jQuery = function( selector, context ) {
20 // The jQuery object is actually just the init constructor 'enhanced'
21 return new jQuery.fn.init( selector, context );
24 // Map over jQuery in case of overwrite
25 _jQuery = window.jQuery,
27 // Map over the $ in case of overwrite
30 // Use the correct document accordingly with window argument (sandbox)
31 document = window.document,
33 // A central reference to the root jQuery(document)
36 // A simple way to check for HTML strings or ID strings
37 // (both of which we optimize for)
38 quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
40 // Is it a simple selector
41 isSimple = /^.[^:#\[\.,]*$/,
43 // Check if a string has a non-whitespace character in it
46 // Used for trimming whitespace
47 rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
49 // Match a standalone tag
50 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
52 // Keep a UserAgent string for use with jQuery.browser
53 userAgent = navigator.userAgent,
55 // For matching the engine and version of the browser
58 // Has the ready events already been bound?
61 // The functions to execute on DOM ready
64 // The ready event handler
67 // Save a reference to some core methods
68 toString = Object.prototype.toString,
69 hasOwnProperty = Object.prototype.hasOwnProperty,
70 push = Array.prototype.push,
71 slice = Array.prototype.slice,
72 indexOf = Array.prototype.indexOf;
74 jQuery.fn = jQuery.prototype = {
75 init: function( selector, context ) {
76 var match, elem, ret, doc;
78 // Handle $(""), $(null), or $(undefined)
83 // Handle $(DOMElement)
84 if ( selector.nodeType ) {
85 this.context = this[0] = selector;
90 // Handle HTML strings
91 if ( typeof selector === "string" ) {
92 // Are we dealing with HTML string or an ID?
93 match = quickExpr.exec( selector );
95 // Verify a match, and that no context was specified for #id
96 if ( match && (match[1] || !context) ) {
98 // HANDLE: $(html) -> $(array)
100 doc = (context ? context.ownerDocument || context : document);
102 // If a single string is passed in and it's a single tag
103 // just do a createElement and skip the rest
104 ret = rsingleTag.exec( selector );
107 if ( jQuery.isPlainObject( context ) ) {
108 selector = [ document.createElement( ret[1] ) ];
109 jQuery.fn.attr.call( selector, context, true );
112 selector = [ doc.createElement( ret[1] ) ];
116 ret = buildFragment( [ match[1] ], [ doc ] );
117 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
122 elem = document.getElementById( match[2] );
125 // Handle the case where IE and Opera return items
126 // by name instead of ID
127 if ( elem.id !== match[2] ) {
128 return rootjQuery.find( selector );
131 // Otherwise, we inject the element directly into the jQuery object
136 this.context = document;
137 this.selector = selector;
142 } else if ( !context && /^\w+$/.test( selector ) ) {
143 this.selector = selector;
144 this.context = document;
145 selector = document.getElementsByTagName( selector );
147 // HANDLE: $(expr, $(...))
148 } else if ( !context || context.jquery ) {
149 return (context || rootjQuery).find( selector );
151 // HANDLE: $(expr, context)
152 // (which is just equivalent to: $(context).find(expr)
154 return jQuery( context ).find( selector );
157 // HANDLE: $(function)
158 // Shortcut for document ready
159 } else if ( jQuery.isFunction( selector ) ) {
160 return rootjQuery.ready( selector );
163 if (selector.selector !== undefined) {
164 this.selector = selector.selector;
165 this.context = selector.context;
168 return jQuery.isArray( selector ) ?
169 this.setArray( selector ) :
170 jQuery.makeArray( selector, this );
173 // Start with an empty selector
176 // The current version of jQuery being used
179 // The default length of a jQuery object is 0
182 // The number of elements contained in the matched element set
187 toArray: function() {
188 return slice.call( this, 0 );
191 // Get the Nth element in the matched element set OR
192 // Get the whole matched element set as a clean array
193 get: function( num ) {
196 // Return a 'clean' array
199 // Return just the object
200 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
203 // Take an array of elements and push it onto the stack
204 // (returning the new matched element set)
205 pushStack: function( elems, name, selector ) {
206 // Build a new jQuery matched element set
207 var ret = jQuery( elems || null );
209 // Add the old object onto the stack (as a reference)
210 ret.prevObject = this;
212 ret.context = this.context;
214 if ( name === "find" ) {
215 ret.selector = this.selector + (this.selector ? " " : "") + selector;
217 ret.selector = this.selector + "." + name + "(" + selector + ")";
220 // Return the newly-formed element set
224 // Force the current matched set of elements to become
225 // the specified array of elements (destroying the stack in the process)
226 // You should use pushStack() in order to do this, but maintain the stack
227 setArray: function( elems ) {
228 // Resetting the length to 0, then using the native Array push
229 // is a super-fast way to populate an object with array-like properties
231 push.apply( this, elems );
236 // Execute a callback for every element in the matched set.
237 // (You can seed the arguments with an array of args, but this is
238 // only used internally.)
239 each: function( callback, args ) {
240 return jQuery.each( this, callback, args );
243 ready: function( fn ) {
244 // Attach the listeners
247 // If the DOM is already ready
248 if ( jQuery.isReady ) {
249 // Execute the function immediately
250 fn.call( document, jQuery );
252 // Otherwise, remember the function for later
253 } else if ( readyList ) {
254 // Add the function to the wait list
255 readyList.push( fn );
264 this.slice( i, +i + 1 );
272 return this.eq( -1 );
276 return this.pushStack( slice.apply( this, arguments ),
277 "slice", slice.call(arguments).join(",") );
280 map: function( callback ) {
281 return this.pushStack( jQuery.map(this, function( elem, i ) {
282 return callback.call( elem, i, elem );
287 return this.prevObject || jQuery(null);
290 // For internal use only.
291 // Behaves like an Array's method, not like a jQuery method.
297 // Give the init function the jQuery prototype for later instantiation
298 jQuery.fn.init.prototype = jQuery.fn;
300 jQuery.extend = jQuery.fn.extend = function() {
301 // copy reference to target object
302 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
304 // Handle a deep copy situation
305 if ( typeof target === "boolean" ) {
307 target = arguments[1] || {};
308 // skip the boolean and the target
312 // Handle case when target is a string or something (possible in deep copy)
313 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
317 // extend jQuery itself if only one argument is passed
318 if ( length === i ) {
323 for ( ; i < length; i++ ) {
324 // Only deal with non-null/undefined values
325 if ( (options = arguments[ i ]) != null ) {
326 // Extend the base object
327 for ( name in options ) {
328 src = target[ name ];
329 copy = options[ name ];
331 // Prevent never-ending loop
332 if ( target === copy ) {
336 // Recurse if we're merging object literal values or arrays
337 if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
338 var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
339 : jQuery.isArray(copy) ? [] : {};
341 // Never move original objects, clone them
342 target[ name ] = jQuery.extend( deep, clone, copy );
344 // Don't bring in undefined values
345 } else if ( copy !== undefined ) {
346 target[ name ] = copy;
352 // Return the modified object
357 noConflict: function( deep ) {
361 window.jQuery = _jQuery;
367 // Is the DOM ready to be used? Set to true once it occurs.
370 // Handle when the DOM is ready
372 // Make sure that the DOM is not already loaded
373 if ( !jQuery.isReady ) {
374 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
375 if ( !document.body ) {
376 return setTimeout( jQuery.ready, 13 );
379 // Remember that the DOM is ready
380 jQuery.isReady = true;
382 // If there are functions bound, to execute
384 // Execute all of them
386 while ( (fn = readyList[ i++ ]) ) {
387 fn.call( document, jQuery );
390 // Reset the list of functions
394 // Trigger any bound ready events
395 if ( jQuery.fn.triggerHandler ) {
396 jQuery( document ).triggerHandler( "ready" );
401 bindReady: function() {
408 // Catch cases where $(document).ready() is called after the
409 // browser event has already occurred.
410 if ( document.readyState === "complete" ) {
411 return jQuery.ready();
414 // Mozilla, Opera and webkit nightlies currently support this event
415 if ( document.addEventListener ) {
416 // Use the handy event callback
417 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
419 // A fallback to window.onload, that will always work
420 window.addEventListener( "load", jQuery.ready, false );
422 // If IE event model is used
423 } else if ( document.attachEvent ) {
424 // ensure firing before onload,
425 // maybe late but safe also for iframes
426 document.attachEvent("onreadystatechange", DOMContentLoaded);
428 // A fallback to window.onload, that will always work
429 window.attachEvent( "onload", jQuery.ready );
431 // If IE and not a frame
432 // continually check to see if the document is ready
433 var toplevel = false;
436 toplevel = window.frameElement == null;
439 if ( document.documentElement.doScroll && toplevel ) {
445 // See test/unit/core.js for details concerning isFunction.
446 // Since version 1.3, DOM methods and functions like alert
447 // aren't supported. They return false on IE (#2968).
448 isFunction: function( obj ) {
449 return toString.call(obj) === "[object Function]";
452 isArray: function( obj ) {
453 return toString.call(obj) === "[object Array]";
456 isPlainObject: function( obj ) {
457 // Must be an Object.
458 // Because of IE, we also have to check the presence of the constructor property.
459 // Make sure that DOM nodes and window objects don't pass through, as well
460 if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
464 // Not own constructor property must be Object
466 && !hasOwnProperty.call(obj, "constructor")
467 && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
471 // Own properties are enumerated firstly, so to speed up,
472 // if last one is own, then all properties are own.
475 for ( key in obj ) {}
477 return key === undefined || hasOwnProperty.call( obj, key );
480 isEmptyObject: function( obj ) {
481 for ( var name in obj ) {
489 // Evalulates a script in a global context
490 globalEval: function( data ) {
491 if ( data && rnotwhite.test(data) ) {
492 // Inspired by code by Andrea Giammarchi
493 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
494 var head = document.getElementsByTagName("head")[0] || document.documentElement,
495 script = document.createElement("script");
497 script.type = "text/javascript";
499 if ( jQuery.support.scriptEval ) {
500 script.appendChild( document.createTextNode( data ) );
505 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
506 // This arises when a base node is used (#2709).
507 head.insertBefore( script, head.firstChild );
508 head.removeChild( script );
512 nodeName: function( elem, name ) {
513 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
516 // args is for internal usage only
517 each: function( object, callback, args ) {
519 length = object.length,
520 isObj = length === undefined || jQuery.isFunction(object);
524 for ( name in object ) {
525 if ( callback.apply( object[ name ], args ) === false ) {
530 for ( ; i < length; ) {
531 if ( callback.apply( object[ i++ ], args ) === false ) {
537 // A special, fast, case for the most common use of each
540 for ( name in object ) {
541 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
546 for ( var value = object[0];
547 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
554 trim: function( text ) {
555 return (text || "").replace( rtrim, "" );
558 // results is for internal usage only
559 makeArray: function( array, results ) {
560 var ret = results || [];
562 if ( array != null ) {
563 // The window, strings (and functions) also have 'length'
564 // The extra typeof function check is to prevent crashes
565 // in Safari 2 (See: #3039)
566 if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
567 push.call( ret, array );
569 jQuery.merge( ret, array );
576 inArray: function( elem, array ) {
577 if ( array.indexOf ) {
578 return array.indexOf( elem );
581 for ( var i = 0, length = array.length; i < length; i++ ) {
582 if ( array[ i ] === elem ) {
590 merge: function( first, second ) {
591 var i = first.length, j = 0;
593 if ( typeof second.length === "number" ) {
594 for ( var l = second.length; j < l; j++ ) {
595 first[ i++ ] = second[ j ];
598 while ( second[j] !== undefined ) {
599 first[ i++ ] = second[ j++ ];
608 grep: function( elems, callback, inv ) {
611 // Go through the array, only saving the items
612 // that pass the validator function
613 for ( var i = 0, length = elems.length; i < length; i++ ) {
614 if ( !inv !== !callback( elems[ i ], i ) ) {
615 ret.push( elems[ i ] );
622 // arg is for internal usage only
623 map: function( elems, callback, arg ) {
626 // Go through the array, translating each of the items to their
627 // new value (or values).
628 for ( var i = 0, length = elems.length; i < length; i++ ) {
629 value = callback( elems[ i ], i, arg );
631 if ( value != null ) {
632 ret[ ret.length ] = value;
636 return ret.concat.apply( [], ret );
639 // A global GUID counter for objects
642 proxy: function( fn, proxy, thisObject ) {
643 if ( arguments.length === 2 ) {
644 if ( typeof proxy === "string" ) {
646 fn = thisObject[ proxy ];
649 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
655 if ( !proxy && fn ) {
657 return fn.apply( thisObject || this, arguments );
661 // Set the guid of unique handler to the same of original handler, so it can be removed
663 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
666 // So proxy can be declared as an argument
670 // Use of jQuery.browser is frowned upon.
671 // More details: http://docs.jquery.com/Utilities/jQuery.browser
672 uaMatch: function( ua ) {
673 var ret = { browser: "" };
675 ua = ua.toLowerCase();
677 if ( /webkit/.test( ua ) ) {
678 ret = { browser: "webkit", version: /webkit[\/ ]([\w.]+)/ };
680 } else if ( /opera/.test( ua ) ) {
681 ret = { browser: "opera", version: /version/.test( ua ) ? /version[\/ ]([\w.]+)/ : /opera[\/ ]([\w.]+)/ };
683 } else if ( /msie/.test( ua ) ) {
684 ret = { browser: "msie", version: /msie ([\w.]+)/ };
686 } else if ( /mozilla/.test( ua ) && !/compatible/.test( ua ) ) {
687 ret = { browser: "mozilla", version: /rv:([\w.]+)/ };
690 ret.version = (ret.version && ret.version.exec( ua ) || [0, "0"])[1];
698 browserMatch = jQuery.uaMatch( userAgent );
699 if ( browserMatch.browser ) {
700 jQuery.browser[ browserMatch.browser ] = true;
701 jQuery.browser.version = browserMatch.version;
704 // Deprecated, use jQuery.browser.webkit instead
705 if ( jQuery.browser.webkit ) {
706 jQuery.browser.safari = true;
710 jQuery.inArray = function( elem, array ) {
711 return indexOf.call( array, elem );
715 // All jQuery objects should point back to these
716 rootjQuery = jQuery(document);
718 // Cleanup functions for the document ready method
719 if ( document.addEventListener ) {
720 DOMContentLoaded = function() {
721 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
725 } else if ( document.attachEvent ) {
726 DOMContentLoaded = function() {
727 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
728 if ( document.readyState === "complete" ) {
729 document.detachEvent( "onreadystatechange", DOMContentLoaded );
735 // The DOM ready check for Internet Explorer
736 function doScrollCheck() {
737 if ( jQuery.isReady ) {
742 // If IE is used, use the trick by Diego Perini
743 // http://javascript.nwbox.com/IEContentLoaded/
744 document.documentElement.doScroll("left");
746 setTimeout( doScrollCheck, 1 );
750 // and execute any waiting functions
755 jQuery.inArray = function( elem, array ) {
756 return indexOf.call( array, elem );
760 function evalScript( i, elem ) {
768 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
771 if ( elem.parentNode ) {
772 elem.parentNode.removeChild( elem );
776 // Mutifunctional method to get and set values to a collection
777 // The value/s can be optionally by executed if its a function
778 function access( elems, key, value, exec, fn, pass ) {
779 var length = elems.length;
781 // Setting many attributes
782 if ( typeof key === "object" ) {
783 for ( var k in key ) {
784 access( elems, k, key[k], exec, fn, value );
789 // Setting one attribute
790 if ( value !== undefined ) {
791 // Optionally, function values get executed if exec is true
792 exec = !pass && exec && jQuery.isFunction(value);
794 for ( var i = 0; i < length; i++ ) {
795 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
801 // Getting an attribute
802 return length ? fn( elems[0], key ) : null;
806 return (new Date).getTime();
812 var root = document.documentElement,
813 script = document.createElement("script"),
814 div = document.createElement("div"),
815 id = "script" + now();
817 div.style.display = "none";
818 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
820 var all = div.getElementsByTagName("*"),
821 a = div.getElementsByTagName("a")[0];
823 // Can't get basic test support
824 if ( !all || !all.length || !a ) {
829 // IE strips leading whitespace when .innerHTML is used
830 leadingWhitespace: div.firstChild.nodeType === 3,
832 // Make sure that tbody elements aren't automatically inserted
833 // IE will insert them into empty tables
834 tbody: !div.getElementsByTagName("tbody").length,
836 // Make sure that link elements get serialized correctly by innerHTML
837 // This requires a wrapper element in IE
838 htmlSerialize: !!div.getElementsByTagName("link").length,
840 // Get the style information from getAttribute
841 // (IE uses .cssText insted)
842 style: /red/.test( a.getAttribute("style") ),
844 // Make sure that URLs aren't manipulated
845 // (IE normalizes it by default)
846 hrefNormalized: a.getAttribute("href") === "/a",
848 // Make sure that element opacity exists
849 // (IE uses filter instead)
850 // Use a regex to work around a WebKit issue. See #5145
851 opacity: /^0.55$/.test( a.style.opacity ),
853 // Verify style float existence
854 // (IE uses styleFloat instead of cssFloat)
855 cssFloat: !!a.style.cssFloat,
857 // Make sure that if no value is specified for a checkbox
858 // that it defaults to "on".
859 // (WebKit defaults to "" instead)
860 checkOn: div.getElementsByTagName("input")[0].value === "on",
862 // Make sure that a selected-by-default option has a working selected property.
863 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
864 optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
866 // Will be defined later
872 script.type = "text/javascript";
874 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
877 root.insertBefore( script, root.firstChild );
879 // Make sure that the execution of code works by injecting a script
880 // tag with appendChild/createTextNode
881 // (IE doesn't support this, fails, and uses .text instead)
882 if ( window[ id ] ) {
883 jQuery.support.scriptEval = true;
887 root.removeChild( script );
889 if ( div.attachEvent && div.fireEvent ) {
890 div.attachEvent("onclick", function click() {
891 // Cloning a node shouldn't copy over any
892 // bound event handlers (IE does this)
893 jQuery.support.noCloneEvent = false;
894 div.detachEvent("onclick", click);
896 div.cloneNode(true).fireEvent("onclick");
899 // Figure out if the W3C box model works as expected
900 // document.body must exist before we can do this
901 // TODO: This timeout is temporary until I move ready into core.js.
903 var div = document.createElement("div");
904 div.style.width = div.style.paddingLeft = "1px";
906 document.body.appendChild( div );
907 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
908 document.body.removeChild( div ).style.display = 'none';
912 // Technique from Juriy Zaytsev
913 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
914 var eventSupported = function( eventName ) {
915 var el = document.createElement("div");
916 eventName = "on" + eventName;
918 var isSupported = (eventName in el);
919 if ( !isSupported ) {
920 el.setAttribute(eventName, "return;");
921 isSupported = typeof el[eventName] === "function";
928 jQuery.support.submitBubbles = eventSupported("submit");
929 jQuery.support.changeBubbles = eventSupported("change");
931 // release memory in IE
932 root = script = div = all = a = null;
937 "class": "className",
938 readonly: "readOnly",
939 maxlength: "maxLength",
940 cellspacing: "cellSpacing",
943 tabindex: "tabIndex",
945 frameborder: "frameBorder"
947 var expando = "jQuery" + now(), uuid = 0, windowData = {};
948 var emptyObject = {};
955 // The following elements throw uncatchable exceptions if you
956 // attempt to add expando properties to them.
963 data: function( elem, name, data ) {
964 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
968 elem = elem == window ?
972 var id = elem[ expando ], cache = jQuery.cache, thisCache;
974 // Handle the case where there's no name immediately
975 if ( !name && !id ) {
979 // Compute a unique ID for the element
984 // Avoid generating a new cache unless none exists and we
985 // want to manipulate it.
986 if ( typeof name === "object" ) {
987 elem[ expando ] = id;
988 thisCache = cache[ id ] = jQuery.extend(true, {}, name);
989 } else if ( cache[ id ] ) {
990 thisCache = cache[ id ];
991 } else if ( typeof data === "undefined" ) {
992 thisCache = emptyObject;
994 thisCache = cache[ id ] = {};
997 // Prevent overriding the named cache with undefined values
998 if ( data !== undefined ) {
999 elem[ expando ] = id;
1000 thisCache[ name ] = data;
1003 return typeof name === "string" ? thisCache[ name ] : thisCache;
1006 removeData: function( elem, name ) {
1007 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
1011 elem = elem == window ?
1015 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
1017 // If we want to remove a specific section of the element's data
1020 // Remove the section of cache data
1021 delete thisCache[ name ];
1023 // If we've removed all the data, remove the element's cache
1024 if ( jQuery.isEmptyObject(thisCache) ) {
1025 jQuery.removeData( elem );
1029 // Otherwise, we want to remove all of the element's data
1031 // Clean up the element expando
1033 delete elem[ expando ];
1035 // IE has trouble directly removing the expando
1036 // but it's ok with using removeAttribute
1037 if ( elem.removeAttribute ) {
1038 elem.removeAttribute( expando );
1042 // Completely remove the data cache
1049 data: function( key, value ) {
1050 if ( typeof key === "undefined" && this.length ) {
1051 return jQuery.data( this[0] );
1053 } else if ( typeof key === "object" ) {
1054 return this.each(function() {
1055 jQuery.data( this, key );
1059 var parts = key.split(".");
1060 parts[1] = parts[1] ? "." + parts[1] : "";
1062 if ( value === undefined ) {
1063 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1065 if ( data === undefined && this.length ) {
1066 data = jQuery.data( this[0], key );
1068 return data === undefined && parts[1] ?
1069 this.data( parts[0] ) :
1072 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
1073 jQuery.data( this, key, value );
1078 removeData: function( key ) {
1079 return this.each(function() {
1080 jQuery.removeData( this, key );
1085 queue: function( elem, type, data ) {
1090 type = (type || "fx") + "queue";
1091 var q = jQuery.data( elem, type );
1093 // Speed up dequeue by getting out quickly if this is just a lookup
1098 if ( !q || jQuery.isArray(data) ) {
1099 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1108 dequeue: function( elem, type ) {
1109 type = type || "fx";
1111 var queue = jQuery.queue( elem, type ), fn = queue.shift();
1113 // If the fx queue is dequeued, always remove the progress sentinel
1114 if ( fn === "inprogress" ) {
1119 // Add a progress sentinel to prevent the fx queue from being
1120 // automatically dequeued
1121 if ( type === "fx" ) {
1122 queue.unshift("inprogress");
1125 fn.call(elem, function() {
1126 jQuery.dequeue(elem, type);
1133 queue: function( type, data ) {
1134 if ( typeof type !== "string" ) {
1139 if ( data === undefined ) {
1140 return jQuery.queue( this[0], type );
1142 return this.each(function( i, elem ) {
1143 var queue = jQuery.queue( this, type, data );
1145 if ( type === "fx" && queue[0] !== "inprogress" ) {
1146 jQuery.dequeue( this, type );
1150 dequeue: function( type ) {
1151 return this.each(function() {
1152 jQuery.dequeue( this, type );
1156 // Based off of the plugin by Clint Helfers, with permission.
1157 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1158 delay: function( time, type ) {
1159 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1160 type = type || "fx";
1162 return this.queue( type, function() {
1164 setTimeout(function() {
1165 jQuery.dequeue( elem, type );
1170 clearQueue: function( type ) {
1171 return this.queue( type || "fx", [] );
1174 var rclass = /[\n\t]/g,
1177 rspecialurl = /href|src|style/,
1178 rtype = /(button|input)/i,
1179 rfocusable = /(button|input|object|select|textarea)/i,
1180 rclickable = /^(a|area)$/i,
1181 rradiocheck = /radio|checkbox/;
1184 attr: function( name, value ) {
1185 return access( this, name, value, true, jQuery.attr );
1188 removeAttr: function( name, fn ) {
1189 return this.each(function(){
1190 jQuery.attr( this, name, "" );
1191 if ( this.nodeType === 1 ) {
1192 this.removeAttribute( name );
1197 addClass: function( value ) {
1198 if ( jQuery.isFunction(value) ) {
1199 return this.each(function(i) {
1200 var self = jQuery(this);
1201 self.addClass( value.call(this, i, self.attr("class")) );
1205 if ( value && typeof value === "string" ) {
1206 var classNames = (value || "").split( rspace );
1208 for ( var i = 0, l = this.length; i < l; i++ ) {
1211 if ( elem.nodeType === 1 ) {
1212 if ( !elem.className ) {
1213 elem.className = value;
1216 var className = " " + elem.className + " ";
1217 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1218 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1219 elem.className += " " + classNames[c];
1230 removeClass: function( value ) {
1231 if ( jQuery.isFunction(value) ) {
1232 return this.each(function(i) {
1233 var self = jQuery(this);
1234 self.removeClass( value.call(this, i, self.attr("class")) );
1238 if ( (value && typeof value === "string") || value === undefined ) {
1239 var classNames = (value || "").split(rspace);
1241 for ( var i = 0, l = this.length; i < l; i++ ) {
1244 if ( elem.nodeType === 1 && elem.className ) {
1246 var className = (" " + elem.className + " ").replace(rclass, " ");
1247 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1248 className = className.replace(" " + classNames[c] + " ", " ");
1250 elem.className = className.substring(1, className.length - 1);
1253 elem.className = "";
1262 toggleClass: function( value, stateVal ) {
1263 var type = typeof value, isBool = typeof stateVal === "boolean";
1265 if ( jQuery.isFunction( value ) ) {
1266 return this.each(function(i) {
1267 var self = jQuery(this);
1268 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1272 return this.each(function() {
1273 if ( type === "string" ) {
1274 // toggle individual class names
1275 var className, i = 0, self = jQuery(this),
1277 classNames = value.split( rspace );
1279 while ( (className = classNames[ i++ ]) ) {
1280 // check each className given, space seperated list
1281 state = isBool ? state : !self.hasClass( className );
1282 self[ state ? "addClass" : "removeClass" ]( className );
1285 } else if ( type === "undefined" || type === "boolean" ) {
1286 if ( this.className ) {
1287 // store className if set
1288 jQuery.data( this, "__className__", this.className );
1291 // toggle whole className
1292 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1297 hasClass: function( selector ) {
1298 var className = " " + selector + " ";
1299 for ( var i = 0, l = this.length; i < l; i++ ) {
1300 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1308 val: function( value ) {
1309 if ( value === undefined ) {
1313 if ( jQuery.nodeName( elem, "option" ) ) {
1314 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
1317 // We need to handle select boxes special
1318 if ( jQuery.nodeName( elem, "select" ) ) {
1319 var index = elem.selectedIndex,
1321 options = elem.options,
1322 one = elem.type === "select-one";
1324 // Nothing was selected
1329 // Loop through all the selected options
1330 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1331 var option = options[ i ];
1333 if ( option.selected ) {
1334 // Get the specifc value for the option
1335 value = jQuery(option).val();
1337 // We don't need an array for one selects
1342 // Multi-Selects return an array
1343 values.push( value );
1350 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1351 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1352 return elem.getAttribute("value") === null ? "on" : elem.value;
1356 // Everything else, we just grab the value
1357 return (elem.value || "").replace(rreturn, "");
1364 var isFunction = jQuery.isFunction(value);
1366 return this.each(function(i) {
1367 var self = jQuery(this), val = value;
1369 if ( this.nodeType !== 1 ) {
1374 val = value.call(this, i, self.val());
1377 // Typecast each time if the value is a Function and the appended
1378 // value is therefore different each time.
1379 if ( typeof val === "number" ) {
1383 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1384 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1386 } else if ( jQuery.nodeName( this, "select" ) ) {
1387 var values = jQuery.makeArray(val);
1389 jQuery( "option", this ).each(function() {
1390 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1393 if ( !values.length ) {
1394 this.selectedIndex = -1;
1416 attr: function( elem, name, value, pass ) {
1417 // don't set attributes on text and comment nodes
1418 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1422 if ( pass && name in jQuery.attrFn ) {
1423 return jQuery(elem)[name](value);
1426 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1427 // Whether we are setting (or getting)
1428 set = value !== undefined;
1430 // Try to normalize/fix the name
1431 name = notxml && jQuery.props[ name ] || name;
1433 // Only do all the following if this is a node (faster for style)
1434 if ( elem.nodeType === 1 ) {
1435 // These attributes require special treatment
1436 var special = rspecialurl.test( name );
1438 // Safari mis-reports the default selected property of an option
1439 // Accessing the parent's selectedIndex property fixes it
1440 if ( name === "selected" && !jQuery.support.optSelected ) {
1441 var parent = elem.parentNode;
1443 parent.selectedIndex;
1445 // Make sure that it also works with optgroups, see #5701
1446 if ( parent.parentNode ) {
1447 parent.parentNode.selectedIndex;
1452 // If applicable, access the attribute via the DOM 0 way
1453 if ( name in elem && notxml && !special ) {
1455 // We can't allow the type property to be changed (since it causes problems in IE)
1456 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1457 throw "type property can't be changed";
1460 elem[ name ] = value;
1463 // browsers index elements by id/name on forms, give priority to attributes.
1464 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1465 return elem.getAttributeNode( name ).nodeValue;
1468 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1469 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1470 if ( name === "tabIndex" ) {
1471 var attributeNode = elem.getAttributeNode( "tabIndex" );
1473 return attributeNode && attributeNode.specified ?
1474 attributeNode.value :
1475 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1480 return elem[ name ];
1483 if ( !jQuery.support.style && notxml && name === "style" ) {
1485 elem.style.cssText = "" + value;
1488 return elem.style.cssText;
1492 // convert the value to a string (all browsers do this but IE) see #1070
1493 elem.setAttribute( name, "" + value );
1496 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1497 // Some attributes require a special call on IE
1498 elem.getAttribute( name, 2 ) :
1499 elem.getAttribute( name );
1501 // Non-existent attributes return null, we normalize to undefined
1502 return attr === null ? undefined : attr;
1505 // elem is actually elem.style ... set the style
1506 // Using attr for specific style information is now deprecated. Use style insead.
1507 return jQuery.style( elem, name, value );
1510 var fcleanup = function( nm ) {
1511 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
1517 * A number of helper functions used for managing events.
1518 * Many of the ideas behind this code originated from
1519 * Dean Edwards' addEvent library.
1523 // Bind an event to an element
1524 // Original by Dean Edwards
1525 add: function( elem, types, handler, data ) {
1526 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1530 // For whatever reason, IE has trouble passing the window object
1531 // around, causing it to be cloned in the process
1532 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
1536 // Make sure that the function being executed has a unique ID
1537 if ( !handler.guid ) {
1538 handler.guid = jQuery.guid++;
1541 // if data is passed, bind to handler
1542 if ( data !== undefined ) {
1543 // Create temporary function pointer to original handler
1546 // Create unique handler function, wrapped around original handler
1547 handler = jQuery.proxy( fn );
1549 // Store data in unique handler
1550 handler.data = data;
1553 // Init the element's event structure
1554 var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
1555 handle = jQuery.data( elem, "handle" ), eventHandle;
1558 eventHandle = function() {
1559 // Handle the second event of a trigger and when
1560 // an event is called after a page has unloaded
1561 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1562 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1566 handle = jQuery.data( elem, "handle", eventHandle );
1569 // If no handle is found then we must be trying to bind to one of the
1570 // banned noData elements
1575 // Add elem as a property of the handle function
1576 // This is to prevent a memory leak with non-native
1580 // Handle multiple events separated by a space
1581 // jQuery(...).bind("mouseover mouseout", fn);
1582 types = types.split( /\s+/ );
1584 while ( (type = types[ i++ ]) ) {
1585 // Namespaced event handlers
1586 var namespaces = type.split(".");
1587 type = namespaces.shift();
1588 handler.type = namespaces.slice(0).sort().join(".");
1590 // Get the current list of functions bound to this event
1591 var handlers = events[ type ],
1592 special = this.special[ type ] || {};
1596 // Init the event handler queue
1598 handlers = events[ type ] = {};
1600 // Check for a special event handler
1601 // Only use addEventListener/attachEvent if the special
1602 // events handler returns false
1603 if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
1604 // Bind the global event handler to the element
1605 if ( elem.addEventListener ) {
1606 elem.addEventListener( type, handle, false );
1607 } else if ( elem.attachEvent ) {
1608 elem.attachEvent( "on" + type, handle );
1613 if ( special.add ) {
1614 var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
1615 if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
1616 modifiedHandler.guid = modifiedHandler.guid || handler.guid;
1617 handler = modifiedHandler;
1621 // Add the function to the element's handler list
1622 handlers[ handler.guid ] = handler;
1624 // Keep track of which events have been used, for global triggering
1625 this.global[ type ] = true;
1628 // Nullify elem to prevent memory leaks in IE
1634 // Detach an event or set of events from an element
1635 remove: function( elem, types, handler ) {
1636 // don't do events on text and comment nodes
1637 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1641 var events = jQuery.data( elem, "events" ), ret, type, fn;
1644 // Unbind all events for the element
1645 if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
1646 for ( type in events ) {
1647 this.remove( elem, type + (types || "") );
1650 // types is actually an event object here
1652 handler = types.handler;
1656 // Handle multiple events separated by a space
1657 // jQuery(...).unbind("mouseover mouseout", fn);
1658 types = types.split(/\s+/);
1660 while ( (type = types[ i++ ]) ) {
1661 // Namespaced event handlers
1662 var namespaces = type.split(".");
1663 type = namespaces.shift();
1664 var all = !namespaces.length,
1665 cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ),
1666 namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"),
1667 special = this.special[ type ] || {};
1669 if ( events[ type ] ) {
1670 // remove the given handler for the given type
1672 fn = events[ type ][ handler.guid ];
1673 delete events[ type ][ handler.guid ];
1675 // remove all handlers for the given type
1677 for ( var handle in events[ type ] ) {
1678 // Handle the removal of namespaced events
1679 if ( all || namespace.test( events[ type ][ handle ].type ) ) {
1680 delete events[ type ][ handle ];
1685 if ( special.remove ) {
1686 special.remove.call( elem, namespaces, fn);
1689 // remove generic event handler if no more handlers exist
1690 for ( ret in events[ type ] ) {
1694 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
1695 if ( elem.removeEventListener ) {
1696 elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
1697 } else if ( elem.detachEvent ) {
1698 elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
1702 delete events[ type ];
1708 // Remove the expando if it's no longer used
1709 for ( ret in events ) {
1713 var handle = jQuery.data( elem, "handle" );
1717 jQuery.removeData( elem, "events" );
1718 jQuery.removeData( elem, "handle" );
1723 // bubbling is internal
1724 trigger: function( event, data, elem /*, bubbling */ ) {
1725 // Event object or event type
1726 var type = event.type || event,
1727 bubbling = arguments[3];
1730 event = typeof event === "object" ?
1731 // jQuery.Event object
1732 event[expando] ? event :
1734 jQuery.extend( jQuery.Event(type), event ) :
1735 // Just the event type (string)
1738 if ( type.indexOf("!") >= 0 ) {
1739 event.type = type = type.slice(0, -1);
1740 event.exclusive = true;
1743 // Handle a global trigger
1745 // Don't bubble custom events when global (to avoid too much overhead)
1746 event.stopPropagation();
1748 // Only trigger if we've ever bound an event for it
1749 if ( this.global[ type ] ) {
1750 jQuery.each( jQuery.cache, function() {
1751 if ( this.events && this.events[type] ) {
1752 jQuery.event.trigger( event, data, this.handle.elem );
1758 // Handle triggering a single element
1760 // don't do events on text and comment nodes
1761 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1765 // Clean up in case it is reused
1766 event.result = undefined;
1767 event.target = elem;
1769 // Clone the incoming data, if any
1770 data = jQuery.makeArray( data );
1771 data.unshift( event );
1774 event.currentTarget = elem;
1776 // Trigger the event, it is assumed that "handle" is a function
1777 var handle = jQuery.data( elem, "handle" );
1779 handle.apply( elem, data );
1782 var nativeFn, nativeHandler;
1784 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
1785 nativeFn = elem[ type ];
1786 nativeHandler = elem[ "on" + type ];
1788 // prevent IE from throwing an error for some elements with some event types, see #3533
1791 var isClick = jQuery.nodeName(elem, "a") && type === "click";
1793 // Trigger the native events (except for clicks on links)
1794 if ( !bubbling && nativeFn && !event.isDefaultPrevented() && !isClick ) {
1795 this.triggered = true;
1798 // prevent IE from throwing an error for some hidden elements
1801 // Handle triggering native .onfoo handlers
1802 } else if ( nativeHandler && elem[ "on" + type ].apply( elem, data ) === false ) {
1803 event.result = false;
1806 this.triggered = false;
1808 if ( !event.isPropagationStopped() ) {
1809 var parent = elem.parentNode || elem.ownerDocument;
1811 jQuery.event.trigger( event, data, parent, true );
1816 handle: function( event ) {
1817 // returned undefined or false
1820 event = arguments[0] = jQuery.event.fix( event || window.event );
1821 event.currentTarget = this;
1823 // Namespaced event handlers
1824 var namespaces = event.type.split(".");
1825 event.type = namespaces.shift();
1827 // Cache this now, all = true means, any handler
1828 all = !namespaces.length && !event.exclusive;
1830 var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
1832 handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
1834 for ( var j in handlers ) {
1835 var handler = handlers[ j ];
1837 // Filter the functions by class
1838 if ( all || namespace.test(handler.type) ) {
1839 // Pass in a reference to the handler function itself
1840 // So that we can later remove it
1841 event.handler = handler;
1842 event.data = handler.data;
1844 var ret = handler.apply( this, arguments );
1846 if ( ret !== undefined ) {
1848 if ( ret === false ) {
1849 event.preventDefault();
1850 event.stopPropagation();
1854 if ( event.isImmediatePropagationStopped() ) {
1861 return event.result;
1864 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
1866 fix: function( event ) {
1867 if ( event[ expando ] ) {
1871 // store a copy of the original event object
1872 // and "clone" to set read-only properties
1873 var originalEvent = event;
1874 event = jQuery.Event( originalEvent );
1876 for ( var i = this.props.length, prop; i; ) {
1877 prop = this.props[ --i ];
1878 event[ prop ] = originalEvent[ prop ];
1881 // Fix target property, if necessary
1882 if ( !event.target ) {
1883 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
1886 // check if target is a textnode (safari)
1887 if ( event.target.nodeType === 3 ) {
1888 event.target = event.target.parentNode;
1891 // Add relatedTarget, if necessary
1892 if ( !event.relatedTarget && event.fromElement ) {
1893 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
1896 // Calculate pageX/Y if missing and clientX/Y available
1897 if ( event.pageX == null && event.clientX != null ) {
1898 var doc = document.documentElement, body = document.body;
1899 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
1900 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
1903 // Add which for key events
1904 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
1905 event.which = event.charCode || event.keyCode;
1908 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
1909 if ( !event.metaKey && event.ctrlKey ) {
1910 event.metaKey = event.ctrlKey;
1913 // Add which for click: 1 === left; 2 === middle; 3 === right
1914 // Note: button is not normalized, so don't use it
1915 if ( !event.which && event.button !== undefined ) {
1916 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
1922 // Deprecated, use jQuery.guid instead
1925 // Deprecated, use jQuery.proxy instead
1926 proxy: jQuery.proxy,
1930 // Make sure the ready event is setup
1931 setup: jQuery.bindReady,
1932 teardown: jQuery.noop
1936 add: function( proxy, data, namespaces, live ) {
1937 jQuery.extend( proxy, data || {} );
1939 proxy.guid += data.selector + data.live;
1940 jQuery.event.add( this, data.live, liveHandler, data );
1944 remove: function( namespaces ) {
1945 if ( namespaces.length ) {
1946 var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
1948 jQuery.each( (jQuery.data(this, "events").live || {}), function() {
1949 if ( name.test(this.type) ) {
1955 jQuery.event.remove( this, namespaces[0], liveHandler );
1962 setup: function( data, namespaces, fn ) {
1963 // We only want to do this special case on windows
1964 if ( this.setInterval ) {
1965 this.onbeforeunload = fn;
1970 teardown: function( namespaces, fn ) {
1971 if ( this.onbeforeunload === fn ) {
1972 this.onbeforeunload = null;
1979 jQuery.Event = function( src ) {
1980 // Allow instantiation without the 'new' keyword
1981 if ( !this.preventDefault ) {
1982 return new jQuery.Event( src );
1986 if ( src && src.type ) {
1987 this.originalEvent = src;
1988 this.type = src.type;
1994 // timeStamp is buggy for some events on Firefox(#3843)
1995 // So we won't rely on the native value
1996 this.timeStamp = now();
1999 this[ expando ] = true;
2002 function returnFalse() {
2005 function returnTrue() {
2009 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2010 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2011 jQuery.Event.prototype = {
2012 preventDefault: function() {
2013 this.isDefaultPrevented = returnTrue;
2015 var e = this.originalEvent;
2020 // if preventDefault exists run it on the original event
2021 if ( e.preventDefault ) {
2024 // otherwise set the returnValue property of the original event to false (IE)
2025 e.returnValue = false;
2027 stopPropagation: function() {
2028 this.isPropagationStopped = returnTrue;
2030 var e = this.originalEvent;
2034 // if stopPropagation exists run it on the original event
2035 if ( e.stopPropagation ) {
2036 e.stopPropagation();
2038 // otherwise set the cancelBubble property of the original event to true (IE)
2039 e.cancelBubble = true;
2041 stopImmediatePropagation: function() {
2042 this.isImmediatePropagationStopped = returnTrue;
2043 this.stopPropagation();
2045 isDefaultPrevented: returnFalse,
2046 isPropagationStopped: returnFalse,
2047 isImmediatePropagationStopped: returnFalse
2050 // Checks if an event happened on an element within another element
2051 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2052 var withinElement = function( event ) {
2053 // Check if mouse(over|out) are still within the same parent element
2054 var parent = event.relatedTarget;
2056 // Traverse up the tree
2057 while ( parent && parent !== this ) {
2058 // Firefox sometimes assigns relatedTarget a XUL element
2059 // which we cannot access the parentNode property of
2061 parent = parent.parentNode;
2063 // assuming we've left the element since we most likely mousedover a xul element
2069 if ( parent !== this ) {
2070 // set the correct event type
2071 event.type = event.data;
2073 // handle event if we actually just moused on to a non sub-element
2074 jQuery.event.handle.apply( this, arguments );
2079 // In case of event delegation, we only need to rename the event.type,
2080 // liveHandler will take care of the rest.
2081 delegate = function( event ) {
2082 event.type = event.data;
2083 jQuery.event.handle.apply( this, arguments );
2086 // Create mouseenter and mouseleave events
2088 mouseenter: "mouseover",
2089 mouseleave: "mouseout"
2090 }, function( orig, fix ) {
2091 jQuery.event.special[ orig ] = {
2092 setup: function( data ) {
2093 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2095 teardown: function( data ) {
2096 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2101 // submit delegation
2102 if ( !jQuery.support.submitBubbles ) {
2104 jQuery.event.special.submit = {
2105 setup: function( data, namespaces, fn ) {
2106 if ( this.nodeName.toLowerCase() !== "form" ) {
2107 jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) {
2108 var elem = e.target, type = elem.type;
2110 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2111 return trigger( "submit", this, arguments );
2115 jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) {
2116 var elem = e.target, type = elem.type;
2118 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2119 return trigger( "submit", this, arguments );
2128 remove: function( namespaces, fn ) {
2129 jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") );
2130 jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") );
2136 // change delegation, happens here so we have bind.
2137 if ( !jQuery.support.changeBubbles ) {
2139 var formElems = /textarea|input|select/i;
2141 function getVal( elem ) {
2142 var type = elem.type, val = elem.value;
2144 if ( type === "radio" || type === "checkbox" ) {
2147 } else if ( type === "select-multiple" ) {
2148 val = elem.selectedIndex > -1 ?
2149 jQuery.map( elem.options, function( elem ) {
2150 return elem.selected;
2154 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2155 val = elem.selectedIndex;
2161 function testChange( e ) {
2162 var elem = e.target, data, val;
2164 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
2168 data = jQuery.data( elem, "_change_data" );
2171 if ( val === data ) {
2175 // the current data will be also retrieved by beforeactivate
2176 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2177 jQuery.data( elem, "_change_data", val );
2180 if ( elem.type !== "select" && (data != null || val) ) {
2182 return jQuery.event.trigger( e, arguments[1], this );
2186 jQuery.event.special.change = {
2188 focusout: testChange,
2190 click: function( e ) {
2191 var elem = e.target, type = elem.type;
2193 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2194 return testChange.call( this, e );
2198 // Change has to be called before submit
2199 // Keydown will be called before keypress, which is used in submit-event delegation
2200 keydown: function( e ) {
2201 var elem = e.target, type = elem.type;
2203 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2204 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2205 type === "select-multiple" ) {
2206 return testChange.call( this, e );
2210 // Beforeactivate happens also before the previous element is blurred
2211 // with this event you can't trigger a change event, but you can store
2212 // information/focus[in] is not needed anymore
2213 beforeactivate: function( e ) {
2214 var elem = e.target;
2216 if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) {
2217 jQuery.data( elem, "_change_data", getVal(elem) );
2221 setup: function( data, namespaces, fn ) {
2222 for ( var type in changeFilters ) {
2223 jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] );
2226 return formElems.test( this.nodeName );
2228 remove: function( namespaces, fn ) {
2229 for ( var type in changeFilters ) {
2230 jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] );
2233 return formElems.test( this.nodeName );
2237 var changeFilters = jQuery.event.special.change.filters;
2241 function trigger( type, elem, args ) {
2242 args[0].type = type;
2243 return jQuery.event.handle.apply( elem, args );
2246 // Create "bubbling" focus and blur events
2247 if ( document.addEventListener ) {
2248 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2249 jQuery.event.special[ fix ] = {
2251 this.addEventListener( orig, handler, true );
2253 teardown: function() {
2254 this.removeEventListener( orig, handler, true );
2258 function handler( e ) {
2259 e = jQuery.event.fix( e );
2261 return jQuery.event.handle.call( this, e );
2266 jQuery.each(["bind", "one"], function( i, name ) {
2267 jQuery.fn[ name ] = function( type, data, fn ) {
2268 // Handle object literals
2269 if ( typeof type === "object" ) {
2270 for ( var key in type ) {
2271 this[ name ](key, data, type[key], fn);
2276 if ( jQuery.isFunction( data ) ) {
2282 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2283 jQuery( this ).unbind( event, handler );
2284 return fn.apply( this, arguments );
2287 return type === "unload" && name !== "one" ?
2288 this.one( type, data, fn, thisObject ) :
2289 this.each(function() {
2290 jQuery.event.add( this, type, handler, data );
2296 unbind: function( type, fn ) {
2297 // Handle object literals
2298 if ( typeof type === "object" && !type.preventDefault ) {
2299 for ( var key in type ) {
2300 this.unbind(key, type[key]);
2305 return this.each(function() {
2306 jQuery.event.remove( this, type, fn );
2309 trigger: function( type, data ) {
2310 return this.each(function() {
2311 jQuery.event.trigger( type, data, this );
2315 triggerHandler: function( type, data ) {
2317 var event = jQuery.Event( type );
2318 event.preventDefault();
2319 event.stopPropagation();
2320 jQuery.event.trigger( event, data, this[0] );
2321 return event.result;
2325 toggle: function( fn ) {
2326 // Save reference to arguments for access in closure
2327 var args = arguments, i = 1;
2329 // link all the functions, so any of them can unbind this click handler
2330 while ( i < args.length ) {
2331 jQuery.proxy( fn, args[ i++ ] );
2334 return this.click( jQuery.proxy( fn, function( event ) {
2335 // Figure out which function to execute
2336 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2337 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2339 // Make sure that clicks stop
2340 event.preventDefault();
2342 // and execute the function
2343 return args[ lastToggle ].apply( this, arguments ) || false;
2347 hover: function( fnOver, fnOut ) {
2348 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2351 live: function( type, data, fn ) {
2352 if ( jQuery.isFunction( data ) ) {
2357 jQuery( this.context ).bind( liveConvert( type, this.selector ), {
2358 data: data, selector: this.selector, live: type
2364 die: function( type, fn ) {
2365 jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
2370 function liveHandler( event ) {
2371 var stop = true, elems = [], selectors = [], args = arguments,
2372 related, match, fn, elem, j, i, data,
2373 live = jQuery.extend({}, jQuery.data( this, "events" ).live);
2377 if ( fn.live === event.type ||
2378 fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) {
2381 if ( !(data.beforeFilter && data.beforeFilter[event.type] &&
2382 !data.beforeFilter[event.type](event)) ) {
2383 selectors.push( fn.selector );
2390 match = jQuery( event.target ).closest( selectors, event.currentTarget );
2392 for ( i = 0, l = match.length; i < l; i++ ) {
2395 elem = match[i].elem;
2398 if ( match[i].selector === fn.selector ) {
2399 // Those two events require additional checking
2400 if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) {
2401 related = jQuery( event.relatedTarget ).closest( fn.selector )[0];
2404 if ( !related || related !== elem ) {
2405 elems.push({ elem: elem, fn: fn });
2411 for ( i = 0, l = elems.length; i < l; i++ ) {
2413 event.currentTarget = match.elem;
2414 event.data = match.fn.data;
2415 if ( match.fn.apply( match.elem, args ) === false ) {
2424 function liveConvert( type, selector ) {
2425 return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "&")].join(".");
2428 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2429 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2430 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2432 // Handle event binding
2433 jQuery.fn[ name ] = function( fn ) {
2434 return fn ? this.bind( name, fn ) : this.trigger( name );
2437 if ( jQuery.attrFn ) {
2438 jQuery.attrFn[ name ] = true;
2442 // Prevent memory leaks in IE
2443 // Window isn't included so as not to unbind existing unload events
2445 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2446 if ( window.attachEvent && !window.addEventListener ) {
2447 window.attachEvent("onunload", function() {
2448 for ( var id in jQuery.cache ) {
2449 if ( jQuery.cache[ id ].handle ) {
2450 // Try/Catch is to handle iframes being unloaded, see #4280
2452 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2459 * Sizzle CSS Selector Engine - v1.0
2460 * Copyright 2009, The Dojo Foundation
2461 * Released under the MIT, BSD, and GPL Licenses.
2462 * More information: http://sizzlejs.com/
2466 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
2468 toString = Object.prototype.toString,
2469 hasDuplicate = false,
2470 baseHasDuplicate = true;
2472 // Here we check if the JavaScript engine is using some sort of
2473 // optimization where it does not always call our comparision
2474 // function. If that is the case, discard the hasDuplicate value.
2475 // Thus far that includes Google Chrome.
2476 [0, 0].sort(function(){
2477 baseHasDuplicate = false;
2481 var Sizzle = function(selector, context, results, seed) {
2482 results = results || [];
2483 var origContext = context = context || document;
2485 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
2489 if ( !selector || typeof selector !== "string" ) {
2493 var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
2496 // Reset the position of the chunker regexp (start from head)
2497 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
2508 if ( parts.length > 1 && origPOS.exec( selector ) ) {
2509 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
2510 set = posProcess( parts[0] + parts[1], context );
2512 set = Expr.relative[ parts[0] ] ?
2514 Sizzle( parts.shift(), context );
2516 while ( parts.length ) {
2517 selector = parts.shift();
2519 if ( Expr.relative[ selector ] ) {
2520 selector += parts.shift();
2523 set = posProcess( selector, set );
2527 // Take a shortcut and set the context if the root selector is an ID
2528 // (but not if it'll be faster if the inner selector is an ID)
2529 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
2530 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
2531 var ret = Sizzle.find( parts.shift(), context, contextXML );
2532 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
2537 { expr: parts.pop(), set: makeArray(seed) } :
2538 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
2539 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
2541 if ( parts.length > 0 ) {
2542 checkSet = makeArray(set);
2547 while ( parts.length ) {
2548 var cur = parts.pop(), pop = cur;
2550 if ( !Expr.relative[ cur ] ) {
2556 if ( pop == null ) {
2560 Expr.relative[ cur ]( checkSet, pop, contextXML );
2563 checkSet = parts = [];
2572 throw "Syntax error, unrecognized expression: " + (cur || selector);
2575 if ( toString.call(checkSet) === "[object Array]" ) {
2577 results.push.apply( results, checkSet );
2578 } else if ( context && context.nodeType === 1 ) {
2579 for ( var i = 0; checkSet[i] != null; i++ ) {
2580 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
2581 results.push( set[i] );
2585 for ( var i = 0; checkSet[i] != null; i++ ) {
2586 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
2587 results.push( set[i] );
2592 makeArray( checkSet, results );
2596 Sizzle( extra, origContext, results, seed );
2597 Sizzle.uniqueSort( results );
2603 Sizzle.uniqueSort = function(results){
2605 hasDuplicate = baseHasDuplicate;
2606 results.sort(sortOrder);
2608 if ( hasDuplicate ) {
2609 for ( var i = 1; i < results.length; i++ ) {
2610 if ( results[i] === results[i-1] ) {
2611 results.splice(i--, 1);
2620 Sizzle.matches = function(expr, set){
2621 return Sizzle(expr, null, null, set);
2624 Sizzle.find = function(expr, context, isXML){
2631 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
2632 var type = Expr.order[i], match;
2634 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
2635 var left = match[1];
2638 if ( left.substr( left.length - 1 ) !== "\\" ) {
2639 match[1] = (match[1] || "").replace(/\\/g, "");
2640 set = Expr.find[ type ]( match, context, isXML );
2641 if ( set != null ) {
2642 expr = expr.replace( Expr.match[ type ], "" );
2650 set = context.getElementsByTagName("*");
2653 return {set: set, expr: expr};
2656 Sizzle.filter = function(expr, set, inplace, not){
2657 var old = expr, result = [], curLoop = set, match, anyFound,
2658 isXMLFilter = set && set[0] && isXML(set[0]);
2660 while ( expr && set.length ) {
2661 for ( var type in Expr.filter ) {
2662 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
2663 var filter = Expr.filter[ type ], found, item, left = match[1];
2668 if ( left.substr( left.length - 1 ) === "\\" ) {
2672 if ( curLoop === result ) {
2676 if ( Expr.preFilter[ type ] ) {
2677 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
2680 anyFound = found = true;
2681 } else if ( match === true ) {
2687 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
2689 found = filter( item, match, i, curLoop );
2690 var pass = not ^ !!found;
2692 if ( inplace && found != null ) {
2698 } else if ( pass ) {
2699 result.push( item );
2706 if ( found !== undefined ) {
2711 expr = expr.replace( Expr.match[ type ], "" );
2722 // Improper expression
2723 if ( expr === old ) {
2724 if ( anyFound == null ) {
2725 throw "Syntax error, unrecognized expression: " + expr;
2737 var Expr = Sizzle.selectors = {
2738 order: [ "ID", "NAME", "TAG" ],
2740 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
2741 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
2742 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
2743 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
2744 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
2745 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
2746 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
2747 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
2751 "class": "className",
2755 href: function(elem){
2756 return elem.getAttribute("href");
2760 "+": function(checkSet, part){
2761 var isPartStr = typeof part === "string",
2762 isTag = isPartStr && !/\W/.test(part),
2763 isPartStrNotTag = isPartStr && !isTag;
2766 part = part.toLowerCase();
2769 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
2770 if ( (elem = checkSet[i]) ) {
2771 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
2773 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
2779 if ( isPartStrNotTag ) {
2780 Sizzle.filter( part, checkSet, true );
2783 ">": function(checkSet, part){
2784 var isPartStr = typeof part === "string";
2786 if ( isPartStr && !/\W/.test(part) ) {
2787 part = part.toLowerCase();
2789 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2790 var elem = checkSet[i];
2792 var parent = elem.parentNode;
2793 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
2797 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2798 var elem = checkSet[i];
2800 checkSet[i] = isPartStr ?
2802 elem.parentNode === part;
2807 Sizzle.filter( part, checkSet, true );
2811 "": function(checkSet, part, isXML){
2812 var doneName = done++, checkFn = dirCheck;
2814 if ( typeof part === "string" && !/\W/.test(part) ) {
2815 var nodeCheck = part = part.toLowerCase();
2816 checkFn = dirNodeCheck;
2819 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
2821 "~": function(checkSet, part, isXML){
2822 var doneName = done++, checkFn = dirCheck;
2824 if ( typeof part === "string" && !/\W/.test(part) ) {
2825 var nodeCheck = part = part.toLowerCase();
2826 checkFn = dirNodeCheck;
2829 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
2833 ID: function(match, context, isXML){
2834 if ( typeof context.getElementById !== "undefined" && !isXML ) {
2835 var m = context.getElementById(match[1]);
2836 return m ? [m] : [];
2839 NAME: function(match, context){
2840 if ( typeof context.getElementsByName !== "undefined" ) {
2841 var ret = [], results = context.getElementsByName(match[1]);
2843 for ( var i = 0, l = results.length; i < l; i++ ) {
2844 if ( results[i].getAttribute("name") === match[1] ) {
2845 ret.push( results[i] );
2849 return ret.length === 0 ? null : ret;
2852 TAG: function(match, context){
2853 return context.getElementsByTagName(match[1]);
2857 CLASS: function(match, curLoop, inplace, result, not, isXML){
2858 match = " " + match[1].replace(/\\/g, "") + " ";
2864 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
2866 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
2868 result.push( elem );
2870 } else if ( inplace ) {
2878 ID: function(match){
2879 return match[1].replace(/\\/g, "");
2881 TAG: function(match, curLoop){
2882 return match[1].toLowerCase();
2884 CHILD: function(match){
2885 if ( match[1] === "nth" ) {
2886 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
2887 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
2888 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
2889 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
2891 // calculate the numbers (first)n+(last) including if they are negative
2892 match[2] = (test[1] + (test[2] || 1)) - 0;
2893 match[3] = test[3] - 0;
2896 // TODO: Move to normal caching system
2901 ATTR: function(match, curLoop, inplace, result, not, isXML){
2902 var name = match[1].replace(/\\/g, "");
2904 if ( !isXML && Expr.attrMap[name] ) {
2905 match[1] = Expr.attrMap[name];
2908 if ( match[2] === "~=" ) {
2909 match[4] = " " + match[4] + " ";
2914 PSEUDO: function(match, curLoop, inplace, result, not){
2915 if ( match[1] === "not" ) {
2916 // If we're dealing with a complex expression, or a simple one
2917 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
2918 match[3] = Sizzle(match[3], null, null, curLoop);
2920 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
2922 result.push.apply( result, ret );
2926 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
2932 POS: function(match){
2933 match.unshift( true );
2938 enabled: function(elem){
2939 return elem.disabled === false && elem.type !== "hidden";
2941 disabled: function(elem){
2942 return elem.disabled === true;
2944 checked: function(elem){
2945 return elem.checked === true;
2947 selected: function(elem){
2948 // Accessing this property makes selected-by-default
2949 // options in Safari work properly
2950 elem.parentNode.selectedIndex;
2951 return elem.selected === true;
2953 parent: function(elem){
2954 return !!elem.firstChild;
2956 empty: function(elem){
2957 return !elem.firstChild;
2959 has: function(elem, i, match){
2960 return !!Sizzle( match[3], elem ).length;
2962 header: function(elem){
2963 return /h\d/i.test( elem.nodeName );
2965 text: function(elem){
2966 return "text" === elem.type;
2968 radio: function(elem){
2969 return "radio" === elem.type;
2971 checkbox: function(elem){
2972 return "checkbox" === elem.type;
2974 file: function(elem){
2975 return "file" === elem.type;
2977 password: function(elem){
2978 return "password" === elem.type;
2980 submit: function(elem){
2981 return "submit" === elem.type;
2983 image: function(elem){
2984 return "image" === elem.type;
2986 reset: function(elem){
2987 return "reset" === elem.type;
2989 button: function(elem){
2990 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
2992 input: function(elem){
2993 return /input|select|textarea|button/i.test(elem.nodeName);
2997 first: function(elem, i){
3000 last: function(elem, i, match, array){
3001 return i === array.length - 1;
3003 even: function(elem, i){
3006 odd: function(elem, i){
3009 lt: function(elem, i, match){
3010 return i < match[3] - 0;
3012 gt: function(elem, i, match){
3013 return i > match[3] - 0;
3015 nth: function(elem, i, match){
3016 return match[3] - 0 === i;
3018 eq: function(elem, i, match){
3019 return match[3] - 0 === i;
3023 PSEUDO: function(elem, match, i, array){
3024 var name = match[1], filter = Expr.filters[ name ];
3027 return filter( elem, i, match, array );
3028 } else if ( name === "contains" ) {
3029 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
3030 } else if ( name === "not" ) {
3033 for ( var i = 0, l = not.length; i < l; i++ ) {
3034 if ( not[i] === elem ) {
3041 throw "Syntax error, unrecognized expression: " + name;
3044 CHILD: function(elem, match){
3045 var type = match[1], node = elem;
3049 while ( (node = node.previousSibling) ) {
3050 if ( node.nodeType === 1 ) {
3054 if ( type === "first" ) {
3059 while ( (node = node.nextSibling) ) {
3060 if ( node.nodeType === 1 ) {
3066 var first = match[2], last = match[3];
3068 if ( first === 1 && last === 0 ) {
3072 var doneName = match[0],
3073 parent = elem.parentNode;
3075 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3077 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3078 if ( node.nodeType === 1 ) {
3079 node.nodeIndex = ++count;
3082 parent.sizcache = doneName;
3085 var diff = elem.nodeIndex - last;
3086 if ( first === 0 ) {
3089 return ( diff % first === 0 && diff / first >= 0 );
3093 ID: function(elem, match){
3094 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3096 TAG: function(elem, match){
3097 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3099 CLASS: function(elem, match){
3100 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3101 .indexOf( match ) > -1;
3103 ATTR: function(elem, match){
3104 var name = match[1],
3105 result = Expr.attrHandle[ name ] ?
3106 Expr.attrHandle[ name ]( elem ) :
3107 elem[ name ] != null ?
3109 elem.getAttribute( name ),
3110 value = result + "",
3114 return result == null ?
3119 value.indexOf(check) >= 0 :
3121 (" " + value + " ").indexOf(check) >= 0 :
3123 value && result !== false :
3127 value.indexOf(check) === 0 :
3129 value.substr(value.length - check.length) === check :
3131 value === check || value.substr(0, check.length + 1) === check + "-" :
3134 POS: function(elem, match, i, array){
3135 var name = match[2], filter = Expr.setFilters[ name ];
3138 return filter( elem, i, match, array );
3144 var origPOS = Expr.match.POS;
3146 for ( var type in Expr.match ) {
3147 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
3148 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
3149 return "\\" + (num - 0 + 1);
3153 var makeArray = function(array, results) {
3154 array = Array.prototype.slice.call( array, 0 );
3157 results.push.apply( results, array );
3164 // Perform a simple check to determine if the browser is capable of
3165 // converting a NodeList to an array using builtin methods.
3167 Array.prototype.slice.call( document.documentElement.childNodes, 0 );
3169 // Provide a fallback method if it does not work
3171 makeArray = function(array, results) {
3172 var ret = results || [];
3174 if ( toString.call(array) === "[object Array]" ) {
3175 Array.prototype.push.apply( ret, array );
3177 if ( typeof array.length === "number" ) {
3178 for ( var i = 0, l = array.length; i < l; i++ ) {
3179 ret.push( array[i] );
3182 for ( var i = 0; array[i]; i++ ) {
3183 ret.push( array[i] );
3194 if ( document.documentElement.compareDocumentPosition ) {
3195 sortOrder = function( a, b ) {
3196 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3198 hasDuplicate = true;
3200 return a.compareDocumentPosition ? -1 : 1;
3203 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
3205 hasDuplicate = true;
3209 } else if ( "sourceIndex" in document.documentElement ) {
3210 sortOrder = function( a, b ) {
3211 if ( !a.sourceIndex || !b.sourceIndex ) {
3213 hasDuplicate = true;
3215 return a.sourceIndex ? -1 : 1;
3218 var ret = a.sourceIndex - b.sourceIndex;
3220 hasDuplicate = true;
3224 } else if ( document.createRange ) {
3225 sortOrder = function( a, b ) {
3226 if ( !a.ownerDocument || !b.ownerDocument ) {
3228 hasDuplicate = true;
3230 return a.ownerDocument ? -1 : 1;
3233 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
3234 aRange.setStart(a, 0);
3235 aRange.setEnd(a, 0);
3236 bRange.setStart(b, 0);
3237 bRange.setEnd(b, 0);
3238 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
3240 hasDuplicate = true;
3246 // Utility function for retreiving the text value of an array of DOM nodes
3247 function getText( elems ) {
3250 for ( var i = 0; elems[i]; i++ ) {
3253 // Get the text from text nodes and CDATA nodes
3254 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3255 ret += elem.nodeValue;
3257 // Traverse everything else, except comment nodes
3258 } else if ( elem.nodeType !== 8 ) {
3259 ret += getText( elem.childNodes );
3266 // Check to see if the browser returns elements by name when
3267 // querying by getElementById (and provide a workaround)
3269 // We're going to inject a fake input element with a specified name
3270 var form = document.createElement("div"),
3271 id = "script" + (new Date).getTime();
3272 form.innerHTML = "<a name='" + id + "'/>";
3274 // Inject it into the root element, check its status, and remove it quickly
3275 var root = document.documentElement;
3276 root.insertBefore( form, root.firstChild );
3278 // The workaround has to do additional checks after a getElementById
3279 // Which slows things down for other browsers (hence the branching)
3280 if ( document.getElementById( id ) ) {
3281 Expr.find.ID = function(match, context, isXML){
3282 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3283 var m = context.getElementById(match[1]);
3284 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
3288 Expr.filter.ID = function(elem, match){
3289 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
3290 return elem.nodeType === 1 && node && node.nodeValue === match;
3294 root.removeChild( form );
3295 root = form = null; // release memory in IE
3299 // Check to see if the browser returns only elements
3300 // when doing getElementsByTagName("*")
3302 // Create a fake element
3303 var div = document.createElement("div");
3304 div.appendChild( document.createComment("") );
3306 // Make sure no comments are found
3307 if ( div.getElementsByTagName("*").length > 0 ) {
3308 Expr.find.TAG = function(match, context){
3309 var results = context.getElementsByTagName(match[1]);
3311 // Filter out possible comments
3312 if ( match[1] === "*" ) {
3315 for ( var i = 0; results[i]; i++ ) {
3316 if ( results[i].nodeType === 1 ) {
3317 tmp.push( results[i] );
3328 // Check to see if an attribute returns normalized href attributes
3329 div.innerHTML = "<a href='#'></a>";
3330 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
3331 div.firstChild.getAttribute("href") !== "#" ) {
3332 Expr.attrHandle.href = function(elem){
3333 return elem.getAttribute("href", 2);
3337 div = null; // release memory in IE
3340 if ( document.querySelectorAll ) {
3342 var oldSizzle = Sizzle, div = document.createElement("div");
3343 div.innerHTML = "<p class='TEST'></p>";
3345 // Safari can't handle uppercase or unicode characters when
3347 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
3351 Sizzle = function(query, context, extra, seed){
3352 context = context || document;
3354 // Only use querySelectorAll on non-XML documents
3355 // (ID selectors don't work in non-HTML documents)
3356 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
3358 return makeArray( context.querySelectorAll(query), extra );
3362 return oldSizzle(query, context, extra, seed);
3365 for ( var prop in oldSizzle ) {
3366 Sizzle[ prop ] = oldSizzle[ prop ];
3369 div = null; // release memory in IE
3374 var div = document.createElement("div");
3376 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
3378 // Opera can't find a second classname (in 9.6)
3379 // Also, make sure that getElementsByClassName actually exists
3380 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
3384 // Safari caches class attributes, doesn't catch changes (in 3.2)
3385 div.lastChild.className = "e";
3387 if ( div.getElementsByClassName("e").length === 1 ) {
3391 Expr.order.splice(1, 0, "CLASS");
3392 Expr.find.CLASS = function(match, context, isXML) {
3393 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
3394 return context.getElementsByClassName(match[1]);
3398 div = null; // release memory in IE
3401 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
3402 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
3403 var elem = checkSet[i];
3409 if ( elem.sizcache === doneName ) {
3410 match = checkSet[elem.sizset];
3414 if ( elem.nodeType === 1 && !isXML ){
3415 elem.sizcache = doneName;
3419 if ( elem.nodeName.toLowerCase() === cur ) {
3427 checkSet[i] = match;
3432 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
3433 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
3434 var elem = checkSet[i];
3440 if ( elem.sizcache === doneName ) {
3441 match = checkSet[elem.sizset];
3445 if ( elem.nodeType === 1 ) {
3447 elem.sizcache = doneName;
3450 if ( typeof cur !== "string" ) {
3451 if ( elem === cur ) {
3456 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
3465 checkSet[i] = match;
3470 var contains = document.compareDocumentPosition ? function(a, b){
3471 return a.compareDocumentPosition(b) & 16;
3473 return a !== b && (a.contains ? a.contains(b) : true);
3476 var isXML = function(elem){
3477 // documentElement is verified for cases where it doesn't yet exist
3478 // (such as loading iframes in IE - #4833)
3479 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
3480 return documentElement ? documentElement.nodeName !== "HTML" : false;
3483 var posProcess = function(selector, context){
3484 var tmpSet = [], later = "", match,
3485 root = context.nodeType ? [context] : context;
3487 // Position selectors must be done after the filter
3488 // And so must :not(positional) so we move all PSEUDOs to the end
3489 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
3491 selector = selector.replace( Expr.match.PSEUDO, "" );
3494 selector = Expr.relative[selector] ? selector + "*" : selector;
3496 for ( var i = 0, l = root.length; i < l; i++ ) {
3497 Sizzle( selector, root[i], tmpSet );
3500 return Sizzle.filter( later, tmpSet );
3504 jQuery.find = Sizzle;
3505 jQuery.expr = Sizzle.selectors;
3506 jQuery.expr[":"] = jQuery.expr.filters;
3507 jQuery.unique = Sizzle.uniqueSort;
3508 jQuery.getText = getText;
3509 jQuery.isXMLDoc = isXML;
3510 jQuery.contains = contains;
3514 window.Sizzle = Sizzle;
3517 var runtil = /Until$/,
3518 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
3519 // Note: This RegExp should be improved, or likely pulled from Sizzle
3520 rmultiselector = /,/,
3521 slice = Array.prototype.slice;
3523 // Implement the identical functionality for filter and not
3524 var winnow = function( elements, qualifier, keep ) {
3525 if ( jQuery.isFunction( qualifier ) ) {
3526 return jQuery.grep(elements, function( elem, i ) {
3527 return !!qualifier.call( elem, i, elem ) === keep;
3530 } else if ( qualifier.nodeType ) {
3531 return jQuery.grep(elements, function( elem, i ) {
3532 return (elem === qualifier) === keep;
3535 } else if ( typeof qualifier === "string" ) {
3536 var filtered = jQuery.grep(elements, function( elem ) {
3537 return elem.nodeType === 1;
3540 if ( isSimple.test( qualifier ) ) {
3541 return jQuery.filter(qualifier, filtered, !keep);
3543 qualifier = jQuery.filter( qualifier, elements );
3547 return jQuery.grep(elements, function( elem, i ) {
3548 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
3553 find: function( selector ) {
3554 var ret = this.pushStack( "", "find", selector ), length = 0;
3556 for ( var i = 0, l = this.length; i < l; i++ ) {
3557 length = ret.length;
3558 jQuery.find( selector, this[i], ret );
3561 // Make sure that the results are unique
3562 for ( var n = length; n < ret.length; n++ ) {
3563 for ( var r = 0; r < length; r++ ) {
3564 if ( ret[r] === ret[n] ) {
3576 has: function( target ) {
3577 var targets = jQuery( target );
3578 return this.filter(function() {
3579 for ( var i = 0, l = targets.length; i < l; i++ ) {
3580 if ( jQuery.contains( this, targets[i] ) ) {
3587 not: function( selector ) {
3588 return this.pushStack( winnow(this, selector, false), "not", selector);
3591 filter: function( selector ) {
3592 return this.pushStack( winnow(this, selector, true), "filter", selector );
3595 is: function( selector ) {
3596 return !!selector && jQuery.filter( selector, this ).length > 0;
3599 closest: function( selectors, context ) {
3600 if ( jQuery.isArray( selectors ) ) {
3601 var ret = [], cur = this[0], match, matches = {}, selector;
3603 if ( cur && selectors.length ) {
3604 for ( var i = 0, l = selectors.length; i < l; i++ ) {
3605 selector = selectors[i];
3607 if ( !matches[selector] ) {
3608 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
3609 jQuery( selector, context || this.context ) :
3614 while ( cur && cur.ownerDocument && cur !== context ) {
3615 for ( selector in matches ) {
3616 match = matches[selector];
3618 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
3619 ret.push({ selector: selector, elem: cur });
3620 delete matches[selector];
3623 cur = cur.parentNode;
3630 var pos = jQuery.expr.match.POS.test( selectors ) ?
3631 jQuery( selectors, context || this.context ) : null;
3633 return this.map(function( i, cur ) {
3634 while ( cur && cur.ownerDocument && cur !== context ) {
3635 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
3638 cur = cur.parentNode;
3644 // Determine the position of an element within
3645 // the matched set of elements
3646 index: function( elem ) {
3647 if ( !elem || typeof elem === "string" ) {
3648 return jQuery.inArray( this[0],
3649 // If it receives a string, the selector is used
3650 // If it receives nothing, the siblings are used
3651 elem ? jQuery( elem ) : this.parent().children() );
3653 // Locate the position of the desired element
3654 return jQuery.inArray(
3655 // If it receives a jQuery object, the first element is used
3656 elem.jquery ? elem[0] : elem, this );
3659 add: function( selector, context ) {
3660 var set = typeof selector === "string" ?
3661 jQuery( selector, context || this.context ) :
3662 jQuery.makeArray( selector ),
3663 all = jQuery.merge( this.get(), set );
3665 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
3667 jQuery.unique( all ) );
3670 andSelf: function() {
3671 return this.add( this.prevObject );
3675 // A painfully simple check to see if an element is disconnected
3676 // from a document (should be improved, where feasible).
3677 function isDisconnected( node ) {
3678 return !node || !node.parentNode || node.parentNode.nodeType === 11;
3682 parent: function( elem ) {
3683 var parent = elem.parentNode;
3684 return parent && parent.nodeType !== 11 ? parent : null;
3686 parents: function( elem ) {
3687 return jQuery.dir( elem, "parentNode" );
3689 parentsUntil: function( elem, i, until ) {
3690 return jQuery.dir( elem, "parentNode", until );
3692 next: function( elem ) {
3693 return jQuery.nth( elem, 2, "nextSibling" );
3695 prev: function( elem ) {
3696 return jQuery.nth( elem, 2, "previousSibling" );
3698 nextAll: function( elem ) {
3699 return jQuery.dir( elem, "nextSibling" );
3701 prevAll: function( elem ) {
3702 return jQuery.dir( elem, "previousSibling" );
3704 nextUntil: function( elem, i, until ) {
3705 return jQuery.dir( elem, "nextSibling", until );
3707 prevUntil: function( elem, i, until ) {
3708 return jQuery.dir( elem, "previousSibling", until );
3710 siblings: function( elem ) {
3711 return jQuery.sibling( elem.parentNode.firstChild, elem );
3713 children: function( elem ) {
3714 return jQuery.sibling( elem.firstChild );
3716 contents: function( elem ) {
3717 return jQuery.nodeName( elem, "iframe" ) ?
3718 elem.contentDocument || elem.contentWindow.document :
3719 jQuery.makeArray( elem.childNodes );
3721 }, function( name, fn ) {
3722 jQuery.fn[ name ] = function( until, selector ) {
3723 var ret = jQuery.map( this, fn, until );
3725 if ( !runtil.test( name ) ) {
3729 if ( selector && typeof selector === "string" ) {
3730 ret = jQuery.filter( selector, ret );
3733 ret = this.length > 1 ? jQuery.unique( ret ) : ret;
3735 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
3736 ret = ret.reverse();
3739 return this.pushStack( ret, name, slice.call(arguments).join(",") );
3744 filter: function( expr, elems, not ) {
3746 expr = ":not(" + expr + ")";
3749 return jQuery.find.matches(expr, elems);
3752 dir: function( elem, dir, until ) {
3753 var matched = [], cur = elem[dir];
3754 while ( cur && cur.nodeType !== 9 && (until === undefined || !jQuery( cur ).is( until )) ) {
3755 if ( cur.nodeType === 1 ) {
3756 matched.push( cur );
3763 nth: function( cur, result, dir, elem ) {
3764 result = result || 1;
3767 for ( ; cur; cur = cur[dir] ) {
3768 if ( cur.nodeType === 1 && ++num === result ) {
3776 sibling: function( n, elem ) {
3779 for ( ; n; n = n.nextSibling ) {
3780 if ( n.nodeType === 1 && n !== elem ) {
3788 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
3789 rleadingWhitespace = /^\s+/,
3790 rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
3791 rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
3792 rtagName = /<([\w:]+)/,
3795 fcloseTag = function( all, front, tag ) {
3796 return rselfClosing.test( tag ) ?
3798 front + "></" + tag + ">";
3801 option: [ 1, "<select multiple='multiple'>", "</select>" ],
3802 legend: [ 1, "<fieldset>", "</fieldset>" ],
3803 thead: [ 1, "<table>", "</table>" ],
3804 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
3805 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
3806 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
3807 area: [ 1, "<map>", "</map>" ],
3808 _default: [ 0, "", "" ]
3811 wrapMap.optgroup = wrapMap.option;
3812 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
3813 wrapMap.th = wrapMap.td;
3815 // IE can't serialize <link> and <script> tags normally
3816 if ( !jQuery.support.htmlSerialize ) {
3817 wrapMap._default = [ 1, "div<div>", "</div>" ];
3821 text: function( text ) {
3822 if ( jQuery.isFunction(text) ) {
3823 return this.each(function(i) {
3824 var self = jQuery(this);
3825 return self.text( text.call(this, i, self.text()) );
3829 if ( typeof text !== "object" && text !== undefined ) {
3830 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
3833 return jQuery.getText( this );
3836 wrapAll: function( html ) {
3837 if ( jQuery.isFunction( html ) ) {
3838 return this.each(function(i) {
3839 jQuery(this).wrapAll( html.call(this, i) );
3844 // The elements to wrap the target around
3845 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
3847 if ( this[0].parentNode ) {
3848 wrap.insertBefore( this[0] );
3851 wrap.map(function() {
3854 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
3855 elem = elem.firstChild;
3865 wrapInner: function( html ) {
3866 return this.each(function() {
3867 var self = jQuery( this ), contents = self.contents();
3869 if ( contents.length ) {
3870 contents.wrapAll( html );
3873 self.append( html );
3878 wrap: function( html ) {
3879 return this.each(function() {
3880 jQuery( this ).wrapAll( html );
3884 unwrap: function() {
3885 return this.parent().each(function() {
3886 if ( !jQuery.nodeName( this, "body" ) ) {
3887 jQuery( this ).replaceWith( this.childNodes );
3892 append: function() {
3893 return this.domManip(arguments, true, function( elem ) {
3894 if ( this.nodeType === 1 ) {
3895 this.appendChild( elem );
3900 prepend: function() {
3901 return this.domManip(arguments, true, function( elem ) {
3902 if ( this.nodeType === 1 ) {
3903 this.insertBefore( elem, this.firstChild );
3908 before: function() {
3909 if ( this[0] && this[0].parentNode ) {
3910 return this.domManip(arguments, false, function( elem ) {
3911 this.parentNode.insertBefore( elem, this );
3913 } else if ( arguments.length ) {
3914 var set = jQuery(arguments[0]);
3915 set.push.apply( set, this.toArray() );
3916 return this.pushStack( set, "before", arguments );
3921 if ( this[0] && this[0].parentNode ) {
3922 return this.domManip(arguments, false, function( elem ) {
3923 this.parentNode.insertBefore( elem, this.nextSibling );
3925 } else if ( arguments.length ) {
3926 var set = this.pushStack( this, "after", arguments );
3927 set.push.apply( set, jQuery(arguments[0]).toArray() );
3932 clone: function( events ) {
3934 var ret = this.map(function() {
3935 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
3936 // IE copies events bound via attachEvent when
3937 // using cloneNode. Calling detachEvent on the
3938 // clone will also remove the events from the orignal
3939 // In order to get around this, we use innerHTML.
3940 // Unfortunately, this means some modifications to
3941 // attributes in IE that are actually only stored
3942 // as properties will not be copied (such as the
3943 // the name attribute on an input).
3944 var html = this.outerHTML, ownerDocument = this.ownerDocument;
3946 var div = ownerDocument.createElement("div");
3947 div.appendChild( this.cloneNode(true) );
3948 html = div.innerHTML;
3951 return jQuery.clean([html.replace(rinlinejQuery, "")
3952 .replace(rleadingWhitespace, "")], ownerDocument)[0];
3954 return this.cloneNode(true);
3958 // Copy the events from the original to the clone
3959 if ( events === true ) {
3960 cloneCopyEvent( this, ret );
3961 cloneCopyEvent( this.find("*"), ret.find("*") );
3964 // Return the cloned set
3968 html: function( value ) {
3969 if ( value === undefined ) {
3970 return this[0] && this[0].nodeType === 1 ?
3971 this[0].innerHTML.replace(rinlinejQuery, "") :
3974 // See if we can take a shortcut and just use innerHTML
3975 } else if ( typeof value === "string" && !/<script/i.test( value ) &&
3976 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
3977 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
3980 for ( var i = 0, l = this.length; i < l; i++ ) {
3981 // Remove element nodes and prevent memory leaks
3982 if ( this[i].nodeType === 1 ) {
3983 cleanData( this[i].getElementsByTagName("*") );
3984 this[i].innerHTML = value;
3988 // If using innerHTML throws an exception, use the fallback method
3990 this.empty().append( value );
3993 } else if ( jQuery.isFunction( value ) ) {
3994 this.each(function(i){
3995 var self = jQuery(this), old = self.html();
3996 self.empty().append(function(){
3997 return value.call( this, i, old );
4002 this.empty().append( value );
4008 replaceWith: function( value ) {
4009 if ( this[0] && this[0].parentNode ) {
4010 // Make sure that the elements are removed from the DOM before they are inserted
4011 // this can help fix replacing a parent with child elements
4012 if ( !jQuery.isFunction( value ) ) {
4013 value = jQuery( value ).detach();
4016 return this.each(function() {
4017 var next = this.nextSibling, parent = this.parentNode;
4019 jQuery(this).remove();
4022 jQuery(next).before( value );
4024 jQuery(parent).append( value );
4028 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4032 detach: function( selector ) {
4033 return this.remove( selector, true );
4036 domManip: function( args, table, callback ) {
4037 var results, first, value = args[0], scripts = [];
4039 if ( jQuery.isFunction(value) ) {
4040 return this.each(function(i) {
4041 var self = jQuery(this);
4042 args[0] = value.call(this, i, table ? self.html() : undefined);
4043 return self.domManip( args, table, callback );
4048 // If we're in a fragment, just use that instead of building a new one
4049 if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) {
4050 results = { fragment: args[0].parentNode };
4052 results = buildFragment( args, this, scripts );
4055 first = results.fragment.firstChild;
4058 table = table && jQuery.nodeName( first, "tr" );
4060 for ( var i = 0, l = this.length; i < l; i++ ) {
4063 root(this[i], first) :
4065 results.cacheable || this.length > 1 || i > 0 ?
4066 results.fragment.cloneNode(true) :
4073 jQuery.each( scripts, evalScript );
4079 function root( elem, cur ) {
4080 return jQuery.nodeName(elem, "table") ?
4081 (elem.getElementsByTagName("tbody")[0] ||
4082 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4088 function cloneCopyEvent(orig, ret) {
4091 ret.each(function() {
4092 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
4096 var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
4099 delete curData.handle;
4100 curData.events = {};
4102 for ( var type in events ) {
4103 for ( var handler in events[ type ] ) {
4104 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
4111 function buildFragment( args, nodes, scripts ) {
4112 var fragment, cacheable, cached, cacheresults, doc;
4114 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 ) {
4116 cacheresults = jQuery.fragments[ args[0] ];
4117 if ( cacheresults ) {
4118 if ( cacheresults !== 1 ) {
4119 fragment = cacheresults;
4126 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
4127 fragment = doc.createDocumentFragment();
4128 jQuery.clean( args, doc, fragment, scripts );
4132 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
4135 return { fragment: fragment, cacheable: cacheable };
4138 jQuery.fragments = {};
4142 prependTo: "prepend",
4143 insertBefore: "before",
4144 insertAfter: "after",
4145 replaceAll: "replaceWith"
4146 }, function( name, original ) {
4147 jQuery.fn[ name ] = function( selector ) {
4148 var ret = [], insert = jQuery( selector );
4150 for ( var i = 0, l = insert.length; i < l; i++ ) {
4151 var elems = (i > 0 ? this.clone(true) : this).get();
4152 jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
4153 ret = ret.concat( elems );
4155 return this.pushStack( ret, name, insert.selector );
4160 // keepData is for internal use only--do not document
4161 remove: function( selector, keepData ) {
4162 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
4163 if ( !keepData && this.nodeType === 1 ) {
4164 cleanData( this.getElementsByTagName("*") );
4165 cleanData( [ this ] );
4168 if ( this.parentNode ) {
4169 this.parentNode.removeChild( this );
4175 // Remove element nodes and prevent memory leaks
4176 if ( this.nodeType === 1 ) {
4177 cleanData( this.getElementsByTagName("*") );
4180 // Remove any remaining nodes
4181 while ( this.firstChild ) {
4182 this.removeChild( this.firstChild );
4185 }, function( name, fn ) {
4186 jQuery.fn[ name ] = function() {
4187 return this.each( fn, arguments );
4192 clean: function( elems, context, fragment, scripts ) {
4193 context = context || document;
4195 // !context.createElement fails in IE with an error but returns typeof 'object'
4196 if ( typeof context.createElement === "undefined" ) {
4197 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
4202 jQuery.each(elems, function( i, elem ) {
4203 if ( typeof elem === "number" ) {
4211 // Convert html string into DOM nodes
4212 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
4213 elem = context.createTextNode( elem );
4215 } else if ( typeof elem === "string" ) {
4216 // Fix "XHTML"-style tags in all browsers
4217 elem = elem.replace(rxhtmlTag, fcloseTag);
4219 // Trim whitespace, otherwise indexOf won't work as expected
4220 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
4221 wrap = wrapMap[ tag ] || wrapMap._default,
4223 div = context.createElement("div");
4225 // Go to html and back, then peel off extra wrappers
4226 div.innerHTML = wrap[1] + elem + wrap[2];
4228 // Move to the right depth
4230 div = div.lastChild;
4233 // Remove IE's autoinserted <tbody> from table fragments
4234 if ( !jQuery.support.tbody ) {
4236 // String was a <table>, *may* have spurious <tbody>
4237 var hasBody = rtbody.test(elem),
4238 tbody = tag === "table" && !hasBody ?
4239 div.firstChild && div.firstChild.childNodes :
4241 // String was a bare <thead> or <tfoot>
4242 wrap[1] === "<table>" && !hasBody ?
4246 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
4247 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
4248 tbody[ j ].parentNode.removeChild( tbody[ j ] );
4254 // IE completely kills leading whitespace when innerHTML is used
4255 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4256 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
4259 elem = jQuery.makeArray( div.childNodes );
4262 if ( elem.nodeType ) {
4265 ret = jQuery.merge( ret, elem );
4271 for ( var i = 0; ret[i]; i++ ) {
4272 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
4273 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
4275 if ( ret[i].nodeType === 1 ) {
4276 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
4278 fragment.appendChild( ret[i] );
4287 function cleanData( elems ) {
4288 for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) {
4289 if ( !jQuery.noData[elem.nodeName.toLowerCase()] && (id = elem[expando]) ) {
4290 delete jQuery.cache[ id ];
4294 // exclude the following css properties to add px
4295 var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
4296 ralpha = /alpha\([^)]*\)/,
4297 ropacity = /opacity=([^)]*)/,
4299 rdashAlpha = /-([a-z])/ig,
4300 rupper = /([A-Z])/g,
4301 rnumpx = /^-?\d+(?:px)?$/i,
4304 cssShow = { position: "absolute", visibility: "hidden", display:"block" },
4305 cssWidth = [ "Left", "Right" ],
4306 cssHeight = [ "Top", "Bottom" ],
4308 // cache check for defaultView.getComputedStyle
4309 getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
4310 // normalize float css property
4311 styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
4312 fcamelCase = function( all, letter ) {
4313 return letter.toUpperCase();
4316 jQuery.fn.css = function( name, value ) {
4317 return access( this, name, value, true, function( elem, name, value ) {
4318 if ( value === undefined ) {
4319 return jQuery.curCSS( elem, name );
4322 if ( typeof value === "number" && !rexclude.test(name) ) {
4326 jQuery.style( elem, name, value );
4331 style: function( elem, name, value ) {
4332 // don't set styles on text and comment nodes
4333 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
4337 // ignore negative width and height values #1599
4338 if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
4342 var style = elem.style || elem, set = value !== undefined;
4344 // IE uses filters for opacity
4345 if ( !jQuery.support.opacity && name === "opacity" ) {
4347 // IE has trouble with opacity if it does not have layout
4348 // Force it by setting the zoom level
4351 // Set the alpha filter to set the opacity
4352 var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
4353 var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
4354 style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
4357 return style.filter && style.filter.indexOf("opacity=") >= 0 ?
4358 (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
4362 // Make sure we're using the right name for getting the float value
4363 if ( rfloat.test( name ) ) {
4367 name = name.replace(rdashAlpha, fcamelCase);
4370 style[ name ] = value;
4373 return style[ name ];
4376 css: function( elem, name, force, extra ) {
4377 if ( name === "width" || name === "height" ) {
4378 var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
4381 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
4383 if ( extra === "border" ) {
4387 jQuery.each( which, function() {
4389 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
4392 if ( extra === "margin" ) {
4393 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
4395 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
4400 if ( elem.offsetWidth !== 0 ) {
4403 jQuery.swap( elem, props, getWH );
4406 return Math.max(0, Math.round(val));
4409 return jQuery.curCSS( elem, name, force );
4412 curCSS: function( elem, name, force ) {
4413 var ret, style = elem.style, filter;
4415 // IE uses filters for opacity
4416 if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
4417 ret = ropacity.test(elem.currentStyle.filter || "") ?
4418 (parseFloat(RegExp.$1) / 100) + "" :
4426 // Make sure we're using the right name for getting the float value
4427 if ( rfloat.test( name ) ) {
4431 if ( !force && style && style[ name ] ) {
4432 ret = style[ name ];
4434 } else if ( getComputedStyle ) {
4436 // Only "float" is needed here
4437 if ( rfloat.test( name ) ) {
4441 name = name.replace( rupper, "-$1" ).toLowerCase();
4443 var defaultView = elem.ownerDocument.defaultView;
4445 if ( !defaultView ) {
4449 var computedStyle = defaultView.getComputedStyle( elem, null );
4451 if ( computedStyle ) {
4452 ret = computedStyle.getPropertyValue( name );
4455 // We should always get a number back from opacity
4456 if ( name === "opacity" && ret === "" ) {
4460 } else if ( elem.currentStyle ) {
4461 var camelCase = name.replace(rdashAlpha, fcamelCase);
4463 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
4465 // From the awesome hack by Dean Edwards
4466 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
4468 // If we're not dealing with a regular pixel number
4469 // but a number that has a weird ending, we need to convert it to pixels
4470 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
4471 // Remember the original values
4472 var left = style.left, rsLeft = elem.runtimeStyle.left;
4474 // Put in the new values to get a computed value out
4475 elem.runtimeStyle.left = elem.currentStyle.left;
4476 style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
4477 ret = style.pixelLeft + "px";
4479 // Revert the changed values
4481 elem.runtimeStyle.left = rsLeft;
4488 // A method for quickly swapping in/out CSS properties to get correct calculations
4489 swap: function( elem, options, callback ) {
4492 // Remember the old values, and insert the new ones
4493 for ( var name in options ) {
4494 old[ name ] = elem.style[ name ];
4495 elem.style[ name ] = options[ name ];
4498 callback.call( elem );
4500 // Revert the old values
4501 for ( var name in options ) {
4502 elem.style[ name ] = old[ name ];
4507 if ( jQuery.expr && jQuery.expr.filters ) {
4508 jQuery.expr.filters.hidden = function( elem ) {
4509 var width = elem.offsetWidth, height = elem.offsetHeight,
4510 skip = elem.nodeName.toLowerCase() === "tr";
4512 return width === 0 && height === 0 && !skip ?
4514 width > 0 && height > 0 && !skip ?
4516 jQuery.curCSS(elem, "display") === "none";
4519 jQuery.expr.filters.visible = function( elem ) {
4520 return !jQuery.expr.filters.hidden( elem );
4524 rscript = /<script(.|\s)*?\/script>/gi,
4525 rselectTextarea = /select|textarea/i,
4526 rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
4529 rts = /(\?|&)_=.*?(&|$)/,
4530 rurl = /^(\w+:)?\/\/([^\/?#]+)/,
4534 // Keep a copy of the old load
4535 _load: jQuery.fn.load,
4537 load: function( url, params, callback ) {
4538 if ( typeof url !== "string" ) {
4539 return this._load( url );
4541 // Don't do a request if no elements are being requested
4542 } else if ( !this.length ) {
4546 var off = url.indexOf(" ");
4548 var selector = url.slice(off, url.length);
4549 url = url.slice(0, off);
4552 // Default to a GET request
4555 // If the second parameter was provided
4557 // If it's a function
4558 if ( jQuery.isFunction( params ) ) {
4559 // We assume that it's the callback
4563 // Otherwise, build a param string
4564 } else if ( typeof params === "object" ) {
4565 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
4570 // Request the remote document
4577 complete: function( res, status ) {
4578 // If successful, inject the HTML into all the matched elements
4579 if ( status === "success" || status === "notmodified" ) {
4580 // See if a selector was specified
4581 this.html( selector ?
4582 // Create a dummy div to hold the results
4584 // inject the contents of the document in, removing the scripts
4585 // to avoid any 'Permission Denied' errors in IE
4586 .append(res.responseText.replace(rscript, ""))
4588 // Locate the specified elements
4591 // If not, just inject the full result
4596 this.each( callback, [res.responseText, status, res] );
4604 serialize: function() {
4605 return jQuery.param(this.serializeArray());
4607 serializeArray: function() {
4608 return this.map(function() {
4609 return this.elements ? jQuery.makeArray(this.elements) : this;
4611 .filter(function() {
4612 return this.name && !this.disabled &&
4613 (this.checked || rselectTextarea.test(this.nodeName) ||
4614 rinput.test(this.type));
4616 .map(function( i, elem ) {
4617 var val = jQuery(this).val();
4619 return val == null ?
4621 jQuery.isArray(val) ?
4622 jQuery.map( val, function( val, i ) {
4623 return { name: elem.name, value: val };
4625 { name: elem.name, value: val };
4630 // Attach a bunch of functions for handling common AJAX events
4631 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
4632 jQuery.fn[o] = function( f ) {
4633 return this.bind(o, f);
4639 get: function( url, data, callback, type ) {
4640 // shift arguments if data argument was omited
4641 if ( jQuery.isFunction( data ) ) {
4642 type = type || callback;
4647 return jQuery.ajax({
4656 getScript: function( url, callback ) {
4657 return jQuery.get(url, null, callback, "script");
4660 getJSON: function( url, data, callback ) {
4661 return jQuery.get(url, data, callback, "json");
4664 post: function( url, data, callback, type ) {
4665 // shift arguments if data argument was omited
4666 if ( jQuery.isFunction( data ) ) {
4667 type = type || callback;
4672 return jQuery.ajax({
4681 ajaxSetup: function( settings ) {
4682 jQuery.extend( jQuery.ajaxSettings, settings );
4689 contentType: "application/x-www-form-urlencoded",
4699 // Create the request object; Microsoft failed to properly
4700 // implement the XMLHttpRequest in IE7 (can't request local files),
4701 // so we use the ActiveXObject when it is available
4702 // This function can be overriden by calling jQuery.ajaxSetup
4703 xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
4705 return new window.XMLHttpRequest();
4709 return new window.ActiveXObject("Microsoft.XMLHTTP");
4713 xml: "application/xml, text/xml",
4715 script: "text/javascript, application/javascript",
4716 json: "application/json, text/javascript",
4722 // Last-Modified header cache for next request
4726 ajax: function( origSettings ) {
4727 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
4729 var jsonp, status, data,
4730 callbackContext = s.context || s,
4731 type = s.type.toUpperCase();
4733 // convert data if not already a string
4734 if ( s.data && s.processData && typeof s.data !== "string" ) {
4735 s.data = jQuery.param( s.data, s.traditional );
4738 // Handle JSONP Parameter Callbacks
4739 if ( s.dataType === "jsonp" ) {
4740 if ( type === "GET" ) {
4741 if ( !jsre.test( s.url ) ) {
4742 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
4744 } else if ( !s.data || !jsre.test(s.data) ) {
4745 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
4747 s.dataType = "json";
4750 // Build temporary JSONP function
4751 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
4752 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
4754 // Replace the =? sequence both in the query string and the data
4756 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
4759 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
4761 // We need to make sure
4762 // that a JSONP style response is executed properly
4763 s.dataType = "script";
4765 // Handle JSONP-style loading
4766 window[ jsonp ] = window[ jsonp ] || function( tmp ) {
4771 window[ jsonp ] = undefined;
4774 delete window[ jsonp ];
4778 head.removeChild( script );
4783 if ( s.dataType === "script" && s.cache === null ) {
4787 if ( s.cache === false && type === "GET" ) {
4790 // try replacing _= if it is there
4791 var ret = s.url.replace(rts, "$1_=" + ts + "$2");
4793 // if nothing was replaced, add timestamp to the end
4794 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
4797 // If data is available, append data to url for get requests
4798 if ( s.data && type === "GET" ) {
4799 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
4802 // Watch for a new set of requests
4803 if ( s.global && ! jQuery.active++ ) {
4804 jQuery.event.trigger( "ajaxStart" );
4807 // Matches an absolute URL, and saves the domain
4808 var parts = rurl.exec( s.url ),
4809 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
4811 // If we're requesting a remote document
4812 // and trying to load JSON or Script with a GET
4813 if ( s.dataType === "script" && type === "GET" && remote ) {
4814 var head = document.getElementsByTagName("head")[0] || document.documentElement;
4815 var script = document.createElement("script");
4817 if ( s.scriptCharset ) {
4818 script.charset = s.scriptCharset;
4821 // Handle Script loading
4825 // Attach handlers for all browsers
4826 script.onload = script.onreadystatechange = function() {
4827 if ( !done && (!this.readyState ||
4828 this.readyState === "loaded" || this.readyState === "complete") ) {
4833 // Handle memory leak in IE
4834 script.onload = script.onreadystatechange = null;
4835 if ( head && script.parentNode ) {
4836 head.removeChild( script );
4842 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
4843 // This arises when a base node is used (#2709 and #4378).
4844 head.insertBefore( script, head.firstChild );
4846 // We handle everything using the script element injection
4850 var requestDone = false;
4852 // Create the request object
4860 // Passing null username, generates a login popup on Opera (#2865)
4862 xhr.open(type, s.url, s.async, s.username, s.password);
4864 xhr.open(type, s.url, s.async);
4867 // Need an extra try/catch for cross domain requests in Firefox 3
4869 // Set the correct header, if data is being sent
4870 if ( s.data || origSettings && origSettings.contentType ) {
4871 xhr.setRequestHeader("Content-Type", s.contentType);
4874 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
4875 if ( s.ifModified ) {
4876 if ( jQuery.lastModified[s.url] ) {
4877 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
4880 if ( jQuery.etag[s.url] ) {
4881 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
4885 // Set header so the called script knows that it's an XMLHttpRequest
4886 // Only send the header if it's not a remote XHR
4888 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
4891 // Set the Accepts header for the server, depending on the dataType
4892 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
4893 s.accepts[ s.dataType ] + ", */*" :
4894 s.accepts._default );
4897 // Allow custom headers/mimetypes and early abort
4898 if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
4899 // Handle the global AJAX counter
4900 if ( s.global && ! --jQuery.active ) {
4901 jQuery.event.trigger( "ajaxStop" );
4904 // close opended socket
4910 trigger("ajaxSend", [xhr, s]);
4913 // Wait for a response to come back
4914 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
4915 // The request was aborted
4916 if ( !xhr || xhr.readyState === 0 ) {
4917 // Opera doesn't call onreadystatechange before this point
4918 // so we simulate the call
4919 if ( !requestDone ) {
4925 xhr.onreadystatechange = jQuery.noop;
4928 // The transfer is complete and the data is available, or the request timed out
4929 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
4931 xhr.onreadystatechange = jQuery.noop;
4933 status = isTimeout === "timeout" ?
4935 !jQuery.httpSuccess( xhr ) ?
4937 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
4941 if ( status === "success" ) {
4942 // Watch for, and catch, XML document parse errors
4944 // process the data (runs the xml through httpData regardless of callback)
4945 data = jQuery.httpData( xhr, s.dataType, s );
4947 status = "parsererror";
4951 // Make sure that the request was successful or notmodified
4952 if ( status === "success" || status === "notmodified" ) {
4953 // JSONP handles its own success callback
4958 jQuery.handleError(s, xhr, status);
4961 // Fire the complete handlers
4964 if ( isTimeout === "timeout" ) {
4968 // Stop memory leaks
4975 // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
4976 // Opera doesn't fire onreadystatechange at all on abort
4978 var oldAbort = xhr.abort;
4979 xhr.abort = function() {
4981 oldAbort.call( xhr );
4987 onreadystatechange();
4992 if ( s.async && s.timeout > 0 ) {
4993 setTimeout(function() {
4994 // Check to see if the request is still happening
4995 if ( xhr && !requestDone ) {
4996 onreadystatechange( "timeout" );
5003 xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
5005 jQuery.handleError(s, xhr, null, e);
5006 // Fire the complete handlers
5010 // firefox 1.5 doesn't fire statechange for sync requests
5012 onreadystatechange();
5015 function success() {
5016 // If a local callback was specified, fire it and pass it the data
5018 s.success.call( callbackContext, data, status, xhr );
5021 // Fire the global callback
5023 trigger( "ajaxSuccess", [xhr, s] );
5027 function complete() {
5030 s.complete.call( callbackContext, xhr, status);
5033 // The request was completed
5035 trigger( "ajaxComplete", [xhr, s] );
5038 // Handle the global AJAX counter
5039 if ( s.global && ! --jQuery.active ) {
5040 jQuery.event.trigger( "ajaxStop" );
5044 function trigger(type, args) {
5045 (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
5048 // return XMLHttpRequest to allow aborting the request etc.
5052 handleError: function( s, xhr, status, e ) {
5053 // If a local callback was specified, fire it
5055 s.error.call( s.context || window, xhr, status, e );
5058 // Fire the global callback
5060 (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
5064 // Counter for holding the number of active queries
5067 // Determines if an XMLHttpRequest was successful or not
5068 httpSuccess: function( xhr ) {
5070 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
5071 return !xhr.status && location.protocol === "file:" ||
5072 // Opera returns 0 when status is 304
5073 ( xhr.status >= 200 && xhr.status < 300 ) ||
5074 xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
5080 // Determines if an XMLHttpRequest returns NotModified
5081 httpNotModified: function( xhr, url ) {
5082 var lastModified = xhr.getResponseHeader("Last-Modified"),
5083 etag = xhr.getResponseHeader("Etag");
5085 if ( lastModified ) {
5086 jQuery.lastModified[url] = lastModified;
5090 jQuery.etag[url] = etag;
5093 // Opera returns 0 when status is 304
5094 return xhr.status === 304 || xhr.status === 0;
5097 httpData: function( xhr, type, s ) {
5098 var ct = xhr.getResponseHeader("content-type") || "",
5099 xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
5100 data = xml ? xhr.responseXML : xhr.responseText;
5102 if ( xml && data.documentElement.nodeName === "parsererror" ) {
5103 throw "parsererror";
5106 // Allow a pre-filtering function to sanitize the response
5107 // s is checked to keep backwards compatibility
5108 if ( s && s.dataFilter ) {
5109 data = s.dataFilter( data, type );
5112 // The filter can actually parse the response
5113 if ( typeof data === "string" ) {
5114 // Get the JavaScript object, if JSON is used.
5115 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
5116 // Make sure the incoming data is actual JSON
5117 // Logic borrowed from http://json.org/json2.js
5118 if (/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
5119 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
5120 .replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
5122 // Try to use the native JSON parser first
5123 if ( window.JSON && window.JSON.parse ) {
5124 data = window.JSON.parse( data );
5127 data = (new Function("return " + data))();
5131 throw "Invalid JSON: " + data;
5134 // If the type is "script", eval it in global context
5135 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
5136 jQuery.globalEval( data );
5143 // Serialize an array of form elements or a set of
5144 // key/values into a query string
5145 param: function( a, traditional ) {
5149 // Set traditional to true for jQuery <= 1.3.2 behavior.
5150 if ( traditional === undefined ) {
5151 traditional = jQuery.ajaxSettings.traditional;
5154 function add( key, value ) {
5155 // If value is a function, invoke it and return its value
5156 value = jQuery.isFunction(value) ? value() : value;
5157 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
5160 // If an array was passed in, assume that it is an array of form elements.
5161 if ( jQuery.isArray(a) || a.jquery ) {
5162 // Serialize the form elements
5163 jQuery.each( a, function() {
5164 add( this.name, this.value );
5168 // If traditional, encode the "old" way (the way 1.3.2 or older
5169 // did it), otherwise encode params recursively.
5170 jQuery.each( a, function buildParams( prefix, obj ) {
5172 if ( jQuery.isArray(obj) ) {
5173 // Serialize array item.
5174 jQuery.each( obj, function( i, v ) {
5175 if ( traditional ) {
5176 // Treat each array item as a scalar.
5179 // If array item is non-scalar (array or object), encode its
5180 // numeric index to resolve deserialization ambiguity issues.
5181 // Note that rack (as of 1.0.0) can't currently deserialize
5182 // nested arrays properly, and attempting to do so may cause
5183 // a server error. Possible fixes are to modify rack's
5184 // deserialization algorithm or to provide an option or flag
5185 // to force array serialization to be shallow.
5186 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
5190 } else if ( !traditional && obj != null && typeof obj === "object" ) {
5191 // Serialize object item.
5192 jQuery.each( obj, function( k, v ) {
5193 buildParams( prefix + "[" + k + "]", v );
5197 // Serialize scalar item.
5203 // Return the resulting serialization
5204 return s.join("&").replace(r20, "+");
5208 var elemdisplay = {},
5209 rfxtypes = /toggle|show|hide/,
5210 rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
5213 // height animations
5214 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
5216 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
5217 // opacity animations
5222 show: function( speed, callback ) {
5223 if ( speed != null ) {
5224 return this.animate( genFx("show", 3), speed, callback);
5227 for ( var i = 0, l = this.length; i < l; i++ ) {
5228 var old = jQuery.data(this[i], "olddisplay");
5230 this[i].style.display = old || "";
5232 if ( jQuery.css(this[i], "display") === "none" ) {
5233 var nodeName = this[i].nodeName, display;
5235 if ( elemdisplay[ nodeName ] ) {
5236 display = elemdisplay[ nodeName ];
5239 var elem = jQuery("<" + nodeName + " />").appendTo("body");
5241 display = elem.css("display");
5243 if ( display === "none" ) {
5249 elemdisplay[ nodeName ] = display;
5252 jQuery.data(this[i], "olddisplay", display);
5256 // Set the display of the elements in a second loop
5257 // to avoid the constant reflow
5258 for ( var j = 0, k = this.length; j < k; j++ ) {
5259 this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
5266 hide: function( speed, callback ) {
5267 if ( speed != null ) {
5268 return this.animate( genFx("hide", 3), speed, callback);
5271 for ( var i = 0, l = this.length; i < l; i++ ) {
5272 var old = jQuery.data(this[i], "olddisplay");
5273 if ( !old && old !== "none" ) {
5274 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
5278 // Set the display of the elements in a second loop
5279 // to avoid the constant reflow
5280 for ( var j = 0, k = this.length; j < k; j++ ) {
5281 this[j].style.display = "none";
5288 // Save the old toggle function
5289 _toggle: jQuery.fn.toggle,
5291 toggle: function( fn, fn2 ) {
5292 var bool = typeof fn === "boolean";
5294 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
5295 this._toggle.apply( this, arguments );
5297 } else if ( fn == null || bool ) {
5298 this.each(function() {
5299 var state = bool ? fn : jQuery(this).is(":hidden");
5300 jQuery(this)[ state ? "show" : "hide" ]();
5304 this.animate(genFx("toggle", 3), fn, fn2);
5310 fadeTo: function( speed, to, callback ) {
5311 return this.filter(":hidden").css("opacity", 0).show().end()
5312 .animate({opacity: to}, speed, callback);
5315 animate: function( prop, speed, easing, callback ) {
5316 var optall = jQuery.speed(speed, easing, callback);
5318 if ( jQuery.isEmptyObject( prop ) ) {
5319 return this.each( optall.complete );
5322 return this[ optall.queue === false ? "each" : "queue" ](function() {
5323 var opt = jQuery.extend({}, optall), p,
5324 hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
5328 var name = p.replace(rdashAlpha, fcamelCase);
5331 prop[ name ] = prop[ p ];
5336 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
5337 return opt.complete.call(this);
5340 if ( ( p === "height" || p === "width" ) && this.style ) {
5341 // Store display property
5342 opt.display = jQuery.css(this, "display");
5344 // Make sure that nothing sneaks out
5345 opt.overflow = this.style.overflow;
5348 if ( jQuery.isArray( prop[p] ) ) {
5349 // Create (if needed) and add to specialEasing
5350 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
5351 prop[p] = prop[p][0];
5355 if ( opt.overflow != null ) {
5356 this.style.overflow = "hidden";
5359 opt.curAnim = jQuery.extend({}, prop);
5361 jQuery.each( prop, function( name, val ) {
5362 var e = new jQuery.fx( self, opt, name );
5364 if ( rfxtypes.test(val) ) {
5365 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
5368 var parts = rfxnum.exec(val),
5369 start = e.cur(true) || 0;
5372 var end = parseFloat( parts[2] ),
5373 unit = parts[3] || "px";
5375 // We need to compute starting value
5376 if ( unit !== "px" ) {
5377 self.style[ name ] = (end || 1) + unit;
5378 start = ((end || 1) / e.cur(true)) * start;
5379 self.style[ name ] = start + unit;
5382 // If a +=/-= token was provided, we're doing a relative animation
5384 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
5387 e.custom( start, end, unit );
5390 e.custom( start, val, "" );
5395 // For JS strict compliance
5400 stop: function( clearQueue, gotoEnd ) {
5401 var timers = jQuery.timers;
5407 this.each(function() {
5408 // go in reverse order so anything added to the queue during the loop is ignored
5409 for ( var i = timers.length - 1; i >= 0; i-- ) {
5410 if ( timers[i].elem === this ) {
5412 // force the next step to be the last
5416 timers.splice(i, 1);
5421 // start the next in the queue if the last step wasn't forced
5431 // Generate shortcuts for custom animations
5433 slideDown: genFx("show", 1),
5434 slideUp: genFx("hide", 1),
5435 slideToggle: genFx("toggle", 1),
5436 fadeIn: { opacity: "show" },
5437 fadeOut: { opacity: "hide" }
5438 }, function( name, props ) {
5439 jQuery.fn[ name ] = function( speed, callback ) {
5440 return this.animate( props, speed, callback );
5445 speed: function( speed, easing, fn ) {
5446 var opt = speed && typeof speed === "object" ? speed : {
5447 complete: fn || !fn && easing ||
5448 jQuery.isFunction( speed ) && speed,
5450 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
5453 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
5454 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
5457 opt.old = opt.complete;
5458 opt.complete = function() {
5459 if ( opt.queue !== false ) {
5460 jQuery(this).dequeue();
5462 if ( jQuery.isFunction( opt.old ) ) {
5463 opt.old.call( this );
5471 linear: function( p, n, firstNum, diff ) {
5472 return firstNum + diff * p;
5474 swing: function( p, n, firstNum, diff ) {
5475 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
5481 fx: function( elem, options, prop ) {
5482 this.options = options;
5486 if ( !options.orig ) {
5493 jQuery.fx.prototype = {
5494 // Simple function for setting a style value
5495 update: function() {
5496 if ( this.options.step ) {
5497 this.options.step.call( this.elem, this.now, this );
5500 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
5502 // Set display property to block for height/width animations
5503 if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
5504 this.elem.style.display = "block";
5508 // Get the current size
5509 cur: function( force ) {
5510 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
5511 return this.elem[ this.prop ];
5514 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
5515 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
5518 // Start an animation from one number to another
5519 custom: function( from, to, unit ) {
5520 this.startTime = now();
5523 this.unit = unit || this.unit || "px";
5524 this.now = this.start;
5525 this.pos = this.state = 0;
5528 function t( gotoEnd ) {
5529 return self.step(gotoEnd);
5534 if ( t() && jQuery.timers.push(t) && !timerId ) {
5535 timerId = setInterval(jQuery.fx.tick, 13);
5539 // Simple 'show' function
5541 // Remember where we started, so that we can go back to it later
5542 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
5543 this.options.show = true;
5545 // Begin the animation
5546 // Make sure that we start at a small width/height to avoid any
5548 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
5550 // Start by showing the element
5551 jQuery( this.elem ).show();
5554 // Simple 'hide' function
5556 // Remember where we started, so that we can go back to it later
5557 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
5558 this.options.hide = true;
5560 // Begin the animation
5561 this.custom(this.cur(), 0);
5564 // Each step of an animation
5565 step: function( gotoEnd ) {
5566 var t = now(), done = true;
5568 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
5569 this.now = this.end;
5570 this.pos = this.state = 1;
5573 this.options.curAnim[ this.prop ] = true;
5575 for ( var i in this.options.curAnim ) {
5576 if ( this.options.curAnim[i] !== true ) {
5582 if ( this.options.display != null ) {
5583 // Reset the overflow
5584 this.elem.style.overflow = this.options.overflow;
5586 // Reset the display
5587 var old = jQuery.data(this.elem, "olddisplay");
5588 this.elem.style.display = old ? old : this.options.display;
5590 if ( jQuery.css(this.elem, "display") === "none" ) {
5591 this.elem.style.display = "block";
5595 // Hide the element if the "hide" operation was done
5596 if ( this.options.hide ) {
5597 jQuery(this.elem).hide();
5600 // Reset the properties, if the item has been hidden or shown
5601 if ( this.options.hide || this.options.show ) {
5602 for ( var p in this.options.curAnim ) {
5603 jQuery.style(this.elem, p, this.options.orig[p]);
5607 // Execute the complete function
5608 this.options.complete.call( this.elem );
5614 var n = t - this.startTime;
5615 this.state = n / this.options.duration;
5617 // Perform the easing function, defaults to swing
5618 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
5619 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
5620 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
5621 this.now = this.start + ((this.end - this.start) * this.pos);
5623 // Perform the next step of the animation
5631 jQuery.extend( jQuery.fx, {
5633 var timers = jQuery.timers;
5635 for ( var i = 0; i < timers.length; i++ ) {
5636 if ( !timers[i]() ) {
5637 timers.splice(i--, 1);
5641 if ( !timers.length ) {
5647 clearInterval( timerId );
5659 opacity: function( fx ) {
5660 jQuery.style(fx.elem, "opacity", fx.now);
5663 _default: function( fx ) {
5664 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
5665 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
5667 fx.elem[ fx.prop ] = fx.now;
5673 if ( jQuery.expr && jQuery.expr.filters ) {
5674 jQuery.expr.filters.animated = function( elem ) {
5675 return jQuery.grep(jQuery.timers, function( fn ) {
5676 return elem === fn.elem;
5681 function genFx( type, num ) {
5684 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
5690 if ( "getBoundingClientRect" in document.documentElement ) {
5691 jQuery.fn.offset = function( options ) {
5694 if ( !elem || !elem.ownerDocument ) {
5699 return this.each(function( i ) {
5700 jQuery.offset.setOffset( this, options, i );
5704 if ( elem === elem.ownerDocument.body ) {
5705 return jQuery.offset.bodyOffset( elem );
5708 var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
5709 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
5710 top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
5711 left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
5713 return { top: top, left: left };
5717 jQuery.fn.offset = function( options ) {
5720 if ( !elem || !elem.ownerDocument ) {
5725 return this.each(function( i ) {
5726 jQuery.offset.setOffset( this, options, i );
5730 if ( elem === elem.ownerDocument.body ) {
5731 return jQuery.offset.bodyOffset( elem );
5734 jQuery.offset.initialize();
5736 var offsetParent = elem.offsetParent, prevOffsetParent = elem,
5737 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
5738 body = doc.body, defaultView = doc.defaultView,
5739 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
5740 top = elem.offsetTop, left = elem.offsetLeft;
5742 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
5743 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
5747 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
5748 top -= elem.scrollTop;
5749 left -= elem.scrollLeft;
5751 if ( elem === offsetParent ) {
5752 top += elem.offsetTop;
5753 left += elem.offsetLeft;
5755 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
5756 top += parseFloat( computedStyle.borderTopWidth ) || 0;
5757 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
5760 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
5763 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
5764 top += parseFloat( computedStyle.borderTopWidth ) || 0;
5765 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
5768 prevComputedStyle = computedStyle;
5771 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
5772 top += body.offsetTop;
5773 left += body.offsetLeft;
5776 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
5777 top += Math.max( docElem.scrollTop, body.scrollTop );
5778 left += Math.max( docElem.scrollLeft, body.scrollLeft );
5781 return { top: top, left: left };
5786 initialize: function() {
5787 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
5788 html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
5790 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
5792 container.innerHTML = html;
5793 body.insertBefore( container, body.firstChild );
5794 innerDiv = container.firstChild;
5795 checkDiv = innerDiv.firstChild;
5796 td = innerDiv.nextSibling.firstChild.firstChild;
5798 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
5799 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
5801 checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
5802 // safari subtracts parent border width here which is 5px
5803 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
5804 checkDiv.style.position = checkDiv.style.top = "";
5806 innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
5807 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
5809 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
5811 body.removeChild( container );
5812 body = container = innerDiv = checkDiv = table = td = null;
5813 jQuery.offset.initialize = jQuery.noop;
5816 bodyOffset: function( body ) {
5817 var top = body.offsetTop, left = body.offsetLeft;
5819 jQuery.offset.initialize();
5821 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
5822 top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
5823 left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
5826 return { top: top, left: left };
5829 setOffset: function( elem, options, i ) {
5830 // set position first, in-case top/left are set even on static elem
5831 if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
5832 elem.style.position = "relative";
5834 var curElem = jQuery( elem ),
5835 curOffset = curElem.offset(),
5836 curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
5837 curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
5839 if ( jQuery.isFunction( options ) ) {
5840 options = options.call( elem, i, curOffset );
5844 top: (options.top - curOffset.top) + curTop,
5845 left: (options.left - curOffset.left) + curLeft
5848 if ( "using" in options ) {
5849 options.using.call( elem, props );
5851 curElem.css( props );
5858 position: function() {
5865 // Get *real* offsetParent
5866 offsetParent = this.offsetParent(),
5868 // Get correct offsets
5869 offset = this.offset(),
5870 parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
5872 // Subtract element margins
5873 // note: when an element has margin: auto the offsetLeft and marginLeft
5874 // are the same in Safari causing offset.left to incorrectly be 0
5875 offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
5876 offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
5878 // Add offsetParent borders
5879 parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
5880 parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
5882 // Subtract the two offsets
5884 top: offset.top - parentOffset.top,
5885 left: offset.left - parentOffset.left
5889 offsetParent: function() {
5890 return this.map(function() {
5891 var offsetParent = this.offsetParent || document.body;
5892 while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
5893 offsetParent = offsetParent.offsetParent;
5895 return offsetParent;
5901 // Create scrollLeft and scrollTop methods
5902 jQuery.each( ["Left", "Top"], function( i, name ) {
5903 var method = "scroll" + name;
5905 jQuery.fn[ method ] = function(val) {
5906 var elem = this[0], win;
5912 if ( val !== undefined ) {
5913 // Set the scroll offset
5914 return this.each(function() {
5915 win = getWindow( this );
5919 !i ? val : jQuery(win).scrollLeft(),
5920 i ? val : jQuery(win).scrollTop()
5924 this[ method ] = val;
5928 win = getWindow( elem );
5930 // Return the scroll offset
5931 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
5932 jQuery.support.boxModel && win.document.documentElement[ method ] ||
5933 win.document.body[ method ] :
5939 function getWindow( elem ) {
5940 return ("scrollTo" in elem && elem.document) ?
5942 elem.nodeType === 9 ?
5943 elem.defaultView || elem.parentWindow :
5946 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
5947 jQuery.each([ "Height", "Width" ], function( i, name ) {
5949 var type = name.toLowerCase();
5951 // innerHeight and innerWidth
5952 jQuery.fn["inner" + name] = function() {
5954 jQuery.css( this[0], type, false, "padding" ) :
5958 // outerHeight and outerWidth
5959 jQuery.fn["outer" + name] = function( margin ) {
5961 jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
5965 jQuery.fn[ type ] = function( size ) {
5966 // Get window width or height
5969 return size == null ? null : this;
5972 return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
5973 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
5974 elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
5975 elem.document.body[ "client" + name ] :
5977 // Get document width or height
5978 (elem.nodeType === 9) ? // is it a document
5979 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
5981 elem.documentElement["client" + name],
5982 elem.body["scroll" + name], elem.documentElement["scroll" + name],
5983 elem.body["offset" + name], elem.documentElement["offset" + name]
5986 // Get or set width or height on the element
5987 size === undefined ?
5988 // Get width or height on the element
5989 jQuery.css( elem, type ) :
5991 // Set the width or height on the element (default to pixels if value is unitless)
5992 this.css( type, typeof size === "string" ? size : size + "px" );
5996 // Expose jQuery to the global object
5997 window.jQuery = window.$ = jQuery;