2 * jQuery JavaScript Library v1.4.4
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: Thu Nov 11 19:04:53 2010 -0500
16 (function( window, undefined ) {
18 // Use the correct document accordingly with window argument (sandbox)
19 var document = window.document;
20 var jQuery = (function() {
22 // Define a local copy of jQuery
23 var jQuery = function( selector, context ) {
24 // The jQuery object is actually just the init constructor 'enhanced'
25 return new jQuery.fn.init( selector, context );
28 // Map over jQuery in case of overwrite
29 _jQuery = window.jQuery,
31 // Map over the $ in case of overwrite
34 // A central reference to the root jQuery(document)
37 // A simple way to check for HTML strings or ID strings
38 // (both of which we optimize for)
39 quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
41 // Is it a simple selector
42 isSimple = /^.[^:#\[\.,]*$/,
44 // Check if a string has a non-whitespace character in it
48 // Used for trimming whitespace
52 // Check for non-word characters
58 // Match a standalone tag
59 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
62 rvalidchars = /^[\],:{}\s]*$/,
63 rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
64 rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
65 rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
68 rwebkit = /(webkit)[ \/]([\w.]+)/,
69 ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
70 rmsie = /(msie) ([\w.]+)/,
71 rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
73 // Keep a UserAgent string for use with jQuery.browser
74 userAgent = navigator.userAgent,
76 // For matching the engine and version of the browser
79 // Has the ready events already been bound?
82 // The functions to execute on DOM ready
85 // The ready event handler
88 // Save a reference to some core methods
89 toString = Object.prototype.toString,
90 hasOwn = Object.prototype.hasOwnProperty,
91 push = Array.prototype.push,
92 slice = Array.prototype.slice,
93 trim = String.prototype.trim,
94 indexOf = Array.prototype.indexOf,
96 // [[Class]] -> type pairs
99 jQuery.fn = jQuery.prototype = {
100 init: function( selector, context ) {
101 var match, elem, ret, doc;
103 // Handle $(""), $(null), or $(undefined)
108 // Handle $(DOMElement)
109 if ( selector.nodeType ) {
110 this.context = this[0] = selector;
115 // The body element only exists once, optimize finding it
116 if ( selector === "body" && !context && document.body ) {
117 this.context = document;
118 this[0] = document.body;
119 this.selector = "body";
124 // Handle HTML strings
125 if ( typeof selector === "string" ) {
126 // Are we dealing with HTML string or an ID?
127 match = quickExpr.exec( selector );
129 // Verify a match, and that no context was specified for #id
130 if ( match && (match[1] || !context) ) {
132 // HANDLE: $(html) -> $(array)
134 doc = (context ? context.ownerDocument || context : document);
136 // If a single string is passed in and it's a single tag
137 // just do a createElement and skip the rest
138 ret = rsingleTag.exec( selector );
141 if ( jQuery.isPlainObject( context ) ) {
142 selector = [ document.createElement( ret[1] ) ];
143 jQuery.fn.attr.call( selector, context, true );
146 selector = [ doc.createElement( ret[1] ) ];
150 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
151 selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
154 return jQuery.merge( this, selector );
158 elem = document.getElementById( match[2] );
160 // Check parentNode to catch when Blackberry 4.6 returns
161 // nodes that are no longer in the document #6963
162 if ( elem && elem.parentNode ) {
163 // Handle the case where IE and Opera return items
164 // by name instead of ID
165 if ( elem.id !== match[2] ) {
166 return rootjQuery.find( selector );
169 // Otherwise, we inject the element directly into the jQuery object
174 this.context = document;
175 this.selector = selector;
180 } else if ( !context && !rnonword.test( selector ) ) {
181 this.selector = selector;
182 this.context = document;
183 selector = document.getElementsByTagName( selector );
184 return jQuery.merge( this, selector );
186 // HANDLE: $(expr, $(...))
187 } else if ( !context || context.jquery ) {
188 return (context || rootjQuery).find( selector );
190 // HANDLE: $(expr, context)
191 // (which is just equivalent to: $(context).find(expr)
193 return jQuery( context ).find( selector );
196 // HANDLE: $(function)
197 // Shortcut for document ready
198 } else if ( jQuery.isFunction( selector ) ) {
199 return rootjQuery.ready( selector );
202 if (selector.selector !== undefined) {
203 this.selector = selector.selector;
204 this.context = selector.context;
207 return jQuery.makeArray( selector, this );
210 // Start with an empty selector
213 // The current version of jQuery being used
216 // The default length of a jQuery object is 0
219 // The number of elements contained in the matched element set
224 toArray: function() {
225 return slice.call( this, 0 );
228 // Get the Nth element in the matched element set OR
229 // Get the whole matched element set as a clean array
230 get: function( num ) {
233 // Return a 'clean' array
236 // Return just the object
237 ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
240 // Take an array of elements and push it onto the stack
241 // (returning the new matched element set)
242 pushStack: function( elems, name, selector ) {
243 // Build a new jQuery matched element set
246 if ( jQuery.isArray( elems ) ) {
247 push.apply( ret, elems );
250 jQuery.merge( ret, elems );
253 // Add the old object onto the stack (as a reference)
254 ret.prevObject = this;
256 ret.context = this.context;
258 if ( name === "find" ) {
259 ret.selector = this.selector + (this.selector ? " " : "") + selector;
261 ret.selector = this.selector + "." + name + "(" + selector + ")";
264 // Return the newly-formed element set
268 // Execute a callback for every element in the matched set.
269 // (You can seed the arguments with an array of args, but this is
270 // only used internally.)
271 each: function( callback, args ) {
272 return jQuery.each( this, callback, args );
275 ready: function( fn ) {
276 // Attach the listeners
279 // If the DOM is already ready
280 if ( jQuery.isReady ) {
281 // Execute the function immediately
282 fn.call( document, jQuery );
284 // Otherwise, remember the function for later
285 } else if ( readyList ) {
286 // Add the function to the wait list
287 readyList.push( fn );
296 this.slice( i, +i + 1 );
304 return this.eq( -1 );
308 return this.pushStack( slice.apply( this, arguments ),
309 "slice", slice.call(arguments).join(",") );
312 map: function( callback ) {
313 return this.pushStack( jQuery.map(this, function( elem, i ) {
314 return callback.call( elem, i, elem );
319 return this.prevObject || jQuery(null);
322 // For internal use only.
323 // Behaves like an Array's method, not like a jQuery method.
329 // Give the init function the jQuery prototype for later instantiation
330 jQuery.fn.init.prototype = jQuery.fn;
332 jQuery.extend = jQuery.fn.extend = function() {
333 var options, name, src, copy, copyIsArray, clone,
334 target = arguments[0] || {},
336 length = arguments.length,
339 // Handle a deep copy situation
340 if ( typeof target === "boolean" ) {
342 target = arguments[1] || {};
343 // skip the boolean and the target
347 // Handle case when target is a string or something (possible in deep copy)
348 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
352 // extend jQuery itself if only one argument is passed
353 if ( length === i ) {
358 for ( ; i < length; i++ ) {
359 // Only deal with non-null/undefined values
360 if ( (options = arguments[ i ]) != null ) {
361 // Extend the base object
362 for ( name in options ) {
363 src = target[ name ];
364 copy = options[ name ];
366 // Prevent never-ending loop
367 if ( target === copy ) {
371 // Recurse if we're merging plain objects or arrays
372 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
375 clone = src && jQuery.isArray(src) ? src : [];
378 clone = src && jQuery.isPlainObject(src) ? src : {};
381 // Never move original objects, clone them
382 target[ name ] = jQuery.extend( deep, clone, copy );
384 // Don't bring in undefined values
385 } else if ( copy !== undefined ) {
386 target[ name ] = copy;
392 // Return the modified object
397 noConflict: function( deep ) {
401 window.jQuery = _jQuery;
407 // Is the DOM ready to be used? Set to true once it occurs.
410 // A counter to track how many items to wait for before
411 // the ready event fires. See #6781
414 // Handle when the DOM is ready
415 ready: function( wait ) {
416 // A third-party is pushing the ready event forwards
417 if ( wait === true ) {
421 // Make sure that the DOM is not already loaded
422 if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
423 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
424 if ( !document.body ) {
425 return setTimeout( jQuery.ready, 1 );
428 // Remember that the DOM is ready
429 jQuery.isReady = true;
431 // If a normal DOM Ready event fired, decrement, and wait if need be
432 if ( wait !== true && --jQuery.readyWait > 0 ) {
436 // If there are functions bound, to execute
438 // Execute all of them
443 // Reset the list of functions
446 while ( (fn = ready[ i++ ]) ) {
447 fn.call( document, jQuery );
450 // Trigger any bound ready events
451 if ( jQuery.fn.trigger ) {
452 jQuery( document ).trigger( "ready" ).unbind( "ready" );
458 bindReady: function() {
465 // Catch cases where $(document).ready() is called after the
466 // browser event has already occurred.
467 if ( document.readyState === "complete" ) {
468 // Handle it asynchronously to allow scripts the opportunity to delay ready
469 return setTimeout( jQuery.ready, 1 );
472 // Mozilla, Opera and webkit nightlies currently support this event
473 if ( document.addEventListener ) {
474 // Use the handy event callback
475 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
477 // A fallback to window.onload, that will always work
478 window.addEventListener( "load", jQuery.ready, false );
480 // If IE event model is used
481 } else if ( document.attachEvent ) {
482 // ensure firing before onload,
483 // maybe late but safe also for iframes
484 document.attachEvent("onreadystatechange", DOMContentLoaded);
486 // A fallback to window.onload, that will always work
487 window.attachEvent( "onload", jQuery.ready );
489 // If IE and not a frame
490 // continually check to see if the document is ready
491 var toplevel = false;
494 toplevel = window.frameElement == null;
497 if ( document.documentElement.doScroll && toplevel ) {
503 // See test/unit/core.js for details concerning isFunction.
504 // Since version 1.3, DOM methods and functions like alert
505 // aren't supported. They return false on IE (#2968).
506 isFunction: function( obj ) {
507 return jQuery.type(obj) === "function";
510 isArray: Array.isArray || function( obj ) {
511 return jQuery.type(obj) === "array";
514 // A crude way of determining if an object is a window
515 isWindow: function( obj ) {
516 return obj && typeof obj === "object" && "setInterval" in obj;
519 isNaN: function( obj ) {
520 return obj == null || !rdigit.test( obj ) || isNaN( obj );
523 type: function( obj ) {
526 class2type[ toString.call(obj) ] || "object";
529 isPlainObject: function( obj ) {
530 // Must be an Object.
531 // Because of IE, we also have to check the presence of the constructor property.
532 // Make sure that DOM nodes and window objects don't pass through, as well
533 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
537 // Not own constructor property must be Object
538 if ( obj.constructor &&
539 !hasOwn.call(obj, "constructor") &&
540 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
544 // Own properties are enumerated firstly, so to speed up,
545 // if last one is own, then all properties are own.
548 for ( key in obj ) {}
550 return key === undefined || hasOwn.call( obj, key );
553 isEmptyObject: function( obj ) {
554 for ( var name in obj ) {
560 error: function( msg ) {
564 parseJSON: function( data ) {
565 if ( typeof data !== "string" || !data ) {
569 // Make sure leading/trailing whitespace is removed (IE can't handle it)
570 data = jQuery.trim( data );
572 // Make sure the incoming data is actual JSON
573 // Logic borrowed from http://json.org/json2.js
574 if ( rvalidchars.test(data.replace(rvalidescape, "@")
575 .replace(rvalidtokens, "]")
576 .replace(rvalidbraces, "")) ) {
578 // Try to use the native JSON parser first
579 return window.JSON && window.JSON.parse ?
580 window.JSON.parse( data ) :
581 (new Function("return " + data))();
584 jQuery.error( "Invalid JSON: " + data );
590 // Evalulates a script in a global context
591 globalEval: function( data ) {
592 if ( data && rnotwhite.test(data) ) {
593 // Inspired by code by Andrea Giammarchi
594 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
595 var head = document.getElementsByTagName("head")[0] || document.documentElement,
596 script = document.createElement("script");
598 script.type = "text/javascript";
600 if ( jQuery.support.scriptEval ) {
601 script.appendChild( document.createTextNode( data ) );
606 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
607 // This arises when a base node is used (#2709).
608 head.insertBefore( script, head.firstChild );
609 head.removeChild( script );
613 nodeName: function( elem, name ) {
614 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
617 // args is for internal usage only
618 each: function( object, callback, args ) {
620 length = object.length,
621 isObj = length === undefined || jQuery.isFunction(object);
625 for ( name in object ) {
626 if ( callback.apply( object[ name ], args ) === false ) {
631 for ( ; i < length; ) {
632 if ( callback.apply( object[ i++ ], args ) === false ) {
638 // A special, fast, case for the most common use of each
641 for ( name in object ) {
642 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
647 for ( var value = object[0];
648 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
655 // Use native String.trim function wherever possible
658 return text == null ?
663 // Otherwise use our own trimming functionality
665 return text == null ?
667 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
670 // results is for internal usage only
671 makeArray: function( array, results ) {
672 var ret = results || [];
674 if ( array != null ) {
675 // The window, strings (and functions) also have 'length'
676 // The extra typeof function check is to prevent crashes
677 // in Safari 2 (See: #3039)
678 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
679 var type = jQuery.type(array);
681 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
682 push.call( ret, array );
684 jQuery.merge( ret, array );
691 inArray: function( elem, array ) {
692 if ( array.indexOf ) {
693 return array.indexOf( elem );
696 for ( var i = 0, length = array.length; i < length; i++ ) {
697 if ( array[ i ] === elem ) {
705 merge: function( first, second ) {
706 var i = first.length,
709 if ( typeof second.length === "number" ) {
710 for ( var l = second.length; j < l; j++ ) {
711 first[ i++ ] = second[ j ];
715 while ( second[j] !== undefined ) {
716 first[ i++ ] = second[ j++ ];
725 grep: function( elems, callback, inv ) {
726 var ret = [], retVal;
729 // Go through the array, only saving the items
730 // that pass the validator function
731 for ( var i = 0, length = elems.length; i < length; i++ ) {
732 retVal = !!callback( elems[ i ], i );
733 if ( inv !== retVal ) {
734 ret.push( elems[ i ] );
741 // arg is for internal usage only
742 map: function( elems, callback, arg ) {
745 // Go through the array, translating each of the items to their
746 // new value (or values).
747 for ( var i = 0, length = elems.length; i < length; i++ ) {
748 value = callback( elems[ i ], i, arg );
750 if ( value != null ) {
751 ret[ ret.length ] = value;
755 return ret.concat.apply( [], ret );
758 // A global GUID counter for objects
761 proxy: function( fn, proxy, thisObject ) {
762 if ( arguments.length === 2 ) {
763 if ( typeof proxy === "string" ) {
765 fn = thisObject[ proxy ];
768 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
774 if ( !proxy && fn ) {
776 return fn.apply( thisObject || this, arguments );
780 // Set the guid of unique handler to the same of original handler, so it can be removed
782 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
785 // So proxy can be declared as an argument
789 // Mutifunctional method to get and set values to a collection
790 // The value/s can be optionally by executed if its a function
791 access: function( elems, key, value, exec, fn, pass ) {
792 var length = elems.length;
794 // Setting many attributes
795 if ( typeof key === "object" ) {
796 for ( var k in key ) {
797 jQuery.access( elems, k, key[k], exec, fn, value );
802 // Setting one attribute
803 if ( value !== undefined ) {
804 // Optionally, function values get executed if exec is true
805 exec = !pass && exec && jQuery.isFunction(value);
807 for ( var i = 0; i < length; i++ ) {
808 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
814 // Getting an attribute
815 return length ? fn( elems[0], key ) : undefined;
819 return (new Date()).getTime();
822 // Use of jQuery.browser is frowned upon.
823 // More details: http://docs.jquery.com/Utilities/jQuery.browser
824 uaMatch: function( ua ) {
825 ua = ua.toLowerCase();
827 var match = rwebkit.exec( ua ) ||
830 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
833 return { browser: match[1] || "", version: match[2] || "0" };
839 // Populate the class2type map
840 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
841 class2type[ "[object " + name + "]" ] = name.toLowerCase();
844 browserMatch = jQuery.uaMatch( userAgent );
845 if ( browserMatch.browser ) {
846 jQuery.browser[ browserMatch.browser ] = true;
847 jQuery.browser.version = browserMatch.version;
850 // Deprecated, use jQuery.browser.webkit instead
851 if ( jQuery.browser.webkit ) {
852 jQuery.browser.safari = true;
856 jQuery.inArray = function( elem, array ) {
857 return indexOf.call( array, elem );
861 // Verify that \s matches non-breaking spaces
862 // (IE fails on this test)
863 if ( !rwhite.test( "\xA0" ) ) {
864 trimLeft = /^[\s\xA0]+/;
865 trimRight = /[\s\xA0]+$/;
868 // All jQuery objects should point back to these
869 rootjQuery = jQuery(document);
871 // Cleanup functions for the document ready method
872 if ( document.addEventListener ) {
873 DOMContentLoaded = function() {
874 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
878 } else if ( document.attachEvent ) {
879 DOMContentLoaded = function() {
880 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
881 if ( document.readyState === "complete" ) {
882 document.detachEvent( "onreadystatechange", DOMContentLoaded );
888 // The DOM ready check for Internet Explorer
889 function doScrollCheck() {
890 if ( jQuery.isReady ) {
895 // If IE is used, use the trick by Diego Perini
896 // http://javascript.nwbox.com/IEContentLoaded/
897 document.documentElement.doScroll("left");
899 setTimeout( doScrollCheck, 1 );
903 // and execute any waiting functions
907 // Expose jQuery to the global object
908 return (window.jQuery = window.$ = jQuery);
917 var root = document.documentElement,
918 script = document.createElement("script"),
919 div = document.createElement("div"),
920 id = "script" + jQuery.now();
922 div.style.display = "none";
923 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
925 var all = div.getElementsByTagName("*"),
926 a = div.getElementsByTagName("a")[0],
927 select = document.createElement("select"),
928 opt = select.appendChild( document.createElement("option") );
930 // Can't get basic test support
931 if ( !all || !all.length || !a ) {
936 // IE strips leading whitespace when .innerHTML is used
937 leadingWhitespace: div.firstChild.nodeType === 3,
939 // Make sure that tbody elements aren't automatically inserted
940 // IE will insert them into empty tables
941 tbody: !div.getElementsByTagName("tbody").length,
943 // Make sure that link elements get serialized correctly by innerHTML
944 // This requires a wrapper element in IE
945 htmlSerialize: !!div.getElementsByTagName("link").length,
947 // Get the style information from getAttribute
948 // (IE uses .cssText insted)
949 style: /red/.test( a.getAttribute("style") ),
951 // Make sure that URLs aren't manipulated
952 // (IE normalizes it by default)
953 hrefNormalized: a.getAttribute("href") === "/a",
955 // Make sure that element opacity exists
956 // (IE uses filter instead)
957 // Use a regex to work around a WebKit issue. See #5145
958 opacity: /^0.55$/.test( a.style.opacity ),
960 // Verify style float existence
961 // (IE uses styleFloat instead of cssFloat)
962 cssFloat: !!a.style.cssFloat,
964 // Make sure that if no value is specified for a checkbox
965 // that it defaults to "on".
966 // (WebKit defaults to "" instead)
967 checkOn: div.getElementsByTagName("input")[0].value === "on",
969 // Make sure that a selected-by-default option has a working selected property.
970 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
971 optSelected: opt.selected,
973 // Will be defined later
980 inlineBlockNeedsLayout: false,
981 shrinkWrapBlocks: false,
982 reliableHiddenOffsets: true
985 // Make sure that the options inside disabled selects aren't marked as disabled
986 // (WebKit marks them as diabled)
987 select.disabled = true;
988 jQuery.support.optDisabled = !opt.disabled;
990 script.type = "text/javascript";
992 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
995 root.insertBefore( script, root.firstChild );
997 // Make sure that the execution of code works by injecting a script
998 // tag with appendChild/createTextNode
999 // (IE doesn't support this, fails, and uses .text instead)
1000 if ( window[ id ] ) {
1001 jQuery.support.scriptEval = true;
1002 delete window[ id ];
1005 // Test to see if it's possible to delete an expando from an element
1006 // Fails in Internet Explorer
1011 jQuery.support.deleteExpando = false;
1014 root.removeChild( script );
1016 if ( div.attachEvent && div.fireEvent ) {
1017 div.attachEvent("onclick", function click() {
1018 // Cloning a node shouldn't copy over any
1019 // bound event handlers (IE does this)
1020 jQuery.support.noCloneEvent = false;
1021 div.detachEvent("onclick", click);
1023 div.cloneNode(true).fireEvent("onclick");
1026 div = document.createElement("div");
1027 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1029 var fragment = document.createDocumentFragment();
1030 fragment.appendChild( div.firstChild );
1032 // WebKit doesn't clone checked state correctly in fragments
1033 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1035 // Figure out if the W3C box model works as expected
1036 // document.body must exist before we can do this
1038 var div = document.createElement("div"),
1039 body = document.getElementsByTagName("body")[0];
1041 // Frameset documents with no body should not run this code
1046 div.style.width = div.style.paddingLeft = "1px";
1047 body.appendChild( div );
1048 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1050 if ( "zoom" in div.style ) {
1051 // Check if natively block-level elements act like inline-block
1052 // elements when setting their display to 'inline' and giving
1054 // (IE < 8 does this)
1055 div.style.display = "inline";
1057 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1059 // Check if elements with layout shrink-wrap their children
1061 div.style.display = "";
1062 div.innerHTML = "<div style='width:4px;'></div>";
1063 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1066 div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1067 var tds = div.getElementsByTagName("td");
1069 // Check if table cells still have offsetWidth/Height when they are set
1070 // to display:none and there are still other visible table cells in a
1071 // table row; if so, offsetWidth/Height are not reliable for use when
1072 // determining if an element has been hidden directly using
1073 // display:none (it is still safe to use offsets if a parent element is
1074 // hidden; don safety goggles and see bug #4512 for more information).
1075 // (only IE 8 fails this test)
1076 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1078 tds[0].style.display = "";
1079 tds[1].style.display = "none";
1081 // Check if empty table cells still have offsetWidth/Height
1082 // (IE < 8 fail this test)
1083 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1086 body.removeChild( div ).style.display = "none";
1090 // Technique from Juriy Zaytsev
1091 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1092 var eventSupported = function( eventName ) {
1093 var el = document.createElement("div");
1094 eventName = "on" + eventName;
1096 var isSupported = (eventName in el);
1097 if ( !isSupported ) {
1098 el.setAttribute(eventName, "return;");
1099 isSupported = typeof el[eventName] === "function";
1106 jQuery.support.submitBubbles = eventSupported("submit");
1107 jQuery.support.changeBubbles = eventSupported("change");
1109 // release memory in IE
1110 root = script = div = all = a = null;
1115 var windowData = {},
1116 rbrace = /^(?:\{.*\}|\[.*\])$/;
1121 // Please use with caution
1124 // Unique for each copy of jQuery on the page
1125 expando: "jQuery" + jQuery.now(),
1127 // The following elements throw uncatchable exceptions if you
1128 // attempt to add expando properties to them.
1131 // Ban all objects except for Flash (which handle expandos)
1132 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1136 data: function( elem, name, data ) {
1137 if ( !jQuery.acceptData( elem ) ) {
1141 elem = elem == window ?
1145 var isNode = elem.nodeType,
1146 id = isNode ? elem[ jQuery.expando ] : null,
1147 cache = jQuery.cache, thisCache;
1149 if ( isNode && !id && typeof name === "string" && data === undefined ) {
1153 // Get the data from the object directly
1157 // Compute a unique ID for the element
1159 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1162 // Avoid generating a new cache unless none exists and we
1163 // want to manipulate it.
1164 if ( typeof name === "object" ) {
1166 cache[ id ] = jQuery.extend(cache[ id ], name);
1169 jQuery.extend( cache, name );
1172 } else if ( isNode && !cache[ id ] ) {
1176 thisCache = isNode ? cache[ id ] : cache;
1178 // Prevent overriding the named cache with undefined values
1179 if ( data !== undefined ) {
1180 thisCache[ name ] = data;
1183 return typeof name === "string" ? thisCache[ name ] : thisCache;
1186 removeData: function( elem, name ) {
1187 if ( !jQuery.acceptData( elem ) ) {
1191 elem = elem == window ?
1195 var isNode = elem.nodeType,
1196 id = isNode ? elem[ jQuery.expando ] : elem,
1197 cache = jQuery.cache,
1198 thisCache = isNode ? cache[ id ] : id;
1200 // If we want to remove a specific section of the element's data
1203 // Remove the section of cache data
1204 delete thisCache[ name ];
1206 // If we've removed all the data, remove the element's cache
1207 if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1208 jQuery.removeData( elem );
1212 // Otherwise, we want to remove all of the element's data
1214 if ( isNode && jQuery.support.deleteExpando ) {
1215 delete elem[ jQuery.expando ];
1217 } else if ( elem.removeAttribute ) {
1218 elem.removeAttribute( jQuery.expando );
1220 // Completely remove the data cache
1221 } else if ( isNode ) {
1224 // Remove all fields from the object
1226 for ( var n in elem ) {
1233 // A method for determining if a DOM node can handle the data expando
1234 acceptData: function( elem ) {
1235 if ( elem.nodeName ) {
1236 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1239 return !(match === true || elem.getAttribute("classid") !== match);
1248 data: function( key, value ) {
1251 if ( typeof key === "undefined" ) {
1252 if ( this.length ) {
1253 var attr = this[0].attributes, name;
1254 data = jQuery.data( this[0] );
1256 for ( var i = 0, l = attr.length; i < l; i++ ) {
1257 name = attr[i].name;
1259 if ( name.indexOf( "data-" ) === 0 ) {
1260 name = name.substr( 5 );
1261 dataAttr( this[0], name, data[ name ] );
1268 } else if ( typeof key === "object" ) {
1269 return this.each(function() {
1270 jQuery.data( this, key );
1274 var parts = key.split(".");
1275 parts[1] = parts[1] ? "." + parts[1] : "";
1277 if ( value === undefined ) {
1278 data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1280 // Try to fetch any internally stored data first
1281 if ( data === undefined && this.length ) {
1282 data = jQuery.data( this[0], key );
1283 data = dataAttr( this[0], key, data );
1286 return data === undefined && parts[1] ?
1287 this.data( parts[0] ) :
1291 return this.each(function() {
1292 var $this = jQuery( this ),
1293 args = [ parts[0], value ];
1295 $this.triggerHandler( "setData" + parts[1] + "!", args );
1296 jQuery.data( this, key, value );
1297 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1302 removeData: function( key ) {
1303 return this.each(function() {
1304 jQuery.removeData( this, key );
1309 function dataAttr( elem, key, data ) {
1310 // If nothing was found internally, try to fetch any
1311 // data from the HTML5 data-* attribute
1312 if ( data === undefined && elem.nodeType === 1 ) {
1313 data = elem.getAttribute( "data-" + key );
1315 if ( typeof data === "string" ) {
1317 data = data === "true" ? true :
1318 data === "false" ? false :
1319 data === "null" ? null :
1320 !jQuery.isNaN( data ) ? parseFloat( data ) :
1321 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1325 // Make sure we set the data so it isn't changed later
1326 jQuery.data( elem, key, data );
1340 queue: function( elem, type, data ) {
1345 type = (type || "fx") + "queue";
1346 var q = jQuery.data( elem, type );
1348 // Speed up dequeue by getting out quickly if this is just a lookup
1353 if ( !q || jQuery.isArray(data) ) {
1354 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1363 dequeue: function( elem, type ) {
1364 type = type || "fx";
1366 var queue = jQuery.queue( elem, type ),
1369 // If the fx queue is dequeued, always remove the progress sentinel
1370 if ( fn === "inprogress" ) {
1375 // Add a progress sentinel to prevent the fx queue from being
1376 // automatically dequeued
1377 if ( type === "fx" ) {
1378 queue.unshift("inprogress");
1381 fn.call(elem, function() {
1382 jQuery.dequeue(elem, type);
1389 queue: function( type, data ) {
1390 if ( typeof type !== "string" ) {
1395 if ( data === undefined ) {
1396 return jQuery.queue( this[0], type );
1398 return this.each(function( i ) {
1399 var queue = jQuery.queue( this, type, data );
1401 if ( type === "fx" && queue[0] !== "inprogress" ) {
1402 jQuery.dequeue( this, type );
1406 dequeue: function( type ) {
1407 return this.each(function() {
1408 jQuery.dequeue( this, type );
1412 // Based off of the plugin by Clint Helfers, with permission.
1413 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1414 delay: function( time, type ) {
1415 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1416 type = type || "fx";
1418 return this.queue( type, function() {
1420 setTimeout(function() {
1421 jQuery.dequeue( elem, type );
1426 clearQueue: function( type ) {
1427 return this.queue( type || "fx", [] );
1434 var rclass = /[\n\t]/g,
1437 rspecialurl = /^(?:href|src|style)$/,
1438 rtype = /^(?:button|input)$/i,
1439 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1440 rclickable = /^a(?:rea)?$/i,
1441 rradiocheck = /^(?:radio|checkbox)$/i;
1445 "class": "className",
1446 readonly: "readOnly",
1447 maxlength: "maxLength",
1448 cellspacing: "cellSpacing",
1451 tabindex: "tabIndex",
1453 frameborder: "frameBorder"
1457 attr: function( name, value ) {
1458 return jQuery.access( this, name, value, true, jQuery.attr );
1461 removeAttr: function( name, fn ) {
1462 return this.each(function(){
1463 jQuery.attr( this, name, "" );
1464 if ( this.nodeType === 1 ) {
1465 this.removeAttribute( name );
1470 addClass: function( value ) {
1471 if ( jQuery.isFunction(value) ) {
1472 return this.each(function(i) {
1473 var self = jQuery(this);
1474 self.addClass( value.call(this, i, self.attr("class")) );
1478 if ( value && typeof value === "string" ) {
1479 var classNames = (value || "").split( rspaces );
1481 for ( var i = 0, l = this.length; i < l; i++ ) {
1484 if ( elem.nodeType === 1 ) {
1485 if ( !elem.className ) {
1486 elem.className = value;
1489 var className = " " + elem.className + " ",
1490 setClass = elem.className;
1492 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1493 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1494 setClass += " " + classNames[c];
1497 elem.className = jQuery.trim( setClass );
1506 removeClass: function( value ) {
1507 if ( jQuery.isFunction(value) ) {
1508 return this.each(function(i) {
1509 var self = jQuery(this);
1510 self.removeClass( value.call(this, i, self.attr("class")) );
1514 if ( (value && typeof value === "string") || value === undefined ) {
1515 var classNames = (value || "").split( rspaces );
1517 for ( var i = 0, l = this.length; i < l; i++ ) {
1520 if ( elem.nodeType === 1 && elem.className ) {
1522 var className = (" " + elem.className + " ").replace(rclass, " ");
1523 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1524 className = className.replace(" " + classNames[c] + " ", " ");
1526 elem.className = jQuery.trim( className );
1529 elem.className = "";
1538 toggleClass: function( value, stateVal ) {
1539 var type = typeof value,
1540 isBool = typeof stateVal === "boolean";
1542 if ( jQuery.isFunction( value ) ) {
1543 return this.each(function(i) {
1544 var self = jQuery(this);
1545 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1549 return this.each(function() {
1550 if ( type === "string" ) {
1551 // toggle individual class names
1554 self = jQuery( this ),
1556 classNames = value.split( rspaces );
1558 while ( (className = classNames[ i++ ]) ) {
1559 // check each className given, space seperated list
1560 state = isBool ? state : !self.hasClass( className );
1561 self[ state ? "addClass" : "removeClass" ]( className );
1564 } else if ( type === "undefined" || type === "boolean" ) {
1565 if ( this.className ) {
1566 // store className if set
1567 jQuery.data( this, "__className__", this.className );
1570 // toggle whole className
1571 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1576 hasClass: function( selector ) {
1577 var className = " " + selector + " ";
1578 for ( var i = 0, l = this.length; i < l; i++ ) {
1579 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1587 val: function( value ) {
1588 if ( !arguments.length ) {
1592 if ( jQuery.nodeName( elem, "option" ) ) {
1593 // attributes.value is undefined in Blackberry 4.7 but
1594 // uses .value. See #6932
1595 var val = elem.attributes.value;
1596 return !val || val.specified ? elem.value : elem.text;
1599 // We need to handle select boxes special
1600 if ( jQuery.nodeName( elem, "select" ) ) {
1601 var index = elem.selectedIndex,
1603 options = elem.options,
1604 one = elem.type === "select-one";
1606 // Nothing was selected
1611 // Loop through all the selected options
1612 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1613 var option = options[ i ];
1615 // Don't return options that are disabled or in a disabled optgroup
1616 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1617 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1619 // Get the specific value for the option
1620 value = jQuery(option).val();
1622 // We don't need an array for one selects
1627 // Multi-Selects return an array
1628 values.push( value );
1635 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1636 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1637 return elem.getAttribute("value") === null ? "on" : elem.value;
1641 // Everything else, we just grab the value
1642 return (elem.value || "").replace(rreturn, "");
1649 var isFunction = jQuery.isFunction(value);
1651 return this.each(function(i) {
1652 var self = jQuery(this), val = value;
1654 if ( this.nodeType !== 1 ) {
1659 val = value.call(this, i, self.val());
1662 // Treat null/undefined as ""; convert numbers to string
1663 if ( val == null ) {
1665 } else if ( typeof val === "number" ) {
1667 } else if ( jQuery.isArray(val) ) {
1668 val = jQuery.map(val, function (value) {
1669 return value == null ? "" : value + "";
1673 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1674 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1676 } else if ( jQuery.nodeName( this, "select" ) ) {
1677 var values = jQuery.makeArray(val);
1679 jQuery( "option", this ).each(function() {
1680 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1683 if ( !values.length ) {
1684 this.selectedIndex = -1;
1706 attr: function( elem, name, value, pass ) {
1707 // don't set attributes on text and comment nodes
1708 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1712 if ( pass && name in jQuery.attrFn ) {
1713 return jQuery(elem)[name](value);
1716 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1717 // Whether we are setting (or getting)
1718 set = value !== undefined;
1720 // Try to normalize/fix the name
1721 name = notxml && jQuery.props[ name ] || name;
1723 // These attributes require special treatment
1724 var special = rspecialurl.test( name );
1726 // Safari mis-reports the default selected property of an option
1727 // Accessing the parent's selectedIndex property fixes it
1728 if ( name === "selected" && !jQuery.support.optSelected ) {
1729 var parent = elem.parentNode;
1731 parent.selectedIndex;
1733 // Make sure that it also works with optgroups, see #5701
1734 if ( parent.parentNode ) {
1735 parent.parentNode.selectedIndex;
1740 // If applicable, access the attribute via the DOM 0 way
1741 // 'in' checks fail in Blackberry 4.7 #6931
1742 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1744 // We can't allow the type property to be changed (since it causes problems in IE)
1745 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1746 jQuery.error( "type property can't be changed" );
1749 if ( value === null ) {
1750 if ( elem.nodeType === 1 ) {
1751 elem.removeAttribute( name );
1755 elem[ name ] = value;
1759 // browsers index elements by id/name on forms, give priority to attributes.
1760 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1761 return elem.getAttributeNode( name ).nodeValue;
1764 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1765 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1766 if ( name === "tabIndex" ) {
1767 var attributeNode = elem.getAttributeNode( "tabIndex" );
1769 return attributeNode && attributeNode.specified ?
1770 attributeNode.value :
1771 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1776 return elem[ name ];
1779 if ( !jQuery.support.style && notxml && name === "style" ) {
1781 elem.style.cssText = "" + value;
1784 return elem.style.cssText;
1788 // convert the value to a string (all browsers do this but IE) see #1070
1789 elem.setAttribute( name, "" + value );
1792 // Ensure that missing attributes return undefined
1793 // Blackberry 4.7 returns "" from getAttribute #6938
1794 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1798 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1799 // Some attributes require a special call on IE
1800 elem.getAttribute( name, 2 ) :
1801 elem.getAttribute( name );
1803 // Non-existent attributes return null, we normalize to undefined
1804 return attr === null ? undefined : attr;
1811 var rnamespaces = /\.(.*)$/,
1812 rformElems = /^(?:textarea|input|select)$/i,
1815 rescape = /[^\w\s.|`]/g,
1816 fcleanup = function( nm ) {
1817 return nm.replace(rescape, "\\$&");
1819 focusCounts = { focusin: 0, focusout: 0 };
1822 * A number of helper functions used for managing events.
1823 * Many of the ideas behind this code originated from
1824 * Dean Edwards' addEvent library.
1828 // Bind an event to an element
1829 // Original by Dean Edwards
1830 add: function( elem, types, handler, data ) {
1831 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1835 // For whatever reason, IE has trouble passing the window object
1836 // around, causing it to be cloned in the process
1837 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
1841 if ( handler === false ) {
1842 handler = returnFalse;
1843 } else if ( !handler ) {
1844 // Fixes bug #7229. Fix recommended by jdalton
1848 var handleObjIn, handleObj;
1850 if ( handler.handler ) {
1851 handleObjIn = handler;
1852 handler = handleObjIn.handler;
1855 // Make sure that the function being executed has a unique ID
1856 if ( !handler.guid ) {
1857 handler.guid = jQuery.guid++;
1860 // Init the element's event structure
1861 var elemData = jQuery.data( elem );
1863 // If no elemData is found then we must be trying to bind to one of the
1864 // banned noData elements
1869 // Use a key less likely to result in collisions for plain JS objects.
1871 var eventKey = elem.nodeType ? "events" : "__events__",
1872 events = elemData[ eventKey ],
1873 eventHandle = elemData.handle;
1875 if ( typeof events === "function" ) {
1876 // On plain objects events is a fn that holds the the data
1877 // which prevents this data from being JSON serialized
1878 // the function does not need to be called, it just contains the data
1879 eventHandle = events.handle;
1880 events = events.events;
1882 } else if ( !events ) {
1883 if ( !elem.nodeType ) {
1884 // On plain objects, create a fn that acts as the holder
1885 // of the values to avoid JSON serialization of event data
1886 elemData[ eventKey ] = elemData = function(){};
1889 elemData.events = events = {};
1892 if ( !eventHandle ) {
1893 elemData.handle = eventHandle = function() {
1894 // Handle the second event of a trigger and when
1895 // an event is called after a page has unloaded
1896 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1897 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1902 // Add elem as a property of the handle function
1903 // This is to prevent a memory leak with non-native events in IE.
1904 eventHandle.elem = elem;
1906 // Handle multiple events separated by a space
1907 // jQuery(...).bind("mouseover mouseout", fn);
1908 types = types.split(" ");
1910 var type, i = 0, namespaces;
1912 while ( (type = types[ i++ ]) ) {
1913 handleObj = handleObjIn ?
1914 jQuery.extend({}, handleObjIn) :
1915 { handler: handler, data: data };
1917 // Namespaced event handlers
1918 if ( type.indexOf(".") > -1 ) {
1919 namespaces = type.split(".");
1920 type = namespaces.shift();
1921 handleObj.namespace = namespaces.slice(0).sort().join(".");
1925 handleObj.namespace = "";
1928 handleObj.type = type;
1929 if ( !handleObj.guid ) {
1930 handleObj.guid = handler.guid;
1933 // Get the current list of functions bound to this event
1934 var handlers = events[ type ],
1935 special = jQuery.event.special[ type ] || {};
1937 // Init the event handler queue
1939 handlers = events[ type ] = [];
1941 // Check for a special event handler
1942 // Only use addEventListener/attachEvent if the special
1943 // events handler returns false
1944 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1945 // Bind the global event handler to the element
1946 if ( elem.addEventListener ) {
1947 elem.addEventListener( type, eventHandle, false );
1949 } else if ( elem.attachEvent ) {
1950 elem.attachEvent( "on" + type, eventHandle );
1955 if ( special.add ) {
1956 special.add.call( elem, handleObj );
1958 if ( !handleObj.handler.guid ) {
1959 handleObj.handler.guid = handler.guid;
1963 // Add the function to the element's handler list
1964 handlers.push( handleObj );
1966 // Keep track of which events have been used, for global triggering
1967 jQuery.event.global[ type ] = true;
1970 // Nullify elem to prevent memory leaks in IE
1976 // Detach an event or set of events from an element
1977 remove: function( elem, types, handler, pos ) {
1978 // don't do events on text and comment nodes
1979 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1983 if ( handler === false ) {
1984 handler = returnFalse;
1987 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1988 eventKey = elem.nodeType ? "events" : "__events__",
1989 elemData = jQuery.data( elem ),
1990 events = elemData && elemData[ eventKey ];
1992 if ( !elemData || !events ) {
1996 if ( typeof events === "function" ) {
1998 events = events.events;
2001 // types is actually an event object here
2002 if ( types && types.type ) {
2003 handler = types.handler;
2007 // Unbind all events for the element
2008 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2009 types = types || "";
2011 for ( type in events ) {
2012 jQuery.event.remove( elem, type + types );
2018 // Handle multiple events separated by a space
2019 // jQuery(...).unbind("mouseover mouseout", fn);
2020 types = types.split(" ");
2022 while ( (type = types[ i++ ]) ) {
2025 all = type.indexOf(".") < 0;
2029 // Namespaced event handlers
2030 namespaces = type.split(".");
2031 type = namespaces.shift();
2033 namespace = new RegExp("(^|\\.)" +
2034 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2037 eventType = events[ type ];
2044 for ( j = 0; j < eventType.length; j++ ) {
2045 handleObj = eventType[ j ];
2047 if ( all || namespace.test( handleObj.namespace ) ) {
2048 jQuery.event.remove( elem, origType, handleObj.handler, j );
2049 eventType.splice( j--, 1 );
2056 special = jQuery.event.special[ type ] || {};
2058 for ( j = pos || 0; j < eventType.length; j++ ) {
2059 handleObj = eventType[ j ];
2061 if ( handler.guid === handleObj.guid ) {
2062 // remove the given handler for the given type
2063 if ( all || namespace.test( handleObj.namespace ) ) {
2064 if ( pos == null ) {
2065 eventType.splice( j--, 1 );
2068 if ( special.remove ) {
2069 special.remove.call( elem, handleObj );
2073 if ( pos != null ) {
2079 // remove generic event handler if no more handlers exist
2080 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2081 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2082 jQuery.removeEvent( elem, type, elemData.handle );
2086 delete events[ type ];
2090 // Remove the expando if it's no longer used
2091 if ( jQuery.isEmptyObject( events ) ) {
2092 var handle = elemData.handle;
2097 delete elemData.events;
2098 delete elemData.handle;
2100 if ( typeof elemData === "function" ) {
2101 jQuery.removeData( elem, eventKey );
2103 } else if ( jQuery.isEmptyObject( elemData ) ) {
2104 jQuery.removeData( elem );
2109 // bubbling is internal
2110 trigger: function( event, data, elem /*, bubbling */ ) {
2111 // Event object or event type
2112 var type = event.type || event,
2113 bubbling = arguments[3];
2116 event = typeof event === "object" ?
2117 // jQuery.Event object
2118 event[ jQuery.expando ] ? event :
2120 jQuery.extend( jQuery.Event(type), event ) :
2121 // Just the event type (string)
2124 if ( type.indexOf("!") >= 0 ) {
2125 event.type = type = type.slice(0, -1);
2126 event.exclusive = true;
2129 // Handle a global trigger
2131 // Don't bubble custom events when global (to avoid too much overhead)
2132 event.stopPropagation();
2134 // Only trigger if we've ever bound an event for it
2135 if ( jQuery.event.global[ type ] ) {
2136 jQuery.each( jQuery.cache, function() {
2137 if ( this.events && this.events[type] ) {
2138 jQuery.event.trigger( event, data, this.handle.elem );
2144 // Handle triggering a single element
2146 // don't do events on text and comment nodes
2147 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2151 // Clean up in case it is reused
2152 event.result = undefined;
2153 event.target = elem;
2155 // Clone the incoming data, if any
2156 data = jQuery.makeArray( data );
2157 data.unshift( event );
2160 event.currentTarget = elem;
2162 // Trigger the event, it is assumed that "handle" is a function
2163 var handle = elem.nodeType ?
2164 jQuery.data( elem, "handle" ) :
2165 (jQuery.data( elem, "__events__" ) || {}).handle;
2168 handle.apply( elem, data );
2171 var parent = elem.parentNode || elem.ownerDocument;
2173 // Trigger an inline bound script
2175 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2176 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2177 event.result = false;
2178 event.preventDefault();
2182 // prevent IE from throwing an error for some elements with some event types, see #3533
2183 } catch (inlineError) {}
2185 if ( !event.isPropagationStopped() && parent ) {
2186 jQuery.event.trigger( event, data, parent, true );
2188 } else if ( !event.isDefaultPrevented() ) {
2190 target = event.target,
2191 targetType = type.replace( rnamespaces, "" ),
2192 isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
2193 special = jQuery.event.special[ targetType ] || {};
2195 if ( (!special._default || special._default.call( elem, event ) === false) &&
2196 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2199 if ( target[ targetType ] ) {
2200 // Make sure that we don't accidentally re-trigger the onFOO events
2201 old = target[ "on" + targetType ];
2204 target[ "on" + targetType ] = null;
2207 jQuery.event.triggered = true;
2208 target[ targetType ]();
2211 // prevent IE from throwing an error for some elements with some event types, see #3533
2212 } catch (triggerError) {}
2215 target[ "on" + targetType ] = old;
2218 jQuery.event.triggered = false;
2223 handle: function( event ) {
2224 var all, handlers, namespaces, namespace_re, events,
2225 namespace_sort = [],
2226 args = jQuery.makeArray( arguments );
2228 event = args[0] = jQuery.event.fix( event || window.event );
2229 event.currentTarget = this;
2231 // Namespaced event handlers
2232 all = event.type.indexOf(".") < 0 && !event.exclusive;
2235 namespaces = event.type.split(".");
2236 event.type = namespaces.shift();
2237 namespace_sort = namespaces.slice(0).sort();
2238 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2241 event.namespace = event.namespace || namespace_sort.join(".");
2243 events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2245 if ( typeof events === "function" ) {
2246 events = events.events;
2249 handlers = (events || {})[ event.type ];
2251 if ( events && handlers ) {
2252 // Clone the handlers to prevent manipulation
2253 handlers = handlers.slice(0);
2255 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2256 var handleObj = handlers[ j ];
2258 // Filter the functions by class
2259 if ( all || namespace_re.test( handleObj.namespace ) ) {
2260 // Pass in a reference to the handler function itself
2261 // So that we can later remove it
2262 event.handler = handleObj.handler;
2263 event.data = handleObj.data;
2264 event.handleObj = handleObj;
2266 var ret = handleObj.handler.apply( this, args );
2268 if ( ret !== undefined ) {
2270 if ( ret === false ) {
2271 event.preventDefault();
2272 event.stopPropagation();
2276 if ( event.isImmediatePropagationStopped() ) {
2283 return event.result;
2286 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2288 fix: function( event ) {
2289 if ( event[ jQuery.expando ] ) {
2293 // store a copy of the original event object
2294 // and "clone" to set read-only properties
2295 var originalEvent = event;
2296 event = jQuery.Event( originalEvent );
2298 for ( var i = this.props.length, prop; i; ) {
2299 prop = this.props[ --i ];
2300 event[ prop ] = originalEvent[ prop ];
2303 // Fix target property, if necessary
2304 if ( !event.target ) {
2305 // Fixes #1925 where srcElement might not be defined either
2306 event.target = event.srcElement || document;
2309 // check if target is a textnode (safari)
2310 if ( event.target.nodeType === 3 ) {
2311 event.target = event.target.parentNode;
2314 // Add relatedTarget, if necessary
2315 if ( !event.relatedTarget && event.fromElement ) {
2316 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2319 // Calculate pageX/Y if missing and clientX/Y available
2320 if ( event.pageX == null && event.clientX != null ) {
2321 var doc = document.documentElement,
2322 body = document.body;
2324 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2325 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2328 // Add which for key events
2329 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2330 event.which = event.charCode != null ? event.charCode : event.keyCode;
2333 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2334 if ( !event.metaKey && event.ctrlKey ) {
2335 event.metaKey = event.ctrlKey;
2338 // Add which for click: 1 === left; 2 === middle; 3 === right
2339 // Note: button is not normalized, so don't use it
2340 if ( !event.which && event.button !== undefined ) {
2341 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2347 // Deprecated, use jQuery.guid instead
2350 // Deprecated, use jQuery.proxy instead
2351 proxy: jQuery.proxy,
2355 // Make sure the ready event is setup
2356 setup: jQuery.bindReady,
2357 teardown: jQuery.noop
2361 add: function( handleObj ) {
2362 jQuery.event.add( this,
2363 liveConvert( handleObj.origType, handleObj.selector ),
2364 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2367 remove: function( handleObj ) {
2368 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2373 setup: function( data, namespaces, eventHandle ) {
2374 // We only want to do this special case on windows
2375 if ( jQuery.isWindow( this ) ) {
2376 this.onbeforeunload = eventHandle;
2380 teardown: function( namespaces, eventHandle ) {
2381 if ( this.onbeforeunload === eventHandle ) {
2382 this.onbeforeunload = null;
2389 jQuery.removeEvent = document.removeEventListener ?
2390 function( elem, type, handle ) {
2391 if ( elem.removeEventListener ) {
2392 elem.removeEventListener( type, handle, false );
2395 function( elem, type, handle ) {
2396 if ( elem.detachEvent ) {
2397 elem.detachEvent( "on" + type, handle );
2401 jQuery.Event = function( src ) {
2402 // Allow instantiation without the 'new' keyword
2403 if ( !this.preventDefault ) {
2404 return new jQuery.Event( src );
2408 if ( src && src.type ) {
2409 this.originalEvent = src;
2410 this.type = src.type;
2416 // timeStamp is buggy for some events on Firefox(#3843)
2417 // So we won't rely on the native value
2418 this.timeStamp = jQuery.now();
2421 this[ jQuery.expando ] = true;
2424 function returnFalse() {
2427 function returnTrue() {
2431 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2432 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2433 jQuery.Event.prototype = {
2434 preventDefault: function() {
2435 this.isDefaultPrevented = returnTrue;
2437 var e = this.originalEvent;
2442 // if preventDefault exists run it on the original event
2443 if ( e.preventDefault ) {
2446 // otherwise set the returnValue property of the original event to false (IE)
2448 e.returnValue = false;
2451 stopPropagation: function() {
2452 this.isPropagationStopped = returnTrue;
2454 var e = this.originalEvent;
2458 // if stopPropagation exists run it on the original event
2459 if ( e.stopPropagation ) {
2460 e.stopPropagation();
2462 // otherwise set the cancelBubble property of the original event to true (IE)
2463 e.cancelBubble = true;
2465 stopImmediatePropagation: function() {
2466 this.isImmediatePropagationStopped = returnTrue;
2467 this.stopPropagation();
2469 isDefaultPrevented: returnFalse,
2470 isPropagationStopped: returnFalse,
2471 isImmediatePropagationStopped: returnFalse
2474 // Checks if an event happened on an element within another element
2475 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2476 var withinElement = function( event ) {
2477 // Check if mouse(over|out) are still within the same parent element
2478 var parent = event.relatedTarget;
2480 // Firefox sometimes assigns relatedTarget a XUL element
2481 // which we cannot access the parentNode property of
2483 // Traverse up the tree
2484 while ( parent && parent !== this ) {
2485 parent = parent.parentNode;
2488 if ( parent !== this ) {
2489 // set the correct event type
2490 event.type = event.data;
2492 // handle event if we actually just moused on to a non sub-element
2493 jQuery.event.handle.apply( this, arguments );
2496 // assuming we've left the element since we most likely mousedover a xul element
2500 // In case of event delegation, we only need to rename the event.type,
2501 // liveHandler will take care of the rest.
2502 delegate = function( event ) {
2503 event.type = event.data;
2504 jQuery.event.handle.apply( this, arguments );
2507 // Create mouseenter and mouseleave events
2509 mouseenter: "mouseover",
2510 mouseleave: "mouseout"
2511 }, function( orig, fix ) {
2512 jQuery.event.special[ orig ] = {
2513 setup: function( data ) {
2514 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2516 teardown: function( data ) {
2517 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2522 // submit delegation
2523 if ( !jQuery.support.submitBubbles ) {
2525 jQuery.event.special.submit = {
2526 setup: function( data, namespaces ) {
2527 if ( this.nodeName.toLowerCase() !== "form" ) {
2528 jQuery.event.add(this, "click.specialSubmit", function( e ) {
2529 var elem = e.target,
2532 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2533 e.liveFired = undefined;
2534 return trigger( "submit", this, arguments );
2538 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2539 var elem = e.target,
2542 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2543 e.liveFired = undefined;
2544 return trigger( "submit", this, arguments );
2553 teardown: function( namespaces ) {
2554 jQuery.event.remove( this, ".specialSubmit" );
2560 // change delegation, happens here so we have bind.
2561 if ( !jQuery.support.changeBubbles ) {
2565 getVal = function( elem ) {
2566 var type = elem.type, val = elem.value;
2568 if ( type === "radio" || type === "checkbox" ) {
2571 } else if ( type === "select-multiple" ) {
2572 val = elem.selectedIndex > -1 ?
2573 jQuery.map( elem.options, function( elem ) {
2574 return elem.selected;
2578 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2579 val = elem.selectedIndex;
2585 testChange = function testChange( e ) {
2586 var elem = e.target, data, val;
2588 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2592 data = jQuery.data( elem, "_change_data" );
2595 // the current data will be also retrieved by beforeactivate
2596 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2597 jQuery.data( elem, "_change_data", val );
2600 if ( data === undefined || val === data ) {
2604 if ( data != null || val ) {
2606 e.liveFired = undefined;
2607 return jQuery.event.trigger( e, arguments[1], elem );
2611 jQuery.event.special.change = {
2613 focusout: testChange,
2615 beforedeactivate: testChange,
2617 click: function( e ) {
2618 var elem = e.target, type = elem.type;
2620 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2621 return testChange.call( this, e );
2625 // Change has to be called before submit
2626 // Keydown will be called before keypress, which is used in submit-event delegation
2627 keydown: function( e ) {
2628 var elem = e.target, type = elem.type;
2630 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2631 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2632 type === "select-multiple" ) {
2633 return testChange.call( this, e );
2637 // Beforeactivate happens also before the previous element is blurred
2638 // with this event you can't trigger a change event, but you can store
2640 beforeactivate: function( e ) {
2641 var elem = e.target;
2642 jQuery.data( elem, "_change_data", getVal(elem) );
2646 setup: function( data, namespaces ) {
2647 if ( this.type === "file" ) {
2651 for ( var type in changeFilters ) {
2652 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2655 return rformElems.test( this.nodeName );
2658 teardown: function( namespaces ) {
2659 jQuery.event.remove( this, ".specialChange" );
2661 return rformElems.test( this.nodeName );
2665 changeFilters = jQuery.event.special.change.filters;
2667 // Handle when the input is .focus()'d
2668 changeFilters.focus = changeFilters.beforeactivate;
2671 function trigger( type, elem, args ) {
2672 args[0].type = type;
2673 return jQuery.event.handle.apply( elem, args );
2676 // Create "bubbling" focus and blur events
2677 if ( document.addEventListener ) {
2678 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2679 jQuery.event.special[ fix ] = {
2681 if ( focusCounts[fix]++ === 0 ) {
2682 document.addEventListener( orig, handler, true );
2685 teardown: function() {
2686 if ( --focusCounts[fix] === 0 ) {
2687 document.removeEventListener( orig, handler, true );
2692 function handler( e ) {
2693 e = jQuery.event.fix( e );
2695 return jQuery.event.trigger( e, null, e.target );
2700 jQuery.each(["bind", "one"], function( i, name ) {
2701 jQuery.fn[ name ] = function( type, data, fn ) {
2702 // Handle object literals
2703 if ( typeof type === "object" ) {
2704 for ( var key in type ) {
2705 this[ name ](key, data, type[key], fn);
2710 if ( jQuery.isFunction( data ) || data === false ) {
2715 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2716 jQuery( this ).unbind( event, handler );
2717 return fn.apply( this, arguments );
2720 if ( type === "unload" && name !== "one" ) {
2721 this.one( type, data, fn );
2724 for ( var i = 0, l = this.length; i < l; i++ ) {
2725 jQuery.event.add( this[i], type, handler, data );
2734 unbind: function( type, fn ) {
2735 // Handle object literals
2736 if ( typeof type === "object" && !type.preventDefault ) {
2737 for ( var key in type ) {
2738 this.unbind(key, type[key]);
2742 for ( var i = 0, l = this.length; i < l; i++ ) {
2743 jQuery.event.remove( this[i], type, fn );
2750 delegate: function( selector, types, data, fn ) {
2751 return this.live( types, data, fn, selector );
2754 undelegate: function( selector, types, fn ) {
2755 if ( arguments.length === 0 ) {
2756 return this.unbind( "live" );
2759 return this.die( types, null, fn, selector );
2763 trigger: function( type, data ) {
2764 return this.each(function() {
2765 jQuery.event.trigger( type, data, this );
2769 triggerHandler: function( type, data ) {
2771 var event = jQuery.Event( type );
2772 event.preventDefault();
2773 event.stopPropagation();
2774 jQuery.event.trigger( event, data, this[0] );
2775 return event.result;
2779 toggle: function( fn ) {
2780 // Save reference to arguments for access in closure
2781 var args = arguments,
2784 // link all the functions, so any of them can unbind this click handler
2785 while ( i < args.length ) {
2786 jQuery.proxy( fn, args[ i++ ] );
2789 return this.click( jQuery.proxy( fn, function( event ) {
2790 // Figure out which function to execute
2791 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2792 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2794 // Make sure that clicks stop
2795 event.preventDefault();
2797 // and execute the function
2798 return args[ lastToggle ].apply( this, arguments ) || false;
2802 hover: function( fnOver, fnOut ) {
2803 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2810 mouseenter: "mouseover",
2811 mouseleave: "mouseout"
2814 jQuery.each(["live", "die"], function( i, name ) {
2815 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2816 var type, i = 0, match, namespaces, preType,
2817 selector = origSelector || this.selector,
2818 context = origSelector ? this : jQuery( this.context );
2820 if ( typeof types === "object" && !types.preventDefault ) {
2821 for ( var key in types ) {
2822 context[ name ]( key, data, types[key], selector );
2828 if ( jQuery.isFunction( data ) ) {
2833 types = (types || "").split(" ");
2835 while ( (type = types[ i++ ]) != null ) {
2836 match = rnamespaces.exec( type );
2840 namespaces = match[0];
2841 type = type.replace( rnamespaces, "" );
2844 if ( type === "hover" ) {
2845 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2851 if ( type === "focus" || type === "blur" ) {
2852 types.push( liveMap[ type ] + namespaces );
2853 type = type + namespaces;
2856 type = (liveMap[ type ] || type) + namespaces;
2859 if ( name === "live" ) {
2860 // bind live handler
2861 for ( var j = 0, l = context.length; j < l; j++ ) {
2862 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
2863 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2867 // unbind live handler
2868 context.unbind( "live." + liveConvert( type, selector ), fn );
2876 function liveHandler( event ) {
2877 var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2880 events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
2882 if ( typeof events === "function" ) {
2883 events = events.events;
2886 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2887 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2891 if ( event.namespace ) {
2892 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2895 event.liveFired = this;
2897 var live = events.live.slice(0);
2899 for ( j = 0; j < live.length; j++ ) {
2900 handleObj = live[j];
2902 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2903 selectors.push( handleObj.selector );
2906 live.splice( j--, 1 );
2910 match = jQuery( event.target ).closest( selectors, event.currentTarget );
2912 for ( i = 0, l = match.length; i < l; i++ ) {
2915 for ( j = 0; j < live.length; j++ ) {
2916 handleObj = live[j];
2918 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
2922 // Those two events require additional checking
2923 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2924 event.type = handleObj.preType;
2925 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2928 if ( !related || related !== elem ) {
2929 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
2935 for ( i = 0, l = elems.length; i < l; i++ ) {
2938 if ( maxLevel && match.level > maxLevel ) {
2942 event.currentTarget = match.elem;
2943 event.data = match.handleObj.data;
2944 event.handleObj = match.handleObj;
2946 ret = match.handleObj.origHandler.apply( match.elem, arguments );
2948 if ( ret === false || event.isPropagationStopped() ) {
2949 maxLevel = match.level;
2951 if ( ret === false ) {
2954 if ( event.isImmediatePropagationStopped() ) {
2963 function liveConvert( type, selector ) {
2964 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
2967 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2968 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2969 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2971 // Handle event binding
2972 jQuery.fn[ name ] = function( data, fn ) {
2978 return arguments.length > 0 ?
2979 this.bind( name, data, fn ) :
2980 this.trigger( name );
2983 if ( jQuery.attrFn ) {
2984 jQuery.attrFn[ name ] = true;
2988 // Prevent memory leaks in IE
2989 // Window isn't included so as not to unbind existing unload events
2991 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2992 if ( window.attachEvent && !window.addEventListener ) {
2993 jQuery(window).bind("unload", function() {
2994 for ( var id in jQuery.cache ) {
2995 if ( jQuery.cache[ id ].handle ) {
2996 // Try/Catch is to handle iframes being unloaded, see #4280
2998 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
3007 * Sizzle CSS Selector Engine - v1.0
3008 * Copyright 2009, The Dojo Foundation
3009 * Released under the MIT, BSD, and GPL Licenses.
3010 * More information: http://sizzlejs.com/
3014 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3016 toString = Object.prototype.toString,
3017 hasDuplicate = false,
3018 baseHasDuplicate = true;
3020 // Here we check if the JavaScript engine is using some sort of
3021 // optimization where it does not always call our comparision
3022 // function. If that is the case, discard the hasDuplicate value.
3023 // Thus far that includes Google Chrome.
3024 [0, 0].sort(function() {
3025 baseHasDuplicate = false;
3029 var Sizzle = function( selector, context, results, seed ) {
3030 results = results || [];
3031 context = context || document;
3033 var origContext = context;
3035 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3039 if ( !selector || typeof selector !== "string" ) {
3043 var m, set, checkSet, extra, ret, cur, pop, i,
3045 contextXML = Sizzle.isXML( context ),
3049 // Reset the position of the chunker regexp (start from head)
3052 m = chunker.exec( soFar );
3066 if ( parts.length > 1 && origPOS.exec( selector ) ) {
3068 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3069 set = posProcess( parts[0] + parts[1], context );
3072 set = Expr.relative[ parts[0] ] ?
3074 Sizzle( parts.shift(), context );
3076 while ( parts.length ) {
3077 selector = parts.shift();
3079 if ( Expr.relative[ selector ] ) {
3080 selector += parts.shift();
3083 set = posProcess( selector, set );
3088 // Take a shortcut and set the context if the root selector is an ID
3089 // (but not if it'll be faster if the inner selector is an ID)
3090 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3091 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3093 ret = Sizzle.find( parts.shift(), context, contextXML );
3094 context = ret.expr ?
3095 Sizzle.filter( ret.expr, ret.set )[0] :
3101 { expr: parts.pop(), set: makeArray(seed) } :
3102 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3105 Sizzle.filter( ret.expr, ret.set ) :
3108 if ( parts.length > 0 ) {
3109 checkSet = makeArray( set );
3115 while ( parts.length ) {
3119 if ( !Expr.relative[ cur ] ) {
3125 if ( pop == null ) {
3129 Expr.relative[ cur ]( checkSet, pop, contextXML );
3133 checkSet = parts = [];
3142 Sizzle.error( cur || selector );
3145 if ( toString.call(checkSet) === "[object Array]" ) {
3147 results.push.apply( results, checkSet );
3149 } else if ( context && context.nodeType === 1 ) {
3150 for ( i = 0; checkSet[i] != null; i++ ) {
3151 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3152 results.push( set[i] );
3157 for ( i = 0; checkSet[i] != null; i++ ) {
3158 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3159 results.push( set[i] );
3165 makeArray( checkSet, results );
3169 Sizzle( extra, origContext, results, seed );
3170 Sizzle.uniqueSort( results );
3176 Sizzle.uniqueSort = function( results ) {
3178 hasDuplicate = baseHasDuplicate;
3179 results.sort( sortOrder );
3181 if ( hasDuplicate ) {
3182 for ( var i = 1; i < results.length; i++ ) {
3183 if ( results[i] === results[ i - 1 ] ) {
3184 results.splice( i--, 1 );
3193 Sizzle.matches = function( expr, set ) {
3194 return Sizzle( expr, null, null, set );
3197 Sizzle.matchesSelector = function( node, expr ) {
3198 return Sizzle( expr, null, null, [node] ).length > 0;
3201 Sizzle.find = function( expr, context, isXML ) {
3208 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3210 type = Expr.order[i];
3212 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3213 var left = match[1];
3214 match.splice( 1, 1 );
3216 if ( left.substr( left.length - 1 ) !== "\\" ) {
3217 match[1] = (match[1] || "").replace(/\\/g, "");
3218 set = Expr.find[ type ]( match, context, isXML );
3220 if ( set != null ) {
3221 expr = expr.replace( Expr.match[ type ], "" );
3229 set = context.getElementsByTagName( "*" );
3232 return { set: set, expr: expr };
3235 Sizzle.filter = function( expr, set, inplace, not ) {
3236 var match, anyFound,
3240 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
3242 while ( expr && set.length ) {
3243 for ( var type in Expr.filter ) {
3244 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3246 filter = Expr.filter[ type ],
3253 if ( left.substr( left.length - 1 ) === "\\" ) {
3257 if ( curLoop === result ) {
3261 if ( Expr.preFilter[ type ] ) {
3262 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3265 anyFound = found = true;
3267 } else if ( match === true ) {
3273 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3275 found = filter( item, match, i, curLoop );
3276 var pass = not ^ !!found;
3278 if ( inplace && found != null ) {
3286 } else if ( pass ) {
3287 result.push( item );
3294 if ( found !== undefined ) {
3299 expr = expr.replace( Expr.match[ type ], "" );
3310 // Improper expression
3311 if ( expr === old ) {
3312 if ( anyFound == null ) {
3313 Sizzle.error( expr );
3326 Sizzle.error = function( msg ) {
3327 throw "Syntax error, unrecognized expression: " + msg;
3330 var Expr = Sizzle.selectors = {
3331 order: [ "ID", "NAME", "TAG" ],
3334 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3335 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3336 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3337 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3338 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3339 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3340 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3341 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3347 "class": "className",
3352 href: function( elem ) {
3353 return elem.getAttribute( "href" );
3358 "+": function(checkSet, part){
3359 var isPartStr = typeof part === "string",
3360 isTag = isPartStr && !/\W/.test( part ),
3361 isPartStrNotTag = isPartStr && !isTag;
3364 part = part.toLowerCase();
3367 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3368 if ( (elem = checkSet[i]) ) {
3369 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3371 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3377 if ( isPartStrNotTag ) {
3378 Sizzle.filter( part, checkSet, true );
3382 ">": function( checkSet, part ) {
3384 isPartStr = typeof part === "string",
3386 l = checkSet.length;
3388 if ( isPartStr && !/\W/.test( part ) ) {
3389 part = part.toLowerCase();
3391 for ( ; i < l; i++ ) {
3395 var parent = elem.parentNode;
3396 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3401 for ( ; i < l; i++ ) {
3405 checkSet[i] = isPartStr ?
3407 elem.parentNode === part;
3412 Sizzle.filter( part, checkSet, true );
3417 "": function(checkSet, part, isXML){
3422 if ( typeof part === "string" && !/\W/.test(part) ) {
3423 part = part.toLowerCase();
3425 checkFn = dirNodeCheck;
3428 checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
3431 "~": function( checkSet, part, isXML ) {
3436 if ( typeof part === "string" && !/\W/.test( part ) ) {
3437 part = part.toLowerCase();
3439 checkFn = dirNodeCheck;
3442 checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
3447 ID: function( match, context, isXML ) {
3448 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3449 var m = context.getElementById(match[1]);
3450 // Check parentNode to catch when Blackberry 4.6 returns
3451 // nodes that are no longer in the document #6963
3452 return m && m.parentNode ? [m] : [];
3456 NAME: function( match, context ) {
3457 if ( typeof context.getElementsByName !== "undefined" ) {
3459 results = context.getElementsByName( match[1] );
3461 for ( var i = 0, l = results.length; i < l; i++ ) {
3462 if ( results[i].getAttribute("name") === match[1] ) {
3463 ret.push( results[i] );
3467 return ret.length === 0 ? null : ret;
3471 TAG: function( match, context ) {
3472 return context.getElementsByTagName( match[1] );
3476 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
3477 match = " " + match[1].replace(/\\/g, "") + " ";
3483 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3485 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3487 result.push( elem );
3490 } else if ( inplace ) {
3499 ID: function( match ) {
3500 return match[1].replace(/\\/g, "");
3503 TAG: function( match, curLoop ) {
3504 return match[1].toLowerCase();
3507 CHILD: function( match ) {
3508 if ( match[1] === "nth" ) {
3509 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3510 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3511 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3512 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3514 // calculate the numbers (first)n+(last) including if they are negative
3515 match[2] = (test[1] + (test[2] || 1)) - 0;
3516 match[3] = test[3] - 0;
3519 // TODO: Move to normal caching system
3525 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
3526 var name = match[1].replace(/\\/g, "");
3528 if ( !isXML && Expr.attrMap[name] ) {
3529 match[1] = Expr.attrMap[name];
3532 if ( match[2] === "~=" ) {
3533 match[4] = " " + match[4] + " ";
3539 PSEUDO: function( match, curLoop, inplace, result, not ) {
3540 if ( match[1] === "not" ) {
3541 // If we're dealing with a complex expression, or a simple one
3542 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3543 match[3] = Sizzle(match[3], null, null, curLoop);
3546 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3549 result.push.apply( result, ret );
3555 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3562 POS: function( match ) {
3563 match.unshift( true );
3570 enabled: function( elem ) {
3571 return elem.disabled === false && elem.type !== "hidden";
3574 disabled: function( elem ) {
3575 return elem.disabled === true;
3578 checked: function( elem ) {
3579 return elem.checked === true;
3582 selected: function( elem ) {
3583 // Accessing this property makes selected-by-default
3584 // options in Safari work properly
3585 elem.parentNode.selectedIndex;
3587 return elem.selected === true;
3590 parent: function( elem ) {
3591 return !!elem.firstChild;
3594 empty: function( elem ) {
3595 return !elem.firstChild;
3598 has: function( elem, i, match ) {
3599 return !!Sizzle( match[3], elem ).length;
3602 header: function( elem ) {
3603 return (/h\d/i).test( elem.nodeName );
3606 text: function( elem ) {
3607 return "text" === elem.type;
3609 radio: function( elem ) {
3610 return "radio" === elem.type;
3613 checkbox: function( elem ) {
3614 return "checkbox" === elem.type;
3617 file: function( elem ) {
3618 return "file" === elem.type;
3620 password: function( elem ) {
3621 return "password" === elem.type;
3624 submit: function( elem ) {
3625 return "submit" === elem.type;
3628 image: function( elem ) {
3629 return "image" === elem.type;
3632 reset: function( elem ) {
3633 return "reset" === elem.type;
3636 button: function( elem ) {
3637 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3640 input: function( elem ) {
3641 return (/input|select|textarea|button/i).test( elem.nodeName );
3645 first: function( elem, i ) {
3649 last: function( elem, i, match, array ) {
3650 return i === array.length - 1;
3653 even: function( elem, i ) {
3657 odd: function( elem, i ) {
3661 lt: function( elem, i, match ) {
3662 return i < match[3] - 0;
3665 gt: function( elem, i, match ) {
3666 return i > match[3] - 0;
3669 nth: function( elem, i, match ) {
3670 return match[3] - 0 === i;
3673 eq: function( elem, i, match ) {
3674 return match[3] - 0 === i;
3678 PSEUDO: function( elem, match, i, array ) {
3679 var name = match[1],
3680 filter = Expr.filters[ name ];
3683 return filter( elem, i, match, array );
3685 } else if ( name === "contains" ) {
3686 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3688 } else if ( name === "not" ) {
3691 for ( var j = 0, l = not.length; j < l; j++ ) {
3692 if ( not[j] === elem ) {
3700 Sizzle.error( "Syntax error, unrecognized expression: " + name );
3704 CHILD: function( elem, match ) {
3705 var type = match[1],
3711 while ( (node = node.previousSibling) ) {
3712 if ( node.nodeType === 1 ) {
3717 if ( type === "first" ) {
3724 while ( (node = node.nextSibling) ) {
3725 if ( node.nodeType === 1 ) {
3733 var first = match[2],
3736 if ( first === 1 && last === 0 ) {
3740 var doneName = match[0],
3741 parent = elem.parentNode;
3743 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3746 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3747 if ( node.nodeType === 1 ) {
3748 node.nodeIndex = ++count;
3752 parent.sizcache = doneName;
3755 var diff = elem.nodeIndex - last;
3757 if ( first === 0 ) {
3761 return ( diff % first === 0 && diff / first >= 0 );
3766 ID: function( elem, match ) {
3767 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3770 TAG: function( elem, match ) {
3771 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3774 CLASS: function( elem, match ) {
3775 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3776 .indexOf( match ) > -1;
3779 ATTR: function( elem, match ) {
3780 var name = match[1],
3781 result = Expr.attrHandle[ name ] ?
3782 Expr.attrHandle[ name ]( elem ) :
3783 elem[ name ] != null ?
3785 elem.getAttribute( name ),
3786 value = result + "",
3790 return result == null ?
3795 value.indexOf(check) >= 0 :
3797 (" " + value + " ").indexOf(check) >= 0 :
3799 value && result !== false :
3803 value.indexOf(check) === 0 :
3805 value.substr(value.length - check.length) === check :
3807 value === check || value.substr(0, check.length + 1) === check + "-" :
3811 POS: function( elem, match, i, array ) {
3812 var name = match[2],
3813 filter = Expr.setFilters[ name ];
3816 return filter( elem, i, match, array );
3822 var origPOS = Expr.match.POS,
3823 fescape = function(all, num){
3824 return "\\" + (num - 0 + 1);
3827 for ( var type in Expr.match ) {
3828 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
3829 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
3832 var makeArray = function( array, results ) {
3833 array = Array.prototype.slice.call( array, 0 );
3836 results.push.apply( results, array );
3843 // Perform a simple check to determine if the browser is capable of
3844 // converting a NodeList to an array using builtin methods.
3845 // Also verifies that the returned array holds DOM nodes
3846 // (which is not the case in the Blackberry browser)
3848 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3850 // Provide a fallback method if it does not work
3852 makeArray = function( array, results ) {
3854 ret = results || [];
3856 if ( toString.call(array) === "[object Array]" ) {
3857 Array.prototype.push.apply( ret, array );
3860 if ( typeof array.length === "number" ) {
3861 for ( var l = array.length; i < l; i++ ) {
3862 ret.push( array[i] );
3866 for ( ; array[i]; i++ ) {
3867 ret.push( array[i] );
3876 var sortOrder, siblingCheck;
3878 if ( document.documentElement.compareDocumentPosition ) {
3879 sortOrder = function( a, b ) {
3881 hasDuplicate = true;
3885 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3886 return a.compareDocumentPosition ? -1 : 1;
3889 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
3893 sortOrder = function( a, b ) {
3901 // The nodes are identical, we can exit early
3903 hasDuplicate = true;
3906 // If the nodes are siblings (or identical) we can do a quick check
3907 } else if ( aup === bup ) {
3908 return siblingCheck( a, b );
3910 // If no parents were found then the nodes are disconnected
3911 } else if ( !aup ) {
3914 } else if ( !bup ) {
3918 // Otherwise they're somewhere else in the tree so we need
3919 // to build up a full list of the parentNodes for comparison
3922 cur = cur.parentNode;
3929 cur = cur.parentNode;
3935 // Start walking down the tree looking for a discrepancy
3936 for ( var i = 0; i < al && i < bl; i++ ) {
3937 if ( ap[i] !== bp[i] ) {
3938 return siblingCheck( ap[i], bp[i] );
3942 // We ended someplace up the tree so do a sibling check
3944 siblingCheck( a, bp[i], -1 ) :
3945 siblingCheck( ap[i], b, 1 );
3948 siblingCheck = function( a, b, ret ) {
3953 var cur = a.nextSibling;
3960 cur = cur.nextSibling;
3967 // Utility function for retreiving the text value of an array of DOM nodes
3968 Sizzle.getText = function( elems ) {
3971 for ( var i = 0; elems[i]; i++ ) {
3974 // Get the text from text nodes and CDATA nodes
3975 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3976 ret += elem.nodeValue;
3978 // Traverse everything else, except comment nodes
3979 } else if ( elem.nodeType !== 8 ) {
3980 ret += Sizzle.getText( elem.childNodes );
3987 // Check to see if the browser returns elements by name when
3988 // querying by getElementById (and provide a workaround)
3990 // We're going to inject a fake input element with a specified name
3991 var form = document.createElement("div"),
3992 id = "script" + (new Date()).getTime(),
3993 root = document.documentElement;
3995 form.innerHTML = "<a name='" + id + "'/>";
3997 // Inject it into the root element, check its status, and remove it quickly
3998 root.insertBefore( form, root.firstChild );
4000 // The workaround has to do additional checks after a getElementById
4001 // Which slows things down for other browsers (hence the branching)
4002 if ( document.getElementById( id ) ) {
4003 Expr.find.ID = function( match, context, isXML ) {
4004 if ( typeof context.getElementById !== "undefined" && !isXML ) {
4005 var m = context.getElementById(match[1]);
4008 m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4015 Expr.filter.ID = function( elem, match ) {
4016 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4018 return elem.nodeType === 1 && node && node.nodeValue === match;
4022 root.removeChild( form );
4024 // release memory in IE
4029 // Check to see if the browser returns only elements
4030 // when doing getElementsByTagName("*")
4032 // Create a fake element
4033 var div = document.createElement("div");
4034 div.appendChild( document.createComment("") );
4036 // Make sure no comments are found
4037 if ( div.getElementsByTagName("*").length > 0 ) {
4038 Expr.find.TAG = function( match, context ) {
4039 var results = context.getElementsByTagName( match[1] );
4041 // Filter out possible comments
4042 if ( match[1] === "*" ) {
4045 for ( var i = 0; results[i]; i++ ) {
4046 if ( results[i].nodeType === 1 ) {
4047 tmp.push( results[i] );
4058 // Check to see if an attribute returns normalized href attributes
4059 div.innerHTML = "<a href='#'></a>";
4061 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4062 div.firstChild.getAttribute("href") !== "#" ) {
4064 Expr.attrHandle.href = function( elem ) {
4065 return elem.getAttribute( "href", 2 );
4069 // release memory in IE
4073 if ( document.querySelectorAll ) {
4075 var oldSizzle = Sizzle,
4076 div = document.createElement("div"),
4079 div.innerHTML = "<p class='TEST'></p>";
4081 // Safari can't handle uppercase or unicode characters when
4083 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4087 Sizzle = function( query, context, extra, seed ) {
4088 context = context || document;
4090 // Make sure that attribute selectors are quoted
4091 query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4093 // Only use querySelectorAll on non-XML documents
4094 // (ID selectors don't work in non-HTML documents)
4095 if ( !seed && !Sizzle.isXML(context) ) {
4096 if ( context.nodeType === 9 ) {
4098 return makeArray( context.querySelectorAll(query), extra );
4099 } catch(qsaError) {}
4101 // qSA works strangely on Element-rooted queries
4102 // We can work around this by specifying an extra ID on the root
4103 // and working up from there (Thanks to Andrew Dupont for the technique)
4104 // IE 8 doesn't work on object elements
4105 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4106 var old = context.getAttribute( "id" ),
4110 context.setAttribute( "id", nid );
4114 return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
4116 } catch(pseudoError) {
4119 context.removeAttribute( "id" );
4125 return oldSizzle(query, context, extra, seed);
4128 for ( var prop in oldSizzle ) {
4129 Sizzle[ prop ] = oldSizzle[ prop ];
4132 // release memory in IE
4138 var html = document.documentElement,
4139 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
4140 pseudoWorks = false;
4143 // This should fail with an exception
4144 // Gecko does not error, returns false instead
4145 matches.call( document.documentElement, "[test!='']:sizzle" );
4147 } catch( pseudoError ) {
4152 Sizzle.matchesSelector = function( node, expr ) {
4153 // Make sure that attribute selectors are quoted
4154 expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
4156 if ( !Sizzle.isXML( node ) ) {
4158 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
4159 return matches.call( node, expr );
4164 return Sizzle(expr, null, null, [node]).length > 0;
4170 var div = document.createElement("div");
4172 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4174 // Opera can't find a second classname (in 9.6)
4175 // Also, make sure that getElementsByClassName actually exists
4176 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
4180 // Safari caches class attributes, doesn't catch changes (in 3.2)
4181 div.lastChild.className = "e";
4183 if ( div.getElementsByClassName("e").length === 1 ) {
4187 Expr.order.splice(1, 0, "CLASS");
4188 Expr.find.CLASS = function( match, context, isXML ) {
4189 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4190 return context.getElementsByClassName(match[1]);
4194 // release memory in IE
4198 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4199 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4200 var elem = checkSet[i];
4208 if ( elem.sizcache === doneName ) {
4209 match = checkSet[elem.sizset];
4213 if ( elem.nodeType === 1 && !isXML ){
4214 elem.sizcache = doneName;
4218 if ( elem.nodeName.toLowerCase() === cur ) {
4226 checkSet[i] = match;
4231 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4232 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4233 var elem = checkSet[i];
4241 if ( elem.sizcache === doneName ) {
4242 match = checkSet[elem.sizset];
4246 if ( elem.nodeType === 1 ) {
4248 elem.sizcache = doneName;
4252 if ( typeof cur !== "string" ) {
4253 if ( elem === cur ) {
4258 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4267 checkSet[i] = match;
4272 if ( document.documentElement.contains ) {
4273 Sizzle.contains = function( a, b ) {
4274 return a !== b && (a.contains ? a.contains(b) : true);
4277 } else if ( document.documentElement.compareDocumentPosition ) {
4278 Sizzle.contains = function( a, b ) {
4279 return !!(a.compareDocumentPosition(b) & 16);
4283 Sizzle.contains = function() {
4288 Sizzle.isXML = function( elem ) {
4289 // documentElement is verified for cases where it doesn't yet exist
4290 // (such as loading iframes in IE - #4833)
4291 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4293 return documentElement ? documentElement.nodeName !== "HTML" : false;
4296 var posProcess = function( selector, context ) {
4300 root = context.nodeType ? [context] : context;
4302 // Position selectors must be done after the filter
4303 // And so must :not(positional) so we move all PSEUDOs to the end
4304 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4306 selector = selector.replace( Expr.match.PSEUDO, "" );
4309 selector = Expr.relative[selector] ? selector + "*" : selector;
4311 for ( var i = 0, l = root.length; i < l; i++ ) {
4312 Sizzle( selector, root[i], tmpSet );
4315 return Sizzle.filter( later, tmpSet );
4319 jQuery.find = Sizzle;
4320 jQuery.expr = Sizzle.selectors;
4321 jQuery.expr[":"] = jQuery.expr.filters;
4322 jQuery.unique = Sizzle.uniqueSort;
4323 jQuery.text = Sizzle.getText;
4324 jQuery.isXMLDoc = Sizzle.isXML;
4325 jQuery.contains = Sizzle.contains;
4331 var runtil = /Until$/,
4332 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4333 // Note: This RegExp should be improved, or likely pulled from Sizzle
4334 rmultiselector = /,/,
4335 isSimple = /^.[^:#\[\.,]*$/,
4336 slice = Array.prototype.slice,
4337 POS = jQuery.expr.match.POS;
4340 find: function( selector ) {
4341 var ret = this.pushStack( "", "find", selector ),
4344 for ( var i = 0, l = this.length; i < l; i++ ) {
4345 length = ret.length;
4346 jQuery.find( selector, this[i], ret );
4349 // Make sure that the results are unique
4350 for ( var n = length; n < ret.length; n++ ) {
4351 for ( var r = 0; r < length; r++ ) {
4352 if ( ret[r] === ret[n] ) {
4364 has: function( target ) {
4365 var targets = jQuery( target );
4366 return this.filter(function() {
4367 for ( var i = 0, l = targets.length; i < l; i++ ) {
4368 if ( jQuery.contains( this, targets[i] ) ) {
4375 not: function( selector ) {
4376 return this.pushStack( winnow(this, selector, false), "not", selector);
4379 filter: function( selector ) {
4380 return this.pushStack( winnow(this, selector, true), "filter", selector );
4383 is: function( selector ) {
4384 return !!selector && jQuery.filter( selector, this ).length > 0;
4387 closest: function( selectors, context ) {
4388 var ret = [], i, l, cur = this[0];
4390 if ( jQuery.isArray( selectors ) ) {
4391 var match, selector,
4395 if ( cur && selectors.length ) {
4396 for ( i = 0, l = selectors.length; i < l; i++ ) {
4397 selector = selectors[i];
4399 if ( !matches[selector] ) {
4400 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4401 jQuery( selector, context || this.context ) :
4406 while ( cur && cur.ownerDocument && cur !== context ) {
4407 for ( selector in matches ) {
4408 match = matches[selector];
4410 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4411 ret.push({ selector: selector, elem: cur, level: level });
4415 cur = cur.parentNode;
4423 var pos = POS.test( selectors ) ?
4424 jQuery( selectors, context || this.context ) : null;
4426 for ( i = 0, l = this.length; i < l; i++ ) {
4430 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4435 cur = cur.parentNode;
4436 if ( !cur || !cur.ownerDocument || cur === context ) {
4443 ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4445 return this.pushStack( ret, "closest", selectors );
4448 // Determine the position of an element within
4449 // the matched set of elements
4450 index: function( elem ) {
4451 if ( !elem || typeof elem === "string" ) {
4452 return jQuery.inArray( this[0],
4453 // If it receives a string, the selector is used
4454 // If it receives nothing, the siblings are used
4455 elem ? jQuery( elem ) : this.parent().children() );
4457 // Locate the position of the desired element
4458 return jQuery.inArray(
4459 // If it receives a jQuery object, the first element is used
4460 elem.jquery ? elem[0] : elem, this );
4463 add: function( selector, context ) {
4464 var set = typeof selector === "string" ?
4465 jQuery( selector, context || this.context ) :
4466 jQuery.makeArray( selector ),
4467 all = jQuery.merge( this.get(), set );
4469 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4471 jQuery.unique( all ) );
4474 andSelf: function() {
4475 return this.add( this.prevObject );
4479 // A painfully simple check to see if an element is disconnected
4480 // from a document (should be improved, where feasible).
4481 function isDisconnected( node ) {
4482 return !node || !node.parentNode || node.parentNode.nodeType === 11;
4486 parent: function( elem ) {
4487 var parent = elem.parentNode;
4488 return parent && parent.nodeType !== 11 ? parent : null;
4490 parents: function( elem ) {
4491 return jQuery.dir( elem, "parentNode" );
4493 parentsUntil: function( elem, i, until ) {
4494 return jQuery.dir( elem, "parentNode", until );
4496 next: function( elem ) {
4497 return jQuery.nth( elem, 2, "nextSibling" );
4499 prev: function( elem ) {
4500 return jQuery.nth( elem, 2, "previousSibling" );
4502 nextAll: function( elem ) {
4503 return jQuery.dir( elem, "nextSibling" );
4505 prevAll: function( elem ) {
4506 return jQuery.dir( elem, "previousSibling" );
4508 nextUntil: function( elem, i, until ) {
4509 return jQuery.dir( elem, "nextSibling", until );
4511 prevUntil: function( elem, i, until ) {
4512 return jQuery.dir( elem, "previousSibling", until );
4514 siblings: function( elem ) {
4515 return jQuery.sibling( elem.parentNode.firstChild, elem );
4517 children: function( elem ) {
4518 return jQuery.sibling( elem.firstChild );
4520 contents: function( elem ) {
4521 return jQuery.nodeName( elem, "iframe" ) ?
4522 elem.contentDocument || elem.contentWindow.document :
4523 jQuery.makeArray( elem.childNodes );
4525 }, function( name, fn ) {
4526 jQuery.fn[ name ] = function( until, selector ) {
4527 var ret = jQuery.map( this, fn, until );
4529 if ( !runtil.test( name ) ) {
4533 if ( selector && typeof selector === "string" ) {
4534 ret = jQuery.filter( selector, ret );
4537 ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4539 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4540 ret = ret.reverse();
4543 return this.pushStack( ret, name, slice.call(arguments).join(",") );
4548 filter: function( expr, elems, not ) {
4550 expr = ":not(" + expr + ")";
4553 return elems.length === 1 ?
4554 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4555 jQuery.find.matches(expr, elems);
4558 dir: function( elem, dir, until ) {
4562 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4563 if ( cur.nodeType === 1 ) {
4564 matched.push( cur );
4571 nth: function( cur, result, dir, elem ) {
4572 result = result || 1;
4575 for ( ; cur; cur = cur[dir] ) {
4576 if ( cur.nodeType === 1 && ++num === result ) {
4584 sibling: function( n, elem ) {
4587 for ( ; n; n = n.nextSibling ) {
4588 if ( n.nodeType === 1 && n !== elem ) {
4597 // Implement the identical functionality for filter and not
4598 function winnow( elements, qualifier, keep ) {
4599 if ( jQuery.isFunction( qualifier ) ) {
4600 return jQuery.grep(elements, function( elem, i ) {
4601 var retVal = !!qualifier.call( elem, i, elem );
4602 return retVal === keep;
4605 } else if ( qualifier.nodeType ) {
4606 return jQuery.grep(elements, function( elem, i ) {
4607 return (elem === qualifier) === keep;
4610 } else if ( typeof qualifier === "string" ) {
4611 var filtered = jQuery.grep(elements, function( elem ) {
4612 return elem.nodeType === 1;
4615 if ( isSimple.test( qualifier ) ) {
4616 return jQuery.filter(qualifier, filtered, !keep);
4618 qualifier = jQuery.filter( qualifier, filtered );
4622 return jQuery.grep(elements, function( elem, i ) {
4623 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4630 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4631 rleadingWhitespace = /^\s+/,
4632 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4633 rtagName = /<([\w:]+)/,
4635 rhtml = /<|&#?\w+;/,
4636 rnocache = /<(?:script|object|embed|option|style)/i,
4637 // checked="checked" or checked (html5)
4638 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4639 raction = /\=([^="'>\s]+\/)>/g,
4641 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4642 legend: [ 1, "<fieldset>", "</fieldset>" ],
4643 thead: [ 1, "<table>", "</table>" ],
4644 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4645 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4646 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4647 area: [ 1, "<map>", "</map>" ],
4648 _default: [ 0, "", "" ]
4651 wrapMap.optgroup = wrapMap.option;
4652 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4653 wrapMap.th = wrapMap.td;
4655 // IE can't serialize <link> and <script> tags normally
4656 if ( !jQuery.support.htmlSerialize ) {
4657 wrapMap._default = [ 1, "div<div>", "</div>" ];
4661 text: function( text ) {
4662 if ( jQuery.isFunction(text) ) {
4663 return this.each(function(i) {
4664 var self = jQuery( this );
4666 self.text( text.call(this, i, self.text()) );
4670 if ( typeof text !== "object" && text !== undefined ) {
4671 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4674 return jQuery.text( this );
4677 wrapAll: function( html ) {
4678 if ( jQuery.isFunction( html ) ) {
4679 return this.each(function(i) {
4680 jQuery(this).wrapAll( html.call(this, i) );
4685 // The elements to wrap the target around
4686 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4688 if ( this[0].parentNode ) {
4689 wrap.insertBefore( this[0] );
4692 wrap.map(function() {
4695 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4696 elem = elem.firstChild;
4706 wrapInner: function( html ) {
4707 if ( jQuery.isFunction( html ) ) {
4708 return this.each(function(i) {
4709 jQuery(this).wrapInner( html.call(this, i) );
4713 return this.each(function() {
4714 var self = jQuery( this ),
4715 contents = self.contents();
4717 if ( contents.length ) {
4718 contents.wrapAll( html );
4721 self.append( html );
4726 wrap: function( html ) {
4727 return this.each(function() {
4728 jQuery( this ).wrapAll( html );
4732 unwrap: function() {
4733 return this.parent().each(function() {
4734 if ( !jQuery.nodeName( this, "body" ) ) {
4735 jQuery( this ).replaceWith( this.childNodes );
4740 append: function() {
4741 return this.domManip(arguments, true, function( elem ) {
4742 if ( this.nodeType === 1 ) {
4743 this.appendChild( elem );
4748 prepend: function() {
4749 return this.domManip(arguments, true, function( elem ) {
4750 if ( this.nodeType === 1 ) {
4751 this.insertBefore( elem, this.firstChild );
4756 before: function() {
4757 if ( this[0] && this[0].parentNode ) {
4758 return this.domManip(arguments, false, function( elem ) {
4759 this.parentNode.insertBefore( elem, this );
4761 } else if ( arguments.length ) {
4762 var set = jQuery(arguments[0]);
4763 set.push.apply( set, this.toArray() );
4764 return this.pushStack( set, "before", arguments );
4769 if ( this[0] && this[0].parentNode ) {
4770 return this.domManip(arguments, false, function( elem ) {
4771 this.parentNode.insertBefore( elem, this.nextSibling );
4773 } else if ( arguments.length ) {
4774 var set = this.pushStack( this, "after", arguments );
4775 set.push.apply( set, jQuery(arguments[0]).toArray() );
4780 // keepData is for internal use only--do not document
4781 remove: function( selector, keepData ) {
4782 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4783 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4784 if ( !keepData && elem.nodeType === 1 ) {
4785 jQuery.cleanData( elem.getElementsByTagName("*") );
4786 jQuery.cleanData( [ elem ] );
4789 if ( elem.parentNode ) {
4790 elem.parentNode.removeChild( elem );
4799 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4800 // Remove element nodes and prevent memory leaks
4801 if ( elem.nodeType === 1 ) {
4802 jQuery.cleanData( elem.getElementsByTagName("*") );
4805 // Remove any remaining nodes
4806 while ( elem.firstChild ) {
4807 elem.removeChild( elem.firstChild );
4814 clone: function( events ) {
4816 var ret = this.map(function() {
4817 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4818 // IE copies events bound via attachEvent when
4819 // using cloneNode. Calling detachEvent on the
4820 // clone will also remove the events from the orignal
4821 // In order to get around this, we use innerHTML.
4822 // Unfortunately, this means some modifications to
4823 // attributes in IE that are actually only stored
4824 // as properties will not be copied (such as the
4825 // the name attribute on an input).
4826 var html = this.outerHTML,
4827 ownerDocument = this.ownerDocument;
4830 var div = ownerDocument.createElement("div");
4831 div.appendChild( this.cloneNode(true) );
4832 html = div.innerHTML;
4835 return jQuery.clean([html.replace(rinlinejQuery, "")
4836 // Handle the case in IE 8 where action=/test/> self-closes a tag
4837 .replace(raction, '="$1">')
4838 .replace(rleadingWhitespace, "")], ownerDocument)[0];
4840 return this.cloneNode(true);
4844 // Copy the events from the original to the clone
4845 if ( events === true ) {
4846 cloneCopyEvent( this, ret );
4847 cloneCopyEvent( this.find("*"), ret.find("*") );
4850 // Return the cloned set
4854 html: function( value ) {
4855 if ( value === undefined ) {
4856 return this[0] && this[0].nodeType === 1 ?
4857 this[0].innerHTML.replace(rinlinejQuery, "") :
4860 // See if we can take a shortcut and just use innerHTML
4861 } else if ( typeof value === "string" && !rnocache.test( value ) &&
4862 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4863 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4865 value = value.replace(rxhtmlTag, "<$1></$2>");
4868 for ( var i = 0, l = this.length; i < l; i++ ) {
4869 // Remove element nodes and prevent memory leaks
4870 if ( this[i].nodeType === 1 ) {
4871 jQuery.cleanData( this[i].getElementsByTagName("*") );
4872 this[i].innerHTML = value;
4876 // If using innerHTML throws an exception, use the fallback method
4878 this.empty().append( value );
4881 } else if ( jQuery.isFunction( value ) ) {
4882 this.each(function(i){
4883 var self = jQuery( this );
4885 self.html( value.call(this, i, self.html()) );
4889 this.empty().append( value );
4895 replaceWith: function( value ) {
4896 if ( this[0] && this[0].parentNode ) {
4897 // Make sure that the elements are removed from the DOM before they are inserted
4898 // this can help fix replacing a parent with child elements
4899 if ( jQuery.isFunction( value ) ) {
4900 return this.each(function(i) {
4901 var self = jQuery(this), old = self.html();
4902 self.replaceWith( value.call( this, i, old ) );
4906 if ( typeof value !== "string" ) {
4907 value = jQuery( value ).detach();
4910 return this.each(function() {
4911 var next = this.nextSibling,
4912 parent = this.parentNode;
4914 jQuery( this ).remove();
4917 jQuery(next).before( value );
4919 jQuery(parent).append( value );
4923 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4927 detach: function( selector ) {
4928 return this.remove( selector, true );
4931 domManip: function( args, table, callback ) {
4932 var results, first, fragment, parent,
4936 // We can't cloneNode fragments that contain checked, in WebKit
4937 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4938 return this.each(function() {
4939 jQuery(this).domManip( args, table, callback, true );
4943 if ( jQuery.isFunction(value) ) {
4944 return this.each(function(i) {
4945 var self = jQuery(this);
4946 args[0] = value.call(this, i, table ? self.html() : undefined);
4947 self.domManip( args, table, callback );
4952 parent = value && value.parentNode;
4954 // If we're in a fragment, just use that instead of building a new one
4955 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
4956 results = { fragment: parent };
4959 results = jQuery.buildFragment( args, this, scripts );
4962 fragment = results.fragment;
4964 if ( fragment.childNodes.length === 1 ) {
4965 first = fragment = fragment.firstChild;
4967 first = fragment.firstChild;
4971 table = table && jQuery.nodeName( first, "tr" );
4973 for ( var i = 0, l = this.length; i < l; i++ ) {
4976 root(this[i], first) :
4978 i > 0 || results.cacheable || this.length > 1 ?
4979 fragment.cloneNode(true) :
4985 if ( scripts.length ) {
4986 jQuery.each( scripts, evalScript );
4994 function root( elem, cur ) {
4995 return jQuery.nodeName(elem, "table") ?
4996 (elem.getElementsByTagName("tbody")[0] ||
4997 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5001 function cloneCopyEvent(orig, ret) {
5004 ret.each(function() {
5005 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
5009 var oldData = jQuery.data( orig[i++] ),
5010 curData = jQuery.data( this, oldData ),
5011 events = oldData && oldData.events;
5014 delete curData.handle;
5015 curData.events = {};
5017 for ( var type in events ) {
5018 for ( var handler in events[ type ] ) {
5019 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
5026 jQuery.buildFragment = function( args, nodes, scripts ) {
5027 var fragment, cacheable, cacheresults,
5028 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
5030 // Only cache "small" (1/2 KB) strings that are associated with the main document
5031 // Cloning options loses the selected state, so don't cache them
5032 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
5033 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
5034 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
5035 !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
5038 cacheresults = jQuery.fragments[ args[0] ];
5039 if ( cacheresults ) {
5040 if ( cacheresults !== 1 ) {
5041 fragment = cacheresults;
5047 fragment = doc.createDocumentFragment();
5048 jQuery.clean( args, doc, fragment, scripts );
5052 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
5055 return { fragment: fragment, cacheable: cacheable };
5058 jQuery.fragments = {};
5062 prependTo: "prepend",
5063 insertBefore: "before",
5064 insertAfter: "after",
5065 replaceAll: "replaceWith"
5066 }, function( name, original ) {
5067 jQuery.fn[ name ] = function( selector ) {
5069 insert = jQuery( selector ),
5070 parent = this.length === 1 && this[0].parentNode;
5072 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
5073 insert[ original ]( this[0] );
5077 for ( var i = 0, l = insert.length; i < l; i++ ) {
5078 var elems = (i > 0 ? this.clone(true) : this).get();
5079 jQuery( insert[i] )[ original ]( elems );
5080 ret = ret.concat( elems );
5083 return this.pushStack( ret, name, insert.selector );
5089 clean: function( elems, context, fragment, scripts ) {
5090 context = context || document;
5092 // !context.createElement fails in IE with an error but returns typeof 'object'
5093 if ( typeof context.createElement === "undefined" ) {
5094 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
5099 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5100 if ( typeof elem === "number" ) {
5108 // Convert html string into DOM nodes
5109 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
5110 elem = context.createTextNode( elem );
5112 } else if ( typeof elem === "string" ) {
5113 // Fix "XHTML"-style tags in all browsers
5114 elem = elem.replace(rxhtmlTag, "<$1></$2>");
5116 // Trim whitespace, otherwise indexOf won't work as expected
5117 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
5118 wrap = wrapMap[ tag ] || wrapMap._default,
5120 div = context.createElement("div");
5122 // Go to html and back, then peel off extra wrappers
5123 div.innerHTML = wrap[1] + elem + wrap[2];
5125 // Move to the right depth
5127 div = div.lastChild;
5130 // Remove IE's autoinserted <tbody> from table fragments
5131 if ( !jQuery.support.tbody ) {
5133 // String was a <table>, *may* have spurious <tbody>
5134 var hasBody = rtbody.test(elem),
5135 tbody = tag === "table" && !hasBody ?
5136 div.firstChild && div.firstChild.childNodes :
5138 // String was a bare <thead> or <tfoot>
5139 wrap[1] === "<table>" && !hasBody ?
5143 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
5144 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
5145 tbody[ j ].parentNode.removeChild( tbody[ j ] );
5151 // IE completely kills leading whitespace when innerHTML is used
5152 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
5153 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
5156 elem = div.childNodes;
5159 if ( elem.nodeType ) {
5162 ret = jQuery.merge( ret, elem );
5167 for ( i = 0; ret[i]; i++ ) {
5168 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
5169 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
5172 if ( ret[i].nodeType === 1 ) {
5173 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
5175 fragment.appendChild( ret[i] );
5183 cleanData: function( elems ) {
5184 var data, id, cache = jQuery.cache,
5185 special = jQuery.event.special,
5186 deleteExpando = jQuery.support.deleteExpando;
5188 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
5189 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
5193 id = elem[ jQuery.expando ];
5198 if ( data && data.events ) {
5199 for ( var type in data.events ) {
5200 if ( special[ type ] ) {
5201 jQuery.event.remove( elem, type );
5204 jQuery.removeEvent( elem, type, data.handle );
5209 if ( deleteExpando ) {
5210 delete elem[ jQuery.expando ];
5212 } else if ( elem.removeAttribute ) {
5213 elem.removeAttribute( jQuery.expando );
5222 function evalScript( i, elem ) {
5230 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
5233 if ( elem.parentNode ) {
5234 elem.parentNode.removeChild( elem );
5241 var ralpha = /alpha\([^)]*\)/i,
5242 ropacity = /opacity=([^)]*)/,
5243 rdashAlpha = /-([a-z])/ig,
5244 rupper = /([A-Z])/g,
5245 rnumpx = /^-?\d+(?:px)?$/i,
5248 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5249 cssWidth = [ "Left", "Right" ],
5250 cssHeight = [ "Top", "Bottom" ],
5256 fcamelCase = function( all, letter ) {
5257 return letter.toUpperCase();
5260 jQuery.fn.css = function( name, value ) {
5261 // Setting 'undefined' is a no-op
5262 if ( arguments.length === 2 && value === undefined ) {
5266 return jQuery.access( this, name, value, true, function( elem, name, value ) {
5267 return value !== undefined ?
5268 jQuery.style( elem, name, value ) :
5269 jQuery.css( elem, name );
5274 // Add in style property hooks for overriding the default
5275 // behavior of getting and setting a style property
5278 get: function( elem, computed ) {
5280 // We should always get a number back from opacity
5281 var ret = curCSS( elem, "opacity", "opacity" );
5282 return ret === "" ? "1" : ret;
5285 return elem.style.opacity;
5291 // Exclude the following css properties to add px
5300 // Add in properties whose names you wish to fix before
5301 // setting or getting the value
5303 // normalize float css property
5304 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5307 // Get and set the style property on a DOM Node
5308 style: function( elem, name, value, extra ) {
5309 // Don't set styles on text and comment nodes
5310 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5314 // Make sure that we're working with the right name
5315 var ret, origName = jQuery.camelCase( name ),
5316 style = elem.style, hooks = jQuery.cssHooks[ origName ];
5318 name = jQuery.cssProps[ origName ] || origName;
5320 // Check if we're setting a value
5321 if ( value !== undefined ) {
5322 // Make sure that NaN and null values aren't set. See: #7116
5323 if ( typeof value === "number" && isNaN( value ) || value == null ) {
5327 // If a number was passed in, add 'px' to the (except for certain CSS properties)
5328 if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5332 // If a hook was provided, use that value, otherwise just set the specified value
5333 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5334 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5337 style[ name ] = value;
5342 // If a hook was provided get the non-computed value from there
5343 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5347 // Otherwise just get the value from the style object
5348 return style[ name ];
5352 css: function( elem, name, extra ) {
5353 // Make sure that we're working with the right name
5354 var ret, origName = jQuery.camelCase( name ),
5355 hooks = jQuery.cssHooks[ origName ];
5357 name = jQuery.cssProps[ origName ] || origName;
5359 // If a hook was provided get the computed value from there
5360 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5363 // Otherwise, if a way to get the computed value exists, use that
5364 } else if ( curCSS ) {
5365 return curCSS( elem, name, origName );
5369 // A method for quickly swapping in/out CSS properties to get correct calculations
5370 swap: function( elem, options, callback ) {
5373 // Remember the old values, and insert the new ones
5374 for ( var name in options ) {
5375 old[ name ] = elem.style[ name ];
5376 elem.style[ name ] = options[ name ];
5379 callback.call( elem );
5381 // Revert the old values
5382 for ( name in options ) {
5383 elem.style[ name ] = old[ name ];
5387 camelCase: function( string ) {
5388 return string.replace( rdashAlpha, fcamelCase );
5392 // DEPRECATED, Use jQuery.css() instead
5393 jQuery.curCSS = jQuery.css;
5395 jQuery.each(["height", "width"], function( i, name ) {
5396 jQuery.cssHooks[ name ] = {
5397 get: function( elem, computed, extra ) {
5401 if ( elem.offsetWidth !== 0 ) {
5402 val = getWH( elem, name, extra );
5405 jQuery.swap( elem, cssShow, function() {
5406 val = getWH( elem, name, extra );
5411 val = curCSS( elem, name, name );
5413 if ( val === "0px" && currentStyle ) {
5414 val = currentStyle( elem, name, name );
5417 if ( val != null ) {
5418 // Should return "auto" instead of 0, use 0 for
5419 // temporary backwards-compat
5420 return val === "" || val === "auto" ? "0px" : val;
5424 if ( val < 0 || val == null ) {
5425 val = elem.style[ name ];
5427 // Should return "auto" instead of 0, use 0 for
5428 // temporary backwards-compat
5429 return val === "" || val === "auto" ? "0px" : val;
5432 return typeof val === "string" ? val : val + "px";
5436 set: function( elem, value ) {
5437 if ( rnumpx.test( value ) ) {
5438 // ignore negative width and height values #1599
5439 value = parseFloat(value);
5442 return value + "px";
5452 if ( !jQuery.support.opacity ) {
5453 jQuery.cssHooks.opacity = {
5454 get: function( elem, computed ) {
5455 // IE uses filters for opacity
5456 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5457 (parseFloat(RegExp.$1) / 100) + "" :
5458 computed ? "1" : "";
5461 set: function( elem, value ) {
5462 var style = elem.style;
5464 // IE has trouble with opacity if it does not have layout
5465 // Force it by setting the zoom level
5468 // Set the alpha filter to set the opacity
5469 var opacity = jQuery.isNaN(value) ?
5471 "alpha(opacity=" + value * 100 + ")",
5472 filter = style.filter || "";
5474 style.filter = ralpha.test(filter) ?
5475 filter.replace(ralpha, opacity) :
5476 style.filter + ' ' + opacity;
5481 if ( document.defaultView && document.defaultView.getComputedStyle ) {
5482 getComputedStyle = function( elem, newName, name ) {
5483 var ret, defaultView, computedStyle;
5485 name = name.replace( rupper, "-$1" ).toLowerCase();
5487 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5491 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5492 ret = computedStyle.getPropertyValue( name );
5493 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5494 ret = jQuery.style( elem, name );
5502 if ( document.documentElement.currentStyle ) {
5503 currentStyle = function( elem, name ) {
5505 ret = elem.currentStyle && elem.currentStyle[ name ],
5508 // From the awesome hack by Dean Edwards
5509 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5511 // If we're not dealing with a regular pixel number
5512 // but a number that has a weird ending, we need to convert it to pixels
5513 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5514 // Remember the original values
5516 rsLeft = elem.runtimeStyle.left;
5518 // Put in the new values to get a computed value out
5519 elem.runtimeStyle.left = elem.currentStyle.left;
5520 style.left = name === "fontSize" ? "1em" : (ret || 0);
5521 ret = style.pixelLeft + "px";
5523 // Revert the changed values
5525 elem.runtimeStyle.left = rsLeft;
5528 return ret === "" ? "auto" : ret;
5532 curCSS = getComputedStyle || currentStyle;
5534 function getWH( elem, name, extra ) {
5535 var which = name === "width" ? cssWidth : cssHeight,
5536 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5538 if ( extra === "border" ) {
5542 jQuery.each( which, function() {
5544 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5547 if ( extra === "margin" ) {
5548 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5551 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5558 if ( jQuery.expr && jQuery.expr.filters ) {
5559 jQuery.expr.filters.hidden = function( elem ) {
5560 var width = elem.offsetWidth,
5561 height = elem.offsetHeight;
5563 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5566 jQuery.expr.filters.visible = function( elem ) {
5567 return !jQuery.expr.filters.hidden( elem );
5574 var jsc = jQuery.now(),
5575 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5576 rselectTextarea = /^(?:select|textarea)/i,
5577 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5578 rnoContent = /^(?:GET|HEAD)$/,
5582 rts = /([?&])_=[^&]*/,
5583 rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5587 // Keep a copy of the old load method
5588 _load = jQuery.fn.load;
5591 load: function( url, params, callback ) {
5592 if ( typeof url !== "string" && _load ) {
5593 return _load.apply( this, arguments );
5595 // Don't do a request if no elements are being requested
5596 } else if ( !this.length ) {
5600 var off = url.indexOf(" ");
5602 var selector = url.slice(off, url.length);
5603 url = url.slice(0, off);
5606 // Default to a GET request
5609 // If the second parameter was provided
5611 // If it's a function
5612 if ( jQuery.isFunction( params ) ) {
5613 // We assume that it's the callback
5617 // Otherwise, build a param string
5618 } else if ( typeof params === "object" ) {
5619 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5626 // Request the remote document
5632 complete: function( res, status ) {
5633 // If successful, inject the HTML into all the matched elements
5634 if ( status === "success" || status === "notmodified" ) {
5635 // See if a selector was specified
5636 self.html( selector ?
5637 // Create a dummy div to hold the results
5639 // inject the contents of the document in, removing the scripts
5640 // to avoid any 'Permission Denied' errors in IE
5641 .append(res.responseText.replace(rscript, ""))
5643 // Locate the specified elements
5646 // If not, just inject the full result
5651 self.each( callback, [res.responseText, status, res] );
5659 serialize: function() {
5660 return jQuery.param(this.serializeArray());
5663 serializeArray: function() {
5664 return this.map(function() {
5665 return this.elements ? jQuery.makeArray(this.elements) : this;
5667 .filter(function() {
5668 return this.name && !this.disabled &&
5669 (this.checked || rselectTextarea.test(this.nodeName) ||
5670 rinput.test(this.type));
5672 .map(function( i, elem ) {
5673 var val = jQuery(this).val();
5675 return val == null ?
5677 jQuery.isArray(val) ?
5678 jQuery.map( val, function( val, i ) {
5679 return { name: elem.name, value: val };
5681 { name: elem.name, value: val };
5686 // Attach a bunch of functions for handling common AJAX events
5687 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5688 jQuery.fn[o] = function( f ) {
5689 return this.bind(o, f);
5694 get: function( url, data, callback, type ) {
5695 // shift arguments if data argument was omited
5696 if ( jQuery.isFunction( data ) ) {
5697 type = type || callback;
5702 return jQuery.ajax({
5711 getScript: function( url, callback ) {
5712 return jQuery.get(url, null, callback, "script");
5715 getJSON: function( url, data, callback ) {
5716 return jQuery.get(url, data, callback, "json");
5719 post: function( url, data, callback, type ) {
5720 // shift arguments if data argument was omited
5721 if ( jQuery.isFunction( data ) ) {
5722 type = type || callback;
5727 return jQuery.ajax({
5736 ajaxSetup: function( settings ) {
5737 jQuery.extend( jQuery.ajaxSettings, settings );
5744 contentType: "application/x-www-form-urlencoded",
5754 // This function can be overriden by calling jQuery.ajaxSetup
5756 return new window.XMLHttpRequest();
5759 xml: "application/xml, text/xml",
5761 script: "text/javascript, application/javascript",
5762 json: "application/json, text/javascript",
5768 ajax: function( origSettings ) {
5769 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5770 jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
5772 s.url = s.url.replace( rhash, "" );
5774 // Use original (not extended) context object if it was provided
5775 s.context = origSettings && origSettings.context != null ? origSettings.context : s;
5777 // convert data if not already a string
5778 if ( s.data && s.processData && typeof s.data !== "string" ) {
5779 s.data = jQuery.param( s.data, s.traditional );
5782 // Handle JSONP Parameter Callbacks
5783 if ( s.dataType === "jsonp" ) {
5784 if ( type === "GET" ) {
5785 if ( !jsre.test( s.url ) ) {
5786 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5788 } else if ( !s.data || !jsre.test(s.data) ) {
5789 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
5791 s.dataType = "json";
5794 // Build temporary JSONP function
5795 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5796 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
5798 // Replace the =? sequence both in the query string and the data
5800 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
5803 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
5805 // We need to make sure
5806 // that a JSONP style response is executed properly
5807 s.dataType = "script";
5809 // Handle JSONP-style loading
5810 var customJsonp = window[ jsonp ];
5812 window[ jsonp ] = function( tmp ) {
5813 if ( jQuery.isFunction( customJsonp ) ) {
5818 window[ jsonp ] = undefined;
5821 delete window[ jsonp ];
5822 } catch( jsonpError ) {}
5826 jQuery.handleSuccess( s, xhr, status, data );
5827 jQuery.handleComplete( s, xhr, status, data );
5830 head.removeChild( script );
5835 if ( s.dataType === "script" && s.cache === null ) {
5839 if ( s.cache === false && noContent ) {
5840 var ts = jQuery.now();
5842 // try replacing _= if it is there
5843 var ret = s.url.replace(rts, "$1_=" + ts);
5845 // if nothing was replaced, add timestamp to the end
5846 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5849 // If data is available, append data to url for GET/HEAD requests
5850 if ( s.data && noContent ) {
5851 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5854 // Watch for a new set of requests
5855 if ( s.global && jQuery.active++ === 0 ) {
5856 jQuery.event.trigger( "ajaxStart" );
5859 // Matches an absolute URL, and saves the domain
5860 var parts = rurl.exec( s.url ),
5861 remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
5863 // If we're requesting a remote document
5864 // and trying to load JSON or Script with a GET
5865 if ( s.dataType === "script" && type === "GET" && remote ) {
5866 var head = document.getElementsByTagName("head")[0] || document.documentElement;
5867 var script = document.createElement("script");
5868 if ( s.scriptCharset ) {
5869 script.charset = s.scriptCharset;
5873 // Handle Script loading
5877 // Attach handlers for all browsers
5878 script.onload = script.onreadystatechange = function() {
5879 if ( !done && (!this.readyState ||
5880 this.readyState === "loaded" || this.readyState === "complete") ) {
5882 jQuery.handleSuccess( s, xhr, status, data );
5883 jQuery.handleComplete( s, xhr, status, data );
5885 // Handle memory leak in IE
5886 script.onload = script.onreadystatechange = null;
5887 if ( head && script.parentNode ) {
5888 head.removeChild( script );
5894 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
5895 // This arises when a base node is used (#2709 and #4378).
5896 head.insertBefore( script, head.firstChild );
5898 // We handle everything using the script element injection
5902 var requestDone = false;
5904 // Create the request object
5912 // Passing null username, generates a login popup on Opera (#2865)
5914 xhr.open(type, s.url, s.async, s.username, s.password);
5916 xhr.open(type, s.url, s.async);
5919 // Need an extra try/catch for cross domain requests in Firefox 3
5921 // Set content-type if data specified and content-body is valid for this type
5922 if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5923 xhr.setRequestHeader("Content-Type", s.contentType);
5926 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5927 if ( s.ifModified ) {
5928 if ( jQuery.lastModified[s.url] ) {
5929 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5932 if ( jQuery.etag[s.url] ) {
5933 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5937 // Set header so the called script knows that it's an XMLHttpRequest
5938 // Only send the header if it's not a remote XHR
5940 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5943 // Set the Accepts header for the server, depending on the dataType
5944 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5945 s.accepts[ s.dataType ] + ", */*; q=0.01" :
5946 s.accepts._default );
5947 } catch( headerError ) {}
5949 // Allow custom headers/mimetypes and early abort
5950 if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5951 // Handle the global AJAX counter
5952 if ( s.global && jQuery.active-- === 1 ) {
5953 jQuery.event.trigger( "ajaxStop" );
5956 // close opended socket
5962 jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
5965 // Wait for a response to come back
5966 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5967 // The request was aborted
5968 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5969 // Opera doesn't call onreadystatechange before this point
5970 // so we simulate the call
5971 if ( !requestDone ) {
5972 jQuery.handleComplete( s, xhr, status, data );
5977 xhr.onreadystatechange = jQuery.noop;
5980 // The transfer is complete and the data is available, or the request timed out
5981 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5983 xhr.onreadystatechange = jQuery.noop;
5985 status = isTimeout === "timeout" ?
5987 !jQuery.httpSuccess( xhr ) ?
5989 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5995 if ( status === "success" ) {
5996 // Watch for, and catch, XML document parse errors
5998 // process the data (runs the xml through httpData regardless of callback)
5999 data = jQuery.httpData( xhr, s.dataType, s );
6000 } catch( parserError ) {
6001 status = "parsererror";
6002 errMsg = parserError;
6006 // Make sure that the request was successful or notmodified
6007 if ( status === "success" || status === "notmodified" ) {
6008 // JSONP handles its own success callback
6010 jQuery.handleSuccess( s, xhr, status, data );
6013 jQuery.handleError( s, xhr, status, errMsg );
6016 // Fire the complete handlers
6018 jQuery.handleComplete( s, xhr, status, data );
6021 if ( isTimeout === "timeout" ) {
6025 // Stop memory leaks
6032 // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
6033 // Opera doesn't fire onreadystatechange at all on abort
6035 var oldAbort = xhr.abort;
6036 xhr.abort = function() {
6038 // oldAbort has no call property in IE7 so
6039 // just do it this way, which works in all
6041 Function.prototype.call.call( oldAbort, xhr );
6044 onreadystatechange( "abort" );
6046 } catch( abortError ) {}
6049 if ( s.async && s.timeout > 0 ) {
6050 setTimeout(function() {
6051 // Check to see if the request is still happening
6052 if ( xhr && !requestDone ) {
6053 onreadystatechange( "timeout" );
6060 xhr.send( noContent || s.data == null ? null : s.data );
6062 } catch( sendError ) {
6063 jQuery.handleError( s, xhr, null, sendError );
6065 // Fire the complete handlers
6066 jQuery.handleComplete( s, xhr, status, data );
6069 // firefox 1.5 doesn't fire statechange for sync requests
6071 onreadystatechange();
6074 // return XMLHttpRequest to allow aborting the request etc.
6078 // Serialize an array of form elements or a set of
6079 // key/values into a query string
6080 param: function( a, traditional ) {
6082 add = function( key, value ) {
6083 // If value is a function, invoke it and return its value
6084 value = jQuery.isFunction(value) ? value() : value;
6085 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
6088 // Set traditional to true for jQuery <= 1.3.2 behavior.
6089 if ( traditional === undefined ) {
6090 traditional = jQuery.ajaxSettings.traditional;
6093 // If an array was passed in, assume that it is an array of form elements.
6094 if ( jQuery.isArray(a) || a.jquery ) {
6095 // Serialize the form elements
6096 jQuery.each( a, function() {
6097 add( this.name, this.value );
6101 // If traditional, encode the "old" way (the way 1.3.2 or older
6102 // did it), otherwise encode params recursively.
6103 for ( var prefix in a ) {
6104 buildParams( prefix, a[prefix], traditional, add );
6108 // Return the resulting serialization
6109 return s.join("&").replace(r20, "+");
6113 function buildParams( prefix, obj, traditional, add ) {
6114 if ( jQuery.isArray(obj) && obj.length ) {
6115 // Serialize array item.
6116 jQuery.each( obj, function( i, v ) {
6117 if ( traditional || rbracket.test( prefix ) ) {
6118 // Treat each array item as a scalar.
6122 // If array item is non-scalar (array or object), encode its
6123 // numeric index to resolve deserialization ambiguity issues.
6124 // Note that rack (as of 1.0.0) can't currently deserialize
6125 // nested arrays properly, and attempting to do so may cause
6126 // a server error. Possible fixes are to modify rack's
6127 // deserialization algorithm or to provide an option or flag
6128 // to force array serialization to be shallow.
6129 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
6133 } else if ( !traditional && obj != null && typeof obj === "object" ) {
6134 if ( jQuery.isEmptyObject( obj ) ) {
6137 // Serialize object item.
6139 jQuery.each( obj, function( k, v ) {
6140 buildParams( prefix + "[" + k + "]", v, traditional, add );
6145 // Serialize scalar item.
6150 // This is still on the jQuery object... for now
6151 // Want to move this to jQuery.ajax some day
6154 // Counter for holding the number of active queries
6157 // Last-Modified header cache for next request
6161 handleError: function( s, xhr, status, e ) {
6162 // If a local callback was specified, fire it
6164 s.error.call( s.context, xhr, status, e );
6167 // Fire the global callback
6169 jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
6173 handleSuccess: function( s, xhr, status, data ) {
6174 // If a local callback was specified, fire it and pass it the data
6176 s.success.call( s.context, data, status, xhr );
6179 // Fire the global callback
6181 jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
6185 handleComplete: function( s, xhr, status ) {
6188 s.complete.call( s.context, xhr, status );
6191 // The request was completed
6193 jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
6196 // Handle the global AJAX counter
6197 if ( s.global && jQuery.active-- === 1 ) {
6198 jQuery.event.trigger( "ajaxStop" );
6202 triggerGlobal: function( s, type, args ) {
6203 (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
6206 // Determines if an XMLHttpRequest was successful or not
6207 httpSuccess: function( xhr ) {
6209 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
6210 return !xhr.status && location.protocol === "file:" ||
6211 xhr.status >= 200 && xhr.status < 300 ||
6212 xhr.status === 304 || xhr.status === 1223;
6218 // Determines if an XMLHttpRequest returns NotModified
6219 httpNotModified: function( xhr, url ) {
6220 var lastModified = xhr.getResponseHeader("Last-Modified"),
6221 etag = xhr.getResponseHeader("Etag");
6223 if ( lastModified ) {
6224 jQuery.lastModified[url] = lastModified;
6228 jQuery.etag[url] = etag;
6231 return xhr.status === 304;
6234 httpData: function( xhr, type, s ) {
6235 var ct = xhr.getResponseHeader("content-type") || "",
6236 xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
6237 data = xml ? xhr.responseXML : xhr.responseText;
6239 if ( xml && data.documentElement.nodeName === "parsererror" ) {
6240 jQuery.error( "parsererror" );
6243 // Allow a pre-filtering function to sanitize the response
6244 // s is checked to keep backwards compatibility
6245 if ( s && s.dataFilter ) {
6246 data = s.dataFilter( data, type );
6249 // The filter can actually parse the response
6250 if ( typeof data === "string" ) {
6251 // Get the JavaScript object, if JSON is used.
6252 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
6253 data = jQuery.parseJSON( data );
6255 // If the type is "script", eval it in global context
6256 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
6257 jQuery.globalEval( data );
6267 * Create the request object; Microsoft failed to properly
6268 * implement the XMLHttpRequest in IE7 (can't request local files),
6269 * so we use the ActiveXObject when it is available
6270 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
6271 * we need a fallback.
6273 if ( window.ActiveXObject ) {
6274 jQuery.ajaxSettings.xhr = function() {
6275 if ( window.location.protocol !== "file:" ) {
6277 return new window.XMLHttpRequest();
6278 } catch(xhrError) {}
6282 return new window.ActiveXObject("Microsoft.XMLHTTP");
6283 } catch(activeError) {}
6287 // Does this browser support XHR requests?
6288 jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
6293 var elemdisplay = {},
6294 rfxtypes = /^(?:toggle|show|hide)$/,
6295 rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
6298 // height animations
6299 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
6301 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
6302 // opacity animations
6307 show: function( speed, easing, callback ) {
6310 if ( speed || speed === 0 ) {
6311 return this.animate( genFx("show", 3), speed, easing, callback);
6314 for ( var i = 0, j = this.length; i < j; i++ ) {
6316 display = elem.style.display;
6318 // Reset the inline display of this element to learn if it is
6319 // being hidden by cascaded rules or not
6320 if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
6321 display = elem.style.display = "";
6324 // Set elements which have been overridden with display: none
6325 // in a stylesheet to whatever the default browser style is
6326 // for such an element
6327 if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
6328 jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
6332 // Set the display of most of the elements in a second loop
6333 // to avoid the constant reflow
6334 for ( i = 0; i < j; i++ ) {
6336 display = elem.style.display;
6338 if ( display === "" || display === "none" ) {
6339 elem.style.display = jQuery.data(elem, "olddisplay") || "";
6347 hide: function( speed, easing, callback ) {
6348 if ( speed || speed === 0 ) {
6349 return this.animate( genFx("hide", 3), speed, easing, callback);
6352 for ( var i = 0, j = this.length; i < j; i++ ) {
6353 var display = jQuery.css( this[i], "display" );
6355 if ( display !== "none" ) {
6356 jQuery.data( this[i], "olddisplay", display );
6360 // Set the display of the elements in a second loop
6361 // to avoid the constant reflow
6362 for ( i = 0; i < j; i++ ) {
6363 this[i].style.display = "none";
6370 // Save the old toggle function
6371 _toggle: jQuery.fn.toggle,
6373 toggle: function( fn, fn2, callback ) {
6374 var bool = typeof fn === "boolean";
6376 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
6377 this._toggle.apply( this, arguments );
6379 } else if ( fn == null || bool ) {
6380 this.each(function() {
6381 var state = bool ? fn : jQuery(this).is(":hidden");
6382 jQuery(this)[ state ? "show" : "hide" ]();
6386 this.animate(genFx("toggle", 3), fn, fn2, callback);
6392 fadeTo: function( speed, to, easing, callback ) {
6393 return this.filter(":hidden").css("opacity", 0).show().end()
6394 .animate({opacity: to}, speed, easing, callback);
6397 animate: function( prop, speed, easing, callback ) {
6398 var optall = jQuery.speed(speed, easing, callback);
6400 if ( jQuery.isEmptyObject( prop ) ) {
6401 return this.each( optall.complete );
6404 return this[ optall.queue === false ? "each" : "queue" ](function() {
6405 // XXX 'this' does not always have a nodeName when running the
6408 var opt = jQuery.extend({}, optall), p,
6409 isElement = this.nodeType === 1,
6410 hidden = isElement && jQuery(this).is(":hidden"),
6414 var name = jQuery.camelCase( p );
6417 prop[ name ] = prop[ p ];
6422 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
6423 return opt.complete.call(this);
6426 if ( isElement && ( p === "height" || p === "width" ) ) {
6427 // Make sure that nothing sneaks out
6428 // Record all 3 overflow attributes because IE does not
6429 // change the overflow attribute when overflowX and
6430 // overflowY are set to the same value
6431 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
6433 // Set display property to inline-block for height/width
6434 // animations on inline elements that are having width/height
6436 if ( jQuery.css( this, "display" ) === "inline" &&
6437 jQuery.css( this, "float" ) === "none" ) {
6438 if ( !jQuery.support.inlineBlockNeedsLayout ) {
6439 this.style.display = "inline-block";
6442 var display = defaultDisplay(this.nodeName);
6444 // inline-level elements accept inline-block;
6445 // block-level elements need to be inline with layout
6446 if ( display === "inline" ) {
6447 this.style.display = "inline-block";
6450 this.style.display = "inline";
6451 this.style.zoom = 1;
6457 if ( jQuery.isArray( prop[p] ) ) {
6458 // Create (if needed) and add to specialEasing
6459 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
6460 prop[p] = prop[p][0];
6464 if ( opt.overflow != null ) {
6465 this.style.overflow = "hidden";
6468 opt.curAnim = jQuery.extend({}, prop);
6470 jQuery.each( prop, function( name, val ) {
6471 var e = new jQuery.fx( self, opt, name );
6473 if ( rfxtypes.test(val) ) {
6474 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
6477 var parts = rfxnum.exec(val),
6478 start = e.cur() || 0;
6481 var end = parseFloat( parts[2] ),
6482 unit = parts[3] || "px";
6484 // We need to compute starting value
6485 if ( unit !== "px" ) {
6486 jQuery.style( self, name, (end || 1) + unit);
6487 start = ((end || 1) / e.cur()) * start;
6488 jQuery.style( self, name, start + unit);
6491 // If a +=/-= token was provided, we're doing a relative animation
6493 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
6496 e.custom( start, end, unit );
6499 e.custom( start, val, "" );
6504 // For JS strict compliance
6509 stop: function( clearQueue, gotoEnd ) {
6510 var timers = jQuery.timers;
6516 this.each(function() {
6517 // go in reverse order so anything added to the queue during the loop is ignored
6518 for ( var i = timers.length - 1; i >= 0; i-- ) {
6519 if ( timers[i].elem === this ) {
6521 // force the next step to be the last
6525 timers.splice(i, 1);
6530 // start the next in the queue if the last step wasn't forced
6540 function genFx( type, num ) {
6543 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
6550 // Generate shortcuts for custom animations
6552 slideDown: genFx("show", 1),
6553 slideUp: genFx("hide", 1),
6554 slideToggle: genFx("toggle", 1),
6555 fadeIn: { opacity: "show" },
6556 fadeOut: { opacity: "hide" },
6557 fadeToggle: { opacity: "toggle" }
6558 }, function( name, props ) {
6559 jQuery.fn[ name ] = function( speed, easing, callback ) {
6560 return this.animate( props, speed, easing, callback );
6565 speed: function( speed, easing, fn ) {
6566 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
6567 complete: fn || !fn && easing ||
6568 jQuery.isFunction( speed ) && speed,
6570 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
6573 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6574 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
6577 opt.old = opt.complete;
6578 opt.complete = function() {
6579 if ( opt.queue !== false ) {
6580 jQuery(this).dequeue();
6582 if ( jQuery.isFunction( opt.old ) ) {
6583 opt.old.call( this );
6591 linear: function( p, n, firstNum, diff ) {
6592 return firstNum + diff * p;
6594 swing: function( p, n, firstNum, diff ) {
6595 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
6601 fx: function( elem, options, prop ) {
6602 this.options = options;
6606 if ( !options.orig ) {
6613 jQuery.fx.prototype = {
6614 // Simple function for setting a style value
6615 update: function() {
6616 if ( this.options.step ) {
6617 this.options.step.call( this.elem, this.now, this );
6620 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
6623 // Get the current size
6625 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
6626 return this.elem[ this.prop ];
6629 var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6630 return r && r > -10000 ? r : 0;
6633 // Start an animation from one number to another
6634 custom: function( from, to, unit ) {
6638 this.startTime = jQuery.now();
6641 this.unit = unit || this.unit || "px";
6642 this.now = this.start;
6643 this.pos = this.state = 0;
6645 function t( gotoEnd ) {
6646 return self.step(gotoEnd);
6651 if ( t() && jQuery.timers.push(t) && !timerId ) {
6652 timerId = setInterval(fx.tick, fx.interval);
6656 // Simple 'show' function
6658 // Remember where we started, so that we can go back to it later
6659 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6660 this.options.show = true;
6662 // Begin the animation
6663 // Make sure that we start at a small width/height to avoid any
6665 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
6667 // Start by showing the element
6668 jQuery( this.elem ).show();
6671 // Simple 'hide' function
6673 // Remember where we started, so that we can go back to it later
6674 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6675 this.options.hide = true;
6677 // Begin the animation
6678 this.custom(this.cur(), 0);
6681 // Each step of an animation
6682 step: function( gotoEnd ) {
6683 var t = jQuery.now(), done = true;
6685 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
6686 this.now = this.end;
6687 this.pos = this.state = 1;
6690 this.options.curAnim[ this.prop ] = true;
6692 for ( var i in this.options.curAnim ) {
6693 if ( this.options.curAnim[i] !== true ) {
6699 // Reset the overflow
6700 if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
6701 var elem = this.elem,
6702 options = this.options;
6704 jQuery.each( [ "", "X", "Y" ], function (index, value) {
6705 elem.style[ "overflow" + value ] = options.overflow[index];
6709 // Hide the element if the "hide" operation was done
6710 if ( this.options.hide ) {
6711 jQuery(this.elem).hide();
6714 // Reset the properties, if the item has been hidden or shown
6715 if ( this.options.hide || this.options.show ) {
6716 for ( var p in this.options.curAnim ) {
6717 jQuery.style( this.elem, p, this.options.orig[p] );
6721 // Execute the complete function
6722 this.options.complete.call( this.elem );
6728 var n = t - this.startTime;
6729 this.state = n / this.options.duration;
6731 // Perform the easing function, defaults to swing
6732 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
6733 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
6734 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
6735 this.now = this.start + ((this.end - this.start) * this.pos);
6737 // Perform the next step of the animation
6745 jQuery.extend( jQuery.fx, {
6747 var timers = jQuery.timers;
6749 for ( var i = 0; i < timers.length; i++ ) {
6750 if ( !timers[i]() ) {
6751 timers.splice(i--, 1);
6755 if ( !timers.length ) {
6763 clearInterval( timerId );
6775 opacity: function( fx ) {
6776 jQuery.style( fx.elem, "opacity", fx.now );
6779 _default: function( fx ) {
6780 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
6781 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
6783 fx.elem[ fx.prop ] = fx.now;
6789 if ( jQuery.expr && jQuery.expr.filters ) {
6790 jQuery.expr.filters.animated = function( elem ) {
6791 return jQuery.grep(jQuery.timers, function( fn ) {
6792 return elem === fn.elem;
6797 function defaultDisplay( nodeName ) {
6798 if ( !elemdisplay[ nodeName ] ) {
6799 var elem = jQuery("<" + nodeName + ">").appendTo("body"),
6800 display = elem.css("display");
6804 if ( display === "none" || display === "" ) {
6808 elemdisplay[ nodeName ] = display;
6811 return elemdisplay[ nodeName ];
6817 var rtable = /^t(?:able|d|h)$/i,
6818 rroot = /^(?:body|html)$/i;
6820 if ( "getBoundingClientRect" in document.documentElement ) {
6821 jQuery.fn.offset = function( options ) {
6822 var elem = this[0], box;
6825 return this.each(function( i ) {
6826 jQuery.offset.setOffset( this, options, i );
6830 if ( !elem || !elem.ownerDocument ) {
6834 if ( elem === elem.ownerDocument.body ) {
6835 return jQuery.offset.bodyOffset( elem );
6839 box = elem.getBoundingClientRect();
6842 var doc = elem.ownerDocument,
6843 docElem = doc.documentElement;
6845 // Make sure we're not dealing with a disconnected DOM node
6846 if ( !box || !jQuery.contains( docElem, elem ) ) {
6847 return box || { top: 0, left: 0 };
6850 var body = doc.body,
6851 win = getWindow(doc),
6852 clientTop = docElem.clientTop || body.clientTop || 0,
6853 clientLeft = docElem.clientLeft || body.clientLeft || 0,
6854 scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
6855 scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
6856 top = box.top + scrollTop - clientTop,
6857 left = box.left + scrollLeft - clientLeft;
6859 return { top: top, left: left };
6863 jQuery.fn.offset = function( options ) {
6867 return this.each(function( i ) {
6868 jQuery.offset.setOffset( this, options, i );
6872 if ( !elem || !elem.ownerDocument ) {
6876 if ( elem === elem.ownerDocument.body ) {
6877 return jQuery.offset.bodyOffset( elem );
6880 jQuery.offset.initialize();
6883 offsetParent = elem.offsetParent,
6884 prevOffsetParent = elem,
6885 doc = elem.ownerDocument,
6886 docElem = doc.documentElement,
6888 defaultView = doc.defaultView,
6889 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
6890 top = elem.offsetTop,
6891 left = elem.offsetLeft;
6893 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
6894 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6898 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
6899 top -= elem.scrollTop;
6900 left -= elem.scrollLeft;
6902 if ( elem === offsetParent ) {
6903 top += elem.offsetTop;
6904 left += elem.offsetLeft;
6906 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
6907 top += parseFloat( computedStyle.borderTopWidth ) || 0;
6908 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6911 prevOffsetParent = offsetParent;
6912 offsetParent = elem.offsetParent;
6915 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
6916 top += parseFloat( computedStyle.borderTopWidth ) || 0;
6917 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6920 prevComputedStyle = computedStyle;
6923 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
6924 top += body.offsetTop;
6925 left += body.offsetLeft;
6928 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6929 top += Math.max( docElem.scrollTop, body.scrollTop );
6930 left += Math.max( docElem.scrollLeft, body.scrollLeft );
6933 return { top: top, left: left };
6938 initialize: function() {
6939 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
6940 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>";
6942 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
6944 container.innerHTML = html;
6945 body.insertBefore( container, body.firstChild );
6946 innerDiv = container.firstChild;
6947 checkDiv = innerDiv.firstChild;
6948 td = innerDiv.nextSibling.firstChild.firstChild;
6950 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
6951 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
6953 checkDiv.style.position = "fixed";
6954 checkDiv.style.top = "20px";
6956 // safari subtracts parent border width here which is 5px
6957 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
6958 checkDiv.style.position = checkDiv.style.top = "";
6960 innerDiv.style.overflow = "hidden";
6961 innerDiv.style.position = "relative";
6963 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
6965 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
6967 body.removeChild( container );
6968 body = container = innerDiv = checkDiv = table = td = null;
6969 jQuery.offset.initialize = jQuery.noop;
6972 bodyOffset: function( body ) {
6973 var top = body.offsetTop,
6974 left = body.offsetLeft;
6976 jQuery.offset.initialize();
6978 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
6979 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
6980 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
6983 return { top: top, left: left };
6986 setOffset: function( elem, options, i ) {
6987 var position = jQuery.css( elem, "position" );
6989 // set position first, in-case top/left are set even on static elem
6990 if ( position === "static" ) {
6991 elem.style.position = "relative";
6994 var curElem = jQuery( elem ),
6995 curOffset = curElem.offset(),
6996 curCSSTop = jQuery.css( elem, "top" ),
6997 curCSSLeft = jQuery.css( elem, "left" ),
6998 calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
6999 props = {}, curPosition = {}, curTop, curLeft;
7001 // need to be able to calculate position if either top or left is auto and position is absolute
7002 if ( calculatePosition ) {
7003 curPosition = curElem.position();
7006 curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0;
7007 curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
7009 if ( jQuery.isFunction( options ) ) {
7010 options = options.call( elem, i, curOffset );
7013 if (options.top != null) {
7014 props.top = (options.top - curOffset.top) + curTop;
7016 if (options.left != null) {
7017 props.left = (options.left - curOffset.left) + curLeft;
7020 if ( "using" in options ) {
7021 options.using.call( elem, props );
7023 curElem.css( props );
7030 position: function() {
7037 // Get *real* offsetParent
7038 offsetParent = this.offsetParent(),
7040 // Get correct offsets
7041 offset = this.offset(),
7042 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
7044 // Subtract element margins
7045 // note: when an element has margin: auto the offsetLeft and marginLeft
7046 // are the same in Safari causing offset.left to incorrectly be 0
7047 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
7048 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
7050 // Add offsetParent borders
7051 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
7052 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
7054 // Subtract the two offsets
7056 top: offset.top - parentOffset.top,
7057 left: offset.left - parentOffset.left
7061 offsetParent: function() {
7062 return this.map(function() {
7063 var offsetParent = this.offsetParent || document.body;
7064 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
7065 offsetParent = offsetParent.offsetParent;
7067 return offsetParent;
7073 // Create scrollLeft and scrollTop methods
7074 jQuery.each( ["Left", "Top"], function( i, name ) {
7075 var method = "scroll" + name;
7077 jQuery.fn[ method ] = function(val) {
7078 var elem = this[0], win;
7084 if ( val !== undefined ) {
7085 // Set the scroll offset
7086 return this.each(function() {
7087 win = getWindow( this );
7091 !i ? val : jQuery(win).scrollLeft(),
7092 i ? val : jQuery(win).scrollTop()
7096 this[ method ] = val;
7100 win = getWindow( elem );
7102 // Return the scroll offset
7103 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
7104 jQuery.support.boxModel && win.document.documentElement[ method ] ||
7105 win.document.body[ method ] :
7111 function getWindow( elem ) {
7112 return jQuery.isWindow( elem ) ?
7114 elem.nodeType === 9 ?
7115 elem.defaultView || elem.parentWindow :
7122 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
7123 jQuery.each([ "Height", "Width" ], function( i, name ) {
7125 var type = name.toLowerCase();
7127 // innerHeight and innerWidth
7128 jQuery.fn["inner" + name] = function() {
7130 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
7134 // outerHeight and outerWidth
7135 jQuery.fn["outer" + name] = function( margin ) {
7137 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
7141 jQuery.fn[ type ] = function( size ) {
7142 // Get window width or height
7145 return size == null ? null : this;
7148 if ( jQuery.isFunction( size ) ) {
7149 return this.each(function( i ) {
7150 var self = jQuery( this );
7151 self[ type ]( size.call( this, i, self[ type ]() ) );
7155 if ( jQuery.isWindow( elem ) ) {
7156 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
7157 return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
7158 elem.document.body[ "client" + name ];
7160 // Get document width or height
7161 } else if ( elem.nodeType === 9 ) {
7162 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
7164 elem.documentElement["client" + name],
7165 elem.body["scroll" + name], elem.documentElement["scroll" + name],
7166 elem.body["offset" + name], elem.documentElement["offset" + name]
7169 // Get or set width or height on the element
7170 } else if ( size === undefined ) {
7171 var orig = jQuery.css( elem, type ),
7172 ret = parseFloat( orig );
7174 return jQuery.isNaN( ret ) ? orig : ret;
7176 // Set the width or height on the element (default to pixels if value is unitless)
7178 return this.css( type, typeof size === "string" ? size : size + "px" );