]> source.dussan.org Git - jquery.git/commitdiff
Scalarize [value, easing] before css-expanding; closes gh-750.
authorRichard Gibson <richard.gibson@gmail.com>
Fri, 11 May 2012 20:20:32 +0000 (16:20 -0400)
committerDave Methvin <dave.methvin@gmail.com>
Fri, 11 May 2012 20:22:00 +0000 (16:22 -0400)
src/effects.js
test/unit/effects.js

index b6a374fb455e1f90045ac7962ca084dda544c39d..ff2d5dedfe471e17f928bd5b5f889ab57876ccca 100644 (file)
@@ -5,7 +5,7 @@ var fxNow, timerId, iframe, iframeDoc,
        rfxtypes = /^(?:toggle|show|hide)$/,
        rfxnum = /^([\-+]=)?((?:\d*\.)?\d+)([a-z%]*)$/i,
        rrun = /\.run$/,
-       animationPrefilters = [],
+       animationPrefilters = [ defaultPrefilter ],
        tweeners = {
                "*": [function( prop, value ) {
                        var end, unit,
@@ -73,10 +73,10 @@ function Animation( elem, properties, options ) {
                }),
                animation = deferred.promise({
                        elem: elem,
+                       props: jQuery.extend( {}, properties ),
+                       opts: jQuery.extend( true, { specialEasing: {} }, options ),
                        originalProperties: properties,
                        originalOptions: options,
-                       props: jQuery.extend( {}, properties ),
-                       opts: jQuery.extend( {}, options ),
                        startTime: fxNow || createFxNow(),
                        duration: options.duration,
                        finish: finished.done,
@@ -120,7 +120,7 @@ function Animation( elem, properties, options ) {
                }),
                props = animation.props;
 
-       propFilter( props );
+       propFilter( props, animation.opts.specialEasing );
 
        for ( ; index < length ; index++ ) {
                result = animationPrefilters[ index ].call( animation,
@@ -142,30 +142,39 @@ function Animation( elem, properties, options ) {
        return animation;
 }
 
-function propFilter( props ) {
-       var index, name, hooks, replace;
+function propFilter( props, specialEasing ) {
+       var index, name, easing, value, hooks;
 
-       // camelCase and expand cssHook pass
+       // 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 ] = props[ index ];
+                       props[ name ] = value;
                        delete props[ index ];
                }
 
                hooks = jQuery.cssHooks[ name ];
                if ( hooks && "expand" in hooks ) {
-                       replace = hooks.expand( props[ name ] );
+                       value = hooks.expand( value );
                        delete props[ name ];
 
                        // not quite $.extend, this wont overwrite keys already present.
                        // also - reusing 'index' from above because we have the correct "name"
-                       for ( index in replace ) {
-                               if ( index in props ) {
-                                       continue;
+                       for ( index in value ) {
+                               if ( !( index in props ) ) {
+                                       props[ index ] = value[ index ];
+                                       specialEasing[ index ] = easing;
                                }
-                               props[ index ] = replace[ index ];
                        }
+               } else {
+                       specialEasing[ name ] = easing;
                }
        }
 }
@@ -200,19 +209,12 @@ jQuery.Animation = jQuery.extend( Animation, {
        }
 });
 
-Animation.prefilter(function( elem, props, opts ) {
-       var index, value,
-               style = elem.style;
-
-       // custom easing pass
-       opts.specialEasing = opts.specialEasing || {};
-       for ( index in props ) {
-               value = props[ index ];
-               if ( jQuery.isArray( value ) ) {
-                       opts.specialEasing[ index ] = value[ 1 ];
-                       value = props[ index ] = value[ 0 ];
-               }
-       }
+function defaultPrefilter( elem, props, opts ) {
+       var index, prop, value, length, dataShow, tween,
+               style = elem.style,
+               orig = {},
+               handled = [],
+               hidden = jQuery( elem ).is(":hidden");
 
        // height/width overflow pass
        if ( elem.nodeType === 1 && ( props.height || props.width ) ) {
@@ -246,15 +248,9 @@ Animation.prefilter(function( elem, props, opts ) {
                        style.overflowY = opts.overflow[ 2 ];
                });
        }
-});
 
-// special case show/hide prefilter
-Animation.prefilter(function( elem, props, opts ) {
-       var index, prop, value, length, dataShow, tween,
-               orig = {},
-               handled = [],
-               hidden = jQuery( elem ).is(":hidden");
 
+       // show/hide pass
        for ( index in props ) {
                value = props[ index ];
                if ( rfxtypes.exec( value ) ) {
@@ -297,7 +293,7 @@ Animation.prefilter(function( elem, props, opts ) {
                        }
                }
        }
-});
+}
 
 function Tween( elem, options, prop, end, easing ) {
        return new Tween.prototype.init( elem, options, prop, end, easing );
index 74f83e7c4f953f3b129668b07c8bcc4077acd2b4..0fab3f5f2ae40bf9ca1308d16f18ec41d99369cd 100644 (file)
@@ -1248,6 +1248,53 @@ test("animate with per-property easing", function(){
 
 });
 
+test("animate with CSS shorthand properties", function(){
+       expect(11);
+       stop();
+
+       var _default_count = 0,
+               _special_count = 0,
+               propsBasic = { padding: "10 20 30" },
+               propsSpecial = { padding: [ "1 2 3", "_special" ] };
+
+       jQuery.easing["_default"] = function(p) {
+               if ( p >= 1 ) {
+                       _default_count++;
+               }
+               return p;
+       };
+
+       jQuery.easing["_special"] = function(p) {
+               if ( p >= 1 ) {
+                       _special_count++;
+               }
+               return p;
+       };
+
+       jQuery("#foo")
+               .animate( propsBasic, 200, "_default", function() {
+                       equal( this.style.paddingTop, "10px", "padding-top was animated" );
+                       equal( this.style.paddingLeft, "20px", "padding-left was animated" );
+                       equal( this.style.paddingRight, "20px", "padding-right was animated" );
+                       equal( this.style.paddingBottom, "30px", "padding-bottom was animated" );
+                       equal( _default_count, 4, "per-animation default easing called for each property" );
+                       _default_count = 0;
+               })
+               .animate( propsSpecial, 200, "_default", function() {
+                       equal( this.style.paddingTop, "1px", "padding-top was animated again" );
+                       equal( this.style.paddingLeft, "2px", "padding-left was animated again" );
+                       equal( this.style.paddingRight, "2px", "padding-right was animated again" );
+                       equal( this.style.paddingBottom, "3px", "padding-bottom was animated again" );
+                       equal( _default_count, 0, "per-animation default easing not called" );
+                       equal( _special_count, 4, "special easing called for each property" );
+
+                       jQuery(this).css("padding", "0");
+                       delete jQuery.easing["_default"];
+                       delete jQuery.easing["_special"];
+                       start();
+               });
+});
+
 test("hide hidden elements (bug #7141)", function() {
        expect(3);
        QUnit.reset();