2 * jQuery JavaScript Library v1.4.3
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 Oct 14 23:10:06 2010 -0400
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 // copy reference to target object
334 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
336 // Handle a deep copy situation
337 if ( typeof target === "boolean" ) {
339 target = arguments[1] || {};
340 // skip the boolean and the target
344 // Handle case when target is a string or something (possible in deep copy)
345 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
349 // extend jQuery itself if only one argument is passed
350 if ( length === i ) {
355 for ( ; i < length; i++ ) {
356 // Only deal with non-null/undefined values
357 if ( (options = arguments[ i ]) != null ) {
358 // Extend the base object
359 for ( name in options ) {
360 src = target[ name ];
361 copy = options[ name ];
363 // Prevent never-ending loop
364 if ( target === copy ) {
368 // Recurse if we're merging plain objects or arrays
369 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
372 clone = src && jQuery.isArray(src) ? src : [];
375 clone = src && jQuery.isPlainObject(src) ? src : {};
378 // Never move original objects, clone them
379 target[ name ] = jQuery.extend( deep, clone, copy );
381 // Don't bring in undefined values
382 } else if ( copy !== undefined ) {
383 target[ name ] = copy;
389 // Return the modified object
394 noConflict: function( deep ) {
398 window.jQuery = _jQuery;
404 // Is the DOM ready to be used? Set to true once it occurs.
407 // A counter to track how many items to wait for before
408 // the ready event fires. See #6781
411 // Handle when the DOM is ready
412 ready: function( wait ) {
413 // A third-party is pushing the ready event forwards
414 if ( wait === true ) {
418 // Make sure that the DOM is not already loaded
419 if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
420 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
421 if ( !document.body ) {
422 return setTimeout( jQuery.ready, 1 );
425 // Remember that the DOM is ready
426 jQuery.isReady = true;
428 // If a normal DOM Ready event fired, decrement, and wait if need be
429 if ( wait !== true && --jQuery.readyWait > 0 ) {
433 // If there are functions bound, to execute
435 // Execute all of them
437 while ( (fn = readyList[ i++ ]) ) {
438 fn.call( document, jQuery );
441 // Reset the list of functions
445 // Trigger any bound ready events
446 if ( jQuery.fn.triggerHandler ) {
447 jQuery( document ).triggerHandler( "ready" );
452 bindReady: function() {
459 // Catch cases where $(document).ready() is called after the
460 // browser event has already occurred.
461 if ( document.readyState === "complete" ) {
462 // Handle it asynchronously to allow scripts the opportunity to delay ready
463 return setTimeout( jQuery.ready, 1 );
466 // Mozilla, Opera and webkit nightlies currently support this event
467 if ( document.addEventListener ) {
468 // Use the handy event callback
469 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
471 // A fallback to window.onload, that will always work
472 window.addEventListener( "load", jQuery.ready, false );
474 // If IE event model is used
475 } else if ( document.attachEvent ) {
476 // ensure firing before onload,
477 // maybe late but safe also for iframes
478 document.attachEvent("onreadystatechange", DOMContentLoaded);
480 // A fallback to window.onload, that will always work
481 window.attachEvent( "onload", jQuery.ready );
483 // If IE and not a frame
484 // continually check to see if the document is ready
485 var toplevel = false;
488 toplevel = window.frameElement == null;
491 if ( document.documentElement.doScroll && toplevel ) {
497 // See test/unit/core.js for details concerning isFunction.
498 // Since version 1.3, DOM methods and functions like alert
499 // aren't supported. They return false on IE (#2968).
500 isFunction: function( obj ) {
501 return jQuery.type(obj) === "function";
504 isArray: Array.isArray || function( obj ) {
505 return jQuery.type(obj) === "array";
508 // A crude way of determining if an object is a window
509 isWindow: function( obj ) {
510 return obj && typeof obj === "object" && "setInterval" in obj;
513 isNaN: function( obj ) {
514 return obj == null || !rdigit.test( obj ) || isNaN( obj );
517 type: function( obj ) {
520 class2type[ toString.call(obj) ] || "object";
523 isPlainObject: function( obj ) {
524 // Must be an Object.
525 // Because of IE, we also have to check the presence of the constructor property.
526 // Make sure that DOM nodes and window objects don't pass through, as well
527 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
531 // Not own constructor property must be Object
532 if ( obj.constructor &&
533 !hasOwn.call(obj, "constructor") &&
534 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
538 // Own properties are enumerated firstly, so to speed up,
539 // if last one is own, then all properties are own.
542 for ( key in obj ) {}
544 return key === undefined || hasOwn.call( obj, key );
547 isEmptyObject: function( obj ) {
548 for ( var name in obj ) {
554 error: function( msg ) {
558 parseJSON: function( data ) {
559 if ( typeof data !== "string" || !data ) {
563 // Make sure leading/trailing whitespace is removed (IE can't handle it)
564 data = jQuery.trim( data );
566 // Make sure the incoming data is actual JSON
567 // Logic borrowed from http://json.org/json2.js
568 if ( rvalidchars.test(data.replace(rvalidescape, "@")
569 .replace(rvalidtokens, "]")
570 .replace(rvalidbraces, "")) ) {
572 // Try to use the native JSON parser first
573 return window.JSON && window.JSON.parse ?
574 window.JSON.parse( data ) :
575 (new Function("return " + data))();
578 jQuery.error( "Invalid JSON: " + data );
584 // Evalulates a script in a global context
585 globalEval: function( data ) {
586 if ( data && rnotwhite.test(data) ) {
587 // Inspired by code by Andrea Giammarchi
588 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
589 var head = document.getElementsByTagName("head")[0] || document.documentElement,
590 script = document.createElement("script");
592 script.type = "text/javascript";
594 if ( jQuery.support.scriptEval ) {
595 script.appendChild( document.createTextNode( data ) );
600 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
601 // This arises when a base node is used (#2709).
602 head.insertBefore( script, head.firstChild );
603 head.removeChild( script );
607 nodeName: function( elem, name ) {
608 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
611 // args is for internal usage only
612 each: function( object, callback, args ) {
614 length = object.length,
615 isObj = length === undefined || jQuery.isFunction(object);
619 for ( name in object ) {
620 if ( callback.apply( object[ name ], args ) === false ) {
625 for ( ; i < length; ) {
626 if ( callback.apply( object[ i++ ], args ) === false ) {
632 // A special, fast, case for the most common use of each
635 for ( name in object ) {
636 if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
641 for ( var value = object[0];
642 i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
649 // Use native String.trim function wherever possible
652 return text == null ?
657 // Otherwise use our own trimming functionality
659 return text == null ?
661 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
664 // results is for internal usage only
665 makeArray: function( array, results ) {
666 var ret = results || [];
668 if ( array != null ) {
669 // The window, strings (and functions) also have 'length'
670 // The extra typeof function check is to prevent crashes
671 // in Safari 2 (See: #3039)
672 // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
673 var type = jQuery.type(array);
675 if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
676 push.call( ret, array );
678 jQuery.merge( ret, array );
685 inArray: function( elem, array ) {
686 if ( array.indexOf ) {
687 return array.indexOf( elem );
690 for ( var i = 0, length = array.length; i < length; i++ ) {
691 if ( array[ i ] === elem ) {
699 merge: function( first, second ) {
700 var i = first.length, j = 0;
702 if ( typeof second.length === "number" ) {
703 for ( var l = second.length; j < l; j++ ) {
704 first[ i++ ] = second[ j ];
708 while ( second[j] !== undefined ) {
709 first[ i++ ] = second[ j++ ];
718 grep: function( elems, callback, inv ) {
719 var ret = [], retVal;
722 // Go through the array, only saving the items
723 // that pass the validator function
724 for ( var i = 0, length = elems.length; i < length; i++ ) {
725 retVal = !!callback( elems[ i ], i );
726 if ( inv !== retVal ) {
727 ret.push( elems[ i ] );
734 // arg is for internal usage only
735 map: function( elems, callback, arg ) {
738 // Go through the array, translating each of the items to their
739 // new value (or values).
740 for ( var i = 0, length = elems.length; i < length; i++ ) {
741 value = callback( elems[ i ], i, arg );
743 if ( value != null ) {
744 ret[ ret.length ] = value;
748 return ret.concat.apply( [], ret );
751 // A global GUID counter for objects
754 proxy: function( fn, proxy, thisObject ) {
755 if ( arguments.length === 2 ) {
756 if ( typeof proxy === "string" ) {
758 fn = thisObject[ proxy ];
761 } else if ( proxy && !jQuery.isFunction( proxy ) ) {
767 if ( !proxy && fn ) {
769 return fn.apply( thisObject || this, arguments );
773 // Set the guid of unique handler to the same of original handler, so it can be removed
775 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
778 // So proxy can be declared as an argument
782 // Mutifunctional method to get and set values to a collection
783 // The value/s can be optionally by executed if its a function
784 access: function( elems, key, value, exec, fn, pass ) {
785 var length = elems.length;
787 // Setting many attributes
788 if ( typeof key === "object" ) {
789 for ( var k in key ) {
790 jQuery.access( elems, k, key[k], exec, fn, value );
795 // Setting one attribute
796 if ( value !== undefined ) {
797 // Optionally, function values get executed if exec is true
798 exec = !pass && exec && jQuery.isFunction(value);
800 for ( var i = 0; i < length; i++ ) {
801 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
807 // Getting an attribute
808 return length ? fn( elems[0], key ) : undefined;
812 return (new Date()).getTime();
815 // Use of jQuery.browser is frowned upon.
816 // More details: http://docs.jquery.com/Utilities/jQuery.browser
817 uaMatch: function( ua ) {
818 ua = ua.toLowerCase();
820 var match = rwebkit.exec( ua ) ||
823 ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
826 return { browser: match[1] || "", version: match[2] || "0" };
832 // Populate the class2type map
833 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
834 class2type[ "[object " + name + "]" ] = name.toLowerCase();
837 browserMatch = jQuery.uaMatch( userAgent );
838 if ( browserMatch.browser ) {
839 jQuery.browser[ browserMatch.browser ] = true;
840 jQuery.browser.version = browserMatch.version;
843 // Deprecated, use jQuery.browser.webkit instead
844 if ( jQuery.browser.webkit ) {
845 jQuery.browser.safari = true;
849 jQuery.inArray = function( elem, array ) {
850 return indexOf.call( array, elem );
854 // Verify that \s matches non-breaking spaces
855 // (IE fails on this test)
856 if ( !rwhite.test( "\xA0" ) ) {
857 trimLeft = /^[\s\xA0]+/;
858 trimRight = /[\s\xA0]+$/;
861 // All jQuery objects should point back to these
862 rootjQuery = jQuery(document);
864 // Cleanup functions for the document ready method
865 if ( document.addEventListener ) {
866 DOMContentLoaded = function() {
867 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
871 } else if ( document.attachEvent ) {
872 DOMContentLoaded = function() {
873 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
874 if ( document.readyState === "complete" ) {
875 document.detachEvent( "onreadystatechange", DOMContentLoaded );
881 // The DOM ready check for Internet Explorer
882 function doScrollCheck() {
883 if ( jQuery.isReady ) {
888 // If IE is used, use the trick by Diego Perini
889 // http://javascript.nwbox.com/IEContentLoaded/
890 document.documentElement.doScroll("left");
892 setTimeout( doScrollCheck, 1 );
896 // and execute any waiting functions
900 // Expose jQuery to the global object
901 return (window.jQuery = window.$ = jQuery);
910 var root = document.documentElement,
911 script = document.createElement("script"),
912 div = document.createElement("div"),
913 id = "script" + jQuery.now();
915 div.style.display = "none";
916 div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
918 var all = div.getElementsByTagName("*"),
919 a = div.getElementsByTagName("a")[0],
920 select = document.createElement("select"),
921 opt = select.appendChild( document.createElement("option") );
923 // Can't get basic test support
924 if ( !all || !all.length || !a ) {
929 // IE strips leading whitespace when .innerHTML is used
930 leadingWhitespace: div.firstChild.nodeType === 3,
932 // Make sure that tbody elements aren't automatically inserted
933 // IE will insert them into empty tables
934 tbody: !div.getElementsByTagName("tbody").length,
936 // Make sure that link elements get serialized correctly by innerHTML
937 // This requires a wrapper element in IE
938 htmlSerialize: !!div.getElementsByTagName("link").length,
940 // Get the style information from getAttribute
941 // (IE uses .cssText insted)
942 style: /red/.test( a.getAttribute("style") ),
944 // Make sure that URLs aren't manipulated
945 // (IE normalizes it by default)
946 hrefNormalized: a.getAttribute("href") === "/a",
948 // Make sure that element opacity exists
949 // (IE uses filter instead)
950 // Use a regex to work around a WebKit issue. See #5145
951 opacity: /^0.55$/.test( a.style.opacity ),
953 // Verify style float existence
954 // (IE uses styleFloat instead of cssFloat)
955 cssFloat: !!a.style.cssFloat,
957 // Make sure that if no value is specified for a checkbox
958 // that it defaults to "on".
959 // (WebKit defaults to "" instead)
960 checkOn: div.getElementsByTagName("input")[0].value === "on",
962 // Make sure that a selected-by-default option has a working selected property.
963 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
964 optSelected: opt.selected,
966 // Will be defined later
972 inlineBlockNeedsLayout: false,
973 shrinkWrapBlocks: false,
974 reliableHiddenOffsets: true
977 // Make sure that the options inside disabled selects aren't marked as disabled
978 // (WebKit marks them as diabled)
979 select.disabled = true;
980 jQuery.support.optDisabled = !opt.disabled;
982 script.type = "text/javascript";
984 script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
987 root.insertBefore( script, root.firstChild );
989 // Make sure that the execution of code works by injecting a script
990 // tag with appendChild/createTextNode
991 // (IE doesn't support this, fails, and uses .text instead)
992 if ( window[ id ] ) {
993 jQuery.support.scriptEval = true;
997 root.removeChild( script );
999 if ( div.attachEvent && div.fireEvent ) {
1000 div.attachEvent("onclick", function click() {
1001 // Cloning a node shouldn't copy over any
1002 // bound event handlers (IE does this)
1003 jQuery.support.noCloneEvent = false;
1004 div.detachEvent("onclick", click);
1006 div.cloneNode(true).fireEvent("onclick");
1009 div = document.createElement("div");
1010 div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
1012 var fragment = document.createDocumentFragment();
1013 fragment.appendChild( div.firstChild );
1015 // WebKit doesn't clone checked state correctly in fragments
1016 jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
1018 // Figure out if the W3C box model works as expected
1019 // document.body must exist before we can do this
1021 var div = document.createElement("div");
1022 div.style.width = div.style.paddingLeft = "1px";
1024 document.body.appendChild( div );
1025 jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
1027 if ( "zoom" in div.style ) {
1028 // Check if natively block-level elements act like inline-block
1029 // elements when setting their display to 'inline' and giving
1031 // (IE < 8 does this)
1032 div.style.display = "inline";
1034 jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
1036 // Check if elements with layout shrink-wrap their children
1038 div.style.display = "";
1039 div.innerHTML = "<div style='width:4px;'></div>";
1040 jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
1043 div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
1044 var tds = div.getElementsByTagName("td");
1046 // Check if table cells still have offsetWidth/Height when they are set
1047 // to display:none and there are still other visible table cells in a
1048 // table row; if so, offsetWidth/Height are not reliable for use when
1049 // determining if an element has been hidden directly using
1050 // display:none (it is still safe to use offsets if a parent element is
1051 // hidden; don safety goggles and see bug #4512 for more information).
1052 // (only IE 8 fails this test)
1053 jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
1055 tds[0].style.display = "";
1056 tds[1].style.display = "none";
1058 // Check if empty table cells still have offsetWidth/Height
1059 // (IE < 8 fail this test)
1060 jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
1063 document.body.removeChild( div ).style.display = "none";
1067 // Technique from Juriy Zaytsev
1068 // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1069 var eventSupported = function( eventName ) {
1070 var el = document.createElement("div");
1071 eventName = "on" + eventName;
1073 var isSupported = (eventName in el);
1074 if ( !isSupported ) {
1075 el.setAttribute(eventName, "return;");
1076 isSupported = typeof el[eventName] === "function";
1083 jQuery.support.submitBubbles = eventSupported("submit");
1084 jQuery.support.changeBubbles = eventSupported("change");
1086 // release memory in IE
1087 root = script = div = all = a = null;
1092 "class": "className",
1093 readonly: "readOnly",
1094 maxlength: "maxLength",
1095 cellspacing: "cellSpacing",
1098 tabindex: "tabIndex",
1100 frameborder: "frameBorder"
1106 var windowData = {},
1107 rbrace = /^(?:\{.*\}|\[.*\])$/;
1112 // Please use with caution
1115 // Unique for each copy of jQuery on the page
1116 expando: "jQuery" + jQuery.now(),
1118 // The following elements throw uncatchable exceptions if you
1119 // attempt to add expando properties to them.
1122 // Ban all objects except for Flash (which handle expandos)
1123 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1127 data: function( elem, name, data ) {
1128 if ( !jQuery.acceptData( elem ) ) {
1132 elem = elem == window ?
1136 var isNode = elem.nodeType,
1137 id = isNode ? elem[ jQuery.expando ] : null,
1138 cache = jQuery.cache, thisCache;
1140 if ( isNode && !id && typeof name === "string" && data === undefined ) {
1144 // Get the data from the object directly
1148 // Compute a unique ID for the element
1150 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1153 // Avoid generating a new cache unless none exists and we
1154 // want to manipulate it.
1155 if ( typeof name === "object" ) {
1157 cache[ id ] = jQuery.extend(cache[ id ], name);
1160 jQuery.extend( cache, name );
1163 } else if ( isNode && !cache[ id ] ) {
1167 thisCache = isNode ? cache[ id ] : cache;
1169 // Prevent overriding the named cache with undefined values
1170 if ( data !== undefined ) {
1171 thisCache[ name ] = data;
1174 return typeof name === "string" ? thisCache[ name ] : thisCache;
1177 removeData: function( elem, name ) {
1178 if ( !jQuery.acceptData( elem ) ) {
1182 elem = elem == window ?
1186 var isNode = elem.nodeType,
1187 id = isNode ? elem[ jQuery.expando ] : elem,
1188 cache = jQuery.cache,
1189 thisCache = isNode ? cache[ id ] : id;
1191 // If we want to remove a specific section of the element's data
1194 // Remove the section of cache data
1195 delete thisCache[ name ];
1197 // If we've removed all the data, remove the element's cache
1198 if ( isNode && jQuery.isEmptyObject(thisCache) ) {
1199 jQuery.removeData( elem );
1203 // Otherwise, we want to remove all of the element's data
1205 if ( isNode && jQuery.support.deleteExpando ) {
1206 delete elem[ jQuery.expando ];
1208 } else if ( elem.removeAttribute ) {
1209 elem.removeAttribute( jQuery.expando );
1211 // Completely remove the data cache
1212 } else if ( isNode ) {
1215 // Remove all fields from the object
1217 for ( var n in elem ) {
1224 // A method for determining if a DOM node can handle the data expando
1225 acceptData: function( elem ) {
1226 if ( elem.nodeName ) {
1227 var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1230 return !(match === true || elem.getAttribute("classid") !== match);
1239 data: function( key, value ) {
1240 if ( typeof key === "undefined" ) {
1241 return this.length ? jQuery.data( this[0] ) : null;
1243 } else if ( typeof key === "object" ) {
1244 return this.each(function() {
1245 jQuery.data( this, key );
1249 var parts = key.split(".");
1250 parts[1] = parts[1] ? "." + parts[1] : "";
1252 if ( value === undefined ) {
1253 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1255 // Try to fetch any internally stored data first
1256 if ( data === undefined && this.length ) {
1257 data = jQuery.data( this[0], key );
1259 // If nothing was found internally, try to fetch any
1260 // data from the HTML5 data-* attribute
1261 if ( data === undefined && this[0].nodeType === 1 ) {
1262 data = this[0].getAttribute( "data-" + key );
1264 if ( typeof data === "string" ) {
1266 data = data === "true" ? true :
1267 data === "false" ? false :
1268 data === "null" ? null :
1269 !jQuery.isNaN( data ) ? parseFloat( data ) :
1270 rbrace.test( data ) ? jQuery.parseJSON( data ) :
1280 return data === undefined && parts[1] ?
1281 this.data( parts[0] ) :
1285 return this.each(function() {
1286 var $this = jQuery( this ), args = [ parts[0], value ];
1288 $this.triggerHandler( "setData" + parts[1] + "!", args );
1289 jQuery.data( this, key, value );
1290 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1295 removeData: function( key ) {
1296 return this.each(function() {
1297 jQuery.removeData( this, key );
1306 queue: function( elem, type, data ) {
1311 type = (type || "fx") + "queue";
1312 var q = jQuery.data( elem, type );
1314 // Speed up dequeue by getting out quickly if this is just a lookup
1319 if ( !q || jQuery.isArray(data) ) {
1320 q = jQuery.data( elem, type, jQuery.makeArray(data) );
1329 dequeue: function( elem, type ) {
1330 type = type || "fx";
1332 var queue = jQuery.queue( elem, type ), fn = queue.shift();
1334 // If the fx queue is dequeued, always remove the progress sentinel
1335 if ( fn === "inprogress" ) {
1340 // Add a progress sentinel to prevent the fx queue from being
1341 // automatically dequeued
1342 if ( type === "fx" ) {
1343 queue.unshift("inprogress");
1346 fn.call(elem, function() {
1347 jQuery.dequeue(elem, type);
1354 queue: function( type, data ) {
1355 if ( typeof type !== "string" ) {
1360 if ( data === undefined ) {
1361 return jQuery.queue( this[0], type );
1363 return this.each(function( i ) {
1364 var queue = jQuery.queue( this, type, data );
1366 if ( type === "fx" && queue[0] !== "inprogress" ) {
1367 jQuery.dequeue( this, type );
1371 dequeue: function( type ) {
1372 return this.each(function() {
1373 jQuery.dequeue( this, type );
1377 // Based off of the plugin by Clint Helfers, with permission.
1378 // http://blindsignals.com/index.php/2009/07/jquery-delay/
1379 delay: function( time, type ) {
1380 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1381 type = type || "fx";
1383 return this.queue( type, function() {
1385 setTimeout(function() {
1386 jQuery.dequeue( elem, type );
1391 clearQueue: function( type ) {
1392 return this.queue( type || "fx", [] );
1399 var rclass = /[\n\t]/g,
1402 rspecialurl = /^(?:href|src|style)$/,
1403 rtype = /^(?:button|input)$/i,
1404 rfocusable = /^(?:button|input|object|select|textarea)$/i,
1405 rclickable = /^a(?:rea)?$/i,
1406 rradiocheck = /^(?:radio|checkbox)$/i;
1409 attr: function( name, value ) {
1410 return jQuery.access( this, name, value, true, jQuery.attr );
1413 removeAttr: function( name, fn ) {
1414 return this.each(function(){
1415 jQuery.attr( this, name, "" );
1416 if ( this.nodeType === 1 ) {
1417 this.removeAttribute( name );
1422 addClass: function( value ) {
1423 if ( jQuery.isFunction(value) ) {
1424 return this.each(function(i) {
1425 var self = jQuery(this);
1426 self.addClass( value.call(this, i, self.attr("class")) );
1430 if ( value && typeof value === "string" ) {
1431 var classNames = (value || "").split( rspaces );
1433 for ( var i = 0, l = this.length; i < l; i++ ) {
1436 if ( elem.nodeType === 1 ) {
1437 if ( !elem.className ) {
1438 elem.className = value;
1441 var className = " " + elem.className + " ", setClass = elem.className;
1442 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1443 if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
1444 setClass += " " + classNames[c];
1447 elem.className = jQuery.trim( setClass );
1456 removeClass: function( value ) {
1457 if ( jQuery.isFunction(value) ) {
1458 return this.each(function(i) {
1459 var self = jQuery(this);
1460 self.removeClass( value.call(this, i, self.attr("class")) );
1464 if ( (value && typeof value === "string") || value === undefined ) {
1465 var classNames = (value || "").split( rspaces );
1467 for ( var i = 0, l = this.length; i < l; i++ ) {
1470 if ( elem.nodeType === 1 && elem.className ) {
1472 var className = (" " + elem.className + " ").replace(rclass, " ");
1473 for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
1474 className = className.replace(" " + classNames[c] + " ", " ");
1476 elem.className = jQuery.trim( className );
1479 elem.className = "";
1488 toggleClass: function( value, stateVal ) {
1489 var type = typeof value, isBool = typeof stateVal === "boolean";
1491 if ( jQuery.isFunction( value ) ) {
1492 return this.each(function(i) {
1493 var self = jQuery(this);
1494 self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
1498 return this.each(function() {
1499 if ( type === "string" ) {
1500 // toggle individual class names
1501 var className, i = 0, self = jQuery(this),
1503 classNames = value.split( rspaces );
1505 while ( (className = classNames[ i++ ]) ) {
1506 // check each className given, space seperated list
1507 state = isBool ? state : !self.hasClass( className );
1508 self[ state ? "addClass" : "removeClass" ]( className );
1511 } else if ( type === "undefined" || type === "boolean" ) {
1512 if ( this.className ) {
1513 // store className if set
1514 jQuery.data( this, "__className__", this.className );
1517 // toggle whole className
1518 this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
1523 hasClass: function( selector ) {
1524 var className = " " + selector + " ";
1525 for ( var i = 0, l = this.length; i < l; i++ ) {
1526 if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
1534 val: function( value ) {
1535 if ( !arguments.length ) {
1539 if ( jQuery.nodeName( elem, "option" ) ) {
1540 // attributes.value is undefined in Blackberry 4.7 but
1541 // uses .value. See #6932
1542 var val = elem.attributes.value;
1543 return !val || val.specified ? elem.value : elem.text;
1546 // We need to handle select boxes special
1547 if ( jQuery.nodeName( elem, "select" ) ) {
1548 var index = elem.selectedIndex,
1550 options = elem.options,
1551 one = elem.type === "select-one";
1553 // Nothing was selected
1558 // Loop through all the selected options
1559 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
1560 var option = options[ i ];
1562 // Don't return options that are disabled or in a disabled optgroup
1563 if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
1564 (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
1566 // Get the specific value for the option
1567 value = jQuery(option).val();
1569 // We don't need an array for one selects
1574 // Multi-Selects return an array
1575 values.push( value );
1582 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
1583 if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
1584 return elem.getAttribute("value") === null ? "on" : elem.value;
1588 // Everything else, we just grab the value
1589 return (elem.value || "").replace(rreturn, "");
1596 var isFunction = jQuery.isFunction(value);
1598 return this.each(function(i) {
1599 var self = jQuery(this), val = value;
1601 if ( this.nodeType !== 1 ) {
1606 val = value.call(this, i, self.val());
1609 // Treat null/undefined as ""; convert numbers to string
1610 if ( val == null ) {
1612 } else if ( typeof val === "number" ) {
1614 } else if ( jQuery.isArray(val) ) {
1615 val = jQuery.map(val, function (value) {
1616 return value == null ? "" : value + "";
1620 if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
1621 this.checked = jQuery.inArray( self.val(), val ) >= 0;
1623 } else if ( jQuery.nodeName( this, "select" ) ) {
1624 var values = jQuery.makeArray(val);
1626 jQuery( "option", this ).each(function() {
1627 this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
1630 if ( !values.length ) {
1631 this.selectedIndex = -1;
1653 attr: function( elem, name, value, pass ) {
1654 // don't set attributes on text and comment nodes
1655 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
1659 if ( pass && name in jQuery.attrFn ) {
1660 return jQuery(elem)[name](value);
1663 var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
1664 // Whether we are setting (or getting)
1665 set = value !== undefined;
1667 // Try to normalize/fix the name
1668 name = notxml && jQuery.props[ name ] || name;
1670 // Only do all the following if this is a node (faster for style)
1671 if ( elem.nodeType === 1 ) {
1672 // These attributes require special treatment
1673 var special = rspecialurl.test( name );
1675 // Safari mis-reports the default selected property of an option
1676 // Accessing the parent's selectedIndex property fixes it
1677 if ( name === "selected" && !jQuery.support.optSelected ) {
1678 var parent = elem.parentNode;
1680 parent.selectedIndex;
1682 // Make sure that it also works with optgroups, see #5701
1683 if ( parent.parentNode ) {
1684 parent.parentNode.selectedIndex;
1689 // If applicable, access the attribute via the DOM 0 way
1690 // 'in' checks fail in Blackberry 4.7 #6931
1691 if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
1693 // We can't allow the type property to be changed (since it causes problems in IE)
1694 if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
1695 jQuery.error( "type property can't be changed" );
1698 if ( value === null ) {
1699 if ( elem.nodeType === 1 ) {
1700 elem.removeAttribute( name );
1704 elem[ name ] = value;
1708 // browsers index elements by id/name on forms, give priority to attributes.
1709 if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
1710 return elem.getAttributeNode( name ).nodeValue;
1713 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1714 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1715 if ( name === "tabIndex" ) {
1716 var attributeNode = elem.getAttributeNode( "tabIndex" );
1718 return attributeNode && attributeNode.specified ?
1719 attributeNode.value :
1720 rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
1725 return elem[ name ];
1728 if ( !jQuery.support.style && notxml && name === "style" ) {
1730 elem.style.cssText = "" + value;
1733 return elem.style.cssText;
1737 // convert the value to a string (all browsers do this but IE) see #1070
1738 elem.setAttribute( name, "" + value );
1741 // Ensure that missing attributes return undefined
1742 // Blackberry 4.7 returns "" from getAttribute #6938
1743 if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
1747 var attr = !jQuery.support.hrefNormalized && notxml && special ?
1748 // Some attributes require a special call on IE
1749 elem.getAttribute( name, 2 ) :
1750 elem.getAttribute( name );
1752 // Non-existent attributes return null, we normalize to undefined
1753 return attr === null ? undefined : attr;
1761 var rnamespaces = /\.(.*)$/,
1762 rformElems = /^(?:textarea|input|select)$/i,
1765 rescape = /[^\w\s.|`]/g,
1766 fcleanup = function( nm ) {
1767 return nm.replace(rescape, "\\$&");
1769 focusCounts = { focusin: 0, focusout: 0 };
1772 * A number of helper functions used for managing events.
1773 * Many of the ideas behind this code originated from
1774 * Dean Edwards' addEvent library.
1778 // Bind an event to an element
1779 // Original by Dean Edwards
1780 add: function( elem, types, handler, data ) {
1781 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1785 // For whatever reason, IE has trouble passing the window object
1786 // around, causing it to be cloned in the process
1787 if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
1791 if ( handler === false ) {
1792 handler = returnFalse;
1795 var handleObjIn, handleObj;
1797 if ( handler.handler ) {
1798 handleObjIn = handler;
1799 handler = handleObjIn.handler;
1802 // Make sure that the function being executed has a unique ID
1803 if ( !handler.guid ) {
1804 handler.guid = jQuery.guid++;
1807 // Init the element's event structure
1808 var elemData = jQuery.data( elem );
1810 // If no elemData is found then we must be trying to bind to one of the
1811 // banned noData elements
1816 // Use a key less likely to result in collisions for plain JS objects.
1818 var eventKey = elem.nodeType ? "events" : "__events__",
1819 events = elemData[ eventKey ],
1820 eventHandle = elemData.handle;
1822 if ( typeof events === "function" ) {
1823 // On plain objects events is a fn that holds the the data
1824 // which prevents this data from being JSON serialized
1825 // the function does not need to be called, it just contains the data
1826 eventHandle = events.handle;
1827 events = events.events;
1829 } else if ( !events ) {
1830 if ( !elem.nodeType ) {
1831 // On plain objects, create a fn that acts as the holder
1832 // of the values to avoid JSON serialization of event data
1833 elemData[ eventKey ] = elemData = function(){};
1836 elemData.events = events = {};
1839 if ( !eventHandle ) {
1840 elemData.handle = eventHandle = function() {
1841 // Handle the second event of a trigger and when
1842 // an event is called after a page has unloaded
1843 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
1844 jQuery.event.handle.apply( eventHandle.elem, arguments ) :
1849 // Add elem as a property of the handle function
1850 // This is to prevent a memory leak with non-native events in IE.
1851 eventHandle.elem = elem;
1853 // Handle multiple events separated by a space
1854 // jQuery(...).bind("mouseover mouseout", fn);
1855 types = types.split(" ");
1857 var type, i = 0, namespaces;
1859 while ( (type = types[ i++ ]) ) {
1860 handleObj = handleObjIn ?
1861 jQuery.extend({}, handleObjIn) :
1862 { handler: handler, data: data };
1864 // Namespaced event handlers
1865 if ( type.indexOf(".") > -1 ) {
1866 namespaces = type.split(".");
1867 type = namespaces.shift();
1868 handleObj.namespace = namespaces.slice(0).sort().join(".");
1872 handleObj.namespace = "";
1875 handleObj.type = type;
1876 if ( !handleObj.guid ) {
1877 handleObj.guid = handler.guid;
1880 // Get the current list of functions bound to this event
1881 var handlers = events[ type ],
1882 special = jQuery.event.special[ type ] || {};
1884 // Init the event handler queue
1886 handlers = events[ type ] = [];
1888 // Check for a special event handler
1889 // Only use addEventListener/attachEvent if the special
1890 // events handler returns false
1891 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
1892 // Bind the global event handler to the element
1893 if ( elem.addEventListener ) {
1894 elem.addEventListener( type, eventHandle, false );
1896 } else if ( elem.attachEvent ) {
1897 elem.attachEvent( "on" + type, eventHandle );
1902 if ( special.add ) {
1903 special.add.call( elem, handleObj );
1905 if ( !handleObj.handler.guid ) {
1906 handleObj.handler.guid = handler.guid;
1910 // Add the function to the element's handler list
1911 handlers.push( handleObj );
1913 // Keep track of which events have been used, for global triggering
1914 jQuery.event.global[ type ] = true;
1917 // Nullify elem to prevent memory leaks in IE
1923 // Detach an event or set of events from an element
1924 remove: function( elem, types, handler, pos ) {
1925 // don't do events on text and comment nodes
1926 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
1930 if ( handler === false ) {
1931 handler = returnFalse;
1934 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
1935 eventKey = elem.nodeType ? "events" : "__events__",
1936 elemData = jQuery.data( elem ),
1937 events = elemData && elemData[ eventKey ];
1939 if ( !elemData || !events ) {
1943 if ( typeof events === "function" ) {
1945 events = events.events;
1948 // types is actually an event object here
1949 if ( types && types.type ) {
1950 handler = types.handler;
1954 // Unbind all events for the element
1955 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
1956 types = types || "";
1958 for ( type in events ) {
1959 jQuery.event.remove( elem, type + types );
1965 // Handle multiple events separated by a space
1966 // jQuery(...).unbind("mouseover mouseout", fn);
1967 types = types.split(" ");
1969 while ( (type = types[ i++ ]) ) {
1972 all = type.indexOf(".") < 0;
1976 // Namespaced event handlers
1977 namespaces = type.split(".");
1978 type = namespaces.shift();
1980 namespace = new RegExp("(^|\\.)" +
1981 jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
1984 eventType = events[ type ];
1991 for ( j = 0; j < eventType.length; j++ ) {
1992 handleObj = eventType[ j ];
1994 if ( all || namespace.test( handleObj.namespace ) ) {
1995 jQuery.event.remove( elem, origType, handleObj.handler, j );
1996 eventType.splice( j--, 1 );
2003 special = jQuery.event.special[ type ] || {};
2005 for ( j = pos || 0; j < eventType.length; j++ ) {
2006 handleObj = eventType[ j ];
2008 if ( handler.guid === handleObj.guid ) {
2009 // remove the given handler for the given type
2010 if ( all || namespace.test( handleObj.namespace ) ) {
2011 if ( pos == null ) {
2012 eventType.splice( j--, 1 );
2015 if ( special.remove ) {
2016 special.remove.call( elem, handleObj );
2020 if ( pos != null ) {
2026 // remove generic event handler if no more handlers exist
2027 if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2028 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2029 jQuery.removeEvent( elem, type, elemData.handle );
2033 delete events[ type ];
2037 // Remove the expando if it's no longer used
2038 if ( jQuery.isEmptyObject( events ) ) {
2039 var handle = elemData.handle;
2044 delete elemData.events;
2045 delete elemData.handle;
2047 if ( typeof elemData === "function" ) {
2048 jQuery.removeData( elem, eventKey );
2050 } else if ( jQuery.isEmptyObject( elemData ) ) {
2051 jQuery.removeData( elem );
2056 // bubbling is internal
2057 trigger: function( event, data, elem /*, bubbling */ ) {
2058 // Event object or event type
2059 var type = event.type || event,
2060 bubbling = arguments[3];
2063 event = typeof event === "object" ?
2064 // jQuery.Event object
2065 event[ jQuery.expando ] ? event :
2067 jQuery.extend( jQuery.Event(type), event ) :
2068 // Just the event type (string)
2071 if ( type.indexOf("!") >= 0 ) {
2072 event.type = type = type.slice(0, -1);
2073 event.exclusive = true;
2076 // Handle a global trigger
2078 // Don't bubble custom events when global (to avoid too much overhead)
2079 event.stopPropagation();
2081 // Only trigger if we've ever bound an event for it
2082 if ( jQuery.event.global[ type ] ) {
2083 jQuery.each( jQuery.cache, function() {
2084 if ( this.events && this.events[type] ) {
2085 jQuery.event.trigger( event, data, this.handle.elem );
2091 // Handle triggering a single element
2093 // don't do events on text and comment nodes
2094 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
2098 // Clean up in case it is reused
2099 event.result = undefined;
2100 event.target = elem;
2102 // Clone the incoming data, if any
2103 data = jQuery.makeArray( data );
2104 data.unshift( event );
2107 event.currentTarget = elem;
2109 // Trigger the event, it is assumed that "handle" is a function
2110 var handle = elem.nodeType ?
2111 jQuery.data( elem, "handle" ) :
2112 (jQuery.data( elem, "__events__" ) || {}).handle;
2115 handle.apply( elem, data );
2118 var parent = elem.parentNode || elem.ownerDocument;
2120 // Trigger an inline bound script
2122 if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
2123 if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
2124 event.result = false;
2125 event.preventDefault();
2129 // prevent IE from throwing an error for some elements with some event types, see #3533
2130 } catch (inlineError) {}
2132 if ( !event.isPropagationStopped() && parent ) {
2133 jQuery.event.trigger( event, data, parent, true );
2135 } else if ( !event.isDefaultPrevented() ) {
2136 var target = event.target, old, targetType = type.replace(rnamespaces, ""),
2137 isClick = jQuery.nodeName(target, "a") && targetType === "click",
2138 special = jQuery.event.special[ targetType ] || {};
2140 if ( (!special._default || special._default.call( elem, event ) === false) &&
2141 !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
2144 if ( target[ targetType ] ) {
2145 // Make sure that we don't accidentally re-trigger the onFOO events
2146 old = target[ "on" + targetType ];
2149 target[ "on" + targetType ] = null;
2152 jQuery.event.triggered = true;
2153 target[ targetType ]();
2156 // prevent IE from throwing an error for some elements with some event types, see #3533
2157 } catch (triggerError) {}
2160 target[ "on" + targetType ] = old;
2163 jQuery.event.triggered = false;
2168 handle: function( event ) {
2169 var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
2171 event = args[0] = jQuery.event.fix( event || window.event );
2172 event.currentTarget = this;
2174 // Namespaced event handlers
2175 all = event.type.indexOf(".") < 0 && !event.exclusive;
2178 namespaces = event.type.split(".");
2179 event.type = namespaces.shift();
2180 namespace_sort = namespaces.slice(0).sort();
2181 namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
2184 event.namespace = event.namespace || namespace_sort.join(".");
2186 events = jQuery.data(this, this.nodeType ? "events" : "__events__");
2188 if ( typeof events === "function" ) {
2189 events = events.events;
2192 handlers = (events || {})[ event.type ];
2194 if ( events && handlers ) {
2195 // Clone the handlers to prevent manipulation
2196 handlers = handlers.slice(0);
2198 for ( var j = 0, l = handlers.length; j < l; j++ ) {
2199 var handleObj = handlers[ j ];
2201 // Filter the functions by class
2202 if ( all || namespace_re.test( handleObj.namespace ) ) {
2203 // Pass in a reference to the handler function itself
2204 // So that we can later remove it
2205 event.handler = handleObj.handler;
2206 event.data = handleObj.data;
2207 event.handleObj = handleObj;
2209 var ret = handleObj.handler.apply( this, args );
2211 if ( ret !== undefined ) {
2213 if ( ret === false ) {
2214 event.preventDefault();
2215 event.stopPropagation();
2219 if ( event.isImmediatePropagationStopped() ) {
2226 return event.result;
2229 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(" "),
2231 fix: function( event ) {
2232 if ( event[ jQuery.expando ] ) {
2236 // store a copy of the original event object
2237 // and "clone" to set read-only properties
2238 var originalEvent = event;
2239 event = jQuery.Event( originalEvent );
2241 for ( var i = this.props.length, prop; i; ) {
2242 prop = this.props[ --i ];
2243 event[ prop ] = originalEvent[ prop ];
2246 // Fix target property, if necessary
2247 if ( !event.target ) {
2248 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2251 // check if target is a textnode (safari)
2252 if ( event.target.nodeType === 3 ) {
2253 event.target = event.target.parentNode;
2256 // Add relatedTarget, if necessary
2257 if ( !event.relatedTarget && event.fromElement ) {
2258 event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
2261 // Calculate pageX/Y if missing and clientX/Y available
2262 if ( event.pageX == null && event.clientX != null ) {
2263 var doc = document.documentElement, body = document.body;
2264 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
2265 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
2268 // Add which for key events
2269 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
2270 event.which = event.charCode != null ? event.charCode : event.keyCode;
2273 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2274 if ( !event.metaKey && event.ctrlKey ) {
2275 event.metaKey = event.ctrlKey;
2278 // Add which for click: 1 === left; 2 === middle; 3 === right
2279 // Note: button is not normalized, so don't use it
2280 if ( !event.which && event.button !== undefined ) {
2281 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2287 // Deprecated, use jQuery.guid instead
2290 // Deprecated, use jQuery.proxy instead
2291 proxy: jQuery.proxy,
2295 // Make sure the ready event is setup
2296 setup: jQuery.bindReady,
2297 teardown: jQuery.noop
2301 add: function( handleObj ) {
2302 jQuery.event.add( this,
2303 liveConvert( handleObj.origType, handleObj.selector ),
2304 jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
2307 remove: function( handleObj ) {
2308 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
2313 setup: function( data, namespaces, eventHandle ) {
2314 // We only want to do this special case on windows
2315 if ( jQuery.isWindow( this ) ) {
2316 this.onbeforeunload = eventHandle;
2320 teardown: function( namespaces, eventHandle ) {
2321 if ( this.onbeforeunload === eventHandle ) {
2322 this.onbeforeunload = null;
2329 jQuery.removeEvent = document.removeEventListener ?
2330 function( elem, type, handle ) {
2331 if ( elem.removeEventListener ) {
2332 elem.removeEventListener( type, handle, false );
2335 function( elem, type, handle ) {
2336 if ( elem.detachEvent ) {
2337 elem.detachEvent( "on" + type, handle );
2341 jQuery.Event = function( src ) {
2342 // Allow instantiation without the 'new' keyword
2343 if ( !this.preventDefault ) {
2344 return new jQuery.Event( src );
2348 if ( src && src.type ) {
2349 this.originalEvent = src;
2350 this.type = src.type;
2356 // timeStamp is buggy for some events on Firefox(#3843)
2357 // So we won't rely on the native value
2358 this.timeStamp = jQuery.now();
2361 this[ jQuery.expando ] = true;
2364 function returnFalse() {
2367 function returnTrue() {
2371 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2372 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2373 jQuery.Event.prototype = {
2374 preventDefault: function() {
2375 this.isDefaultPrevented = returnTrue;
2377 var e = this.originalEvent;
2382 // if preventDefault exists run it on the original event
2383 if ( e.preventDefault ) {
2386 // otherwise set the returnValue property of the original event to false (IE)
2388 e.returnValue = false;
2391 stopPropagation: function() {
2392 this.isPropagationStopped = returnTrue;
2394 var e = this.originalEvent;
2398 // if stopPropagation exists run it on the original event
2399 if ( e.stopPropagation ) {
2400 e.stopPropagation();
2402 // otherwise set the cancelBubble property of the original event to true (IE)
2403 e.cancelBubble = true;
2405 stopImmediatePropagation: function() {
2406 this.isImmediatePropagationStopped = returnTrue;
2407 this.stopPropagation();
2409 isDefaultPrevented: returnFalse,
2410 isPropagationStopped: returnFalse,
2411 isImmediatePropagationStopped: returnFalse
2414 // Checks if an event happened on an element within another element
2415 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2416 var withinElement = function( event ) {
2417 // Check if mouse(over|out) are still within the same parent element
2418 var parent = event.relatedTarget;
2420 // Firefox sometimes assigns relatedTarget a XUL element
2421 // which we cannot access the parentNode property of
2423 // Traverse up the tree
2424 while ( parent && parent !== this ) {
2425 parent = parent.parentNode;
2428 if ( parent !== this ) {
2429 // set the correct event type
2430 event.type = event.data;
2432 // handle event if we actually just moused on to a non sub-element
2433 jQuery.event.handle.apply( this, arguments );
2436 // assuming we've left the element since we most likely mousedover a xul element
2440 // In case of event delegation, we only need to rename the event.type,
2441 // liveHandler will take care of the rest.
2442 delegate = function( event ) {
2443 event.type = event.data;
2444 jQuery.event.handle.apply( this, arguments );
2447 // Create mouseenter and mouseleave events
2449 mouseenter: "mouseover",
2450 mouseleave: "mouseout"
2451 }, function( orig, fix ) {
2452 jQuery.event.special[ orig ] = {
2453 setup: function( data ) {
2454 jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
2456 teardown: function( data ) {
2457 jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
2462 // submit delegation
2463 if ( !jQuery.support.submitBubbles ) {
2465 jQuery.event.special.submit = {
2466 setup: function( data, namespaces ) {
2467 if ( this.nodeName.toLowerCase() !== "form" ) {
2468 jQuery.event.add(this, "click.specialSubmit", function( e ) {
2469 var elem = e.target, type = elem.type;
2471 if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
2472 e.liveFired = undefined;
2473 return trigger( "submit", this, arguments );
2477 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
2478 var elem = e.target, type = elem.type;
2480 if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
2481 e.liveFired = undefined;
2482 return trigger( "submit", this, arguments );
2491 teardown: function( namespaces ) {
2492 jQuery.event.remove( this, ".specialSubmit" );
2498 // change delegation, happens here so we have bind.
2499 if ( !jQuery.support.changeBubbles ) {
2503 getVal = function( elem ) {
2504 var type = elem.type, val = elem.value;
2506 if ( type === "radio" || type === "checkbox" ) {
2509 } else if ( type === "select-multiple" ) {
2510 val = elem.selectedIndex > -1 ?
2511 jQuery.map( elem.options, function( elem ) {
2512 return elem.selected;
2516 } else if ( elem.nodeName.toLowerCase() === "select" ) {
2517 val = elem.selectedIndex;
2523 testChange = function testChange( e ) {
2524 var elem = e.target, data, val;
2526 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
2530 data = jQuery.data( elem, "_change_data" );
2533 // the current data will be also retrieved by beforeactivate
2534 if ( e.type !== "focusout" || elem.type !== "radio" ) {
2535 jQuery.data( elem, "_change_data", val );
2538 if ( data === undefined || val === data ) {
2542 if ( data != null || val ) {
2544 e.liveFired = undefined;
2545 return jQuery.event.trigger( e, arguments[1], elem );
2549 jQuery.event.special.change = {
2551 focusout: testChange,
2553 beforedeactivate: testChange,
2555 click: function( e ) {
2556 var elem = e.target, type = elem.type;
2558 if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
2559 return testChange.call( this, e );
2563 // Change has to be called before submit
2564 // Keydown will be called before keypress, which is used in submit-event delegation
2565 keydown: function( e ) {
2566 var elem = e.target, type = elem.type;
2568 if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
2569 (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
2570 type === "select-multiple" ) {
2571 return testChange.call( this, e );
2575 // Beforeactivate happens also before the previous element is blurred
2576 // with this event you can't trigger a change event, but you can store
2578 beforeactivate: function( e ) {
2579 var elem = e.target;
2580 jQuery.data( elem, "_change_data", getVal(elem) );
2584 setup: function( data, namespaces ) {
2585 if ( this.type === "file" ) {
2589 for ( var type in changeFilters ) {
2590 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
2593 return rformElems.test( this.nodeName );
2596 teardown: function( namespaces ) {
2597 jQuery.event.remove( this, ".specialChange" );
2599 return rformElems.test( this.nodeName );
2603 changeFilters = jQuery.event.special.change.filters;
2605 // Handle when the input is .focus()'d
2606 changeFilters.focus = changeFilters.beforeactivate;
2609 function trigger( type, elem, args ) {
2610 args[0].type = type;
2611 return jQuery.event.handle.apply( elem, args );
2614 // Create "bubbling" focus and blur events
2615 if ( document.addEventListener ) {
2616 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
2617 jQuery.event.special[ fix ] = {
2619 if ( focusCounts[fix]++ === 0 ) {
2620 document.addEventListener( orig, handler, true );
2623 teardown: function() {
2624 if ( --focusCounts[fix] === 0 ) {
2625 document.removeEventListener( orig, handler, true );
2630 function handler( e ) {
2631 e = jQuery.event.fix( e );
2633 return jQuery.event.trigger( e, null, e.target );
2638 jQuery.each(["bind", "one"], function( i, name ) {
2639 jQuery.fn[ name ] = function( type, data, fn ) {
2640 // Handle object literals
2641 if ( typeof type === "object" ) {
2642 for ( var key in type ) {
2643 this[ name ](key, data, type[key], fn);
2648 if ( jQuery.isFunction( data ) || data === false ) {
2653 var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
2654 jQuery( this ).unbind( event, handler );
2655 return fn.apply( this, arguments );
2658 if ( type === "unload" && name !== "one" ) {
2659 this.one( type, data, fn );
2662 for ( var i = 0, l = this.length; i < l; i++ ) {
2663 jQuery.event.add( this[i], type, handler, data );
2672 unbind: function( type, fn ) {
2673 // Handle object literals
2674 if ( typeof type === "object" && !type.preventDefault ) {
2675 for ( var key in type ) {
2676 this.unbind(key, type[key]);
2680 for ( var i = 0, l = this.length; i < l; i++ ) {
2681 jQuery.event.remove( this[i], type, fn );
2688 delegate: function( selector, types, data, fn ) {
2689 return this.live( types, data, fn, selector );
2692 undelegate: function( selector, types, fn ) {
2693 if ( arguments.length === 0 ) {
2694 return this.unbind( "live" );
2697 return this.die( types, null, fn, selector );
2701 trigger: function( type, data ) {
2702 return this.each(function() {
2703 jQuery.event.trigger( type, data, this );
2707 triggerHandler: function( type, data ) {
2709 var event = jQuery.Event( type );
2710 event.preventDefault();
2711 event.stopPropagation();
2712 jQuery.event.trigger( event, data, this[0] );
2713 return event.result;
2717 toggle: function( fn ) {
2718 // Save reference to arguments for access in closure
2719 var args = arguments, i = 1;
2721 // link all the functions, so any of them can unbind this click handler
2722 while ( i < args.length ) {
2723 jQuery.proxy( fn, args[ i++ ] );
2726 return this.click( jQuery.proxy( fn, function( event ) {
2727 // Figure out which function to execute
2728 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
2729 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
2731 // Make sure that clicks stop
2732 event.preventDefault();
2734 // and execute the function
2735 return args[ lastToggle ].apply( this, arguments ) || false;
2739 hover: function( fnOver, fnOut ) {
2740 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
2747 mouseenter: "mouseover",
2748 mouseleave: "mouseout"
2751 jQuery.each(["live", "die"], function( i, name ) {
2752 jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
2753 var type, i = 0, match, namespaces, preType,
2754 selector = origSelector || this.selector,
2755 context = origSelector ? this : jQuery( this.context );
2757 if ( typeof types === "object" && !types.preventDefault ) {
2758 for ( var key in types ) {
2759 context[ name ]( key, data, types[key], selector );
2765 if ( jQuery.isFunction( data ) ) {
2770 types = (types || "").split(" ");
2772 while ( (type = types[ i++ ]) != null ) {
2773 match = rnamespaces.exec( type );
2777 namespaces = match[0];
2778 type = type.replace( rnamespaces, "" );
2781 if ( type === "hover" ) {
2782 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
2788 if ( type === "focus" || type === "blur" ) {
2789 types.push( liveMap[ type ] + namespaces );
2790 type = type + namespaces;
2793 type = (liveMap[ type ] || type) + namespaces;
2796 if ( name === "live" ) {
2797 // bind live handler
2798 for ( var j = 0, l = context.length; j < l; j++ ) {
2799 jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
2800 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
2804 // unbind live handler
2805 context.unbind( "live." + liveConvert( type, selector ), fn );
2813 function liveHandler( event ) {
2814 var stop, maxLevel, elems = [], selectors = [],
2815 related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
2816 events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
2818 if ( typeof events === "function" ) {
2819 events = events.events;
2822 // Make sure we avoid non-left-click bubbling in Firefox (#3861)
2823 if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
2827 if ( event.namespace ) {
2828 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
2831 event.liveFired = this;
2833 var live = events.live.slice(0);
2835 for ( j = 0; j < live.length; j++ ) {
2836 handleObj = live[j];
2838 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
2839 selectors.push( handleObj.selector );
2842 live.splice( j--, 1 );
2846 match = jQuery( event.target ).closest( selectors, event.currentTarget );
2848 for ( i = 0, l = match.length; i < l; i++ ) {
2851 for ( j = 0; j < live.length; j++ ) {
2852 handleObj = live[j];
2854 if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
2858 // Those two events require additional checking
2859 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
2860 event.type = handleObj.preType;
2861 related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
2864 if ( !related || related !== elem ) {
2865 elems.push({ elem: elem, handleObj: handleObj, level: close.level });
2871 for ( i = 0, l = elems.length; i < l; i++ ) {
2874 if ( maxLevel && match.level > maxLevel ) {
2878 event.currentTarget = match.elem;
2879 event.data = match.handleObj.data;
2880 event.handleObj = match.handleObj;
2882 ret = match.handleObj.origHandler.apply( match.elem, arguments );
2884 if ( ret === false || event.isPropagationStopped() ) {
2885 maxLevel = match.level;
2887 if ( ret === false ) {
2896 function liveConvert( type, selector ) {
2897 return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
2900 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
2901 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
2902 "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
2904 // Handle event binding
2905 jQuery.fn[ name ] = function( data, fn ) {
2911 return arguments.length > 0 ?
2912 this.bind( name, data, fn ) :
2913 this.trigger( name );
2916 if ( jQuery.attrFn ) {
2917 jQuery.attrFn[ name ] = true;
2921 // Prevent memory leaks in IE
2922 // Window isn't included so as not to unbind existing unload events
2924 // - http://isaacschlueter.com/2006/10/msie-memory-leaks/
2925 if ( window.attachEvent && !window.addEventListener ) {
2926 jQuery(window).bind("unload", function() {
2927 for ( var id in jQuery.cache ) {
2928 if ( jQuery.cache[ id ].handle ) {
2929 // Try/Catch is to handle iframes being unloaded, see #4280
2931 jQuery.event.remove( jQuery.cache[ id ].handle.elem );
2940 * Sizzle CSS Selector Engine - v1.0
2941 * Copyright 2009, The Dojo Foundation
2942 * Released under the MIT, BSD, and GPL Licenses.
2943 * More information: http://sizzlejs.com/
2947 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
2949 toString = Object.prototype.toString,
2950 hasDuplicate = false,
2951 baseHasDuplicate = true;
2953 // Here we check if the JavaScript engine is using some sort of
2954 // optimization where it does not always call our comparision
2955 // function. If that is the case, discard the hasDuplicate value.
2956 // Thus far that includes Google Chrome.
2957 [0, 0].sort(function(){
2958 baseHasDuplicate = false;
2962 var Sizzle = function(selector, context, results, seed) {
2963 results = results || [];
2964 context = context || document;
2966 var origContext = context;
2968 if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
2972 if ( !selector || typeof selector !== "string" ) {
2976 var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),
2977 soFar = selector, ret, cur, pop, i;
2979 // Reset the position of the chunker regexp (start from head)
2982 m = chunker.exec(soFar);
2996 if ( parts.length > 1 && origPOS.exec( selector ) ) {
2997 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
2998 set = posProcess( parts[0] + parts[1], context );
3000 set = Expr.relative[ parts[0] ] ?
3002 Sizzle( parts.shift(), context );
3004 while ( parts.length ) {
3005 selector = parts.shift();
3007 if ( Expr.relative[ selector ] ) {
3008 selector += parts.shift();
3011 set = posProcess( selector, set );
3015 // Take a shortcut and set the context if the root selector is an ID
3016 // (but not if it'll be faster if the inner selector is an ID)
3017 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3018 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3019 ret = Sizzle.find( parts.shift(), context, contextXML );
3020 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
3025 { expr: parts.pop(), set: makeArray(seed) } :
3026 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3027 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
3029 if ( parts.length > 0 ) {
3030 checkSet = makeArray(set);
3035 while ( parts.length ) {
3039 if ( !Expr.relative[ cur ] ) {
3045 if ( pop == null ) {
3049 Expr.relative[ cur ]( checkSet, pop, contextXML );
3052 checkSet = parts = [];
3061 Sizzle.error( cur || selector );
3064 if ( toString.call(checkSet) === "[object Array]" ) {
3066 results.push.apply( results, checkSet );
3067 } else if ( context && context.nodeType === 1 ) {
3068 for ( i = 0; checkSet[i] != null; i++ ) {
3069 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3070 results.push( set[i] );
3074 for ( i = 0; checkSet[i] != null; i++ ) {
3075 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3076 results.push( set[i] );
3081 makeArray( checkSet, results );
3085 Sizzle( extra, origContext, results, seed );
3086 Sizzle.uniqueSort( results );
3092 Sizzle.uniqueSort = function(results){
3094 hasDuplicate = baseHasDuplicate;
3095 results.sort(sortOrder);
3097 if ( hasDuplicate ) {
3098 for ( var i = 1; i < results.length; i++ ) {
3099 if ( results[i] === results[i-1] ) {
3100 results.splice(i--, 1);
3109 Sizzle.matches = function(expr, set){
3110 return Sizzle(expr, null, null, set);
3113 Sizzle.matchesSelector = function(node, expr){
3114 return Sizzle(expr, null, null, [node]).length > 0;
3117 Sizzle.find = function(expr, context, isXML){
3124 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3125 var type = Expr.order[i], match;
3127 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3128 var left = match[1];
3131 if ( left.substr( left.length - 1 ) !== "\\" ) {
3132 match[1] = (match[1] || "").replace(/\\/g, "");
3133 set = Expr.find[ type ]( match, context, isXML );
3134 if ( set != null ) {
3135 expr = expr.replace( Expr.match[ type ], "" );
3143 set = context.getElementsByTagName("*");
3146 return {set: set, expr: expr};
3149 Sizzle.filter = function(expr, set, inplace, not){
3150 var old = expr, result = [], curLoop = set, match, anyFound,
3151 isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
3153 while ( expr && set.length ) {
3154 for ( var type in Expr.filter ) {
3155 if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
3156 var filter = Expr.filter[ type ], found, item, left = match[1];
3161 if ( left.substr( left.length - 1 ) === "\\" ) {
3165 if ( curLoop === result ) {
3169 if ( Expr.preFilter[ type ] ) {
3170 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
3173 anyFound = found = true;
3174 } else if ( match === true ) {
3180 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
3182 found = filter( item, match, i, curLoop );
3183 var pass = not ^ !!found;
3185 if ( inplace && found != null ) {
3191 } else if ( pass ) {
3192 result.push( item );
3199 if ( found !== undefined ) {
3204 expr = expr.replace( Expr.match[ type ], "" );
3215 // Improper expression
3216 if ( expr === old ) {
3217 if ( anyFound == null ) {
3218 Sizzle.error( expr );
3230 Sizzle.error = function( msg ) {
3231 throw "Syntax error, unrecognized expression: " + msg;
3234 var Expr = Sizzle.selectors = {
3235 order: [ "ID", "NAME", "TAG" ],
3237 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3238 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
3239 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
3240 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
3241 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
3242 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
3243 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
3244 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
3248 "class": "className",
3252 href: function(elem){
3253 return elem.getAttribute("href");
3257 "+": function(checkSet, part){
3258 var isPartStr = typeof part === "string",
3259 isTag = isPartStr && !/\W/.test(part),
3260 isPartStrNotTag = isPartStr && !isTag;
3263 part = part.toLowerCase();
3266 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
3267 if ( (elem = checkSet[i]) ) {
3268 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
3270 checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
3276 if ( isPartStrNotTag ) {
3277 Sizzle.filter( part, checkSet, true );
3280 ">": function(checkSet, part){
3281 var isPartStr = typeof part === "string",
3282 elem, i = 0, l = checkSet.length;
3284 if ( isPartStr && !/\W/.test(part) ) {
3285 part = part.toLowerCase();
3287 for ( ; i < l; i++ ) {
3290 var parent = elem.parentNode;
3291 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
3295 for ( ; i < l; i++ ) {
3298 checkSet[i] = isPartStr ?
3300 elem.parentNode === part;
3305 Sizzle.filter( part, checkSet, true );
3309 "": function(checkSet, part, isXML){
3310 var doneName = done++, checkFn = dirCheck, nodeCheck;
3312 if ( typeof part === "string" && !/\W/.test(part) ) {
3313 part = part.toLowerCase();
3315 checkFn = dirNodeCheck;
3318 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
3320 "~": function(checkSet, part, isXML){
3321 var doneName = done++, checkFn = dirCheck, nodeCheck;
3323 if ( typeof part === "string" && !/\W/.test(part) ) {
3324 part = part.toLowerCase();
3326 checkFn = dirNodeCheck;
3329 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
3333 ID: function(match, context, isXML){
3334 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3335 var m = context.getElementById(match[1]);
3336 // Check parentNode to catch when Blackberry 4.6 returns
3337 // nodes that are no longer in the document #6963
3338 return m && m.parentNode ? [m] : [];
3341 NAME: function(match, context){
3342 if ( typeof context.getElementsByName !== "undefined" ) {
3343 var ret = [], results = context.getElementsByName(match[1]);
3345 for ( var i = 0, l = results.length; i < l; i++ ) {
3346 if ( results[i].getAttribute("name") === match[1] ) {
3347 ret.push( results[i] );
3351 return ret.length === 0 ? null : ret;
3354 TAG: function(match, context){
3355 return context.getElementsByTagName(match[1]);
3359 CLASS: function(match, curLoop, inplace, result, not, isXML){
3360 match = " " + match[1].replace(/\\/g, "") + " ";
3366 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
3368 if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
3370 result.push( elem );
3372 } else if ( inplace ) {
3380 ID: function(match){
3381 return match[1].replace(/\\/g, "");
3383 TAG: function(match, curLoop){
3384 return match[1].toLowerCase();
3386 CHILD: function(match){
3387 if ( match[1] === "nth" ) {
3388 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
3389 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
3390 match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
3391 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
3393 // calculate the numbers (first)n+(last) including if they are negative
3394 match[2] = (test[1] + (test[2] || 1)) - 0;
3395 match[3] = test[3] - 0;
3398 // TODO: Move to normal caching system
3403 ATTR: function(match, curLoop, inplace, result, not, isXML){
3404 var name = match[1].replace(/\\/g, "");
3406 if ( !isXML && Expr.attrMap[name] ) {
3407 match[1] = Expr.attrMap[name];
3410 if ( match[2] === "~=" ) {
3411 match[4] = " " + match[4] + " ";
3416 PSEUDO: function(match, curLoop, inplace, result, not){
3417 if ( match[1] === "not" ) {
3418 // If we're dealing with a complex expression, or a simple one
3419 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
3420 match[3] = Sizzle(match[3], null, null, curLoop);
3422 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
3424 result.push.apply( result, ret );
3428 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
3434 POS: function(match){
3435 match.unshift( true );
3440 enabled: function(elem){
3441 return elem.disabled === false && elem.type !== "hidden";
3443 disabled: function(elem){
3444 return elem.disabled === true;
3446 checked: function(elem){
3447 return elem.checked === true;
3449 selected: function(elem){
3450 // Accessing this property makes selected-by-default
3451 // options in Safari work properly
3452 elem.parentNode.selectedIndex;
3453 return elem.selected === true;
3455 parent: function(elem){
3456 return !!elem.firstChild;
3458 empty: function(elem){
3459 return !elem.firstChild;
3461 has: function(elem, i, match){
3462 return !!Sizzle( match[3], elem ).length;
3464 header: function(elem){
3465 return (/h\d/i).test( elem.nodeName );
3467 text: function(elem){
3468 return "text" === elem.type;
3470 radio: function(elem){
3471 return "radio" === elem.type;
3473 checkbox: function(elem){
3474 return "checkbox" === elem.type;
3476 file: function(elem){
3477 return "file" === elem.type;
3479 password: function(elem){
3480 return "password" === elem.type;
3482 submit: function(elem){
3483 return "submit" === elem.type;
3485 image: function(elem){
3486 return "image" === elem.type;
3488 reset: function(elem){
3489 return "reset" === elem.type;
3491 button: function(elem){
3492 return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
3494 input: function(elem){
3495 return (/input|select|textarea|button/i).test(elem.nodeName);
3499 first: function(elem, i){
3502 last: function(elem, i, match, array){
3503 return i === array.length - 1;
3505 even: function(elem, i){
3508 odd: function(elem, i){
3511 lt: function(elem, i, match){
3512 return i < match[3] - 0;
3514 gt: function(elem, i, match){
3515 return i > match[3] - 0;
3517 nth: function(elem, i, match){
3518 return match[3] - 0 === i;
3520 eq: function(elem, i, match){
3521 return match[3] - 0 === i;
3525 PSEUDO: function(elem, match, i, array){
3526 var name = match[1], filter = Expr.filters[ name ];
3529 return filter( elem, i, match, array );
3530 } else if ( name === "contains" ) {
3531 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
3532 } else if ( name === "not" ) {
3535 for ( var j = 0, l = not.length; j < l; j++ ) {
3536 if ( not[j] === elem ) {
3543 Sizzle.error( "Syntax error, unrecognized expression: " + name );
3546 CHILD: function(elem, match){
3547 var type = match[1], node = elem;
3551 while ( (node = node.previousSibling) ) {
3552 if ( node.nodeType === 1 ) {
3556 if ( type === "first" ) {
3561 while ( (node = node.nextSibling) ) {
3562 if ( node.nodeType === 1 ) {
3568 var first = match[2], last = match[3];
3570 if ( first === 1 && last === 0 ) {
3574 var doneName = match[0],
3575 parent = elem.parentNode;
3577 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
3579 for ( node = parent.firstChild; node; node = node.nextSibling ) {
3580 if ( node.nodeType === 1 ) {
3581 node.nodeIndex = ++count;
3584 parent.sizcache = doneName;
3587 var diff = elem.nodeIndex - last;
3588 if ( first === 0 ) {
3591 return ( diff % first === 0 && diff / first >= 0 );
3595 ID: function(elem, match){
3596 return elem.nodeType === 1 && elem.getAttribute("id") === match;
3598 TAG: function(elem, match){
3599 return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
3601 CLASS: function(elem, match){
3602 return (" " + (elem.className || elem.getAttribute("class")) + " ")
3603 .indexOf( match ) > -1;
3605 ATTR: function(elem, match){
3606 var name = match[1],
3607 result = Expr.attrHandle[ name ] ?
3608 Expr.attrHandle[ name ]( elem ) :
3609 elem[ name ] != null ?
3611 elem.getAttribute( name ),
3612 value = result + "",
3616 return result == null ?
3621 value.indexOf(check) >= 0 :
3623 (" " + value + " ").indexOf(check) >= 0 :
3625 value && result !== false :
3629 value.indexOf(check) === 0 :
3631 value.substr(value.length - check.length) === check :
3633 value === check || value.substr(0, check.length + 1) === check + "-" :
3636 POS: function(elem, match, i, array){
3637 var name = match[2], filter = Expr.setFilters[ name ];
3640 return filter( elem, i, match, array );
3646 var origPOS = Expr.match.POS,
3647 fescape = function(all, num){
3648 return "\\" + (num - 0 + 1);
3651 for ( var type in Expr.match ) {
3652 Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
3653 Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
3656 var makeArray = function(array, results) {
3657 array = Array.prototype.slice.call( array, 0 );
3660 results.push.apply( results, array );
3667 // Perform a simple check to determine if the browser is capable of
3668 // converting a NodeList to an array using builtin methods.
3669 // Also verifies that the returned array holds DOM nodes
3670 // (which is not the case in the Blackberry browser)
3672 Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
3674 // Provide a fallback method if it does not work
3676 makeArray = function(array, results) {
3677 var ret = results || [], i = 0;
3679 if ( toString.call(array) === "[object Array]" ) {
3680 Array.prototype.push.apply( ret, array );
3682 if ( typeof array.length === "number" ) {
3683 for ( var l = array.length; i < l; i++ ) {
3684 ret.push( array[i] );
3687 for ( ; array[i]; i++ ) {
3688 ret.push( array[i] );
3697 var sortOrder, siblingCheck;
3699 if ( document.documentElement.compareDocumentPosition ) {
3700 sortOrder = function( a, b ) {
3702 hasDuplicate = true;
3706 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
3707 return a.compareDocumentPosition ? -1 : 1;
3710 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
3713 sortOrder = function( a, b ) {
3714 var ap = [], bp = [], aup = a.parentNode, bup = b.parentNode,
3717 // The nodes are identical, we can exit early
3719 hasDuplicate = true;
3722 // If the nodes are siblings (or identical) we can do a quick check
3723 } else if ( aup === bup ) {
3724 return siblingCheck( a, b );
3726 // If no parents were found then the nodes are disconnected
3727 } else if ( !aup ) {
3730 } else if ( !bup ) {
3734 // Otherwise they're somewhere else in the tree so we need
3735 // to build up a full list of the parentNodes for comparison
3738 cur = cur.parentNode;
3745 cur = cur.parentNode;
3751 // Start walking down the tree looking for a discrepancy
3752 for ( var i = 0; i < al && i < bl; i++ ) {
3753 if ( ap[i] !== bp[i] ) {
3754 return siblingCheck( ap[i], bp[i] );
3758 // We ended someplace up the tree so do a sibling check
3760 siblingCheck( a, bp[i], -1 ) :
3761 siblingCheck( ap[i], b, 1 );
3764 siblingCheck = function( a, b, ret ) {
3769 var cur = a.nextSibling;
3776 cur = cur.nextSibling;
3783 // Utility function for retreiving the text value of an array of DOM nodes
3784 Sizzle.getText = function( elems ) {
3787 for ( var i = 0; elems[i]; i++ ) {
3790 // Get the text from text nodes and CDATA nodes
3791 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
3792 ret += elem.nodeValue;
3794 // Traverse everything else, except comment nodes
3795 } else if ( elem.nodeType !== 8 ) {
3796 ret += Sizzle.getText( elem.childNodes );
3803 // Check to see if the browser returns elements by name when
3804 // querying by getElementById (and provide a workaround)
3806 // We're going to inject a fake input element with a specified name
3807 var form = document.createElement("div"),
3808 id = "script" + (new Date()).getTime();
3809 form.innerHTML = "<a name='" + id + "'/>";
3811 // Inject it into the root element, check its status, and remove it quickly
3812 var root = document.documentElement;
3813 root.insertBefore( form, root.firstChild );
3815 // The workaround has to do additional checks after a getElementById
3816 // Which slows things down for other browsers (hence the branching)
3817 if ( document.getElementById( id ) ) {
3818 Expr.find.ID = function(match, context, isXML){
3819 if ( typeof context.getElementById !== "undefined" && !isXML ) {
3820 var m = context.getElementById(match[1]);
3821 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
3825 Expr.filter.ID = function(elem, match){
3826 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
3827 return elem.nodeType === 1 && node && node.nodeValue === match;
3831 root.removeChild( form );
3832 root = form = null; // release memory in IE
3836 // Check to see if the browser returns only elements
3837 // when doing getElementsByTagName("*")
3839 // Create a fake element
3840 var div = document.createElement("div");
3841 div.appendChild( document.createComment("") );
3843 // Make sure no comments are found
3844 if ( div.getElementsByTagName("*").length > 0 ) {
3845 Expr.find.TAG = function(match, context){
3846 var results = context.getElementsByTagName(match[1]);
3848 // Filter out possible comments
3849 if ( match[1] === "*" ) {
3852 for ( var i = 0; results[i]; i++ ) {
3853 if ( results[i].nodeType === 1 ) {
3854 tmp.push( results[i] );
3865 // Check to see if an attribute returns normalized href attributes
3866 div.innerHTML = "<a href='#'></a>";
3867 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
3868 div.firstChild.getAttribute("href") !== "#" ) {
3869 Expr.attrHandle.href = function(elem){
3870 return elem.getAttribute("href", 2);
3874 div = null; // release memory in IE
3877 if ( document.querySelectorAll ) {
3879 var oldSizzle = Sizzle, div = document.createElement("div");
3880 div.innerHTML = "<p class='TEST'></p>";
3882 // Safari can't handle uppercase or unicode characters when
3884 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
3888 Sizzle = function(query, context, extra, seed){
3889 context = context || document;
3891 // Only use querySelectorAll on non-XML documents
3892 // (ID selectors don't work in non-HTML documents)
3893 if ( !seed && !Sizzle.isXML(context) ) {
3894 if ( context.nodeType === 9 ) {
3896 return makeArray( context.querySelectorAll(query), extra );
3897 } catch(qsaError) {}
3899 // qSA works strangely on Element-rooted queries
3900 // We can work around this by specifying an extra ID on the root
3901 // and working up from there (Thanks to Andrew Dupont for the technique)
3902 // IE 8 doesn't work on object elements
3903 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
3904 var old = context.id, id = context.id = "__sizzle__";
3907 return makeArray( context.querySelectorAll( "#" + id + " " + query ), extra );
3909 } catch(pseudoError) {
3915 context.removeAttribute( "id" );
3921 return oldSizzle(query, context, extra, seed);
3924 for ( var prop in oldSizzle ) {
3925 Sizzle[ prop ] = oldSizzle[ prop ];
3928 div = null; // release memory in IE
3933 var html = document.documentElement,
3934 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
3935 pseudoWorks = false;
3938 // This should fail with an exception
3939 // Gecko does not error, returns false instead
3940 matches.call( document.documentElement, ":sizzle" );
3942 } catch( pseudoError ) {
3947 Sizzle.matchesSelector = function( node, expr ) {
3949 if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) ) {
3950 return matches.call( node, expr );
3954 return Sizzle(expr, null, null, [node]).length > 0;
3960 var div = document.createElement("div");
3962 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
3964 // Opera can't find a second classname (in 9.6)
3965 // Also, make sure that getElementsByClassName actually exists
3966 if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
3970 // Safari caches class attributes, doesn't catch changes (in 3.2)
3971 div.lastChild.className = "e";
3973 if ( div.getElementsByClassName("e").length === 1 ) {
3977 Expr.order.splice(1, 0, "CLASS");
3978 Expr.find.CLASS = function(match, context, isXML) {
3979 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
3980 return context.getElementsByClassName(match[1]);
3984 div = null; // release memory in IE
3987 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
3988 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
3989 var elem = checkSet[i];
3995 if ( elem.sizcache === doneName ) {
3996 match = checkSet[elem.sizset];
4000 if ( elem.nodeType === 1 && !isXML ){
4001 elem.sizcache = doneName;
4005 if ( elem.nodeName.toLowerCase() === cur ) {
4013 checkSet[i] = match;
4018 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4019 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4020 var elem = checkSet[i];
4026 if ( elem.sizcache === doneName ) {
4027 match = checkSet[elem.sizset];
4031 if ( elem.nodeType === 1 ) {
4033 elem.sizcache = doneName;
4036 if ( typeof cur !== "string" ) {
4037 if ( elem === cur ) {
4042 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4051 checkSet[i] = match;
4056 Sizzle.contains = document.documentElement.contains ? function(a, b){
4057 return a !== b && (a.contains ? a.contains(b) : true);
4059 return !!(a.compareDocumentPosition(b) & 16);
4062 Sizzle.isXML = function(elem){
4063 // documentElement is verified for cases where it doesn't yet exist
4064 // (such as loading iframes in IE - #4833)
4065 var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
4066 return documentElement ? documentElement.nodeName !== "HTML" : false;
4069 var posProcess = function(selector, context){
4070 var tmpSet = [], later = "", match,
4071 root = context.nodeType ? [context] : context;
4073 // Position selectors must be done after the filter
4074 // And so must :not(positional) so we move all PSEUDOs to the end
4075 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4077 selector = selector.replace( Expr.match.PSEUDO, "" );
4080 selector = Expr.relative[selector] ? selector + "*" : selector;
4082 for ( var i = 0, l = root.length; i < l; i++ ) {
4083 Sizzle( selector, root[i], tmpSet );
4086 return Sizzle.filter( later, tmpSet );
4090 jQuery.find = Sizzle;
4091 jQuery.expr = Sizzle.selectors;
4092 jQuery.expr[":"] = jQuery.expr.filters;
4093 jQuery.unique = Sizzle.uniqueSort;
4094 jQuery.text = Sizzle.getText;
4095 jQuery.isXMLDoc = Sizzle.isXML;
4096 jQuery.contains = Sizzle.contains;
4102 var runtil = /Until$/,
4103 rparentsprev = /^(?:parents|prevUntil|prevAll)/,
4104 // Note: This RegExp should be improved, or likely pulled from Sizzle
4105 rmultiselector = /,/,
4106 isSimple = /^.[^:#\[\.,]*$/,
4107 slice = Array.prototype.slice,
4108 POS = jQuery.expr.match.POS;
4111 find: function( selector ) {
4112 var ret = this.pushStack( "", "find", selector ), length = 0;
4114 for ( var i = 0, l = this.length; i < l; i++ ) {
4115 length = ret.length;
4116 jQuery.find( selector, this[i], ret );
4119 // Make sure that the results are unique
4120 for ( var n = length; n < ret.length; n++ ) {
4121 for ( var r = 0; r < length; r++ ) {
4122 if ( ret[r] === ret[n] ) {
4134 has: function( target ) {
4135 var targets = jQuery( target );
4136 return this.filter(function() {
4137 for ( var i = 0, l = targets.length; i < l; i++ ) {
4138 if ( jQuery.contains( this, targets[i] ) ) {
4145 not: function( selector ) {
4146 return this.pushStack( winnow(this, selector, false), "not", selector);
4149 filter: function( selector ) {
4150 return this.pushStack( winnow(this, selector, true), "filter", selector );
4153 is: function( selector ) {
4154 return !!selector && jQuery.filter( selector, this ).length > 0;
4157 closest: function( selectors, context ) {
4158 var ret = [], i, l, cur = this[0];
4160 if ( jQuery.isArray( selectors ) ) {
4161 var match, matches = {}, selector, level = 1;
4163 if ( cur && selectors.length ) {
4164 for ( i = 0, l = selectors.length; i < l; i++ ) {
4165 selector = selectors[i];
4167 if ( !matches[selector] ) {
4168 matches[selector] = jQuery.expr.match.POS.test( selector ) ?
4169 jQuery( selector, context || this.context ) :
4174 while ( cur && cur.ownerDocument && cur !== context ) {
4175 for ( selector in matches ) {
4176 match = matches[selector];
4178 if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
4179 ret.push({ selector: selector, elem: cur, level: level });
4183 cur = cur.parentNode;
4191 var pos = POS.test( selectors ) ?
4192 jQuery( selectors, context || this.context ) : null;
4194 for ( i = 0, l = this.length; i < l; i++ ) {
4198 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
4203 cur = cur.parentNode;
4204 if ( !cur || !cur.ownerDocument || cur === context ) {
4211 ret = ret.length > 1 ? jQuery.unique(ret) : ret;
4213 return this.pushStack( ret, "closest", selectors );
4216 // Determine the position of an element within
4217 // the matched set of elements
4218 index: function( elem ) {
4219 if ( !elem || typeof elem === "string" ) {
4220 return jQuery.inArray( this[0],
4221 // If it receives a string, the selector is used
4222 // If it receives nothing, the siblings are used
4223 elem ? jQuery( elem ) : this.parent().children() );
4225 // Locate the position of the desired element
4226 return jQuery.inArray(
4227 // If it receives a jQuery object, the first element is used
4228 elem.jquery ? elem[0] : elem, this );
4231 add: function( selector, context ) {
4232 var set = typeof selector === "string" ?
4233 jQuery( selector, context || this.context ) :
4234 jQuery.makeArray( selector ),
4235 all = jQuery.merge( this.get(), set );
4237 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
4239 jQuery.unique( all ) );
4242 andSelf: function() {
4243 return this.add( this.prevObject );
4247 // A painfully simple check to see if an element is disconnected
4248 // from a document (should be improved, where feasible).
4249 function isDisconnected( node ) {
4250 return !node || !node.parentNode || node.parentNode.nodeType === 11;
4254 parent: function( elem ) {
4255 var parent = elem.parentNode;
4256 return parent && parent.nodeType !== 11 ? parent : null;
4258 parents: function( elem ) {
4259 return jQuery.dir( elem, "parentNode" );
4261 parentsUntil: function( elem, i, until ) {
4262 return jQuery.dir( elem, "parentNode", until );
4264 next: function( elem ) {
4265 return jQuery.nth( elem, 2, "nextSibling" );
4267 prev: function( elem ) {
4268 return jQuery.nth( elem, 2, "previousSibling" );
4270 nextAll: function( elem ) {
4271 return jQuery.dir( elem, "nextSibling" );
4273 prevAll: function( elem ) {
4274 return jQuery.dir( elem, "previousSibling" );
4276 nextUntil: function( elem, i, until ) {
4277 return jQuery.dir( elem, "nextSibling", until );
4279 prevUntil: function( elem, i, until ) {
4280 return jQuery.dir( elem, "previousSibling", until );
4282 siblings: function( elem ) {
4283 return jQuery.sibling( elem.parentNode.firstChild, elem );
4285 children: function( elem ) {
4286 return jQuery.sibling( elem.firstChild );
4288 contents: function( elem ) {
4289 return jQuery.nodeName( elem, "iframe" ) ?
4290 elem.contentDocument || elem.contentWindow.document :
4291 jQuery.makeArray( elem.childNodes );
4293 }, function( name, fn ) {
4294 jQuery.fn[ name ] = function( until, selector ) {
4295 var ret = jQuery.map( this, fn, until );
4297 if ( !runtil.test( name ) ) {
4301 if ( selector && typeof selector === "string" ) {
4302 ret = jQuery.filter( selector, ret );
4305 ret = this.length > 1 ? jQuery.unique( ret ) : ret;
4307 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
4308 ret = ret.reverse();
4311 return this.pushStack( ret, name, slice.call(arguments).join(",") );
4316 filter: function( expr, elems, not ) {
4318 expr = ":not(" + expr + ")";
4321 return elems.length === 1 ?
4322 jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
4323 jQuery.find.matches(expr, elems);
4326 dir: function( elem, dir, until ) {
4327 var matched = [], cur = elem[dir];
4328 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
4329 if ( cur.nodeType === 1 ) {
4330 matched.push( cur );
4337 nth: function( cur, result, dir, elem ) {
4338 result = result || 1;
4341 for ( ; cur; cur = cur[dir] ) {
4342 if ( cur.nodeType === 1 && ++num === result ) {
4350 sibling: function( n, elem ) {
4353 for ( ; n; n = n.nextSibling ) {
4354 if ( n.nodeType === 1 && n !== elem ) {
4363 // Implement the identical functionality for filter and not
4364 function winnow( elements, qualifier, keep ) {
4365 if ( jQuery.isFunction( qualifier ) ) {
4366 return jQuery.grep(elements, function( elem, i ) {
4367 var retVal = !!qualifier.call( elem, i, elem );
4368 return retVal === keep;
4371 } else if ( qualifier.nodeType ) {
4372 return jQuery.grep(elements, function( elem, i ) {
4373 return (elem === qualifier) === keep;
4376 } else if ( typeof qualifier === "string" ) {
4377 var filtered = jQuery.grep(elements, function( elem ) {
4378 return elem.nodeType === 1;
4381 if ( isSimple.test( qualifier ) ) {
4382 return jQuery.filter(qualifier, filtered, !keep);
4384 qualifier = jQuery.filter( qualifier, filtered );
4388 return jQuery.grep(elements, function( elem, i ) {
4389 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
4396 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
4397 rleadingWhitespace = /^\s+/,
4398 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
4399 rtagName = /<([\w:]+)/,
4401 rhtml = /<|&#?\w+;/,
4402 rnocache = /<(?:script|object|embed|option|style)/i,
4403 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
4404 raction = /\=([^="'>\s]+\/)>/g,
4406 option: [ 1, "<select multiple='multiple'>", "</select>" ],
4407 legend: [ 1, "<fieldset>", "</fieldset>" ],
4408 thead: [ 1, "<table>", "</table>" ],
4409 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4410 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4411 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4412 area: [ 1, "<map>", "</map>" ],
4413 _default: [ 0, "", "" ]
4416 wrapMap.optgroup = wrapMap.option;
4417 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4418 wrapMap.th = wrapMap.td;
4420 // IE can't serialize <link> and <script> tags normally
4421 if ( !jQuery.support.htmlSerialize ) {
4422 wrapMap._default = [ 1, "div<div>", "</div>" ];
4426 text: function( text ) {
4427 if ( jQuery.isFunction(text) ) {
4428 return this.each(function(i) {
4429 var self = jQuery(this);
4430 self.text( text.call(this, i, self.text()) );
4434 if ( typeof text !== "object" && text !== undefined ) {
4435 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
4438 return jQuery.text( this );
4441 wrapAll: function( html ) {
4442 if ( jQuery.isFunction( html ) ) {
4443 return this.each(function(i) {
4444 jQuery(this).wrapAll( html.call(this, i) );
4449 // The elements to wrap the target around
4450 var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
4452 if ( this[0].parentNode ) {
4453 wrap.insertBefore( this[0] );
4456 wrap.map(function() {
4459 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
4460 elem = elem.firstChild;
4470 wrapInner: function( html ) {
4471 if ( jQuery.isFunction( html ) ) {
4472 return this.each(function(i) {
4473 jQuery(this).wrapInner( html.call(this, i) );
4477 return this.each(function() {
4478 var self = jQuery( this ), contents = self.contents();
4480 if ( contents.length ) {
4481 contents.wrapAll( html );
4484 self.append( html );
4489 wrap: function( html ) {
4490 return this.each(function() {
4491 jQuery( this ).wrapAll( html );
4495 unwrap: function() {
4496 return this.parent().each(function() {
4497 if ( !jQuery.nodeName( this, "body" ) ) {
4498 jQuery( this ).replaceWith( this.childNodes );
4503 append: function() {
4504 return this.domManip(arguments, true, function( elem ) {
4505 if ( this.nodeType === 1 ) {
4506 this.appendChild( elem );
4511 prepend: function() {
4512 return this.domManip(arguments, true, function( elem ) {
4513 if ( this.nodeType === 1 ) {
4514 this.insertBefore( elem, this.firstChild );
4519 before: function() {
4520 if ( this[0] && this[0].parentNode ) {
4521 return this.domManip(arguments, false, function( elem ) {
4522 this.parentNode.insertBefore( elem, this );
4524 } else if ( arguments.length ) {
4525 var set = jQuery(arguments[0]);
4526 set.push.apply( set, this.toArray() );
4527 return this.pushStack( set, "before", arguments );
4532 if ( this[0] && this[0].parentNode ) {
4533 return this.domManip(arguments, false, function( elem ) {
4534 this.parentNode.insertBefore( elem, this.nextSibling );
4536 } else if ( arguments.length ) {
4537 var set = this.pushStack( this, "after", arguments );
4538 set.push.apply( set, jQuery(arguments[0]).toArray() );
4543 // keepData is for internal use only--do not document
4544 remove: function( selector, keepData ) {
4545 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4546 if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
4547 if ( !keepData && elem.nodeType === 1 ) {
4548 jQuery.cleanData( elem.getElementsByTagName("*") );
4549 jQuery.cleanData( [ elem ] );
4552 if ( elem.parentNode ) {
4553 elem.parentNode.removeChild( elem );
4562 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
4563 // Remove element nodes and prevent memory leaks
4564 if ( elem.nodeType === 1 ) {
4565 jQuery.cleanData( elem.getElementsByTagName("*") );
4568 // Remove any remaining nodes
4569 while ( elem.firstChild ) {
4570 elem.removeChild( elem.firstChild );
4577 clone: function( events ) {
4579 var ret = this.map(function() {
4580 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
4581 // IE copies events bound via attachEvent when
4582 // using cloneNode. Calling detachEvent on the
4583 // clone will also remove the events from the orignal
4584 // In order to get around this, we use innerHTML.
4585 // Unfortunately, this means some modifications to
4586 // attributes in IE that are actually only stored
4587 // as properties will not be copied (such as the
4588 // the name attribute on an input).
4589 var html = this.outerHTML, ownerDocument = this.ownerDocument;
4591 var div = ownerDocument.createElement("div");
4592 div.appendChild( this.cloneNode(true) );
4593 html = div.innerHTML;
4596 return jQuery.clean([html.replace(rinlinejQuery, "")
4597 // Handle the case in IE 8 where action=/test/> self-closes a tag
4598 .replace(raction, '="$1">')
4599 .replace(rleadingWhitespace, "")], ownerDocument)[0];
4601 return this.cloneNode(true);
4605 // Copy the events from the original to the clone
4606 if ( events === true ) {
4607 cloneCopyEvent( this, ret );
4608 cloneCopyEvent( this.find("*"), ret.find("*") );
4611 // Return the cloned set
4615 html: function( value ) {
4616 if ( value === undefined ) {
4617 return this[0] && this[0].nodeType === 1 ?
4618 this[0].innerHTML.replace(rinlinejQuery, "") :
4621 // See if we can take a shortcut and just use innerHTML
4622 } else if ( typeof value === "string" && !rnocache.test( value ) &&
4623 (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
4624 !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
4626 value = value.replace(rxhtmlTag, "<$1></$2>");
4629 for ( var i = 0, l = this.length; i < l; i++ ) {
4630 // Remove element nodes and prevent memory leaks
4631 if ( this[i].nodeType === 1 ) {
4632 jQuery.cleanData( this[i].getElementsByTagName("*") );
4633 this[i].innerHTML = value;
4637 // If using innerHTML throws an exception, use the fallback method
4639 this.empty().append( value );
4642 } else if ( jQuery.isFunction( value ) ) {
4643 this.each(function(i){
4644 var self = jQuery(this);
4645 self.html( value.call(this, i, self.html()) );
4649 this.empty().append( value );
4655 replaceWith: function( value ) {
4656 if ( this[0] && this[0].parentNode ) {
4657 // Make sure that the elements are removed from the DOM before they are inserted
4658 // this can help fix replacing a parent with child elements
4659 if ( jQuery.isFunction( value ) ) {
4660 return this.each(function(i) {
4661 var self = jQuery(this), old = self.html();
4662 self.replaceWith( value.call( this, i, old ) );
4666 if ( typeof value !== "string" ) {
4667 value = jQuery(value).detach();
4670 return this.each(function() {
4671 var next = this.nextSibling, parent = this.parentNode;
4673 jQuery(this).remove();
4676 jQuery(next).before( value );
4678 jQuery(parent).append( value );
4682 return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
4686 detach: function( selector ) {
4687 return this.remove( selector, true );
4690 domManip: function( args, table, callback ) {
4691 var results, first, value = args[0], scripts = [], fragment, parent;
4693 // We can't cloneNode fragments that contain checked, in WebKit
4694 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
4695 return this.each(function() {
4696 jQuery(this).domManip( args, table, callback, true );
4700 if ( jQuery.isFunction(value) ) {
4701 return this.each(function(i) {
4702 var self = jQuery(this);
4703 args[0] = value.call(this, i, table ? self.html() : undefined);
4704 self.domManip( args, table, callback );
4709 parent = value && value.parentNode;
4711 // If we're in a fragment, just use that instead of building a new one
4712 if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
4713 results = { fragment: parent };
4716 results = jQuery.buildFragment( args, this, scripts );
4719 fragment = results.fragment;
4721 if ( fragment.childNodes.length === 1 ) {
4722 first = fragment = fragment.firstChild;
4724 first = fragment.firstChild;
4728 table = table && jQuery.nodeName( first, "tr" );
4730 for ( var i = 0, l = this.length; i < l; i++ ) {
4733 root(this[i], first) :
4735 i > 0 || results.cacheable || this.length > 1 ?
4736 fragment.cloneNode(true) :
4742 if ( scripts.length ) {
4743 jQuery.each( scripts, evalScript );
4751 function root( elem, cur ) {
4752 return jQuery.nodeName(elem, "table") ?
4753 (elem.getElementsByTagName("tbody")[0] ||
4754 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
4758 function cloneCopyEvent(orig, ret) {
4761 ret.each(function() {
4762 if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
4766 var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
4769 delete curData.handle;
4770 curData.events = {};
4772 for ( var type in events ) {
4773 for ( var handler in events[ type ] ) {
4774 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
4781 jQuery.buildFragment = function( args, nodes, scripts ) {
4782 var fragment, cacheable, cacheresults,
4783 doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
4785 // Only cache "small" (1/2 KB) strings that are associated with the main document
4786 // Cloning options loses the selected state, so don't cache them
4787 // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
4788 // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
4789 if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
4790 !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
4793 cacheresults = jQuery.fragments[ args[0] ];
4794 if ( cacheresults ) {
4795 if ( cacheresults !== 1 ) {
4796 fragment = cacheresults;
4802 fragment = doc.createDocumentFragment();
4803 jQuery.clean( args, doc, fragment, scripts );
4807 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
4810 return { fragment: fragment, cacheable: cacheable };
4813 jQuery.fragments = {};
4817 prependTo: "prepend",
4818 insertBefore: "before",
4819 insertAfter: "after",
4820 replaceAll: "replaceWith"
4821 }, function( name, original ) {
4822 jQuery.fn[ name ] = function( selector ) {
4823 var ret = [], insert = jQuery( selector ),
4824 parent = this.length === 1 && this[0].parentNode;
4826 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
4827 insert[ original ]( this[0] );
4831 for ( var i = 0, l = insert.length; i < l; i++ ) {
4832 var elems = (i > 0 ? this.clone(true) : this).get();
4833 jQuery( insert[i] )[ original ]( elems );
4834 ret = ret.concat( elems );
4837 return this.pushStack( ret, name, insert.selector );
4843 clean: function( elems, context, fragment, scripts ) {
4844 context = context || document;
4846 // !context.createElement fails in IE with an error but returns typeof 'object'
4847 if ( typeof context.createElement === "undefined" ) {
4848 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
4853 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
4854 if ( typeof elem === "number" ) {
4862 // Convert html string into DOM nodes
4863 if ( typeof elem === "string" && !rhtml.test( elem ) ) {
4864 elem = context.createTextNode( elem );
4866 } else if ( typeof elem === "string" ) {
4867 // Fix "XHTML"-style tags in all browsers
4868 elem = elem.replace(rxhtmlTag, "<$1></$2>");
4870 // Trim whitespace, otherwise indexOf won't work as expected
4871 var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
4872 wrap = wrapMap[ tag ] || wrapMap._default,
4874 div = context.createElement("div");
4876 // Go to html and back, then peel off extra wrappers
4877 div.innerHTML = wrap[1] + elem + wrap[2];
4879 // Move to the right depth
4881 div = div.lastChild;
4884 // Remove IE's autoinserted <tbody> from table fragments
4885 if ( !jQuery.support.tbody ) {
4887 // String was a <table>, *may* have spurious <tbody>
4888 var hasBody = rtbody.test(elem),
4889 tbody = tag === "table" && !hasBody ?
4890 div.firstChild && div.firstChild.childNodes :
4892 // String was a bare <thead> or <tfoot>
4893 wrap[1] === "<table>" && !hasBody ?
4897 for ( var j = tbody.length - 1; j >= 0 ; --j ) {
4898 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
4899 tbody[ j ].parentNode.removeChild( tbody[ j ] );
4905 // IE completely kills leading whitespace when innerHTML is used
4906 if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4907 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
4910 elem = div.childNodes;
4913 if ( elem.nodeType ) {
4916 ret = jQuery.merge( ret, elem );
4921 for ( i = 0; ret[i]; i++ ) {
4922 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
4923 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
4926 if ( ret[i].nodeType === 1 ) {
4927 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
4929 fragment.appendChild( ret[i] );
4937 cleanData: function( elems ) {
4938 var data, id, cache = jQuery.cache,
4939 special = jQuery.event.special,
4940 deleteExpando = jQuery.support.deleteExpando;
4942 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
4943 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
4947 id = elem[ jQuery.expando ];
4952 if ( data && data.events ) {
4953 for ( var type in data.events ) {
4954 if ( special[ type ] ) {
4955 jQuery.event.remove( elem, type );
4958 jQuery.removeEvent( elem, type, data.handle );
4963 if ( deleteExpando ) {
4964 delete elem[ jQuery.expando ];
4966 } else if ( elem.removeAttribute ) {
4967 elem.removeAttribute( jQuery.expando );
4976 function evalScript( i, elem ) {
4984 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
4987 if ( elem.parentNode ) {
4988 elem.parentNode.removeChild( elem );
4995 var ralpha = /alpha\([^)]*\)/i,
4996 ropacity = /opacity=([^)]*)/,
4997 rdashAlpha = /-([a-z])/ig,
4998 rupper = /([A-Z])/g,
4999 rnumpx = /^-?\d+(?:px)?$/i,
5002 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5003 cssWidth = [ "Left", "Right" ],
5004 cssHeight = [ "Top", "Bottom" ],
5007 // cache check for defaultView.getComputedStyle
5008 getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
5010 fcamelCase = function( all, letter ) {
5011 return letter.toUpperCase();
5014 jQuery.fn.css = function( name, value ) {
5015 // Setting 'undefined' is a no-op
5016 if ( arguments.length === 2 && value === undefined ) {
5020 return jQuery.access( this, name, value, true, function( elem, name, value ) {
5021 return value !== undefined ?
5022 jQuery.style( elem, name, value ) :
5023 jQuery.css( elem, name );
5028 // Add in style property hooks for overriding the default
5029 // behavior of getting and setting a style property
5032 get: function( elem, computed ) {
5034 // We should always get a number back from opacity
5035 var ret = curCSS( elem, "opacity", "opacity" );
5036 return ret === "" ? "1" : ret;
5039 return elem.style.opacity;
5045 // Exclude the following css properties to add px
5054 // Add in properties whose names you wish to fix before
5055 // setting or getting the value
5057 // normalize float css property
5058 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
5061 // Get and set the style property on a DOM Node
5062 style: function( elem, name, value, extra ) {
5063 // Don't set styles on text and comment nodes
5064 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5068 // Make sure that we're working with the right name
5069 var ret, origName = jQuery.camelCase( name ),
5070 style = elem.style, hooks = jQuery.cssHooks[ origName ];
5072 name = jQuery.cssProps[ origName ] || origName;
5074 // Check if we're setting a value
5075 if ( value !== undefined ) {
5076 // Make sure that NaN and null values aren't set. See: #7116
5077 if ( typeof value === "number" && isNaN( value ) || value == null ) {
5081 // If a number was passed in, add 'px' to the (except for certain CSS properties)
5082 if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
5086 // If a hook was provided, use that value, otherwise just set the specified value
5087 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
5088 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
5091 style[ name ] = value;
5096 // If a hook was provided get the non-computed value from there
5097 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
5101 // Otherwise just get the value from the style object
5102 return style[ name ];
5106 css: function( elem, name, extra ) {
5107 // Make sure that we're working with the right name
5108 var ret, origName = jQuery.camelCase( name ),
5109 hooks = jQuery.cssHooks[ origName ];
5111 name = jQuery.cssProps[ origName ] || origName;
5113 // If a hook was provided get the computed value from there
5114 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
5117 // Otherwise, if a way to get the computed value exists, use that
5118 } else if ( curCSS ) {
5119 return curCSS( elem, name, origName );
5123 // A method for quickly swapping in/out CSS properties to get correct calculations
5124 swap: function( elem, options, callback ) {
5127 // Remember the old values, and insert the new ones
5128 for ( var name in options ) {
5129 old[ name ] = elem.style[ name ];
5130 elem.style[ name ] = options[ name ];
5133 callback.call( elem );
5135 // Revert the old values
5136 for ( name in options ) {
5137 elem.style[ name ] = old[ name ];
5141 camelCase: function( string ) {
5142 return string.replace( rdashAlpha, fcamelCase );
5146 // DEPRECATED, Use jQuery.css() instead
5147 jQuery.curCSS = jQuery.css;
5149 jQuery.each(["height", "width"], function( i, name ) {
5150 jQuery.cssHooks[ name ] = {
5151 get: function( elem, computed, extra ) {
5155 if ( elem.offsetWidth !== 0 ) {
5156 val = getWH( elem, name, extra );
5159 jQuery.swap( elem, cssShow, function() {
5160 val = getWH( elem, name, extra );
5168 set: function( elem, value ) {
5169 if ( rnumpx.test( value ) ) {
5170 // ignore negative width and height values #1599
5171 value = parseFloat(value);
5174 return value + "px";
5184 if ( !jQuery.support.opacity ) {
5185 jQuery.cssHooks.opacity = {
5186 get: function( elem, computed ) {
5187 // IE uses filters for opacity
5188 return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
5189 (parseFloat(RegExp.$1) / 100) + "" :
5190 computed ? "1" : "";
5193 set: function( elem, value ) {
5194 var style = elem.style;
5196 // IE has trouble with opacity if it does not have layout
5197 // Force it by setting the zoom level
5200 // Set the alpha filter to set the opacity
5201 var opacity = jQuery.isNaN(value) ?
5203 "alpha(opacity=" + value * 100 + ")",
5204 filter = style.filter || "";
5206 style.filter = ralpha.test(filter) ?
5207 filter.replace(ralpha, opacity) :
5208 style.filter + ' ' + opacity;
5213 if ( getComputedStyle ) {
5214 curCSS = function( elem, newName, name ) {
5215 var ret, defaultView, computedStyle;
5217 name = name.replace( rupper, "-$1" ).toLowerCase();
5219 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
5223 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
5224 ret = computedStyle.getPropertyValue( name );
5225 if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
5226 ret = jQuery.style( elem, name );
5233 } else if ( document.documentElement.currentStyle ) {
5234 curCSS = function( elem, name ) {
5235 var left, rsLeft, ret = elem.currentStyle && elem.currentStyle[ name ], style = elem.style;
5237 // From the awesome hack by Dean Edwards
5238 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
5240 // If we're not dealing with a regular pixel number
5241 // but a number that has a weird ending, we need to convert it to pixels
5242 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
5243 // Remember the original values
5245 rsLeft = elem.runtimeStyle.left;
5247 // Put in the new values to get a computed value out
5248 elem.runtimeStyle.left = elem.currentStyle.left;
5249 style.left = name === "fontSize" ? "1em" : (ret || 0);
5250 ret = style.pixelLeft + "px";
5252 // Revert the changed values
5254 elem.runtimeStyle.left = rsLeft;
5261 function getWH( elem, name, extra ) {
5262 var which = name === "width" ? cssWidth : cssHeight,
5263 val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
5265 if ( extra === "border" ) {
5269 jQuery.each( which, function() {
5271 val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
5274 if ( extra === "margin" ) {
5275 val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
5278 val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
5285 if ( jQuery.expr && jQuery.expr.filters ) {
5286 jQuery.expr.filters.hidden = function( elem ) {
5287 var width = elem.offsetWidth, height = elem.offsetHeight;
5289 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
5292 jQuery.expr.filters.visible = function( elem ) {
5293 return !jQuery.expr.filters.hidden( elem );
5300 var jsc = jQuery.now(),
5301 rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
5302 rselectTextarea = /^(?:select|textarea)/i,
5303 rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
5304 rnoContent = /^(?:GET|HEAD|DELETE)$/,
5308 rts = /([?&])_=[^&]*/,
5309 rurl = /^(\w+:)?\/\/([^\/?#]+)/,
5313 // Keep a copy of the old load method
5314 _load = jQuery.fn.load;
5317 load: function( url, params, callback ) {
5318 if ( typeof url !== "string" && _load ) {
5319 return _load.apply( this, arguments );
5321 // Don't do a request if no elements are being requested
5322 } else if ( !this.length ) {
5326 var off = url.indexOf(" ");
5328 var selector = url.slice(off, url.length);
5329 url = url.slice(0, off);
5332 // Default to a GET request
5335 // If the second parameter was provided
5337 // If it's a function
5338 if ( jQuery.isFunction( params ) ) {
5339 // We assume that it's the callback
5343 // Otherwise, build a param string
5344 } else if ( typeof params === "object" ) {
5345 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
5352 // Request the remote document
5358 complete: function( res, status ) {
5359 // If successful, inject the HTML into all the matched elements
5360 if ( status === "success" || status === "notmodified" ) {
5361 // See if a selector was specified
5362 self.html( selector ?
5363 // Create a dummy div to hold the results
5365 // inject the contents of the document in, removing the scripts
5366 // to avoid any 'Permission Denied' errors in IE
5367 .append(res.responseText.replace(rscript, ""))
5369 // Locate the specified elements
5372 // If not, just inject the full result
5377 self.each( callback, [res.responseText, status, res] );
5385 serialize: function() {
5386 return jQuery.param(this.serializeArray());
5389 serializeArray: function() {
5390 return this.map(function() {
5391 return this.elements ? jQuery.makeArray(this.elements) : this;
5393 .filter(function() {
5394 return this.name && !this.disabled &&
5395 (this.checked || rselectTextarea.test(this.nodeName) ||
5396 rinput.test(this.type));
5398 .map(function( i, elem ) {
5399 var val = jQuery(this).val();
5401 return val == null ?
5403 jQuery.isArray(val) ?
5404 jQuery.map( val, function( val, i ) {
5405 return { name: elem.name, value: val };
5407 { name: elem.name, value: val };
5412 // Attach a bunch of functions for handling common AJAX events
5413 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
5414 jQuery.fn[o] = function( f ) {
5415 return this.bind(o, f);
5420 get: function( url, data, callback, type ) {
5421 // shift arguments if data argument was omited
5422 if ( jQuery.isFunction( data ) ) {
5423 type = type || callback;
5428 return jQuery.ajax({
5437 getScript: function( url, callback ) {
5438 return jQuery.get(url, null, callback, "script");
5441 getJSON: function( url, data, callback ) {
5442 return jQuery.get(url, data, callback, "json");
5445 post: function( url, data, callback, type ) {
5446 // shift arguments if data argument was omited
5447 if ( jQuery.isFunction( data ) ) {
5448 type = type || callback;
5453 return jQuery.ajax({
5462 ajaxSetup: function( settings ) {
5463 jQuery.extend( jQuery.ajaxSettings, settings );
5470 contentType: "application/x-www-form-urlencoded",
5480 // This function can be overriden by calling jQuery.ajaxSetup
5482 return new window.XMLHttpRequest();
5485 xml: "application/xml, text/xml",
5487 script: "text/javascript, application/javascript",
5488 json: "application/json, text/javascript",
5494 ajax: function( origSettings ) {
5495 var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
5496 jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
5498 s.url = s.url.replace( rhash, "" );
5500 // Use original (not extended) context object if it was provided
5501 s.context = origSettings && origSettings.context != null ? origSettings.context : s;
5503 // convert data if not already a string
5504 if ( s.data && s.processData && typeof s.data !== "string" ) {
5505 s.data = jQuery.param( s.data, s.traditional );
5508 // Handle JSONP Parameter Callbacks
5509 if ( s.dataType === "jsonp" ) {
5510 if ( type === "GET" ) {
5511 if ( !jsre.test( s.url ) ) {
5512 s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
5514 } else if ( !s.data || !jsre.test(s.data) ) {
5515 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
5517 s.dataType = "json";
5520 // Build temporary JSONP function
5521 if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
5522 jsonp = s.jsonpCallback || ("jsonp" + jsc++);
5524 // Replace the =? sequence both in the query string and the data
5526 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
5529 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
5531 // We need to make sure
5532 // that a JSONP style response is executed properly
5533 s.dataType = "script";
5535 // Handle JSONP-style loading
5536 var customJsonp = window[ jsonp ];
5538 window[ jsonp ] = function( tmp ) {
5540 jQuery.handleSuccess( s, xhr, status, data );
5541 jQuery.handleComplete( s, xhr, status, data );
5543 if ( jQuery.isFunction( customJsonp ) ) {
5548 window[ jsonp ] = undefined;
5551 delete window[ jsonp ];
5552 } catch( jsonpError ) {}
5556 head.removeChild( script );
5561 if ( s.dataType === "script" && s.cache === null ) {
5565 if ( s.cache === false && type === "GET" ) {
5566 var ts = jQuery.now();
5568 // try replacing _= if it is there
5569 var ret = s.url.replace(rts, "$1_=" + ts);
5571 // if nothing was replaced, add timestamp to the end
5572 s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
5575 // If data is available, append data to url for get requests
5576 if ( s.data && type === "GET" ) {
5577 s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
5580 // Watch for a new set of requests
5581 if ( s.global && jQuery.active++ === 0 ) {
5582 jQuery.event.trigger( "ajaxStart" );
5585 // Matches an absolute URL, and saves the domain
5586 var parts = rurl.exec( s.url ),
5587 remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
5589 // If we're requesting a remote document
5590 // and trying to load JSON or Script with a GET
5591 if ( s.dataType === "script" && type === "GET" && remote ) {
5592 var head = document.getElementsByTagName("head")[0] || document.documentElement;
5593 var script = document.createElement("script");
5594 if ( s.scriptCharset ) {
5595 script.charset = s.scriptCharset;
5599 // Handle Script loading
5603 // Attach handlers for all browsers
5604 script.onload = script.onreadystatechange = function() {
5605 if ( !done && (!this.readyState ||
5606 this.readyState === "loaded" || this.readyState === "complete") ) {
5608 jQuery.handleSuccess( s, xhr, status, data );
5609 jQuery.handleComplete( s, xhr, status, data );
5611 // Handle memory leak in IE
5612 script.onload = script.onreadystatechange = null;
5613 if ( head && script.parentNode ) {
5614 head.removeChild( script );
5620 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
5621 // This arises when a base node is used (#2709 and #4378).
5622 head.insertBefore( script, head.firstChild );
5624 // We handle everything using the script element injection
5628 var requestDone = false;
5630 // Create the request object
5638 // Passing null username, generates a login popup on Opera (#2865)
5640 xhr.open(type, s.url, s.async, s.username, s.password);
5642 xhr.open(type, s.url, s.async);
5645 // Need an extra try/catch for cross domain requests in Firefox 3
5647 // Set content-type if data specified and content-body is valid for this type
5648 if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
5649 xhr.setRequestHeader("Content-Type", s.contentType);
5652 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
5653 if ( s.ifModified ) {
5654 if ( jQuery.lastModified[s.url] ) {
5655 xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
5658 if ( jQuery.etag[s.url] ) {
5659 xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
5663 // Set header so the called script knows that it's an XMLHttpRequest
5664 // Only send the header if it's not a remote XHR
5666 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
5669 // Set the Accepts header for the server, depending on the dataType
5670 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
5671 s.accepts[ s.dataType ] + ", */*; q=0.01" :
5672 s.accepts._default );
5673 } catch( headerError ) {}
5675 // Allow custom headers/mimetypes and early abort
5676 if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
5677 // Handle the global AJAX counter
5678 if ( s.global && jQuery.active-- === 1 ) {
5679 jQuery.event.trigger( "ajaxStop" );
5682 // close opended socket
5688 jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
5691 // Wait for a response to come back
5692 var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
5693 // The request was aborted
5694 if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
5695 // Opera doesn't call onreadystatechange before this point
5696 // so we simulate the call
5697 if ( !requestDone ) {
5698 jQuery.handleComplete( s, xhr, status, data );
5703 xhr.onreadystatechange = jQuery.noop;
5706 // The transfer is complete and the data is available, or the request timed out
5707 } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
5709 xhr.onreadystatechange = jQuery.noop;
5711 status = isTimeout === "timeout" ?
5713 !jQuery.httpSuccess( xhr ) ?
5715 s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
5721 if ( status === "success" ) {
5722 // Watch for, and catch, XML document parse errors
5724 // process the data (runs the xml through httpData regardless of callback)
5725 data = jQuery.httpData( xhr, s.dataType, s );
5726 } catch( parserError ) {
5727 status = "parsererror";
5728 errMsg = parserError;
5732 // Make sure that the request was successful or notmodified
5733 if ( status === "success" || status === "notmodified" ) {
5734 // JSONP handles its own success callback
5736 jQuery.handleSuccess( s, xhr, status, data );
5739 jQuery.handleError( s, xhr, status, errMsg );
5742 // Fire the complete handlers
5744 jQuery.handleComplete( s, xhr, status, data );
5747 if ( isTimeout === "timeout" ) {
5751 // Stop memory leaks
5758 // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
5759 // Opera doesn't fire onreadystatechange at all on abort
5761 var oldAbort = xhr.abort;
5762 xhr.abort = function() {
5763 // xhr.abort in IE7 is not a native JS function
5764 // and does not have a call property
5765 if ( xhr && oldAbort.call ) {
5766 oldAbort.call( xhr );
5769 onreadystatechange( "abort" );
5771 } catch( abortError ) {}
5774 if ( s.async && s.timeout > 0 ) {
5775 setTimeout(function() {
5776 // Check to see if the request is still happening
5777 if ( xhr && !requestDone ) {
5778 onreadystatechange( "timeout" );
5785 xhr.send( noContent || s.data == null ? null : s.data );
5787 } catch( sendError ) {
5788 jQuery.handleError( s, xhr, null, sendError );
5790 // Fire the complete handlers
5791 jQuery.handleComplete( s, xhr, status, data );
5794 // firefox 1.5 doesn't fire statechange for sync requests
5796 onreadystatechange();
5799 // return XMLHttpRequest to allow aborting the request etc.
5803 // Serialize an array of form elements or a set of
5804 // key/values into a query string
5805 param: function( a, traditional ) {
5806 var s = [], add = function( key, value ) {
5807 // If value is a function, invoke it and return its value
5808 value = jQuery.isFunction(value) ? value() : value;
5809 s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
5812 // Set traditional to true for jQuery <= 1.3.2 behavior.
5813 if ( traditional === undefined ) {
5814 traditional = jQuery.ajaxSettings.traditional;
5817 // If an array was passed in, assume that it is an array of form elements.
5818 if ( jQuery.isArray(a) || a.jquery ) {
5819 // Serialize the form elements
5820 jQuery.each( a, function() {
5821 add( this.name, this.value );
5825 // If traditional, encode the "old" way (the way 1.3.2 or older
5826 // did it), otherwise encode params recursively.
5827 for ( var prefix in a ) {
5828 buildParams( prefix, a[prefix], traditional, add );
5832 // Return the resulting serialization
5833 return s.join("&").replace(r20, "+");
5837 function buildParams( prefix, obj, traditional, add ) {
5838 if ( jQuery.isArray(obj) && obj.length ) {
5839 // Serialize array item.
5840 jQuery.each( obj, function( i, v ) {
5841 if ( traditional || rbracket.test( prefix ) ) {
5842 // Treat each array item as a scalar.
5846 // If array item is non-scalar (array or object), encode its
5847 // numeric index to resolve deserialization ambiguity issues.
5848 // Note that rack (as of 1.0.0) can't currently deserialize
5849 // nested arrays properly, and attempting to do so may cause
5850 // a server error. Possible fixes are to modify rack's
5851 // deserialization algorithm or to provide an option or flag
5852 // to force array serialization to be shallow.
5853 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
5857 } else if ( !traditional && obj != null && typeof obj === "object" ) {
5858 if ( jQuery.isEmptyObject( obj ) ) {
5861 // Serialize object item.
5863 jQuery.each( obj, function( k, v ) {
5864 buildParams( prefix + "[" + k + "]", v, traditional, add );
5869 // Serialize scalar item.
5874 // This is still on the jQuery object... for now
5875 // Want to move this to jQuery.ajax some day
5878 // Counter for holding the number of active queries
5881 // Last-Modified header cache for next request
5885 handleError: function( s, xhr, status, e ) {
5886 // If a local callback was specified, fire it
5888 s.error.call( s.context, xhr, status, e );
5891 // Fire the global callback
5893 jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
5897 handleSuccess: function( s, xhr, status, data ) {
5898 // If a local callback was specified, fire it and pass it the data
5900 s.success.call( s.context, data, status, xhr );
5903 // Fire the global callback
5905 jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
5909 handleComplete: function( s, xhr, status ) {
5912 s.complete.call( s.context, xhr, status );
5915 // The request was completed
5917 jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
5920 // Handle the global AJAX counter
5921 if ( s.global && jQuery.active-- === 1 ) {
5922 jQuery.event.trigger( "ajaxStop" );
5926 triggerGlobal: function( s, type, args ) {
5927 (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
5930 // Determines if an XMLHttpRequest was successful or not
5931 httpSuccess: function( xhr ) {
5933 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
5934 return !xhr.status && location.protocol === "file:" ||
5935 xhr.status >= 200 && xhr.status < 300 ||
5936 xhr.status === 304 || xhr.status === 1223;
5942 // Determines if an XMLHttpRequest returns NotModified
5943 httpNotModified: function( xhr, url ) {
5944 var lastModified = xhr.getResponseHeader("Last-Modified"),
5945 etag = xhr.getResponseHeader("Etag");
5947 if ( lastModified ) {
5948 jQuery.lastModified[url] = lastModified;
5952 jQuery.etag[url] = etag;
5955 return xhr.status === 304;
5958 httpData: function( xhr, type, s ) {
5959 var ct = xhr.getResponseHeader("content-type") || "",
5960 xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
5961 data = xml ? xhr.responseXML : xhr.responseText;
5963 if ( xml && data.documentElement.nodeName === "parsererror" ) {
5964 jQuery.error( "parsererror" );
5967 // Allow a pre-filtering function to sanitize the response
5968 // s is checked to keep backwards compatibility
5969 if ( s && s.dataFilter ) {
5970 data = s.dataFilter( data, type );
5973 // The filter can actually parse the response
5974 if ( typeof data === "string" ) {
5975 // Get the JavaScript object, if JSON is used.
5976 if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
5977 data = jQuery.parseJSON( data );
5979 // If the type is "script", eval it in global context
5980 } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
5981 jQuery.globalEval( data );
5991 * Create the request object; Microsoft failed to properly
5992 * implement the XMLHttpRequest in IE7 (can't request local files),
5993 * so we use the ActiveXObject when it is available
5994 * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
5995 * we need a fallback.
5997 if ( window.ActiveXObject ) {
5998 jQuery.ajaxSettings.xhr = function() {
5999 if ( window.location.protocol !== "file:" ) {
6001 return new window.XMLHttpRequest();
6002 } catch(xhrError) {}
6006 return new window.ActiveXObject("Microsoft.XMLHTTP");
6007 } catch(activeError) {}
6011 // Does this browser support XHR requests?
6012 jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
6017 var elemdisplay = {},
6018 rfxtypes = /^(?:toggle|show|hide)$/,
6019 rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
6022 // height animations
6023 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
6025 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
6026 // opacity animations
6031 show: function( speed, easing, callback ) {
6032 if ( speed || speed === 0 ) {
6033 return this.animate( genFx("show", 3), speed, easing, callback);
6035 for ( var i = 0, j = this.length; i < j; i++ ) {
6036 // Reset the inline display of this element to learn if it is
6037 // being hidden by cascaded rules or not
6038 if ( !jQuery.data(this[i], "olddisplay") && this[i].style.display === "none" ) {
6039 this[i].style.display = "";
6042 // Set elements which have been overridden with display: none
6043 // in a stylesheet to whatever the default browser style is
6044 // for such an element
6045 if ( this[i].style.display === "" && jQuery.css( this[i], "display" ) === "none" ) {
6046 jQuery.data(this[i], "olddisplay", defaultDisplay(this[i].nodeName));
6050 // Set the display of most of the elements in a second loop
6051 // to avoid the constant reflow
6052 for ( i = 0; i < j; i++ ) {
6053 this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
6060 hide: function( speed, easing, callback ) {
6061 if ( speed || speed === 0 ) {
6062 return this.animate( genFx("hide", 3), speed, easing, callback);
6065 for ( var i = 0, j = this.length; i < j; i++ ) {
6066 var display = jQuery.css( this[i], "display" );
6068 if ( display !== "none" ) {
6069 jQuery.data( this[i], "olddisplay", display );
6073 // Set the display of the elements in a second loop
6074 // to avoid the constant reflow
6075 for ( i = 0; i < j; i++ ) {
6076 this[i].style.display = "none";
6083 // Save the old toggle function
6084 _toggle: jQuery.fn.toggle,
6086 toggle: function( fn, fn2, callback ) {
6087 var bool = typeof fn === "boolean";
6089 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
6090 this._toggle.apply( this, arguments );
6092 } else if ( fn == null || bool ) {
6093 this.each(function() {
6094 var state = bool ? fn : jQuery(this).is(":hidden");
6095 jQuery(this)[ state ? "show" : "hide" ]();
6099 this.animate(genFx("toggle", 3), fn, fn2, callback);
6105 fadeTo: function( speed, to, easing, callback ) {
6106 return this.filter(":hidden").css("opacity", 0).show().end()
6107 .animate({opacity: to}, speed, easing, callback);
6110 animate: function( prop, speed, easing, callback ) {
6111 var optall = jQuery.speed(speed, easing, callback);
6113 if ( jQuery.isEmptyObject( prop ) ) {
6114 return this.each( optall.complete );
6117 return this[ optall.queue === false ? "each" : "queue" ](function() {
6118 // XXX ‘this’ does not always have a nodeName when running the
6121 var opt = jQuery.extend({}, optall), p,
6122 isElement = this.nodeType === 1,
6123 hidden = isElement && jQuery(this).is(":hidden"),
6127 var name = jQuery.camelCase( p );
6130 prop[ name ] = prop[ p ];
6135 if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
6136 return opt.complete.call(this);
6139 if ( isElement && ( p === "height" || p === "width" ) ) {
6140 // Make sure that nothing sneaks out
6141 // Record all 3 overflow attributes because IE does not
6142 // change the overflow attribute when overflowX and
6143 // overflowY are set to the same value
6144 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
6146 // Set display property to inline-block for height/width
6147 // animations on inline elements that are having width/height
6149 if ( jQuery.css( this, "display" ) === "inline" &&
6150 jQuery.css( this, "float" ) === "none" ) {
6151 if ( !jQuery.support.inlineBlockNeedsLayout ) {
6152 this.style.display = "inline-block";
6155 var display = defaultDisplay(this.nodeName);
6157 // inline-level elements accept inline-block;
6158 // block-level elements need to be inline with layout
6159 if ( display === "inline" ) {
6160 this.style.display = "inline-block";
6163 this.style.display = "inline";
6164 this.style.zoom = 1;
6170 if ( jQuery.isArray( prop[p] ) ) {
6171 // Create (if needed) and add to specialEasing
6172 (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
6173 prop[p] = prop[p][0];
6177 if ( opt.overflow != null ) {
6178 this.style.overflow = "hidden";
6181 opt.curAnim = jQuery.extend({}, prop);
6183 jQuery.each( prop, function( name, val ) {
6184 var e = new jQuery.fx( self, opt, name );
6186 if ( rfxtypes.test(val) ) {
6187 e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
6190 var parts = rfxnum.exec(val),
6191 start = e.cur(true) || 0;
6194 var end = parseFloat( parts[2] ),
6195 unit = parts[3] || "px";
6197 // We need to compute starting value
6198 if ( unit !== "px" ) {
6199 jQuery.style( self, name, (end || 1) + unit);
6200 start = ((end || 1) / e.cur(true)) * start;
6201 jQuery.style( self, name, start + unit);
6204 // If a +=/-= token was provided, we're doing a relative animation
6206 end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
6209 e.custom( start, end, unit );
6212 e.custom( start, val, "" );
6217 // For JS strict compliance
6222 stop: function( clearQueue, gotoEnd ) {
6223 var timers = jQuery.timers;
6229 this.each(function() {
6230 // go in reverse order so anything added to the queue during the loop is ignored
6231 for ( var i = timers.length - 1; i >= 0; i-- ) {
6232 if ( timers[i].elem === this ) {
6234 // force the next step to be the last
6238 timers.splice(i, 1);
6243 // start the next in the queue if the last step wasn't forced
6253 function genFx( type, num ) {
6256 jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
6263 // Generate shortcuts for custom animations
6265 slideDown: genFx("show", 1),
6266 slideUp: genFx("hide", 1),
6267 slideToggle: genFx("toggle", 1),
6268 fadeIn: { opacity: "show" },
6269 fadeOut: { opacity: "hide" }
6270 }, function( name, props ) {
6271 jQuery.fn[ name ] = function( speed, easing, callback ) {
6272 return this.animate( props, speed, easing, callback );
6277 speed: function( speed, easing, fn ) {
6278 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
6279 complete: fn || !fn && easing ||
6280 jQuery.isFunction( speed ) && speed,
6282 easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
6285 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6286 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
6289 opt.old = opt.complete;
6290 opt.complete = function() {
6291 if ( opt.queue !== false ) {
6292 jQuery(this).dequeue();
6294 if ( jQuery.isFunction( opt.old ) ) {
6295 opt.old.call( this );
6303 linear: function( p, n, firstNum, diff ) {
6304 return firstNum + diff * p;
6306 swing: function( p, n, firstNum, diff ) {
6307 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
6313 fx: function( elem, options, prop ) {
6314 this.options = options;
6318 if ( !options.orig ) {
6325 jQuery.fx.prototype = {
6326 // Simple function for setting a style value
6327 update: function() {
6328 if ( this.options.step ) {
6329 this.options.step.call( this.elem, this.now, this );
6332 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
6335 // Get the current size
6337 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
6338 return this.elem[ this.prop ];
6341 var r = parseFloat( jQuery.css( this.elem, this.prop ) );
6342 return r && r > -10000 ? r : 0;
6345 // Start an animation from one number to another
6346 custom: function( from, to, unit ) {
6347 this.startTime = jQuery.now();
6350 this.unit = unit || this.unit || "px";
6351 this.now = this.start;
6352 this.pos = this.state = 0;
6354 var self = this, fx = jQuery.fx;
6355 function t( gotoEnd ) {
6356 return self.step(gotoEnd);
6361 if ( t() && jQuery.timers.push(t) && !timerId ) {
6362 timerId = setInterval(fx.tick, fx.interval);
6366 // Simple 'show' function
6368 // Remember where we started, so that we can go back to it later
6369 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6370 this.options.show = true;
6372 // Begin the animation
6373 // Make sure that we start at a small width/height to avoid any
6375 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
6377 // Start by showing the element
6378 jQuery( this.elem ).show();
6381 // Simple 'hide' function
6383 // Remember where we started, so that we can go back to it later
6384 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
6385 this.options.hide = true;
6387 // Begin the animation
6388 this.custom(this.cur(), 0);
6391 // Each step of an animation
6392 step: function( gotoEnd ) {
6393 var t = jQuery.now(), done = true;
6395 if ( gotoEnd || t >= this.options.duration + this.startTime ) {
6396 this.now = this.end;
6397 this.pos = this.state = 1;
6400 this.options.curAnim[ this.prop ] = true;
6402 for ( var i in this.options.curAnim ) {
6403 if ( this.options.curAnim[i] !== true ) {
6409 // Reset the overflow
6410 if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
6411 var elem = this.elem, options = this.options;
6412 jQuery.each( [ "", "X", "Y" ], function (index, value) {
6413 elem.style[ "overflow" + value ] = options.overflow[index];
6417 // Hide the element if the "hide" operation was done
6418 if ( this.options.hide ) {
6419 jQuery(this.elem).hide();
6422 // Reset the properties, if the item has been hidden or shown
6423 if ( this.options.hide || this.options.show ) {
6424 for ( var p in this.options.curAnim ) {
6425 jQuery.style( this.elem, p, this.options.orig[p] );
6429 // Execute the complete function
6430 this.options.complete.call( this.elem );
6436 var n = t - this.startTime;
6437 this.state = n / this.options.duration;
6439 // Perform the easing function, defaults to swing
6440 var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
6441 var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
6442 this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
6443 this.now = this.start + ((this.end - this.start) * this.pos);
6445 // Perform the next step of the animation
6453 jQuery.extend( jQuery.fx, {
6455 var timers = jQuery.timers;
6457 for ( var i = 0; i < timers.length; i++ ) {
6458 if ( !timers[i]() ) {
6459 timers.splice(i--, 1);
6463 if ( !timers.length ) {
6471 clearInterval( timerId );
6483 opacity: function( fx ) {
6484 jQuery.style( fx.elem, "opacity", fx.now );
6487 _default: function( fx ) {
6488 if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
6489 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
6491 fx.elem[ fx.prop ] = fx.now;
6497 if ( jQuery.expr && jQuery.expr.filters ) {
6498 jQuery.expr.filters.animated = function( elem ) {
6499 return jQuery.grep(jQuery.timers, function( fn ) {
6500 return elem === fn.elem;
6505 function defaultDisplay( nodeName ) {
6506 if ( !elemdisplay[ nodeName ] ) {
6507 var elem = jQuery("<" + nodeName + ">").appendTo("body"),
6508 display = elem.css("display");
6512 if ( display === "none" || display === "" ) {
6516 elemdisplay[ nodeName ] = display;
6519 return elemdisplay[ nodeName ];
6525 var rtable = /^t(?:able|d|h)$/i,
6526 rroot = /^(?:body|html)$/i;
6528 if ( "getBoundingClientRect" in document.documentElement ) {
6529 jQuery.fn.offset = function( options ) {
6530 var elem = this[0], box;
6533 return this.each(function( i ) {
6534 jQuery.offset.setOffset( this, options, i );
6538 if ( !elem || !elem.ownerDocument ) {
6542 if ( elem === elem.ownerDocument.body ) {
6543 return jQuery.offset.bodyOffset( elem );
6547 box = elem.getBoundingClientRect();
6550 var doc = elem.ownerDocument,
6551 docElem = doc.documentElement;
6553 // Make sure we're not dealing with a disconnected DOM node
6554 if ( !box || !jQuery.contains( docElem, elem ) ) {
6555 return box || { top: 0, left: 0 };
6558 var body = doc.body,
6559 win = getWindow(doc),
6560 clientTop = docElem.clientTop || body.clientTop || 0,
6561 clientLeft = docElem.clientLeft || body.clientLeft || 0,
6562 scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
6563 scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
6564 top = box.top + scrollTop - clientTop,
6565 left = box.left + scrollLeft - clientLeft;
6567 return { top: top, left: left };
6571 jQuery.fn.offset = function( options ) {
6575 return this.each(function( i ) {
6576 jQuery.offset.setOffset( this, options, i );
6580 if ( !elem || !elem.ownerDocument ) {
6584 if ( elem === elem.ownerDocument.body ) {
6585 return jQuery.offset.bodyOffset( elem );
6588 jQuery.offset.initialize();
6590 var offsetParent = elem.offsetParent, prevOffsetParent = elem,
6591 doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
6592 body = doc.body, defaultView = doc.defaultView,
6593 prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
6594 top = elem.offsetTop, left = elem.offsetLeft;
6596 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
6597 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6601 computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
6602 top -= elem.scrollTop;
6603 left -= elem.scrollLeft;
6605 if ( elem === offsetParent ) {
6606 top += elem.offsetTop;
6607 left += elem.offsetLeft;
6609 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
6610 top += parseFloat( computedStyle.borderTopWidth ) || 0;
6611 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6614 prevOffsetParent = offsetParent;
6615 offsetParent = elem.offsetParent;
6618 if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
6619 top += parseFloat( computedStyle.borderTopWidth ) || 0;
6620 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
6623 prevComputedStyle = computedStyle;
6626 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
6627 top += body.offsetTop;
6628 left += body.offsetLeft;
6631 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
6632 top += Math.max( docElem.scrollTop, body.scrollTop );
6633 left += Math.max( docElem.scrollLeft, body.scrollLeft );
6636 return { top: top, left: left };
6641 initialize: function() {
6642 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
6643 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>";
6645 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
6647 container.innerHTML = html;
6648 body.insertBefore( container, body.firstChild );
6649 innerDiv = container.firstChild;
6650 checkDiv = innerDiv.firstChild;
6651 td = innerDiv.nextSibling.firstChild.firstChild;
6653 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
6654 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
6656 checkDiv.style.position = "fixed";
6657 checkDiv.style.top = "20px";
6659 // safari subtracts parent border width here which is 5px
6660 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
6661 checkDiv.style.position = checkDiv.style.top = "";
6663 innerDiv.style.overflow = "hidden";
6664 innerDiv.style.position = "relative";
6666 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
6668 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
6670 body.removeChild( container );
6671 body = container = innerDiv = checkDiv = table = td = null;
6672 jQuery.offset.initialize = jQuery.noop;
6675 bodyOffset: function( body ) {
6676 var top = body.offsetTop, left = body.offsetLeft;
6678 jQuery.offset.initialize();
6680 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
6681 top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
6682 left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
6685 return { top: top, left: left };
6688 setOffset: function( elem, options, i ) {
6689 var position = jQuery.css( elem, "position" );
6691 // set position first, in-case top/left are set even on static elem
6692 if ( position === "static" ) {
6693 elem.style.position = "relative";
6696 var curElem = jQuery( elem ),
6697 curOffset = curElem.offset(),
6698 curCSSTop = jQuery.css( elem, "top" ),
6699 curCSSLeft = jQuery.css( elem, "left" ),
6700 calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
6701 props = {}, curPosition = {}, curTop, curLeft;
6703 // need to be able to calculate position if either top or left is auto and position is absolute
6704 if ( calculatePosition ) {
6705 curPosition = curElem.position();
6708 curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0;
6709 curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
6711 if ( jQuery.isFunction( options ) ) {
6712 options = options.call( elem, i, curOffset );
6715 if (options.top != null) {
6716 props.top = (options.top - curOffset.top) + curTop;
6718 if (options.left != null) {
6719 props.left = (options.left - curOffset.left) + curLeft;
6722 if ( "using" in options ) {
6723 options.using.call( elem, props );
6725 curElem.css( props );
6732 position: function() {
6739 // Get *real* offsetParent
6740 offsetParent = this.offsetParent(),
6742 // Get correct offsets
6743 offset = this.offset(),
6744 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
6746 // Subtract element margins
6747 // note: when an element has margin: auto the offsetLeft and marginLeft
6748 // are the same in Safari causing offset.left to incorrectly be 0
6749 offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
6750 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
6752 // Add offsetParent borders
6753 parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
6754 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
6756 // Subtract the two offsets
6758 top: offset.top - parentOffset.top,
6759 left: offset.left - parentOffset.left
6763 offsetParent: function() {
6764 return this.map(function() {
6765 var offsetParent = this.offsetParent || document.body;
6766 while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
6767 offsetParent = offsetParent.offsetParent;
6769 return offsetParent;
6775 // Create scrollLeft and scrollTop methods
6776 jQuery.each( ["Left", "Top"], function( i, name ) {
6777 var method = "scroll" + name;
6779 jQuery.fn[ method ] = function(val) {
6780 var elem = this[0], win;
6786 if ( val !== undefined ) {
6787 // Set the scroll offset
6788 return this.each(function() {
6789 win = getWindow( this );
6793 !i ? val : jQuery(win).scrollLeft(),
6794 i ? val : jQuery(win).scrollTop()
6798 this[ method ] = val;
6802 win = getWindow( elem );
6804 // Return the scroll offset
6805 return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
6806 jQuery.support.boxModel && win.document.documentElement[ method ] ||
6807 win.document.body[ method ] :
6813 function getWindow( elem ) {
6814 return jQuery.isWindow( elem ) ?
6816 elem.nodeType === 9 ?
6817 elem.defaultView || elem.parentWindow :
6824 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
6825 jQuery.each([ "Height", "Width" ], function( i, name ) {
6827 var type = name.toLowerCase();
6829 // innerHeight and innerWidth
6830 jQuery.fn["inner" + name] = function() {
6832 parseFloat( jQuery.css( this[0], type, "padding" ) ) :
6836 // outerHeight and outerWidth
6837 jQuery.fn["outer" + name] = function( margin ) {
6839 parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
6843 jQuery.fn[ type ] = function( size ) {
6844 // Get window width or height
6847 return size == null ? null : this;
6850 if ( jQuery.isFunction( size ) ) {
6851 return this.each(function( i ) {
6852 var self = jQuery( this );
6853 self[ type ]( size.call( this, i, self[ type ]() ) );
6857 return jQuery.isWindow( elem ) ?
6858 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
6859 elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
6860 elem.document.body[ "client" + name ] :
6862 // Get document width or height
6863 (elem.nodeType === 9) ? // is it a document
6864 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
6866 elem.documentElement["client" + name],
6867 elem.body["scroll" + name], elem.documentElement["scroll" + name],
6868 elem.body["offset" + name], elem.documentElement["offset" + name]
6871 // Get or set width or height on the element
6872 size === undefined ?
6873 // Get width or height on the element
6874 parseFloat( jQuery.css( elem, type ) ) :
6876 // Set the width or height on the element (default to pixels if value is unitless)
6877 this.css( type, typeof size === "string" ? size : size + "px" );