| define( [ |
| "./core", |
| "./core/camelCase", |
| "./var/document", |
| "./var/isFunction", |
| "./var/rcssNum", |
| "./var/rnothtmlwhite", |
| "./css/var/cssExpand", |
| "./css/var/isHiddenWithinTree", |
| "./css/adjustCSS", |
| "./data/var/dataPriv", |
| "./css/showHide", |
| |
| "./core/init", |
| "./queue", |
| "./deferred", |
| "./traversing", |
| "./manipulation", |
| "./css", |
| "./effects/Tween" |
| ], function( jQuery, camelCase, document, isFunction, rcssNum, rnothtmlwhite, cssExpand, |
| isHiddenWithinTree, adjustCSS, dataPriv, showHide ) { |
| |
| "use strict"; |
| |
| var |
| fxNow, inProgress, |
| rfxtypes = /^(?:toggle|show|hide)$/, |
| rrun = /queueHooks$/; |
| |
| function schedule() { |
| if ( inProgress ) { |
| if ( document.hidden === false && window.requestAnimationFrame ) { |
| window.requestAnimationFrame( schedule ); |
| } else { |
| window.setTimeout( schedule, jQuery.fx.interval ); |
| } |
| |
| jQuery.fx.tick(); |
| } |
| } |
| |
| // Animations created synchronously will run synchronously |
| function createFxNow() { |
| window.setTimeout( function() { |
| fxNow = undefined; |
| } ); |
| return ( fxNow = Date.now() ); |
| } |
| |
| // Generate parameters to create a standard animation |
| function genFx( type, includeWidth ) { |
| var which, |
| i = 0, |
| attrs = { height: type }; |
| |
| // If we include width, step value is 1 to do all cssExpand values, |
| // otherwise step value is 2 to skip over Left and Right |
| includeWidth = includeWidth ? 1 : 0; |
| for ( ; i < 4; i += 2 - includeWidth ) { |
| which = cssExpand[ i ]; |
| attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; |
| } |
| |
| if ( includeWidth ) { |
| attrs.opacity = attrs.width = type; |
| } |
| |
| return attrs; |
| } |
| |
| function createTween( value, prop, animation ) { |
| var tween, |
| collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), |
| index = 0, |
| length = collection.length; |
| for ( ; index < length; index++ ) { |
| if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { |
| |
| // We're done with this property |
| return tween; |
| } |
| } |
| } |
| |
| function defaultPrefilter( elem, props, opts ) { |
| var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, |
| isBox = "width" in props || "height" in props, |
| anim = this, |
| orig = {}, |
| style = elem.style, |
| hidden = elem.nodeType && isHiddenWithinTree( elem ), |
| dataShow = dataPriv.get( elem, "fxshow" ); |
| |
| // Queue-skipping animations hijack the fx hooks |
| if ( !opts.queue ) { |
| hooks = jQuery._queueHooks( elem, "fx" ); |
| if ( hooks.unqueued == null ) { |
| hooks.unqueued = 0; |
| oldfire = hooks.empty.fire; |
| hooks.empty.fire = function() { |
| if ( !hooks.unqueued ) { |
| oldfire(); |
| } |
| }; |
| } |
| hooks.unqueued++; |
| |
| anim.always( function() { |
| |
| // Ensure the complete handler is called before this completes |
| anim.always( function() { |
| hooks.unqueued--; |
| if ( !jQuery.queue( elem, "fx" ).length ) { |
| hooks.empty.fire(); |
| } |
| } ); |
| } ); |
| } |
| |
| // Detect show/hide animations |
| for ( prop in props ) { |
| value = props[ prop ]; |
| if ( rfxtypes.test( value ) ) { |
| delete props[ prop ]; |
| toggle = toggle || value === "toggle"; |
| if ( value === ( hidden ? "hide" : "show" ) ) { |
| |
| // Pretend to be hidden if this is a "show" and |
| // there is still data from a stopped show/hide |
| if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { |
| hidden = true; |
| |
| // Ignore all other no-op show/hide data |
| } else { |
| continue; |
| } |
| } |
| orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); |
| } |
| } |
| |
| // Bail out if this is a no-op like .hide().hide() |
| propTween = !jQuery.isEmptyObject( props ); |
| if ( !propTween && jQuery.isEmptyObject( orig ) ) { |
| return; |
| } |
| |
| // Restrict "overflow" and "display" styles during box animations |
| if ( isBox && elem.nodeType === 1 ) { |
| |
| // Support: IE <=9 - 11, Edge 12 - 15 |
| // Record all 3 overflow attributes because IE does not infer the shorthand |
| // from identically-valued overflowX and overflowY and Edge just mirrors |
| // the overflowX value there. |
| opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; |
| |
| // Identify a display type, preferring old show/hide data over the CSS cascade |
| restoreDisplay = dataShow && dataShow.display; |
| if ( restoreDisplay == null ) { |
| restoreDisplay = dataPriv.get( elem, "display" ); |
| } |
| display = jQuery.css( elem, "display" ); |
| if ( display === "none" ) { |
| if ( restoreDisplay ) { |
| display = restoreDisplay; |
| } else { |
| |
| // Get nonempty value(s) by temporarily forcing visibility |
| showHide( [ elem ], true ); |
| restoreDisplay = elem.style.display || restoreDisplay; |
| display = jQuery.css( elem, "display" ); |
| showHide( [ elem ] ); |
| } |
| } |
| |
| // Animate inline elements as inline-block |
| if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { |
| if ( jQuery.css( elem, "float" ) === "none" ) { |
| |
| // Restore the original display value at the end of pure show/hide animations |
| if ( !propTween ) { |
| anim.done( function() { |
| style.display = restoreDisplay; |
| } ); |
| if ( restoreDisplay == null ) { |
| display = style.display; |
| restoreDisplay = display === "none" ? "" : display; |
| } |
| } |
| style.display = "inline-block"; |
| } |
| } |
| } |
| |
| if ( opts.overflow ) { |
| style.overflow = "hidden"; |
| anim.always( function() { |
| style.overflow = opts.overflow[ 0 ]; |
| style.overflowX = opts.overflow[ 1 ]; |
| style.overflowY = opts.overflow[ 2 ]; |
| } ); |
| } |
| |
| // Implement show/hide animations |
| propTween = false; |
| for ( prop in orig ) { |
| |
| // General show/hide setup for this element animation |
| if ( !propTween ) { |
| if ( dataShow ) { |
| if ( "hidden" in dataShow ) { |
| hidden = dataShow.hidden; |
| } |
| } else { |
| dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); |
| } |
| |
| // Store hidden/visible for toggle so `.stop().toggle()` "reverses" |
| if ( toggle ) { |
| dataShow.hidden = !hidden; |
| } |
| |
| // Show elements before animating them |
| if ( hidden ) { |
| showHide( [ elem ], true ); |
| } |
| |
| /* eslint-disable no-loop-func */ |
| |
| anim.done( function() { |
| |
| /* eslint-enable no-loop-func */ |
| |
| // The final step of a "hide" animation is actually hiding the element |
| if ( !hidden ) { |
| showHide( [ elem ] ); |
| } |
| dataPriv.remove( elem, "fxshow" ); |
| for ( prop in orig ) { |
| jQuery.style( elem, prop, orig[ prop ] ); |
| } |
| } ); |
| } |
| |
| // Per-property setup |
| propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); |
| if ( !( prop in dataShow ) ) { |
| dataShow[ prop ] = propTween.start; |
| if ( hidden ) { |
| propTween.end = propTween.start; |
| propTween.start = 0; |
| } |
| } |
| } |
| } |
| |
| function propFilter( props, specialEasing ) { |
| var index, name, easing, value, hooks; |
| |
| // camelCase, specialEasing and expand cssHook pass |
| for ( index in props ) { |
| name = camelCase( index ); |
| easing = specialEasing[ name ]; |
| value = props[ index ]; |
| if ( Array.isArray( value ) ) { |
| easing = value[ 1 ]; |
| value = props[ index ] = value[ 0 ]; |
| } |
| |
| if ( index !== name ) { |
| props[ name ] = value; |
| delete props[ index ]; |
| } |
| |
| hooks = jQuery.cssHooks[ name ]; |
| if ( hooks && "expand" in hooks ) { |
| value = hooks.expand( value ); |
| delete props[ name ]; |
| |
| // Not quite $.extend, this won't overwrite existing keys. |
| // Reusing 'index' because we have the correct "name" |
| for ( index in value ) { |
| if ( !( index in props ) ) { |
| props[ index ] = value[ index ]; |
| specialEasing[ index ] = easing; |
| } |
| } |
| } else { |
| specialEasing[ name ] = easing; |
| } |
| } |
| } |
| |
| function Animation( elem, properties, options ) { |
| var result, |
| stopped, |
| index = 0, |
| length = Animation.prefilters.length, |
| deferred = jQuery.Deferred().always( function() { |
| |
| // Don't match elem in the :animated selector |
| delete tick.elem; |
| } ), |
| tick = function() { |
| if ( stopped ) { |
| return false; |
| } |
| var currentTime = fxNow || createFxNow(), |
| remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), |
| |
| // Support: Android 2.3 only |
| // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) |
| temp = remaining / animation.duration || 0, |
| percent = 1 - temp, |
| index = 0, |
| length = animation.tweens.length; |
| |
| for ( ; index < length; index++ ) { |
| animation.tweens[ index ].run( percent ); |
| } |
| |
| deferred.notifyWith( elem, [ animation, percent, remaining ] ); |
| |
| // If there's more to do, yield |
| if ( percent < 1 && length ) { |
| return remaining; |
| } |
| |
| // If this was an empty animation, synthesize a final progress notification |
| if ( !length ) { |
| deferred.notifyWith( elem, [ animation, 1, 0 ] ); |
| } |
| |
| // Resolve the animation and report its conclusion |
| deferred.resolveWith( elem, [ animation ] ); |
| return false; |
| }, |
| animation = deferred.promise( { |
| elem: elem, |
| props: jQuery.extend( {}, properties ), |
| opts: jQuery.extend( true, { |
| specialEasing: {}, |
| easing: jQuery.easing._default |
| }, options ), |
| originalProperties: properties, |
| originalOptions: options, |
| startTime: fxNow || createFxNow(), |
| duration: options.duration, |
| tweens: [], |
| createTween: function( prop, end ) { |
| var tween = jQuery.Tween( elem, animation.opts, prop, end, |
| animation.opts.specialEasing[ prop ] || animation.opts.easing ); |
| animation.tweens.push( tween ); |
| return tween; |
| }, |
| stop: function( gotoEnd ) { |
| var index = 0, |
| |
| // If we are going to the end, we want to run all the tweens |
| // otherwise we skip this part |
| length = gotoEnd ? animation.tweens.length : 0; |
| if ( stopped ) { |
| return this; |
| } |
| stopped = true; |
| for ( ; index < length; index++ ) { |
| animation.tweens[ index ].run( 1 ); |
| } |
| |
| // Resolve when we played the last frame; otherwise, reject |
| if ( gotoEnd ) { |
| deferred.notifyWith( elem, [ animation, 1, 0 ] ); |
| deferred.resolveWith( elem, [ animation, gotoEnd ] ); |
| } else { |
| deferred.rejectWith( elem, [ animation, gotoEnd ] ); |
| } |
| return this; |
| } |
| } ), |
| props = animation.props; |
| |
| propFilter( props, animation.opts.specialEasing ); |
| |
| for ( ; index < length; index++ ) { |
| result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); |
| if ( result ) { |
| if ( isFunction( result.stop ) ) { |
| jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = |
| result.stop.bind( result ); |
| } |
| return result; |
| } |
| } |
| |
| jQuery.map( props, createTween, animation ); |
| |
| if ( isFunction( animation.opts.start ) ) { |
| animation.opts.start.call( elem, animation ); |
| } |
| |
| // Attach callbacks from options |
| animation |
| .progress( animation.opts.progress ) |
| .done( animation.opts.done, animation.opts.complete ) |
| .fail( animation.opts.fail ) |
| .always( animation.opts.always ); |
| |
| jQuery.fx.timer( |
| jQuery.extend( tick, { |
| elem: elem, |
| anim: animation, |
| queue: animation.opts.queue |
| } ) |
| ); |
| |
| return animation; |
| } |
| |
| jQuery.Animation = jQuery.extend( Animation, { |
| |
| tweeners: { |
| "*": [ function( prop, value ) { |
| var tween = this.createTween( prop, value ); |
| adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); |
| return tween; |
| } ] |
| }, |
| |
| tweener: function( props, callback ) { |
| if ( isFunction( props ) ) { |
| callback = props; |
| props = [ "*" ]; |
| } else { |
| props = props.match( rnothtmlwhite ); |
| } |
| |
| var prop, |
| index = 0, |
| length = props.length; |
| |
| for ( ; index < length; index++ ) { |
| prop = props[ index ]; |
| Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; |
| Animation.tweeners[ prop ].unshift( callback ); |
| } |
| }, |
| |
| prefilters: [ defaultPrefilter ], |
| |
| prefilter: function( callback, prepend ) { |
| if ( prepend ) { |
| Animation.prefilters.unshift( callback ); |
| } else { |
| Animation.prefilters.push( callback ); |
| } |
| } |
| } ); |
| |
| jQuery.speed = function( speed, easing, fn ) { |
| var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { |
| complete: fn || !fn && easing || |
| isFunction( speed ) && speed, |
| duration: speed, |
| easing: fn && easing || easing && !isFunction( easing ) && easing |
| }; |
| |
| // Go to the end state if fx are off |
| if ( jQuery.fx.off ) { |
| opt.duration = 0; |
| |
| } else { |
| if ( typeof opt.duration !== "number" ) { |
| if ( opt.duration in jQuery.fx.speeds ) { |
| opt.duration = jQuery.fx.speeds[ opt.duration ]; |
| |
| } else { |
| opt.duration = jQuery.fx.speeds._default; |
| } |
| } |
| } |
| |
| // Normalize opt.queue - true/undefined/null -> "fx" |
| if ( opt.queue == null || opt.queue === true ) { |
| opt.queue = "fx"; |
| } |
| |
| // Queueing |
| opt.old = opt.complete; |
| |
| opt.complete = function() { |
| if ( isFunction( opt.old ) ) { |
| opt.old.call( this ); |
| } |
| |
| if ( opt.queue ) { |
| jQuery.dequeue( this, opt.queue ); |
| } |
| }; |
| |
| return opt; |
| }; |
| |
| jQuery.fn.extend( { |
| fadeTo: function( speed, to, easing, callback ) { |
| |
| // Show any hidden elements after setting opacity to 0 |
| return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() |
| |
| // Animate to the value specified |
| .end().animate( { opacity: to }, speed, easing, callback ); |
| }, |
| animate: function( prop, speed, easing, callback ) { |
| var empty = jQuery.isEmptyObject( prop ), |
| optall = jQuery.speed( speed, easing, callback ), |
| doAnimation = function() { |
| |
| // Operate on a copy of prop so per-property easing won't be lost |
| var anim = Animation( this, jQuery.extend( {}, prop ), optall ); |
| |
| // Empty animations, or finishing resolves immediately |
| if ( empty || dataPriv.get( this, "finish" ) ) { |
| anim.stop( true ); |
| } |
| }; |
| doAnimation.finish = doAnimation; |
| |
| return empty || optall.queue === false ? |
| this.each( doAnimation ) : |
| this.queue( optall.queue, doAnimation ); |
| }, |
| stop: function( type, clearQueue, gotoEnd ) { |
| var stopQueue = function( hooks ) { |
| var stop = hooks.stop; |
| delete hooks.stop; |
| stop( gotoEnd ); |
| }; |
| |
| if ( typeof type !== "string" ) { |
| gotoEnd = clearQueue; |
| clearQueue = type; |
| type = undefined; |
| } |
| if ( clearQueue ) { |
| this.queue( type || "fx", [] ); |
| } |
| |
| return this.each( function() { |
| var dequeue = true, |
| index = type != null && type + "queueHooks", |
| timers = jQuery.timers, |
| data = dataPriv.get( this ); |
| |
| if ( index ) { |
| if ( data[ index ] && data[ index ].stop ) { |
| stopQueue( data[ index ] ); |
| } |
| } else { |
| for ( index in data ) { |
| if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { |
| stopQueue( data[ index ] ); |
| } |
| } |
| } |
| |
| for ( index = timers.length; index--; ) { |
| if ( timers[ index ].elem === this && |
| ( type == null || timers[ index ].queue === type ) ) { |
| |
| timers[ index ].anim.stop( gotoEnd ); |
| dequeue = false; |
| timers.splice( index, 1 ); |
| } |
| } |
| |
| // Start the next in the queue if the last step wasn't forced. |
| // Timers currently will call their complete callbacks, which |
| // will dequeue but only if they were gotoEnd. |
| if ( dequeue || !gotoEnd ) { |
| jQuery.dequeue( this, type ); |
| } |
| } ); |
| }, |
| finish: function( type ) { |
| if ( type !== false ) { |
| type = type || "fx"; |
| } |
| return this.each( function() { |
| var index, |
| data = dataPriv.get( this ), |
| queue = data[ type + "queue" ], |
| hooks = data[ type + "queueHooks" ], |
| timers = jQuery.timers, |
| length = queue ? queue.length : 0; |
| |
| // Enable finishing flag on private data |
| data.finish = true; |
| |
| // Empty the queue first |
| jQuery.queue( this, type, [] ); |
| |
| if ( hooks && hooks.stop ) { |
| hooks.stop.call( this, true ); |
| } |
| |
| // Look for any active animations, and finish them |
| for ( index = timers.length; index--; ) { |
| if ( timers[ index ].elem === this && timers[ index ].queue === type ) { |
| timers[ index ].anim.stop( true ); |
| timers.splice( index, 1 ); |
| } |
| } |
| |
| // Look for any animations in the old queue and finish them |
| for ( index = 0; index < length; index++ ) { |
| if ( queue[ index ] && queue[ index ].finish ) { |
| queue[ index ].finish.call( this ); |
| } |
| } |
| |
| // Turn off finishing flag |
| delete data.finish; |
| } ); |
| } |
| } ); |
| |
| jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { |
| var cssFn = jQuery.fn[ name ]; |
| jQuery.fn[ name ] = function( speed, easing, callback ) { |
| return speed == null || typeof speed === "boolean" ? |
| cssFn.apply( this, arguments ) : |
| this.animate( genFx( name, true ), speed, easing, callback ); |
| }; |
| } ); |
| |
| // Generate shortcuts for custom animations |
| jQuery.each( { |
| slideDown: genFx( "show" ), |
| slideUp: genFx( "hide" ), |
| slideToggle: genFx( "toggle" ), |
| fadeIn: { opacity: "show" }, |
| fadeOut: { opacity: "hide" }, |
| fadeToggle: { opacity: "toggle" } |
| }, function( name, props ) { |
| jQuery.fn[ name ] = function( speed, easing, callback ) { |
| return this.animate( props, speed, easing, callback ); |
| }; |
| } ); |
| |
| jQuery.timers = []; |
| jQuery.fx.tick = function() { |
| var timer, |
| i = 0, |
| timers = jQuery.timers; |
| |
| fxNow = Date.now(); |
| |
| for ( ; i < timers.length; i++ ) { |
| timer = timers[ i ]; |
| |
| // Run the timer and safely remove it when done (allowing for external removal) |
| if ( !timer() && timers[ i ] === timer ) { |
| timers.splice( i--, 1 ); |
| } |
| } |
| |
| if ( !timers.length ) { |
| jQuery.fx.stop(); |
| } |
| fxNow = undefined; |
| }; |
| |
| jQuery.fx.timer = function( timer ) { |
| jQuery.timers.push( timer ); |
| jQuery.fx.start(); |
| }; |
| |
| jQuery.fx.interval = 13; |
| jQuery.fx.start = function() { |
| if ( inProgress ) { |
| return; |
| } |
| |
| inProgress = true; |
| schedule(); |
| }; |
| |
| jQuery.fx.stop = function() { |
| inProgress = null; |
| }; |
| |
| jQuery.fx.speeds = { |
| slow: 600, |
| fast: 200, |
| |
| // Default speed |
| _default: 400 |
| }; |
| |
| return jQuery; |
| } ); |