Permalink
Browse files

Effects: Rewrite

1. Introduces a set of helper methods to easily create and define new effects.
2. Uses clip animations and placeholders instead of wrappers for clip effects.
3. Ensures all animations are detectable as animated

Fixes #10599
Fixes #9477
Fixes #9257
Fixes #9066
Fixes #8867
Fixes #8671
Fixes #8505
Fixes #7885
Fixes #7041

Closes gh-1017
  • Loading branch information...
1 parent 2a99bb7 commit b6bec797d6a8ef0b377a866c38c67e66a626b45f @mikesherov mikesherov committed Dec 26, 2012
@@ -10,8 +10,8 @@
<style>
.toggler { width: 500px; height: 200px; position: relative; }
#button { padding: .5em 1em; text-decoration: none; }
- #effect { width: 240px; padding: 1em; font-size: 1.2em; border: 1px solid #000; background: #eee; color: #333; }
- .newClass { text-indent: 40px; letter-spacing: .4em; width: 410px; height: 100px; padding: 30px; margin: 10px; font-size: 1.6em; }
+ #effect { width: 240px; padding: 1em; border: 1px solid #000; background: #eee; color: #333; }
+ .newClass { text-indent: 40px; letter-spacing: .4em; width: 410px; height: 120px; padding: 30px; margin: 10px; font-size: 1.1em; }
</style>
<script>
$(function() {
@@ -10,7 +10,7 @@
<style>
.toggler { width: 500px; height: 200px; position: relative; }
#button { padding: .5em 1em; text-decoration: none; }
- #effect { width: 240px; height: 135px; padding: 0.4em; position: relative; background: #fff; }
+ #effect { width: 240px; height: 170px; padding: 0.4em; position: relative; background: #fff; }
#effect h3 { margin: 0; padding: 0.4em; text-align: center; }
</style>
<script>
@@ -25,7 +25,7 @@
<style>
.toggler { width: 500px; height: 200px; position: relative; }
#button { padding: .5em 1em; text-decoration: none; }
- #effect { width: 240px; height: 135px; padding: 0.4em; position: relative; }
+ #effect { width: 240px; height: 170px; padding: 0.4em; position: relative; }
#effect h3 { margin: 0; padding: 0.4em; text-align: center; }
.ui-effects-transfer { border: 2px dotted gray; }
</style>
@@ -40,7 +40,7 @@
var options = {};
// some effects have required parameters
if ( selectedEffect === "scale" ) {
- options = { percent: 0 };
+ options = { percent: 50 };
} else if ( selectedEffect === "transfer" ) {
options = { to: "#button", className: "ui-effects-transfer" };
} else if ( selectedEffect === "size" ) {
View
@@ -11,6 +11,7 @@
<script src="../../ui/effect-clip.js"></script>
<script src="../../ui/effect-drop.js"></script>
<script src="../../ui/effect-explode.js"></script>
+ <script src="../../ui/effect-fade.js"></script>
<script src="../../ui/effect-fold.js"></script>
<script src="../../ui/effect-highlight.js"></script>
<script src="../../ui/effect-puff.js"></script>
@@ -23,7 +24,7 @@
<style>
.toggler { width: 500px; height: 200px; }
#button { padding: .5em 1em; text-decoration: none; }
- #effect { width: 240px; height: 135px; padding: 0.4em; position: relative; }
+ #effect { width: 240px; height: 170px; padding: 0.4em; position: relative; }
#effect h3 { margin: 0; padding: 0.4em; text-align: center; }
</style>
<script>
@@ -37,7 +38,7 @@
var options = {};
// some effects have required parameters
if ( selectedEffect === "scale" ) {
- options = { percent: 0 };
+ options = { percent: 50 };
} else if ( selectedEffect === "size" ) {
options = { to: { width: 200, height: 60 } };
}
@@ -77,6 +78,7 @@ <h3 class="ui-widget-header ui-corner-all">Hide</h3>
<option value="clip">Clip</option>
<option value="drop">Drop</option>
<option value="explode">Explode</option>
+ <option value="fade">Fade</option>
<option value="fold">Fold</option>
<option value="highlight">Highlight</option>
<option value="puff">Puff</option>
View
@@ -11,6 +11,7 @@
<script src="../../ui/effect-clip.js"></script>
<script src="../../ui/effect-drop.js"></script>
<script src="../../ui/effect-explode.js"></script>
+ <script src="../../ui/effect-fade.js"></script>
<script src="../../ui/effect-fold.js"></script>
<script src="../../ui/effect-highlight.js"></script>
<script src="../../ui/effect-puff.js"></script>
@@ -23,7 +24,7 @@
<style>
.toggler { width: 500px; height: 200px; }
#button { padding: .5em 1em; text-decoration: none; }
- #effect { width: 240px; height: 135px; padding: 0.4em; position: relative; }
+ #effect { width: 240px; height: 170px; padding: 0.4em; position: relative; }
#effect h3 { margin: 0; padding: 0.4em; text-align: center; }
</style>
<script>
@@ -37,7 +38,7 @@
var options = {};
// some effects have required parameters
if ( selectedEffect === "scale" ) {
- options = { percent: 100 };
+ options = { percent: 50 };
} else if ( selectedEffect === "size" ) {
options = { to: { width: 280, height: 185 } };
}
@@ -79,6 +80,7 @@ <h3 class="ui-widget-header ui-corner-all">Show</h3>
<option value="clip">Clip</option>
<option value="drop">Drop</option>
<option value="explode">Explode</option>
+ <option value="fade">Fade</option>
<option value="fold">Fold</option>
<option value="highlight">Highlight</option>
<option value="puff">Puff</option>
@@ -11,8 +11,8 @@
.toggler { width: 500px; height: 200px; position: relative; }
#button { padding: .5em 1em; text-decoration: none; }
#effect { position: relative; }
- .newClass { width: 240px; padding: 1em; letter-spacing: 0; font-size: 1.2em; margin: 0; }
- .anotherNewClass { text-indent: 40px; letter-spacing: .4em; width: 410px; height: 100px; padding: 30px; margin: 10px; font-size: 1.6em; }
+ .newClass { width: 240px; padding: 1em; letter-spacing: 0; margin: 0; }
+ .anotherNewClass { text-indent: 40px; letter-spacing: .2em; width: 410px; height: 100px; padding: 30px; margin: 10px; font-size: 1.1em; }
</style>
<script>
$(function() {
View
@@ -11,6 +11,7 @@
<script src="../../ui/effect-clip.js"></script>
<script src="../../ui/effect-drop.js"></script>
<script src="../../ui/effect-explode.js"></script>
+ <script src="../../ui/effect-fade.js"></script>
<script src="../../ui/effect-fold.js"></script>
<script src="../../ui/effect-highlight.js"></script>
<script src="../../ui/effect-puff.js"></script>
@@ -32,7 +33,7 @@
#effect {
position: relative;
width: 240px;
- height: 135px;
+ height: 170px;
padding: 0.4em;
}
#effect h3 {
@@ -52,7 +53,7 @@
var options = {};
// some effects have required parameters
if ( selectedEffect === "scale" ) {
- options = { percent: 0 };
+ options = { percent: 50 };
} else if ( selectedEffect === "size" ) {
options = { to: { width: 200, height: 60 } };
}
@@ -85,6 +86,7 @@ <h3 class="ui-widget-header ui-corner-all">Toggle</h3>
<option value="clip">Clip</option>
<option value="drop">Drop</option>
<option value="explode">Explode</option>
+ <option value="fade">Fade</option>
<option value="fold">Fold</option>
<option value="highlight">Highlight</option>
<option value="puff">Puff</option>
@@ -88,28 +88,47 @@
width: 100px;
}
+ .relative {
+ position: relative;
+ top: 0px;
+ left: 0px;
+ }
+ .absolute {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ }
+ .fixed {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ }
+ .static {
+ position: static;
+ }
+
</style>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
-<div id="elem" class="test">
-</div>
-<div class="hidden test">
- <div>.</div>
-</div>
-<div class="animateClass test">
- <h2>Child Element Test</h2>
-</div>
-<div class="relWidth relHeight testAddBorder">
- <h2>Slide with relative width</h2>
-</div>
-<div class="testScale">
-</div>
-<div class="ticket7106">
-</div>
-
+ <div id="elem" class="test"></div>
+ <div class="hidden test">
+ <div>.</div>
+ </div>
+ <div class="animateClass test">
+ <h2>Child Element Test</h2>
+ </div>
+ <div class="relWidth relHeight testAddBorder">
+ <h2>Slide with relative width</h2>
+ </div>
+ <div class="testScale"></div>
+ <div class="ticket7106"></div>
+ <div class="relative"></div>
+ <div class="absolute"></div>
+ <div class="fixed"></div>
+ <div class="static"></div>
</div>
</body>
</html>
@@ -1,11 +1,11 @@
(function($) {
function present( value, array, message ) {
- QUnit.push( jQuery.inArray( value, array ) !== -1 , value, array, message );
+ QUnit.push( jQuery.inArray( value, array ) !== -1, value, array, message );
}
function notPresent( value, array, message ) {
- QUnit.push( jQuery.inArray( value, array ) === -1 , value, array, message );
+ QUnit.push( jQuery.inArray( value, array ) === -1, value, array, message );
}
// minDuration is used for "short" animate tests where we are only concerned about the final
@@ -75,20 +75,6 @@ test( "removeClass", function() {
equal( "", element[ 0 ].className );
});
-
-/* TODO: Disabled - Can't figure out why this is failing in IE 6/7
-test( "createWrapper and removeWrapper retain focused elements (#7595)", function() {
- expect( 2 );
- var test = $( "div.hidden" ).show(),
- input = $( "<input type='text'>" ).appendTo( test ).focus();
-
- $.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( "effects.core: animateClass" );
asyncTest( "animateClass works with borderStyle", function() {
@@ -213,6 +199,44 @@ asyncTest( "animateClass: css and class changes during animation are not lost (#
.height( 100 );
});
+test( "createPlaceholder: only created for static or relative elements", function() {
+ expect( 4 );
+
+ ok( $.effects.createPlaceholder( $( ".relative" ) ).length, "placeholder created for relative element" );
+ ok( $.effects.createPlaceholder( $( ".static" ) ).length, "placeholder created for static element" );
+ ok( !$.effects.createPlaceholder( $( ".absolute" ) ), "placeholder not created for absolute element" );
+ ok( !$.effects.createPlaceholder( $( ".fixed" ) ), "placeholder not created for fixed element" );
+});
+
+test( "createPlaceholder: preserves layout affecting properties", function() {
+ expect( 7 );
+
+ var position = 5,
+ element = $( ".relative" ).css({
+ top: position,
+ left: position
+ }),
+ before = {
+ offset: element.offset(),
+ outerWidth: element.outerWidth( true ),
+ outerHeight: element.outerHeight( true ),
+ "float": element.css( "float" ),
+ position: element.position()
+ },
+ placeholder = $.effects.createPlaceholder( element );
+
+ // Placeholders are only placed to preserve the effect on layout. Considering
+ // top and left do not change layout, they are not preserved, which makes some
+ // of the math simpler in the implementation.
+ deepEqual( before.offset.top - position, placeholder.offset().top, "offset top preserved" );
+ deepEqual( before.offset.left - position, placeholder.offset().left, "offset left preserved" );
+ deepEqual( before.position.top - position, placeholder.position().top, "position top preserved" );
+ deepEqual( before.position.left - position, placeholder.position().left, "position left preserved" );
+
+ deepEqual( before[ "float" ], placeholder.css( "float" ), "float preserved" );
+ deepEqual( before.outerWidth, placeholder.outerWidth( true ), "width preserved" );
+ deepEqual( before.outerHeight, placeholder.outerHeight( true ), "height preserved" );
+});
$.each( $.effects.effect, function( effect ) {
module( "effects." + effect );
@@ -223,7 +247,7 @@ $.each( $.effects.effect, function( effect ) {
return;
}
asyncTest( "show/hide", function() {
- expect( 8 );
+ expect( 12 );
var hidden = $( "div.hidden" ),
count = 0,
test = 0;
@@ -242,14 +266,40 @@ $.each( $.effects.effect, function( effect ) {
};
}
- 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() {
- deepEqual( hidden.queue(), ["inprogress"], "Only the inprogress sentinel remains");
- start();
- }));
+ function duringTest( fn ) {
+ return function( next ) {
+ setTimeout( fn );
+ next();
+ };
+ }
+
+ hidden
+ .queue( queueTest() )
+ .queue( duringTest(function() {
+ ok( hidden.is( ":animated" ),
+ "Hidden is seen as animated during .show(\"" + effect + "\", time)" );
+ }) )
+ .show( effect, minDuration, queueTest(function() {
+ equal( hidden.css( "display" ), "block",
+ "Hidden is shown after .show(\"" + effect + "\", time)" );
+ ok( !$( ".ui-effects-placeholder" ).length,
+ "No placeholder remains after .show(\"" + effect + "\", time)" );
+ }) )
+ .queue( queueTest() )
+ .queue( duringTest(function() {
+ ok( hidden.is( ":animated" ),
+ "Hidden is seen as animated during .hide(\"" + effect + "\", time)" );
+ }) )
+ .hide( effect, minDuration, queueTest(function() {
+ equal( hidden.css( "display" ), "none",
+ "Back to hidden after .hide(\"" + effect + "\", time)" );
+ ok( !$( ".ui-effects-placeholder" ).length,
+ "No placeholder remains after .hide(\"" + effect + "\", time)" );
+ }) )
+ .queue( queueTest(function() {
+ deepEqual( hidden.queue(), [ "inprogress" ], "Only the inprogress sentinel remains" );
+ start();
+ }) );
});
asyncTest( "relative width & height - properties are preserved", function() {
@@ -6,8 +6,8 @@ function run( position, v, h, vo, ho ) {
asyncTest( desc, function() {
expect( 2 );
function complete() {
- equal( parseInt( test.css( h ), 10 ), target[ h ], "Horizontal Position Correct " + desc );
- equal( parseInt( test.css( v ), 10 ), target[ v ], "Vertical Position Correct " + desc );
+ closeEnough( parseInt( test.css( h ), 10 ), target[ h ], 1, "Horizontal Position Correct " + desc );
+ closeEnough( parseInt( test.css( v ), 10 ), target[ v ], 1, "Vertical Position Correct " + desc );
start();
}
var test = $( ".testScale" ),
@@ -14,8 +14,10 @@
<script src="../../../ui/effect-fade.js"></script>
<script src="../../../ui/effect-fold.js"></script>
<script src="../../../ui/effect-highlight.js"></script>
+ <script src="../../../ui/effect-puff.js"></script>
<script src="../../../ui/effect-pulsate.js"></script>
<script src="../../../ui/effect-scale.js"></script>
+ <script src="../../../ui/effect-size.js"></script>
<script src="../../../ui/effect-shake.js"></script>
<script src="../../../ui/effect-slide.js"></script>
<script src="../../../ui/effect-transfer.js"></script>
@@ -70,6 +70,7 @@
<p>EXPECTED: Clicking "Toggle" or "Effect Toggle" a second time reverses the animation, first showing all elements at their original dimensions, and restoring them to their original state.</p>
<p>EXPECTED: Clicking "Effect Default" should always perform a "hide" animation.</p>
<p>EXPECTED: Clicking any of the buttons in quick succession should queue the relevant animations.</p>
+<p>EXPECTED CANTFIX: In IE8, the clip animation jumps due to a bug that causes .css('clip') to return undefined unless the clip property is an inline style.</p>
<div class="container">
<button class="toggle">Toggle</button>
@@ -80,7 +81,7 @@
<p>Jerky corned beef short loin fatback jowl tail. Rump spare ribs shoulder pork belly. Sausage cow ground round bacon. Bresaola kielbasa pastrami brisket ham hock. Andouille kielbasa ham, pork beef tenderloin ground round beef ribs flank turkey pancetta tri-tip.</p>
<div class="column">
<p>Shankle filet mignon ribeye chicken, bacon jowl drumstick frankfurter swine short loin capicola leberkas tenderloin pig. Shankle bacon shank pork loin, shoulder ham drumstick biltong. Shankle ham pastrami ball tip turkey leberkas pork loin ground round. Chicken strip steak venison shoulder biltong ham. Bacon pork loin tenderloin kielbasa, prosciutto sausage leberkas jowl ribeye turducken. Flank short loin venison tenderloin spare ribs boudin, tongue pork chop shank sirloin. Ground round ham pork belly, corned beef jowl strip steak short ribs prosciutto pig bresaola spare ribs.</p>
- <img class="target" style="margin: 10px 20px 30px 40px;" src="../../images/jquery_521x191.png" alt="jQuery Logo">
+ <img class="target margin" src="../../images/jquery_521x191.png" alt="jQuery Logo">
<p>Pork loin biltong ball tip tail jerky beef ribs prosciutto short loin turducken. Turkey chicken jowl pork loin shank tri-tip swine brisket. Doner prosciutto leberkas venison ground round, short loin capicola hamburger pork bacon. Spare ribs beef pork tenderloin rump shoulder pork belly turducken cow beef ribs pastrami tail flank. Spare ribs tri-tip shank, pork beef ribs ribeye chicken bacon boudin shoulder venison. Sirloin beef ribs boudin, andouille doner tail ball tip biltong prosciutto chicken beef turkey tongue hamburger tri-tip.</p>
</div>
<p>Doner salami jowl beef ribs. Pork chop beef short loin pork, kielbasa tail andouille salami sausage meatball short ribs t-bone tri-tip ham. Meatball short ribs prosciutto flank chicken fatback frankfurter brisket turducken. Corned beef hamburger swine short ribs pancetta. Jerky bresaola pork chuck spare ribs pastrami shoulder flank chicken leberkas beef.</p>
Oops, something went wrong.

0 comments on commit b6bec79

Please sign in to comment.