9 "./css/defaultDisplay",
10 "./data/var/dataPriv",
18 ], function( jQuery, document, rcssNum, cssExpand, rnotwhite,
19 isHidden, adjustCSS, defaultDisplay, dataPriv ) {
23 rfxtypes = /^(?:toggle|show|hide)$/,
26 // Animations created synchronously will run synchronously
27 function createFxNow() {
28 window.setTimeout( function() {
31 return ( fxNow = jQuery.now() );
34 // Generate parameters to create a standard animation
35 function genFx( type, includeWidth ) {
38 attrs = { height: type };
40 // If we include width, step value is 1 to do all cssExpand values,
41 // otherwise step value is 2 to skip over Left and Right
42 includeWidth = includeWidth ? 1 : 0;
43 for ( ; i < 4 ; i += 2 - includeWidth ) {
44 which = cssExpand[ i ];
45 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
49 attrs.opacity = attrs.width = type;
55 function createTween( value, prop, animation ) {
57 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
59 length = collection.length;
60 for ( ; index < length; index++ ) {
61 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
63 // We're done with this property
69 function defaultPrefilter( elem, props, opts ) {
70 /* jshint validthis: true */
71 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
75 hidden = elem.nodeType && isHidden( elem ),
76 dataShow = dataPriv.get( elem, "fxshow" );
78 // Handle queue: false promises
80 hooks = jQuery._queueHooks( elem, "fx" );
81 if ( hooks.unqueued == null ) {
83 oldfire = hooks.empty.fire;
84 hooks.empty.fire = function() {
85 if ( !hooks.unqueued ) {
92 anim.always( function() {
94 // Ensure the complete handler is called before this completes
95 anim.always( function() {
97 if ( !jQuery.queue( elem, "fx" ).length ) {
104 // Height/width overflow pass
105 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
107 // Make sure that nothing sneaks out
108 // Record all 3 overflow attributes because IE9-10 do not
109 // change the overflow attribute when overflowX and
110 // overflowY are set to the same value
111 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
113 // Set display property to inline-block for height/width
114 // animations on inline elements that are having width/height animated
115 display = jQuery.css( elem, "display" );
117 // Test default display if display is currently "none"
118 checkDisplay = display === "none" ?
119 dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
121 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
122 style.display = "inline-block";
126 if ( opts.overflow ) {
127 style.overflow = "hidden";
128 anim.always( function() {
129 style.overflow = opts.overflow[ 0 ];
130 style.overflowX = opts.overflow[ 1 ];
131 style.overflowY = opts.overflow[ 2 ];
136 for ( prop in props ) {
137 value = props[ prop ];
138 if ( rfxtypes.exec( value ) ) {
139 delete props[ prop ];
140 toggle = toggle || value === "toggle";
141 if ( value === ( hidden ? "hide" : "show" ) ) {
143 // If there is dataShow left over from a stopped hide or show
144 // and we are going to proceed with show, we should pretend to be hidden
145 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
151 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
153 // Any non-fx value stops us from restoring the original display value
159 if ( !jQuery.isEmptyObject( orig ) ) {
161 if ( "hidden" in dataShow ) {
162 hidden = dataShow.hidden;
165 dataShow = dataPriv.access( elem, "fxshow", {} );
168 // Store state if its toggle - enables .stop().toggle() to "reverse"
170 dataShow.hidden = !hidden;
173 jQuery( elem ).show();
175 anim.done( function() {
176 jQuery( elem ).hide();
179 anim.done( function() {
182 dataPriv.remove( elem, "fxshow" );
183 for ( prop in orig ) {
184 jQuery.style( elem, prop, orig[ prop ] );
187 for ( prop in orig ) {
188 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
190 if ( !( prop in dataShow ) ) {
191 dataShow[ prop ] = tween.start;
193 tween.end = tween.start;
194 tween.start = prop === "width" || prop === "height" ? 1 : 0;
199 // If this is a noop like .hide().hide(), restore an overwritten display value
200 } else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
201 style.display = display;
205 function propFilter( props, specialEasing ) {
206 var index, name, easing, value, hooks;
208 // camelCase, specialEasing and expand cssHook pass
209 for ( index in props ) {
210 name = jQuery.camelCase( index );
211 easing = specialEasing[ name ];
212 value = props[ index ];
213 if ( jQuery.isArray( value ) ) {
215 value = props[ index ] = value[ 0 ];
218 if ( index !== name ) {
219 props[ name ] = value;
220 delete props[ index ];
223 hooks = jQuery.cssHooks[ name ];
224 if ( hooks && "expand" in hooks ) {
225 value = hooks.expand( value );
226 delete props[ name ];
228 // Not quite $.extend, this won't overwrite existing keys.
229 // Reusing 'index' because we have the correct "name"
230 for ( index in value ) {
231 if ( !( index in props ) ) {
232 props[ index ] = value[ index ];
233 specialEasing[ index ] = easing;
237 specialEasing[ name ] = easing;
242 function Animation( elem, properties, options ) {
246 length = Animation.prefilters.length,
247 deferred = jQuery.Deferred().always( function() {
249 // Don't match elem in the :animated selector
256 var currentTime = fxNow || createFxNow(),
257 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
259 // Support: Android 2.3
260 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
261 temp = remaining / animation.duration || 0,
264 length = animation.tweens.length;
266 for ( ; index < length ; index++ ) {
267 animation.tweens[ index ].run( percent );
270 deferred.notifyWith( elem, [ animation, percent, remaining ] );
272 if ( percent < 1 && length ) {
275 deferred.resolveWith( elem, [ animation ] );
279 animation = deferred.promise( {
281 props: jQuery.extend( {}, properties ),
282 opts: jQuery.extend( true, {
284 easing: jQuery.easing._default
286 originalProperties: properties,
287 originalOptions: options,
288 startTime: fxNow || createFxNow(),
289 duration: options.duration,
291 createTween: function( prop, end ) {
292 var tween = jQuery.Tween( elem, animation.opts, prop, end,
293 animation.opts.specialEasing[ prop ] || animation.opts.easing );
294 animation.tweens.push( tween );
297 stop: function( gotoEnd ) {
300 // If we are going to the end, we want to run all the tweens
301 // otherwise we skip this part
302 length = gotoEnd ? animation.tweens.length : 0;
307 for ( ; index < length ; index++ ) {
308 animation.tweens[ index ].run( 1 );
311 // Resolve when we played the last frame; otherwise, reject
313 deferred.notifyWith( elem, [ animation, 1, 0 ] );
314 deferred.resolveWith( elem, [ animation, gotoEnd ] );
316 deferred.rejectWith( elem, [ animation, gotoEnd ] );
321 props = animation.props;
323 propFilter( props, animation.opts.specialEasing );
325 for ( ; index < length ; index++ ) {
326 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
328 if ( jQuery.isFunction( result.stop ) ) {
329 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
330 jQuery.proxy( result.stop, result );
336 jQuery.map( props, createTween, animation );
338 if ( jQuery.isFunction( animation.opts.start ) ) {
339 animation.opts.start.call( elem, animation );
343 jQuery.extend( tick, {
346 queue: animation.opts.queue
350 // attach callbacks from options
351 return animation.progress( animation.opts.progress )
352 .done( animation.opts.done, animation.opts.complete )
353 .fail( animation.opts.fail )
354 .always( animation.opts.always );
357 jQuery.Animation = jQuery.extend( Animation, {
359 "*": [ function( prop, value ) {
360 var tween = this.createTween( prop, value );
361 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
366 tweener: function( props, callback ) {
367 if ( jQuery.isFunction( props ) ) {
371 props = props.match( rnotwhite );
376 length = props.length;
378 for ( ; index < length ; index++ ) {
379 prop = props[ index ];
380 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
381 Animation.tweeners[ prop ].unshift( callback );
385 prefilters: [ defaultPrefilter ],
387 prefilter: function( callback, prepend ) {
389 Animation.prefilters.unshift( callback );
391 Animation.prefilters.push( callback );
396 jQuery.speed = function( speed, easing, fn ) {
397 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
398 complete: fn || !fn && easing ||
399 jQuery.isFunction( speed ) && speed,
401 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
404 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
405 opt.duration : opt.duration in jQuery.fx.speeds ?
406 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
408 // Normalize opt.queue - true/undefined/null -> "fx"
409 if ( opt.queue == null || opt.queue === true ) {
414 opt.old = opt.complete;
416 opt.complete = function() {
417 if ( jQuery.isFunction( opt.old ) ) {
418 opt.old.call( this );
422 jQuery.dequeue( this, opt.queue );
430 fadeTo: function( speed, to, easing, callback ) {
432 // Show any hidden elements after setting opacity to 0
433 return this.filter( isHidden ).css( "opacity", 0 ).show()
435 // Animate to the value specified
436 .end().animate( { opacity: to }, speed, easing, callback );
438 animate: function( prop, speed, easing, callback ) {
439 var empty = jQuery.isEmptyObject( prop ),
440 optall = jQuery.speed( speed, easing, callback ),
441 doAnimation = function() {
443 // Operate on a copy of prop so per-property easing won't be lost
444 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
446 // Empty animations, or finishing resolves immediately
447 if ( empty || dataPriv.get( this, "finish" ) ) {
451 doAnimation.finish = doAnimation;
453 return empty || optall.queue === false ?
454 this.each( doAnimation ) :
455 this.queue( optall.queue, doAnimation );
457 stop: function( type, clearQueue, gotoEnd ) {
458 var stopQueue = function( hooks ) {
459 var stop = hooks.stop;
464 if ( typeof type !== "string" ) {
465 gotoEnd = clearQueue;
469 if ( clearQueue && type !== false ) {
470 this.queue( type || "fx", [] );
473 return this.each( function() {
475 index = type != null && type + "queueHooks",
476 timers = jQuery.timers,
477 data = dataPriv.get( this );
480 if ( data[ index ] && data[ index ].stop ) {
481 stopQueue( data[ index ] );
484 for ( index in data ) {
485 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
486 stopQueue( data[ index ] );
491 for ( index = timers.length; index--; ) {
492 if ( timers[ index ].elem === this &&
493 ( type == null || timers[ index ].queue === type ) ) {
495 timers[ index ].anim.stop( gotoEnd );
497 timers.splice( index, 1 );
501 // Start the next in the queue if the last step wasn't forced.
502 // Timers currently will call their complete callbacks, which
503 // will dequeue but only if they were gotoEnd.
504 if ( dequeue || !gotoEnd ) {
505 jQuery.dequeue( this, type );
509 finish: function( type ) {
510 if ( type !== false ) {
513 return this.each( function() {
515 data = dataPriv.get( this ),
516 queue = data[ type + "queue" ],
517 hooks = data[ type + "queueHooks" ],
518 timers = jQuery.timers,
519 length = queue ? queue.length : 0;
521 // Enable finishing flag on private data
524 // Empty the queue first
525 jQuery.queue( this, type, [] );
527 if ( hooks && hooks.stop ) {
528 hooks.stop.call( this, true );
531 // Look for any active animations, and finish them
532 for ( index = timers.length; index--; ) {
533 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
534 timers[ index ].anim.stop( true );
535 timers.splice( index, 1 );
539 // Look for any animations in the old queue and finish them
540 for ( index = 0; index < length; index++ ) {
541 if ( queue[ index ] && queue[ index ].finish ) {
542 queue[ index ].finish.call( this );
546 // Turn off finishing flag
552 jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
553 var cssFn = jQuery.fn[ name ];
554 jQuery.fn[ name ] = function( speed, easing, callback ) {
555 return speed == null || typeof speed === "boolean" ?
556 cssFn.apply( this, arguments ) :
557 this.animate( genFx( name, true ), speed, easing, callback );
561 // Generate shortcuts for custom animations
563 slideDown: genFx( "show" ),
564 slideUp: genFx( "hide" ),
565 slideToggle: genFx( "toggle" ),
566 fadeIn: { opacity: "show" },
567 fadeOut: { opacity: "hide" },
568 fadeToggle: { opacity: "toggle" }
569 }, function( name, props ) {
570 jQuery.fn[ name ] = function( speed, easing, callback ) {
571 return this.animate( props, speed, easing, callback );
576 jQuery.fx.tick = function() {
579 timers = jQuery.timers;
581 fxNow = jQuery.now();
583 for ( ; i < timers.length; i++ ) {
586 // Checks the timer has not already been removed
587 if ( !timer() && timers[ i ] === timer ) {
588 timers.splice( i--, 1 );
592 if ( !timers.length ) {
598 jQuery.fx.timer = function( timer ) {
599 jQuery.timers.push( timer );
607 jQuery.fx.interval = 13;
608 jQuery.fx.start = function() {
610 timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
614 jQuery.fx.stop = function() {
615 window.clearInterval( timerId );