6 "./css/defaultDisplay",
15 ], function( jQuery, pnum, cssExpand, isHidden, defaultDisplay, support ) {
19 rfxtypes = /^(?:toggle|show|hide)$/,
20 rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
22 animationPrefilters = [ defaultPrefilter ],
24 "*": [ function( prop, value ) {
25 var tween = this.createTween( prop, value ),
27 parts = rfxnum.exec( value ),
28 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
30 // Starting value computation is required for potential unit mismatches
31 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
32 rfxnum.exec( jQuery.css( tween.elem, prop ) ),
36 if ( start && start[ 3 ] !== unit ) {
37 // Trust units reported by jQuery.css
38 unit = unit || start[ 3 ];
40 // Make sure we update the tween properties later on
43 // Iteratively approximate from a nonzero starting point
47 // If previous iteration zeroed out, double until we get *something*
48 // Use a string for doubling factor so we don't accidentally see scale as unchanged below
49 scale = scale || ".5";
52 start = start / scale;
53 jQuery.style( tween.elem, prop, start + unit );
55 // Update scale, tolerating zero or NaN from tween.cur()
56 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
57 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
60 // Update tween properties
62 start = tween.start = +start || +target || 0;
64 // If a +=/-= token was provided, we're doing a relative animation
65 tween.end = parts[ 1 ] ?
66 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
76 window.requestAnimationFrame( raf );
81 // Animations created synchronously will run synchronously
82 function createFxNow() {
83 setTimeout(function() {
86 return ( fxNow = jQuery.now() );
89 // Generate parameters to create a standard animation
90 function genFx( type, includeWidth ) {
92 attrs = { height: type },
95 // if we include width, step value is 1 to do all cssExpand values,
96 // if we don't include width, step value is 2 to skip over Left and Right
97 includeWidth = includeWidth ? 1 : 0;
98 for ( ; i < 4 ; i += 2 - includeWidth ) {
99 which = cssExpand[ i ];
100 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
103 if ( includeWidth ) {
104 attrs.opacity = attrs.width = type;
110 function createTween( value, prop, animation ) {
112 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
114 length = collection.length;
115 for ( ; index < length; index++ ) {
116 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
118 // we're done with this property
124 function defaultPrefilter( elem, props, opts ) {
125 /* jshint validthis: true */
126 var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
130 hidden = elem.nodeType && isHidden( elem ),
131 dataShow = jQuery._data( elem, "fxshow" );
133 // handle queue: false promises
135 hooks = jQuery._queueHooks( elem, "fx" );
136 if ( hooks.unqueued == null ) {
138 oldfire = hooks.empty.fire;
139 hooks.empty.fire = function() {
140 if ( !hooks.unqueued ) {
147 anim.always(function() {
148 // doing this makes sure that the complete handler will be called
149 // before this completes
150 anim.always(function() {
152 if ( !jQuery.queue( elem, "fx" ).length ) {
159 // height/width overflow pass
160 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
161 // Make sure that nothing sneaks out
162 // Record all 3 overflow attributes because IE does not
163 // change the overflow attribute when overflowX and
164 // overflowY are set to the same value
165 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
167 // Set display property to inline-block for height/width
168 // animations on inline elements that are having width/height animated
169 display = jQuery.css( elem, "display" );
171 // Test default display if display is currently "none"
172 checkDisplay = display === "none" ?
173 jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
175 if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
177 // inline-level elements accept inline-block;
178 // block-level elements need to be inline with layout
179 if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
180 style.display = "inline-block";
187 if ( opts.overflow ) {
188 style.overflow = "hidden";
189 if ( !support.shrinkWrapBlocks() ) {
190 anim.always(function() {
191 style.overflow = opts.overflow[ 0 ];
192 style.overflowX = opts.overflow[ 1 ];
193 style.overflowY = opts.overflow[ 2 ];
199 for ( prop in props ) {
200 value = props[ prop ];
201 if ( rfxtypes.exec( value ) ) {
202 delete props[ prop ];
203 toggle = toggle || value === "toggle";
204 if ( value === ( hidden ? "hide" : "show" ) ) {
206 // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
207 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
213 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
215 // Any non-fx value stops us from restoring the original display value
221 if ( !jQuery.isEmptyObject( orig ) ) {
223 if ( "hidden" in dataShow ) {
224 hidden = dataShow.hidden;
227 dataShow = jQuery._data( elem, "fxshow", {} );
230 // store state if its toggle - enables .stop().toggle() to "reverse"
232 dataShow.hidden = !hidden;
235 jQuery( elem ).show();
237 anim.done(function() {
238 jQuery( elem ).hide();
241 anim.done(function() {
243 jQuery._removeData( elem, "fxshow" );
244 for ( prop in orig ) {
245 jQuery.style( elem, prop, orig[ prop ] );
248 for ( prop in orig ) {
249 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
251 if ( !( prop in dataShow ) ) {
252 dataShow[ prop ] = tween.start;
254 tween.end = tween.start;
255 tween.start = prop === "width" || prop === "height" ? 1 : 0;
260 // If this is a noop like .hide().hide(), restore an overwritten display value
261 } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
262 style.display = display;
266 function propFilter( props, specialEasing ) {
267 var index, name, easing, value, hooks;
269 // camelCase, specialEasing and expand cssHook pass
270 for ( index in props ) {
271 name = jQuery.camelCase( index );
272 easing = specialEasing[ name ];
273 value = props[ index ];
274 if ( jQuery.isArray( value ) ) {
276 value = props[ index ] = value[ 0 ];
279 if ( index !== name ) {
280 props[ name ] = value;
281 delete props[ index ];
284 hooks = jQuery.cssHooks[ name ];
285 if ( hooks && "expand" in hooks ) {
286 value = hooks.expand( value );
287 delete props[ name ];
289 // not quite $.extend, this wont overwrite keys already present.
290 // also - reusing 'index' from above because we have the correct "name"
291 for ( index in value ) {
292 if ( !( index in props ) ) {
293 props[ index ] = value[ index ];
294 specialEasing[ index ] = easing;
298 specialEasing[ name ] = easing;
303 function Animation( elem, properties, options ) {
307 length = animationPrefilters.length,
308 deferred = jQuery.Deferred().always( function() {
309 // don't match elem in the :animated selector
316 var currentTime = fxNow || createFxNow(),
317 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
318 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
319 temp = remaining / animation.duration || 0,
322 length = animation.tweens.length;
324 for ( ; index < length ; index++ ) {
325 animation.tweens[ index ].run( percent );
328 deferred.notifyWith( elem, [ animation, percent, remaining ]);
330 if ( percent < 1 && length ) {
333 deferred.resolveWith( elem, [ animation ] );
337 animation = deferred.promise({
339 props: jQuery.extend( {}, properties ),
340 opts: jQuery.extend( true, { specialEasing: {} }, options ),
341 originalProperties: properties,
342 originalOptions: options,
343 startTime: fxNow || createFxNow(),
344 duration: options.duration,
346 createTween: function( prop, end ) {
347 var tween = jQuery.Tween( elem, animation.opts, prop, end,
348 animation.opts.specialEasing[ prop ] || animation.opts.easing );
349 animation.tweens.push( tween );
352 stop: function( gotoEnd ) {
354 // if we are going to the end, we want to run all the tweens
355 // otherwise we skip this part
356 length = gotoEnd ? animation.tweens.length : 0;
361 for ( ; index < length ; index++ ) {
362 animation.tweens[ index ].run( 1 );
365 // resolve when we played the last frame
368 deferred.resolveWith( elem, [ animation, gotoEnd ] );
370 deferred.rejectWith( elem, [ animation, gotoEnd ] );
375 props = animation.props;
377 propFilter( props, animation.opts.specialEasing );
379 for ( ; index < length ; index++ ) {
380 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
386 jQuery.map( props, createTween, animation );
388 if ( jQuery.isFunction( animation.opts.start ) ) {
389 animation.opts.start.call( elem, animation );
393 jQuery.extend( tick, {
396 queue: animation.opts.queue
400 // attach callbacks from options
401 return animation.progress( animation.opts.progress )
402 .done( animation.opts.done, animation.opts.complete )
403 .fail( animation.opts.fail )
404 .always( animation.opts.always );
407 jQuery.Animation = jQuery.extend( Animation, {
408 tweener: function( props, callback ) {
409 if ( jQuery.isFunction( props ) ) {
413 props = props.split(" ");
418 length = props.length;
420 for ( ; index < length ; index++ ) {
421 prop = props[ index ];
422 tweeners[ prop ] = tweeners[ prop ] || [];
423 tweeners[ prop ].unshift( callback );
427 prefilter: function( callback, prepend ) {
429 animationPrefilters.unshift( callback );
431 animationPrefilters.push( callback );
436 jQuery.speed = function( speed, easing, fn ) {
437 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
438 complete: fn || !fn && easing ||
439 jQuery.isFunction( speed ) && speed,
441 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
444 // Go to the end state if fx are off or if document is hidden
445 if ( jQuery.fx.off || document.hidden ) {
449 opt.duration = typeof opt.duration === "number" ?
450 opt.duration : opt.duration in jQuery.fx.speeds ?
451 jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
454 // normalize opt.queue - true/undefined/null -> "fx"
455 if ( opt.queue == null || opt.queue === true ) {
460 opt.old = opt.complete;
462 opt.complete = function() {
463 if ( jQuery.isFunction( opt.old ) ) {
464 opt.old.call( this );
468 jQuery.dequeue( this, opt.queue );
476 fadeTo: function( speed, to, easing, callback ) {
477 // show any hidden elements after setting opacity to 0
478 return this.filter( isHidden ).css( "opacity", 0 ).show()
480 // animate to the value specified
481 .end().animate({ opacity: to }, speed, easing, callback );
483 animate: function( prop, speed, easing, callback ) {
484 var empty = jQuery.isEmptyObject( prop ),
485 optall = jQuery.speed( speed, easing, callback ),
486 doAnimation = function() {
487 // Operate on a copy of prop so per-property easing won't be lost
488 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
490 // Empty animations, or finishing resolves immediately
491 if ( empty || jQuery._data( this, "finish" ) ) {
495 doAnimation.finish = doAnimation;
497 return empty || optall.queue === false ?
498 this.each( doAnimation ) :
499 this.queue( optall.queue, doAnimation );
501 stop: function( type, clearQueue, gotoEnd ) {
502 var stopQueue = function( hooks ) {
503 var stop = hooks.stop;
508 if ( typeof type !== "string" ) {
509 gotoEnd = clearQueue;
513 if ( clearQueue && type !== false ) {
514 this.queue( type || "fx", [] );
517 return this.each(function() {
519 index = type != null && type + "queueHooks",
520 timers = jQuery.timers,
521 data = jQuery._data( this );
524 if ( data[ index ] && data[ index ].stop ) {
525 stopQueue( data[ index ] );
528 for ( index in data ) {
529 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
530 stopQueue( data[ index ] );
535 for ( index = timers.length; index--; ) {
536 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
537 timers[ index ].anim.stop( gotoEnd );
539 timers.splice( index, 1 );
543 // start the next in the queue if the last step wasn't forced
544 // timers currently will call their complete callbacks, which will dequeue
545 // but only if they were gotoEnd
546 if ( dequeue || !gotoEnd ) {
547 jQuery.dequeue( this, type );
551 finish: function( type ) {
552 if ( type !== false ) {
555 return this.each(function() {
557 data = jQuery._data( this ),
558 queue = data[ type + "queue" ],
559 hooks = data[ type + "queueHooks" ],
560 timers = jQuery.timers,
561 length = queue ? queue.length : 0;
563 // enable finishing flag on private data
566 // empty the queue first
567 jQuery.queue( this, type, [] );
569 if ( hooks && hooks.stop ) {
570 hooks.stop.call( this, true );
573 // look for any active animations, and finish them
574 for ( index = timers.length; index--; ) {
575 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
576 timers[ index ].anim.stop( true );
577 timers.splice( index, 1 );
581 // look for any animations in the old queue and finish them
582 for ( index = 0; index < length; index++ ) {
583 if ( queue[ index ] && queue[ index ].finish ) {
584 queue[ index ].finish.call( this );
588 // turn off finishing flag
594 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
595 var cssFn = jQuery.fn[ name ];
596 jQuery.fn[ name ] = function( speed, easing, callback ) {
597 return speed == null || typeof speed === "boolean" ?
598 cssFn.apply( this, arguments ) :
599 this.animate( genFx( name, true ), speed, easing, callback );
603 // Generate shortcuts for custom animations
605 slideDown: genFx("show"),
606 slideUp: genFx("hide"),
607 slideToggle: genFx("toggle"),
608 fadeIn: { opacity: "show" },
609 fadeOut: { opacity: "hide" },
610 fadeToggle: { opacity: "toggle" }
611 }, function( name, props ) {
612 jQuery.fn[ name ] = function( speed, easing, callback ) {
613 return this.animate( props, speed, easing, callback );
618 jQuery.fx.tick = function() {
620 timers = jQuery.timers,
623 fxNow = jQuery.now();
625 for ( ; i < timers.length; i++ ) {
627 // Checks the timer has not already been removed
628 if ( !timer() && timers[ i ] === timer ) {
629 timers.splice( i--, 1 );
633 if ( !timers.length ) {
639 jQuery.fx.timer = function( timer ) {
640 jQuery.timers.push( timer );
648 jQuery.fx.interval = 13;
650 jQuery.fx.start = function() {
651 timerId = window.requestAnimationFrame ?
652 window.requestAnimationFrame( raf ) :
653 setInterval( jQuery.fx.tick, jQuery.fx.interval );
656 jQuery.fx.stop = function() {
657 if ( window.cancelAnimationFrame ) {
658 window.cancelAnimationFrame( timerId );
660 clearInterval( timerId );