2 * jQuery JavaScript Library v1.3.2
5 * Copyright (c) 2009 John Resig
6 * Dual licensed under the MIT and GPL licenses.
7 * http://docs.jquery.com/License
9 * Date: 2009-02-19 23:34:21 +0100 (Thu, 19 Feb 2009)
15 // Will speed up references to window, and allows munging its name.
17 // Will speed up references to undefined, and allows munging its name.
19 // Map over jQuery in case of overwrite
20 _jQuery = window.jQuery,
21 // Map over the $ in case of overwrite
24 jQuery = window.jQuery = window.$ = function( selector, context ) {
25 // The jQuery object is actually just the init constructor 'enhanced'
26 return new jQuery.fn.init( selector, context );
29 // A simple way to check for HTML strings or ID strings
30 // (both of which we optimize for)
31 quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
32 // Is it a simple selector
33 isSimple = /^.[^:#\[\.,]*$/;
35 jQuery.fn = jQuery.prototype = {
36 init: function( selector, context ) {
37 // Make sure that a selection was provided
38 selector = selector || document;
40 // Handle $(DOMElement)
41 if ( selector.nodeType ) {
44 this.context = selector;
47 // Handle HTML strings
48 if ( typeof selector === "string" ) {
49 // Are we dealing with HTML string or an ID?
50 var match = quickExpr.exec( selector );
52 // Verify a match, and that no context was specified for #id
53 if ( match && (match[1] || !context) ) {
55 // HANDLE: $(html) -> $(array)
57 selector = jQuery.clean( [ match[1] ], context );
61 var elem = document.getElementById( match[3] );
63 // Handle the case where IE and Opera return items
64 // by name instead of ID
65 if ( elem && elem.id != match[3] )
66 return jQuery().find( selector );
68 // Otherwise, we inject the element directly into the jQuery object
69 var ret = jQuery( elem || [] );
70 ret.context = document;
71 ret.selector = selector;
75 // HANDLE: $(expr, [context])
76 // (which is just equivalent to: $(content).find(expr)
78 return jQuery( context ).find( selector );
80 // HANDLE: $(function)
81 // Shortcut for document ready
82 } else if ( jQuery.isFunction( selector ) )
83 return jQuery( document ).ready( selector );
85 // Make sure that old selector state is passed along
86 if ( selector.selector && selector.context ) {
87 this.selector = selector.selector;
88 this.context = selector.context;
91 return this.setArray(jQuery.isArray( selector ) ?
93 jQuery.makeArray(selector));
96 // Start with an empty selector
99 // The current version of jQuery being used
102 // The number of elements contained in the matched element set
107 // Get the Nth element in the matched element set OR
108 // Get the whole matched element set as a clean array
109 get: function( num ) {
110 return num === undefined ?
112 // Return a 'clean' array
113 Array.prototype.slice.call( this ) :
115 // Return just the object
119 // Take an array of elements and push it onto the stack
120 // (returning the new matched element set)
121 pushStack: function( elems, name, selector ) {
122 // Build a new jQuery matched element set
123 var ret = jQuery( elems );
125 // Add the old object onto the stack (as a reference)
126 ret.prevObject = this;
128 ret.context = this.context;
130 if ( name === "find" )
131 ret.selector = this.selector + (this.selector ? " " : "") + selector;
133 ret.selector = this.selector + "." + name + "(" + selector + ")";
135 // Return the newly-formed element set
139 // Force the current matched set of elements to become
140 // the specified array of elements (destroying the stack in the process)
141 // You should use pushStack() in order to do this, but maintain the stack
142 setArray: function( elems ) {
143 // Resetting the length to 0, then using the native Array push
144 // is a super-fast way to populate an object with array-like properties
146 Array.prototype.push.apply( this, elems );
151 // Execute a callback for every element in the matched set.
152 // (You can seed the arguments with an array of args, but this is
153 // only used internally.)
154 each: function( callback, args ) {
155 return jQuery.each( this, callback, args );
158 // Determine the position of an element within
159 // the matched set of elements
160 index: function( elem ) {
161 // Locate the position of the desired element
162 return jQuery.inArray(
163 // If it receives a jQuery object, the first element is used
164 elem && elem.jquery ? elem[0] : elem
168 attr: function( name, value, type ) {
171 // Look for the case where we're accessing a style value
172 if ( typeof name === "string" )
173 if ( value === undefined )
174 return this[0] && jQuery[ type || "attr" ]( this[0], name );
178 options[ name ] = value;
181 // Check to see if we're setting style values
182 return this.each(function(i){
183 // Set all the styles
184 for ( name in options )
189 name, jQuery.prop( this, options[ name ], type, i, name )
194 css: function( key, value ) {
195 // ignore negative width and height values
196 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
198 return this.attr( key, value, "curCSS" );
201 text: function( text ) {
202 if ( typeof text !== "object" && text != null )
203 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
207 jQuery.each( text || this, function(){
208 jQuery.each( this.childNodes, function(){
209 if ( this.nodeType != 8 )
210 ret += this.nodeType != 1 ?
212 jQuery.fn.text( [ this ] );
219 wrapAll: function( html ) {
221 // The elements to wrap the target around
222 var wrap = jQuery( html, this[0].ownerDocument ).clone();
224 if ( this[0].parentNode )
225 wrap.insertBefore( this[0] );
230 while ( elem.firstChild )
231 elem = elem.firstChild;
240 wrapInner: function( html ) {
241 return this.each(function(){
242 jQuery( this ).contents().wrapAll( html );
246 wrap: function( html ) {
247 return this.each(function(){
248 jQuery( this ).wrapAll( html );
253 return this.domManip(arguments, true, function(elem){
254 if (this.nodeType == 1)
255 this.appendChild( elem );
259 prepend: function() {
260 return this.domManip(arguments, true, function(elem){
261 if (this.nodeType == 1)
262 this.insertBefore( elem, this.firstChild );
267 return this.domManip(arguments, false, function(elem){
268 this.parentNode.insertBefore( elem, this );
273 return this.domManip(arguments, false, function(elem){
274 this.parentNode.insertBefore( elem, this.nextSibling );
279 return this.prevObject || jQuery( [] );
282 // For internal use only.
283 // Behaves like an Array's method, not like a jQuery method.
288 find: function( selector ) {
289 if ( this.length === 1 ) {
290 var ret = this.pushStack( [], "find", selector );
292 jQuery.find( selector, this[0], ret );
295 return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
296 return jQuery.find( selector, elem );
297 })), "find", selector );
301 clone: function( events ) {
303 var ret = this.map(function(){
304 if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
305 // IE copies events bound via attachEvent when
306 // using cloneNode. Calling detachEvent on the
307 // clone will also remove the events from the orignal
308 // In order to get around this, we use innerHTML.
309 // Unfortunately, this means some modifications to
310 // attributes in IE that are actually only stored
311 // as properties will not be copied (such as the
312 // the name attribute on an input).
313 var html = this.outerHTML;
315 var div = this.ownerDocument.createElement("div");
316 div.appendChild( this.cloneNode(true) );
317 html = div.innerHTML;
320 return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
322 return this.cloneNode(true);
325 // Copy the events from the original to the clone
326 if ( events === true ) {
327 var orig = this.find("*").andSelf(), i = 0;
329 ret.find("*").andSelf().each(function(){
330 if ( this.nodeName !== orig[i].nodeName )
333 var events = jQuery.data( orig[i], "events" );
335 for ( var type in events ) {
336 for ( var handler in events[ type ] ) {
337 jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
345 // Return the cloned set
349 filter: function( selector ) {
350 return this.pushStack(
351 jQuery.isFunction( selector ) &&
352 jQuery.grep(this, function(elem, i){
353 return selector.call( elem, i );
356 jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
357 return elem.nodeType === 1;
358 }) ), "filter", selector );
361 closest: function( selector ) {
362 var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
365 return this.map(function(){
367 while ( cur && cur.ownerDocument ) {
368 if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
369 jQuery.data(cur, "closest", closer);
372 cur = cur.parentNode;
378 not: function( selector ) {
379 if ( typeof selector === "string" )
380 // test special case where just one selector is passed in
381 if ( isSimple.test( selector ) )
382 return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
384 selector = jQuery.multiFilter( selector, this );
386 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
387 return this.filter(function() {
388 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
392 add: function( selector ) {
393 return this.pushStack( jQuery.unique( jQuery.merge(
395 typeof selector === "string" ?
397 jQuery.makeArray( selector )
401 is: function( selector ) {
402 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
405 hasClass: function( selector ) {
406 return !!selector && this.is( "." + selector );
409 val: function( value ) {
410 if ( value === undefined ) {
414 if( jQuery.nodeName( elem, 'option' ) )
415 return (elem.attributes.value || {}).specified ? elem.value : elem.text;
417 // We need to handle select boxes special
418 if ( jQuery.nodeName( elem, "select" ) ) {
419 var index = elem.selectedIndex,
421 options = elem.options,
422 one = elem.type == "select-one";
424 // Nothing was selected
428 // Loop through all the selected options
429 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
430 var option = options[ i ];
432 if ( option.selected ) {
433 // Get the specifc value for the option
434 value = jQuery(option).val();
436 // We don't need an array for one selects
440 // Multi-Selects return an array
441 values.push( value );
448 // Everything else, we just grab the value
449 return (elem.value || "").replace(/\r/g, "");
456 if ( typeof value === "number" )
459 return this.each(function(){
460 if ( this.nodeType != 1 )
463 if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
464 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
465 jQuery.inArray(this.name, value) >= 0);
467 else if ( jQuery.nodeName( this, "select" ) ) {
468 var values = jQuery.makeArray(value);
470 jQuery( "option", this ).each(function(){
471 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
472 jQuery.inArray( this.text, values ) >= 0);
475 if ( !values.length )
476 this.selectedIndex = -1;
483 html: function( value ) {
484 return value === undefined ?
486 this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
488 this.empty().append( value );
491 replaceWith: function( value ) {
492 return this.after( value ).remove();
496 return this.slice( i, +i + 1 );
500 return this.pushStack( Array.prototype.slice.apply( this, arguments ),
501 "slice", Array.prototype.slice.call(arguments).join(",") );
504 map: function( callback ) {
505 return this.pushStack( jQuery.map(this, function(elem, i){
506 return callback.call( elem, i, elem );
510 andSelf: function() {
511 return this.add( this.prevObject );
514 domManip: function( args, table, callback ) {
516 var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
517 scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
518 first = fragment.firstChild;
521 for ( var i = 0, l = this.length; i < l; i++ )
522 callback.call( root(this[i], first), this.length > 1 || i > 0 ?
523 fragment.cloneNode(true) : fragment );
526 jQuery.each( scripts, evalScript );
531 function root( elem, cur ) {
532 return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
533 (elem.getElementsByTagName("tbody")[0] ||
534 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
540 // Give the init function the jQuery prototype for later instantiation
541 jQuery.fn.init.prototype = jQuery.fn;
543 function evalScript( i, elem ) {
552 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
554 if ( elem.parentNode )
555 elem.parentNode.removeChild( elem );
562 jQuery.extend = jQuery.fn.extend = function() {
563 // copy reference to target object
564 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
566 // Handle a deep copy situation
567 if ( typeof target === "boolean" ) {
569 target = arguments[1] || {};
570 // skip the boolean and the target
574 // Handle case when target is a string or something (possible in deep copy)
575 if ( typeof target !== "object" && !jQuery.isFunction(target) )
578 // extend jQuery itself if only one argument is passed
584 for ( ; i < length; i++ )
585 // Only deal with non-null/undefined values
586 if ( (options = arguments[ i ]) != null )
587 // Extend the base object
588 for ( var name in options ) {
589 var src = target[ name ], copy = options[ name ];
591 // Prevent never-ending loop
592 if ( target === copy )
595 // Recurse if we're merging object values
596 if ( deep && copy && typeof copy === "object" && !copy.nodeType )
597 target[ name ] = jQuery.extend( deep,
598 // Never move original objects, clone them
599 src || ( copy.length != null ? [ ] : { } )
602 // Don't bring in undefined values
603 else if ( copy !== undefined )
604 target[ name ] = copy;
608 // Return the modified object
612 // exclude the following css properties to add px
613 var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
615 defaultView = document.defaultView || {},
616 toString = Object.prototype.toString;
619 noConflict: function( deep ) {
623 window.jQuery = _jQuery;
628 // See test/unit/core.js for details concerning isFunction.
629 // Since version 1.3, DOM methods and functions like alert
630 // aren't supported. They return false on IE (#2968).
631 isFunction: function( obj ) {
632 return toString.call(obj) === "[object Function]";
635 isArray: function( obj ) {
636 return toString.call(obj) === "[object Array]";
639 // check if an element is in a (or is an) XML document
640 isXMLDoc: function( elem ) {
641 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
642 !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
645 // Evalulates a script in a global context
646 globalEval: function( data ) {
647 if ( data && /\S/.test(data) ) {
648 // Inspired by code by Andrea Giammarchi
649 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
650 var head = document.getElementsByTagName("head")[0] || document.documentElement,
651 script = document.createElement("script");
653 script.type = "text/javascript";
654 if ( jQuery.support.scriptEval )
655 script.appendChild( document.createTextNode( data ) );
659 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
660 // This arises when a base node is used (#2709).
661 head.insertBefore( script, head.firstChild );
662 head.removeChild( script );
666 nodeName: function( elem, name ) {
667 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
670 // args is for internal usage only
671 each: function( object, callback, args ) {
672 var name, i = 0, length = object.length;
675 if ( length === undefined ) {
676 for ( name in object )
677 if ( callback.apply( object[ name ], args ) === false )
680 for ( ; i < length; )
681 if ( callback.apply( object[ i++ ], args ) === false )
684 // A special, fast, case for the most common use of each
686 if ( length === undefined ) {
687 for ( name in object )
688 if ( callback.call( object[ name ], name, object[ name ] ) === false )
691 for ( var value = object[0];
692 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
698 prop: function( elem, value, type, i, name ) {
699 // Handle executable functions
700 if ( jQuery.isFunction( value ) )
701 value = value.call( elem, i );
703 // Handle passing in a number to a CSS property
704 return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
710 // internal only, use addClass("class")
711 add: function( elem, classNames ) {
712 jQuery.each((classNames || "").split(/\s+/), function(i, className){
713 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
714 elem.className += (elem.className ? " " : "") + className;
718 // internal only, use removeClass("class")
719 remove: function( elem, classNames ) {
720 if (elem.nodeType == 1)
721 elem.className = classNames !== undefined ?
722 jQuery.grep(elem.className.split(/\s+/), function(className){
723 return !jQuery.className.has( classNames, className );
728 // internal only, use hasClass("class")
729 has: function( elem, className ) {
730 return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
734 // A method for quickly swapping in/out CSS properties to get correct calculations
735 swap: function( elem, options, callback ) {
737 // Remember the old values, and insert the new ones
738 for ( var name in options ) {
739 old[ name ] = elem.style[ name ];
740 elem.style[ name ] = options[ name ];
743 callback.call( elem );
745 // Revert the old values
746 for ( var name in options )
747 elem.style[ name ] = old[ name ];
750 css: function( elem, name, force, extra ) {
751 if ( name == "width" || name == "height" ) {
752 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
755 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
757 if ( extra === "border" )
760 jQuery.each( which, function() {
762 val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
763 if ( extra === "margin" )
764 val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
766 val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
770 if ( elem.offsetWidth !== 0 )
773 jQuery.swap( elem, props, getWH );
775 return Math.max(0, Math.round(val));
778 return jQuery.curCSS( elem, name, force );
781 curCSS: function( elem, name, force ) {
782 var ret, style = elem.style;
784 // We need to handle opacity special in IE
785 if ( name == "opacity" && !jQuery.support.opacity ) {
786 ret = jQuery.attr( style, "opacity" );
793 // Make sure we're using the right name for getting the float value
794 if ( name.match( /float/i ) )
797 if ( !force && style && style[ name ] )
800 else if ( defaultView.getComputedStyle ) {
802 // Only "float" is needed here
803 if ( name.match( /float/i ) )
806 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
808 var computedStyle = defaultView.getComputedStyle( elem, null );
811 ret = computedStyle.getPropertyValue( name );
813 // We should always get a number back from opacity
814 if ( name == "opacity" && ret == "" )
817 } else if ( elem.currentStyle ) {
818 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
819 return letter.toUpperCase();
822 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
824 // From the awesome hack by Dean Edwards
825 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
827 // If we're not dealing with a regular pixel number
828 // but a number that has a weird ending, we need to convert it to pixels
829 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
830 // Remember the original values
831 var left = style.left, rsLeft = elem.runtimeStyle.left;
833 // Put in the new values to get a computed value out
834 elem.runtimeStyle.left = elem.currentStyle.left;
835 style.left = ret || 0;
836 ret = style.pixelLeft + "px";
838 // Revert the changed values
840 elem.runtimeStyle.left = rsLeft;
847 clean: function( elems, context, fragment ) {
848 context = context || document;
850 // !context.createElement fails in IE with an error but returns typeof 'object'
851 if ( typeof context.createElement === "undefined" )
852 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
854 // If a single string is passed in and it's a single tag
855 // just do a createElement and skip the rest
856 if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
857 var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
859 return [ context.createElement( match[1] ) ];
862 var ret = [], scripts = [], div = context.createElement("div");
864 jQuery.each(elems, function(i, elem){
865 if ( typeof elem === "number" )
871 // Convert html string into DOM nodes
872 if ( typeof elem === "string" ) {
873 // Fix "XHTML"-style tags in all browsers
874 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
875 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
877 front + "></" + tag + ">";
880 // Trim whitespace, otherwise indexOf won't work as expected
881 var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
884 // option or optgroup
885 !tags.indexOf("<opt") &&
886 [ 1, "<select multiple='multiple'>", "</select>" ] ||
888 !tags.indexOf("<leg") &&
889 [ 1, "<fieldset>", "</fieldset>" ] ||
891 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
892 [ 1, "<table>", "</table>" ] ||
894 !tags.indexOf("<tr") &&
895 [ 2, "<table><tbody>", "</tbody></table>" ] ||
897 // <thead> matched above
898 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
899 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
901 !tags.indexOf("<col") &&
902 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
904 // IE can't serialize <link> and <script> tags normally
905 !jQuery.support.htmlSerialize &&
906 [ 1, "div<div>", "</div>" ] ||
910 // Go to html and back, then peel off extra wrappers
911 div.innerHTML = wrap[1] + elem + wrap[2];
913 // Move to the right depth
917 // Remove IE's autoinserted <tbody> from table fragments
918 if ( !jQuery.support.tbody ) {
920 // String was a <table>, *may* have spurious <tbody>
921 var hasBody = /<tbody/i.test(elem),
922 tbody = !tags.indexOf("<table") && !hasBody ?
923 div.firstChild && div.firstChild.childNodes :
925 // String was a bare <thead> or <tfoot>
926 wrap[1] == "<table>" && !hasBody ?
930 for ( var j = tbody.length - 1; j >= 0 ; --j )
931 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
932 tbody[ j ].parentNode.removeChild( tbody[ j ] );
936 // IE completely kills leading whitespace when innerHTML is used
937 if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
938 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
940 elem = jQuery.makeArray( div.childNodes );
946 ret = jQuery.merge( ret, elem );
951 for ( var i = 0; ret[i]; i++ ) {
952 if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
953 scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
955 if ( ret[i].nodeType === 1 )
956 ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
957 fragment.appendChild( ret[i] );
967 attr: function( elem, name, value ) {
968 // don't set attributes on text and comment nodes
969 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
972 var notxml = !jQuery.isXMLDoc( elem ),
973 // Whether we are setting (or getting)
974 set = value !== undefined;
976 // Try to normalize/fix the name
977 name = notxml && jQuery.props[ name ] || name;
979 // Only do all the following if this is a node (faster for style)
980 // IE elem.getAttribute passes even for style
981 if ( elem.tagName ) {
983 // These attributes require special treatment
984 var special = /href|src|style/.test( name );
986 // Safari mis-reports the default selected property of a hidden option
987 // Accessing the parent's selectedIndex property fixes it
988 if ( name == "selected" && elem.parentNode )
989 elem.parentNode.selectedIndex;
991 // If applicable, access the attribute via the DOM 0 way
992 if ( name in elem && notxml && !special ) {
994 // We can't allow the type property to be changed (since it causes problems in IE)
995 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
996 throw "type property can't be changed";
998 elem[ name ] = value;
1001 // browsers index elements by id/name on forms, give priority to attributes.
1002 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
1003 return elem.getAttributeNode( name ).nodeValue;
1005 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
1006 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
1007 if ( name == "tabIndex" ) {
1008 var attributeNode = elem.getAttributeNode( "tabIndex" );
1009 return attributeNode && attributeNode.specified
1010 ? attributeNode.value
1011 : elem.nodeName.match(/(button|input|object|select|textarea)/i)
1013 : elem.nodeName.match(/^(a|area)$/i) && elem.href
1018 return elem[ name ];
1021 if ( !jQuery.support.style && notxml && name == "style" )
1022 return jQuery.attr( elem.style, "cssText", value );
1025 // convert the value to a string (all browsers do this but IE) see #1070
1026 elem.setAttribute( name, "" + value );
1028 var attr = !jQuery.support.hrefNormalized && notxml && special
1029 // Some attributes require a special call on IE
1030 ? elem.getAttribute( name, 2 )
1031 : elem.getAttribute( name );
1033 // Non-existent attributes return null, we normalize to undefined
1034 return attr === null ? undefined : attr;
1037 // elem is actually elem.style ... set the style
1039 // IE uses filters for opacity
1040 if ( !jQuery.support.opacity && name == "opacity" ) {
1042 // IE has trouble with opacity if it does not have layout
1043 // Force it by setting the zoom level
1046 // Set the alpha filter to set the opacity
1047 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
1048 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
1051 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
1052 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
1056 name = name.replace(/-([a-z])/ig, function(all, letter){
1057 return letter.toUpperCase();
1061 elem[ name ] = value;
1063 return elem[ name ];
1066 trim: function( text ) {
1067 return (text || "").replace( /^\s+|\s+$/g, "" );
1070 makeArray: function( array ) {
1073 if( array != null ){
1074 var i = array.length;
1075 // The window, strings (and functions) also have 'length'
1076 if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
1080 ret[--i] = array[i];
1086 inArray: function( elem, array ) {
1087 for ( var i = 0, length = array.length; i < length; i++ )
1088 // Use === because on IE, window == document
1089 if ( array[ i ] === elem )
1095 merge: function( first, second ) {
1096 // We have to loop this way because IE & Opera overwrite the length
1097 // expando of getElementsByTagName
1098 var i = 0, elem, pos = first.length;
1099 // Also, we need to make sure that the correct elements are being returned
1100 // (IE returns comment nodes in a '*' query)
1101 if ( !jQuery.support.getAll ) {
1102 while ( (elem = second[ i++ ]) != null )
1103 if ( elem.nodeType != 8 )
1104 first[ pos++ ] = elem;
1107 while ( (elem = second[ i++ ]) != null )
1108 first[ pos++ ] = elem;
1113 unique: function( array ) {
1114 var ret = [], done = {};
1118 for ( var i = 0, length = array.length; i < length; i++ ) {
1119 var id = jQuery.data( array[ i ] );
1121 if ( !done[ id ] ) {
1123 ret.push( array[ i ] );
1134 grep: function( elems, callback, inv ) {
1137 // Go through the array, only saving the items
1138 // that pass the validator function
1139 for ( var i = 0, length = elems.length; i < length; i++ )
1140 if ( !inv != !callback( elems[ i ], i ) )
1141 ret.push( elems[ i ] );
1146 map: function( elems, callback ) {
1149 // Go through the array, translating each of the items to their
1150 // new value (or values).
1151 for ( var i = 0, length = elems.length; i < length; i++ ) {
1152 var value = callback( elems[ i ], i );
1154 if ( value != null )
1155 ret[ ret.length ] = value;
1158 return ret.concat.apply( [], ret );
1162 // Use of jQuery.browser is deprecated.
1163 // It's included for backwards compatibility and plugins,
1164 // although they should work to migrate away.
1166 var userAgent = navigator.userAgent.toLowerCase();
1168 // Figure out what browser is being used
1170 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
1171 safari: /webkit/.test( userAgent ),
1172 opera: /opera/.test( userAgent ),
1173 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
1174 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
1178 parent: function(elem){return elem.parentNode;},
1179 parents: function(elem){return jQuery.dir(elem,"parentNode");},
1180 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
1181 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
1182 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
1183 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
1184 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
1185 children: function(elem){return jQuery.sibling(elem.firstChild);},
1186 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
1187 }, function(name, fn){
1188 jQuery.fn[ name ] = function( selector ) {
1189 var ret = jQuery.map( this, fn );
1191 if ( selector && typeof selector == "string" )
1192 ret = jQuery.multiFilter( selector, ret );
1194 return this.pushStack( jQuery.unique( ret ), name, selector );
1200 prependTo: "prepend",
1201 insertBefore: "before",
1202 insertAfter: "after",
1203 replaceAll: "replaceWith"
1204 }, function(name, original){
1205 jQuery.fn[ name ] = function( selector ) {
1206 var ret = [], insert = jQuery( selector );
1208 for ( var i = 0, l = insert.length; i < l; i++ ) {
1209 var elems = (i > 0 ? this.clone(true) : this).get();
1210 jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211 ret = ret.concat( elems );
1214 return this.pushStack( ret, name, selector );
1219 removeAttr: function( name ) {
1220 jQuery.attr( this, name, "" );
1221 if (this.nodeType == 1)
1222 this.removeAttribute( name );
1225 addClass: function( classNames ) {
1226 jQuery.className.add( this, classNames );
1229 removeClass: function( classNames ) {
1230 jQuery.className.remove( this, classNames );
1233 toggleClass: function( classNames, state ) {
1234 if( typeof state !== "boolean" )
1235 state = !jQuery.className.has( this, classNames );
1236 jQuery.className[ state ? "add" : "remove" ]( this, classNames );
1239 remove: function( selector ) {
1240 if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
1241 // Prevent memory leaks
1242 jQuery( "*", this ).add([this]).each(function(){
1243 jQuery.event.remove(this);
1244 jQuery.removeData(this);
1246 if (this.parentNode)
1247 this.parentNode.removeChild( this );
1252 // Remove element nodes and prevent memory leaks
1253 jQuery(this).children().remove();
1255 // Remove any remaining nodes
1256 while ( this.firstChild )
1257 this.removeChild( this.firstChild );
1259 }, function(name, fn){
1260 jQuery.fn[ name ] = function(){
1261 return this.each( fn, arguments );
1265 // Helper function used by the dimensions and offset modules
1266 function num(elem, prop) {
1267 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
1269 var expando = "jQuery" + now(), uuid = 0, windowData = {};
\r
1274 data: function( elem, name, data ) {
\r
1275 elem = elem == window ?
\r
1279 var id = elem[ expando ];
\r
1281 // Compute a unique ID for the element
\r
1283 id = elem[ expando ] = ++uuid;
\r
1285 // Only generate the data cache if we're
\r
1286 // trying to access or manipulate it
\r
1287 if ( name && !jQuery.cache[ id ] )
\r
1288 jQuery.cache[ id ] = {};
\r
1290 // Prevent overriding the named cache with undefined values
\r
1291 if ( data !== undefined )
\r
1292 jQuery.cache[ id ][ name ] = data;
\r
1294 // Return the named cache data, or the ID for the element
\r
1296 jQuery.cache[ id ][ name ] :
\r
1300 removeData: function( elem, name ) {
\r
1301 elem = elem == window ?
\r
1305 var id = elem[ expando ];
\r
1307 // If we want to remove a specific section of the element's data
\r
1309 if ( jQuery.cache[ id ] ) {
\r
1310 // Remove the section of cache data
\r
1311 delete jQuery.cache[ id ][ name ];
\r
1313 // If we've removed all the data, remove the element's cache
\r
1316 for ( name in jQuery.cache[ id ] )
\r
1320 jQuery.removeData( elem );
\r
1323 // Otherwise, we want to remove all of the element's data
\r
1325 // Clean up the element expando
\r
1327 delete elem[ expando ];
\r
1329 // IE has trouble directly removing the expando
\r
1330 // but it's ok with using removeAttribute
\r
1331 if ( elem.removeAttribute )
\r
1332 elem.removeAttribute( expando );
\r
1335 // Completely remove the data cache
\r
1336 delete jQuery.cache[ id ];
\r
1339 queue: function( elem, type, data ) {
\r
1342 type = (type || "fx") + "queue";
\r
1344 var q = jQuery.data( elem, type );
\r
1346 if ( !q || jQuery.isArray(data) )
\r
1347 q = jQuery.data( elem, type, jQuery.makeArray(data) );
\r
1355 dequeue: function( elem, type ){
\r
1356 var queue = jQuery.queue( elem, type ),
\r
1357 fn = queue.shift();
\r
1359 if( !type || type === "fx" )
\r
1362 if( fn !== undefined )
\r
1367 jQuery.fn.extend({
\r
1368 data: function( key, value ){
\r
1369 var parts = key.split(".");
\r
1370 parts[1] = parts[1] ? "." + parts[1] : "";
\r
1372 if ( value === undefined ) {
\r
1373 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
\r
1375 if ( data === undefined && this.length )
\r
1376 data = jQuery.data( this[0], key );
\r
1378 return data === undefined && parts[1] ?
\r
1379 this.data( parts[0] ) :
\r
1382 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
\r
1383 jQuery.data( this, key, value );
\r
1387 removeData: function( key ){
\r
1388 return this.each(function(){
\r
1389 jQuery.removeData( this, key );
\r
1392 queue: function(type, data){
\r
1393 if ( typeof type !== "string" ) {
\r
1398 if ( data === undefined )
\r
1399 return jQuery.queue( this[0], type );
\r
1401 return this.each(function(){
\r
1402 var queue = jQuery.queue( this, type, data );
\r
1404 if( type == "fx" && queue.length == 1 )
\r
1405 queue[0].call(this);
\r
1408 dequeue: function(type){
\r
1409 return this.each(function(){
\r
1410 jQuery.dequeue( this, type );
\r
1414 * Sizzle CSS Selector Engine - v0.9.3
1415 * Copyright 2009, The Dojo Foundation
1416 * Released under the MIT, BSD, and GPL Licenses.
1417 * More information: http://sizzlejs.com/
1421 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
1423 toString = Object.prototype.toString;
1425 var Sizzle = function(selector, context, results, seed) {
1426 results = results || [];
1427 context = context || document;
1429 if ( context.nodeType !== 1 && context.nodeType !== 9 )
1432 if ( !selector || typeof selector !== "string" ) {
1436 var parts = [], m, set, checkSet, check, mode, extra, prune = true;
1438 // Reset the position of the chunker regexp (start from head)
1439 chunker.lastIndex = 0;
1441 while ( (m = chunker.exec(selector)) !== null ) {
1445 extra = RegExp.rightContext;
1450 if ( parts.length > 1 && origPOS.exec( selector ) ) {
1451 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
1452 set = posProcess( parts[0] + parts[1], context );
1454 set = Expr.relative[ parts[0] ] ?
1456 Sizzle( parts.shift(), context );
1458 while ( parts.length ) {
1459 selector = parts.shift();
1461 if ( Expr.relative[ selector ] )
1462 selector += parts.shift();
1464 set = posProcess( selector, set );
1469 { expr: parts.pop(), set: makeArray(seed) } :
1470 Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
1471 set = Sizzle.filter( ret.expr, ret.set );
1473 if ( parts.length > 0 ) {
1474 checkSet = makeArray(set);
1479 while ( parts.length ) {
1480 var cur = parts.pop(), pop = cur;
1482 if ( !Expr.relative[ cur ] ) {
1488 if ( pop == null ) {
1492 Expr.relative[ cur ]( checkSet, pop, isXML(context) );
1501 throw "Syntax error, unrecognized expression: " + (cur || selector);
1504 if ( toString.call(checkSet) === "[object Array]" ) {
1506 results.push.apply( results, checkSet );
1507 } else if ( context.nodeType === 1 ) {
1508 for ( var i = 0; checkSet[i] != null; i++ ) {
1509 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
1510 results.push( set[i] );
1514 for ( var i = 0; checkSet[i] != null; i++ ) {
1515 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
1516 results.push( set[i] );
1521 makeArray( checkSet, results );
1525 Sizzle( extra, context, results, seed );
1528 hasDuplicate = false;
1529 results.sort(sortOrder);
1531 if ( hasDuplicate ) {
1532 for ( var i = 1; i < results.length; i++ ) {
1533 if ( results[i] === results[i-1] ) {
1534 results.splice(i--, 1);
1544 Sizzle.matches = function(expr, set){
1545 return Sizzle(expr, null, null, set);
1548 Sizzle.find = function(expr, context, isXML){
1555 for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
1556 var type = Expr.order[i], match;
1558 if ( (match = Expr.match[ type ].exec( expr )) ) {
1559 var left = RegExp.leftContext;
1561 if ( left.substr( left.length - 1 ) !== "\\" ) {
1562 match[1] = (match[1] || "").replace(/\\/g, "");
1563 set = Expr.find[ type ]( match, context, isXML );
1564 if ( set != null ) {
1565 expr = expr.replace( Expr.match[ type ], "" );
1573 set = context.getElementsByTagName("*");
1576 return {set: set, expr: expr};
1579 Sizzle.filter = function(expr, set, inplace, not){
1580 var old = expr, result = [], curLoop = set, match, anyFound,
1581 isXMLFilter = set && set[0] && isXML(set[0]);
1583 while ( expr && set.length ) {
1584 for ( var type in Expr.filter ) {
1585 if ( (match = Expr.match[ type ].exec( expr )) != null ) {
1586 var filter = Expr.filter[ type ], found, item;
1589 if ( curLoop == result ) {
1593 if ( Expr.preFilter[ type ] ) {
1594 match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
1597 anyFound = found = true;
1598 } else if ( match === true ) {
1604 for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
1606 found = filter( item, match, i, curLoop );
1607 var pass = not ^ !!found;
1609 if ( inplace && found != null ) {
1615 } else if ( pass ) {
1616 result.push( item );
1623 if ( found !== undefined ) {
1628 expr = expr.replace( Expr.match[ type ], "" );
1639 // Improper expression
1640 if ( expr == old ) {
1641 if ( anyFound == null ) {
1642 throw "Syntax error, unrecognized expression: " + expr;
1654 var Expr = Sizzle.selectors = {
1655 order: [ "ID", "NAME", "TAG" ],
1657 ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1658 CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
1659 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
1660 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
1661 TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
1662 CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
1663 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
1664 PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
1667 "class": "className",
1671 href: function(elem){
1672 return elem.getAttribute("href");
1676 "+": function(checkSet, part, isXML){
1677 var isPartStr = typeof part === "string",
1678 isTag = isPartStr && !/\W/.test(part),
1679 isPartStrNotTag = isPartStr && !isTag;
1681 if ( isTag && !isXML ) {
1682 part = part.toUpperCase();
1685 for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
1686 if ( (elem = checkSet[i]) ) {
1687 while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
1689 checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
1695 if ( isPartStrNotTag ) {
1696 Sizzle.filter( part, checkSet, true );
1699 ">": function(checkSet, part, isXML){
1700 var isPartStr = typeof part === "string";
1702 if ( isPartStr && !/\W/.test(part) ) {
1703 part = isXML ? part : part.toUpperCase();
1705 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1706 var elem = checkSet[i];
1708 var parent = elem.parentNode;
1709 checkSet[i] = parent.nodeName === part ? parent : false;
1713 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
1714 var elem = checkSet[i];
1716 checkSet[i] = isPartStr ?
1718 elem.parentNode === part;
1723 Sizzle.filter( part, checkSet, true );
1727 "": function(checkSet, part, isXML){
1728 var doneName = done++, checkFn = dirCheck;
1730 if ( !part.match(/\W/) ) {
1731 var nodeCheck = part = isXML ? part : part.toUpperCase();
1732 checkFn = dirNodeCheck;
1735 checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
1737 "~": function(checkSet, part, isXML){
1738 var doneName = done++, checkFn = dirCheck;
1740 if ( typeof part === "string" && !part.match(/\W/) ) {
1741 var nodeCheck = part = isXML ? part : part.toUpperCase();
1742 checkFn = dirNodeCheck;
1745 checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
1749 ID: function(match, context, isXML){
1750 if ( typeof context.getElementById !== "undefined" && !isXML ) {
1751 var m = context.getElementById(match[1]);
1752 return m ? [m] : [];
1755 NAME: function(match, context, isXML){
1756 if ( typeof context.getElementsByName !== "undefined" ) {
1757 var ret = [], results = context.getElementsByName(match[1]);
1759 for ( var i = 0, l = results.length; i < l; i++ ) {
1760 if ( results[i].getAttribute("name") === match[1] ) {
1761 ret.push( results[i] );
1765 return ret.length === 0 ? null : ret;
1768 TAG: function(match, context){
1769 return context.getElementsByTagName(match[1]);
1773 CLASS: function(match, curLoop, inplace, result, not, isXML){
1774 match = " " + match[1].replace(/\\/g, "") + " ";
1780 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
1782 if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
1784 result.push( elem );
1785 } else if ( inplace ) {
1793 ID: function(match){
1794 return match[1].replace(/\\/g, "");
1796 TAG: function(match, curLoop){
1797 for ( var i = 0; curLoop[i] === false; i++ ){}
1798 return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
1800 CHILD: function(match){
1801 if ( match[1] == "nth" ) {
1802 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
1803 var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
1804 match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
1805 !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
1807 // calculate the numbers (first)n+(last) including if they are negative
1808 match[2] = (test[1] + (test[2] || 1)) - 0;
1809 match[3] = test[3] - 0;
1812 // TODO: Move to normal caching system
1817 ATTR: function(match, curLoop, inplace, result, not, isXML){
1818 var name = match[1].replace(/\\/g, "");
1820 if ( !isXML && Expr.attrMap[name] ) {
1821 match[1] = Expr.attrMap[name];
1824 if ( match[2] === "~=" ) {
1825 match[4] = " " + match[4] + " ";
1830 PSEUDO: function(match, curLoop, inplace, result, not){
1831 if ( match[1] === "not" ) {
1832 // If we're dealing with a complex expression, or a simple one
1833 if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
1834 match[3] = Sizzle(match[3], null, null, curLoop);
1836 var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
1838 result.push.apply( result, ret );
1842 } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
1848 POS: function(match){
1849 match.unshift( true );
1854 enabled: function(elem){
1855 return elem.disabled === false && elem.type !== "hidden";
1857 disabled: function(elem){
1858 return elem.disabled === true;
1860 checked: function(elem){
1861 return elem.checked === true;
1863 selected: function(elem){
1864 // Accessing this property makes selected-by-default
1865 // options in Safari work properly
1866 elem.parentNode.selectedIndex;
1867 return elem.selected === true;
1869 parent: function(elem){
1870 return !!elem.firstChild;
1872 empty: function(elem){
1873 return !elem.firstChild;
1875 has: function(elem, i, match){
1876 return !!Sizzle( match[3], elem ).length;
1878 header: function(elem){
1879 return /h\d/i.test( elem.nodeName );
1881 text: function(elem){
1882 return "text" === elem.type;
1884 radio: function(elem){
1885 return "radio" === elem.type;
1887 checkbox: function(elem){
1888 return "checkbox" === elem.type;
1890 file: function(elem){
1891 return "file" === elem.type;
1893 password: function(elem){
1894 return "password" === elem.type;
1896 submit: function(elem){
1897 return "submit" === elem.type;
1899 image: function(elem){
1900 return "image" === elem.type;
1902 reset: function(elem){
1903 return "reset" === elem.type;
1905 button: function(elem){
1906 return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
1908 input: function(elem){
1909 return /input|select|textarea|button/i.test(elem.nodeName);
1913 first: function(elem, i){
1916 last: function(elem, i, match, array){
1917 return i === array.length - 1;
1919 even: function(elem, i){
1922 odd: function(elem, i){
1925 lt: function(elem, i, match){
1926 return i < match[3] - 0;
1928 gt: function(elem, i, match){
1929 return i > match[3] - 0;
1931 nth: function(elem, i, match){
1932 return match[3] - 0 == i;
1934 eq: function(elem, i, match){
1935 return match[3] - 0 == i;
1939 PSEUDO: function(elem, match, i, array){
1940 var name = match[1], filter = Expr.filters[ name ];
1943 return filter( elem, i, match, array );
1944 } else if ( name === "contains" ) {
1945 return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
1946 } else if ( name === "not" ) {
1949 for ( var i = 0, l = not.length; i < l; i++ ) {
1950 if ( not[i] === elem ) {
1958 CHILD: function(elem, match){
1959 var type = match[1], node = elem;
1963 while (node = node.previousSibling) {
1964 if ( node.nodeType === 1 ) return false;
1966 if ( type == 'first') return true;
1969 while (node = node.nextSibling) {
1970 if ( node.nodeType === 1 ) return false;
1974 var first = match[2], last = match[3];
1976 if ( first == 1 && last == 0 ) {
1980 var doneName = match[0],
1981 parent = elem.parentNode;
1983 if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
1985 for ( node = parent.firstChild; node; node = node.nextSibling ) {
1986 if ( node.nodeType === 1 ) {
1987 node.nodeIndex = ++count;
1990 parent.sizcache = doneName;
1993 var diff = elem.nodeIndex - last;
1997 return ( diff % first == 0 && diff / first >= 0 );
2001 ID: function(elem, match){
2002 return elem.nodeType === 1 && elem.getAttribute("id") === match;
2004 TAG: function(elem, match){
2005 return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
2007 CLASS: function(elem, match){
2008 return (" " + (elem.className || elem.getAttribute("class")) + " ")
2009 .indexOf( match ) > -1;
2011 ATTR: function(elem, match){
2012 var name = match[1],
2013 result = Expr.attrHandle[ name ] ?
2014 Expr.attrHandle[ name ]( elem ) :
2015 elem[ name ] != null ?
2017 elem.getAttribute( name ),
2018 value = result + "",
2022 return result == null ?
2027 value.indexOf(check) >= 0 :
2029 (" " + value + " ").indexOf(check) >= 0 :
2031 value && result !== false :
2035 value.indexOf(check) === 0 :
2037 value.substr(value.length - check.length) === check :
2039 value === check || value.substr(0, check.length + 1) === check + "-" :
2042 POS: function(elem, match, i, array){
2043 var name = match[2], filter = Expr.setFilters[ name ];
2046 return filter( elem, i, match, array );
2052 var origPOS = Expr.match.POS;
2054 for ( var type in Expr.match ) {
2055 Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
2058 var makeArray = function(array, results) {
2059 array = Array.prototype.slice.call( array );
2062 results.push.apply( results, array );
2069 // Perform a simple check to determine if the browser is capable of
2070 // converting a NodeList to an array using builtin methods.
2072 Array.prototype.slice.call( document.documentElement.childNodes );
2074 // Provide a fallback method if it does not work
2076 makeArray = function(array, results) {
2077 var ret = results || [];
2079 if ( toString.call(array) === "[object Array]" ) {
2080 Array.prototype.push.apply( ret, array );
2082 if ( typeof array.length === "number" ) {
2083 for ( var i = 0, l = array.length; i < l; i++ ) {
2084 ret.push( array[i] );
2087 for ( var i = 0; array[i]; i++ ) {
2088 ret.push( array[i] );
2099 if ( document.documentElement.compareDocumentPosition ) {
2100 sortOrder = function( a, b ) {
2101 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2103 hasDuplicate = true;
2107 } else if ( "sourceIndex" in document.documentElement ) {
2108 sortOrder = function( a, b ) {
2109 var ret = a.sourceIndex - b.sourceIndex;
2111 hasDuplicate = true;
2115 } else if ( document.createRange ) {
2116 sortOrder = function( a, b ) {
2117 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
2118 aRange.selectNode(a);
2119 aRange.collapse(true);
2120 bRange.selectNode(b);
2121 bRange.collapse(true);
2122 var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2124 hasDuplicate = true;
2130 // Check to see if the browser returns elements by name when
2131 // querying by getElementById (and provide a workaround)
2133 // We're going to inject a fake input element with a specified name
2134 var form = document.createElement("form"),
2135 id = "script" + (new Date).getTime();
2136 form.innerHTML = "<input name='" + id + "'/>";
2138 // Inject it into the root element, check its status, and remove it quickly
2139 var root = document.documentElement;
2140 root.insertBefore( form, root.firstChild );
2142 // The workaround has to do additional checks after a getElementById
2143 // Which slows things down for other browsers (hence the branching)
2144 if ( !!document.getElementById( id ) ) {
2145 Expr.find.ID = function(match, context, isXML){
2146 if ( typeof context.getElementById !== "undefined" && !isXML ) {
2147 var m = context.getElementById(match[1]);
2148 return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
2152 Expr.filter.ID = function(elem, match){
2153 var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
2154 return elem.nodeType === 1 && node && node.nodeValue === match;
2158 root.removeChild( form );
2162 // Check to see if the browser returns only elements
2163 // when doing getElementsByTagName("*")
2165 // Create a fake element
2166 var div = document.createElement("div");
2167 div.appendChild( document.createComment("") );
2169 // Make sure no comments are found
2170 if ( div.getElementsByTagName("*").length > 0 ) {
2171 Expr.find.TAG = function(match, context){
2172 var results = context.getElementsByTagName(match[1]);
2174 // Filter out possible comments
2175 if ( match[1] === "*" ) {
2178 for ( var i = 0; results[i]; i++ ) {
2179 if ( results[i].nodeType === 1 ) {
2180 tmp.push( results[i] );
2191 // Check to see if an attribute returns normalized href attributes
2192 div.innerHTML = "<a href='#'></a>";
2193 if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
2194 div.firstChild.getAttribute("href") !== "#" ) {
2195 Expr.attrHandle.href = function(elem){
2196 return elem.getAttribute("href", 2);
2201 if ( document.querySelectorAll ) (function(){
2202 var oldSizzle = Sizzle, div = document.createElement("div");
2203 div.innerHTML = "<p class='TEST'></p>";
2205 // Safari can't handle uppercase or unicode characters when
2207 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
2211 Sizzle = function(query, context, extra, seed){
2212 context = context || document;
2214 // Only use querySelectorAll on non-XML documents
2215 // (ID selectors don't work in non-HTML documents)
2216 if ( !seed && context.nodeType === 9 && !isXML(context) ) {
2218 return makeArray( context.querySelectorAll(query), extra );
2222 return oldSizzle(query, context, extra, seed);
2225 Sizzle.find = oldSizzle.find;
2226 Sizzle.filter = oldSizzle.filter;
2227 Sizzle.selectors = oldSizzle.selectors;
2228 Sizzle.matches = oldSizzle.matches;
2231 if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
2232 var div = document.createElement("div");
2233 div.innerHTML = "<div class='test e'></div><div class='test'></div>";
2235 // Opera can't find a second classname (in 9.6)
2236 if ( div.getElementsByClassName("e").length === 0 )
2239 // Safari caches class attributes, doesn't catch changes (in 3.2)
2240 div.lastChild.className = "e";
2242 if ( div.getElementsByClassName("e").length === 1 )
2245 Expr.order.splice(1, 0, "CLASS");
2246 Expr.find.CLASS = function(match, context, isXML) {
2247 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
2248 return context.getElementsByClassName(match[1]);
2253 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2254 var sibDir = dir == "previousSibling" && !isXML;
2255 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2256 var elem = checkSet[i];
2258 if ( sibDir && elem.nodeType === 1 ){
2259 elem.sizcache = doneName;
2266 if ( elem.sizcache === doneName ) {
2267 match = checkSet[elem.sizset];
2271 if ( elem.nodeType === 1 && !isXML ){
2272 elem.sizcache = doneName;
2276 if ( elem.nodeName === cur ) {
2284 checkSet[i] = match;
2289 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
2290 var sibDir = dir == "previousSibling" && !isXML;
2291 for ( var i = 0, l = checkSet.length; i < l; i++ ) {
2292 var elem = checkSet[i];
2294 if ( sibDir && elem.nodeType === 1 ) {
2295 elem.sizcache = doneName;
2302 if ( elem.sizcache === doneName ) {
2303 match = checkSet[elem.sizset];
2307 if ( elem.nodeType === 1 ) {
2309 elem.sizcache = doneName;
2312 if ( typeof cur !== "string" ) {
2313 if ( elem === cur ) {
2318 } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
2327 checkSet[i] = match;
2332 var contains = document.compareDocumentPosition ? function(a, b){
2333 return a.compareDocumentPosition(b) & 16;
2335 return a !== b && (a.contains ? a.contains(b) : true);
2338 var isXML = function(elem){
2339 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
2340 !!elem.ownerDocument && isXML( elem.ownerDocument );
2343 var posProcess = function(selector, context){
2344 var tmpSet = [], later = "", match,
2345 root = context.nodeType ? [context] : context;
2347 // Position selectors must be done after the filter
2348 // And so must :not(positional) so we move all PSEUDOs to the end
2349 while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
2351 selector = selector.replace( Expr.match.PSEUDO, "" );
2354 selector = Expr.relative[selector] ? selector + "*" : selector;
2356 for ( var i = 0, l = root.length; i < l; i++ ) {
2357 Sizzle( selector, root[i], tmpSet );
2360 return Sizzle.filter( later, tmpSet );
2364 jQuery.find = Sizzle;
2365 jQuery.filter = Sizzle.filter;
2366 jQuery.expr = Sizzle.selectors;
2367 jQuery.expr[":"] = jQuery.expr.filters;
2369 Sizzle.selectors.filters.hidden = function(elem){
2370 return elem.offsetWidth === 0 || elem.offsetHeight === 0;
2373 Sizzle.selectors.filters.visible = function(elem){
2374 return elem.offsetWidth > 0 || elem.offsetHeight > 0;
2377 Sizzle.selectors.filters.animated = function(elem){
2378 return jQuery.grep(jQuery.timers, function(fn){
2379 return elem === fn.elem;
2383 jQuery.multiFilter = function( expr, elems, not ) {
2385 expr = ":not(" + expr + ")";
2388 return Sizzle.matches(expr, elems);
2391 jQuery.dir = function( elem, dir ){
2392 var matched = [], cur = elem[dir];
2393 while ( cur && cur != document ) {
2394 if ( cur.nodeType == 1 )
2395 matched.push( cur );
2401 jQuery.nth = function(cur, result, dir, elem){
2402 result = result || 1;
2405 for ( ; cur; cur = cur[dir] )
2406 if ( cur.nodeType == 1 && ++num == result )
2412 jQuery.sibling = function(n, elem){
2415 for ( ; n; n = n.nextSibling ) {
2416 if ( n.nodeType == 1 && n != elem )
2425 window.Sizzle = Sizzle;
2429 * A number of helper functions used for managing events.
2430 * Many of the ideas behind this code originated from
2431 * Dean Edwards' addEvent library.
2435 // Bind an event to an element
2436 // Original by Dean Edwards
2437 add: function(elem, types, handler, data) {
2438 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2441 // For whatever reason, IE has trouble passing the window object
2442 // around, causing it to be cloned in the process
2443 if ( elem.setInterval && elem != window )
2446 // Make sure that the function being executed has a unique ID
2447 if ( !handler.guid )
2448 handler.guid = this.guid++;
2450 // if data is passed, bind to handler
2451 if ( data !== undefined ) {
2452 // Create temporary function pointer to original handler
2455 // Create unique handler function, wrapped around original handler
2456 handler = this.proxy( fn );
2458 // Store data in unique handler
2459 handler.data = data;
2462 // Init the element's event structure
2463 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
2464 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
2465 // Handle the second event of a trigger and when
2466 // an event is called after a page has unloaded
2467 return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
2468 jQuery.event.handle.apply(arguments.callee.elem, arguments) :
2471 // Add elem as a property of the handle function
2472 // This is to prevent a memory leak with non-native
2476 // Handle multiple events separated by a space
2477 // jQuery(...).bind("mouseover mouseout", fn);
2478 jQuery.each(types.split(/\s+/), function(index, type) {
2479 // Namespaced event handlers
2480 var namespaces = type.split(".");
2481 type = namespaces.shift();
2482 handler.type = namespaces.slice().sort().join(".");
2484 // Get the current list of functions bound to this event
2485 var handlers = events[type];
2487 if ( jQuery.event.specialAll[type] )
2488 jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
2490 // Init the event handler queue
2492 handlers = events[type] = {};
2494 // Check for a special event handler
2495 // Only use addEventListener/attachEvent if the special
2496 // events handler returns false
2497 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
2498 // Bind the global event handler to the element
2499 if (elem.addEventListener)
2500 elem.addEventListener(type, handle, false);
2501 else if (elem.attachEvent)
2502 elem.attachEvent("on" + type, handle);
2506 // Add the function to the element's handler list
2507 handlers[handler.guid] = handler;
2509 // Keep track of which events have been used, for global triggering
2510 jQuery.event.global[type] = true;
2513 // Nullify elem to prevent memory leaks in IE
2520 // Detach an event or set of events from an element
2521 remove: function(elem, types, handler) {
2522 // don't do events on text and comment nodes
2523 if ( elem.nodeType == 3 || elem.nodeType == 8 )
2526 var events = jQuery.data(elem, "events"), ret, index;
2529 // Unbind all events for the element
2530 if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
2531 for ( var type in events )
2532 this.remove( elem, type + (types || "") );
2534 // types is actually an event object here
2536 handler = types.handler;
2540 // Handle multiple events seperated by a space
2541 // jQuery(...).unbind("mouseover mouseout", fn);
2542 jQuery.each(types.split(/\s+/), function(index, type){
2543 // Namespaced event handlers
2544 var namespaces = type.split(".");
2545 type = namespaces.shift();
2546 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2548 if ( events[type] ) {
2549 // remove the given handler for the given type
2551 delete events[type][handler.guid];
2553 // remove all handlers for the given type
2555 for ( var handle in events[type] )
2556 // Handle the removal of namespaced events
2557 if ( namespace.test(events[type][handle].type) )
2558 delete events[type][handle];
2560 if ( jQuery.event.specialAll[type] )
2561 jQuery.event.specialAll[type].teardown.call(elem, namespaces);
2563 // remove generic event handler if no more handlers exist
2564 for ( ret in events[type] ) break;
2566 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
2567 if (elem.removeEventListener)
2568 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
2569 else if (elem.detachEvent)
2570 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
2573 delete events[type];
2579 // Remove the expando if it's no longer used
2580 for ( ret in events ) break;
2582 var handle = jQuery.data( elem, "handle" );
2583 if ( handle ) handle.elem = null;
2584 jQuery.removeData( elem, "events" );
2585 jQuery.removeData( elem, "handle" );
2590 // bubbling is internal
2591 trigger: function( event, data, elem, bubbling ) {
2592 // Event object or event type
2593 var type = event.type || event;
2596 event = typeof event === "object" ?
2597 // jQuery.Event object
2598 event[expando] ? event :
2600 jQuery.extend( jQuery.Event(type), event ) :
2601 // Just the event type (string)
2604 if ( type.indexOf("!") >= 0 ) {
2605 event.type = type = type.slice(0, -1);
2606 event.exclusive = true;
2609 // Handle a global trigger
2611 // Don't bubble custom events when global (to avoid too much overhead)
2612 event.stopPropagation();
2613 // Only trigger if we've ever bound an event for it
2614 if ( this.global[type] )
2615 jQuery.each( jQuery.cache, function(){
2616 if ( this.events && this.events[type] )
2617 jQuery.event.trigger( event, data, this.handle.elem );
2621 // Handle triggering a single element
2623 // don't do events on text and comment nodes
2624 if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
2627 // Clean up in case it is reused
2628 event.result = undefined;
2629 event.target = elem;
2631 // Clone the incoming data, if any
2632 data = jQuery.makeArray(data);
2633 data.unshift( event );
2636 event.currentTarget = elem;
2638 // Trigger the event, it is assumed that "handle" is a function
2639 var handle = jQuery.data(elem, "handle");
2641 handle.apply( elem, data );
2643 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
2644 if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
2645 event.result = false;
2647 // Trigger the native events (except for clicks on links)
2648 if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
2649 this.triggered = true;
2652 // prevent IE from throwing an error for some hidden elements
2656 this.triggered = false;
2658 if ( !event.isPropagationStopped() ) {
2659 var parent = elem.parentNode || elem.ownerDocument;
2661 jQuery.event.trigger(event, data, parent, true);
2665 handle: function(event) {
2666 // returned undefined or false
2669 event = arguments[0] = jQuery.event.fix( event || window.event );
2670 event.currentTarget = this;
2672 // Namespaced event handlers
2673 var namespaces = event.type.split(".");
2674 event.type = namespaces.shift();
2676 // Cache this now, all = true means, any handler
2677 all = !namespaces.length && !event.exclusive;
2679 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
2681 handlers = ( jQuery.data(this, "events") || {} )[event.type];
2683 for ( var j in handlers ) {
2684 var handler = handlers[j];
2686 // Filter the functions by class
2687 if ( all || namespace.test(handler.type) ) {
2688 // Pass in a reference to the handler function itself
2689 // So that we can later remove it
2690 event.handler = handler;
2691 event.data = handler.data;
2693 var ret = handler.apply(this, arguments);
2695 if( ret !== undefined ){
2697 if ( ret === false ) {
2698 event.preventDefault();
2699 event.stopPropagation();
2703 if( event.isImmediatePropagationStopped() )
2710 props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
2712 fix: function(event) {
2713 if ( event[expando] )
2716 // store a copy of the original event object
2717 // and "clone" to set read-only properties
2718 var originalEvent = event;
2719 event = jQuery.Event( originalEvent );
2721 for ( var i = this.props.length, prop; i; ){
2722 prop = this.props[ --i ];
2723 event[ prop ] = originalEvent[ prop ];
2726 // Fix target property, if necessary
2727 if ( !event.target )
2728 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
2730 // check if target is a textnode (safari)
2731 if ( event.target.nodeType == 3 )
2732 event.target = event.target.parentNode;
2734 // Add relatedTarget, if necessary
2735 if ( !event.relatedTarget && event.fromElement )
2736 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
2738 // Calculate pageX/Y if missing and clientX/Y available
2739 if ( event.pageX == null && event.clientX != null ) {
2740 var doc = document.documentElement, body = document.body;
2741 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
2742 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
2745 // Add which for key events
2746 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
2747 event.which = event.charCode || event.keyCode;
2749 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
2750 if ( !event.metaKey && event.ctrlKey )
2751 event.metaKey = event.ctrlKey;
2753 // Add which for click: 1 == left; 2 == middle; 3 == right
2754 // Note: button is not normalized, so don't use it
2755 if ( !event.which && event.button )
2756 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
2761 proxy: function( fn, proxy ){
2762 proxy = proxy || function(){ return fn.apply(this, arguments); };
2763 // Set the guid of unique handler to the same of original handler, so it can be removed
2764 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
2765 // So proxy can be declared as an argument
2771 // Make sure the ready event is setup
2773 teardown: function() {}
2779 setup: function( selector, namespaces ){
2780 jQuery.event.add( this, namespaces[0], liveHandler );
2782 teardown: function( namespaces ){
2783 if ( namespaces.length ) {
2784 var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
2786 jQuery.each( (jQuery.data(this, "events").live || {}), function(){
2787 if ( name.test(this.type) )
2792 jQuery.event.remove( this, namespaces[0], liveHandler );
2799 jQuery.Event = function( src ){
2800 // Allow instantiation without the 'new' keyword
2801 if( !this.preventDefault )
2802 return new jQuery.Event(src);
2805 if( src && src.type ){
2806 this.originalEvent = src;
2807 this.type = src.type;
2812 // timeStamp is buggy for some events on Firefox(#3843)
2813 // So we won't rely on the native value
2814 this.timeStamp = now();
2817 this[expando] = true;
2820 function returnFalse(){
2823 function returnTrue(){
2827 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
2828 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
2829 jQuery.Event.prototype = {
2830 preventDefault: function() {
2831 this.isDefaultPrevented = returnTrue;
2833 var e = this.originalEvent;
2836 // if preventDefault exists run it on the original event
2837 if (e.preventDefault)
2839 // otherwise set the returnValue property of the original event to false (IE)
2840 e.returnValue = false;
2842 stopPropagation: function() {
2843 this.isPropagationStopped = returnTrue;
2845 var e = this.originalEvent;
2848 // if stopPropagation exists run it on the original event
2849 if (e.stopPropagation)
2850 e.stopPropagation();
2851 // otherwise set the cancelBubble property of the original event to true (IE)
2852 e.cancelBubble = true;
2854 stopImmediatePropagation:function(){
2855 this.isImmediatePropagationStopped = returnTrue;
2856 this.stopPropagation();
2858 isDefaultPrevented: returnFalse,
2859 isPropagationStopped: returnFalse,
2860 isImmediatePropagationStopped: returnFalse
2862 // Checks if an event happened on an element within another element
2863 // Used in jQuery.event.special.mouseenter and mouseleave handlers
2864 var withinElement = function(event) {
2865 // Check if mouse(over|out) are still within the same parent element
2866 var parent = event.relatedTarget;
2867 // Traverse up the tree
2868 while ( parent && parent != this )
2869 try { parent = parent.parentNode; }
2870 catch(e) { parent = this; }
2872 if( parent != this ){
2873 // set the correct event type
2874 event.type = event.data;
2875 // handle event if we actually just moused on to a non sub-element
2876 jQuery.event.handle.apply( this, arguments );
2881 mouseover: 'mouseenter',
2882 mouseout: 'mouseleave'
2883 }, function( orig, fix ){
2884 jQuery.event.special[ fix ] = {
2886 jQuery.event.add( this, orig, withinElement, fix );
2888 teardown: function(){
2889 jQuery.event.remove( this, orig, withinElement );
2895 bind: function( type, data, fn ) {
2896 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
2897 jQuery.event.add( this, type, fn || data, fn && data );
2901 one: function( type, data, fn ) {
2902 var one = jQuery.event.proxy( fn || data, function(event) {
2903 jQuery(this).unbind(event, one);
2904 return (fn || data).apply( this, arguments );
2906 return this.each(function(){
2907 jQuery.event.add( this, type, one, fn && data);
2911 unbind: function( type, fn ) {
2912 return this.each(function(){
2913 jQuery.event.remove( this, type, fn );
2917 trigger: function( type, data ) {
2918 return this.each(function(){
2919 jQuery.event.trigger( type, data, this );
2923 triggerHandler: function( type, data ) {
2925 var event = jQuery.Event(type);
2926 event.preventDefault();
2927 event.stopPropagation();
2928 jQuery.event.trigger( event, data, this[0] );
2929 return event.result;
2933 toggle: function( fn ) {
2934 // Save reference to arguments for access in closure
2935 var args = arguments, i = 1;
2937 // link all the functions, so any of them can unbind this click handler
2938 while( i < args.length )
2939 jQuery.event.proxy( fn, args[i++] );
2941 return this.click( jQuery.event.proxy( fn, function(event) {
2942 // Figure out which function to execute
2943 this.lastToggle = ( this.lastToggle || 0 ) % i;
2945 // Make sure that clicks stop
2946 event.preventDefault();
2948 // and execute the function
2949 return args[ this.lastToggle++ ].apply( this, arguments ) || false;
2953 hover: function(fnOver, fnOut) {
2954 return this.mouseenter(fnOver).mouseleave(fnOut);
2957 ready: function(fn) {
2958 // Attach the listeners
2961 // If the DOM is already ready
2962 if ( jQuery.isReady )
2963 // Execute the function immediately
2964 fn.call( document, jQuery );
2966 // Otherwise, remember the function for later
2968 // Add the function to the wait list
2969 jQuery.readyList.push( fn );
2974 live: function( type, fn ){
2975 var proxy = jQuery.event.proxy( fn );
2976 proxy.guid += this.selector + type;
2978 jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
2983 die: function( type, fn ){
2984 jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
2989 function liveHandler( event ){
2990 var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
2994 jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
2995 if ( check.test(fn.type) ) {
2996 var elem = jQuery(event.target).closest(fn.data)[0];
2998 elems.push({ elem: elem, fn: fn });
3002 elems.sort(function(a,b) {
3003 return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
3006 jQuery.each(elems, function(){
3007 if ( this.fn.call(this.elem, event, this.fn.data) === false )
3008 return (stop = false);
3014 function liveConvert(type, selector){
3015 return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
3021 // Handle when the DOM is ready
3023 // Make sure that the DOM is not already loaded
3024 if ( !jQuery.isReady ) {
3025 // Remember that the DOM is ready
3026 jQuery.isReady = true;
3028 // If there are functions bound, to execute
3029 if ( jQuery.readyList ) {
3030 // Execute all of them