scratch – Rev 125

Subversion Repositories:
Rev:
define([
        "./core",
        "./var/pnum",
        "./css/var/cssExpand",
        "./css/var/isHidden",
        "./css/defaultDisplay",
        "./data/var/data_priv",

        "./core/init",
        "./effects/Tween",
        "./queue",
        "./css",
        "./deferred",
        "./traversing"
], function( jQuery, pnum, cssExpand, isHidden, defaultDisplay, data_priv ) {

var
        fxNow, timerId,
        rfxtypes = /^(?:toggle|show|hide)$/,
        rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
        rrun = /queueHooks$/,
        animationPrefilters = [ defaultPrefilter ],
        tweeners = {
                "*": [ function( prop, value ) {
                        var tween = this.createTween( prop, value ),
                                target = tween.cur(),
                                parts = rfxnum.exec( value ),
                                unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),

                                // Starting value computation is required for potential unit mismatches
                                start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
                                        rfxnum.exec( jQuery.css( tween.elem, prop ) ),
                                scale = 1,
                                maxIterations = 20;

                        if ( start && start[ 3 ] !== unit ) {
                                // Trust units reported by jQuery.css
                                unit = unit || start[ 3 ];

                                // Make sure we update the tween properties later on
                                parts = parts || [];

                                // Iteratively approximate from a nonzero starting point
                                start = +target || 1;

                                do {
                                        // If previous iteration zeroed out, double until we get *something*.
                                        // Use string for doubling so we don't accidentally see scale as unchanged below
                                        scale = scale || ".5";

                                        // Adjust and apply
                                        start = start / scale;
                                        jQuery.style( tween.elem, prop, start + unit );

                                // Update scale, tolerating zero or NaN from tween.cur(),
                                // break the loop if scale is unchanged or perfect, or if we've just had enough
                                } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
                        }

                        // Update tween properties
                        if ( parts ) {
                                start = tween.start = +start || +target || 0;
                                tween.unit = unit;
                                // If a +=/-= token was provided, we're doing a relative animation
                                tween.end = parts[ 1 ] ?
                                        start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
                                        +parts[ 2 ];
                        }

                        return tween;
                } ]
        };

// Animations created synchronously will run synchronously
function createFxNow() {
        setTimeout(function() {
                fxNow = undefined;
        });
        return ( fxNow = jQuery.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 = ( tweeners[ prop ] || [] ).concat( 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 ) {
        /* jshint validthis: true */
        var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
                anim = this,
                orig = {},
                style = elem.style,
                hidden = elem.nodeType && isHidden( elem ),
                dataShow = data_priv.get( elem, "fxshow" );

        // Handle queue: false promises
        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();
                                }
                        });
                });
        }

        // Height/width overflow pass
        if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
                // Make sure that nothing sneaks out
                // Record all 3 overflow attributes because IE9-10 do not
                // change the overflow attribute when overflowX and
                // overflowY are set to the same value
                opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];

                // Set display property to inline-block for height/width
                // animations on inline elements that are having width/height animated
                display = jQuery.css( elem, "display" );

                // Test default display if display is currently "none"
                checkDisplay = display === "none" ?
                        data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;

                if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
                        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 ];
                });
        }

        // show/hide pass
        for ( prop in props ) {
                value = props[ prop ];
                if ( rfxtypes.exec( value ) ) {
                        delete props[ prop ];
                        toggle = toggle || value === "toggle";
                        if ( value === ( hidden ? "hide" : "show" ) ) {

                                // 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
                                if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
                                        hidden = true;
                                } else {
                                        continue;
                                }
                        }
                        orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );

                // Any non-fx value stops us from restoring the original display value
                } else {
                        display = undefined;
                }
        }

        if ( !jQuery.isEmptyObject( orig ) ) {
                if ( dataShow ) {
                        if ( "hidden" in dataShow ) {
                                hidden = dataShow.hidden;
                        }
                } else {
                        dataShow = data_priv.access( elem, "fxshow", {} );
                }

                // Store state if its toggle - enables .stop().toggle() to "reverse"
                if ( toggle ) {
                        dataShow.hidden = !hidden;
                }
                if ( hidden ) {
                        jQuery( elem ).show();
                } else {
                        anim.done(function() {
                                jQuery( elem ).hide();
                        });
                }
                anim.done(function() {
                        var prop;

                        data_priv.remove( elem, "fxshow" );
                        for ( prop in orig ) {
                                jQuery.style( elem, prop, orig[ prop ] );
                        }
                });
                for ( prop in orig ) {
                        tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );

                        if ( !( prop in dataShow ) ) {
                                dataShow[ prop ] = tween.start;
                                if ( hidden ) {
                                        tween.end = tween.start;
                                        tween.start = prop === "width" || prop === "height" ? 1 : 0;
                                }
                        }
                }

        // If this is a noop like .hide().hide(), restore an overwritten display value
        } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
                style.display = display;
        }
}

function propFilter( props, specialEasing ) {
        var index, name, easing, value, hooks;

        // camelCase, specialEasing and expand cssHook pass
        for ( index in props ) {
                name = jQuery.camelCase( index );
                easing = specialEasing[ name ];
                value = props[ index ];
                if ( jQuery.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 = animationPrefilters.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
                                // 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 ( percent < 1 && length ) {
                                return remaining;
                        } else {
                                deferred.resolveWith( elem, [ animation ] );
                                return false;
                        }
                },
                animation = deferred.promise({
                        elem: elem,
                        props: jQuery.extend( {}, properties ),
                        opts: jQuery.extend( true, { specialEasing: {} }, 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.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 = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
                if ( result ) {
                        return result;
                }
        }

        jQuery.map( props, createTween, animation );

        if ( jQuery.isFunction( animation.opts.start ) ) {
                animation.opts.start.call( elem, animation );
        }

        jQuery.fx.timer(
                jQuery.extend( tick, {
                        elem: elem,
                        anim: animation,
                        queue: animation.opts.queue
                })
        );

        // attach callbacks from options
        return animation.progress( animation.opts.progress )
                .done( animation.opts.done, animation.opts.complete )
                .fail( animation.opts.fail )
                .always( animation.opts.always );
}

jQuery.Animation = jQuery.extend( Animation, {

        tweener: function( props, callback ) {
                if ( jQuery.isFunction( props ) ) {
                        callback = props;
                        props = [ "*" ];
                } else {
                        props = props.split(" ");
                }

                var prop,
                        index = 0,
                        length = props.length;

                for ( ; index < length ; index++ ) {
                        prop = props[ index ];
                        tweeners[ prop ] = tweeners[ prop ] || [];
                        tweeners[ prop ].unshift( callback );
                }
        },

        prefilter: function( callback, prepend ) {
                if ( prepend ) {
                        animationPrefilters.unshift( callback );
                } else {
                        animationPrefilters.push( callback );
                }
        }
});

jQuery.speed = function( speed, easing, fn ) {
        var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
                complete: fn || !fn && easing ||
                        jQuery.isFunction( speed ) && speed,
                duration: speed,
                easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
        };

        opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
                opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ 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 ( jQuery.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( isHidden ).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 || data_priv.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 && type !== false ) {
                        this.queue( type || "fx", [] );
                }

                return this.each(function() {
                        var dequeue = true,
                                index = type != null && type + "queueHooks",
                                timers = jQuery.timers,
                                data = data_priv.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 = data_priv.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 = jQuery.now();

        for ( ; i < timers.length; i++ ) {
                timer = timers[ i ];
                // Checks the timer has not already been removed
                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 );
        if ( timer() ) {
                jQuery.fx.start();
        } else {
                jQuery.timers.pop();
        }
};

jQuery.fx.interval = 13;

jQuery.fx.start = function() {
        if ( !timerId ) {
                timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
        }
};

jQuery.fx.stop = function() {
        clearInterval( timerId );
        timerId = null;
};

jQuery.fx.speeds = {
        slow: 600,
        fast: 200,
        // Default speed
        _default: 400
};

return jQuery;
});

Generated by GNU Enscript 1.6.5.90.