7 "./css/defaultDisplay",
16 ], function( jQuery, document, pnum, cssExpand, isHidden, defaultDisplay, dataPriv ) {
20 rfxtypes = /^(?:toggle|show|hide)$/,
21 rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
23 animationPrefilters = [ defaultPrefilter ],
25 "*": [ function( prop, value ) {
26 var tween = this.createTween( prop, value ),
28 parts = rfxnum.exec( value ),
29 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
31 // Starting value computation is required for potential unit mismatches
32 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
33 rfxnum.exec( jQuery.css( tween.elem, prop ) ),
37 if ( start && start[ 3 ] !== unit ) {
38 // Trust units reported by jQuery.css
39 unit = unit || start[ 3 ];
41 // Make sure we update the tween properties later on
44 // Iteratively approximate from a nonzero starting point
48 // If previous iteration zeroed out, double until we get *something*.
49 // Use string for doubling so we don't accidentally see scale as unchanged below
50 scale = scale || ".5";
53 start = start / scale;
54 jQuery.style( tween.elem, prop, start + unit );
56 // Update scale, tolerating zero or NaN from tween.cur(),
57 // break the loop if scale is unchanged or perfect, or if we've just had enough
59 scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations
63 // Update tween properties
65 start = tween.start = +start || +target || 0;
67 // If a +=/-= token was provided, we're doing a relative animation
68 tween.end = parts[ 1 ] ?
69 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
79 window.requestAnimationFrame( raf );
84 // Animations created synchronously will run synchronously
85 function createFxNow() {
86 setTimeout(function() {
89 return ( fxNow = jQuery.now() );
92 // Generate parameters to create a standard animation
93 function genFx( type, includeWidth ) {
96 attrs = { height: type };
98 // If we include width, step value is 1 to do all cssExpand values,
99 // otherwise step value is 2 to skip over Left and Right
100 includeWidth = includeWidth ? 1 : 0;
101 for ( ; i < 4 ; i += 2 - includeWidth ) {
102 which = cssExpand[ i ];
103 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
106 if ( includeWidth ) {
107 attrs.opacity = attrs.width = type;
113 function createTween( value, prop, animation ) {
115 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
117 length = collection.length;
118 for ( ; index < length; index++ ) {
119 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
121 // We're done with this property
127 function defaultPrefilter( elem, props, opts ) {
128 /* jshint validthis: true */
129 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
133 hidden = elem.nodeType && isHidden( elem ),
134 dataShow = dataPriv.get( elem, "fxshow" );
136 // Handle queue: false promises
138 hooks = jQuery._queueHooks( elem, "fx" );
139 if ( hooks.unqueued == null ) {
141 oldfire = hooks.empty.fire;
142 hooks.empty.fire = function() {
143 if ( !hooks.unqueued ) {
150 anim.always(function() {
151 // Ensure the complete handler is called before this completes
152 anim.always(function() {
154 if ( !jQuery.queue( elem, "fx" ).length ) {
161 // Height/width overflow pass
162 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
163 // Make sure that nothing sneaks out
164 // Record all 3 overflow attributes because IE9-10 do not
165 // change the overflow attribute when overflowX and
166 // overflowY are set to the same value
167 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
169 // Set display property to inline-block for height/width
170 // animations on inline elements that are having width/height animated
171 display = jQuery.css( elem, "display" );
173 // Test default display if display is currently "none"
174 checkDisplay = display === "none" ?
175 dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
177 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
178 style.display = "inline-block";
182 if ( opts.overflow ) {
183 style.overflow = "hidden";
184 anim.always(function() {
185 style.overflow = opts.overflow[ 0 ];
186 style.overflowX = opts.overflow[ 1 ];
187 style.overflowY = opts.overflow[ 2 ];
192 for ( prop in props ) {
193 value = props[ prop ];
194 if ( rfxtypes.exec( value ) ) {
195 delete props[ prop ];
196 toggle = toggle || value === "toggle";
197 if ( value === ( hidden ? "hide" : "show" ) ) {
199 // If there is dataShow left over from a stopped hide or show
200 // and we are going to proceed with show, we should pretend to be hidden
201 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
207 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
209 // Any non-fx value stops us from restoring the original display value
215 if ( !jQuery.isEmptyObject( orig ) ) {
217 if ( "hidden" in dataShow ) {
218 hidden = dataShow.hidden;
221 dataShow = dataPriv.access( elem, "fxshow", {} );
224 // Store state if its toggle - enables .stop().toggle() to "reverse"
226 dataShow.hidden = !hidden;
229 jQuery( elem ).show();
231 anim.done(function() {
232 jQuery( elem ).hide();
235 anim.done(function() {
238 dataPriv.remove( elem, "fxshow" );
239 for ( prop in orig ) {
240 jQuery.style( elem, prop, orig[ prop ] );
243 for ( prop in orig ) {
244 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
246 if ( !( prop in dataShow ) ) {
247 dataShow[ prop ] = tween.start;
249 tween.end = tween.start;
250 tween.start = prop === "width" || prop === "height" ? 1 : 0;
255 // If this is a noop like .hide().hide(), restore an overwritten display value
256 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
257 style.display = display;
261 function propFilter( props, specialEasing ) {
262 var index, name, easing, value, hooks;
264 // camelCase, specialEasing and expand cssHook pass
265 for ( index in props ) {
266 name = jQuery.camelCase( index );
267 easing = specialEasing[ name ];
268 value = props[ index ];
269 if ( jQuery.isArray( value ) ) {
271 value = props[ index ] = value[ 0 ];
274 if ( index !== name ) {
275 props[ name ] = value;
276 delete props[ index ];
279 hooks = jQuery.cssHooks[ name ];
280 if ( hooks && "expand" in hooks ) {
281 value = hooks.expand( value );
282 delete props[ name ];
284 // Not quite $.extend, this won't overwrite existing keys.
285 // Reusing 'index' because we have the correct "name"
286 for ( index in value ) {
287 if ( !( index in props ) ) {
288 props[ index ] = value[ index ];
289 specialEasing[ index ] = easing;
293 specialEasing[ name ] = easing;
298 function Animation( elem, properties, options ) {
302 length = animationPrefilters.length,
303 deferred = jQuery.Deferred().always( function() {
304 // Don't match elem in the :animated selector
311 var currentTime = fxNow || createFxNow(),
312 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
313 // Support: Android 2.3
314 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
315 temp = remaining / animation.duration || 0,
318 length = animation.tweens.length;
320 for ( ; index < length ; index++ ) {
321 animation.tweens[ index ].run( percent );
324 deferred.notifyWith( elem, [ animation, percent, remaining ]);
326 if ( percent < 1 && length ) {
329 deferred.resolveWith( elem, [ animation ] );
333 animation = deferred.promise({
335 props: jQuery.extend( {}, properties ),
336 opts: jQuery.extend( true, { specialEasing: {} }, options ),
337 originalProperties: properties,
338 originalOptions: options,
339 startTime: fxNow || createFxNow(),
340 duration: options.duration,
342 createTween: function( prop, end ) {
343 var tween = jQuery.Tween( elem, animation.opts, prop, end,
344 animation.opts.specialEasing[ prop ] || animation.opts.easing );
345 animation.tweens.push( tween );
348 stop: function( gotoEnd ) {
350 // If we are going to the end, we want to run all the tweens
351 // otherwise we skip this part
352 length = gotoEnd ? animation.tweens.length : 0;
357 for ( ; index < length ; index++ ) {
358 animation.tweens[ index ].run( 1 );
361 // Resolve when we played the last frame; otherwise, reject
363 deferred.resolveWith( elem, [ animation, gotoEnd ] );
365 deferred.rejectWith( elem, [ animation, gotoEnd ] );
370 props = animation.props;
372 propFilter( props, animation.opts.specialEasing );
374 for ( ; index < length ; index++ ) {
375 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
381 jQuery.map( props, createTween, animation );
383 if ( jQuery.isFunction( animation.opts.start ) ) {
384 animation.opts.start.call( elem, animation );
388 jQuery.extend( tick, {
391 queue: animation.opts.queue
395 // attach callbacks from options
396 return animation.progress( animation.opts.progress )
397 .done( animation.opts.done, animation.opts.complete )
398 .fail( animation.opts.fail )
399 .always( animation.opts.always );
402 jQuery.Animation = jQuery.extend( Animation, {
404 tweener: function( props, callback ) {
405 if ( jQuery.isFunction( props ) ) {
409 props = props.split(" ");
414 length = props.length;
416 for ( ; index < length ; index++ ) {
417 prop = props[ index ];
418 tweeners[ prop ] = tweeners[ prop ] || [];
419 tweeners[ prop ].unshift( callback );
423 prefilter: function( callback, prepend ) {
425 animationPrefilters.unshift( callback );
427 animationPrefilters.push( callback );
432 jQuery.speed = function( speed, easing, fn ) {
433 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
434 complete: fn || !fn && easing ||
435 jQuery.isFunction( speed ) && speed,
437 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
440 // Go to the end state if fx are off or if document is hidden
441 if ( jQuery.fx.off || document.hidden ) {
445 opt.duration = typeof opt.duration === "number" ?
446 opt.duration : opt.duration in jQuery.fx.speeds ?
447 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
450 // Normalize opt.queue - true/undefined/null -> "fx"
451 if ( opt.queue == null || opt.queue === true ) {
456 opt.old = opt.complete;
458 opt.complete = function() {
459 if ( jQuery.isFunction( opt.old ) ) {
460 opt.old.call( this );
464 jQuery.dequeue( this, opt.queue );
472 fadeTo: function( speed, to, easing, callback ) {
474 // Show any hidden elements after setting opacity to 0
475 return this.filter( isHidden ).css( "opacity", 0 ).show()
477 // Animate to the value specified
478 .end().animate({ opacity: to }, speed, easing, callback );
480 animate: function( prop, speed, easing, callback ) {
481 var empty = jQuery.isEmptyObject( prop ),
482 optall = jQuery.speed( speed, easing, callback ),
483 doAnimation = function() {
484 // Operate on a copy of prop so per-property easing won't be lost
485 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
487 // Empty animations, or finishing resolves immediately
488 if ( empty || dataPriv.get( this, "finish" ) ) {
492 doAnimation.finish = doAnimation;
494 return empty || optall.queue === false ?
495 this.each( doAnimation ) :
496 this.queue( optall.queue, doAnimation );
498 stop: function( type, clearQueue, gotoEnd ) {
499 var stopQueue = function( hooks ) {
500 var stop = hooks.stop;
505 if ( typeof type !== "string" ) {
506 gotoEnd = clearQueue;
510 if ( clearQueue && type !== false ) {
511 this.queue( type || "fx", [] );
514 return this.each(function() {
516 index = type != null && type + "queueHooks",
517 timers = jQuery.timers,
518 data = dataPriv.get( this );
521 if ( data[ index ] && data[ index ].stop ) {
522 stopQueue( data[ index ] );
525 for ( index in data ) {
526 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
527 stopQueue( data[ index ] );
532 for ( index = timers.length; index--; ) {
533 if ( timers[ index ].elem === this &&
534 (type == null || timers[ index ].queue === type) ) {
536 timers[ index ].anim.stop( gotoEnd );
538 timers.splice( index, 1 );
542 // Start the next in the queue if the last step wasn't forced.
543 // Timers currently will call their complete callbacks, which
544 // will dequeue but only if they were gotoEnd.
545 if ( dequeue || !gotoEnd ) {
546 jQuery.dequeue( this, type );
550 finish: function( type ) {
551 if ( type !== false ) {
554 return this.each(function() {
556 data = dataPriv.get( this ),
557 queue = data[ type + "queue" ],
558 hooks = data[ type + "queueHooks" ],
559 timers = jQuery.timers,
560 length = queue ? queue.length : 0;
562 // Enable finishing flag on private data
565 // Empty the queue first
566 jQuery.queue( this, type, [] );
568 if ( hooks && hooks.stop ) {
569 hooks.stop.call( this, true );
572 // Look for any active animations, and finish them
573 for ( index = timers.length; index--; ) {
574 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
575 timers[ index ].anim.stop( true );
576 timers.splice( index, 1 );
580 // Look for any animations in the old queue and finish them
581 for ( index = 0; index < length; index++ ) {
582 if ( queue[ index ] && queue[ index ].finish ) {
583 queue[ index ].finish.call( this );
587 // Turn off finishing flag
593 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
594 var cssFn = jQuery.fn[ name ];
595 jQuery.fn[ name ] = function( speed, easing, callback ) {
596 return speed == null || typeof speed === "boolean" ?
597 cssFn.apply( this, arguments ) :
598 this.animate( genFx( name, true ), speed, easing, callback );
602 // Generate shortcuts for custom animations
604 slideDown: genFx("show"),
605 slideUp: genFx("hide"),
606 slideToggle: genFx("toggle"),
607 fadeIn: { opacity: "show" },
608 fadeOut: { opacity: "hide" },
609 fadeToggle: { opacity: "toggle" }
610 }, function( name, props ) {
611 jQuery.fn[ name ] = function( speed, easing, callback ) {
612 return this.animate( props, speed, easing, callback );
617 jQuery.fx.tick = function() {
620 timers = jQuery.timers;
622 fxNow = jQuery.now();
624 for ( ; i < timers.length; i++ ) {
626 // Checks the timer has not already been removed
627 if ( !timer() && timers[ i ] === timer ) {
628 timers.splice( i--, 1 );
632 if ( !timers.length ) {
638 jQuery.fx.timer = function( timer ) {
639 jQuery.timers.push( timer );
647 jQuery.fx.interval = 13;
648 jQuery.fx.start = function() {
650 timerId = window.requestAnimationFrame ?
651 window.requestAnimationFrame( raf ) :
652 setInterval( jQuery.fx.tick, jQuery.fx.interval );
656 jQuery.fx.stop = function() {
657 if ( window.cancelAnimationFrame ) {
658 window.cancelAnimationFrame( timerId );
660 clearInterval( timerId );