jquery-mobile/tests/unit/navigation/navigation_transitions.js
Kin Blas 19c06952fd Changes to allow 3rd party transitions. Developers can now register a custom transition by adding their transition handler to the $.mobile.transitionHandlers dictionary. The name of the custom transition is used as the key within the transtionsHandlers dictionary, and should be the same name used within the @data-transtion attribute.
The expected prototype for a transitionHandler is as follows:

function handler(name, reverse, $to, $from)

The name parameter is the name of the transition as specified by @data-transition attribute, reverse is a boolean that is false for a normal transition, and true for a reverse transition. The $to param is a jQuery collection containing the page that is being transitioned "to", and $from is an optional collection that tells us what page we are transitioning "from". Because $from is optional, handler developers should take care and check $from to make sure it is not undefined before attempting to dereference it.

In addition to registering custom transition by name, developers can specify a handler to use in the case where a transition name is specified and does not exist within the $.mobile.transitionHanlders dictionary. Within jQuery Mobile, the default handler for unknown transition types is the $.mobile.css3Transition() handler. This handler always assumes that the transition name is to be used as a CSS class to be placed on the $to and $from elements. To change the default handler, simply set $.mobile.defaultTransitionHandler to you function handler:

$.mobile.defaultTransitionHandler = myTransitionHandler;

The changes to make all this necessary are as follows:

- Created $.mobile.noneTransitionHandler which is the default transitionHandler for the framework that simply adds and removes the page active class on the $from and $to pages with no animations.

- Moved class based transition code into a new plugin jquery.mobile.transition.js file. This plugin, when present, overrides the noneTransitionHandler as the defaultTranstionHandler for the framework so that CSS3 animation transitions are available.

- Removed code related to the setting/removal of the ui-mobile-viewport-perspective class. The css3TransitionHandler plugin takes care of automatically placing a "viewport-<transition name>" class on the viewport (body) element. This allows any other transition to specify properties on the viewport that are necessary to accomplish the transition.

- changed the CSS class ui-mobile-viewport-perspective to viewport-flip to match code changes. This makes it more apparent that setting -webkit-perspective is only used with the flip transition.

- Updated js/index.php, Makefile and build.xml to include the new jquery.mobile.transition.js file.
2011-04-26 14:06:10 -07:00

151 lines
3.8 KiB
JavaScript

/*
* mobile navigation unit tests
*/
(function($){
var perspective = "viewport-flip",
transitioning = "ui-mobile-viewport-transitioning",
animationCompleteFn = $.fn.animationComplete,
//TODO centralize class names?
transitionTypes = "in out fade slide flip reverse pop",
isTransitioning = function(page){
return $.grep(transitionTypes.split(" "), function(className, i){
return page.hasClass(className);
}).length > 0;
},
isTransitioningIn = function(page){
return page.hasClass("in") && isTransitioning(page);
},
//animationComplete callback queue
callbackQueue = [],
finishPageTransition = function(){
callbackQueue.pop()();
},
clearPageTransitionStack = function(){
stop();
var checkTransitionStack = function(){
if(callbackQueue.length>0) {
setTimeout(function(){
finishPageTransition();
checkTransitionStack();
},0);
}
else {
start();
}
};
checkTransitionStack();
},
//wipe all urls
clearUrlHistory = function(){
$.mobile.urlHistory.stack = [];
$.mobile.urlHistory.activeIndex = 0;
};
module('jquery.mobile.navigation.js', {
setup: function(){
//stub to prevent class removal
$.fn.animationComplete = function(callback){
callbackQueue.unshift(callback);
};
clearPageTransitionStack();
clearUrlHistory();
},
teardown: function(){
// unmock animation complete
$.fn.animationComplete = animationCompleteFn;
}
});
test( "changePage applys perspective class to mobile viewport for flip", function(){
$("#foo > a").click();
ok($("body").hasClass(perspective), "has perspective class");
});
test( "changePage does not apply perspective class to mobile viewport for transitions other than flip", function(){
$("#bar > a").click();
ok(!$("body").hasClass(perspective), "doesn't have perspective class");
});
test( "changePage applys transition class to mobile viewport for default transition", function(){
$("#baz > a").click();
ok($("body").hasClass(transitioning), "has transitioning class");
});
test( "explicit transition preferred for page navigation reversal (ie back)", function(){
$("#fade-trans > a").click();
stop();
setTimeout(function(){
finishPageTransition();
$("#flip-trans > a").click();
setTimeout(function(){
finishPageTransition();
$("#fade-trans > a").click();
setTimeout(function(){
ok($("#flip-trans").hasClass("fade"), "has fade class");
start();
},0);
},0);
},0);
});
test( "default transition is slide", function(){
$("#default-trans > a").click();
stop();
setTimeout(function(){
ok($("#no-trans").hasClass("slide"), "has slide class");
start();
},0);
});
test( "changePage queues requests", function(){
var firstPage = $("#foo"),
secondPage = $("#bar");
$.mobile.changePage(firstPage);
$.mobile.changePage(secondPage);
stop();
setTimeout(function(){
ok(isTransitioningIn(firstPage), "first page begins transition");
ok(!isTransitioningIn(secondPage), "second page doesn't transition yet");
finishPageTransition();
setTimeout(function(){
ok(!isTransitioningIn(firstPage), "first page transition should be complete");
ok(isTransitioningIn(secondPage), "second page should begin transitioning");
start();
},0);
},0);
});
test( "default transition is pop for a dialog", function(){
expect( 1 );
stop();
setTimeout(function(){
$("#default-trans-dialog > a").click();
ok($("#no-trans-dialog").hasClass("pop"), "expected the pop class to be present but instead was " + $("#no-trans-dialog").attr('class'));
start();
}, 900);
});
test( "animationComplete return value", function(){
$.fn.animationComplete = animationCompleteFn;
equals($("#foo").animationComplete(function(){})[0], $("#foo")[0]);
});
})(jQuery);