Skip to content

Commit

Permalink
Effects Core: Do not overwrite css or class changes that aren't anima…
Browse files Browse the repository at this point in the history
…ted during class animation. Fixed #7106 - animateClass: css and class changes during animation are lost
  • Loading branch information
ddstreet authored and gnarf committed Oct 25, 2011
1 parent 4cc61b4 commit e3156ea
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 75 deletions.
10 changes: 10 additions & 0 deletions tests/unit/effects/effects.html
Expand Up @@ -75,6 +75,14 @@
height: 50px;
}

.ticket7106 {
width: 50px;
height: 50px;
}
.ticket7106.animate {
width: 100px;
}

</style>
</head>
<body>
Expand All @@ -94,6 +102,8 @@ <h2>Slide with relative width</h2>
</div>
<div class="testScale">
</div>
<div class="ticket7106">
</div>

</div>
</body>
Expand Down
136 changes: 77 additions & 59 deletions tests/unit/effects/effects_core.js
Expand Up @@ -31,59 +31,19 @@ test( "Immediate Return Conditions", function() {
equal( ++count, 3, "Both Functions worked properly" );
});

$.each( $.effects.effect, function( effect ) {
if ( effect === "transfer" ) {
return;
}
module( "effect."+effect );
asyncTest( "show/hide", function() {
var hidden = $( "div.hidden" );
expect( 8 );

var count = 0,
test = 0;

function queueTest( fn ) {
count++;
var point = count;
return function( next ) {
test++;
equal( point, test, "Queue function fired in order" );
if ( fn ) {
fn();
} else {
setTimeout( next, minDuration );
}
};
}

hidden.queue( queueTest() ).show( effect, minDuration, queueTest(function() {
equal( hidden.css("display"), "block", "Hidden is shown after .show(\"" +effect+ "\", time)" );
})).queue( queueTest() ).hide( effect, minDuration, queueTest(function() {
equal( hidden.css("display"), "none", "Back to hidden after .hide(\"" +effect+ "\", time)" );
})).queue( queueTest(function(next) {
deepEqual( hidden.queue(), ["inprogress"], "Only the inprogress sentinel remains");
start();
}));
});

asyncTest( "relative width & height - properties are preserved", function() {
var test = $("div.relWidth.relHeight"),
width = test.width(), height = test.height(),
cssWidth = test[0].style.width, cssHeight = test[0].style.height;
test( "createWrapper and removeWrapper retain focused elements (#7595)", function() {
expect( 2 );
var test = $( "div.hidden" ).show(),
input = $( "<input>" ).appendTo( test ).focus();

expect( 4 );
test.toggle( effect, minDuration, function() {
equal( test[0].style.width, cssWidth, "Inline CSS Width has been reset after animation ended" );
equal( test[0].style.height, cssHeight, "Inline CSS Height has been rest after animation ended" );
start();
});
equal( test.width(), width, "Width is the same px after animation started" );
equal( test.height(), height, "Height is the same px after animation started" );
});
$.effects.createWrapper( test );
equal( document.activeElement, input[ 0 ], "Active element is still input after createWrapper" );
$.effects.removeWrapper( test );
equal( document.activeElement, input[ 0 ], "Active element is still input after removeWrapper" );
});

module("animateClass");

module( "effects.core: animateClass" );

asyncTest( "animateClass works with borderStyle", function() {
var test = $("div.animateClass"),
Expand Down Expand Up @@ -150,15 +110,73 @@ asyncTest( "animateClass clears style properties when stopped", function() {
start();
});

test( "createWrapper and removeWrapper retain focused elements (#7595)", function() {
expect( 2 );
var test = $( "div.hidden" ).show(),
input = $( "<input>" ).appendTo( test ).focus();
asyncTest( "animateClass: css and class changes during animation are not lost (#7106)", function() {
var test = $( "div.ticket7106" );

$.effects.createWrapper( test );
equal( document.activeElement, input[ 0 ], "Active element is still input after createWrapper" );
$.effects.removeWrapper( test );
equal( document.activeElement, input[ 0 ], "Active element is still input after removeWrapper" );
})
// add a class and change a style property after starting an animated class
test.addClass( "animate", minDuration, animationComplete )
.addClass( "testClass" )
.height( 100 );

// ensure the class stays and that the css property stays
function animationComplete() {
ok( test.hasClass( "testClass" ), "class change during animateClass was not lost" );
equal( test.height(), 100, "css change during animateClass was not lost" );
start();
}
});


$.each( $.effects.effect, function( effect ) {
if ( effect === "transfer" ) {
return;
}
module( "effect."+effect );
asyncTest( "show/hide", function() {
var hidden = $( "div.hidden" );
expect( 8 );

var count = 0,
test = 0;

function queueTest( fn ) {
count++;
var point = count;
return function( next ) {
test++;
equal( point, test, "Queue function fired in order" );
if ( fn ) {
fn();
} else {
setTimeout( next, minDuration );
}
};
}

hidden.queue( queueTest() ).show( effect, minDuration, queueTest(function() {
equal( hidden.css("display"), "block", "Hidden is shown after .show(\"" +effect+ "\", time)" );
})).queue( queueTest() ).hide( effect, minDuration, queueTest(function() {
equal( hidden.css("display"), "none", "Back to hidden after .hide(\"" +effect+ "\", time)" );
})).queue( queueTest(function(next) {
deepEqual( hidden.queue(), ["inprogress"], "Only the inprogress sentinel remains");
start();
}));
});

asyncTest( "relative width & height - properties are preserved", function() {
var test = $("div.relWidth.relHeight"),
width = test.width(), height = test.height(),
cssWidth = test[0].style.width, cssHeight = test[0].style.height;

expect( 4 );
test.toggle( effect, minDuration, function() {
equal( test[0].style.width, cssWidth, "Inline CSS Width has been reset after animation ended" );
equal( test[0].style.height, cssHeight, "Inline CSS Height has been rest after animation ended" );
start();
});
equal( test.width(), width, "Width is the same px after animation started" );
equal( test.height(), height, "Height is the same px after animation started" );
});
});

})(jQuery);
32 changes: 16 additions & 16 deletions ui/jquery.effects.core.js
Expand Up @@ -224,26 +224,27 @@ $.effects.animateClass = function( value, duration, easing, callback ) {
return this.queue( function() {
var animated = $( this ),
baseClass = animated.attr( "class" ) || "",
finalClass,
applyClassChange,
allAnimations = o.children ? animated.find( "*" ).andSelf() : animated;

// map the animated objects to store the original styles.
allAnimations = allAnimations.map(function() {
var el = $( this );
return {
el: el,
originalStyleAttr: el.attr( "style" ) || " ",
start: getElementStyles.call( this )
};
});

// apply class change
$.each( classAnimationActions, function(i, action) {
if ( value[ action ] ) {
animated[ action + "Class" ]( value[ action ] );
}
});
finalClass = animated.attr( "class" );
applyClassChange = function() {
$.each( classAnimationActions, function(i, action) {
if ( value[ action ] ) {
animated[ action + "Class" ]( value[ action ] );
}
});
};
applyClassChange();

// map all animated objects again - calculate new styles and diff
allAnimations = allAnimations.map(function() {
Expand Down Expand Up @@ -275,16 +276,15 @@ $.effects.animateClass = function( value, duration, easing, callback ) {
$.when.apply( $, allAnimations.get() ).done(function() {

// set the final class
animated.attr( "class", finalClass );
applyClassChange();

// for each animated element
// for each animated element,
// clear all css properties that were animated
$.each( arguments, function() {
if ( typeof this.el.attr( "style" ) === "object" ) {
this.el.attr( "style" ).cssText = "";
this.el.attr( "style" ).cssText = this.originalStyleAttr;
} else {
this.el.attr( "style", this.originalStyleAttr );
}
var el = this.el;
$.each( this.diff, function(key) {
el.css( key, '' );
});
});

// this is guarnteed to be there if you use jQuery.speed()
Expand Down

0 comments on commit e3156ea

Please sign in to comment.