7 "./css/defaultDisplay",
15 ], function( jQuery, rcssNum, cssExpand, isHidden, adjustCSS, defaultDisplay ) {
19 rfxtypes = /^(?:toggle|show|hide)$/,
21 animationPrefilters = [ defaultPrefilter ],
23 "*": [ function( prop, value ) {
24 var tween = this.createTween( prop, value );
25 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
32 window.requestAnimationFrame( raf );
37 // Animations created synchronously will run synchronously
38 function createFxNow() {
39 setTimeout(function() {
42 return ( fxNow = jQuery.now() );
45 // Generate parameters to create a standard animation
46 function genFx( type, includeWidth ) {
48 attrs = { height: type },
51 // if we include width, step value is 1 to do all cssExpand values,
52 // if we don't include width, step value is 2 to skip over Left and Right
53 includeWidth = includeWidth ? 1 : 0;
54 for ( ; i < 4 ; i += 2 - includeWidth ) {
55 which = cssExpand[ i ];
56 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
60 attrs.opacity = attrs.width = type;
66 function createTween( value, prop, animation ) {
68 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
70 length = collection.length;
71 for ( ; index < length; index++ ) {
72 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
74 // we're done with this property
80 function defaultPrefilter( elem, props, opts ) {
81 /* jshint validthis: true */
82 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
86 hidden = elem.nodeType && isHidden( elem ),
87 dataShow = jQuery._data( elem, "fxshow" );
89 // handle queue: false promises
91 hooks = jQuery._queueHooks( elem, "fx" );
92 if ( hooks.unqueued == null ) {
94 oldfire = hooks.empty.fire;
95 hooks.empty.fire = function() {
96 if ( !hooks.unqueued ) {
103 anim.always(function() {
104 // doing this makes sure that the complete handler will be called
105 // before this completes
106 anim.always(function() {
108 if ( !jQuery.queue( elem, "fx" ).length ) {
115 // height/width overflow pass
116 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
117 // Make sure that nothing sneaks out
118 // Record all 3 overflow attributes because IE does not
119 // change the overflow attribute when overflowX and
120 // overflowY are set to the same value
121 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
123 // Set display property to inline-block for height/width
124 // animations on inline elements that are having width/height animated
125 display = jQuery.css( elem, "display" );
127 // Test default display if display is currently "none"
128 checkDisplay = display === "none" ?
129 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
131 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
132 style.display = "inline-block";
136 if ( opts.overflow ) {
137 style.overflow = "hidden";
138 anim.always(function() {
139 style.overflow = opts.overflow[ 0 ];
140 style.overflowX = opts.overflow[ 1 ];
141 style.overflowY = opts.overflow[ 2 ];
146 for ( prop in props ) {
147 value = props[ prop ];
148 if ( rfxtypes.exec( value ) ) {
149 delete props[ prop ];
150 toggle = toggle || value === "toggle";
151 if ( value === ( hidden ? "hide" : "show" ) ) {
153 // If there is dataShow left over from a stopped hide or show
154 // and we are going to proceed with show, we should pretend to be hidden
155 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
161 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
163 // Any non-fx value stops us from restoring the original display value
169 if ( !jQuery.isEmptyObject( orig ) ) {
171 if ( "hidden" in dataShow ) {
172 hidden = dataShow.hidden;
175 dataShow = jQuery._data( elem, "fxshow", {} );
178 // store state if its toggle - enables .stop().toggle() to "reverse"
180 dataShow.hidden = !hidden;
183 jQuery( elem ).show();
185 anim.done(function() {
186 jQuery( elem ).hide();
189 anim.done(function() {
191 jQuery._removeData( elem, "fxshow" );
192 for ( prop in orig ) {
193 jQuery.style( elem, prop, orig[ prop ] );
196 for ( prop in orig ) {
197 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
199 if ( !( prop in dataShow ) ) {
200 dataShow[ prop ] = tween.start;
202 tween.end = tween.start;
203 tween.start = prop === "width" || prop === "height" ? 1 : 0;
208 // If this is a noop like .hide().hide(), restore an overwritten display value
209 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
210 style.display = display;
214 function propFilter( props, specialEasing ) {
215 var index, name, easing, value, hooks;
217 // camelCase, specialEasing and expand cssHook pass
218 for ( index in props ) {
219 name = jQuery.camelCase( index );
220 easing = specialEasing[ name ];
221 value = props[ index ];
222 if ( jQuery.isArray( value ) ) {
224 value = props[ index ] = value[ 0 ];
227 if ( index !== name ) {
228 props[ name ] = value;
229 delete props[ index ];
232 hooks = jQuery.cssHooks[ name ];
233 if ( hooks && "expand" in hooks ) {
234 value = hooks.expand( value );
235 delete props[ name ];
237 // not quite $.extend, this wont overwrite keys already present.
238 // also - reusing 'index' from above because we have the correct "name"
239 for ( index in value ) {
240 if ( !( index in props ) ) {
241 props[ index ] = value[ index ];
242 specialEasing[ index ] = easing;
246 specialEasing[ name ] = easing;
251 function Animation( elem, properties, options ) {
255 length = animationPrefilters.length,
256 deferred = jQuery.Deferred().always( function() {
257 // don't match elem in the :animated selector
264 var currentTime = fxNow || createFxNow(),
265 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
266 // Support: Android 2.3
267 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
268 temp = remaining / animation.duration || 0,
271 length = animation.tweens.length;
273 for ( ; index < length ; index++ ) {
274 animation.tweens[ index ].run( percent );
277 deferred.notifyWith( elem, [ animation, percent, remaining ]);
279 if ( percent < 1 && length ) {
282 deferred.resolveWith( elem, [ animation ] );
286 animation = deferred.promise({
288 props: jQuery.extend( {}, properties ),
289 opts: jQuery.extend( true, {
291 easing: jQuery.easing._default
293 originalProperties: properties,
294 originalOptions: options,
295 startTime: fxNow || createFxNow(),
296 duration: options.duration,
298 createTween: function( prop, end ) {
299 var tween = jQuery.Tween( elem, animation.opts, prop, end,
300 animation.opts.specialEasing[ prop ] || animation.opts.easing );
301 animation.tweens.push( tween );
304 stop: function( gotoEnd ) {
306 // if we are going to the end, we want to run all the tweens
307 // otherwise we skip this part
308 length = gotoEnd ? animation.tweens.length : 0;
313 for ( ; index < length ; index++ ) {
314 animation.tweens[ index ].run( 1 );
317 // resolve when we played the last frame
320 deferred.resolveWith( elem, [ animation, gotoEnd ] );
322 deferred.rejectWith( elem, [ animation, gotoEnd ] );
327 props = animation.props;
329 propFilter( props, animation.opts.specialEasing );
331 for ( ; index < length ; index++ ) {
332 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
338 jQuery.map( props, createTween, animation );
340 if ( jQuery.isFunction( animation.opts.start ) ) {
341 animation.opts.start.call( elem, animation );
345 jQuery.extend( tick, {
348 queue: animation.opts.queue
352 // attach callbacks from options
353 return animation.progress( animation.opts.progress )
354 .done( animation.opts.done, animation.opts.complete )
355 .fail( animation.opts.fail )
356 .always( animation.opts.always );
359 jQuery.Animation = jQuery.extend( Animation, {
360 tweener: function( props, callback ) {
361 if ( jQuery.isFunction( props ) ) {
365 props = props.split(" ");
370 length = props.length;
372 for ( ; index < length ; index++ ) {
373 prop = props[ index ];
374 tweeners[ prop ] = tweeners[ prop ] || [];
375 tweeners[ prop ].unshift( callback );
379 prefilter: function( callback, prepend ) {
381 animationPrefilters.unshift( callback );
383 animationPrefilters.push( callback );
388 jQuery.speed = function( speed, easing, fn ) {
389 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
390 complete: fn || !fn && easing ||
391 jQuery.isFunction( speed ) && speed,
393 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
396 // Go to the end state if fx are off or if document is hidden
397 if ( jQuery.fx.off || document.hidden ) {
401 opt.duration = typeof opt.duration === "number" ?
402 opt.duration : opt.duration in jQuery.fx.speeds ?
403 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
406 // normalize opt.queue - true/undefined/null -> "fx"
407 if ( opt.queue == null || opt.queue === true ) {
412 opt.old = opt.complete;
414 opt.complete = function() {
415 if ( jQuery.isFunction( opt.old ) ) {
416 opt.old.call( this );
420 jQuery.dequeue( this, opt.queue );
428 fadeTo: function( speed, to, easing, callback ) {
429 // show any hidden elements after setting opacity to 0
430 return this.filter( isHidden ).css( "opacity", 0 ).show()
432 // animate to the value specified
433 .end().animate({ opacity: to }, speed, easing, callback );
435 animate: function( prop, speed, easing, callback ) {
436 var empty = jQuery.isEmptyObject( prop ),
437 optall = jQuery.speed( speed, easing, callback ),
438 doAnimation = function() {
439 // Operate on a copy of prop so per-property easing won't be lost
440 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
442 // Empty animations, or finishing resolves immediately
443 if ( empty || jQuery._data( this, "finish" ) ) {
447 doAnimation.finish = doAnimation;
449 return empty || optall.queue === false ?
450 this.each( doAnimation ) :
451 this.queue( optall.queue, doAnimation );
453 stop: function( type, clearQueue, gotoEnd ) {
454 var stopQueue = function( hooks ) {
455 var stop = hooks.stop;
460 if ( typeof type !== "string" ) {
461 gotoEnd = clearQueue;
465 if ( clearQueue && type !== false ) {
466 this.queue( type || "fx", [] );
469 return this.each(function() {
471 index = type != null && type + "queueHooks",
472 timers = jQuery.timers,
473 data = jQuery._data( this );
476 if ( data[ index ] && data[ index ].stop ) {
477 stopQueue( data[ index ] );
480 for ( index in data ) {
481 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
482 stopQueue( data[ index ] );
487 for ( index = timers.length; index--; ) {
488 if ( timers[ index ].elem === this &&
489 (type == null || timers[ index ].queue === type) ) {
491 timers[ index ].anim.stop( gotoEnd );
493 timers.splice( index, 1 );
497 // start the next in the queue if the last step wasn't forced
498 // timers currently will call their complete callbacks, which will dequeue
499 // but only if they were gotoEnd
500 if ( dequeue || !gotoEnd ) {
501 jQuery.dequeue( this, type );
505 finish: function( type ) {
506 if ( type !== false ) {
509 return this.each(function() {
511 data = jQuery._data( this ),
512 queue = data[ type + "queue" ],
513 hooks = data[ type + "queueHooks" ],
514 timers = jQuery.timers,
515 length = queue ? queue.length : 0;
517 // enable finishing flag on private data
520 // empty the queue first
521 jQuery.queue( this, type, [] );
523 if ( hooks && hooks.stop ) {
524 hooks.stop.call( this, true );
527 // look for any active animations, and finish them
528 for ( index = timers.length; index--; ) {
529 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
530 timers[ index ].anim.stop( true );
531 timers.splice( index, 1 );
535 // look for any animations in the old queue and finish them
536 for ( index = 0; index < length; index++ ) {
537 if ( queue[ index ] && queue[ index ].finish ) {
538 queue[ index ].finish.call( this );
542 // turn off finishing flag
548 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
549 var cssFn = jQuery.fn[ name ];
550 jQuery.fn[ name ] = function( speed, easing, callback ) {
551 return speed == null || typeof speed === "boolean" ?
552 cssFn.apply( this, arguments ) :
553 this.animate( genFx( name, true ), speed, easing, callback );
557 // Generate shortcuts for custom animations
559 slideDown: genFx("show"),
560 slideUp: genFx("hide"),
561 slideToggle: genFx("toggle"),
562 fadeIn: { opacity: "show" },
563 fadeOut: { opacity: "hide" },
564 fadeToggle: { opacity: "toggle" }
565 }, function( name, props ) {
566 jQuery.fn[ name ] = function( speed, easing, callback ) {
567 return this.animate( props, speed, easing, callback );
572 jQuery.fx.tick = function() {
574 timers = jQuery.timers,
577 fxNow = jQuery.now();
579 for ( ; i < timers.length; i++ ) {
581 // Checks the timer has not already been removed
582 if ( !timer() && timers[ i ] === timer ) {
583 timers.splice( i--, 1 );
587 if ( !timers.length ) {
593 jQuery.fx.timer = function( timer ) {
594 jQuery.timers.push( timer );
602 jQuery.fx.interval = 13;
604 jQuery.fx.start = function() {
605 timerId = window.requestAnimationFrame ?
606 window.requestAnimationFrame( raf ) :
607 setInterval( jQuery.fx.tick, jQuery.fx.interval );
610 jQuery.fx.stop = function() {
611 if ( window.cancelAnimationFrame ) {
612 window.cancelAnimationFrame( timerId );
614 clearInterval( timerId );