blob: 7f0762174bc3f43548b3e0a8529113062a27764b [file] [log] [blame]
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:
* <tapestry.fx.attachPostEffect>
* <dojo.lfx.IAnimation>
*
* 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:
* <tapestry.fx.attachPreEffect>
* <dojo.lfx.IAnimation>
*
* 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();
}
}
}