2 * jQuery JavaScript Library v1.4.1
5 * Copyright 2010, John Resig
6 * Dual licensed under the MIT or GPL Version 2 licenses.
7 * http://jquery.org/license
10 * http://sizzlejs.com/
11 * Copyright 2010, The Dojo Foundation
12 * Released under the MIT, BSD, and GPL Licenses.
14 * Date: Mon Jan 25 19:43:33 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 ) {
487 error: function( msg ) {
491 parseJSON: function( data ) {
492 if ( typeof data !== "string" || !data ) {
496 // Make sure the incoming data is actual JSON
497 // Logic borrowed from http://json.org/json2.js
498 if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
499 .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
500 .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
502 // Try to use the native JSON parser first
503 return window.JSON && window.JSON.parse ?
504 window.JSON.parse( data ) :
505 (new Function("return " + data))();
508 jQuery.error( "Invalid JSON: " + data );
514 // Evalulates a script in a global context
515 globalEval: function( data ) {
516 if ( data && rnotwhite.test(data) ) {
517 // Inspired by code by Andrea Giammarchi
518 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
519 var head = document.getElementsByTagName("head")[0] || document.documentElement,
520 script = document.createElement("script");
522 script.type = "text/javascript";
524 if ( jQuery.support.scriptEval ) {
525 script.appendChild( document.createTextNode( data ) );
530 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
531 // This arises when a base node is used (#2709).
532 head.insertBefore( script, head.firstChild );
533 head.removeChild( script );
537 nodeName: function( elem, name ) {
538 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
541 // args is for internal usage only
542 each: function( object, callback, args ) {
544 length = object.length,
545 isObj = length === undefined || jQuery.isFunction(object);
549 for ( name in object ) {
550 if ( callback.apply( object[ name ], args ) === false ) {
555 for ( ; i < length; ) {
556 if ( callback.apply( object[ i++ ], args ) === false ) {
562 // A special, fast, case for the most common use of each
565 for ( name in object ) {
566 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
571 for ( var value = object[0];
572 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
579 trim: function( text ) {
580 return (text || "").replace( rtrim, "" );
583 // results is for internal usage only
584 makeArray: function( array, results ) {
585 var ret = results || [];
587 if ( array != null ) {
588 // The window, strings (and functions) also have 'length'
589 // The extra typeof function check is to prevent crashes
590 // in Safari 2 (See: #3039)
591 if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
592 push.call( ret, array );
594 jQuery.merge( ret, array );
601 inArray: function( elem, array ) {
602 if ( array.indexOf ) {
603 return array.indexOf( elem );
606 for ( var i = 0, length = array.length; i < length; i++ ) {
607 if ( array[ i ] === elem ) {
615 merge: function( first, second ) {
616 var i = first.length, j = 0;
618 if ( typeof second.length === "number" ) {
619 for ( var l = second.length; j < l; j++ ) {
620 first[ i++ ] = second[ j ];
623 while ( second[j] !== undefined ) {
624 first[ i++ ] = second[ j++ ];
633 grep: function( elems, callback, inv ) {
636 // Go through the array, only saving the items
637 // that pass the validator function
638 for ( var i = 0, length = elems.length; i < length; i++ ) {
639 if ( !inv !== !callback( elems[ i ], i ) ) {
640 ret.push( elems[ i ] );
647 // arg is for internal usage only
648 map: function( elems, callback, arg ) {
651 // Go through the array, translating each of the items to their
652 // new value (or values).
653 for ( var i = 0, length = elems.length; i < length; i++ ) {
654 value = callback( elems[ i ], i, arg );
656 if ( value != null ) {
657 ret[ ret.length ] = value;
661 return ret.concat.apply( [], ret );
664 // A global GUID counter for objects
667 proxy: function( fn, proxy, thisObject ) {
668 if ( arguments.length === 2 ) {
669 if ( typeof proxy === "string" ) {
671 fn = thisObject[ proxy ];
674 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
680 if ( !proxy && fn ) {
682 return fn.apply( thisObject || this, arguments );
686 // Set the guid of unique handler to the same of original handler, so it can be removed
688 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
691 // So proxy can be declared as an argument
695 // Use of jQuery.browser is frowned upon.
696 // More details: http://docs.jquery.com/Utilities/jQuery.browser
697 uaMatch: function( ua ) {
698 ua = ua.toLowerCase();
700 var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
701 /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
702 /(msie) ([\w.]+)/.exec( ua ) ||
703 !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
706 return { browser: match[1] || "", version: match[2] || "0" };
712 browserMatch = jQuery.uaMatch( userAgent );
713 if ( browserMatch.browser ) {
714 jQuery.browser[ browserMatch.browser ] = true;
715 jQuery.browser.version = browserMatch.version;
718 // Deprecated, use jQuery.browser.webkit instead
719 if ( jQuery.browser.webkit ) {
720 jQuery.browser.safari = true;
724 jQuery.inArray = function( elem, array ) {
725 return indexOf.call( array, elem );
729 // All jQuery objects should point back to these
730 rootjQuery = jQuery(document);
732 // Cleanup functions for the document ready method
733 if ( document.addEventListener ) {
734 DOMContentLoaded = function() {
735 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
739 } else if ( document.attachEvent ) {
740 DOMContentLoaded = function() {
741 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
742 if ( document.readyState === "complete" ) {
743 document.detachEvent( "onreadystatechange", DOMContentLoaded );
749 // The DOM ready check for Internet Explorer
750 function doScrollCheck() {
751 if ( jQuery.isReady ) {
756 // If IE is used, use the trick by Diego Perini
757 // http://javascript.nwbox.com/IEContentLoaded/
758 document.documentElement.doScroll("left");
760 setTimeout( doScrollCheck, 1 );
764 // and execute any waiting functions
768 function evalScript( i, elem ) {
776 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
779 if ( elem.parentNode ) {
780 elem.parentNode.removeChild( elem );
784 // Mutifunctional method to get and set values to a collection
785 // The value/s can be optionally by executed if its a function
786 function access( elems, key, value, exec, fn, pass ) {
787 var length = elems.length;
789 // Setting many attributes
790 if ( typeof key === "object" ) {
791 for ( var k in key ) {
792 access( elems, k, key[k], exec, fn, value );
797 // Setting one attribute
798 if ( value !== undefined ) {
799 // Optionally, function values get executed if exec is true
800 exec = !pass && exec && jQuery.isFunction(value);
802 for ( var i = 0; i < length; i++ ) {
803 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
809 // Getting an attribute
810 return length ? fn( elems[0], key ) : null;
814 return (new Date).getTime();
820 var root = document.documentElement,
821 script = document.createElement("script"),
822 div = document.createElement("div"),
823 id = "script" + now();
825 div.style.display = "none";
826 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
828 var all = div.getElementsByTagName("*"),
829 a = div.getElementsByTagName("a")[0];
831 // Can't get basic test support
832 if ( !all || !all.length || !a ) {
837 // IE strips leading whitespace when .innerHTML is used
838 leadingWhitespace: div.firstChild.nodeType === 3,
840 // Make sure that tbody elements aren't automatically inserted
841 // IE will insert them into empty tables
842 tbody: !div.getElementsByTagName("tbody").length,
844 // Make sure that link elements get serialized correctly by innerHTML
845 // This requires a wrapper element in IE
846 htmlSerialize: !!div.getElementsByTagName("link").length,
848 // Get the style information from getAttribute
849 // (IE uses .cssText insted)
850 style: /red/.test( a.getAttribute("style") ),
852 // Make sure that URLs aren't manipulated
853 // (IE normalizes it by default)
854 hrefNormalized: a.getAttribute("href") === "/a",
856 // Make sure that element opacity exists
857 // (IE uses filter instead)
858 // Use a regex to work around a WebKit issue. See #5145
859 opacity: /^0.55$/.test( a.style.opacity ),
861 // Verify style float existence
862 // (IE uses styleFloat instead of cssFloat)
863 cssFloat: !!a.style.cssFloat,
865 // Make sure that if no value is specified for a checkbox
866 // that it defaults to "on".
867 // (WebKit defaults to "" instead)
868 checkOn: div.getElementsByTagName("input")[0].value === "on",
870 // Make sure that a selected-by-default option has a working selected property.
871 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
872 optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
874 // Will be defined later
881 script.type = "text/javascript";
883 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
886 root.insertBefore( script, root.firstChild );
888 // Make sure that the execution of code works by injecting a script
889 // tag with appendChild/createTextNode
890 // (IE doesn't support this, fails, and uses .text instead)
891 if ( window[ id ] ) {
892 jQuery.support.scriptEval = true;
896 root.removeChild( script );
898 if ( div.attachEvent && div.fireEvent ) {
899 div.attachEvent("onclick", function click() {
900 // Cloning a node shouldn't copy over any
901 // bound event handlers (IE does this)
902 jQuery.support.noCloneEvent = false;
903 div.detachEvent("onclick", click);
905 div.cloneNode(true).fireEvent("onclick");
908 div = document.createElement("div");
909 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
911 var fragment = document.createDocumentFragment();
912 fragment.appendChild( div.firstChild );
914 // WebKit doesn't clone checked state correctly in fragments
915 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
917 // Figure out if the W3C box model works as expected
918 // document.body must exist before we can do this
920 var div = document.createElement("div");
921 div.style.width = div.style.paddingLeft = "1px";
923 document.body.appendChild( div );
924 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
925 document.body.removeChild( div ).style.display = 'none';
929 // Technique from Juriy Zaytsev
930 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
931 var eventSupported = function( eventName ) {
932 var el = document.createElement("div");
933 eventName = "on" + eventName;
935 var isSupported = (eventName in el);
936 if ( !isSupported ) {
937 el.setAttribute(eventName, "return;");
938 isSupported = typeof el[eventName] === "function";
945 jQuery.support.submitBubbles = eventSupported("submit");
946 jQuery.support.changeBubbles = eventSupported("change");
948 // release memory in IE
949 root = script = div = all = a = null;
954 "class": "className",
955 readonly: "readOnly",
956 maxlength: "maxLength",
957 cellspacing: "cellSpacing",
960 tabindex: "tabIndex",
962 frameborder: "frameBorder"
964 var expando = "jQuery" + now(), uuid = 0, windowData = {};
965 var emptyObject = {};
972 // The following elements throw uncatchable exceptions if you
973 // attempt to add expando properties to them.
980 data: function( elem, name, data ) {
981 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
985 elem = elem == window ?
989 var id = elem[ expando ], cache = jQuery.cache, thisCache;
991 // Handle the case where there's no name immediately
992 if ( !name && !id ) {
996 // Compute a unique ID for the element
1001 // Avoid generating a new cache unless none exists and we
1002 // want to manipulate it.
1003 if ( typeof name === "object" ) {
1004 elem[ expando ] = id;
1005 thisCache = cache[ id ] = jQuery.extend(true, {}, name);
1006 } else if ( cache[ id ] ) {
1007 thisCache = cache[ id ];
1008 } else if ( typeof data === "undefined" ) {
1009 thisCache = emptyObject;
1011 thisCache = cache[ id ] = {};
1014 // Prevent overriding the named cache with undefined values
1015 if ( data !== undefined ) {
1016 elem[ expando ] = id;
1017 thisCache[ name ] = data;
1020 return typeof name === "string" ? thisCache[ name ] : thisCache;
1023 removeData: function( elem, name ) {
1024 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
1028 elem = elem == window ?
1032 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
1034 // If we want to remove a specific section of the element's data
1037 // Remove the section of cache data
1038 delete thisCache[ name ];
1040 // If we've removed all the data, remove the element's cache
1041 if ( jQuery.isEmptyObject(thisCache) ) {
1042 jQuery.removeData( elem );
1046 // Otherwise, we want to remove all of the element's data
1048 // Clean up the element expando
1050 delete elem[ expando ];
1052 // IE has trouble directly removing the expando
1053 // but it's ok with using removeAttribute
1054 if ( elem.removeAttribute ) {
1055 elem.removeAttribute( expando );
1059 // Completely remove the data cache
1066 data: function( key, value ) {
1067 if ( typeof key === "undefined" && this.length ) {
1068 return jQuery.data( this[0] );
1070 } else if ( typeof key === "object" ) {
1071 return this.each(function() {
1072 jQuery.data( this, key );
1076 var parts = key.split(".");
1077 parts[1] = parts[1] ? "." + parts[1] : "";
1079 if ( value === undefined ) {
1080 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1082 if ( data === undefined && this.length ) {
1083 data = jQuery.data( this[0], key );
1085 return data === undefined && parts[1] ?
1086 this.data( parts[0] ) :
1089 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
1090 jQuery.data( this, key, value );
1095 removeData: function( key ) {
1096 return this.each(function() {
1097 jQuery.removeData( this, key );
1102 queue: function( elem, type, data ) {
1107 type = (type || "fx") + "queue";
1108 var q = jQuery.data( elem, type );
1110 // Speed up dequeue by getting out quickly if this is just a lookup
1115 if ( !q || jQuery.isArray(data) ) {
1116 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1125 dequeue: function( elem, type ) {
1126 type = type || "fx";
1128 var queue = jQuery.queue( elem, type ), fn = queue.shift();
1130 // If the fx queue is dequeued, always remove the progress sentinel
1131 if ( fn === "inprogress" ) {
1136 // Add a progress sentinel to prevent the fx queue from being
1137 // automatically dequeued
1138 if ( type === "fx" ) {
1139 queue.unshift("inprogress");
1142 fn.call(elem, function() {
1143 jQuery.dequeue(elem, type);
1150 queue: function( type, data ) {
1151 if ( typeof type !== "string" ) {
1156 if ( data === undefined ) {
1157 return jQuery.queue( this[0], type );
1159 return this.each(function( i, elem ) {
1160 var queue = jQuery.queue( this, type, data );
1162 if ( type === "fx" && queue[0] !== "inprogress" ) {
1163 jQuery.dequeue( this, type );
1167 dequeue: function( type ) {
1168 return this.each(function() {
1169 jQuery.dequeue( this, type );
1173 // Based off of the plugin by Clint Helfers, with permission.
1174 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1175 delay: function( time, type ) {
1176 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1177 type = type || "fx";
1179 return this.queue( type, function() {
1181 setTimeout(function() {
1182 jQuery.dequeue( elem, type );
1187 clearQueue: function( type ) {
1188 return this.queue( type || "fx", [] );
1191 var rclass = /[\n\t]/g,
1194 rspecialurl = /href|src|style/,
1195 rtype = /(button|input)/i,
1196 rfocusable = /(button|input|object|select|textarea)/i,
1197 rclickable = /^(a|area)$/i,
1198 rradiocheck = /radio|checkbox/;
1201 attr: function( name, value ) {
1202 return access( this, name, value, true, jQuery.attr );
1205 removeAttr: function( name, fn ) {
1206 return this.each(function(){
1207 jQuery.attr( this, name, "" );
1208 if ( this.nodeType === 1 ) {
1209 this.removeAttribute( name );
1214 addClass: function( value ) {
1215 if ( jQuery.isFunction(value) ) {
1216 return this.each(function(i) {
1217 var self = jQuery(this);
1218 self.addClass( value.call(this, i, self.attr("class")) );
1222 if ( value && typeof value === "string" ) {
1223 var classNames = (value || "").split( rspace );
1225 for ( var i = 0, l = this.length; i < l; i++ ) {
1228 if ( elem.nodeType === 1 ) {
1229 if ( !elem.className ) {
1230 elem.className = value;
1233 var className = " " + elem.className + " ";
1234 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1235 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1236 elem.className += " " + classNames[c];
1247 removeClass: function( value ) {
1248 if ( jQuery.isFunction(value) ) {
1249 return this.each(function(i) {
1250 var self = jQuery(this);
1251 self.removeClass( value.call(this, i, self.attr("class")) );
1255 if ( (value && typeof value === "string") || value === undefined ) {
1256 var classNames = (value || "").split(rspace);
1258 for ( var i = 0, l = this.length; i < l; i++ ) {
1261 if ( elem.nodeType === 1 && elem.className ) {
1263 var className = (" " + elem.className + " ").replace(rclass, " ");
1264 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1265 className = className.replace(" " + classNames[c] + " ", " ");
1267 elem.className = className.substring(1, className.length - 1);
1270 elem.className = "";
1279 toggleClass: function( value, stateVal ) {
1280 var type = typeof value, isBool = typeof stateVal === "boolean";
1282 if ( jQuery.isFunction( value ) ) {
1283 return this.each(function(i) {
1284 var self = jQuery(this);
1285 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1289 return this.each(function() {
1290 if ( type === "string" ) {
1291 // toggle individual class names
1292 var className, i = 0, self = jQuery(this),
1294 classNames = value.split( rspace );
1296 while ( (className = classNames[ i++ ]) ) {
1297 // check each className given, space seperated list
1298 state = isBool ? state : !self.hasClass( className );
1299 self[ state ? "addClass" : "removeClass" ]( className );
1302 } else if ( type === "undefined" || type === "boolean" ) {
1303 if ( this.className ) {
1304 // store className if set
1305 jQuery.data( this, "__className__", this.className );
1308 // toggle whole className
1309 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1314 hasClass: function( selector ) {
1315 var className = " " + selector + " ";
1316 for ( var i = 0, l = this.length; i < l; i++ ) {
1317 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1325 val: function( value ) {
1326 if ( value === undefined ) {
1330 if ( jQuery.nodeName( elem, "option" ) ) {
1331 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
1334 // We need to handle select boxes special
1335 if ( jQuery.nodeName( elem, "select" ) ) {
1336 var index = elem.selectedIndex,
1338 options = elem.options,
1339 one = elem.type === "select-one";
1341 // Nothing was selected
1346 // Loop through all the selected options
1347 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1348 var option = options[ i ];
1350 if ( option.selected ) {
1351 // Get the specifc value for the option
1352 value = jQuery(option).val();
1354 // We don't need an array for one selects
1359 // Multi-Selects return an array
1360 values.push( value );
1367 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1368 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1369 return elem.getAttribute("value") === null ? "on" : elem.value;
1373 // Everything else, we just grab the value
1374 return (elem.value || "").replace(rreturn, "");
1381 var isFunction = jQuery.isFunction(value);
1383 return this.each(function(i) {
1384 var self = jQuery(this), val = value;
1386 if ( this.nodeType !== 1 ) {
1391 val = value.call(this, i, self.val());
1394 // Typecast each time if the value is a Function and the appended
1395 // value is therefore different each time.
1396 if ( typeof val === "number" ) {
1400 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1401 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1403 } else if ( jQuery.nodeName( this, "select" ) ) {
1404 var values = jQuery.makeArray(val);
1406 jQuery( "option", this ).each(function() {
1407 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1410 if ( !values.length ) {
1411 this.selectedIndex = -1;
1433 attr: function( elem, name, value, pass ) {
1434 // don't set attributes on text and comment nodes
1435 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1439 if ( pass && name in jQuery.attrFn ) {
1440 return jQuery(elem)[name](value);
1443 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1444 // Whether we are setting (or getting)
1445 set = value !== undefined;
1447 // Try to normalize/fix the name
1448 name = notxml && jQuery.props[ name ] || name;
1450 // Only do all the following if this is a node (faster for style)
1451 if ( elem.nodeType === 1 ) {
1452 // These attributes require special treatment
1453 var special = rspecialurl.test( name );
1455 // Safari mis-reports the default selected property of an option
1456 // Accessing the parent's selectedIndex property fixes it
1457 if ( name === "selected" && !jQuery.support.optSelected ) {
1458 var parent = elem.parentNode;
1460 parent.selectedIndex;
1462 // Make sure that it also works with optgroups, see #5701
1463 if ( parent.parentNode ) {
1464 parent.parentNode.selectedIndex;
1469 // If applicable, access the attribute via the DOM 0 way
1470 if ( name in elem && notxml && !special ) {
1472 // We can't allow the type property to be changed (since it causes problems in IE)
1473 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1474 jQuery.error( "type property can't be changed" );
1477 elem[ name ] = value;
1480 // browsers index elements by id/name on forms, give priority to attributes.
1481 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1482 return elem.getAttributeNode( name ).nodeValue;
1485 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1486 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1487 if ( name === "tabIndex" ) {
1488 var attributeNode = elem.getAttributeNode( "tabIndex" );
1490 return attributeNode && attributeNode.specified ?
1491 attributeNode.value :
1492 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1497 return elem[ name ];
1500 if ( !jQuery.support.style && notxml && name === "style" ) {
1502 elem.style.cssText = "" + value;
1505 return elem.style.cssText;
1509 // convert the value to a string (all browsers do this but IE) see #1070
1510 elem.setAttribute( name, "" + value );
1513 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1514 // Some attributes require a special call on IE
1515 elem.getAttribute( name, 2 ) :
1516 elem.getAttribute( name );
1518 // Non-existent attributes return null, we normalize to undefined
1519 return attr === null ? undefined : attr;
1522 // elem is actually elem.style ... set the style
1523 // Using attr for specific style information is now deprecated. Use style insead.
1524 return jQuery.style( elem, name, value );
1527 var fcleanup = function( nm ) {
1528 return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
1534 * A number of helper functions used for managing events.
1535 * Many of the ideas behind this code originated from
1536 * Dean Edwards' addEvent library.
1540 // Bind an event to an element
1541 // Original by Dean Edwards
1542 add: function( elem, types, handler, data ) {
1543 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1547 // For whatever reason, IE has trouble passing the window object
1548 // around, causing it to be cloned in the process
1549 if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
1553 // Make sure that the function being executed has a unique ID
1554 if ( !handler.guid ) {
1555 handler.guid = jQuery.guid++;
1558 // if data is passed, bind to handler
1559 if ( data !== undefined ) {
1560 // Create temporary function pointer to original handler
1563 // Create unique handler function, wrapped around original handler
1564 handler = jQuery.proxy( fn );
1566 // Store data in unique handler
1567 handler.data = data;
1570 // Init the element's event structure
1571 var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
1572 handle = jQuery.data( elem, "handle" ), eventHandle;
1575 eventHandle = function() {
1576 // Handle the second event of a trigger and when
1577 // an event is called after a page has unloaded
1578 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1579 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1583 handle = jQuery.data( elem, "handle", eventHandle );
1586 // If no handle is found then we must be trying to bind to one of the
1587 // banned noData elements
1592 // Add elem as a property of the handle function
1593 // This is to prevent a memory leak with non-native
1597 // Handle multiple events separated by a space
1598 // jQuery(...).bind("mouseover mouseout", fn);
1599 types = types.split( /\s+/ );
1603 while ( (type = types[ i++ ]) ) {
1604 // Namespaced event handlers
1605 var namespaces = type.split(".");
1606 type = namespaces.shift();
1609 handler = jQuery.proxy( handler );
1611 if ( data !== undefined ) {
1612 handler.data = data;
1616 handler.type = namespaces.slice(0).sort().join(".");
1618 // Get the current list of functions bound to this event
1619 var handlers = events[ type ],
1620 special = this.special[ type ] || {};
1622 // Init the event handler queue
1624 handlers = events[ type ] = {};
1626 // Check for a special event handler
1627 // Only use addEventListener/attachEvent if the special
1628 // events handler returns false
1629 if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
1630 // Bind the global event handler to the element
1631 if ( elem.addEventListener ) {
1632 elem.addEventListener( type, handle, false );
1633 } else if ( elem.attachEvent ) {
1634 elem.attachEvent( "on" + type, handle );
1639 if ( special.add ) {
1640 var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
1641 if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
1642 modifiedHandler.guid = modifiedHandler.guid || handler.guid;
1643 modifiedHandler.data = modifiedHandler.data || handler.data;
1644 modifiedHandler.type = modifiedHandler.type || handler.type;
1645 handler = modifiedHandler;
1649 // Add the function to the element's handler list
1650 handlers[ handler.guid ] = handler;
1652 // Keep track of which events have been used, for global triggering
1653 this.global[ type ] = true;
1656 // Nullify elem to prevent memory leaks in IE
1662 // Detach an event or set of events from an element
1663 remove: function( elem, types, handler ) {
1664 // don't do events on text and comment nodes
1665 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1669 var events = jQuery.data( elem, "events" ), ret, type, fn;
1672 // Unbind all events for the element
1673 if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
1674 for ( type in events ) {
1675 this.remove( elem, type + (types || "") );
1678 // types is actually an event object here
1680 handler = types.handler;
1684 // Handle multiple events separated by a space
1685 // jQuery(...).unbind("mouseover mouseout", fn);
1686 types = types.split(/\s+/);
1688 while ( (type = types[ i++ ]) ) {
1689 // Namespaced event handlers
1690 var namespaces = type.split(".");
1691 type = namespaces.shift();
1692 var all = !namespaces.length,
1693 cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ),
1694 namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"),
1695 special = this.special[ type ] || {};
1697 if ( events[ type ] ) {
1698 // remove the given handler for the given type
1700 fn = events[ type ][ handler.guid ];
1701 delete events[ type ][ handler.guid ];
1703 // remove all handlers for the given type
1705 for ( var handle in events[ type ] ) {
1706 // Handle the removal of namespaced events
1707 if ( all || namespace.test( events[ type ][ handle ].type ) ) {
1708 delete events[ type ][ handle ];
1713 if ( special.remove ) {
1714 special.remove.call( elem, namespaces, fn);
1717 // remove generic event handler if no more handlers exist
1718 for ( ret in events[ type ] ) {
1722 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
1723 if ( elem.removeEventListener ) {
1724 elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
1725 } else if ( elem.detachEvent ) {
1726 elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
1730 delete events[ type ];
1736 // Remove the expando if it's no longer used
1737 for ( ret in events ) {
1741 var handle = jQuery.data( elem, "handle" );
1745 jQuery.removeData( elem, "events" );
1746 jQuery.removeData( elem, "handle" );
1751 // bubbling is internal
1752 trigger: function( event, data, elem /*, bubbling */ ) {
1753 // Event object or event type
1754 var type = event.type || event,
1755 bubbling = arguments[3];
1758 event = typeof event === "object" ?
1759 // jQuery.Event object
1760 event[expando] ? event :
1762 jQuery.extend( jQuery.Event(type), event ) :
1763 // Just the event type (string)
1766 if ( type.indexOf("!") >= 0 ) {
1767 event.type = type = type.slice(0, -1);
1768 event.exclusive = true;
1771 // Handle a global trigger
1773 // Don't bubble custom events when global (to avoid too much overhead)
1774 event.stopPropagation();
1776 // Only trigger if we've ever bound an event for it
1777 if ( this.global[ type ] ) {
1778 jQuery.each( jQuery.cache, function() {
1779 if ( this.events && this.events[type] ) {
1780 jQuery.event.trigger( event, data, this.handle.elem );
1786 // Handle triggering a single element
1788 // don't do events on text and comment nodes
1789 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1793 // Clean up in case it is reused
1794 event.result = undefined;
1795 event.target = elem;
1797 // Clone the incoming data, if any
1798 data = jQuery.makeArray( data );
1799 data.unshift( event );
1802 event.currentTarget = elem;
1804 // Trigger the event, it is assumed that "handle" is a function
1805 var handle = jQuery.data( elem, "handle" );
1807 handle.apply( elem, data );
1810 var parent = elem.parentNode || elem.ownerDocument;
1812 // Trigger an inline bound script
1814 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
1815 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
1816 event.result = false;
1820 // prevent IE from throwing an error for some elements with some event types, see #3533
1823 if ( !event.isPropagationStopped() && parent ) {
1824 jQuery.event.trigger( event, data, parent, true );
1826 } else if ( !event.isDefaultPrevented() ) {
1827 var target = event.target, old,
1828 isClick = jQuery.nodeName(target, "a") && type === "click";
1830 if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
1832 if ( target[ type ] ) {
1833 // Make sure that we don't accidentally re-trigger the onFOO events
1834 old = target[ "on" + type ];
1837 target[ "on" + type ] = null;
1840 this.triggered = true;
1844 // prevent IE from throwing an error for some elements with some event types, see #3533
1848 target[ "on" + type ] = old;
1851 this.triggered = false;
1856 handle: function( event ) {
1857 // returned undefined or false
1860 event = arguments[0] = jQuery.event.fix( event || window.event );
1861 event.currentTarget = this;
1863 // Namespaced event handlers
1864 var namespaces = event.type.split(".");
1865 event.type = namespaces.shift();
1867 // Cache this now, all = true means, any handler
1868 all = !namespaces.length && !event.exclusive;
1870 var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
1872 handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
1874 for ( var j in handlers ) {
1875 var handler = handlers[ j ];
1877 // Filter the functions by class
1878 if ( all || namespace.test(handler.type) ) {
1879 // Pass in a reference to the handler function itself
1880 // So that we can later remove it
1881 event.handler = handler;
1882 event.data = handler.data;
1884 var ret = handler.apply( this, arguments );
1886 if ( ret !== undefined ) {
1888 if ( ret === false ) {
1889 event.preventDefault();
1890 event.stopPropagation();
1894 if ( event.isImmediatePropagationStopped() ) {
1901 return event.result;
1904 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(" "),
1906 fix: function( event ) {
1907 if ( event[ expando ] ) {
1911 // store a copy of the original event object
1912 // and "clone" to set read-only properties
1913 var originalEvent = event;
1914 event = jQuery.Event( originalEvent );
1916 for ( var i = this.props.length, prop; i; ) {
1917 prop = this.props[ --i ];
1918 event[ prop ] = originalEvent[ prop ];
1921 // Fix target property, if necessary
1922 if ( !event.target ) {
1923 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
1926 // check if target is a textnode (safari)
1927 if ( event.target.nodeType === 3 ) {
1928 event.target = event.target.parentNode;
1931 // Add relatedTarget, if necessary
1932 if ( !event.relatedTarget && event.fromElement ) {
1933 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
1936 // Calculate pageX/Y if missing and clientX/Y available
1937 if ( event.pageX == null && event.clientX != null ) {
1938 var doc = document.documentElement, body = document.body;
1939 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
1940 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
1943 // Add which for key events
1944 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
1945 event.which = event.charCode || event.keyCode;
1948 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
1949 if ( !event.metaKey && event.ctrlKey ) {
1950 event.metaKey = event.ctrlKey;
1953 // Add which for click: 1 === left; 2 === middle; 3 === right
1954 // Note: button is not normalized, so don't use it
1955 if ( !event.which && event.button !== undefined ) {
1956 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
1962 // Deprecated, use jQuery.guid instead
1965 // Deprecated, use jQuery.proxy instead
1966 proxy: jQuery.proxy,
1970 // Make sure the ready event is setup
1971 setup: jQuery.bindReady,
1972 teardown: jQuery.noop
1976 add: function( proxy, data, namespaces, live ) {
1977 jQuery.extend( proxy, data || {} );
1979 proxy.guid += data.selector + data.live;
1980 data.liveProxy = proxy;
1982 jQuery.event.add( this, data.live, liveHandler, data );
1986 remove: function( namespaces ) {
1987 if ( namespaces.length ) {
1988 var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
1990 jQuery.each( (jQuery.data(this, "events").live || {}), function() {
1991 if ( name.test(this.type) ) {
1997 jQuery.event.remove( this, namespaces[0], liveHandler );
2004 setup: function( data, namespaces, fn ) {
2005 // We only want to do this special case on windows
2006 if ( this.setInterval ) {
2007 this.onbeforeunload = fn;
2012 teardown: function( namespaces, fn ) {
2013 if ( this.onbeforeunload === fn ) {
2014 this.onbeforeunload = null;
2021 jQuery.Event = function( src ) {
2022 // Allow instantiation without the 'new' keyword
2023 if ( !this.preventDefault ) {
2024 return new jQuery.Event( src );
2028 if ( src && src.type ) {
2029 this.originalEvent = src;
2030 this.type = src.type;
2036 // timeStamp is buggy for some events on Firefox(#3843)
2037 // So we won't rely on the native value
2038 this.timeStamp = now();
2041 this[ expando ] = true;
2044 function returnFalse() {
2047 function returnTrue() {
2051 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2052 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2053 jQuery.Event.prototype = {
2054 preventDefault: function() {
2055 this.isDefaultPrevented = returnTrue;
2057 var e = this.originalEvent;
2062 // if preventDefault exists run it on the original event
2063 if ( e.preventDefault ) {
2066 // otherwise set the returnValue property of the original event to false (IE)
2067 e.returnValue = false;
2069 stopPropagation: function() {
2070 this.isPropagationStopped = returnTrue;
2072 var e = this.originalEvent;
2076 // if stopPropagation exists run it on the original event
2077 if ( e.stopPropagation ) {
2078 e.stopPropagation();
2080 // otherwise set the cancelBubble property of the original event to true (IE)
2081 e.cancelBubble = true;
2083 stopImmediatePropagation: function() {
2084 this.isImmediatePropagationStopped = returnTrue;
2085 this.stopPropagation();
2087 isDefaultPrevented: returnFalse,
2088 isPropagationStopped: returnFalse,
2089 isImmediatePropagationStopped: returnFalse
2092 // Checks if an event happened on an element within another element
2093 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2094 var withinElement = function( event ) {
2095 // Check if mouse(over|out) are still within the same parent element
2096 var parent = event.relatedTarget;
2098 // Traverse up the tree
2099 while ( parent && parent !== this ) {
2100 // Firefox sometimes assigns relatedTarget a XUL element
2101 // which we cannot access the parentNode property of
2103 parent = parent.parentNode;
2105 // assuming we've left the element since we most likely mousedover a xul element
2111 if ( parent !== this ) {
2112 // set the correct event type
2113 event.type = event.data;
2115 // handle event if we actually just moused on to a non sub-element
2116 jQuery.event.handle.apply( this, arguments );
2121 // In case of event delegation, we only need to rename the event.type,
2122 // liveHandler will take care of the rest.
2123 delegate = function( event ) {
2124 event.type = event.data;
2125 jQuery.event.handle.apply( this, arguments );
2128 // Create mouseenter and mouseleave events
2130 mouseenter: "mouseover",
2131 mouseleave: "mouseout"
2132 }, function( orig, fix ) {
2133 jQuery.event.special[ orig ] = {
2134 setup: function( data ) {
2135 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2137 teardown: function( data ) {
2138 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2143 // submit delegation
2144 if ( !jQuery.support.submitBubbles ) {
2146 jQuery.event.special.submit = {
2147 setup: function( data, namespaces, fn ) {
2148 if ( this.nodeName.toLowerCase() !== "form" ) {
2149 jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) {
2150 var elem = e.target, type = elem.type;
2152 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2153 return trigger( "submit", this, arguments );
2157 jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) {
2158 var elem = e.target, type = elem.type;
2160 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2161 return trigger( "submit", this, arguments );
2170 remove: function( namespaces, fn ) {
2171 jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") );
2172 jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") );
2178 // change delegation, happens here so we have bind.
2179 if ( !jQuery.support.changeBubbles ) {
2181 var formElems = /textarea|input|select/i;
2183 function getVal( elem ) {
2184 var type = elem.type, val = elem.value;
2186 if ( type === "radio" || type === "checkbox" ) {
2189 } else if ( type === "select-multiple" ) {
2190 val = elem.selectedIndex > -1 ?
2191 jQuery.map( elem.options, function( elem ) {
2192 return elem.selected;
2196 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2197 val = elem.selectedIndex;
2203 function testChange( e ) {
2204 var elem = e.target, data, val;
2206 if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
2210 data = jQuery.data( elem, "_change_data" );
2213 // the current data will be also retrieved by beforeactivate
2214 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2215 jQuery.data( elem, "_change_data", val );
2218 if ( data === undefined || val === data ) {
2222 if ( data != null || val ) {
2224 return jQuery.event.trigger( e, arguments[1], elem );
2228 jQuery.event.special.change = {
2230 focusout: testChange,
2232 click: function( e ) {
2233 var elem = e.target, type = elem.type;
2235 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2236 return testChange.call( this, e );
2240 // Change has to be called before submit
2241 // Keydown will be called before keypress, which is used in submit-event delegation
2242 keydown: function( e ) {
2243 var elem = e.target, type = elem.type;
2245 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2246 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2247 type === "select-multiple" ) {
2248 return testChange.call( this, e );
2252 // Beforeactivate happens also before the previous element is blurred
2253 // with this event you can't trigger a change event, but you can store
2254 // information/focus[in] is not needed anymore
2255 beforeactivate: function( e ) {
2256 var elem = e.target;
2258 if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) {
2259 jQuery.data( elem, "_change_data", getVal(elem) );
2263 setup: function( data, namespaces, fn ) {
2264 for ( var type in changeFilters ) {
2265 jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] );
2268 return formElems.test( this.nodeName );
2270 remove: function( namespaces, fn ) {
2271 for ( var type in changeFilters ) {
2272 jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] );
2275 return formElems.test( this.nodeName );
2279 var changeFilters = jQuery.event.special.change.filters;
2283 function trigger( type, elem, args ) {
2284 args[0].type = type;
2285 return jQuery.event.handle.apply( elem, args );
2288 // Create "bubbling" focus and blur events
2289 if ( document.addEventListener ) {
2290 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2291 jQuery.event.special[ fix ] = {
2293 this.addEventListener( orig, handler, true );
2295 teardown: function() {
2296 this.removeEventListener( orig, handler, true );
2300 function handler( e ) {
2301 e = jQuery.event.fix( e );
2303 return jQuery.event.handle.call( this, e );
2308 jQuery.each(["bind", "one"], function( i, name ) {
2309 jQuery.fn[ name ] = function( type, data, fn ) {
2310 // Handle object literals
2311 if ( typeof type === "object" ) {
2312 for ( var key in type ) {
2313 this[ name ](key, data, type[key], fn);
2318 if ( jQuery.isFunction( data ) ) {
2323 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2324 jQuery( this ).unbind( event, handler );
2325 return fn.apply( this, arguments );
2328 return type === "unload" && name !== "one" ?
2329 this.one( type, data, fn ) :
2330 this.each(function() {
2331 jQuery.event.add( this, type, handler, data );
2337 unbind: function( type, fn ) {
2338 // Handle object literals
2339 if ( typeof type === "object" && !type.preventDefault ) {
2340 for ( var key in type ) {
2341 this.unbind(key, type[key]);
2346 return this.each(function() {
2347 jQuery.event.remove( this, type, fn );
2350 trigger: function( type, data ) {
2351 return this.each(function() {
2352 jQuery.event.trigger( type, data, this );
2356 triggerHandler: function( type, data ) {
2358 var event = jQuery.Event( type );
2359 event.preventDefault();
2360 event.stopPropagation();
2361 jQuery.event.trigger( event, data, this[0] );
2362 return event.result;
2366 toggle: function( fn ) {
2367 // Save reference to arguments for access in closure
2368 var args = arguments, i = 1;
2370 // link all the functions, so any of them can unbind this click handler
2371 while ( i < args.length ) {
2372 jQuery.proxy( fn, args[ i++ ] );
2375 return this.click( jQuery.proxy( fn, function( event ) {
2376 // Figure out which function to execute
2377 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2378 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2380 // Make sure that clicks stop
2381 event.preventDefault();
2383 // and execute the function
2384 return args[ lastToggle ].apply( this, arguments ) || false;
2388 hover: function( fnOver, fnOut ) {
2389 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2393 jQuery.each(["live", "die"], function( i, name ) {
2394 jQuery.fn[ name ] = function( types, data, fn ) {
2397 if ( jQuery.isFunction( data ) ) {
2402 types = (types || "").split( /\s+/ );
2404 while ( (type = types[ i++ ]) != null ) {
2405 type = type === "focus" ? "focusin" : // focus --> focusin
2406 type === "blur" ? "focusout" : // blur --> focusout
2407 type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
2410 if ( name === "live" ) {
2411 // bind live handler
2412 jQuery( this.context ).bind( liveConvert( type, this.selector ), {
2413 data: data, selector: this.selector, live: type
2417 // unbind live handler
2418 jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
2426 function liveHandler( event ) {
2427 var stop, elems = [], selectors = [], args = arguments,
2428 related, match, fn, elem, j, i, l, data,
2429 live = jQuery.extend({}, jQuery.data( this, "events" ).live);
2431 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2432 if ( event.button && event.type === "click" ) {
2438 if ( fn.live === event.type ||
2439 fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) {
2442 if ( !(data.beforeFilter && data.beforeFilter[event.type] &&
2443 !data.beforeFilter[event.type](event)) ) {
2444 selectors.push( fn.selector );
2451 match = jQuery( event.target ).closest( selectors, event.currentTarget );
2453 for ( i = 0, l = match.length; i < l; i++ ) {
2456 elem = match[i].elem;
2459 if ( match[i].selector === fn.selector ) {
2460 // Those two events require additional checking
2461 if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) {
2462 related = jQuery( event.relatedTarget ).closest( fn.selector )[0];
2465 if ( !related || related !== elem ) {
2466 elems.push({ elem: elem, fn: fn });
2472 for ( i = 0, l = elems.length; i < l; i++ ) {
2474 event.currentTarget = match.elem;
2475 event.data = match.fn.data;
2476 if ( match.fn.apply( match.elem, args ) === false ) {
2485 function liveConvert( type, selector ) {
2486 return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
2489 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2490 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2491 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2493 // Handle event binding
2494 jQuery.fn[ name ] = function( fn ) {
2495 return fn ? this.bind( name, fn ) : this.trigger( name );
2498 if ( jQuery.attrFn ) {
2499 jQuery.attrFn[ name ] = true;
2503 // Prevent memory leaks in IE
2504 // Window isn't included so as not to unbind existing unload events
2506 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2507 if ( window.attachEvent && !window.addEventListener ) {
2508 window.attachEvent("onunload", function() {
2509 for ( var id in jQuery.cache ) {
2510 if ( jQuery.cache[ id ].handle ) {
2511 // Try/Catch is to handle iframes being unloaded, see #4280
2513 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2520 * Sizzle CSS Selector Engine - v1.0
2521 * Copyright 2009, The Dojo Foundation
2522 * Released under the MIT, BSD, and GPL Licenses.
2523 * More information: http://sizzlejs.com/
2527 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
2529 toString = Object.prototype.toString,
2530 hasDuplicate = false,
2531 baseHasDuplicate = true;
2533 // Here we check if the JavaScript engine is using some sort of
2534 // optimization where it does not always call our comparision
2535 // function. If that is the case, discard the hasDuplicate value.
2536 // Thus far that includes Google Chrome.
2537 [0, 0].sort(function(){
2538 baseHasDuplicate = false;
2542 var Sizzle = function(selector, context, results, seed) {
2543 results = results || [];
2544 var origContext = context = context || document;
2546 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
2550 if ( !selector || typeof selector !== "string" ) {
2554 var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
2557 // Reset the position of the chunker regexp (start from head)
2558 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
2569 if ( parts.length > 1 && origPOS.exec( selector ) ) {
2570 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
2571 set = posProcess( parts[0] + parts[1], context );
2573 set = Expr.relative[ parts[0] ] ?
2575 Sizzle( parts.shift(), context );
2577 while ( parts.length ) {
2578 selector = parts.shift();
2580 if ( Expr.relative[ selector ] ) {
2581 selector += parts.shift();
2584 set = posProcess( selector, set );
2588 // Take a shortcut and set the context if the root selector is an ID
2589 // (but not if it'll be faster if the inner selector is an ID)
2590 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
2591 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
2592 var ret = Sizzle.find( parts.shift(), context, contextXML );
2593 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
2598 { expr: parts.pop(), set: makeArray(seed) } :
2599 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
2600 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
2602 if ( parts.length > 0 ) {
2603 checkSet = makeArray(set);
2608 while ( parts.length ) {
2609 var cur = parts.pop(), pop = cur;
2611 if ( !Expr.relative[ cur ] ) {
2617 if ( pop == null ) {
2621 Expr.relative[ cur ]( checkSet, pop, contextXML );
2624 checkSet = parts = [];
2633 Sizzle.error( cur || selector );
2636 if ( toString.call(checkSet) === "[object Array]" ) {
2638 results.push.apply( results, checkSet );
2639 } else if ( context && context.nodeType === 1 ) {
2640 for ( var i = 0; checkSet[i] != null; i++ ) {
2641 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
2642 results.push( set[i] );
2646 for ( var i = 0; checkSet[i] != null; i++ ) {
2647 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
2648 results.push( set[i] );
2653 makeArray( checkSet, results );
2657 Sizzle( extra, origContext, results, seed );
2658 Sizzle.uniqueSort( results );
2664 Sizzle.uniqueSort = function(results){
2666 hasDuplicate = baseHasDuplicate;
2667 results.sort(sortOrder);
2669 if ( hasDuplicate ) {
2670 for ( var i = 1; i < results.length; i++ ) {
2671 if ( results[i] === results[i-1] ) {
2672 results.splice(i--, 1);
2681 Sizzle.matches = function(expr, set){
2682 return Sizzle(expr, null, null, set);
2685 Sizzle.find = function(expr, context, isXML){
2692 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
2693 var type = Expr.order[i], match;
2695 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
2696 var left = match[1];
2699 if ( left.substr( left.length - 1 ) !== "\\" ) {
2700 match[1] = (match[1] || "").replace(/\\/g, "");
2701 set = Expr.find[ type ]( match, context, isXML );
2702 if ( set != null ) {
2703 expr = expr.replace( Expr.match[ type ], "" );
2711 set = context.getElementsByTagName("*");
2714 return {set: set, expr: expr};
2717 Sizzle.filter = function(expr, set, inplace, not){
2718 var old = expr, result = [], curLoop = set, match, anyFound,
2719 isXMLFilter = set && set[0] && isXML(set[0]);
2721 while ( expr && set.length ) {
2722 for ( var type in Expr.filter ) {
2723 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
2724 var filter = Expr.filter[ type ], found, item, left = match[1];
2729 if ( left.substr( left.length - 1 ) === "\\" ) {
2733 if ( curLoop === result ) {
2737 if ( Expr.preFilter[ type ] ) {
2738 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
2741 anyFound = found = true;
2742 } else if ( match === true ) {
2748 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
2750 found = filter( item, match, i, curLoop );
2751 var pass = not ^ !!found;
2753 if ( inplace && found != null ) {
2759 } else if ( pass ) {
2760 result.push( item );
2767 if ( found !== undefined ) {
2772 expr = expr.replace( Expr.match[ type ], "" );
2783 // Improper expression
2784 if ( expr === old ) {
2785 if ( anyFound == null ) {
2786 Sizzle.error( expr );
2798 Sizzle.error = function( msg ) {
2799 throw "Syntax error, unrecognized expression: " + msg;
2802 var Expr = Sizzle.selectors = {
2803 order: [ "ID", "NAME", "TAG" ],
2805 ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
2806 CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
2807 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
2808 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
2809 TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
2810 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
2811 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
2812 PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
2816 "class": "className",
2820 href: function(elem){
2821 return elem.getAttribute("href");
2825 "+": function(checkSet, part){
2826 var isPartStr = typeof part === "string",
2827 isTag = isPartStr && !/\W/.test(part),
2828 isPartStrNotTag = isPartStr && !isTag;
2831 part = part.toLowerCase();
2834 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
2835 if ( (elem = checkSet[i]) ) {
2836 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
2838 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
2844 if ( isPartStrNotTag ) {
2845 Sizzle.filter( part, checkSet, true );
2848 ">": function(checkSet, part){
2849 var isPartStr = typeof part === "string";
2851 if ( isPartStr && !/\W/.test(part) ) {
2852 part = part.toLowerCase();
2854 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2855 var elem = checkSet[i];
2857 var parent = elem.parentNode;
2858 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
2862 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2863 var elem = checkSet[i];
2865 checkSet[i] = isPartStr ?
2867 elem.parentNode === part;
2872 Sizzle.filter( part, checkSet, true );
2876 "": function(checkSet, part, isXML){
2877 var doneName = done++, checkFn = dirCheck;
2879 if ( typeof part === "string" && !/\W/.test(part) ) {
2880 var nodeCheck = part = part.toLowerCase();
2881 checkFn = dirNodeCheck;
2884 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
2886 "~": function(checkSet, part, isXML){
2887 var doneName = done++, checkFn = dirCheck;
2889 if ( typeof part === "string" && !/\W/.test(part) ) {
2890 var nodeCheck = part = part.toLowerCase();
2891 checkFn = dirNodeCheck;
2894 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
2898 ID: function(match, context, isXML){
2899 if ( typeof context.getElementById !== "undefined" && !isXML ) {
2900 var m = context.getElementById(match[1]);
2901 return m ? [m] : [];
2904 NAME: function(match, context){
2905 if ( typeof context.getElementsByName !== "undefined" ) {
2906 var ret = [], results = context.getElementsByName(match[1]);
2908 for ( var i = 0, l = results.length; i < l; i++ ) {
2909 if ( results[i].getAttribute("name") === match[1] ) {
2910 ret.push( results[i] );
2914 return ret.length === 0 ? null : ret;
2917 TAG: function(match, context){
2918 return context.getElementsByTagName(match[1]);
2922 CLASS: function(match, curLoop, inplace, result, not, isXML){
2923 match = " " + match[1].replace(/\\/g, "") + " ";
2929 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
2931 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
2933 result.push( elem );
2935 } else if ( inplace ) {
2943 ID: function(match){
2944 return match[1].replace(/\\/g, "");
2946 TAG: function(match, curLoop){
2947 return match[1].toLowerCase();
2949 CHILD: function(match){
2950 if ( match[1] === "nth" ) {
2951 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
2952 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
2953 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
2954 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
2956 // calculate the numbers (first)n+(last) including if they are negative
2957 match[2] = (test[1] + (test[2] || 1)) - 0;
2958 match[3] = test[3] - 0;
2961 // TODO: Move to normal caching system
2966 ATTR: function(match, curLoop, inplace, result, not, isXML){
2967 var name = match[1].replace(/\\/g, "");
2969 if ( !isXML && Expr.attrMap[name] ) {
2970 match[1] = Expr.attrMap[name];
2973 if ( match[2] === "~=" ) {
2974 match[4] = " " + match[4] + " ";
2979 PSEUDO: function(match, curLoop, inplace, result, not){
2980 if ( match[1] === "not" ) {
2981 // If we're dealing with a complex expression, or a simple one
2982 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
2983 match[3] = Sizzle(match[3], null, null, curLoop);
2985 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
2987 result.push.apply( result, ret );
2991 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
2997 POS: function(match){
2998 match.unshift( true );
3003 enabled: function(elem){
3004 return elem.disabled === false && elem.type !== "hidden";
3006 disabled: function(elem){
3007 return elem.disabled === true;
3009 checked: function(elem){
3010 return elem.checked === true;
3012 selected: function(elem){
3013 // Accessing this property makes selected-by-default
3014 // options in Safari work properly
3015 elem.parentNode.selectedIndex;
3016 return elem.selected === true;
3018 parent: function(elem){
3019 return !!elem.firstChild;
3021 empty: function(elem){
3022 return !elem.firstChild;
3024 has: function(elem, i, match){
3025 return !!Sizzle( match[3], elem ).length;
3027 header: function(elem){
3028 return /h\d/i.test( elem.nodeName );
3030 text: function(elem){
3031 return "text" === elem.type;
3033 radio: function(elem){
3034 return "radio" === elem.type;
3036 checkbox: function(elem){
3037 return "checkbox" === elem.type;
3039 file: function(elem){
3040 return "file" === elem.type;
3042 password: function(elem){
3043 return "password" === elem.type;
3045 submit: function(elem){
3046 return "submit" === elem.type;
3048 image: function(elem){
3049 return "image" === elem.type;
3051 reset: function(elem){
3052 return "reset" === elem.type;
3054 button: function(elem){
3055 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3057 input: function(elem){
3058 return /input|select|textarea|button/i.test(elem.nodeName);
3062 first: function(elem, i){
3065 last: function(elem, i, match, array){
3066 return i === array.length - 1;
3068 even: function(elem, i){
3071 odd: function(elem, i){
3074 lt: function(elem, i, match){
3075 return i < match[3] - 0;
3077 gt: function(elem, i, match){
3078 return i > match[3] - 0;
3080 nth: function(elem, i, match){
3081 return match[3] - 0 === i;
3083 eq: function(elem, i, match){
3084 return match[3] - 0 === i;
3088 PSEUDO: function(elem, match, i, array){
3089 var name = match[1], filter = Expr.filters[ name ];
3092 return filter( elem, i, match, array );
3093 } else if ( name === "contains" ) {
3094 return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
3095 } else if ( name === "not" ) {
3098 for ( var i = 0, l = not.length; i < l; i++ ) {
3099 if ( not[i] === elem ) {
3106 Sizzle.error( "Syntax error, unrecognized expression: " + name );
3109 CHILD: function(elem, match){
3110 var type = match[1], node = elem;
3114 while ( (node = node.previousSibling) ) {
3115 if ( node.nodeType === 1 ) {
3119 if ( type === "first" ) {
3124 while ( (node = node.nextSibling) ) {
3125 if ( node.nodeType === 1 ) {
3131 var first = match[2], last = match[3];
3133 if ( first === 1 && last === 0 ) {
3137 var doneName = match[0],
3138 parent = elem.parentNode;
3140 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3142 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3143 if ( node.nodeType === 1 ) {
3144 node.nodeIndex = ++count;
3147 parent.sizcache = doneName;
3150 var diff = elem.nodeIndex - last;
3151 if ( first === 0 ) {
3154 return ( diff % first === 0 && diff / first >= 0 );
3158 ID: function(elem, match){
3159 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3161 TAG: function(elem, match){
3162 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3164 CLASS: function(elem, match){
3165 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3166 .indexOf( match ) > -1;
3168 ATTR: function(elem, match){
3169 var name = match[1],
3170 result = Expr.attrHandle[ name ] ?
3171 Expr.attrHandle[ name ]( elem ) :
3172 elem[ name ] != null ?
3174 elem.getAttribute( name ),
3175 value = result + "",
3179 return result == null ?
3184 value.indexOf(check) >= 0 :
3186 (" " + value + " ").indexOf(check) >= 0 :
3188 value && result !== false :
3192 value.indexOf(check) === 0 :
3194 value.substr(value.length - check.length) === check :
3196 value === check || value.substr(0, check.length + 1) === check + "-" :
3199 POS: function(elem, match, i, array){
3200 var name = match[2], filter = Expr.setFilters[ name ];
3203 return filter( elem, i, match, array );
3209 var origPOS = Expr.match.POS;
3211 for ( var type in Expr.match ) {
3212 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
3213 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
3214 return "\\" + (num - 0 + 1);
3218 var makeArray = function(array, results) {
3219 array = Array.prototype.slice.call( array, 0 );
3222 results.push.apply( results, array );
3229 // Perform a simple check to determine if the browser is capable of
3230 // converting a NodeList to an array using builtin methods.
3232 Array.prototype.slice.call( document.documentElement.childNodes, 0 );
3234 // Provide a fallback method if it does not work
3236 makeArray = function(array, results) {
3237 var ret = results || [];
3239 if ( toString.call(array) === "[object Array]" ) {
3240 Array.prototype.push.apply( ret, array );
3242 if ( typeof array.length === "number" ) {
3243 for ( var i = 0, l = array.length; i < l; i++ ) {
3244 ret.push( array[i] );
3247 for ( var i = 0; array[i]; i++ ) {
3248 ret.push( array[i] );
3259 if ( document.documentElement.compareDocumentPosition ) {
3260 sortOrder = function( a, b ) {
3261 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3263 hasDuplicate = true;
3265 return a.compareDocumentPosition ? -1 : 1;
3268 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
3270 hasDuplicate = true;
3274 } else if ( "sourceIndex" in document.documentElement ) {
3275 sortOrder = function( a, b ) {
3276 if ( !a.sourceIndex || !b.sourceIndex ) {
3278 hasDuplicate = true;
3280 return a.sourceIndex ? -1 : 1;
3283 var ret = a.sourceIndex - b.sourceIndex;
3285 hasDuplicate = true;
3289 } else if ( document.createRange ) {
3290 sortOrder = function( a, b ) {
3291 if ( !a.ownerDocument || !b.ownerDocument ) {
3293 hasDuplicate = true;
3295 return a.ownerDocument ? -1 : 1;
3298 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
3299 aRange.setStart(a, 0);
3300 aRange.setEnd(a, 0);
3301 bRange.setStart(b, 0);
3302 bRange.setEnd(b, 0);
3303 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
3305 hasDuplicate = true;
3311 // Utility function for retreiving the text value of an array of DOM nodes
3312 function getText( elems ) {
3315 for ( var i = 0; elems[i]; i++ ) {
3318 // Get the text from text nodes and CDATA nodes
3319 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3320 ret += elem.nodeValue;
3322 // Traverse everything else, except comment nodes
3323 } else if ( elem.nodeType !== 8 ) {
3324 ret += getText( elem.childNodes );
3331 // Check to see if the browser returns elements by name when
3332 // querying by getElementById (and provide a workaround)
3334 // We're going to inject a fake input element with a specified name
3335 var form = document.createElement("div"),
3336 id = "script" + (new Date).getTime();
3337 form.innerHTML = "<a name='" + id + "'/>";
3339 // Inject it into the root element, check its status, and remove it quickly
3340 var root = document.documentElement;
3341 root.insertBefore( form, root.firstChild );
3343 // The workaround has to do additional checks after a getElementById
3344 // Which slows things down for other browsers (hence the branching)
3345 if ( document.getElementById( id ) ) {
3346 Expr.find.ID = function(match, context, isXML){
3347 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3348 var m = context.getElementById(match[1]);
3349 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
3353 Expr.filter.ID = function(elem, match){
3354 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
3355 return elem.nodeType === 1 && node && node.nodeValue === match;
3359 root.removeChild( form );
3360 root = form = null; // release memory in IE
3364 // Check to see if the browser returns only elements
3365 // when doing getElementsByTagName("*")
3367 // Create a fake element
3368 var div = document.createElement("div");
3369 div.appendChild( document.createComment("") );
3371 // Make sure no comments are found
3372 if ( div.getElementsByTagName("*").length > 0 ) {
3373 Expr.find.TAG = function(match, context){
3374 var results = context.getElementsByTagName(match[1]);
3376 // Filter out possible comments
3377 if ( match[1] === "*" ) {
3380 for ( var i = 0; results[i]; i++ ) {
3381 if ( results[i].nodeType === 1 ) {
3382 tmp.push( results[i] );
3393 // Check to see if an attribute returns normalized href attributes
3394 div.innerHTML = "<a href='#'></a>";
3395 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
3396 div.firstChild.getAttribute("href") !== "#" ) {
3397 Expr.attrHandle.href = function(elem){
3398 return elem.getAttribute("href", 2);
3402 div = null; // release memory in IE
3405 if ( document.querySelectorAll ) {
3407 var oldSizzle = Sizzle, div = document.createElement("div");
3408 div.innerHTML = "<p class='TEST'></p>";
3410 // Safari can't handle uppercase or unicode characters when
3412 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
3416 Sizzle = function(query, context, extra, seed){
3417 context = context || document;
3419 // Only use querySelectorAll on non-XML documents
3420 // (ID selectors don't work in non-HTML documents)
3421 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
3423 return makeArray( context.querySelectorAll(query), extra );
3427 return oldSizzle(query, context, extra, seed);
3430 for ( var prop in oldSizzle ) {
3431 Sizzle[ prop ] = oldSizzle[ prop ];
3434 div = null; // release memory in IE
3439 var div = document.createElement("div");
3441 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
3443 // Opera can't find a second classname (in 9.6)
3444 // Also, make sure that getElementsByClassName actually exists
3445 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
3449 // Safari caches class attributes, doesn't catch changes (in 3.2)
3450 div.lastChild.className = "e";
3452 if ( div.getElementsByClassName("e").length === 1 ) {
3456 Expr.order.splice(1, 0, "CLASS");
3457 Expr.find.CLASS = function(match, context, isXML) {
3458 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
3459 return context.getElementsByClassName(match[1]);
3463 div = null; // release memory in IE
3466 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
3467 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
3468 var elem = checkSet[i];
3474 if ( elem.sizcache === doneName ) {
3475 match = checkSet[elem.sizset];
3479 if ( elem.nodeType === 1 && !isXML ){
3480 elem.sizcache = doneName;
3484 if ( elem.nodeName.toLowerCase() === cur ) {
3492 checkSet[i] = match;
3497 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
3498 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
3499 var elem = checkSet[i];
3505 if ( elem.sizcache === doneName ) {
3506 match = checkSet[elem.sizset];
3510 if ( elem.nodeType === 1 ) {
3512 elem.sizcache = doneName;
3515 if ( typeof cur !== "string" ) {
3516 if ( elem === cur ) {
3521 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
3530 checkSet[i] = match;
3535 var contains = document.compareDocumentPosition ? function(a, b){
3536 return a.compareDocumentPosition(b) & 16;
3538 return a !== b && (a.contains ? a.contains(b) : true);
3541 var isXML = function(elem){
3542 // documentElement is verified for cases where it doesn't yet exist
3543 // (such as loading iframes in IE - #4833)
3544 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
3545 return documentElement ? documentElement.nodeName !== "HTML" : false;
3548 var posProcess = function(selector, context){
3549 var tmpSet = [], later = "", match,
3550 root = context.nodeType ? [context] : context;
3552 // Position selectors must be done after the filter
3553 // And so must :not(positional) so we move all PSEUDOs to the end
3554 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
3556 selector = selector.replace( Expr.match.PSEUDO, "" );
3559 selector = Expr.relative[selector] ? selector + "*" : selector;
3561 for ( var i = 0, l = root.length; i < l; i++ ) {
3562 Sizzle( selector, root[i], tmpSet );
3565 return Sizzle.filter( later, tmpSet );
3569 jQuery.find = Sizzle;
3570 jQuery.expr = Sizzle.selectors;
3571 jQuery.expr[":"] = jQuery.expr.filters;
3572 jQuery.unique = Sizzle.uniqueSort;
3573 jQuery.getText = getText;
3574 jQuery.isXMLDoc = isXML;
3575 jQuery.contains = contains;
3579 window.Sizzle = Sizzle;
3582 var runtil = /Until$/,
3583 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
3584 // Note: This RegExp should be improved, or likely pulled from Sizzle
3585 rmultiselector = /,/,
3586 slice = Array.prototype.slice;
3588 // Implement the identical functionality for filter and not
3589 var winnow = function( elements, qualifier, keep ) {
3590 if ( jQuery.isFunction( qualifier ) ) {
3591 return jQuery.grep(elements, function( elem, i ) {
3592 return !!qualifier.call( elem, i, elem ) === keep;
3595 } else if ( qualifier.nodeType ) {
3596 return jQuery.grep(elements, function( elem, i ) {
3597 return (elem === qualifier) === keep;
3600 } else if ( typeof qualifier === "string" ) {
3601 var filtered = jQuery.grep(elements, function( elem ) {
3602 return elem.nodeType === 1;
3605 if ( isSimple.test( qualifier ) ) {
3606 return jQuery.filter(qualifier, filtered, !keep);
3608 qualifier = jQuery.filter( qualifier, filtered );
3612 return jQuery.grep(elements, function( elem, i ) {
3613 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
3618 find: function( selector ) {
3619 var ret = this.pushStack( "", "find", selector ), length = 0;
3621 for ( var i = 0, l = this.length; i < l; i++ ) {
3622 length = ret.length;
3623 jQuery.find( selector, this[i], ret );
3626 // Make sure that the results are unique
3627 for ( var n = length; n < ret.length; n++ ) {
3628 for ( var r = 0; r < length; r++ ) {
3629 if ( ret[r] === ret[n] ) {
3641 has: function( target ) {
3642 var targets = jQuery( target );
3643 return this.filter(function() {
3644 for ( var i = 0, l = targets.length; i < l; i++ ) {
3645 if ( jQuery.contains( this, targets[i] ) ) {
3652 not: function( selector ) {
3653 return this.pushStack( winnow(this, selector, false), "not", selector);
3656 filter: function( selector ) {
3657 return this.pushStack( winnow(this, selector, true), "filter", selector );
3660 is: function( selector ) {
3661 return !!selector && jQuery.filter( selector, this ).length > 0;
3664 closest: function( selectors, context ) {
3665 if ( jQuery.isArray( selectors ) ) {
3666 var ret = [], cur = this[0], match, matches = {}, selector;
3668 if ( cur && selectors.length ) {
3669 for ( var i = 0, l = selectors.length; i < l; i++ ) {
3670 selector = selectors[i];
3672 if ( !matches[selector] ) {
3673 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
3674 jQuery( selector, context || this.context ) :
3679 while ( cur && cur.ownerDocument && cur !== context ) {
3680 for ( selector in matches ) {
3681 match = matches[selector];
3683 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
3684 ret.push({ selector: selector, elem: cur });
3685 delete matches[selector];
3688 cur = cur.parentNode;
3695 var pos = jQuery.expr.match.POS.test( selectors ) ?
3696 jQuery( selectors, context || this.context ) : null;
3698 return this.map(function( i, cur ) {
3699 while ( cur && cur.ownerDocument && cur !== context ) {
3700 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
3703 cur = cur.parentNode;
3709 // Determine the position of an element within
3710 // the matched set of elements
3711 index: function( elem ) {
3712 if ( !elem || typeof elem === "string" ) {
3713 return jQuery.inArray( this[0],
3714 // If it receives a string, the selector is used
3715 // If it receives nothing, the siblings are used
3716 elem ? jQuery( elem ) : this.parent().children() );
3718 // Locate the position of the desired element
3719 return jQuery.inArray(
3720 // If it receives a jQuery object, the first element is used
3721 elem.jquery ? elem[0] : elem, this );
3724 add: function( selector, context ) {
3725 var set = typeof selector === "string" ?
3726 jQuery( selector, context || this.context ) :
3727 jQuery.makeArray( selector ),
3728 all = jQuery.merge( this.get(), set );
3730 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
3732 jQuery.unique( all ) );
3735 andSelf: function() {
3736 return this.add( this.prevObject );
3740 // A painfully simple check to see if an element is disconnected
3741 // from a document (should be improved, where feasible).
3742 function isDisconnected( node ) {
3743 return !node || !node.parentNode || node.parentNode.nodeType === 11;
3747 parent: function( elem ) {
3748 var parent = elem.parentNode;
3749 return parent && parent.nodeType !== 11 ? parent : null;
3751 parents: function( elem ) {
3752 return jQuery.dir( elem, "parentNode" );
3754 parentsUntil: function( elem, i, until ) {
3755 return jQuery.dir( elem, "parentNode", until );
3757 next: function( elem ) {
3758 return jQuery.nth( elem, 2, "nextSibling" );
3760 prev: function( elem ) {
3761 return jQuery.nth( elem, 2, "previousSibling" );
3763 nextAll: function( elem ) {
3764 return jQuery.dir( elem, "nextSibling" );
3766 prevAll: function( elem ) {
3767 return jQuery.dir( elem, "previousSibling" );
3769 nextUntil: function( elem, i, until ) {
3770 return jQuery.dir( elem, "nextSibling", until );
3772 prevUntil: function( elem, i, until ) {
3773 return jQuery.dir( elem, "previousSibling", until );
3775 siblings: function( elem ) {
3776 return jQuery.sibling( elem.parentNode.firstChild, elem );
3778 children: function( elem ) {
3779 return jQuery.sibling( elem.firstChild );
3781 contents: function( elem ) {
3782 return jQuery.nodeName( elem, "iframe" ) ?
3783 elem.contentDocument || elem.contentWindow.document :
3784 jQuery.makeArray( elem.childNodes );
3786 }, function( name, fn ) {
3787 jQuery.fn[ name ] = function( until, selector ) {
3788 var ret = jQuery.map( this, fn, until );
3790 if ( !runtil.test( name ) ) {
3794 if ( selector && typeof selector === "string" ) {
3795 ret = jQuery.filter( selector, ret );
3798 ret = this.length > 1 ? jQuery.unique( ret ) : ret;
3800 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
3801 ret = ret.reverse();
3804 return this.pushStack( ret, name, slice.call(arguments).join(",") );
3809 filter: function( expr, elems, not ) {
3811 expr = ":not(" + expr + ")";
3814 return jQuery.find.matches(expr, elems);
3817 dir: function( elem, dir, until ) {
3818 var matched = [], cur = elem[dir];
3819 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
3820 if ( cur.nodeType === 1 ) {
3821 matched.push( cur );
3828 nth: function( cur, result, dir, elem ) {
3829 result = result || 1;
3832 for ( ; cur; cur = cur[dir] ) {
3833 if ( cur.nodeType === 1 && ++num === result ) {
3841 sibling: function( n, elem ) {
3844 for ( ; n; n = n.nextSibling ) {
3845 if ( n.nodeType === 1 && n !== elem ) {
3853 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
3854 rleadingWhitespace = /^\s+/,
3855 rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
3856 rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
3857 rtagName = /<([\w:]+)/,
3860 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
3861 fcloseTag = function( all, front, tag ) {
3862 return rselfClosing.test( tag ) ?
3864 front + "></" + tag + ">";
3867 option: [ 1, "<select multiple='multiple'>", "</select>" ],
3868 legend: [ 1, "<fieldset>", "</fieldset>" ],
3869 thead: [ 1, "<table>", "</table>" ],
3870 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
3871 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
3872 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
3873 area: [ 1, "<map>", "</map>" ],
3874 _default: [ 0, "", "" ]
3877 wrapMap.optgroup = wrapMap.option;
3878 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
3879 wrapMap.th = wrapMap.td;
3881 // IE can't serialize <link> and <script> tags normally
3882 if ( !jQuery.support.htmlSerialize ) {
3883 wrapMap._default = [ 1, "div<div>", "</div>" ];
3887 text: function( text ) {
3888 if ( jQuery.isFunction(text) ) {
3889 return this.each(function(i) {
3890 var self = jQuery(this);
3891 self.text( text.call(this, i, self.text()) );
3895 if ( typeof text !== "object" && text !== undefined ) {
3896 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
3899 return jQuery.getText( this );
3902 wrapAll: function( html ) {
3903 if ( jQuery.isFunction( html ) ) {
3904 return this.each(function(i) {
3905 jQuery(this).wrapAll( html.call(this, i) );
3910 // The elements to wrap the target around
3911 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
3913 if ( this[0].parentNode ) {
3914 wrap.insertBefore( this[0] );
3917 wrap.map(function() {
3920 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
3921 elem = elem.firstChild;
3931 wrapInner: function( html ) {
3932 if ( jQuery.isFunction( html ) ) {
3933 return this.each(function(i) {
3934 jQuery(this).wrapInner( html.call(this, i) );
3938 return this.each(function() {
3939 var self = jQuery( this ), contents = self.contents();
3941 if ( contents.length ) {
3942 contents.wrapAll( html );
3945 self.append( html );
3950 wrap: function( html ) {
3951 return this.each(function() {
3952 jQuery( this ).wrapAll( html );
3956 unwrap: function() {
3957 return this.parent().each(function() {
3958 if ( !jQuery.nodeName( this, "body" ) ) {
3959 jQuery( this ).replaceWith( this.childNodes );
3964 append: function() {
3965 return this.domManip(arguments, true, function( elem ) {
3966 if ( this.nodeType === 1 ) {
3967 this.appendChild( elem );
3972 prepend: function() {
3973 return this.domManip(arguments, true, function( elem ) {
3974 if ( this.nodeType === 1 ) {
3975 this.insertBefore( elem, this.firstChild );
3980 before: function() {
3981 if ( this[0] && this[0].parentNode ) {
3982 return this.domManip(arguments, false, function( elem ) {
3983 this.parentNode.insertBefore( elem, this );
3985 } else if ( arguments.length ) {
3986 var set = jQuery(arguments[0]);
3987 set.push.apply( set, this.toArray() );
3988 return this.pushStack( set, "before", arguments );
3993 if ( this[0] && this[0].parentNode ) {
3994 return this.domManip(arguments, false, function( elem ) {
3995 this.parentNode.insertBefore( elem, this.nextSibling );
3997 } else if ( arguments.length ) {
3998 var set = this.pushStack( this, "after", arguments );
3999 set.push.apply( set, jQuery(arguments[0]).toArray() );
4004 clone: function( events ) {
4006 var ret = this.map(function() {
4007 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4008 // IE copies events bound via attachEvent when
4009 // using cloneNode. Calling detachEvent on the
4010 // clone will also remove the events from the orignal
4011 // In order to get around this, we use innerHTML.
4012 // Unfortunately, this means some modifications to
4013 // attributes in IE that are actually only stored
4014 // as properties will not be copied (such as the
4015 // the name attribute on an input).
4016 var html = this.outerHTML, ownerDocument = this.ownerDocument;
4018 var div = ownerDocument.createElement("div");
4019 div.appendChild( this.cloneNode(true) );
4020 html = div.innerHTML;
4023 return jQuery.clean([html.replace(rinlinejQuery, "")
4024 .replace(rleadingWhitespace, "")], ownerDocument)[0];
4026 return this.cloneNode(true);
4030 // Copy the events from the original to the clone
4031 if ( events === true ) {
4032 cloneCopyEvent( this, ret );
4033 cloneCopyEvent( this.find("*"), ret.find("*") );
4036 // Return the cloned set
4040 html: function( value ) {
4041 if ( value === undefined ) {
4042 return this[0] && this[0].nodeType === 1 ?
4043 this[0].innerHTML.replace(rinlinejQuery, "") :
4046 // See if we can take a shortcut and just use innerHTML
4047 } else if ( typeof value === "string" && !/<script/i.test( value ) &&
4048 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4049 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4051 value = value.replace(rxhtmlTag, fcloseTag);
4054 for ( var i = 0, l = this.length; i < l; i++ ) {
4055 // Remove element nodes and prevent memory leaks
4056 if ( this[i].nodeType === 1 ) {
4057 jQuery.cleanData( this[i].getElementsByTagName("*") );
4058 this[i].innerHTML = value;
4062 // If using innerHTML throws an exception, use the fallback method
4064 this.empty().append( value );
4067 } else if ( jQuery.isFunction( value ) ) {
4068 this.each(function(i){
4069 var self = jQuery(this), old = self.html();
4070 self.empty().append(function(){
4071 return value.call( this, i, old );
4076 this.empty().append( value );
4082 replaceWith: function( value ) {
4083 if ( this[0] && this[0].parentNode ) {
4084 // Make sure that the elements are removed from the DOM before they are inserted
4085 // this can help fix replacing a parent with child elements
4086 if ( !jQuery.isFunction( value ) ) {
4087 value = jQuery( value ).detach();
4090 return this.each(function(i) {
4091 var self = jQuery(this), old = self.html();
4092 self.replaceWith( value.call( this, i, old ) );
4096 return this.each(function() {
4097 var next = this.nextSibling, parent = this.parentNode;
4099 jQuery(this).remove();
4102 jQuery(next).before( value );
4104 jQuery(parent).append( value );
4108 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4112 detach: function( selector ) {
4113 return this.remove( selector, true );
4116 domManip: function( args, table, callback ) {
4117 var results, first, value = args[0], scripts = [];
4119 // We can't cloneNode fragments that contain checked, in WebKit
4120 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4121 return this.each(function() {
4122 jQuery(this).domManip( args, table, callback, true );
4126 if ( jQuery.isFunction(value) ) {
4127 return this.each(function(i) {
4128 var self = jQuery(this);
4129 args[0] = value.call(this, i, table ? self.html() : undefined);
4130 self.domManip( args, table, callback );
4135 // If we're in a fragment, just use that instead of building a new one
4136 if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) {
4137 results = { fragment: args[0].parentNode };
4139 results = buildFragment( args, this, scripts );
4142 first = results.fragment.firstChild;
4145 table = table && jQuery.nodeName( first, "tr" );
4147 for ( var i = 0, l = this.length; i < l; i++ ) {
4150 root(this[i], first) :
4152 results.cacheable || this.length > 1 || i > 0 ?
4153 results.fragment.cloneNode(true) :
4160 jQuery.each( scripts, evalScript );
4166 function root( elem, cur ) {
4167 return jQuery.nodeName(elem, "table") ?
4168 (elem.getElementsByTagName("tbody")[0] ||
4169 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4175 function cloneCopyEvent(orig, ret) {
4178 ret.each(function() {
4179 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
4183 var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
4186 delete curData.handle;
4187 curData.events = {};
4189 for ( var type in events ) {
4190 for ( var handler in events[ type ] ) {
4191 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
4198 function buildFragment( args, nodes, scripts ) {
4199 var fragment, cacheable, cacheresults, doc;
4201 // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked
4202 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
4204 cacheresults = jQuery.fragments[ args[0] ];
4205 if ( cacheresults ) {
4206 if ( cacheresults !== 1 ) {
4207 fragment = cacheresults;
4213 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
4214 fragment = doc.createDocumentFragment();
4215 jQuery.clean( args, doc, fragment, scripts );
4219 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
4222 return { fragment: fragment, cacheable: cacheable };
4225 jQuery.fragments = {};
4229 prependTo: "prepend",
4230 insertBefore: "before",
4231 insertAfter: "after",
4232 replaceAll: "replaceWith"
4233 }, function( name, original ) {
4234 jQuery.fn[ name ] = function( selector ) {
4235 var ret = [], insert = jQuery( selector );
4237 for ( var i = 0, l = insert.length; i < l; i++ ) {
4238 var elems = (i > 0 ? this.clone(true) : this).get();
4239 jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
4240 ret = ret.concat( elems );
4242 return this.pushStack( ret, name, insert.selector );
4247 // keepData is for internal use only--do not document
4248 remove: function( selector, keepData ) {
4249 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
4250 if ( !keepData && this.nodeType === 1 ) {
4251 jQuery.cleanData( this.getElementsByTagName("*") );
4252 jQuery.cleanData( [ this ] );
4255 if ( this.parentNode ) {
4256 this.parentNode.removeChild( this );
4262 // Remove element nodes and prevent memory leaks
4263 if ( this.nodeType === 1 ) {
4264 jQuery.cleanData( this.getElementsByTagName("*") );
4267 // Remove any remaining nodes
4268 while ( this.firstChild ) {
4269 this.removeChild( this.firstChild );
4272 }, function( name, fn ) {
4273 jQuery.fn[ name ] = function() {
4274 return this.each( fn, arguments );
4279 clean: function( elems, context, fragment, scripts ) {
4280 context = context || document;
4282 // !context.createElement fails in IE with an error but returns typeof 'object'
4283 if ( typeof context.createElement === "undefined" ) {
4284 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
4289 jQuery.each(elems, function( i, elem ) {
4290 if ( typeof elem === "number" ) {
4298 // Convert html string into DOM nodes
4299 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
4300 elem = context.createTextNode( elem );
4302 } else if ( typeof elem === "string" ) {
4303 // Fix "XHTML"-style tags in all browsers
4304 elem = elem.replace(rxhtmlTag, fcloseTag);
4306 // Trim whitespace, otherwise indexOf won't work as expected
4307 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
4308 wrap = wrapMap[ tag ] || wrapMap._default,
4310 div = context.createElement("div");
4312 // Go to html and back, then peel off extra wrappers
4313 div.innerHTML = wrap[1] + elem + wrap[2];
4315 // Move to the right depth
4317 div = div.lastChild;
4320 // Remove IE's autoinserted <tbody> from table fragments
4321 if ( !jQuery.support.tbody ) {
4323 // String was a <table>, *may* have spurious <tbody>
4324 var hasBody = rtbody.test(elem),
4325 tbody = tag === "table" && !hasBody ?
4326 div.firstChild && div.firstChild.childNodes :
4328 // String was a bare <thead> or <tfoot>
4329 wrap[1] === "<table>" && !hasBody ?
4333 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
4334 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
4335 tbody[ j ].parentNode.removeChild( tbody[ j ] );
4341 // IE completely kills leading whitespace when innerHTML is used
4342 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4343 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
4346 elem = jQuery.makeArray( div.childNodes );
4349 if ( elem.nodeType ) {
4352 ret = jQuery.merge( ret, elem );
4358 for ( var i = 0; ret[i]; i++ ) {
4359 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
4360 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
4362 if ( ret[i].nodeType === 1 ) {
4363 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
4365 fragment.appendChild( ret[i] );
4373 cleanData: function( elems ) {
4374 for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) {
4375 jQuery.event.remove( elem );
4376 jQuery.removeData( elem );
4380 // exclude the following css properties to add px
4381 var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
4382 ralpha = /alpha\([^)]*\)/,
4383 ropacity = /opacity=([^)]*)/,
4385 rdashAlpha = /-([a-z])/ig,
4386 rupper = /([A-Z])/g,
4387 rnumpx = /^-?\d+(?:px)?$/i,
4390 cssShow = { position: "absolute", visibility: "hidden", display:"block" },
4391 cssWidth = [ "Left", "Right" ],
4392 cssHeight = [ "Top", "Bottom" ],
4394 // cache check for defaultView.getComputedStyle
4395 getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
4396 // normalize float css property
4397 styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
4398 fcamelCase = function( all, letter ) {
4399 return letter.toUpperCase();
4402 jQuery.fn.css = function( name, value ) {
4403 return access( this, name, value, true, function( elem, name, value ) {
4404 if ( value === undefined ) {
4405 return jQuery.curCSS( elem, name );
4408 if ( typeof value === "number" && !rexclude.test(name) ) {
4412 jQuery.style( elem, name, value );
4417 style: function( elem, name, value ) {
4418 // don't set styles on text and comment nodes
4419 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
4423 // ignore negative width and height values #1599
4424 if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
4428 var style = elem.style || elem, set = value !== undefined;
4430 // IE uses filters for opacity
4431 if ( !jQuery.support.opacity && name === "opacity" ) {
4433 // IE has trouble with opacity if it does not have layout
4434 // Force it by setting the zoom level
4437 // Set the alpha filter to set the opacity
4438 var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
4439 var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
4440 style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
4443 return style.filter && style.filter.indexOf("opacity=") >= 0 ?
4444 (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
4448 // Make sure we're using the right name for getting the float value
4449 if ( rfloat.test( name ) ) {
4453 name = name.replace(rdashAlpha, fcamelCase);
4456 style[ name ] = value;
4459 return style[ name ];
4462 css: function( elem, name, force, extra ) {
4463 if ( name === "width" || name === "height" ) {
4464 var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
4467 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
4469 if ( extra === "border" ) {
4473 jQuery.each( which, function() {
4475 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
4478 if ( extra === "margin" ) {
4479 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
4481 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
4486 if ( elem.offsetWidth !== 0 ) {
4489 jQuery.swap( elem, props, getWH );
4492 return Math.max(0, Math.round(val));
4495 return jQuery.curCSS( elem, name, force );
4498 curCSS: function( elem, name, force ) {
4499 var ret, style = elem.style, filter;
4501 // IE uses filters for opacity
4502 if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
4503 ret = ropacity.test(elem.currentStyle.filter || "") ?
4504 (parseFloat(RegExp.$1) / 100) + "" :
4512 // Make sure we're using the right name for getting the float value
4513 if ( rfloat.test( name ) ) {
4517 if ( !force && style && style[ name ] ) {
4518 ret = style[ name ];
4520 } else if ( getComputedStyle ) {
4522 // Only "float" is needed here
4523 if ( rfloat.test( name ) ) {
4527 name = name.replace( rupper, "-$1" ).toLowerCase();
4529 var defaultView = elem.ownerDocument.defaultView;
4531 if ( !defaultView ) {
4535 var computedStyle = defaultView.getComputedStyle( elem, null );
4537 if ( computedStyle ) {
4538 ret = computedStyle.getPropertyValue( name );
4541 // We should always get a number back from opacity
4542 if ( name === "opacity" && ret === "" ) {
4546 } else if ( elem.currentStyle ) {
4547 var camelCase = name.replace(rdashAlpha, fcamelCase);
4549 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
4551 // From the awesome hack by Dean Edwards
4552 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
4554 // If we're not dealing with a regular pixel number
4555 // but a number that has a weird ending, we need to convert it to pixels
4556 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
4557 // Remember the original values
4558 var left = style.left, rsLeft = elem.runtimeStyle.left;
4560 // Put in the new values to get a computed value out
4561 elem.runtimeStyle.left = elem.currentStyle.left;
4562 style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
4563 ret = style.pixelLeft + "px";
4565 // Revert the changed values
4567 elem.runtimeStyle.left = rsLeft;
4574 // A method for quickly swapping in/out CSS properties to get correct calculations
4575 swap: function( elem, options, callback ) {
4578 // Remember the old values, and insert the new ones
4579 for ( var name in options ) {
4580 old[ name ] = elem.style[ name ];
4581 elem.style[ name ] = options[ name ];
4584 callback.call( elem );
4586 // Revert the old values
4587 for ( var name in options ) {
4588 elem.style[ name ] = old[ name ];
4593 if ( jQuery.expr && jQuery.expr.filters ) {
4594 jQuery.expr.filters.hidden = function( elem ) {
4595 var width = elem.offsetWidth, height = elem.offsetHeight,
4596 skip = elem.nodeName.toLowerCase() === "tr";
4598 return width === 0 && height === 0 && !skip ?
4600 width > 0 && height > 0 && !skip ?
4602 jQuery.curCSS(elem, "display") === "none";
4605 jQuery.expr.filters.visible = function( elem ) {
4606 return !jQuery.expr.filters.hidden( elem );
4610 rscript = /<script(.|\s)*?\/script>/gi,
4611 rselectTextarea = /select|textarea/i,
4612 rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
4615 rts = /(\?|&)_=.*?(&|$)/,
4616 rurl = /^(\w+:)?\/\/([^\/?#]+)/,
4620 // Keep a copy of the old load
4621 _load: jQuery.fn.load,
4623 load: function( url, params, callback ) {
4624 if ( typeof url !== "string" ) {
4625 return this._load( url );
4627 // Don't do a request if no elements are being requested
4628 } else if ( !this.length ) {
4632 var off = url.indexOf(" ");
4634 var selector = url.slice(off, url.length);
4635 url = url.slice(0, off);
4638 // Default to a GET request
4641 // If the second parameter was provided
4643 // If it's a function
4644 if ( jQuery.isFunction( params ) ) {
4645 // We assume that it's the callback
4649 // Otherwise, build a param string
4650 } else if ( typeof params === "object" ) {
4651 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
4658 // Request the remote document
4664 complete: function( res, status ) {
4665 // If successful, inject the HTML into all the matched elements
4666 if ( status === "success" || status === "notmodified" ) {
4667 // See if a selector was specified
4668 self.html( selector ?
4669 // Create a dummy div to hold the results
4671 // inject the contents of the document in, removing the scripts
4672 // to avoid any 'Permission Denied' errors in IE
4673 .append(res.responseText.replace(rscript, ""))
4675 // Locate the specified elements
4678 // If not, just inject the full result
4683 self.each( callback, [res.responseText, status, res] );
4691 serialize: function() {
4692 return jQuery.param(this.serializeArray());
4694 serializeArray: function() {
4695 return this.map(function() {
4696 return this.elements ? jQuery.makeArray(this.elements) : this;
4698 .filter(function() {
4699 return this.name && !this.disabled &&
4700 (this.checked || rselectTextarea.test(this.nodeName) ||
4701 rinput.test(this.type));
4703 .map(function( i, elem ) {
4704 var val = jQuery(this).val();
4706 return val == null ?
4708 jQuery.isArray(val) ?
4709 jQuery.map( val, function( val, i ) {
4710 return { name: elem.name, value: val };
4712 { name: elem.name, value: val };
4717 // Attach a bunch of functions for handling common AJAX events
4718 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
4719 jQuery.fn[o] = function( f ) {
4720 return this.bind(o, f);
4726 get: function( url, data, callback, type ) {
4727 // shift arguments if data argument was omited
4728 if ( jQuery.isFunction( data ) ) {
4729 type = type || callback;
4734 return jQuery.ajax({
4743 getScript: function( url, callback ) {
4744 return jQuery.get(url, null, callback, "script");
4747 getJSON: function( url, data, callback ) {
4748 return jQuery.get(url, data, callback, "json");
4751 post: function( url, data, callback, type ) {
4752 // shift arguments if data argument was omited
4753 if ( jQuery.isFunction( data ) ) {
4754 type = type || callback;
4759 return jQuery.ajax({
4768 ajaxSetup: function( settings ) {
4769 jQuery.extend( jQuery.ajaxSettings, settings );
4776 contentType: "application/x-www-form-urlencoded",
4786 // Create the request object; Microsoft failed to properly
4787 // implement the XMLHttpRequest in IE7 (can't request local files),
4788 // so we use the ActiveXObject when it is available
4789 // This function can be overriden by calling jQuery.ajaxSetup
4790 xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
4792 return new window.XMLHttpRequest();
4796 return new window.ActiveXObject("Microsoft.XMLHTTP");
4800 xml: "application/xml, text/xml",
4802 script: "text/javascript, application/javascript",
4803 json: "application/json, text/javascript",
4809 // Last-Modified header cache for next request
4813 ajax: function( origSettings ) {
4814 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
4816 var jsonp, status, data,
4817 callbackContext = origSettings && origSettings.context || s,
4818 type = s.type.toUpperCase();
4820 // convert data if not already a string
4821 if ( s.data && s.processData && typeof s.data !== "string" ) {
4822 s.data = jQuery.param( s.data, s.traditional );
4825 // Handle JSONP Parameter Callbacks
4826 if ( s.dataType === "jsonp" ) {
4827 if ( type === "GET" ) {
4828 if ( !jsre.test( s.url ) ) {
4829 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
4831 } else if ( !s.data || !jsre.test(s.data) ) {
4832 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
4834 s.dataType = "json";
4837 // Build temporary JSONP function
4838 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
4839 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
4841 // Replace the =? sequence both in the query string and the data
4843 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
4846 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
4848 // We need to make sure
4849 // that a JSONP style response is executed properly
4850 s.dataType = "script";
4852 // Handle JSONP-style loading
4853 window[ jsonp ] = window[ jsonp ] || function( tmp ) {
4858 window[ jsonp ] = undefined;
4861 delete window[ jsonp ];
4865 head.removeChild( script );
4870 if ( s.dataType === "script" && s.cache === null ) {
4874 if ( s.cache === false && type === "GET" ) {
4877 // try replacing _= if it is there
4878 var ret = s.url.replace(rts, "$1_=" + ts + "$2");
4880 // if nothing was replaced, add timestamp to the end
4881 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
4884 // If data is available, append data to url for get requests
4885 if ( s.data && type === "GET" ) {
4886 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
4889 // Watch for a new set of requests
4890 if ( s.global && ! jQuery.active++ ) {
4891 jQuery.event.trigger( "ajaxStart" );
4894 // Matches an absolute URL, and saves the domain
4895 var parts = rurl.exec( s.url ),
4896 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
4898 // If we're requesting a remote document
4899 // and trying to load JSON or Script with a GET
4900 if ( s.dataType === "script" && type === "GET" && remote ) {
4901 var head = document.getElementsByTagName("head")[0] || document.documentElement;
4902 var script = document.createElement("script");
4904 if ( s.scriptCharset ) {
4905 script.charset = s.scriptCharset;
4908 // Handle Script loading
4912 // Attach handlers for all browsers
4913 script.onload = script.onreadystatechange = function() {
4914 if ( !done && (!this.readyState ||
4915 this.readyState === "loaded" || this.readyState === "complete") ) {
4920 // Handle memory leak in IE
4921 script.onload = script.onreadystatechange = null;
4922 if ( head && script.parentNode ) {
4923 head.removeChild( script );
4929 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
4930 // This arises when a base node is used (#2709 and #4378).
4931 head.insertBefore( script, head.firstChild );
4933 // We handle everything using the script element injection
4937 var requestDone = false;
4939 // Create the request object
4947 // Passing null username, generates a login popup on Opera (#2865)
4949 xhr.open(type, s.url, s.async, s.username, s.password);
4951 xhr.open(type, s.url, s.async);
4954 // Need an extra try/catch for cross domain requests in Firefox 3
4956 // Set the correct header, if data is being sent
4957 if ( s.data || origSettings && origSettings.contentType ) {
4958 xhr.setRequestHeader("Content-Type", s.contentType);
4961 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
4962 if ( s.ifModified ) {
4963 if ( jQuery.lastModified[s.url] ) {
4964 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
4967 if ( jQuery.etag[s.url] ) {
4968 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
4972 // Set header so the called script knows that it's an XMLHttpRequest
4973 // Only send the header if it's not a remote XHR
4975 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
4978 // Set the Accepts header for the server, depending on the dataType
4979 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
4980 s.accepts[ s.dataType ] + ", */*" :
4981 s.accepts._default );
4984 // Allow custom headers/mimetypes and early abort
4985 if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
4986 // Handle the global AJAX counter
4987 if ( s.global && ! --jQuery.active ) {
4988 jQuery.event.trigger( "ajaxStop" );
4991 // close opended socket
4997 trigger("ajaxSend", [xhr, s]);
5000 // Wait for a response to come back
5001 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5002 // The request was aborted
5003 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5004 // Opera doesn't call onreadystatechange before this point
5005 // so we simulate the call
5006 if ( !requestDone ) {
5012 xhr.onreadystatechange = jQuery.noop;
5015 // The transfer is complete and the data is available, or the request timed out
5016 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5018 xhr.onreadystatechange = jQuery.noop;
5020 status = isTimeout === "timeout" ?
5022 !jQuery.httpSuccess( xhr ) ?
5024 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5030 if ( status === "success" ) {
5031 // Watch for, and catch, XML document parse errors
5033 // process the data (runs the xml through httpData regardless of callback)
5034 data = jQuery.httpData( xhr, s.dataType, s );
5036 status = "parsererror";
5041 // Make sure that the request was successful or notmodified
5042 if ( status === "success" || status === "notmodified" ) {
5043 // JSONP handles its own success callback
5048 jQuery.handleError(s, xhr, status, errMsg);
5051 // Fire the complete handlers
5054 if ( isTimeout === "timeout" ) {
5058 // Stop memory leaks
5065 // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
5066 // Opera doesn't fire onreadystatechange at all on abort
5068 var oldAbort = xhr.abort;
5069 xhr.abort = function() {
5071 oldAbort.call( xhr );
5074 onreadystatechange( "abort" );
5079 if ( s.async && s.timeout > 0 ) {
5080 setTimeout(function() {
5081 // Check to see if the request is still happening
5082 if ( xhr && !requestDone ) {
5083 onreadystatechange( "timeout" );
5090 xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
5092 jQuery.handleError(s, xhr, null, e);
5093 // Fire the complete handlers
5097 // firefox 1.5 doesn't fire statechange for sync requests
5099 onreadystatechange();
5102 function success() {
5103 // If a local callback was specified, fire it and pass it the data
5105 s.success.call( callbackContext, data, status, xhr );
5108 // Fire the global callback
5110 trigger( "ajaxSuccess", [xhr, s] );
5114 function complete() {
5117 s.complete.call( callbackContext, xhr, status);
5120 // The request was completed
5122 trigger( "ajaxComplete", [xhr, s] );
5125 // Handle the global AJAX counter
5126 if ( s.global && ! --jQuery.active ) {
5127 jQuery.event.trigger( "ajaxStop" );
5131 function trigger(type, args) {
5132 (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
5135 // return XMLHttpRequest to allow aborting the request etc.
5139 handleError: function( s, xhr, status, e ) {
5140 // If a local callback was specified, fire it
5142 s.error.call( s.context || s, xhr, status, e );
5145 // Fire the global callback
5147 (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
5151 // Counter for holding the number of active queries
5154 // Determines if an XMLHttpRequest was successful or not
5155 httpSuccess: function( xhr ) {
5157 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
5158 return !xhr.status && location.protocol === "file:" ||
5159 // Opera returns 0 when status is 304
5160 ( xhr.status >= 200 && xhr.status < 300 ) ||
5161 xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
5167 // Determines if an XMLHttpRequest returns NotModified
5168 httpNotModified: function( xhr, url ) {
5169 var lastModified = xhr.getResponseHeader("Last-Modified"),
5170 etag = xhr.getResponseHeader("Etag");
5172 if ( lastModified ) {
5173 jQuery.lastModified[url] = lastModified;
5177 jQuery.etag[url] = etag;
5180 // Opera returns 0 when status is 304
5181 return xhr.status === 304 || xhr.status === 0;
5184 httpData: function( xhr, type, s ) {
5185 var ct = xhr.getResponseHeader("content-type") || "",
5186 xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
5187 data = xml ? xhr.responseXML : xhr.responseText;
5189 if ( xml && data.documentElement.nodeName === "parsererror" ) {
5190 jQuery.error( "parsererror" );
5193 // Allow a pre-filtering function to sanitize the response
5194 // s is checked to keep backwards compatibility
5195 if ( s && s.dataFilter ) {
5196 data = s.dataFilter( data, type );
5199 // The filter can actually parse the response
5200 if ( typeof data === "string" ) {
5201 // Get the JavaScript object, if JSON is used.
5202 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
5203 data = jQuery.parseJSON( data );
5205 // If the type is "script", eval it in global context
5206 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
5207 jQuery.globalEval( data );
5214 // Serialize an array of form elements or a set of
5215 // key/values into a query string
5216 param: function( a, traditional ) {
5219 // Set traditional to true for jQuery <= 1.3.2 behavior.
5220 if ( traditional === undefined ) {
5221 traditional = jQuery.ajaxSettings.traditional;
5224 // If an array was passed in, assume that it is an array of form elements.
5225 if ( jQuery.isArray(a) || a.jquery ) {
5226 // Serialize the form elements
5227 jQuery.each( a, function() {
5228 add( this.name, this.value );
5232 // If traditional, encode the "old" way (the way 1.3.2 or older
5233 // did it), otherwise encode params recursively.
5234 for ( var prefix in a ) {
5235 buildParams( prefix, a[prefix] );
5239 // Return the resulting serialization
5240 return s.join("&").replace(r20, "+");
5242 function buildParams( prefix, obj ) {
5243 if ( jQuery.isArray(obj) ) {
5244 // Serialize array item.
5245 jQuery.each( obj, function( i, v ) {
5246 if ( traditional ) {
5247 // Treat each array item as a scalar.
5250 // If array item is non-scalar (array or object), encode its
5251 // numeric index to resolve deserialization ambiguity issues.
5252 // Note that rack (as of 1.0.0) can't currently deserialize
5253 // nested arrays properly, and attempting to do so may cause
5254 // a server error. Possible fixes are to modify rack's
5255 // deserialization algorithm or to provide an option or flag
5256 // to force array serialization to be shallow.
5257 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
5261 } else if ( !traditional && obj != null && typeof obj === "object" ) {
5262 // Serialize object item.
5263 jQuery.each( obj, function( k, v ) {
5264 buildParams( prefix + "[" + k + "]", v );
5268 // Serialize scalar item.
5273 function add( key, value ) {
5274 // If value is a function, invoke it and return its value
5275 value = jQuery.isFunction(value) ? value() : value;
5276 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
5280 var elemdisplay = {},
5281 rfxtypes = /toggle|show|hide/,
5282 rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
5285 // height animations
5286 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
5288 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
5289 // opacity animations
5294 show: function( speed, callback ) {
5295 if ( speed || speed === 0) {
5296 return this.animate( genFx("show", 3), speed, callback);
5299 for ( var i = 0, l = this.length; i < l; i++ ) {
5300 var old = jQuery.data(this[i], "olddisplay");
5302 this[i].style.display = old || "";
5304 if ( jQuery.css(this[i], "display") === "none" ) {
5305 var nodeName = this[i].nodeName, display;
5307 if ( elemdisplay[ nodeName ] ) {
5308 display = elemdisplay[ nodeName ];
5311 var elem = jQuery("<" + nodeName + " />").appendTo("body");
5313 display = elem.css("display");
5315 if ( display === "none" ) {
5321 elemdisplay[ nodeName ] = display;
5324 jQuery.data(this[i], "olddisplay", display);
5328 // Set the display of the elements in a second loop
5329 // to avoid the constant reflow
5330 for ( var j = 0, k = this.length; j < k; j++ ) {
5331 this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
5338 hide: function( speed, callback ) {
5339 if ( speed || speed === 0 ) {
5340 return this.animate( genFx("hide", 3), speed, callback);
5343 for ( var i = 0, l = this.length; i < l; i++ ) {
5344 var old = jQuery.data(this[i], "olddisplay");
5345 if ( !old && old !== "none" ) {
5346 jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
5350 // Set the display of the elements in a second loop
5351 // to avoid the constant reflow
5352 for ( var j = 0, k = this.length; j < k; j++ ) {
5353 this[j].style.display = "none";
5360 // Save the old toggle function
5361 _toggle: jQuery.fn.toggle,
5363 toggle: function( fn, fn2 ) {
5364 var bool = typeof fn === "boolean";
5366 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
5367 this._toggle.apply( this, arguments );
5369 } else if ( fn == null || bool ) {
5370 this.each(function() {
5371 var state = bool ? fn : jQuery(this).is(":hidden");
5372 jQuery(this)[ state ? "show" : "hide" ]();
5376 this.animate(genFx("toggle", 3), fn, fn2);
5382 fadeTo: function( speed, to, callback ) {
5383 return this.filter(":hidden").css("opacity", 0).show().end()
5384 .animate({opacity: to}, speed, callback);
5387 animate: function( prop, speed, easing, callback ) {
5388 var optall = jQuery.speed(speed, easing, callback);
5390 if ( jQuery.isEmptyObject( prop ) ) {
5391 return this.each( optall.complete );
5394 return this[ optall.queue === false ? "each" : "queue" ](function() {
5395 var opt = jQuery.extend({}, optall), p,
5396 hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
5400 var name = p.replace(rdashAlpha, fcamelCase);
5403 prop[ name ] = prop[ p ];
5408 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
5409 return opt.complete.call(this);
5412 if ( ( p === "height" || p === "width" ) && this.style ) {
5413 // Store display property
5414 opt.display = jQuery.css(this, "display");
5416 // Make sure that nothing sneaks out
5417 opt.overflow = this.style.overflow;
5420 if ( jQuery.isArray( prop[p] ) ) {
5421 // Create (if needed) and add to specialEasing
5422 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
5423 prop[p] = prop[p][0];
5427 if ( opt.overflow != null ) {
5428 this.style.overflow = "hidden";
5431 opt.curAnim = jQuery.extend({}, prop);
5433 jQuery.each( prop, function( name, val ) {
5434 var e = new jQuery.fx( self, opt, name );
5436 if ( rfxtypes.test(val) ) {
5437 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
5440 var parts = rfxnum.exec(val),
5441 start = e.cur(true) || 0;
5444 var end = parseFloat( parts[2] ),
5445 unit = parts[3] || "px";
5447 // We need to compute starting value
5448 if ( unit !== "px" ) {
5449 self.style[ name ] = (end || 1) + unit;
5450 start = ((end || 1) / e.cur(true)) * start;
5451 self.style[ name ] = start + unit;
5454 // If a +=/-= token was provided, we're doing a relative animation
5456 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
5459 e.custom( start, end, unit );
5462 e.custom( start, val, "" );
5467 // For JS strict compliance
5472 stop: function( clearQueue, gotoEnd ) {
5473 var timers = jQuery.timers;
5479 this.each(function() {
5480 // go in reverse order so anything added to the queue during the loop is ignored
5481 for ( var i = timers.length - 1; i >= 0; i-- ) {
5482 if ( timers[i].elem === this ) {
5484 // force the next step to be the last
5488 timers.splice(i, 1);
5493 // start the next in the queue if the last step wasn't forced
5503 // Generate shortcuts for custom animations
5505 slideDown: genFx("show", 1),
5506 slideUp: genFx("hide", 1),
5507 slideToggle: genFx("toggle", 1),
5508 fadeIn: { opacity: "show" },
5509 fadeOut: { opacity: "hide" }
5510 }, function( name, props ) {
5511 jQuery.fn[ name ] = function( speed, callback ) {
5512 return this.animate( props, speed, callback );
5517 speed: function( speed, easing, fn ) {
5518 var opt = speed && typeof speed === "object" ? speed : {
5519 complete: fn || !fn && easing ||
5520 jQuery.isFunction( speed ) && speed,
5522 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
5525 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
5526 jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
5529 opt.old = opt.complete;
5530 opt.complete = function() {
5531 if ( opt.queue !== false ) {
5532 jQuery(this).dequeue();
5534 if ( jQuery.isFunction( opt.old ) ) {
5535 opt.old.call( this );
5543 linear: function( p, n, firstNum, diff ) {
5544 return firstNum + diff * p;
5546 swing: function( p, n, firstNum, diff ) {
5547 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
5553 fx: function( elem, options, prop ) {
5554 this.options = options;
5558 if ( !options.orig ) {
5565 jQuery.fx.prototype = {
5566 // Simple function for setting a style value
5567 update: function() {
5568 if ( this.options.step ) {
5569 this.options.step.call( this.elem, this.now, this );
5572 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
5574 // Set display property to block for height/width animations
5575 if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
5576 this.elem.style.display = "block";
5580 // Get the current size
5581 cur: function( force ) {
5582 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
5583 return this.elem[ this.prop ];
5586 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
5587 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
5590 // Start an animation from one number to another
5591 custom: function( from, to, unit ) {
5592 this.startTime = now();
5595 this.unit = unit || this.unit || "px";
5596 this.now = this.start;
5597 this.pos = this.state = 0;
5600 function t( gotoEnd ) {
5601 return self.step(gotoEnd);
5606 if ( t() && jQuery.timers.push(t) && !timerId ) {
5607 timerId = setInterval(jQuery.fx.tick, 13);
5611 // Simple 'show' function
5613 // Remember where we started, so that we can go back to it later
5614 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
5615 this.options.show = true;
5617 // Begin the animation
5618 // Make sure that we start at a small width/height to avoid any
5620 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
5622 // Start by showing the element
5623 jQuery( this.elem ).show();
5626 // Simple 'hide' function
5628 // Remember where we started, so that we can go back to it later
5629 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
5630 this.options.hide = true;
5632 // Begin the animation
5633 this.custom(this.cur(), 0);
5636 // Each step of an animation
5637 step: function( gotoEnd ) {
5638 var t = now(), done = true;
5640 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
5641 this.now = this.end;
5642 this.pos = this.state = 1;
5645 this.options.curAnim[ this.prop ] = true;
5647 for ( var i in this.options.curAnim ) {
5648 if ( this.options.curAnim[i] !== true ) {
5654 if ( this.options.display != null ) {
5655 // Reset the overflow
5656 this.elem.style.overflow = this.options.overflow;
5658 // Reset the display
5659 var old = jQuery.data(this.elem, "olddisplay");
5660 this.elem.style.display = old ? old : this.options.display;
5662 if ( jQuery.css(this.elem, "display") === "none" ) {
5663 this.elem.style.display = "block";
5667 // Hide the element if the "hide" operation was done
5668 if ( this.options.hide ) {
5669 jQuery(this.elem).hide();
5672 // Reset the properties, if the item has been hidden or shown
5673 if ( this.options.hide || this.options.show ) {
5674 for ( var p in this.options.curAnim ) {
5675 jQuery.style(this.elem, p, this.options.orig[p]);
5679 // Execute the complete function
5680 this.options.complete.call( this.elem );
5686 var n = t - this.startTime;
5687 this.state = n / this.options.duration;
5689 // Perform the easing function, defaults to swing
5690 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
5691 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
5692 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
5693 this.now = this.start + ((this.end - this.start) * this.pos);
5695 // Perform the next step of the animation
5703 jQuery.extend( jQuery.fx, {
5705 var timers = jQuery.timers;
5707 for ( var i = 0; i < timers.length; i++ ) {
5708 if ( !timers[i]() ) {
5709 timers.splice(i--, 1);
5713 if ( !timers.length ) {
5719 clearInterval( timerId );
5731 opacity: function( fx ) {
5732 jQuery.style(fx.elem, "opacity", fx.now);
5735 _default: function( fx ) {
5736 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
5737 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
5739 fx.elem[ fx.prop ] = fx.now;
5745 if ( jQuery.expr && jQuery.expr.filters ) {
5746 jQuery.expr.filters.animated = function( elem ) {
5747 return jQuery.grep(jQuery.timers, function( fn ) {
5748 return elem === fn.elem;
5753 function genFx( type, num ) {
5756 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
5762 if ( "getBoundingClientRect" in document.documentElement ) {
5763 jQuery.fn.offset = function( options ) {
5767 return this.each(function( i ) {
5768 jQuery.offset.setOffset( this, options, i );
5772 if ( !elem || !elem.ownerDocument ) {
5776 if ( elem === elem.ownerDocument.body ) {
5777 return jQuery.offset.bodyOffset( elem );
5780 var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
5781 clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
5782 top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
5783 left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
5785 return { top: top, left: left };
5789 jQuery.fn.offset = function( options ) {
5793 return this.each(function( i ) {
5794 jQuery.offset.setOffset( this, options, i );
5798 if ( !elem || !elem.ownerDocument ) {
5802 if ( elem === elem.ownerDocument.body ) {
5803 return jQuery.offset.bodyOffset( elem );
5806 jQuery.offset.initialize();
5808 var offsetParent = elem.offsetParent, prevOffsetParent = elem,
5809 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
5810 body = doc.body, defaultView = doc.defaultView,
5811 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
5812 top = elem.offsetTop, left = elem.offsetLeft;
5814 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
5815 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
5819 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
5820 top -= elem.scrollTop;
5821 left -= elem.scrollLeft;
5823 if ( elem === offsetParent ) {
5824 top += elem.offsetTop;
5825 left += elem.offsetLeft;
5827 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
5828 top += parseFloat( computedStyle.borderTopWidth ) || 0;
5829 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
5832 prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
5835 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
5836 top += parseFloat( computedStyle.borderTopWidth ) || 0;
5837 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
5840 prevComputedStyle = computedStyle;
5843 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
5844 top += body.offsetTop;
5845 left += body.offsetLeft;
5848 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
5849 top += Math.max( docElem.scrollTop, body.scrollTop );
5850 left += Math.max( docElem.scrollLeft, body.scrollLeft );
5853 return { top: top, left: left };
5858 initialize: function() {
5859 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
5860 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>";
5862 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
5864 container.innerHTML = html;
5865 body.insertBefore( container, body.firstChild );
5866 innerDiv = container.firstChild;
5867 checkDiv = innerDiv.firstChild;
5868 td = innerDiv.nextSibling.firstChild.firstChild;
5870 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
5871 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
5873 checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
5874 // safari subtracts parent border width here which is 5px
5875 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
5876 checkDiv.style.position = checkDiv.style.top = "";
5878 innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
5879 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
5881 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
5883 body.removeChild( container );
5884 body = container = innerDiv = checkDiv = table = td = null;
5885 jQuery.offset.initialize = jQuery.noop;
5888 bodyOffset: function( body ) {
5889 var top = body.offsetTop, left = body.offsetLeft;
5891 jQuery.offset.initialize();
5893 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
5894 top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
5895 left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
5898 return { top: top, left: left };
5901 setOffset: function( elem, options, i ) {
5902 // set position first, in-case top/left are set even on static elem
5903 if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
5904 elem.style.position = "relative";
5906 var curElem = jQuery( elem ),
5907 curOffset = curElem.offset(),
5908 curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
5909 curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
5911 if ( jQuery.isFunction( options ) ) {
5912 options = options.call( elem, i, curOffset );
5916 top: (options.top - curOffset.top) + curTop,
5917 left: (options.left - curOffset.left) + curLeft
5920 if ( "using" in options ) {
5921 options.using.call( elem, props );
5923 curElem.css( props );
5930 position: function() {
5937 // Get *real* offsetParent
5938 offsetParent = this.offsetParent(),
5940 // Get correct offsets
5941 offset = this.offset(),
5942 parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
5944 // Subtract element margins
5945 // note: when an element has margin: auto the offsetLeft and marginLeft
5946 // are the same in Safari causing offset.left to incorrectly be 0
5947 offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
5948 offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
5950 // Add offsetParent borders
5951 parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
5952 parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
5954 // Subtract the two offsets
5956 top: offset.top - parentOffset.top,
5957 left: offset.left - parentOffset.left
5961 offsetParent: function() {
5962 return this.map(function() {
5963 var offsetParent = this.offsetParent || document.body;
5964 while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
5965 offsetParent = offsetParent.offsetParent;
5967 return offsetParent;
5973 // Create scrollLeft and scrollTop methods
5974 jQuery.each( ["Left", "Top"], function( i, name ) {
5975 var method = "scroll" + name;
5977 jQuery.fn[ method ] = function(val) {
5978 var elem = this[0], win;
5984 if ( val !== undefined ) {
5985 // Set the scroll offset
5986 return this.each(function() {
5987 win = getWindow( this );
5991 !i ? val : jQuery(win).scrollLeft(),
5992 i ? val : jQuery(win).scrollTop()
5996 this[ method ] = val;
6000 win = getWindow( elem );
6002 // Return the scroll offset
6003 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
6004 jQuery.support.boxModel && win.document.documentElement[ method ] ||
6005 win.document.body[ method ] :
6011 function getWindow( elem ) {
6012 return ("scrollTo" in elem && elem.document) ?
6014 elem.nodeType === 9 ?
6015 elem.defaultView || elem.parentWindow :
6018 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
6019 jQuery.each([ "Height", "Width" ], function( i, name ) {
6021 var type = name.toLowerCase();
6023 // innerHeight and innerWidth
6024 jQuery.fn["inner" + name] = function() {
6026 jQuery.css( this[0], type, false, "padding" ) :
6030 // outerHeight and outerWidth
6031 jQuery.fn["outer" + name] = function( margin ) {
6033 jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
6037 jQuery.fn[ type ] = function( size ) {
6038 // Get window width or height
6041 return size == null ? null : this;
6044 if ( jQuery.isFunction( size ) ) {
6045 return this.each(function( i ) {
6046 var self = jQuery( this );
6047 self[ type ]( size.call( this, i, self[ type ]() ) );
6051 return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
6052 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
6053 elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
6054 elem.document.body[ "client" + name ] :
6056 // Get document width or height
6057 (elem.nodeType === 9) ? // is it a document
6058 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
6060 elem.documentElement["client" + name],
6061 elem.body["scroll" + name], elem.documentElement["scroll" + name],
6062 elem.body["offset" + name], elem.documentElement["offset" + name]
6065 // Get or set width or height on the element
6066 size === undefined ?
6067 // Get width or height on the element
6068 jQuery.css( elem, type ) :
6070 // Set the width or height on the element (default to pixels if value is unitless)
6071 this.css( type, typeof size === "string" ? size : size + "px" );
6075 // Expose jQuery to the global object
6076 window.jQuery = window.$ = jQuery;