8 "./css/defaultDisplay",
17 ], function( jQuery, document, rcssNum, cssExpand,
18 isHidden, adjustCSS, defaultDisplay, dataPriv ) {
22 rfxtypes = /^(?:toggle|show|hide)$/,
24 animationPrefilters = [ defaultPrefilter ],
26 "*": [ function( prop, value ) {
27 var tween = this.createTween( prop, value );
28 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
35 window.requestAnimationFrame( raf );
40 // Animations created synchronously will run synchronously
41 function createFxNow() {
42 setTimeout(function() {
45 return ( fxNow = jQuery.now() );
48 // Generate parameters to create a standard animation
49 function genFx( type, includeWidth ) {
52 attrs = { height: type };
54 // If we include width, step value is 1 to do all cssExpand values,
55 // otherwise step value is 2 to skip over Left and Right
56 includeWidth = includeWidth ? 1 : 0;
57 for ( ; i < 4 ; i += 2 - includeWidth ) {
58 which = cssExpand[ i ];
59 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
63 attrs.opacity = attrs.width = type;
69 function createTween( value, prop, animation ) {
71 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
73 length = collection.length;
74 for ( ; index < length; index++ ) {
75 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
77 // We're done with this property
83 function defaultPrefilter( elem, props, opts ) {
84 /* jshint validthis: true */
85 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
89 hidden = elem.nodeType && isHidden( elem ),
90 dataShow = dataPriv.get( elem, "fxshow" );
92 // Handle queue: false promises
94 hooks = jQuery._queueHooks( elem, "fx" );
95 if ( hooks.unqueued == null ) {
97 oldfire = hooks.empty.fire;
98 hooks.empty.fire = function() {
99 if ( !hooks.unqueued ) {
106 anim.always(function() {
107 // Ensure the complete handler is called before this completes
108 anim.always(function() {
110 if ( !jQuery.queue( elem, "fx" ).length ) {
117 // Height/width overflow pass
118 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
119 // Make sure that nothing sneaks out
120 // Record all 3 overflow attributes because IE9-10 do not
121 // change the overflow attribute when overflowX and
122 // overflowY are set to the same value
123 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
125 // Set display property to inline-block for height/width
126 // animations on inline elements that are having width/height animated
127 display = jQuery.css( elem, "display" );
129 // Test default display if display is currently "none"
130 checkDisplay = display === "none" ?
131 dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
133 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
134 style.display = "inline-block";
138 if ( opts.overflow ) {
139 style.overflow = "hidden";
140 anim.always(function() {
141 style.overflow = opts.overflow[ 0 ];
142 style.overflowX = opts.overflow[ 1 ];
143 style.overflowY = opts.overflow[ 2 ];
148 for ( prop in props ) {
149 value = props[ prop ];
150 if ( rfxtypes.exec( value ) ) {
151 delete props[ prop ];
152 toggle = toggle || value === "toggle";
153 if ( value === ( hidden ? "hide" : "show" ) ) {
155 // If there is dataShow left over from a stopped hide or show
156 // and we are going to proceed with show, we should pretend to be hidden
157 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
163 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
165 // Any non-fx value stops us from restoring the original display value
171 if ( !jQuery.isEmptyObject( orig ) ) {
173 if ( "hidden" in dataShow ) {
174 hidden = dataShow.hidden;
177 dataShow = dataPriv.access( elem, "fxshow", {} );
180 // Store state if its toggle - enables .stop().toggle() to "reverse"
182 dataShow.hidden = !hidden;
185 jQuery( elem ).show();
187 anim.done(function() {
188 jQuery( elem ).hide();
191 anim.done(function() {
194 dataPriv.remove( elem, "fxshow" );
195 for ( prop in orig ) {
196 jQuery.style( elem, prop, orig[ prop ] );
199 for ( prop in orig ) {
200 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
202 if ( !( prop in dataShow ) ) {
203 dataShow[ prop ] = tween.start;
205 tween.end = tween.start;
206 tween.start = prop === "width" || prop === "height" ? 1 : 0;
211 // If this is a noop like .hide().hide(), restore an overwritten display value
212 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
213 style.display = display;
217 function propFilter( props, specialEasing ) {
218 var index, name, easing, value, hooks;
220 // camelCase, specialEasing and expand cssHook pass
221 for ( index in props ) {
222 name = jQuery.camelCase( index );
223 easing = specialEasing[ name ];
224 value = props[ index ];
225 if ( jQuery.isArray( value ) ) {
227 value = props[ index ] = value[ 0 ];
230 if ( index !== name ) {
231 props[ name ] = value;
232 delete props[ index ];
235 hooks = jQuery.cssHooks[ name ];
236 if ( hooks && "expand" in hooks ) {
237 value = hooks.expand( value );
238 delete props[ name ];
240 // Not quite $.extend, this won't overwrite existing keys.
241 // Reusing 'index' because we have the correct "name"
242 for ( index in value ) {
243 if ( !( index in props ) ) {
244 props[ index ] = value[ index ];
245 specialEasing[ index ] = easing;
249 specialEasing[ name ] = easing;
254 function Animation( elem, properties, options ) {
258 length = animationPrefilters.length,
259 deferred = jQuery.Deferred().always( function() {
260 // Don't match elem in the :animated selector
267 var currentTime = fxNow || createFxNow(),
268 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
269 // Support: Android 2.3
270 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
271 temp = remaining / animation.duration || 0,
274 length = animation.tweens.length;
276 for ( ; index < length ; index++ ) {
277 animation.tweens[ index ].run( percent );
280 deferred.notifyWith( elem, [ animation, percent, remaining ]);
282 if ( percent < 1 && length ) {
285 deferred.resolveWith( elem, [ animation ] );
289 animation = deferred.promise({
291 props: jQuery.extend( {}, properties ),
292 opts: jQuery.extend( true, { specialEasing: {} }, options ),
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; otherwise, reject
319 deferred.resolveWith( elem, [ animation, gotoEnd ] );
321 deferred.rejectWith( elem, [ animation, gotoEnd ] );
326 props = animation.props;
328 propFilter( props, animation.opts.specialEasing );
330 for ( ; index < length ; index++ ) {
331 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
337 jQuery.map( props, createTween, animation );
339 if ( jQuery.isFunction( animation.opts.start ) ) {
340 animation.opts.start.call( elem, animation );
344 jQuery.extend( tick, {
347 queue: animation.opts.queue
351 // attach callbacks from options
352 return animation.progress( animation.opts.progress )
353 .done( animation.opts.done, animation.opts.complete )
354 .fail( animation.opts.fail )
355 .always( animation.opts.always );
358 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 ) {
430 // Show any hidden elements after setting opacity to 0
431 return this.filter( isHidden ).css( "opacity", 0 ).show()
433 // Animate to the value specified
434 .end().animate({ opacity: to }, speed, easing, callback );
436 animate: function( prop, speed, easing, callback ) {
437 var empty = jQuery.isEmptyObject( prop ),
438 optall = jQuery.speed( speed, easing, callback ),
439 doAnimation = function() {
440 // Operate on a copy of prop so per-property easing won't be lost
441 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
443 // Empty animations, or finishing resolves immediately
444 if ( empty || dataPriv.get( this, "finish" ) ) {
448 doAnimation.finish = doAnimation;
450 return empty || optall.queue === false ?
451 this.each( doAnimation ) :
452 this.queue( optall.queue, doAnimation );
454 stop: function( type, clearQueue, gotoEnd ) {
455 var stopQueue = function( hooks ) {
456 var stop = hooks.stop;
461 if ( typeof type !== "string" ) {
462 gotoEnd = clearQueue;
466 if ( clearQueue && type !== false ) {
467 this.queue( type || "fx", [] );
470 return this.each(function() {
472 index = type != null && type + "queueHooks",
473 timers = jQuery.timers,
474 data = dataPriv.get( this );
477 if ( data[ index ] && data[ index ].stop ) {
478 stopQueue( data[ index ] );
481 for ( index in data ) {
482 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
483 stopQueue( data[ index ] );
488 for ( index = timers.length; index--; ) {
489 if ( timers[ index ].elem === this &&
490 (type == null || timers[ index ].queue === type) ) {
492 timers[ index ].anim.stop( gotoEnd );
494 timers.splice( index, 1 );
498 // Start the next in the queue if the last step wasn't forced.
499 // Timers currently will call their complete callbacks, which
500 // will dequeue but only if they were gotoEnd.
501 if ( dequeue || !gotoEnd ) {
502 jQuery.dequeue( this, type );
506 finish: function( type ) {
507 if ( type !== false ) {
510 return this.each(function() {
512 data = dataPriv.get( this ),
513 queue = data[ type + "queue" ],
514 hooks = data[ type + "queueHooks" ],
515 timers = jQuery.timers,
516 length = queue ? queue.length : 0;
518 // Enable finishing flag on private data
521 // Empty the queue first
522 jQuery.queue( this, type, [] );
524 if ( hooks && hooks.stop ) {
525 hooks.stop.call( this, true );
528 // Look for any active animations, and finish them
529 for ( index = timers.length; index--; ) {
530 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
531 timers[ index ].anim.stop( true );
532 timers.splice( index, 1 );
536 // Look for any animations in the old queue and finish them
537 for ( index = 0; index < length; index++ ) {
538 if ( queue[ index ] && queue[ index ].finish ) {
539 queue[ index ].finish.call( this );
543 // Turn off finishing flag
549 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
550 var cssFn = jQuery.fn[ name ];
551 jQuery.fn[ name ] = function( speed, easing, callback ) {
552 return speed == null || typeof speed === "boolean" ?
553 cssFn.apply( this, arguments ) :
554 this.animate( genFx( name, true ), speed, easing, callback );
558 // Generate shortcuts for custom animations
560 slideDown: genFx("show"),
561 slideUp: genFx("hide"),
562 slideToggle: genFx("toggle"),
563 fadeIn: { opacity: "show" },
564 fadeOut: { opacity: "hide" },
565 fadeToggle: { opacity: "toggle" }
566 }, function( name, props ) {
567 jQuery.fn[ name ] = function( speed, easing, callback ) {
568 return this.animate( props, speed, easing, callback );
573 jQuery.fx.tick = function() {
576 timers = jQuery.timers;
578 fxNow = jQuery.now();
580 for ( ; i < timers.length; i++ ) {
582 // Checks the timer has not already been removed
583 if ( !timer() && timers[ i ] === timer ) {
584 timers.splice( i--, 1 );
588 if ( !timers.length ) {
594 jQuery.fx.timer = function( timer ) {
595 jQuery.timers.push( timer );
603 jQuery.fx.interval = 13;
604 jQuery.fx.start = function() {
606 timerId = window.requestAnimationFrame ?
607 window.requestAnimationFrame( raf ) :
608 setInterval( jQuery.fx.tick, jQuery.fx.interval );
612 jQuery.fx.stop = function() {
613 if ( window.cancelAnimationFrame ) {
614 window.cancelAnimationFrame( timerId );
616 clearInterval( timerId );