3 * jQuery 1.2.6 - New Wave Javascript
\r
5 * Copyright (c) 2008 John Resig (jquery.com)
\r
6 * Dual licensed under the MIT (MIT-LICENSE.txt)
\r
7 * and GPL (GPL-LICENSE.txt) licenses.
\r
9 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
\r
13 // Map over jQuery in case of overwrite
\r
14 var _jQuery = window.jQuery,
\r
15 // Map over the $ in case of overwrite
\r
18 var jQuery = window.jQuery = window.$ = function( selector, context ) {
\r
19 // The jQuery object is actually just the init constructor 'enhanced'
\r
20 return new jQuery.fn.init( selector, context );
\r
23 // A simple way to check for HTML strings or ID strings
\r
24 // (both of which we optimize for)
\r
25 var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
\r
27 // Is it a simple selector
\r
28 isSimple = /^.[^:#\[\.]*$/,
\r
30 // Will speed up references to undefined, and allows munging its name.
\r
33 jQuery.fn = jQuery.prototype = {
\r
34 init: function( selector, context ) {
\r
35 // Make sure that a selection was provided
\r
36 selector = selector || document;
\r
38 // Handle $(DOMElement)
\r
39 if ( selector.nodeType ) {
\r
44 // Handle HTML strings
\r
45 if ( typeof selector == "string" ) {
\r
46 // Are we dealing with HTML string or an ID?
\r
47 var match = quickExpr.exec( selector );
\r
49 // Verify a match, and that no context was specified for #id
\r
50 if ( match && (match[1] || !context) ) {
\r
52 // HANDLE: $(html) -> $(array)
\r
54 selector = jQuery.clean( [ match[1] ], context );
\r
58 var elem = document.getElementById( match[3] );
\r
60 // Make sure an element was located
\r
62 // Handle the case where IE and Opera return items
\r
63 // by name instead of ID
\r
64 if ( elem.id != match[3] )
\r
65 return jQuery().find( selector );
\r
67 // Otherwise, we inject the element directly into the jQuery object
\r
68 return jQuery( elem );
\r
73 // HANDLE: $(expr, [context])
\r
74 // (which is just equivalent to: $(content).find(expr)
\r
76 return jQuery( context ).find( selector );
\r
78 // HANDLE: $(function)
\r
79 // Shortcut for document ready
\r
80 } else if ( jQuery.isFunction( selector ) )
\r
81 return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );
\r
83 return this.setArray(jQuery.makeArray(selector));
\r
86 // The current version of jQuery being used
\r
89 // The number of elements contained in the matched element set
\r
94 // The number of elements contained in the matched element set
\r
97 // Get the Nth element in the matched element set OR
\r
98 // Get the whole matched element set as a clean array
\r
99 get: function( num ) {
\r
100 return num == undefined ?
\r
102 // Return a 'clean' array
\r
103 jQuery.makeArray( this ) :
\r
105 // Return just the object
\r
109 // Take an array of elements and push it onto the stack
\r
110 // (returning the new matched element set)
\r
111 pushStack: function( elems ) {
\r
112 // Build a new jQuery matched element set
\r
113 var ret = jQuery( elems );
\r
115 // Add the old object onto the stack (as a reference)
\r
116 ret.prevObject = this;
\r
118 // Return the newly-formed element set
\r
122 // Force the current matched set of elements to become
\r
123 // the specified array of elements (destroying the stack in the process)
\r
124 // You should use pushStack() in order to do this, but maintain the stack
\r
125 setArray: function( elems ) {
\r
126 // Resetting the length to 0, then using the native Array push
\r
127 // is a super-fast way to populate an object with array-like properties
\r
129 Array.prototype.push.apply( this, elems );
\r
134 // Execute a callback for every element in the matched set.
\r
135 // (You can seed the arguments with an array of args, but this is
\r
136 // only used internally.)
\r
137 each: function( callback, args ) {
\r
138 return jQuery.each( this, callback, args );
\r
141 // Determine the position of an element within
\r
142 // the matched set of elements
\r
143 index: function( elem ) {
\r
146 // Locate the position of the desired element
\r
147 return jQuery.inArray(
\r
148 // If it receives a jQuery object, the first element is used
\r
149 elem && elem.jquery ? elem[0] : elem
\r
153 attr: function( name, value, type ) {
\r
154 var options = name;
\r
156 // Look for the case where we're accessing a style value
\r
157 if ( name.constructor == String )
\r
158 if ( value === undefined )
\r
159 return this[0] && jQuery[ type || "attr" ]( this[0], name );
\r
163 options[ name ] = value;
\r
166 // Check to see if we're setting style values
\r
167 return this.each(function(i){
\r
168 // Set all the styles
\r
169 for ( name in options )
\r
174 name, jQuery.prop( this, options[ name ], type, i, name )
\r
179 css: function( key, value ) {
\r
180 // ignore negative width and height values
\r
181 if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
\r
183 return this.attr( key, value, "curCSS" );
\r
186 text: function( text ) {
\r
187 if ( typeof text != "object" && text != null )
\r
188 return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
\r
192 jQuery.each( text || this, function(){
\r
193 jQuery.each( this.childNodes, function(){
\r
194 if ( this.nodeType != 8 )
\r
195 ret += this.nodeType != 1 ?
\r
197 jQuery.fn.text( [ this ] );
\r
204 wrapAll: function( html ) {
\r
206 // The elements to wrap the target around
\r
207 jQuery( html, this[0].ownerDocument )
\r
209 .insertBefore( this[0] )
\r
213 while ( elem.firstChild )
\r
214 elem = elem.firstChild;
\r
223 wrapInner: function( html ) {
\r
224 return this.each(function(){
\r
225 jQuery( this ).contents().wrapAll( html );
\r
229 wrap: function( html ) {
\r
230 return this.each(function(){
\r
231 jQuery( this ).wrapAll( html );
\r
235 append: function() {
\r
236 return this.domManip(arguments, true, false, function(elem){
\r
237 if (this.nodeType == 1)
\r
238 this.appendChild( elem );
\r
242 prepend: function() {
\r
243 return this.domManip(arguments, true, true, function(elem){
\r
244 if (this.nodeType == 1)
\r
245 this.insertBefore( elem, this.firstChild );
\r
249 before: function() {
\r
250 return this.domManip(arguments, false, false, function(elem){
\r
251 this.parentNode.insertBefore( elem, this );
\r
255 after: function() {
\r
256 return this.domManip(arguments, false, true, function(elem){
\r
257 this.parentNode.insertBefore( elem, this.nextSibling );
\r
262 return this.prevObject || jQuery( [] );
\r
265 find: function( selector ) {
\r
266 var elems = jQuery.map(this, function(elem){
\r
267 return jQuery.find( selector, elem );
\r
270 return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?
\r
271 jQuery.unique( elems ) :
\r
275 clone: function( events ) {
\r
277 var ret = this.map(function(){
\r
278 if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
\r
279 // IE copies events bound via attachEvent when
\r
280 // using cloneNode. Calling detachEvent on the
\r
281 // clone will also remove the events from the orignal
\r
282 // In order to get around this, we use innerHTML.
\r
283 // Unfortunately, this means some modifications to
\r
284 // attributes in IE that are actually only stored
\r
285 // as properties will not be copied (such as the
\r
286 // the name attribute on an input).
\r
287 var clone = this.cloneNode(true),
\r
288 container = document.createElement("div");
\r
289 container.appendChild(clone);
\r
290 return jQuery.clean([container.innerHTML])[0];
\r
292 return this.cloneNode(true);
\r
295 // Need to set the expando to null on the cloned set if it exists
\r
296 // removeData doesn't work here, IE removes it from the original as well
\r
297 // this is primarily for IE but the data expando shouldn't be copied over in any browser
\r
298 var clone = ret.find("*").andSelf().each(function(){
\r
299 if ( this[ expando ] != undefined )
\r
300 this[ expando ] = null;
\r
303 // Copy the events from the original to the clone
\r
304 if ( events === true )
\r
305 this.find("*").andSelf().each(function(i){
\r
306 if (this.nodeType == 3)
\r
308 var events = jQuery.data( this, "events" );
\r
310 for ( var type in events )
\r
311 for ( var handler in events[ type ] )
\r
312 jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
\r
315 // Return the cloned set
\r
319 filter: function( selector ) {
\r
320 return this.pushStack(
\r
321 jQuery.isFunction( selector ) &&
\r
322 jQuery.grep(this, function(elem, i){
\r
323 return selector.call( elem, i );
\r
326 jQuery.multiFilter( selector, this ) );
\r
329 not: function( selector ) {
\r
330 if ( selector.constructor == String )
\r
331 // test special case where just one selector is passed in
\r
332 if ( isSimple.test( selector ) )
\r
333 return this.pushStack( jQuery.multiFilter( selector, this, true ) );
\r
335 selector = jQuery.multiFilter( selector, this );
\r
337 var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
\r
338 return this.filter(function() {
\r
339 return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
\r
343 add: function( selector ) {
\r
344 return this.pushStack( jQuery.unique( jQuery.merge(
\r
346 typeof selector == 'string' ?
\r
347 jQuery( selector ) :
\r
348 jQuery.makeArray( selector )
\r
352 is: function( selector ) {
\r
353 return !!selector && jQuery.multiFilter( selector, this ).length > 0;
\r
356 hasClass: function( selector ) {
\r
357 return this.is( "." + selector );
\r
360 val: function( value ) {
\r
361 if ( value == undefined ) {
\r
363 if ( this.length ) {
\r
364 var elem = this[0];
\r
366 // We need to handle select boxes special
\r
367 if ( jQuery.nodeName( elem, "select" ) ) {
\r
368 var index = elem.selectedIndex,
\r
370 options = elem.options,
\r
371 one = elem.type == "select-one";
\r
373 // Nothing was selected
\r
377 // Loop through all the selected options
\r
378 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
\r
379 var option = options[ i ];
\r
381 if ( option.selected ) {
\r
382 // Get the specifc value for the option
\r
383 value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
\r
385 // We don't need an array for one selects
\r
389 // Multi-Selects return an array
\r
390 values.push( value );
\r
396 // Everything else, we just grab the value
\r
398 return (this[0].value || "").replace(/\r/g, "");
\r
405 if( value.constructor == Number )
\r
408 return this.each(function(){
\r
409 if ( this.nodeType != 1 )
\r
412 if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
\r
413 this.checked = (jQuery.inArray(this.value, value) >= 0 ||
\r
414 jQuery.inArray(this.name, value) >= 0);
\r
416 else if ( jQuery.nodeName( this, "select" ) ) {
\r
417 var values = jQuery.makeArray(value);
\r
419 jQuery( "option", this ).each(function(){
\r
420 this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
\r
421 jQuery.inArray( this.text, values ) >= 0);
\r
424 if ( !values.length )
\r
425 this.selectedIndex = -1;
\r
428 this.value = value;
\r
432 html: function( value ) {
\r
433 return value == undefined ?
\r
435 this[0].innerHTML :
\r
437 this.empty().append( value );
\r
440 replaceWith: function( value ) {
\r
441 return this.after( value ).remove();
\r
444 eq: function( i ) {
\r
445 return this.slice( i, i + 1 );
\r
448 slice: function() {
\r
449 return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
\r
452 map: function( callback ) {
\r
453 return this.pushStack( jQuery.map(this, function(elem, i){
\r
454 return callback.call( elem, i, elem );
\r
458 andSelf: function() {
\r
459 return this.add( this.prevObject );
\r
462 data: function( key, value ){
\r
463 var parts = key.split(".");
\r
464 parts[1] = parts[1] ? "." + parts[1] : "";
\r
466 if ( value === undefined ) {
\r
467 var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
\r
469 if ( data === undefined && this.length )
\r
470 data = jQuery.data( this[0], key );
\r
472 return data === undefined && parts[1] ?
\r
473 this.data( parts[0] ) :
\r
476 return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
\r
477 jQuery.data( this, key, value );
\r
481 removeData: function( key ){
\r
482 return this.each(function(){
\r
483 jQuery.removeData( this, key );
\r
487 domManip: function( args, table, reverse, callback ) {
\r
488 var clone = this.length > 1, elems;
\r
490 return this.each(function(){
\r
492 elems = jQuery.clean( args, this.ownerDocument );
\r
500 if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
\r
501 obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );
\r
503 var scripts = jQuery( [] );
\r
505 jQuery.each(elems, function(){
\r
507 jQuery( this ).clone( true )[0] :
\r
510 // execute all scripts after the elements have been injected
\r
511 if ( jQuery.nodeName( elem, "script" ) )
\r
512 scripts = scripts.add( elem );
\r
514 // Remove any inner scripts for later evaluation
\r
515 if ( elem.nodeType == 1 )
\r
516 scripts = scripts.add( jQuery( "script", elem ).remove() );
\r
518 // Inject the elements into the document
\r
519 callback.call( obj, elem );
\r
523 scripts.each( evalScript );
\r
528 // Give the init function the jQuery prototype for later instantiation
\r
529 jQuery.fn.init.prototype = jQuery.fn;
\r
531 function evalScript( i, elem ) {
\r
540 jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
\r
542 if ( elem.parentNode )
\r
543 elem.parentNode.removeChild( elem );
\r
550 jQuery.extend = jQuery.fn.extend = function() {
\r
551 // copy reference to target object
\r
552 var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
\r
554 // Handle a deep copy situation
\r
555 if ( target.constructor == Boolean ) {
\r
557 target = arguments[1] || {};
\r
558 // skip the boolean and the target
\r
562 // Handle case when target is a string or something (possible in deep copy)
\r
563 if ( typeof target != "object" && typeof target != "function" )
\r
566 // extend jQuery itself if only one argument is passed
\r
567 if ( length == i ) {
\r
572 for ( ; i < length; i++ )
\r
573 // Only deal with non-null/undefined values
\r
574 if ( (options = arguments[ i ]) != null )
\r
575 // Extend the base object
\r
576 for ( var name in options ) {
\r
577 var src = target[ name ], copy = options[ name ];
\r
579 // Prevent never-ending loop
\r
580 if ( target === copy )
\r
583 // Recurse if we're merging object values
\r
584 if ( deep && copy && typeof copy == "object" && !copy.nodeType )
\r
585 target[ name ] = jQuery.extend( deep,
\r
586 // Never move original objects, clone them
\r
587 src || ( copy.length != null ? [ ] : { } )
\r
590 // Don't bring in undefined values
\r
591 else if ( copy !== undefined )
\r
592 target[ name ] = copy;
\r
596 // Return the modified object
\r
600 var expando = "jQuery" + now(), uuid = 0, windowData = {},
\r
601 // exclude the following css properties to add px
\r
602 exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
\r
603 // cache defaultView
\r
604 defaultView = document.defaultView || {};
\r
607 noConflict: function( deep ) {
\r
611 window.jQuery = _jQuery;
\r
616 // See test/unit/core.js for details concerning this function.
\r
617 isFunction: function( fn ) {
\r
618 return !!fn && typeof fn != "string" && !fn.nodeName &&
\r
619 fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
\r
622 // check if an element is in a (or is an) XML document
\r
623 isXMLDoc: function( elem ) {
\r
624 return elem.documentElement && !elem.body ||
\r
625 elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
\r
628 // Evalulates a script in a global context
\r
629 globalEval: function( data ) {
\r
630 data = jQuery.trim( data );
\r
633 // Inspired by code by Andrea Giammarchi
\r
634 // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
\r
635 var head = document.getElementsByTagName("head")[0] || document.documentElement,
\r
636 script = document.createElement("script");
\r
638 script.type = "text/javascript";
\r
639 if ( jQuery.browser.msie )
\r
640 script.text = data;
\r
642 script.appendChild( document.createTextNode( data ) );
\r
644 // Use insertBefore instead of appendChild to circumvent an IE6 bug.
\r
645 // This arises when a base node is used (#2709).
\r
646 head.insertBefore( script, head.firstChild );
\r
647 head.removeChild( script );
\r
651 nodeName: function( elem, name ) {
\r
652 return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
\r
657 data: function( elem, name, data ) {
\r
658 elem = elem == window ?
\r
662 var id = elem[ expando ];
\r
664 // Compute a unique ID for the element
\r
666 id = elem[ expando ] = ++uuid;
\r
668 // Only generate the data cache if we're
\r
669 // trying to access or manipulate it
\r
670 if ( name && !jQuery.cache[ id ] )
\r
671 jQuery.cache[ id ] = {};
\r
673 // Prevent overriding the named cache with undefined values
\r
674 if ( data !== undefined )
\r
675 jQuery.cache[ id ][ name ] = data;
\r
677 // Return the named cache data, or the ID for the element
\r
679 jQuery.cache[ id ][ name ] :
\r
683 removeData: function( elem, name ) {
\r
684 elem = elem == window ?
\r
688 var id = elem[ expando ];
\r
690 // If we want to remove a specific section of the element's data
\r
692 if ( jQuery.cache[ id ] ) {
\r
693 // Remove the section of cache data
\r
694 delete jQuery.cache[ id ][ name ];
\r
696 // If we've removed all the data, remove the element's cache
\r
699 for ( name in jQuery.cache[ id ] )
\r
703 jQuery.removeData( elem );
\r
706 // Otherwise, we want to remove all of the element's data
\r
708 // Clean up the element expando
\r
710 delete elem[ expando ];
\r
712 // IE has trouble directly removing the expando
\r
713 // but it's ok with using removeAttribute
\r
714 if ( elem.removeAttribute )
\r
715 elem.removeAttribute( expando );
\r
718 // Completely remove the data cache
\r
719 delete jQuery.cache[ id ];
\r
723 // args is for internal usage only
\r
724 each: function( object, callback, args ) {
\r
725 var name, i = 0, length = object.length;
\r
728 if ( length == undefined ) {
\r
729 for ( name in object )
\r
730 if ( callback.apply( object[ name ], args ) === false )
\r
733 for ( ; i < length; )
\r
734 if ( callback.apply( object[ i++ ], args ) === false )
\r
737 // A special, fast, case for the most common use of each
\r
739 if ( length == undefined ) {
\r
740 for ( name in object )
\r
741 if ( callback.call( object[ name ], name, object[ name ] ) === false )
\r
744 for ( var value = object[0];
\r
745 i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
\r
751 prop: function( elem, value, type, i, name ) {
\r
752 // Handle executable functions
\r
753 if ( jQuery.isFunction( value ) )
\r
754 value = value.call( elem, i );
\r
756 // Handle passing in a number to a CSS property
\r
757 return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
\r
763 // internal only, use addClass("class")
\r
764 add: function( elem, classNames ) {
\r
765 jQuery.each((classNames || "").split(/\s+/), function(i, className){
\r
766 if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
\r
767 elem.className += (elem.className ? " " : "") + className;
\r
771 // internal only, use removeClass("class")
\r
772 remove: function( elem, classNames ) {
\r
773 if (elem.nodeType == 1)
\r
774 elem.className = classNames != undefined ?
\r
775 jQuery.grep(elem.className.split(/\s+/), function(className){
\r
776 return !jQuery.className.has( classNames, className );
\r
781 // internal only, use hasClass("class")
\r
782 has: function( elem, className ) {
\r
783 return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
\r
787 // A method for quickly swapping in/out CSS properties to get correct calculations
\r
788 swap: function( elem, options, callback ) {
\r
790 // Remember the old values, and insert the new ones
\r
791 for ( var name in options ) {
\r
792 old[ name ] = elem.style[ name ];
\r
793 elem.style[ name ] = options[ name ];
\r
796 callback.call( elem );
\r
798 // Revert the old values
\r
799 for ( var name in options )
\r
800 elem.style[ name ] = old[ name ];
\r
803 css: function( elem, name, force ) {
\r
804 if ( name == "width" || name == "height" ) {
\r
805 var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
\r
808 val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
\r
809 var padding = 0, border = 0;
\r
810 jQuery.each( which, function() {
\r
811 padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
\r
812 border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
\r
814 val -= Math.round(padding + border);
\r
817 if ( jQuery(elem).is(":visible") )
\r
820 jQuery.swap( elem, props, getWH );
\r
822 return Math.max(0, val);
\r
825 return jQuery.curCSS( elem, name, force );
\r
828 curCSS: function( elem, name, force ) {
\r
829 var ret, style = elem.style;
\r
831 // A helper method for determining if an element's values are broken
\r
832 function color( elem ) {
\r
833 if ( !jQuery.browser.safari )
\r
836 // defaultView is cached
\r
837 var ret = defaultView.getComputedStyle( elem, null );
\r
838 return !ret || ret.getPropertyValue("color") == "";
\r
841 // We need to handle opacity special in IE
\r
842 if ( name == "opacity" && jQuery.browser.msie ) {
\r
843 ret = jQuery.attr( style, "opacity" );
\r
849 // Opera sometimes will give the wrong display answer, this fixes it, see #2037
\r
850 if ( jQuery.browser.opera && name == "display" ) {
\r
851 var save = style.outline;
\r
852 style.outline = "0 solid black";
\r
853 style.outline = save;
\r
856 // Make sure we're using the right name for getting the float value
\r
857 if ( name.match( /float/i ) )
\r
860 if ( !force && style && style[ name ] )
\r
861 ret = style[ name ];
\r
863 else if ( defaultView.getComputedStyle ) {
\r
865 // Only "float" is needed here
\r
866 if ( name.match( /float/i ) )
\r
869 name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
\r
871 var computedStyle = defaultView.getComputedStyle( elem, null );
\r
873 if ( computedStyle && !color( elem ) )
\r
874 ret = computedStyle.getPropertyValue( name );
\r
876 // If the element isn't reporting its values properly in Safari
\r
877 // then some display: none elements are involved
\r
879 var swap = [], stack = [], a = elem, i = 0;
\r
881 // Locate all of the parent display: none elements
\r
882 for ( ; a && color(a); a = a.parentNode )
\r
885 // Go through and make them visible, but in reverse
\r
886 // (It would be better if we knew the exact display type that they had)
\r
887 for ( ; i < stack.length; i++ )
\r
888 if ( color( stack[ i ] ) ) {
\r
889 swap[ i ] = stack[ i ].style.display;
\r
890 stack[ i ].style.display = "block";
\r
893 // Since we flip the display style, we have to handle that
\r
894 // one special, otherwise get the value
\r
895 ret = name == "display" && swap[ stack.length - 1 ] != null ?
\r
897 ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";
\r
899 // Finally, revert the display styles back
\r
900 for ( i = 0; i < swap.length; i++ )
\r
901 if ( swap[ i ] != null )
\r
902 stack[ i ].style.display = swap[ i ];
\r
905 // We should always get a number back from opacity
\r
906 if ( name == "opacity" && ret == "" )
\r
909 } else if ( elem.currentStyle ) {
\r
910 var camelCase = name.replace(/\-(\w)/g, function(all, letter){
\r
911 return letter.toUpperCase();
\r
914 ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
\r
916 // From the awesome hack by Dean Edwards
\r
917 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
\r
919 // If we're not dealing with a regular pixel number
\r
920 // but a number that has a weird ending, we need to convert it to pixels
\r
921 if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
\r
922 // Remember the original values
\r
923 var left = style.left, rsLeft = elem.runtimeStyle.left;
\r
925 // Put in the new values to get a computed value out
\r
926 elem.runtimeStyle.left = elem.currentStyle.left;
\r
927 style.left = ret || 0;
\r
928 ret = style.pixelLeft + "px";
\r
930 // Revert the changed values
\r
932 elem.runtimeStyle.left = rsLeft;
\r
939 clean: function( elems, context ) {
\r
941 context = context || document;
\r
942 // !context.createElement fails in IE with an error but returns typeof 'object'
\r
943 if (typeof context.createElement == 'undefined')
\r
944 context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
\r
946 jQuery.each(elems, function(i, elem){
\r
950 if ( elem.constructor == Number )
\r
953 // Convert html string into DOM nodes
\r
954 if ( typeof elem == "string" ) {
\r
955 // Fix "XHTML"-style tags in all browsers
\r
956 elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
\r
957 return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
\r
959 front + "></" + tag + ">";
\r
962 // Trim whitespace, otherwise indexOf won't work as expected
\r
963 var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");
\r
966 // option or optgroup
\r
967 !tags.indexOf("<opt") &&
\r
968 [ 1, "<select multiple='multiple'>", "</select>" ] ||
\r
970 !tags.indexOf("<leg") &&
\r
971 [ 1, "<fieldset>", "</fieldset>" ] ||
\r
973 tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
\r
974 [ 1, "<table>", "</table>" ] ||
\r
976 !tags.indexOf("<tr") &&
\r
977 [ 2, "<table><tbody>", "</tbody></table>" ] ||
\r
979 // <thead> matched above
\r
980 (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
\r
981 [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
\r
983 !tags.indexOf("<col") &&
\r
984 [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
\r
986 // IE can't serialize <link> and <script> tags normally
\r
987 jQuery.browser.msie &&
\r
988 [ 1, "div<div>", "</div>" ] ||
\r
992 // Go to html and back, then peel off extra wrappers
\r
993 div.innerHTML = wrap[1] + elem + wrap[2];
\r
995 // Move to the right depth
\r
996 while ( wrap[0]-- )
\r
997 div = div.lastChild;
\r
999 // Remove IE's autoinserted <tbody> from table fragments
\r
1000 if ( jQuery.browser.msie ) {
\r
1002 // String was a <table>, *may* have spurious <tbody>
\r
1003 var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
\r
1004 div.firstChild && div.firstChild.childNodes :
\r
1006 // String was a bare <thead> or <tfoot>
\r
1007 wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
\r
1011 for ( var j = tbody.length - 1; j >= 0 ; --j )
\r
1012 if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
\r
1013 tbody[ j ].parentNode.removeChild( tbody[ j ] );
\r
1015 // IE completely kills leading whitespace when innerHTML is used
\r
1016 if ( /^\s/.test( elem ) )
\r
1017 div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
\r
1021 elem = jQuery.makeArray( div.childNodes );
\r
1024 if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
\r
1027 if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
\r
1031 ret = jQuery.merge( ret, elem );
\r
1038 attr: function( elem, name, value ) {
\r
1039 // don't set attributes on text and comment nodes
\r
1040 if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
\r
1043 var notxml = !jQuery.isXMLDoc( elem ),
\r
1044 // Whether we are setting (or getting)
\r
1045 set = value !== undefined,
\r
1046 msie = jQuery.browser.msie;
\r
1048 // Try to normalize/fix the name
\r
1049 name = notxml && jQuery.props[ name ] || name;
\r
1051 // Only do all the following if this is a node (faster for style)
\r
1052 // IE elem.getAttribute passes even for style
\r
1053 if ( elem.tagName ) {
\r
1055 // These attributes require special treatment
\r
1056 var special = /href|src|style/.test( name );
\r
1058 // Safari mis-reports the default selected property of a hidden option
\r
1059 // Accessing the parent's selectedIndex property fixes it
\r
1060 if ( name == "selected" && jQuery.browser.safari )
\r
1061 elem.parentNode.selectedIndex;
\r
1063 // If applicable, access the attribute via the DOM 0 way
\r
1064 if ( name in elem && notxml && !special ) {
\r
1066 // We can't allow the type property to be changed (since it causes problems in IE)
\r
1067 if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
\r
1068 throw "type property can't be changed";
\r
1070 elem[ name ] = value;
\r
1073 // browsers index elements by id/name on forms, give priority to attributes.
\r
1074 if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
\r
1075 return elem.getAttributeNode( name ).nodeValue;
\r
1077 return elem[ name ];
\r
1080 if ( msie && notxml && name == "style" )
\r
1081 return jQuery.attr( elem.style, "cssText", value );
\r
1084 // convert the value to a string (all browsers do this but IE) see #1070
\r
1085 elem.setAttribute( name, "" + value );
\r
1087 var attr = msie && notxml && special
\r
1088 // Some attributes require a special call on IE
\r
1089 ? elem.getAttribute( name, 2 )
\r
1090 : elem.getAttribute( name );
\r
1092 // Non-existent attributes return null, we normalize to undefined
\r
1093 return attr === null ? undefined : attr;
\r
1096 // elem is actually elem.style ... set the style
\r
1098 // IE uses filters for opacity
\r
1099 if ( msie && name == "opacity" ) {
\r
1101 // IE has trouble with opacity if it does not have layout
\r
1102 // Force it by setting the zoom level
\r
1105 // Set the alpha filter to set the opacity
\r
1106 elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
\r
1107 (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
\r
1110 return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
\r
1111 (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
\r
1115 name = name.replace(/-([a-z])/ig, function(all, letter){
\r
1116 return letter.toUpperCase();
\r
1120 elem[ name ] = value;
\r
1122 return elem[ name ];
\r
1125 trim: function( text ) {
\r
1126 return (text || "").replace( /^\s+|\s+$/g, "" );
\r
1129 makeArray: function( array ) {
\r
1132 if( array != null ){
\r
1133 var i = array.length;
\r
1134 //the window, strings and functions also have 'length'
\r
1135 if( i == null || array.split || array.setInterval || array.call )
\r
1139 ret[--i] = array[i];
\r
1145 inArray: function( elem, array ) {
\r
1146 for ( var i = 0, length = array.length; i < length; i++ )
\r
1147 // Use === because on IE, window == document
\r
1148 if ( array[ i ] === elem )
\r
1154 merge: function( first, second ) {
\r
1155 // We have to loop this way because IE & Opera overwrite the length
\r
1156 // expando of getElementsByTagName
\r
1157 var i = 0, elem, pos = first.length;
\r
1158 // Also, we need to make sure that the correct elements are being returned
\r
1159 // (IE returns comment nodes in a '*' query)
\r
1160 if ( jQuery.browser.msie ) {
\r
1161 while ( elem = second[ i++ ] )
\r
1162 if ( elem.nodeType != 8 )
\r
1163 first[ pos++ ] = elem;
\r
1166 while ( elem = second[ i++ ] )
\r
1167 first[ pos++ ] = elem;
\r
1172 unique: function( array ) {
\r
1173 var ret = [], done = {};
\r
1177 for ( var i = 0, length = array.length; i < length; i++ ) {
\r
1178 var id = jQuery.data( array[ i ] );
\r
1180 if ( !done[ id ] ) {
\r
1181 done[ id ] = true;
\r
1182 ret.push( array[ i ] );
\r
1193 grep: function( elems, callback, inv ) {
\r
1196 // Go through the array, only saving the items
\r
1197 // that pass the validator function
\r
1198 for ( var i = 0, length = elems.length; i < length; i++ )
\r
1199 if ( !inv != !callback( elems[ i ], i ) )
\r
1200 ret.push( elems[ i ] );
\r
1205 map: function( elems, callback ) {
\r
1208 // Go through the array, translating each of the items to their
\r
1209 // new value (or values).
\r
1210 for ( var i = 0, length = elems.length; i < length; i++ ) {
\r
1211 var value = callback( elems[ i ], i );
\r
1213 if ( value != null )
\r
1214 ret[ ret.length ] = value;
\r
1217 return ret.concat.apply( [], ret );
\r
1221 var userAgent = navigator.userAgent.toLowerCase();
\r
1223 // Figure out what browser is being used
\r
1224 jQuery.browser = {
\r
1225 version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
\r
1226 safari: /webkit/.test( userAgent ),
\r
1227 opera: /opera/.test( userAgent ),
\r
1228 msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
\r
1229 mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
\r
1232 var styleFloat = jQuery.browser.msie ?
\r
1237 // Check to see if the W3C box model is being used
\r
1238 boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
\r
1242 "class": "className",
\r
1243 "float": styleFloat,
\r
1244 cssFloat: styleFloat,
\r
1245 styleFloat: styleFloat,
\r
1246 readonly: "readOnly",
\r
1247 maxlength: "maxLength",
\r
1248 cellspacing: "cellSpacing"
\r
1253 parent: function(elem){return elem.parentNode;},
\r
1254 parents: function(elem){return jQuery.dir(elem,"parentNode");},
\r
1255 next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
\r
1256 prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
\r
1257 nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
\r
1258 prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
\r
1259 siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
\r
1260 children: function(elem){return jQuery.sibling(elem.firstChild);},
\r
1261 contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
\r
1262 }, function(name, fn){
\r
1263 jQuery.fn[ name ] = function( selector ) {
\r
1264 var ret = jQuery.map( this, fn );
\r
1266 if ( selector && typeof selector == "string" )
\r
1267 ret = jQuery.multiFilter( selector, ret );
\r
1269 return this.pushStack( jQuery.unique( ret ) );
\r
1274 appendTo: "append",
\r
1275 prependTo: "prepend",
\r
1276 insertBefore: "before",
\r
1277 insertAfter: "after",
\r
1278 replaceAll: "replaceWith"
\r
1279 }, function(name, original){
\r
1280 jQuery.fn[ name ] = function() {
\r
1281 var args = arguments;
\r
1283 return this.each(function(){
\r
1284 for ( var i = 0, length = args.length; i < length; i++ )
\r
1285 jQuery( args[ i ] )[ original ]( this );
\r
1291 removeAttr: function( name ) {
\r
1292 jQuery.attr( this, name, "" );
\r
1293 if (this.nodeType == 1)
\r
1294 this.removeAttribute( name );
\r
1297 addClass: function( classNames ) {
\r
1298 jQuery.className.add( this, classNames );
\r
1301 removeClass: function( classNames ) {
\r
1302 jQuery.className.remove( this, classNames );
\r
1305 toggleClass: function( classNames ) {
\r
1306 jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
\r
1309 remove: function( selector ) {
\r
1310 if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
\r
1311 // Prevent memory leaks
\r
1312 jQuery( "*", this ).add(this).each(function(){
\r
1313 jQuery.event.remove(this);
\r
1314 jQuery.removeData(this);
\r
1316 if (this.parentNode)
\r
1317 this.parentNode.removeChild( this );
\r
1321 empty: function() {
\r
1322 // Remove element nodes and prevent memory leaks
\r
1323 jQuery( ">*", this ).remove();
\r
1325 // Remove any remaining nodes
\r
1326 while ( this.firstChild )
\r
1327 this.removeChild( this.firstChild );
\r
1329 }, function(name, fn){
\r
1330 jQuery.fn[ name ] = function(){
\r
1331 return this.each( fn, arguments );
\r
1335 jQuery.each([ "Height", "Width" ], function(i, name){
\r
1336 var type = name.toLowerCase();
\r
1338 jQuery.fn[ type ] = function( size ) {
\r
1339 // Get window width or height
\r
1340 return this[0] == window ?
\r
1341 // Opera reports document.body.client[Width/Height] properly in both quirks and standards
\r
1342 jQuery.browser.opera && document.body[ "client" + name ] ||
\r
1344 // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
\r
1345 jQuery.browser.safari && window[ "inner" + name ] ||
\r
1347 // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
\r
1348 document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
\r
1350 // Get document width or height
\r
1351 this[0] == document ?
\r
1352 // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
\r
1354 Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
\r
1355 Math.max(document.body["offset" + name], document.documentElement["offset" + name])
\r
1358 // Get or set width or height on the element
\r
1359 size == undefined ?
\r
1360 // Get width or height on the element
\r
1361 (this.length ? jQuery.css( this[0], type ) : null) :
\r
1363 // Set the width or height on the element (default to pixels if value is unitless)
\r
1364 this.css( type, size.constructor == String ? size : size + "px" );
\r
1368 // Helper function used by the dimensions and offset modules
\r
1369 function num(elem, prop) {
\r
1370 return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
\r
1371 }var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
\r
1372 "(?:[\\w*_-]|\\\\.)" :
\r
1373 "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
\r
1374 quickChild = new RegExp("^>\\s*(" + chars + "+)"),
\r
1375 quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
\r
1376 quickClass = new RegExp("^([#.]?)(" + chars + "*)");
\r
1380 "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
\r
1381 "#": function(a,i,m){return a.getAttribute("id")==m[2];},
\r
1383 // Position Checks
\r
1384 lt: function(a,i,m){return i<m[3]-0;},
\r
1385 gt: function(a,i,m){return i>m[3]-0;},
\r
1386 nth: function(a,i,m){return m[3]-0==i;},
\r
1387 eq: function(a,i,m){return m[3]-0==i;},
\r
1388 first: function(a,i){return i==0;},
\r
1389 last: function(a,i,m,r){return i==r.length-1;},
\r
1390 even: function(a,i){return i%2==0;},
\r
1391 odd: function(a,i){return i%2;},
\r
1394 "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
\r
1395 "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
\r
1396 "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},
\r
1399 parent: function(a){return a.firstChild;},
\r
1400 empty: function(a){return !a.firstChild;},
\r
1403 contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},
\r
1406 visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
\r
1407 hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},
\r
1409 // Form attributes
\r
1410 enabled: function(a){return !a.disabled;},
\r
1411 disabled: function(a){return a.disabled;},
\r
1412 checked: function(a){return a.checked;},
\r
1413 selected: function(a){return a.selected||jQuery.attr(a,"selected");},
\r
1416 text: function(a){return "text"==a.type;},
\r
1417 radio: function(a){return "radio"==a.type;},
\r
1418 checkbox: function(a){return "checkbox"==a.type;},
\r
1419 file: function(a){return "file"==a.type;},
\r
1420 password: function(a){return "password"==a.type;},
\r
1421 submit: function(a){return "submit"==a.type;},
\r
1422 image: function(a){return "image"==a.type;},
\r
1423 reset: function(a){return "reset"==a.type;},
\r
1424 button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
\r
1425 input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},
\r
1428 has: function(a,i,m){return jQuery.find(m[3],a).length;},
\r
1431 header: function(a){return /h\d/i.test(a.nodeName);},
\r
1434 animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
\r
1438 // The regular expressions that power the parsing engine
\r
1440 // Match: [@value='test'], [@foo]
\r
1441 /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,
\r
1443 // Match: :contains('foo')
\r
1444 /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,
\r
1446 // Match: :even, :last-child, #id, .class
\r
1447 new RegExp("^([:.#]*)(" + chars + "+)")
\r
1450 multiFilter: function( expr, elems, not ) {
\r
1451 var old, cur = [];
\r
1453 while ( expr && expr != old ) {
\r
1455 var f = jQuery.filter( expr, elems, not );
\r
1456 expr = f.t.replace(/^\s*,\s*/, "" );
\r
1457 cur = not ? elems = f.r : jQuery.merge( cur, f.r );
\r
1463 find: function( t, context ) {
\r
1464 // Quickly handle non-string expressions
\r
1465 if ( typeof t != "string" )
\r
1468 // check to make sure context is a DOM element or a document
\r
1469 if ( context && context.nodeType != 1 && context.nodeType != 9)
\r
1472 // Set the correct context (if none is provided)
\r
1473 context = context || document;
\r
1475 // Initialize the search
\r
1476 var ret = [context], done = [], last, nodeName;
\r
1478 // Continue while a selector expression exists, and while
\r
1479 // we're no longer looping upon ourselves
\r
1480 while ( t && last != t ) {
\r
1484 t = jQuery.trim(t);
\r
1486 var foundToken = false,
\r
1488 // An attempt at speeding up child selectors that
\r
1489 // point to a specific element tag
\r
1495 nodeName = m[1].toUpperCase();
\r
1497 // Perform our own iteration and filter
\r
1498 for ( var i = 0; ret[i]; i++ )
\r
1499 for ( var c = ret[i].firstChild; c; c = c.nextSibling )
\r
1500 if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
\r
1504 t = t.replace( re, "" );
\r
1505 if ( t.indexOf(" ") == 0 ) continue;
\r
1506 foundToken = true;
\r
1508 re = /^([>+~])\s*(\w*)/i;
\r
1510 if ( (m = re.exec(t)) != null ) {
\r
1514 nodeName = m[2].toUpperCase();
\r
1517 for ( var j = 0, rl = ret.length; j < rl; j++ ) {
\r
1518 var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
\r
1519 for ( ; n; n = n.nextSibling )
\r
1520 if ( n.nodeType == 1 ) {
\r
1521 var id = jQuery.data(n);
\r
1523 if ( m == "~" && merge[id] ) break;
\r
1525 if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
\r
1526 if ( m == "~" ) merge[id] = true;
\r
1530 if ( m == "+" ) break;
\r
1536 // And remove the token
\r
1537 t = jQuery.trim( t.replace( re, "" ) );
\r
1538 foundToken = true;
\r
1542 // See if there's still an expression, and that we haven't already
\r
1543 // matched a token
\r
1544 if ( t && !foundToken ) {
\r
1545 // Handle multiple expressions
\r
1546 if ( !t.indexOf(",") ) {
\r
1547 // Clean the result set
\r
1548 if ( context == ret[0] ) ret.shift();
\r
1550 // Merge the result sets
\r
1551 done = jQuery.merge( done, ret );
\r
1553 // Reset the context
\r
1554 r = ret = [context];
\r
1556 // Touch up the selector string
\r
1557 t = " " + t.substr(1,t.length);
\r
1560 // Optimize for the case nodeName#idName
\r
1561 var re2 = quickID;
\r
1562 var m = re2.exec(t);
\r
1564 // Re-organize the results, so that they're consistent
\r
1566 m = [ 0, m[2], m[3], m[1] ];
\r
1569 // Otherwise, do a traditional filter check for
\r
1570 // ID, class, and element selectors
\r
1575 m[2] = m[2].replace(/\\/g, "");
\r
1577 var elem = ret[ret.length-1];
\r
1579 // Try to do a global search by ID, where we can
\r
1580 if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
\r
1581 // Optimization for HTML document case
\r
1582 var oid = elem.getElementById(m[2]);
\r
1584 // Do a quick check for the existence of the actual ID attribute
\r
1585 // to avoid selecting by the name attribute in IE
\r
1586 // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
\r
1587 if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
\r
1588 oid = jQuery('[@id="'+m[2]+'"]', elem)[0];
\r
1590 // Do a quick check for node name (where applicable) so
\r
1591 // that div#foo searches will be really fast
\r
1592 ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
\r
1594 // We need to find all descendant elements
\r
1595 for ( var i = 0; ret[i]; i++ ) {
\r
1596 // Grab the tag name being searched for
\r
1597 var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];
\r
1599 // Handle IE7 being really dumb about <object>s
\r
1600 if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
\r
1603 r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
\r
1606 // It's faster to filter by class and be done with it
\r
1607 if ( m[1] == "." )
\r
1608 r = jQuery.classFilter( r, m[2] );
\r
1610 // Same with ID filtering
\r
1611 if ( m[1] == "#" ) {
\r
1614 // Try to find the element with the ID
\r
1615 for ( var i = 0; r[i]; i++ )
\r
1616 if ( r[i].getAttribute("id") == m[2] ) {
\r
1627 t = t.replace( re2, "" );
\r
1632 // If a selector string still exists
\r
1634 // Attempt to filter it
\r
1635 var val = jQuery.filter(t,r);
\r
1637 t = jQuery.trim(val.t);
\r
1641 // An error occurred with the selector;
\r
1642 // just return an empty set instead
\r
1646 // Remove the root context
\r
1647 if ( ret && context == ret[0] )
\r
1650 // And combine the results
\r
1651 done = jQuery.merge( done, ret );
\r
1656 classFilter: function(r,m,not){
\r
1657 m = " " + m + " ";
\r
1659 for ( var i = 0; r[i]; i++ ) {
\r
1660 var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
\r
1661 if ( !not && pass || not && !pass )
\r
1667 filter: function(t,r,not) {
\r
1670 // Look for common filter expressions
\r
1671 while ( t && t != last ) {
\r
1674 var p = jQuery.parse, m;
\r
1676 for ( var i = 0; p[i]; i++ ) {
\r
1677 m = p[i].exec( t );
\r
1680 // Remove what we just matched
\r
1681 t = t.substring( m[0].length );
\r
1683 m[2] = m[2].replace(/\\/g, "");
\r
1691 // :not() is a special case that can be optimized by
\r
1692 // keeping it out of the expression list
\r
1693 if ( m[1] == ":" && m[2] == "not" )
\r
1694 // optimize if only one selector found (most common case)
\r
1695 r = isSimple.test( m[3] ) ?
\r
1696 jQuery.filter(m[3], r, true).r :
\r
1697 jQuery( r ).not( m[3] );
\r
1699 // We can get a big speed boost by filtering by class here
\r
1700 else if ( m[1] == "." )
\r
1701 r = jQuery.classFilter(r, m[2], not);
\r
1703 else if ( m[1] == "[" ) {
\r
1704 var tmp = [], type = m[3];
\r
1706 for ( var i = 0, rl = r.length; i < rl; i++ ) {
\r
1707 var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
\r
1709 if ( z == null || /href|src|selected/.test(m[2]) )
\r
1710 z = jQuery.attr(a,m[2]) || '';
\r
1712 if ( (type == "" && !!z ||
\r
1713 type == "=" && z == m[5] ||
\r
1714 type == "!=" && z != m[5] ||
\r
1715 type == "^=" && z && !z.indexOf(m[5]) ||
\r
1716 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
\r
1717 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
\r
1723 // We can get a speed boost by handling nth-child here
\r
1724 } else if ( m[1] == ":" && m[2] == "nth-child" ) {
\r
1725 var merge = {}, tmp = [],
\r
1726 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
\r
1727 test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
\r
1728 m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
\r
1729 !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
\r
1730 // calculate the numbers (first)n+(last) including if they are negative
\r
1731 first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
\r
1733 // loop through all the elements left in the jQuery object
\r
1734 for ( var i = 0, rl = r.length; i < rl; i++ ) {
\r
1735 var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);
\r
1737 if ( !merge[id] ) {
\r
1740 for ( var n = parentNode.firstChild; n; n = n.nextSibling )
\r
1741 if ( n.nodeType == 1 )
\r
1742 n.nodeIndex = c++;
\r
1749 if ( first == 0 ) {
\r
1750 if ( node.nodeIndex == last )
\r
1752 } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
\r
1761 // Otherwise, find the expression to execute
\r
1763 var fn = jQuery.expr[ m[1] ];
\r
1764 if ( typeof fn == "object" )
\r
1767 if ( typeof fn == "string" )
\r
1768 fn = eval("false||function(a,i){return " + fn + ";}");
\r
1770 // Execute it against the current filter
\r
1771 r = jQuery.grep( r, function(elem, i){
\r
1772 return fn(elem, i, m, r);
\r
1777 // Return an array of filtered elements (r)
\r
1778 // and the modified expression string (t)
\r
1779 return { r: r, t: t };
\r
1782 dir: function( elem, dir ){
\r
1785 while ( cur && cur != document ) {
\r
1786 if ( cur.nodeType == 1 )
\r
1787 matched.push( cur );
\r
1793 nth: function(cur,result,dir,elem){
\r
1794 result = result || 1;
\r
1797 for ( ; cur; cur = cur[dir] )
\r
1798 if ( cur.nodeType == 1 && ++num == result )
\r
1804 sibling: function( n, elem ) {
\r
1807 for ( ; n; n = n.nextSibling ) {
\r
1808 if ( n.nodeType == 1 && n != elem )
\r
1816 * A number of helper functions used for managing events.
\r
1817 * Many of the ideas behind this code orignated from
\r
1818 * Dean Edwards' addEvent library.
\r
1822 // Bind an event to an element
\r
1823 // Original by Dean Edwards
\r
1824 add: function(elem, types, handler, data) {
\r
1825 if ( elem.nodeType == 3 || elem.nodeType == 8 )
\r
1828 // For whatever reason, IE has trouble passing the window object
\r
1829 // around, causing it to be cloned in the process
\r
1830 if ( jQuery.browser.msie && elem.setInterval )
\r
1833 // Make sure that the function being executed has a unique ID
\r
1834 if ( !handler.guid )
\r
1835 handler.guid = this.guid++;
\r
1837 // if data is passed, bind to handler
\r
1838 if( data != undefined ) {
\r
1839 // Create temporary function pointer to original handler
\r
1842 // Create unique handler function, wrapped around original handler
\r
1843 handler = this.proxy( fn, function() {
\r
1844 // Pass arguments and context to original handler
\r
1845 return fn.apply(this, arguments);
\r
1848 // Store data in unique handler
\r
1849 handler.data = data;
\r
1852 // Init the element's event structure
\r
1853 var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
\r
1854 handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
\r
1855 // Handle the second event of a trigger and when
\r
1856 // an event is called after a page has unloaded
\r
1857 if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
\r
1858 return jQuery.event.handle.apply(arguments.callee.elem, arguments);
\r
1860 // Add elem as a property of the handle function
\r
1861 // This is to prevent a memory leak with non-native
\r
1863 handle.elem = elem;
\r
1865 // Handle multiple events separated by a space
\r
1866 // jQuery(...).bind("mouseover mouseout", fn);
\r
1867 jQuery.each(types.split(/\s+/), function(index, type) {
\r
1868 // Namespaced event handlers
\r
1869 var parts = type.split(".");
\r
1871 handler.type = parts[1];
\r
1873 // Get the current list of functions bound to this event
\r
1874 var handlers = events[type];
\r
1876 // Init the event handler queue
\r
1878 handlers = events[type] = {};
\r
1880 // Check for a special event handler
\r
1881 // Only use addEventListener/attachEvent if the special
\r
1882 // events handler returns false
\r
1883 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
\r
1884 // Bind the global event handler to the element
\r
1885 if (elem.addEventListener)
\r
1886 elem.addEventListener(type, handle, false);
\r
1887 else if (elem.attachEvent)
\r
1888 elem.attachEvent("on" + type, handle);
\r
1892 // Add the function to the element's handler list
\r
1893 handlers[handler.guid] = handler;
\r
1895 // Keep track of which events have been used, for global triggering
\r
1896 jQuery.event.global[type] = true;
\r
1899 // Nullify elem to prevent memory leaks in IE
\r
1906 // Detach an event or set of events from an element
\r
1907 remove: function(elem, types, handler) {
\r
1908 // don't do events on text and comment nodes
\r
1909 if ( elem.nodeType == 3 || elem.nodeType == 8 )
\r
1912 var events = jQuery.data(elem, "events"), ret, index;
\r
1915 // Unbind all events for the element
\r
1916 if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
\r
1917 for ( var type in events )
\r
1918 this.remove( elem, type + (types || "") );
\r
1920 // types is actually an event object here
\r
1921 if ( types.type ) {
\r
1922 handler = types.handler;
\r
1923 types = types.type;
\r
1926 // Handle multiple events seperated by a space
\r
1927 // jQuery(...).unbind("mouseover mouseout", fn);
\r
1928 jQuery.each(types.split(/\s+/), function(index, type){
\r
1929 // Namespaced event handlers
\r
1930 var parts = type.split(".");
\r
1933 if ( events[type] ) {
\r
1934 // remove the given handler for the given type
\r
1936 delete events[type][handler.guid];
\r
1938 // remove all handlers for the given type
\r
1940 for ( handler in events[type] )
\r
1941 // Handle the removal of namespaced events
\r
1942 if ( !parts[1] || events[type][handler].type == parts[1] )
\r
1943 delete events[type][handler];
\r
1945 // remove generic event handler if no more handlers exist
\r
1946 for ( ret in events[type] ) break;
\r
1948 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
\r
1949 if (elem.removeEventListener)
\r
1950 elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
\r
1951 else if (elem.detachEvent)
\r
1952 elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
\r
1955 delete events[type];
\r
1961 // Remove the expando if it's no longer used
\r
1962 for ( ret in events ) break;
\r
1964 var handle = jQuery.data( elem, "handle" );
\r
1965 if ( handle ) handle.elem = null;
\r
1966 jQuery.removeData( elem, "events" );
\r
1967 jQuery.removeData( elem, "handle" );
\r
1972 trigger: function(type, data, elem, donative, extra) {
\r
1973 // Clone the incoming data, if any
\r
1974 data = jQuery.makeArray(data);
\r
1976 if ( type.indexOf("!") >= 0 ) {
\r
1977 type = type.slice(0, -1);
\r
1978 var exclusive = true;
\r
1981 // Handle a global trigger
\r
1983 // Only trigger if we've ever bound an event for it
\r
1984 if ( this.global[type] )
\r
1985 jQuery("*").add([window, document]).trigger(type, data);
\r
1987 // Handle triggering a single element
\r
1989 // don't do events on text and comment nodes
\r
1990 if ( elem.nodeType == 3 || elem.nodeType == 8 )
\r
1993 var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
\r
1994 // Check to see if we need to provide a fake event, or not
\r
1995 event = !data[0] || !data[0].preventDefault;
\r
1997 // Pass along a fake event
\r
2002 preventDefault: function(){},
\r
2003 stopPropagation: function(){},
\r
2006 data[0][expando] = true; // no need to fix fake event
\r
2009 // Enforce the right trigger type
\r
2010 data[0].type = type;
\r
2012 data[0].exclusive = true;
\r
2014 // Trigger the event, it is assumed that "handle" is a function
\r
2015 var handle = jQuery.data(elem, "handle");
\r
2017 val = handle.apply( elem, data );
\r
2019 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
\r
2020 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
\r
2023 // Extra functions don't get the custom event object
\r
2027 // Handle triggering of extra function
\r
2028 if ( extra && jQuery.isFunction( extra ) ) {
\r
2029 // call the extra function and tack the current return value on the end for possible inspection
\r
2030 ret = extra.apply( elem, val == null ? data : data.concat( val ) );
\r
2031 // if anything is returned, give it precedence and have it overwrite the previous value
\r
2032 if (ret !== undefined)
\r
2036 // Trigger the native events (except for clicks on links)
\r
2037 if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
\r
2038 this.triggered = true;
\r
2041 // prevent IE from throwing an error for some hidden elements
\r
2045 this.triggered = false;
\r
2051 handle: function(event) {
\r
2052 // returned undefined or false
\r
2053 var val, ret, namespace, all, handlers;
\r
2055 event = arguments[0] = jQuery.event.fix( event || window.event );
\r
2057 // Namespaced event handlers
\r
2058 namespace = event.type.split(".");
\r
2059 event.type = namespace[0];
\r
2060 namespace = namespace[1];
\r
2061 // Cache this now, all = true means, any handler
\r
2062 all = !namespace && !event.exclusive;
\r
2064 handlers = ( jQuery.data(this, "events") || {} )[event.type];
\r
2066 for ( var j in handlers ) {
\r
2067 var handler = handlers[j];
\r
2069 // Filter the functions by class
\r
2070 if ( all || handler.type == namespace ) {
\r
2071 // Pass in a reference to the handler function itself
\r
2072 // So that we can later remove it
\r
2073 event.handler = handler;
\r
2074 event.data = handler.data;
\r
2076 ret = handler.apply( this, arguments );
\r
2078 if ( val !== false )
\r
2081 if ( ret === false ) {
\r
2082 event.preventDefault();
\r
2083 event.stopPropagation();
\r
2091 fix: function(event) {
\r
2092 if ( event[expando] == true )
\r
2095 // store a copy of the original event object
\r
2096 // and "clone" to set read-only properties
\r
2097 var originalEvent = event;
\r
2098 event = { originalEvent: originalEvent };
\r
2099 var 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 timeStamp toElement type view wheelDelta which".split(" ");
\r
2100 for ( var i=props.length; i; i-- )
\r
2101 event[ props[i] ] = originalEvent[ props[i] ];
\r
2103 // Mark it as fixed
\r
2104 event[expando] = true;
\r
2106 // add preventDefault and stopPropagation since
\r
2107 // they will not work on the clone
\r
2108 event.preventDefault = function() {
\r
2109 // if preventDefault exists run it on the original event
\r
2110 if (originalEvent.preventDefault)
\r
2111 originalEvent.preventDefault();
\r
2112 // otherwise set the returnValue property of the original event to false (IE)
\r
2113 originalEvent.returnValue = false;
\r
2115 event.stopPropagation = function() {
\r
2116 // if stopPropagation exists run it on the original event
\r
2117 if (originalEvent.stopPropagation)
\r
2118 originalEvent.stopPropagation();
\r
2119 // otherwise set the cancelBubble property of the original event to true (IE)
\r
2120 originalEvent.cancelBubble = true;
\r
2124 event.timeStamp = event.timeStamp || now();
\r
2126 // Fix target property, if necessary
\r
2127 if ( !event.target )
\r
2128 event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
\r
2130 // check if target is a textnode (safari)
\r
2131 if ( event.target.nodeType == 3 )
\r
2132 event.target = event.target.parentNode;
\r
2134 // Add relatedTarget, if necessary
\r
2135 if ( !event.relatedTarget && event.fromElement )
\r
2136 event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
\r
2138 // Calculate pageX/Y if missing and clientX/Y available
\r
2139 if ( event.pageX == null && event.clientX != null ) {
\r
2140 var doc = document.documentElement, body = document.body;
\r
2141 event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
\r
2142 event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
\r
2145 // Add which for key events
\r
2146 if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
\r
2147 event.which = event.charCode || event.keyCode;
\r
2149 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
\r
2150 if ( !event.metaKey && event.ctrlKey )
\r
2151 event.metaKey = event.ctrlKey;
\r
2153 // Add which for click: 1 == left; 2 == middle; 3 == right
\r
2154 // Note: button is not normalized, so don't use it
\r
2155 if ( !event.which && event.button )
\r
2156 event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
\r
2161 proxy: function( fn, proxy ){
\r
2162 // Set the guid of unique handler to the same of original handler, so it can be removed
\r
2163 proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
\r
2164 // So proxy can be declared as an argument
\r
2170 setup: function() {
\r
2171 // Make sure the ready event is setup
\r
2176 teardown: function() { return; }
\r
2180 setup: function() {
\r
2181 if ( jQuery.browser.msie ) return false;
\r
2182 jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
\r
2186 teardown: function() {
\r
2187 if ( jQuery.browser.msie ) return false;
\r
2188 jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
\r
2192 handler: function(event) {
\r
2193 // If we actually just moused on to a sub-element, ignore it
\r
2194 if ( withinElement(event, this) ) return true;
\r
2195 // Execute the right handlers by setting the event type to mouseenter
\r
2196 event.type = "mouseenter";
\r
2197 return jQuery.event.handle.apply(this, arguments);
\r
2202 setup: function() {
\r
2203 if ( jQuery.browser.msie ) return false;
\r
2204 jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
\r
2208 teardown: function() {
\r
2209 if ( jQuery.browser.msie ) return false;
\r
2210 jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
\r
2214 handler: function(event) {
\r
2215 // If we actually just moused on to a sub-element, ignore it
\r
2216 if ( withinElement(event, this) ) return true;
\r
2217 // Execute the right handlers by setting the event type to mouseleave
\r
2218 event.type = "mouseleave";
\r
2219 return jQuery.event.handle.apply(this, arguments);
\r
2225 jQuery.fn.extend({
\r
2226 bind: function( type, data, fn ) {
\r
2227 return type == "unload" ? this.one(type, data, fn) : this.each(function(){
\r
2228 jQuery.event.add( this, type, fn || data, fn && data );
\r
2232 one: function( type, data, fn ) {
\r
2233 var one = jQuery.event.proxy( fn || data, function(event) {
\r
2234 jQuery(this).unbind(event, one);
\r
2235 return (fn || data).apply( this, arguments );
\r
2237 return this.each(function(){
\r
2238 jQuery.event.add( this, type, one, fn && data);
\r
2242 unbind: function( type, fn ) {
\r
2243 return this.each(function(){
\r
2244 jQuery.event.remove( this, type, fn );
\r
2248 trigger: function( type, data, fn ) {
\r
2249 return this.each(function(){
\r
2250 jQuery.event.trigger( type, data, this, true, fn );
\r
2254 triggerHandler: function( type, data, fn ) {
\r
2255 return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
\r
2258 toggle: function( fn ) {
\r
2259 // Save reference to arguments for access in closure
\r
2260 var args = arguments, i = 1;
\r
2262 // link all the functions, so any of them can unbind this click handler
\r
2263 while( i < args.length )
\r
2264 jQuery.event.proxy( fn, args[i++] );
\r
2266 return this.click( jQuery.event.proxy( fn, function(event) {
\r
2267 // Figure out which function to execute
\r
2268 this.lastToggle = ( this.lastToggle || 0 ) % i;
\r
2270 // Make sure that clicks stop
\r
2271 event.preventDefault();
\r
2273 // and execute the function
\r
2274 return args[ this.lastToggle++ ].apply( this, arguments ) || false;
\r
2278 hover: function(fnOver, fnOut) {
\r
2279 return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
\r
2282 ready: function(fn) {
\r
2283 // Attach the listeners
\r
2286 // If the DOM is already ready
\r
2287 if ( jQuery.isReady )
\r
2288 // Execute the function immediately
\r
2289 fn.call( document, jQuery );
\r
2291 // Otherwise, remember the function for later
\r
2293 // Add the function to the wait list
\r
2294 jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
\r
2303 // Handle when the DOM is ready
\r
2304 ready: function() {
\r
2305 // Make sure that the DOM is not already loaded
\r
2306 if ( !jQuery.isReady ) {
\r
2307 // Remember that the DOM is ready
\r
2308 jQuery.isReady = true;
\r
2310 // If there are functions bound, to execute
\r
2311 if ( jQuery.readyList ) {
\r
2312 // Execute all of them
\r
2313 jQuery.each( jQuery.readyList, function(){
\r
2314 this.call( document );
\r
2317 // Reset the list of functions
\r
2318 jQuery.readyList = null;
\r
2321 // Trigger any bound ready events
\r
2322 jQuery(document).triggerHandler("ready");
\r
2327 var readyBound = false;
\r
2329 function bindReady(){
\r
2330 if ( readyBound ) return;
\r
2331 readyBound = true;
\r
2333 // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
\r
2334 if ( document.addEventListener && !jQuery.browser.opera)
\r
2335 // Use the handy event callback
\r
2336 document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
\r
2338 // If IE is used and is not in a frame
\r
2339 // Continually check to see if the document is ready
\r
2340 if ( jQuery.browser.msie && window == top ) (function(){
\r
2341 if (jQuery.isReady) return;
\r
2343 // If IE is used, use the trick by Diego Perini
\r
2344 // http://javascript.nwbox.com/IEContentLoaded/
\r
2345 document.documentElement.doScroll("left");
\r
2346 } catch( error ) {
\r
2347 setTimeout( arguments.callee, 0 );
\r
2350 // and execute any waiting functions
\r
2354 if ( jQuery.browser.opera )
\r
2355 document.addEventListener( "DOMContentLoaded", function () {
\r
2356 if (jQuery.isReady) return;
\r
2357 for (var i = 0; i < document.styleSheets.length; i++)
\r
2358 if (document.styleSheets[i].disabled) {
\r
2359 setTimeout( arguments.callee, 0 );
\r
2362 // and execute any waiting functions
\r
2366 if ( jQuery.browser.safari ) {
\r
2369 if (jQuery.isReady) return;
\r
2370 if ( document.readyState != "loaded" && document.readyState != "complete" ) {
\r
2371 setTimeout( arguments.callee, 0 );
\r
2374 if ( numStyles === undefined )
\r
2375 numStyles = jQuery("style, link[rel=stylesheet]").length;
\r
2376 if ( document.styleSheets.length != numStyles ) {
\r
2377 setTimeout( arguments.callee, 0 );
\r
2380 // and execute any waiting functions
\r
2385 // A fallback to window.onload, that will always work
\r
2386 jQuery.event.add( window, "load", jQuery.ready );
\r
2389 jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
\r
2390 "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
\r
2391 "submit,keydown,keypress,keyup,error").split(","), function(i, name){
\r
2393 // Handle event binding
\r
2394 jQuery.fn[name] = function(fn){
\r
2395 return fn ? this.bind(name, fn) : this.trigger(name);
\r
2399 // Checks if an event happened on an element within another element
\r
2400 // Used in jQuery.event.special.mouseenter and mouseleave handlers
\r
2401 var withinElement = function(event, elem) {
\r
2402 // Check if mouse(over|out) are still within the same parent element
\r
2403 var parent = event.relatedTarget;
\r
2404 // Traverse up the tree
\r
2405 while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
\r
2406 // Return true if we actually just moused on to a sub-element
\r
2407 return parent == elem;
\r
2410 // Prevent memory leaks in IE
\r
2411 // And prevent errors on refresh with events like mouseover in other browsers
\r
2412 // Window isn't included so as not to unbind existing unload events
\r
2413 jQuery(window).bind("unload", function() {
\r
2414 jQuery("*").add(document).unbind();
\r
2416 jQuery.fn.extend({
\r
2417 // Keep a copy of the old load
\r
2418 _load: jQuery.fn.load,
\r
2420 load: function( url, params, callback ) {
\r
2421 if ( typeof url != 'string' )
\r
2422 return this._load( url );
\r
2424 var off = url.indexOf(" ");
\r
2426 var selector = url.slice(off, url.length);
\r
2427 url = url.slice(0, off);
\r
2430 callback = callback || function(){};
\r
2432 // Default to a GET request
\r
2435 // If the second parameter was provided
\r
2437 // If it's a function
\r
2438 if ( jQuery.isFunction( params ) ) {
\r
2439 // We assume that it's the callback
\r
2440 callback = params;
\r
2443 // Otherwise, build a param string
\r
2445 params = jQuery.param( params );
\r
2451 // Request the remote document
\r
2457 complete: function(res, status){
\r
2458 // If successful, inject the HTML into all the matched elements
\r
2459 if ( status == "success" || status == "notmodified" )
\r
2460 // See if a selector was specified
\r
2461 self.html( selector ?
\r
2462 // Create a dummy div to hold the results
\r
2464 // inject the contents of the document in, removing the scripts
\r
2465 // to avoid any 'Permission Denied' errors in IE
\r
2466 .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
\r
2468 // Locate the specified elements
\r
2471 // If not, just inject the full result
\r
2472 res.responseText );
\r
2474 self.each( callback, [res.responseText, status, res] );
\r
2480 serialize: function() {
\r
2481 return jQuery.param(this.serializeArray());
\r
2483 serializeArray: function() {
\r
2484 return this.map(function(){
\r
2485 return jQuery.nodeName(this, "form") ?
\r
2486 jQuery.makeArray(this.elements) : this;
\r
2488 .filter(function(){
\r
2489 return this.name && !this.disabled &&
\r
2490 (this.checked || /select|textarea/i.test(this.nodeName) ||
\r
2491 /text|hidden|password/i.test(this.type));
\r
2493 .map(function(i, elem){
\r
2494 var val = jQuery(this).val();
\r
2495 return val == null ? null :
\r
2496 val.constructor == Array ?
\r
2497 jQuery.map( val, function(val, i){
\r
2498 return {name: elem.name, value: val};
\r
2500 {name: elem.name, value: val};
\r
2505 // Attach a bunch of functions for handling common AJAX events
\r
2506 jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
\r
2507 jQuery.fn[o] = function(f){
\r
2508 return this.bind(o, f);
\r
2515 get: function( url, data, callback, type ) {
\r
2516 // shift arguments if data argument was ommited
\r
2517 if ( jQuery.isFunction( data ) ) {
\r
2522 return jQuery.ajax({
\r
2526 success: callback,
\r
2531 getScript: function( url, callback ) {
\r
2532 return jQuery.get(url, null, callback, "script");
\r
2535 getJSON: function( url, data, callback ) {
\r
2536 return jQuery.get(url, data, callback, "json");
\r
2539 post: function( url, data, callback, type ) {
\r
2540 if ( jQuery.isFunction( data ) ) {
\r
2545 return jQuery.ajax({
\r
2549 success: callback,
\r
2554 ajaxSetup: function( settings ) {
\r
2555 jQuery.extend( jQuery.ajaxSettings, settings );
\r
2559 url: location.href,
\r
2563 contentType: "application/x-www-form-urlencoded",
\r
2564 processData: true,
\r
2570 xml: "application/xml, text/xml",
\r
2571 html: "text/html",
\r
2572 script: "text/javascript, application/javascript",
\r
2573 json: "application/json, text/javascript",
\r
2574 text: "text/plain",
\r
2579 // Last-Modified header cache for next request
\r
2582 ajax: function( s ) {
\r
2583 // Extend the settings, but re-extend 's' so that it can be
\r
2584 // checked again later (in the test suite, specifically)
\r
2585 s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
\r
2587 var jsonp, jsre = /=\?(&|$)/g, status, data,
\r
2588 type = s.type.toUpperCase();
\r
2590 // convert data if not already a string
\r
2591 if ( s.data && s.processData && typeof s.data != "string" )
\r
2592 s.data = jQuery.param(s.data);
\r
2594 // Handle JSONP Parameter Callbacks
\r
2595 if ( s.dataType == "jsonp" ) {
\r
2596 if ( type == "GET" ) {
\r
2597 if ( !s.url.match(jsre) )
\r
2598 s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
\r
2599 } else if ( !s.data || !s.data.match(jsre) )
\r
2600 s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
\r
2601 s.dataType = "json";
\r
2604 // Build temporary JSONP function
\r
2605 if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
\r
2606 jsonp = "jsonp" + jsc++;
\r
2608 // Replace the =? sequence both in the query string and the data
\r
2610 s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
\r
2611 s.url = s.url.replace(jsre, "=" + jsonp + "$1");
\r
2613 // We need to make sure
\r
2614 // that a JSONP style response is executed properly
\r
2615 s.dataType = "script";
\r
2617 // Handle JSONP-style loading
\r
2618 window[ jsonp ] = function(tmp){
\r
2622 // Garbage collect
\r
2623 window[ jsonp ] = undefined;
\r
2624 try{ delete window[ jsonp ]; } catch(e){}
\r
2626 head.removeChild( script );
\r
2630 if ( s.dataType == "script" && s.cache == null )
\r
2633 if ( s.cache === false && type == "GET" ) {
\r
2635 // try replacing _= if it is there
\r
2636 var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
\r
2637 // if nothing was replaced, add timestamp to the end
\r
2638 s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
\r
2641 // If data is available, append data to url for get requests
\r
2642 if ( s.data && type == "GET" ) {
\r
2643 s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
\r
2645 // IE likes to send both get and post data, prevent this
\r
2649 // Watch for a new set of requests
\r
2650 if ( s.global && ! jQuery.active++ )
\r
2651 jQuery.event.trigger( "ajaxStart" );
\r
2653 // Matches an absolute URL, and saves the domain
\r
2654 var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
\r
2656 // If we're requesting a remote document
\r
2657 // and trying to load JSON or Script with a GET
\r
2658 if ( s.dataType == "script" && type == "GET"
\r
2659 && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
\r
2660 var head = document.getElementsByTagName("head")[0];
\r
2661 var script = document.createElement("script");
\r
2662 script.src = s.url;
\r
2663 if (s.scriptCharset)
\r
2664 script.charset = s.scriptCharset;
\r
2666 // Handle Script loading
\r
2670 // Attach handlers for all browsers
\r
2671 script.onload = script.onreadystatechange = function(){
\r
2672 if ( !done && (!this.readyState ||
\r
2673 this.readyState == "loaded" || this.readyState == "complete") ) {
\r
2677 head.removeChild( script );
\r
2682 head.appendChild(script);
\r
2684 // We handle everything using the script element injection
\r
2688 var requestDone = false;
\r
2690 // Create the request object; Microsoft failed to properly
\r
2691 // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
\r
2692 var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
\r
2694 // Open the socket
\r
2695 // Passing null username, generates a login popup on Opera (#2865)
\r
2697 xhr.open(type, s.url, s.async, s.username, s.password);
\r
2699 xhr.open(type, s.url, s.async);
\r
2701 // Need an extra try/catch for cross domain requests in Firefox 3
\r
2703 // Set the correct header, if data is being sent
\r
2705 xhr.setRequestHeader("Content-Type", s.contentType);
\r
2707 // Set the If-Modified-Since header, if ifModified mode.
\r
2708 if ( s.ifModified )
\r
2709 xhr.setRequestHeader("If-Modified-Since",
\r
2710 jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
\r
2712 // Set header so the called script knows that it's an XMLHttpRequest
\r
2713 xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
\r
2715 // Set the Accepts header for the server, depending on the dataType
\r
2716 xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
\r
2717 s.accepts[ s.dataType ] + ", */*" :
\r
2718 s.accepts._default );
\r
2721 // Allow custom headers/mimetypes
\r
2722 if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
\r
2723 // cleanup active request counter
\r
2724 s.global && jQuery.active--;
\r
2725 // close opended socket
\r
2731 jQuery.event.trigger("ajaxSend", [xhr, s]);
\r
2733 // Wait for a response to come back
\r
2734 var onreadystatechange = function(isTimeout){
\r
2735 // The transfer is complete and the data is available, or the request timed out
\r
2736 if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
\r
2737 requestDone = true;
\r
2739 // clear poll interval
\r
2741 clearInterval(ival);
\r
2745 status = isTimeout == "timeout" && "timeout" ||
\r
2746 !jQuery.httpSuccess( xhr ) && "error" ||
\r
2747 s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
\r
2750 if ( status == "success" ) {
\r
2751 // Watch for, and catch, XML document parse errors
\r
2753 // process the data (runs the xml through httpData regardless of callback)
\r
2754 data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
\r
2756 status = "parsererror";
\r
2760 // Make sure that the request was successful or notmodified
\r
2761 if ( status == "success" ) {
\r
2762 // Cache Last-Modified header, if ifModified mode.
\r
2765 modRes = xhr.getResponseHeader("Last-Modified");
\r
2766 } catch(e) {} // swallow exception thrown by FF if header is not available
\r
2768 if ( s.ifModified && modRes )
\r
2769 jQuery.lastModified[s.url] = modRes;
\r
2771 // JSONP handles its own success callback
\r
2775 jQuery.handleError(s, xhr, status);
\r
2777 // Fire the complete handlers
\r
2780 // Stop memory leaks
\r
2787 // don't attach the handler to the request, just poll it instead
\r
2788 var ival = setInterval(onreadystatechange, 13);
\r
2790 // Timeout checker
\r
2791 if ( s.timeout > 0 )
\r
2792 setTimeout(function(){
\r
2793 // Check to see if the request is still happening
\r
2795 // Cancel the request
\r
2798 if( !requestDone )
\r
2799 onreadystatechange( "timeout" );
\r
2808 jQuery.handleError(s, xhr, null, e);
\r
2811 // firefox 1.5 doesn't fire statechange for sync requests
\r
2813 onreadystatechange();
\r
2815 function success(){
\r
2816 // If a local callback was specified, fire it and pass it the data
\r
2818 s.success( data, status );
\r
2820 // Fire the global callback
\r
2822 jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
\r
2825 function complete(){
\r
2828 s.complete(xhr, status);
\r
2830 // The request was completed
\r
2832 jQuery.event.trigger( "ajaxComplete", [xhr, s] );
\r
2834 // Handle the global AJAX counter
\r
2835 if ( s.global && ! --jQuery.active )
\r
2836 jQuery.event.trigger( "ajaxStop" );
\r
2839 // return XMLHttpRequest to allow aborting the request etc.
\r
2843 handleError: function( s, xhr, status, e ) {
\r
2844 // If a local callback was specified, fire it
\r
2845 if ( s.error ) s.error( xhr, status, e );
\r
2847 // Fire the global callback
\r
2849 jQuery.event.trigger( "ajaxError", [xhr, s, e] );
\r
2852 // Counter for holding the number of active queries
\r
2855 // Determines if an XMLHttpRequest was successful or not
\r
2856 httpSuccess: function( xhr ) {
\r
2858 // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
\r
2859 return !xhr.status && location.protocol == "file:" ||
\r
2860 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
\r
2861 jQuery.browser.safari && xhr.status == undefined;
\r
2866 // Determines if an XMLHttpRequest returns NotModified
\r
2867 httpNotModified: function( xhr, url ) {
\r
2869 var xhrRes = xhr.getResponseHeader("Last-Modified");
\r
2871 // Firefox always returns 200. check Last-Modified date
\r
2872 return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
\r
2873 jQuery.browser.safari && xhr.status == undefined;
\r
2878 httpData: function( xhr, type, filter ) {
\r
2879 var ct = xhr.getResponseHeader("content-type"),
\r
2880 xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
\r
2881 data = xml ? xhr.responseXML : xhr.responseText;
\r
2883 if ( xml && data.documentElement.tagName == "parsererror" )
\r
2884 throw "parsererror";
\r
2886 // Allow a pre-filtering function to sanitize the response
\r
2888 data = filter( data, type );
\r
2890 // If the type is "script", eval it in global context
\r
2891 if ( type == "script" )
\r
2892 jQuery.globalEval( data );
\r
2894 // Get the JavaScript object, if JSON is used.
\r
2895 if ( type == "json" )
\r
2896 data = eval("(" + data + ")");
\r
2901 // Serialize an array of form elements or a set of
\r
2902 // key/values into a query string
\r
2903 param: function( a ) {
\r
2906 // If an array was passed in, assume that it is an array
\r
2907 // of form elements
\r
2908 if ( a.constructor == Array || a.jquery )
\r
2909 // Serialize the form elements
\r
2910 jQuery.each( a, function(){
\r
2911 s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
\r
2914 // Otherwise, assume that it's an object of key/value pairs
\r
2916 // Serialize the key/values
\r
2917 for ( var j in a )
\r
2918 // If the value is an array then the key names need to be repeated
\r
2919 if ( a[j] && a[j].constructor == Array )
\r
2920 jQuery.each( a[j], function(){
\r
2921 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
\r
2924 s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );
\r
2926 // Return the resulting serialization
\r
2927 return s.join("&").replace(/%20/g, "+");
\r
2931 jQuery.fn.extend({
\r
2932 show: function(speed,callback){
\r
2935 height: "show", width: "show", opacity: "show"
\r
2936 }, speed, callback) :
\r
2938 this.filter(":hidden").each(function(){
\r
2939 this.style.display = this.oldblock || "";
\r
2940 if ( jQuery.css(this,"display") == "none" ) {
\r
2941 var elem = jQuery("<" + this.tagName + " />").appendTo("body");
\r
2942 this.style.display = elem.css("display");
\r
2943 // handle an edge condition where css is - div { display:none; } or similar
\r
2944 if (this.style.display == "none")
\r
2945 this.style.display = "block";
\r
2951 hide: function(speed,callback){
\r
2954 height: "hide", width: "hide", opacity: "hide"
\r
2955 }, speed, callback) :
\r
2957 this.filter(":visible").each(function(){
\r
2958 this.oldblock = this.oldblock || jQuery.css(this,"display");
\r
2959 this.style.display = "none";
\r
2963 // Save the old toggle function
\r
2964 _toggle: jQuery.fn.toggle,
\r
2966 toggle: function( fn, fn2 ){
\r
2967 return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
\r
2968 this._toggle.apply( this, arguments ) :
\r
2971 height: "toggle", width: "toggle", opacity: "toggle"
\r
2973 this.each(function(){
\r
2974 jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
\r
2978 slideDown: function(speed,callback){
\r
2979 return this.animate({height: "show"}, speed, callback);
\r
2982 slideUp: function(speed,callback){
\r
2983 return this.animate({height: "hide"}, speed, callback);
\r
2986 slideToggle: function(speed, callback){
\r
2987 return this.animate({height: "toggle"}, speed, callback);
\r
2990 fadeIn: function(speed, callback){
\r
2991 return this.animate({opacity: "show"}, speed, callback);
\r
2994 fadeOut: function(speed, callback){
\r
2995 return this.animate({opacity: "hide"}, speed, callback);
\r
2998 fadeTo: function(speed,to,callback){
\r
2999 return this.animate({opacity: to}, speed, callback);
\r
3002 animate: function( prop, speed, easing, callback ) {
\r
3003 var optall = jQuery.speed(speed, easing, callback);
\r
3005 return this[ optall.queue === false ? "each" : "queue" ](function(){
\r
3006 if ( this.nodeType != 1)
\r
3009 var opt = jQuery.extend({}, optall), p,
\r
3010 hidden = jQuery(this).is(":hidden"), self = this;
\r
3012 for ( p in prop ) {
\r
3013 if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
\r
3014 return opt.complete.call(this);
\r
3016 if ( p == "height" || p == "width" ) {
\r
3017 // Store display property
\r
3018 opt.display = jQuery.css(this, "display");
\r
3020 // Make sure that nothing sneaks out
\r
3021 opt.overflow = this.style.overflow;
\r
3025 if ( opt.overflow != null )
\r
3026 this.style.overflow = "hidden";
\r
3028 opt.curAnim = jQuery.extend({}, prop);
\r
3030 jQuery.each( prop, function(name, val){
\r
3031 var e = new jQuery.fx( self, opt, name );
\r
3033 if ( /toggle|show|hide/.test(val) )
\r
3034 e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
\r
3036 var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
\r
3037 start = e.cur(true) || 0;
\r
3040 var end = parseFloat(parts[2]),
\r
3041 unit = parts[3] || "px";
\r
3043 // We need to compute starting value
\r
3044 if ( unit != "px" ) {
\r
3045 self.style[ name ] = (end || 1) + unit;
\r
3046 start = ((end || 1) / e.cur(true)) * start;
\r
3047 self.style[ name ] = start + unit;
\r
3050 // If a +=/-= token was provided, we're doing a relative animation
\r
3052 end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
\r
3054 e.custom( start, end, unit );
\r
3056 e.custom( start, val, "" );
\r
3060 // For JS strict compliance
\r
3065 queue: function(type, fn){
\r
3066 if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
\r
3071 if ( !type || (typeof type == "string" && !fn) )
\r
3072 return queue( this[0], type );
\r
3074 return this.each(function(){
\r
3075 if ( fn.constructor == Array )
\r
3076 queue(this, type, fn);
\r
3078 queue(this, type).push( fn );
\r
3080 if ( queue(this, type).length == 1 )
\r
3086 stop: function(clearQueue, gotoEnd){
\r
3087 var timers = jQuery.timers;
\r
3092 this.each(function(){
\r
3093 // go in reverse order so anything added to the queue during the loop is ignored
\r
3094 for ( var i = timers.length - 1; i >= 0; i-- )
\r
3095 if ( timers[i].elem == this ) {
\r
3097 // force the next step to be the last
\r
3099 timers.splice(i, 1);
\r
3103 // start the next in the queue if the last step wasn't forced
\r
3112 var queue = function( elem, type, array ) {
\r
3115 type = type || "fx";
\r
3117 var q = jQuery.data( elem, type + "queue" );
\r
3119 if ( !q || array )
\r
3120 q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
\r
3126 jQuery.fn.dequeue = function(type){
\r
3127 type = type || "fx";
\r
3129 return this.each(function(){
\r
3130 var q = queue(this, type);
\r
3135 q[0].call( this );
\r
3141 speed: function(speed, easing, fn) {
\r
3142 var opt = speed && speed.constructor == Object ? speed : {
\r
3143 complete: fn || !fn && easing ||
\r
3144 jQuery.isFunction( speed ) && speed,
\r
3146 easing: fn && easing || easing && easing.constructor != Function && easing
\r
3149 opt.duration = (opt.duration && opt.duration.constructor == Number ?
\r
3151 jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
\r
3154 opt.old = opt.complete;
\r
3155 opt.complete = function(){
\r
3156 if ( opt.queue !== false )
\r
3157 jQuery(this).dequeue();
\r
3158 if ( jQuery.isFunction( opt.old ) )
\r
3159 opt.old.call( this );
\r
3166 linear: function( p, n, firstNum, diff ) {
\r
3167 return firstNum + diff * p;
\r
3169 swing: function( p, n, firstNum, diff ) {
\r
3170 return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
\r
3177 fx: function( elem, options, prop ){
\r
3178 this.options = options;
\r
3182 if ( !options.orig )
\r
3183 options.orig = {};
\r
3188 jQuery.fx.prototype = {
\r
3190 // Simple function for setting a style value
\r
3191 update: function(){
\r
3192 if ( this.options.step )
\r
3193 this.options.step.call( this.elem, this.now, this );
\r
3195 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
\r
3197 // Set display property to block for height/width animations
\r
3198 if ( this.prop == "height" || this.prop == "width" )
\r
3199 this.elem.style.display = "block";
\r
3202 // Get the current size
\r
3203 cur: function(force){
\r
3204 if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
\r
3205 return this.elem[ this.prop ];
\r
3207 var r = parseFloat(jQuery.css(this.elem, this.prop, force));
\r
3208 return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
\r
3211 // Start an animation from one number to another
\r
3212 custom: function(from, to, unit){
\r
3213 this.startTime = now();
\r
3214 this.start = from;
\r
3216 this.unit = unit || this.unit || "px";
\r
3217 this.now = this.start;
\r
3218 this.pos = this.state = 0;
\r
3222 function t(gotoEnd){
\r
3223 return self.step(gotoEnd);
\r
3226 t.elem = this.elem;
\r
3228 jQuery.timers.push(t);
\r
3230 if ( jQuery.timerId == null ) {
\r
3231 jQuery.timerId = setInterval(function(){
\r
3232 var timers = jQuery.timers;
\r
3234 for ( var i = 0; i < timers.length; i++ )
\r
3235 if ( !timers[i]() )
\r
3236 timers.splice(i--, 1);
\r
3238 if ( !timers.length ) {
\r
3239 clearInterval( jQuery.timerId );
\r
3240 jQuery.timerId = null;
\r
3246 // Simple 'show' function
\r
3248 // Remember where we started, so that we can go back to it later
\r
3249 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
\r
3250 this.options.show = true;
\r
3252 // Begin the animation
\r
3253 this.custom(0, this.cur());
\r
3255 // Make sure that we start at a small width/height to avoid any
\r
3256 // flash of content
\r
3257 if ( this.prop == "width" || this.prop == "height" )
\r
3258 this.elem.style[this.prop] = "1px";
\r
3260 // Start by showing the element
\r
3261 jQuery(this.elem).show();
\r
3264 // Simple 'hide' function
\r
3266 // Remember where we started, so that we can go back to it later
\r
3267 this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
\r
3268 this.options.hide = true;
\r
3270 // Begin the animation
\r
3271 this.custom(this.cur(), 0);
\r
3274 // Each step of an animation
\r
3275 step: function(gotoEnd){
\r
3278 if ( gotoEnd || t > this.options.duration + this.startTime ) {
\r
3279 this.now = this.end;
\r
3280 this.pos = this.state = 1;
\r
3283 this.options.curAnim[ this.prop ] = true;
\r
3286 for ( var i in this.options.curAnim )
\r
3287 if ( this.options.curAnim[i] !== true )
\r
3291 if ( this.options.display != null ) {
\r
3292 // Reset the overflow
\r
3293 this.elem.style.overflow = this.options.overflow;
\r
3295 // Reset the display
\r
3296 this.elem.style.display = this.options.display;
\r
3297 if ( jQuery.css(this.elem, "display") == "none" )
\r
3298 this.elem.style.display = "block";
\r
3301 // Hide the element if the "hide" operation was done
\r
3302 if ( this.options.hide )
\r
3303 this.elem.style.display = "none";
\r
3305 // Reset the properties, if the item has been hidden or shown
\r
3306 if ( this.options.hide || this.options.show )
\r
3307 for ( var p in this.options.curAnim )
\r
3308 jQuery.attr(this.elem.style, p, this.options.orig[p]);
\r
3312 // Execute the complete function
\r
3313 this.options.complete.call( this.elem );
\r
3317 var n = t - this.startTime;
\r
3318 this.state = n / this.options.duration;
\r
3320 // Perform the easing function, defaults to swing
\r
3321 this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
\r
3322 this.now = this.start + ((this.end - this.start) * this.pos);
\r
3324 // Perform the next step of the animation
\r
3333 jQuery.extend( jQuery.fx, {
\r
3341 scrollLeft: function(fx){
\r
3342 fx.elem.scrollLeft = fx.now;
\r
3345 scrollTop: function(fx){
\r
3346 fx.elem.scrollTop = fx.now;
\r
3349 opacity: function(fx){
\r
3350 jQuery.attr(fx.elem.style, "opacity", fx.now);
\r
3353 _default: function(fx){
\r
3354 fx.elem.style[ fx.prop ] = fx.now + fx.unit;
\r
3358 // The Offset Method
\r
3359 // Originally By Brandon Aaron, part of the Dimension Plugin
\r
3360 // http://jquery.com/plugins/project/dimensions
\r
3361 jQuery.fn.offset = function() {
\r
3362 var left = 0, top = 0, elem = this[0], results;
\r
3364 if ( elem ) with ( jQuery.browser ) {
\r
3365 var parent = elem.parentNode,
\r
3366 offsetChild = elem,
\r
3367 offsetParent = elem.offsetParent,
\r
3368 doc = elem.ownerDocument,
\r
3369 safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
\r
3370 css = jQuery.curCSS,
\r
3371 fixed = css(elem, "position") == "fixed";
\r
3373 // Use getBoundingClientRect if available
\r
3374 if ( elem.getBoundingClientRect ) {
\r
3375 var box = elem.getBoundingClientRect();
\r
3377 // Add the document scroll offsets
\r
3378 add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
\r
3379 box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
\r
3381 // IE adds the HTML element's border, by default it is medium which is 2px
\r
3382 // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
\r
3383 // IE 7 standards mode, the border is always 2px
\r
3384 // This border/offset is typically represented by the clientLeft and clientTop properties
\r
3385 // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
\r
3386 // Therefore this method will be off by 2px in IE while in quirksmode
\r
3387 add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
\r
3389 // Otherwise loop through the offsetParents and parentNodes
\r
3392 // Initial element offsets
\r
3393 add( elem.offsetLeft, elem.offsetTop );
\r
3395 // Get parent offsets
\r
3396 while ( offsetParent ) {
\r
3397 // Add offsetParent offsets
\r
3398 add( offsetParent.offsetLeft, offsetParent.offsetTop );
\r
3400 // Mozilla and Safari > 2 does not include the border on offset parents
\r
3401 // However Mozilla adds the border for table or table cells
\r
3402 if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
\r
3403 border( offsetParent );
\r
3405 // Add the document scroll offsets if position is fixed on any offsetParent
\r
3406 if ( !fixed && css(offsetParent, "position") == "fixed" )
\r
3409 // Set offsetChild to previous offsetParent unless it is the body element
\r
3410 offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
\r
3411 // Get next offsetParent
\r
3412 offsetParent = offsetParent.offsetParent;
\r
3415 // Get parent scroll offsets
\r
3416 while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
\r
3417 // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
\r
3418 if ( !/^inline|table.*$/i.test(css(parent, "display")) )
\r
3419 // Subtract parent scroll offsets
\r
3420 add( -parent.scrollLeft, -parent.scrollTop );
\r
3422 // Mozilla does not add the border for a parent that has overflow != visible
\r
3423 if ( mozilla && css(parent, "overflow") != "visible" )
\r
3426 // Get next parent
\r
3427 parent = parent.parentNode;
\r
3430 // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
\r
3431 // Mozilla doubles body offsets with a non-absolutely positioned offsetChild
\r
3432 if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
\r
3433 (mozilla && css(offsetChild, "position") != "absolute") )
\r
3434 add( -doc.body.offsetLeft, -doc.body.offsetTop );
\r
3436 // Add the document scroll offsets if position is fixed
\r
3438 add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
\r
3439 Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
\r
3442 // Return an object with top and left properties
\r
3443 results = { top: top, left: left };
\r
3446 function border(elem) {
\r
3447 add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
\r
3450 function add(l, t) {
\r
3451 left += parseInt(l, 10) || 0;
\r
3452 top += parseInt(t, 10) || 0;
\r
3459 jQuery.fn.extend({
\r
3460 position: function() {
\r
3461 var left = 0, top = 0, results;
\r
3464 // Get *real* offsetParent
\r
3465 var offsetParent = this.offsetParent(),
\r
3467 // Get correct offsets
\r
3468 offset = this.offset(),
\r
3469 parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
\r
3471 // Subtract element margins
\r
3472 // note: when an element has margin: auto the offsetLeft and marginLeft
\r
3473 // are the same in Safari causing offset.left to incorrectly be 0
\r
3474 offset.top -= num( this, 'marginTop' );
\r
3475 offset.left -= num( this, 'marginLeft' );
\r
3477 // Add offsetParent borders
\r
3478 parentOffset.top += num( offsetParent, 'borderTopWidth' );
\r
3479 parentOffset.left += num( offsetParent, 'borderLeftWidth' );
\r
3481 // Subtract the two offsets
\r
3483 top: offset.top - parentOffset.top,
\r
3484 left: offset.left - parentOffset.left
\r
3491 offsetParent: function() {
\r
3492 var offsetParent = this[0].offsetParent;
\r
3493 while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
\r
3494 offsetParent = offsetParent.offsetParent;
\r
3495 return jQuery(offsetParent);
\r
3500 // Create scrollLeft and scrollTop methods
\r
3501 jQuery.each( ['Left', 'Top'], function(i, name) {
\r
3502 var method = 'scroll' + name;
\r
3504 jQuery.fn[ method ] = function(val) {
\r
3505 if (!this[0]) return;
\r
3507 return val != undefined ?
\r
3509 // Set the scroll offset
\r
3510 this.each(function() {
\r
3511 this == window || this == document ?
\r
3513 !i ? val : jQuery(window).scrollLeft(),
\r
3514 i ? val : jQuery(window).scrollTop()
\r
3516 this[ method ] = val;
\r
3519 // Return the scroll offset
\r
3520 this[0] == window || this[0] == document ?
\r
3521 self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
\r
3522 jQuery.boxModel && document.documentElement[ method ] ||
\r
3523 document.body[ method ] :
\r
3524 this[0][ method ];
\r
3527 // Create innerHeight, innerWidth, outerHeight and outerWidth methods
\r
3528 jQuery.each([ "Height", "Width" ], function(i, name){
\r
3530 var tl = i ? "Left" : "Top", // top or left
\r
3531 br = i ? "Right" : "Bottom"; // bottom or right
\r
3533 // innerHeight and innerWidth
\r
3534 jQuery.fn["inner" + name] = function(){
\r
3535 return this[ name.toLowerCase() ]() +
\r
3536 num(this, "padding" + tl) +
\r
3537 num(this, "padding" + br);
\r
3540 // outerHeight and outerWidth
\r
3541 jQuery.fn["outer" + name] = function(margin) {
\r
3542 return this["inner" + name]() +
\r
3543 num(this, "border" + tl + "Width") +
\r
3544 num(this, "border" + br + "Width") +
\r
3546 num(this, "margin" + tl) + num(this, "margin" + br) : 0);
\r
3550 var $j = jQuery.noConflict();