From 19c06952fd3b639780d5fa97a6552934b868a2cd Mon Sep 17 00:00:00 2001 From: Kin Blas Date: Tue, 26 Apr 2011 14:06:10 -0700 Subject: [PATCH] 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-" 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. --- Makefile | 1 + build.xml | 1 + js/index.php | 1 + js/jquery.mobile.navigation.js | 71 +++++++------------ .../unit/navigation/navigation_transitions.js | 2 +- themes/default/jquery.mobile.transitions.css | 4 +- 6 files changed, 33 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index af43acc5..cb03230e 100755 --- a/Makefile +++ b/Makefile @@ -47,6 +47,7 @@ JSFILES = js/jquery.ui.widget.js \ js/jquery.mobile.page.js \ js/jquery.mobile.core.js \ js/jquery.mobile.navigation.js \ + js/jquery.mobile.transition.js \ js/jquery.mobile.fixHeaderFooter.js \ js/jquery.mobile.forms.checkboxradio.js \ js/jquery.mobile.forms.textinput.js \ diff --git a/build.xml b/build.xml index 521fc1cd..0024dc22 100644 --- a/build.xml +++ b/build.xml @@ -29,6 +29,7 @@ jquery.mobile.page.js, jquery.mobile.core.js, jquery.mobile.navigation.js, + jquery.mobile.transition.js, jquery.mobile.fixHeaderFooter.js, jquery.mobile.forms.checkboxradio.js, jquery.mobile.forms.textinput.js, diff --git a/js/index.php b/js/index.php index d6683c55..d901581a 100644 --- a/js/index.php +++ b/js/index.php @@ -11,6 +11,7 @@ $elements = array( 'jquery.mobile.page.js', 'jquery.mobile.core.js', 'jquery.mobile.navigation.js', + 'jquery.mobile.transition.js', 'jquery.mobile.fixHeaderFooter.js', 'jquery.mobile.forms.checkboxradio.js', 'jquery.mobile.forms.textinput.js', diff --git a/js/jquery.mobile.navigation.js b/js/jquery.mobile.navigation.js index e3bcb05c..7f64334b 100644 --- a/js/jquery.mobile.navigation.js +++ b/js/jquery.mobile.navigation.js @@ -313,6 +313,24 @@ //history stack $.mobile.urlHistory = urlHistory; + //default non-animation transition handler + $.mobile.noneTransitionHandler = function(name, reverse, $to, $from){ + if ($from && $from.length){ + $from.removeClass( $.mobile.activePageClass ); + } + $to.addClass( $.mobile.activePageClass ); + + return $.Deferred().resolve(name, reverse, $to, $from).promise(); + }; + + //default handler for unknown transitions + $.mobile.defaultTransitionHandler = $.mobile.noneTransitionHandler; + + //transition handler dictionary for 3rd party transitions + $.mobile.transitionHandlers = { + none: $.mobile.defaultTransitionHandler + }; + //enable cross-domain page support $.mobile.allowCrossDomainPages = false; @@ -412,9 +430,7 @@ $.mobile.silentScroll(); //get current scroll distance - var currScroll = $window.scrollTop(), - perspectiveTransitions = [ "flip" ], - pageContainerClasses = []; + var currScroll = $window.scrollTop(); //support deep-links to generated sub-pages if( url.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ){ @@ -481,52 +497,19 @@ releasePageTransitionLock(); } - function addContainerClass(className){ - $.mobile.pageContainer.addClass(className); - pageContainerClasses.push(className); - } - - function removeContainerClasses(){ - $.mobile - .pageContainer - .removeClass(pageContainerClasses.join(" ")); - - pageContainerClasses = []; - } - //clear page loader $.mobile.pageLoading( true ); - if(transition && (transition !== 'none')){ - if( $.inArray(transition, perspectiveTransitions) >= 0 ){ - addContainerClass('ui-mobile-viewport-perspective'); - } + //find the transition handler for the specified transition. If there + //isn't one in our transitionHandlers dictionary, use the default one. + //call the handler immediately to kick-off the transition. + var th = $.mobile.transitionHandlers[transition || "none"] || $.mobile.defaultTransitionHandler, + deferred = th(transition, reverse, to, from); - addContainerClass('ui-mobile-viewport-transitioning'); - - if( from ){ - from.addClass( transition + " out " + ( reverse ? "reverse" : "" ) ); - } - to.addClass( $.mobile.activePageClass + " " + transition + - " in " + ( reverse ? "reverse" : "" ) ); - - // callback - remove classes, etc - to.animationComplete(function() { - to.add(from).removeClass("out in reverse " + transition ); - if( from ){ - from.removeClass( $.mobile.activePageClass ); - } - pageChangeComplete(); - removeContainerClasses(); - }); - } - else{ - if( from ){ - from.removeClass( $.mobile.activePageClass ); - } - to.addClass( $.mobile.activePageClass ); + //register a done callback on the transition so we can do some book-keeping cleanup. + deferred.done(function(){ pageChangeComplete(); - } + }); } //shared page enhancements diff --git a/tests/unit/navigation/navigation_transitions.js b/tests/unit/navigation/navigation_transitions.js index 8de0f3ae..5a44806c 100644 --- a/tests/unit/navigation/navigation_transitions.js +++ b/tests/unit/navigation/navigation_transitions.js @@ -2,7 +2,7 @@ * mobile navigation unit tests */ (function($){ - var perspective = "ui-mobile-viewport-perspective", + var perspective = "viewport-flip", transitioning = "ui-mobile-viewport-transitioning", animationCompleteFn = $.fn.animationComplete, diff --git a/themes/default/jquery.mobile.transitions.css b/themes/default/jquery.mobile.transitions.css index 0b828635..a6733e78 100644 --- a/themes/default/jquery.mobile.transitions.css +++ b/themes/default/jquery.mobile.transitions.css @@ -145,13 +145,13 @@ Built by David Kaneda and maintained by Jonathan Stark. -webkit-animation-name: fadeout; } -/* The properties in this body rule are only necessary for the 'flip' transition. +/* The properties in this rule are only necessary for the 'flip' transition. * We need specify the perspective to create a projection matrix. This will add * some depth as the element flips. The depth number represents the distance of * the viewer from the z-plane. According to the CSS3 spec, 1000 is a moderate * value. */ -.ui-mobile-viewport-perspective { +.viewport-flip { -webkit-perspective: 1000; position: absolute; }