dojo.provide("tapestry.fx"); dojo.require("tapestry.core"); /** * package: tapestry.fx * Provides handling of effects applied before, during or after an XHR request/response. */ tapestry.fx={ // property: preEffects // Contains a reference to all registered pre-effects, i.e. effects that are // executed before an XHR request. preEffects:{}, // property: postEffects // Contains a reference to all registered post-effects, i.e. effects that are // executed when new content arrives through an XHR response. postEffects:{}, // property: ajaxStatusAction ajaxStatusAction:'loading', /** * Function: attachPreEffect * Schedules the execution of an effect when the specified link * is clicked (and thus an XHR request begins). * * See Also: * * * * Parameters: * triggerId - The clientId of the DirectLink that triggers the effect. * animationFunc - A function that returns the animation to execute. * async - Boolean for whether to execute the effect in parallel to the * XHR request. Defaults to false, i.e. the XHR is blocked until * the effect ends. * * Note: * Here's an example usage: * tapestry.fx.attachPreEffect("DirectLink", * function(){return dojo.lfx.wipeOut("entry", 800, dojo.lfx.easeDefault) }); */ attachPreEffect:function(triggerId, animationFunc, async){ if (dojo.lang.isEmpty(this.preEffects)) this._initPreEffects(); this.preEffects[triggerId] = {async:async, animation:animationFunc}; }, /** * Function: attachPostEffect * Schedules the execution of an effect when the specified content * is returned through an XHR response. * * See Also: * * * * Parameters: * updateId - The id of a dom node that (when updated) triggers the effect. * animationFunc - A function that returns the animation to execute. * * Note: * Here's an example usage: * tapestry.fx.attachPostEffect("entry", * function(){return dojo.lfx.wipeIn("entry", 1500, dojo.lfx.easeDefault) }); */ attachPostEffect:function(updateId, animationFunc){ if (dojo.lang.isEmpty(this.postEffects)) this._initPostEffects(); this.postEffects[updateId] = {animation:animationFunc}; }, /** * Function: removeAll * Removes all registered effects (preEffects and postEffects). */ removeAll:function(){ this.preEffects={}; this.postEffects={}; }, /** * Function: attachAjaxStatus * Allows specifying a dom node that will be shown or hidden while ajax requests * are in progress or have finished. * Alternatively, one can specify a custom * function which will get invoked when an ajax request starts or ends - the first * argument to that function will be a boolean corresponding to wheather the status * element should be showing or not. * * Parameters: * a1 - The dom id to show - hide, or the function to invoke when ajax starts or ends. */ attachAjaxStatus:function(a1){ dojo.log.debug("Attaching ajax status listener"); if (dojo.lang.isString(a1)) { tapestry.fx.ajaxStatusAction = function(bShow){if (bShow) dojo.html.show(a1); else dojo.html.hide(a1);}; } else if (dojo.lang.isFunction(a1)) { tapestry.fx.ajaxStatusAction = a1; } else { dojo.log.warn("Argument to tapestry.fx.attachAjaxStatus should be either a string or a function"); return; } dojo.event.connectOnce(dojo.io, "queueBind", tapestry.fx._processAjaxStatus); dojo.event.connectOnce(tapestry, "error", tapestry.fx._processAjaxStatus); dojo.event.connectOnce(tapestry, "load", tapestry.fx._processAjaxStatus); dojo.event.connectOnce(tapestry, "loadJson", tapestry.fx._processAjaxStatus); }, _processAjaxStatus:function(){ tapestry.fx.ajaxStatusAction.apply(this, [tapestry.isServingRequests()]); }, _initPreEffects:function(){ dojo.log.debug("Advising tapestry.linkOnClick"); dojo.event.connectAround(tapestry, "linkOnClick", tapestry.fx, "_applyPreEffects"); }, _initPostEffects:function(){ dojo.log.debug("Advising tapestry.loadContent"); dojo.event.connectAround(tapestry, "loadContent", tapestry.fx, "_applyPostEffects"); }, _applyPreEffects:function(miObj){ var id = miObj.args[1]; var effect = this.preEffects[id]; if (effect){ dojo.log.debug("Found pre-effect:", effect, id); var anim = effect.animation(); if (effect.async){ anim.play(); return miObj.proceed(); } else{ anim.connect("onEnd", function(){ miObj.proceed(); }); anim.play(); return false; } } else{ return miObj.proceed(); } }, _applyPostEffects:function(miObj){ var id = miObj.args[0]; var effect = this.postEffects[id]; if (effect){ dojo.log.debug("Found post-effect:", effect, id); var ret = miObj.proceed(); var anim = effect.animation(); anim.play(); return ret; } else{ return miObj.proceed(); } } }