diff options
Diffstat (limited to 'framework')
25 files changed, 338 insertions, 288 deletions
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt index 3df84dde..5edd7c75 100644 --- a/framework/Exceptions/messages.txt +++ b/framework/Exceptions/messages.txt @@ -295,4 +295,6 @@ stack_data_not_iterable					= TStack can only fetch data from an array or a trav  stack_empty								= TStack is empty.
  queue_data_not_iterable					= TQueue can only fetch data from an array or a traversable object.
 -queue_empty								= TQueue is empty.
\ No newline at end of file +queue_empty								= TQueue is empty.
 +
 +callback_not_support_no_priority_state_update	= Callback request does not support unprioritized pagestate update.
\ No newline at end of file diff --git a/framework/I18N/core/Gettext/MO.php b/framework/I18N/core/Gettext/MO.php index f3be1a30..5ee0057f 100644 --- a/framework/I18N/core/Gettext/MO.php +++ b/framework/I18N/core/Gettext/MO.php @@ -352,4 +352,4 @@ class TGettext_MO extends TGettext          return true;
      }
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/I18N/core/Gettext/PO.php b/framework/I18N/core/Gettext/PO.php index 3c69c091..015747a0 100644 --- a/framework/I18N/core/Gettext/PO.php +++ b/framework/I18N/core/Gettext/PO.php @@ -157,4 +157,4 @@ class TGettext_PO extends TGettext          return true;
      }
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/I18N/core/Gettext/TGettext.php b/framework/I18N/core/Gettext/TGettext.php index 8e87bee5..c13940b3 100644 --- a/framework/I18N/core/Gettext/TGettext.php +++ b/framework/I18N/core/Gettext/TGettext.php @@ -284,4 +284,4 @@ class TGettext          return $PO;
      }
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/I18N/core/MessageSource_SQLite.php b/framework/I18N/core/MessageSource_SQLite.php index ac98df77..99065f7f 100644 --- a/framework/I18N/core/MessageSource_SQLite.php +++ b/framework/I18N/core/MessageSource_SQLite.php @@ -351,4 +351,4 @@ class MessageSource_SQLite extends MessageSource  	}	
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/I18N/core/TCache_Lite.php b/framework/I18N/core/TCache_Lite.php index b42afc10..260e56c4 100644 --- a/framework/I18N/core/TCache_Lite.php +++ b/framework/I18N/core/TCache_Lite.php @@ -622,4 +622,4 @@ class TCache_Lite  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/IO/TTarFileExtractor.php b/framework/IO/TTarFileExtractor.php index 611662c5..9f61026d 100644 --- a/framework/IO/TTarFileExtractor.php +++ b/framework/IO/TTarFileExtractor.php @@ -569,4 +569,4 @@ class TTarFileExtractor        return $p_path;
      }
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/PradoBase.php b/framework/PradoBase.php index 7e631cb8..9c6ef96b 100644 --- a/framework/PradoBase.php +++ b/framework/PradoBase.php @@ -645,4 +645,4 @@ else // PHP < 5.1.0  	}
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/Javascripts/js/ajax.js b/framework/Web/Javascripts/js/ajax.js index 6ab3d18d..5deebd1b 100644 --- a/framework/Web/Javascripts/js/ajax.js +++ b/framework/Web/Javascripts/js/ajax.js @@ -23,7 +23,7 @@ setTimeout(this.onComplete.bind(this),10);}}});Ajax.PeriodicalUpdater=Class.crea  this.timer=setTimeout(this.onTimerEvent.bind(this),this.decay*this.frequency*1000);},onTimerEvent:function(){this.updater=new Ajax.Updater(this.container,this.url,this.options);}});Object.extend(Ajax.Request.prototype,{respondToReadyState:function(readyState)  {var event=Ajax.Request.Events[readyState];var transport=this.transport,json=this.getHeaderData(Prado.CallbackRequest.DATA_HEADER);if(event=='Complete')  {try -{Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(transport,json);}catch(e){this.dispatchException(e);} +{Prado.CallbackRequest.updatePageState(this,transport);Ajax.Responders.dispatch('on'+transport.status,this,transport,json);Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));(this.options['on'+this.transport.status]||this.options['on'+(this.responseIsSuccess()?'Success':'Failure')]||Prototype.emptyFunction)(transport,json);}catch(e){this.dispatchException(e);}  if((this.header('Content-type')||'').match(/^text\/javascript/i))  this.evalResponse();}  try{(this.options['on'+event]||Prototype.emptyFunction)(transport,json);Ajax.Responders.dispatch('on'+event,this,transport,json);}catch(e){this.dispatchException(e);} @@ -34,7 +34,7 @@ this.transport.onreadystatechange=Prototype.emptyFunction;},getHeaderData:functi  catch(e)  {if(typeof(json)=="string")  {Logger.info("using json") -return Prado.CallbackRequest.decode(json);}}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',Queque:[],InProgress:[],dispatchActions:function(transport,actions) +return Prado.CallbackRequest.decode(json);}}}});Prado.CallbackRequest=Class.create();Object.extend(Prado.CallbackRequest,{FIELD_CALLBACK_TARGET:'PRADO_CALLBACK_TARGET',FIELD_CALLBACK_PARAMETER:'PRADO_CALLBACK_PARAMETER',FIELD_CALLBACK_PAGESTATE:'PRADO_PAGESTATE',PostDataLoaders:[],DATA_HEADER:'X-PRADO-DATA',ACTION_HEADER:'X-PRADO-ACTIONS',ERROR_HEADER:'X-PRADO-ERROR',PAGESTATE_HEADER:'X-PRADO-PAGESTATE',requestInProgress:null,dispatchActions:function(transport,actions)  {if(actions&&actions.length>0)  actions.each(this.__run.bind(this,transport));},__run:function(transport,command)  {for(var method in command) @@ -54,27 +54,29 @@ msg+=e.version+" "+e.time+"\n";return msg;}},encode:function(data)  {return Prado.JSON.stringify(data);},decode:function(data)  {if(typeof(data)=="string"&&data.trim().length>0)  return Prado.JSON.parse(data);else -return null;},dispatchQuequedRequest:function() -{requests=Prado.CallbackRequest;if(requests.InProgress.length==0&&requests.Queque.length>0) -{var item=requests.Queque.pop();item.callback=new Ajax.Request(item.url,item.options);item.callback.callbackID=item.id;item.timeout=setTimeout(function() -{requests.removeInProgress(item.callback);},item.options.TimeOut);requests.InProgress.push(item);}},removeInProgress:function(request) -{if(request&&request.callbackID) -{var stillInProgress=[];requests=Prado.CallbackRequest;requests.InProgress.each(function(item) -{if(item.callback.callbackID==request.callbackID) -{item.callback.transport.abort();request.transport.abort();clearTimeout(item.timeout);} -else -{stillInProgress.push(item);}}) -requests.InProgress=stillInProgress;} -requests.dispatchQuequedRequest();}}) -Ajax.Responders.register({onComplete:Prado.CallbackRequest.removeInProgress});Event.OnLoad(function() +return null;},dispatchPriorityRequest:function(callback) +{Logger.info("priority request "+callback.id) +this.abortRequestInProgress();callback.request=new Ajax.Request(callback.url,callback.options);callback.timeout=setTimeout(function() +{Logger.warn("priority timeout");Prado.CallbackRequest.abortRequestInProgress();},callback.options.RequestTimeOut);this.requestInProgress=callback;Logger.info("dispatched "+this.requestInProgress)},dispatchNormalRequest:function(callback) +{Logger.info("dispatching normal request");new Ajax.Request(callback.url,callback.options);},abortRequestInProgress:function() +{inProgress=Prado.CallbackRequest.requestInProgress;if(inProgress) +{Logger.warn("aborted "+inProgress.id) +inProgress.request.transport.abort();clearTimeout(inProgress.timeout);Prado.CallbackRequest.requestInProgress=null;}},updatePageState:function(request,transport) +{pagestate=$(this.FIELD_CALLBACK_PAGESTATE);if(request.options.EnablePageStateUpdate&&request.options.HasPriority&&pagestate) +{Logger.warn("updating page state");pagestate.value=request.header(this.PAGESTATE_HEADER);}}}) +Ajax.Responders.register({onComplete:function(request) +{if(request.options.HasPriority) +Prado.CallbackRequest.abortRequestInProgress();}});Event.OnLoad(function()  {if(typeof Logger!="undefined") -Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={url:window.location.href,options:{TimeOut:30000},id:null,callback:null,initialize:function(id,options) -{Object.extend(this.options,options||{});this.id=id;var request={postBody:this._getPostData(),parameters:''} -Object.extend(this.options,request);if(this.options.CausesValidation!=false&&typeof(Prado.Validation)!="undefined") +Ajax.Responders.register(Prado.CallbackRequest.Exception);});Prado.CallbackRequest.prototype={url:window.location.href,options:{},id:null,request:null,initialize:function(id,options) +{this.id=id;this.options={RequestTimeOut:30000,EnablePageStateUpdate:true,HasPriority:true,CausesValidation:true,ValidationGroup:null,PostInputs:true,postBody:this._getPostData(),parameters:''} +Object.extend(this.options,options||{});if(this.options.CausesValidation&&typeof(Prado.Validation)!="undefined")  {var form=this.options.Form||Prado.Validation.getForm();if(Prado.Validation.validate(form,this.options.ValidationGroup,this)==false)  return;} -Prado.CallbackRequest.Queque.push(this);Prado.CallbackRequest.dispatchQuequedRequest();},_getPostData:function() -{var data={};var callback=Prado.CallbackRequest;if(this.options.PostState!=false) +if(this.options.HasPriority) +Prado.CallbackRequest.dispatchPriorityRequest(this);else +Prado.CallbackRequest.dispatchNormalRequest(this);},_getPostData:function() +{var data={};var callback=Prado.CallbackRequest;if(this.options.PostInputs!=false)  {callback.PostDataLoaders.each(function(name)  {$A(document.getElementsByName(name)).each(function(element)  {var value=$F(element);if(typeof(value)!="undefined") @@ -83,7 +85,7 @@ if(typeof(this.options.params)!="undefined")  data[callback.FIELD_CALLBACK_PARAMETER]=callback.encode(this.options.params);var pageState=$F(callback.FIELD_CALLBACK_PAGESTATE);if(typeof(pageState)!="undefined")  data[callback.FIELD_CALLBACK_PAGESTATE]=pageState;data[callback.FIELD_CALLBACK_TARGET]=this.id;return $H(data).toQueryString();}}  Prado.Callback=function(UniqueID,parameter,onSuccess,options) -{var callback={'params':parameter||'','onSuccess':onSuccess||Prototype.emptyFunction,'CausesValidation':true};Object.extend(callback,options||{});new Prado.CallbackRequest(UniqueID,callback);return false;} +{var callback={'params':parameter||'','onSuccess':onSuccess||Prototype.emptyFunction};Object.extend(callback,options||{});new Prado.CallbackRequest(UniqueID,callback);return false;}  Array.prototype.______array='______array';Prado.JSON={org:'http://www.JSON.org',copyright:'(c)2005 JSON.org',license:'http://www.crockford.com/JSON/license.html',stringify:function(arg){var c,i,l,s='',v;switch(typeof arg){case'object':if(arg){if(arg.______array=='______array'){for(i=0;i<arg.length;++i){v=this.stringify(arg[i]);if(s){s+=',';}  s+=v;}  return'['+s+']';}else if(typeof arg.toString!='undefined'){for(i in arg){v=arg[i];if(typeof v!='undefined'&&typeof v!='function'){v=this.stringify(v);if(s){s+=',';} diff --git a/framework/Web/Javascripts/prado/ajax3.js b/framework/Web/Javascripts/prado/ajax3.js index 8ea76e10..2caaf553 100644 --- a/framework/Web/Javascripts/prado/ajax3.js +++ b/framework/Web/Javascripts/prado/ajax3.js @@ -16,6 +16,7 @@ Object.extend(Ajax.Request.prototype,  	    {	      
  	      try 
  	      {
 +	      	Prado.CallbackRequest.updatePageState(this,transport);
  			Ajax.Responders.dispatch('on' + transport.status, this, transport, json);
  			Prado.CallbackRequest.dispatchActions(transport,this.getHeaderData(Prado.CallbackRequest.ACTION_HEADER));
 @@ -104,13 +105,13 @@ Object.extend(Prado.CallbackRequest,  	 */
  	ERROR_HEADER : 'X-PRADO-ERROR',
  	/**
 -	 * Callback request queque.
 +	 * Page state header name.
  	 */
 -	Queque : [],
 +	PAGESTATE_HEADER : 'X-PRADO-PAGESTATE',
  	/**
 -	 * Requests In progress.
 +	 * Current requests in progress.
  	 */
 -	InProgress : [],
 +	requestInProgress : null,
  	/**
  	 * Dispatch callback response actions.
 @@ -223,53 +224,71 @@ Object.extend(Prado.CallbackRequest,  	},
  	/**
 -	 * Dispatch quequed requests, and set a timeout.
 +	 * Dispatch a priority request, it will call abortRequestInProgress first.
  	 */
 -	dispatchQuequedRequest : function()
 +	dispatchPriorityRequest : function(callback)
  	{
 -		requests = Prado.CallbackRequest;
 -		if(requests.InProgress.length == 0 && requests.Queque.length > 0)
 +		Logger.info("priority request "+callback.id)
 +		this.abortRequestInProgress();
 +		
 +		callback.request = new Ajax.Request(callback.url, callback.options);
 +		callback.timeout = setTimeout(function()
  		{
 -			var item = requests.Queque.pop();
 -			item.callback = new Ajax.Request(item.url, item.options);
 -			item.callback.callbackID = item.id;
 -			item.timeout = setTimeout(function()
 -			{
 -				requests.removeInProgress(item.callback);
 -			}, item.options.TimeOut);
 -			requests.InProgress.push(item);
 +			Logger.warn("priority timeout");
 +			Prado.CallbackRequest.abortRequestInProgress();
 +		},callback.options.RequestTimeOut);
 +		
 +		this.requestInProgress = callback;
 +		Logger.info("dispatched "+this.requestInProgress)
 +	},
 +	
 +	/**
 +	 * Dispatch a normal request, no timeouts or aborting of requests.
 +	 */
 +	dispatchNormalRequest : function(callback)
 +	{
 +		Logger.info("dispatching normal request");
 +		new Ajax.Request(callback.url, callback.options);
 +	},
 +	
 +	/**
 +	 * Abort the current priority request in progress.
 +	 */
 +	abortRequestInProgress : function()
 +	{
 +		inProgress = Prado.CallbackRequest.requestInProgress;
 +		if(inProgress)
 +		{
 +			Logger.warn("aborted "+inProgress.id)
 +			inProgress.request.transport.abort();
 +			clearTimeout(inProgress.timeout);
 +			Prado.CallbackRequest.requestInProgress = null;
  		}
  	},
  	/**
 -	 * Remove a request currently in progress and call dispatchQuequedRequest.
 +	 * Updates the page state. It will update only if EnablePageStateUpdate and
 +	 * HasPriority options are both true.
  	 */
 -	removeInProgress : function(request)
 +	updatePageState : function(request, transport)
  	{
 -		if(request && request.callbackID)
 +		pagestate = $(this.FIELD_CALLBACK_PAGESTATE);
 +		if(request.options.EnablePageStateUpdate && request.options.HasPriority && pagestate)
  		{
 -			var stillInProgress = [];
 -			requests = Prado.CallbackRequest;
 -			requests.InProgress.each(function(item)
 -			{
 -				if(item.callback.callbackID == request.callbackID)
 -				{
 -					item.callback.transport.abort();
 -					request.transport.abort();
 -					clearTimeout(item.timeout);	
 -				}
 -				else
 -				{
 -					stillInProgress.push(item);
 -				}
 -			})
 -			requests.InProgress = stillInProgress;
 +			Logger.warn("updating page state");
 +			pagestate.value = request.header(this.PAGESTATE_HEADER);
  		}
 -		requests.dispatchQuequedRequest();
  	}
  })
 -Ajax.Responders.register({onComplete : Prado.CallbackRequest.removeInProgress});
 +/**
 + * Automatically aborts the current request when a priority request has returned.
 + */
 +Ajax.Responders.register({onComplete : function(request)
 +{
 +	if(request.options.HasPriority)
 +		Prado.CallbackRequest.abortRequestInProgress();
 +}});
  //Add HTTP exception respones when logger is enabled.
  Event.OnLoad(function()
 @@ -291,10 +310,7 @@ Prado.CallbackRequest.prototype =  	/**
  	 * Callback options, including onXXX events.
  	 */
 -	options : 
 -	{
 -		TimeOut : 30000 // 30 second timeout.
 -	},
 +	options : {	},
  	/**
  	 * Callback target ID. E.g. $control->getUniqueID();
 @@ -304,34 +320,39 @@ Prado.CallbackRequest.prototype =  	/**
  	 * Current callback request.
  	 */
 -	callback : null,
 +	request : null,
  	/**
  	 * Prepare and inititate a callback request.
  	 */
  	initialize : function(id, options)
  	{
 -		Object.extend(this.options, options || {});
 -		
  		this.id = id;
 -		
 -		var request = 
 +
 +		this.options = 
  		{
 +			RequestTimeOut : 30000, // 30 second timeout.
 +			EnablePageStateUpdate : true,
 +			HasPriority : true,
 +			CausesValidation : true,
 +			ValidationGroup : null,
 +			PostInputs : true,
  			postBody : this._getPostData(),
  			parameters : ''
  		}
 -		
 -		Object.extend(this.options, request);		
 -		
 -		if(this.options.CausesValidation != false && typeof(Prado.Validation) != "undefined")
 +		Object.extend(this.options, options || {});
 +				
 +		if(this.options.CausesValidation && typeof(Prado.Validation) != "undefined")
  		{
  			var form =  this.options.Form || Prado.Validation.getForm();
  			if(Prado.Validation.validate(form,this.options.ValidationGroup,this) == false)
  				return;
  		}
 -		Prado.CallbackRequest.Queque.push(this);
 -		Prado.CallbackRequest.dispatchQuequedRequest();
 +		if(this.options.HasPriority)
 +			Prado.CallbackRequest.dispatchPriorityRequest(this);
 +		else
 +			Prado.CallbackRequest.dispatchNormalRequest(this);
  	},
  	/**
 @@ -343,7 +364,7 @@ Prado.CallbackRequest.prototype =  	{
  		var data = {};
  		var callback = Prado.CallbackRequest;
 -		if(this.options.PostState != false)
 +		if(this.options.PostInputs != false)
  		{
  			callback.PostDataLoaders.each(function(name)
  			{
 @@ -378,8 +399,7 @@ Prado.Callback = function(UniqueID, parameter, onSuccess, options)  	var callback =  
  	{
  		'params' : parameter || '',
 -		'onSuccess' : onSuccess || Prototype.emptyFunction, 
 -		'CausesValidation' : true
 +		'onSuccess' : onSuccess || Prototype.emptyFunction
  	};
  	Object.extend(callback, options || {});
 diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php index b95bdd37..77973b2c 100644 --- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php +++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php @@ -22,4 +22,4 @@ class TActiveControlAdapter extends TControlAdapter  		parent::render($writer);
  	}	
  } 
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TActiveLabel.php b/framework/Web/UI/ActiveControls/TActiveLabel.php index d71d8b7a..3216be43 100644 --- a/framework/Web/UI/ActiveControls/TActiveLabel.php +++ b/framework/Web/UI/ActiveControls/TActiveLabel.php @@ -29,7 +29,7 @@ class TActiveLabel extends TLabel  	/**
  	 * Creates a new callback control, sets the adapter to
  	 * TActiveControlAdapter. If you override this class, be sure to set the
 -	 * adapter appropriately by, for example, call this constructor.
 +	 * adapter appropriately by, for example, by calling this constructor.
  	 */
  	public function __construct()
  	{
 @@ -44,7 +44,7 @@ class TActiveLabel extends TLabel  	public function setText($value)
  	{
  		parent::setText($value);
 -		if($this->getPage()->getAllowCallbackUpdate())
 +		if($this->getIsInitialized())
  		{
  			$this->getPage()->getCallbackClient()->update($this, $value);
  		}
 @@ -59,7 +59,7 @@ class TActiveLabel extends TLabel  	public function setForControl($value)
  	{
  		parent::setForControl($value);
 -		if($this->getPage()->getAllowCallbackUpdate())
 +		if($this->getIsInitialized())
  		{
  			$id=$this->findControl($value)->getClientID();
  			$this->getPage()->getCallbackClient()->setAttribute($this, 'for', $id);
 @@ -67,4 +67,4 @@ class TActiveLabel extends TLabel  	}
  } 
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TActivePageAdapter.php b/framework/Web/UI/ActiveControls/TActivePageAdapter.php index db783a12..67720afd 100644 --- a/framework/Web/UI/ActiveControls/TActivePageAdapter.php +++ b/framework/Web/UI/ActiveControls/TActivePageAdapter.php @@ -25,6 +25,7 @@ class TActivePageAdapter extends TControlAdapter  	const CALLBACK_DATA_HEADER = 'X-PRADO-DATA';
  	const CALLBACK_ACTION_HEADER = 'X-PRADO-ACTIONS';
  	const CALLBACK_ERROR_HEADER = 'X-PRADO-ERROR';
 +	const CALLBACK_PAGESTATE_HEADER = 'X-PRADO-PAGESTATE';
  	/**
  	 * @var ICallbackEventHandler callback event handler. 
 @@ -80,7 +81,7 @@ class TActivePageAdapter extends TControlAdapter  	/**
  	 * Renders the callback response by adding additional callback data and
 -	 * javascript actions in the header.
 +	 * javascript actions in the header and page state if required.
  	 */
  	protected function renderResponse($writer)
  	{
 @@ -92,7 +93,15 @@ class TActivePageAdapter extends TControlAdapter  		{
  			$data = TJavascript::jsonEncode($this->_result->getData());
  			$response->appendHeader(self::CALLBACK_DATA_HEADER.': '.$data);
 -		}		
 +		}
 +		if(($handler = $this->getCallbackEventTarget()) !== null)
 +		{
 +			if($handler->getClientSide()->getEnablePageStateUpdate())
 +			{
 +				$pagestate = $this->getPage()->getClientState();
 +				$response->appendHeader(self::CALLBACK_PAGESTATE_HEADER.': '.$pagestate);
 +			}
 +		}
  	}
  	/**
 @@ -329,4 +338,4 @@ class TInvalidCallbackRequestException extends TException  {
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TCallback.php b/framework/Web/UI/ActiveControls/TCallback.php index 9c3234fd..9d2301d8 100644 --- a/framework/Web/UI/ActiveControls/TCallback.php +++ b/framework/Web/UI/ActiveControls/TCallback.php @@ -147,4 +147,4 @@ class TCallback extends TControl implements ICallbackEventHandler  	}
  } 
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TCallbackClientScript.php b/framework/Web/UI/ActiveControls/TCallbackClientScript.php index 5f8851db..5d317c8a 100644 --- a/framework/Web/UI/ActiveControls/TCallbackClientScript.php +++ b/framework/Web/UI/ActiveControls/TCallbackClientScript.php @@ -531,4 +531,4 @@ class TCallbackClientScript extends TApplicationComponent  	}
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php b/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php index 6a4731f7..c0a817f0 100644 --- a/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php +++ b/framework/Web/UI/ActiveControls/TCallbackClientSideOptions.php @@ -1,37 +1,4 @@  <?php
 -/*
 - * Created on 1/05/2006
 - */
 -
 -class TClientSideOptions extends TComponent
 -{
 -	private $_options;
 -	
 -	public function __construct()
 -	{
 -		$this->_options = Prado::createComponent('System.Collections.TMap');
 -	}
 -	
 -	protected function setFunction($name, $code)
 -	{
 -		$this->_options->add($name, $this->ensureFunction($code));
 -	}
 -	
 -	protected function getOption($name)
 -	{
 -		return $this->_options->itemAt($name);
 -	}
 -	
 -	public function getOptions()
 -	{
 -		return $this->_options;
 -	}
 -	
 -	protected function ensureFunction($javascript)
 -	{
 -		return $javascript;
 -	}
 -}
  /**
   * TCallbackClientSideOptions class.
 @@ -54,6 +21,15 @@ class TClientSideOptions extends TComponent   * - <b>onException</b> raised when callback request fails due to
   * request/response errors.
   * 
 + * - <b>PostInputs</b> true to collect the form inputs and post them during
 + * callback, default is true.
 + * - <b>RequestTimeOut</b> The request timeout in milliseconds.
 + * - <b>HasPriority</b> true to ensure that the callback request will be sent
 + * immediately and will abort existing prioritized requests. It does not affect
 + * callbacks that are not prioritized.
 + * - <b>EnablePageStateUpdate</b> enable the callback response to enable the
 + * viewstate update. This will automatically set HasPrority to true when
 + * enabled.
   */
  class TCallbackClientSideOptions extends TClientSideOptions
  {
 @@ -65,13 +41,7 @@ class TCallbackClientSideOptions extends TClientSideOptions  	 */
  	protected function ensureFunction($javascript)
  	{
 -		if(TJavascript::isFunction($javascript))
 -			return $javascript;
 -		else
 -		{
 -			$code = "function(request, result){ {$javascript} }";
 -			return TJavascript::quoteFunction($code);
 -		}
 +		return "function(request, result){ {$javascript} }";
  	}
  	/**
 @@ -200,21 +170,21 @@ class TCallbackClientSideOptions extends TClientSideOptions  	}	
  	/**
 -	 * @return boolean true to post the state on callback, default is post the
 -	 * state on callback.
 +	 * @return boolean true to post the inputs of the form on callback, default
 +	 * is post the inputs on callback.
  	 */
  	public function getPostState()
  	{
 -		return $this->getOption('PostState');
 +		return $this->getOption('PostInputs');
  	}
  	/**
 -	 * @param boolean true to post the state of the form with callback requests.
 -	 * Default is to post the state.
 +	 * @param boolean true to post the inputs of the form with callback
 +	 * requests. Default is to post the inputs.
  	 */
  	public function setPostState($value)
  	{
 -		$this->getOptions()->add('PostState', TPropertyValue::ensureBoolean($value));
 +		$this->setOption('PostInputs', TPropertyValue::ensureBoolean($value));
  	}
  	/**
 @@ -222,7 +192,7 @@ class TCallbackClientSideOptions extends TClientSideOptions  	 */
  	public function getRequestTimeOut()
  	{
 -		return $this->getOption('TimeOut');
 +		return $this->getOption('RequestTimeOut');
  	}
  	/**
 @@ -230,8 +200,54 @@ class TCallbackClientSideOptions extends TClientSideOptions  	 */
  	public function setRequestTimeOut($value)
  	{
 -		$this->getOptions()->add('TimeOut', TPropertyValue::ensureInteger($value));
 +		$this->setOption('RequestTimeOut', TPropertyValue::ensureInteger($value));
 +	}
 +	
 +	/**
 +	 * @return boolean true if the callback request has priority and will abort
 +	 * existing prioritized request in order to send immediately. It does not
 +	 * affect callbacks that are not prioritized.
 +	 */
 +	public function getHasPriority()
 +	{
 +		return $this->getOption('HasPriority');
 +	}
 +	
 +	/**
 +	 * @param boolean true to ensure that the callback request will be sent
 +	 * immediately and will abort existing prioritized requests. It does not
 +	 * affect callbacks that are not prioritized.
 +	 */
 +	public function setHasPriority($value)
 +	{
 +		$hasPriority = TPropertyValue::ensureBoolean($value);
 +		$this->setOption('HasPriority', $hasPriority);
 +		if(!$hasPriority)
 +			$this->setEnablePageStateUpdate(false);
 +	}
 +	
 +	/**
 +	 * Set to true to enable the callback response to enable the viewstate
 +	 * update. This will automatically set HasPrority to true.
 +	 * @param boolean true enables the callback response to update the
 +	 * viewstate.
 +	 */
 +	public function setEnablePageStateUpdate($value)
 +	{
 +		$enabled = TPropertyValue::ensureBoolean($value); 
 +		$this->setOption('EnablePageStateUpdate', $enabled);
 +		if($enabled) 
 +			$this->setHasPriority(true);
 +	}
 +	
 +	/**
 +	 * @return boolean client-side viewstate will be updated on callback
 +	 * response if true.
 +	 */
 +	public function getEnablePageStateUpdate()
 +	{
 +		return $this->getOption('EnablePageStateUpdate');
  	}
  } 
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/ActiveControls/TCallbackResponse.php b/framework/Web/UI/ActiveControls/TCallbackResponse.php index 4a893b9a..024ad6ef 100644 --- a/framework/Web/UI/ActiveControls/TCallbackResponse.php +++ b/framework/Web/UI/ActiveControls/TCallbackResponse.php @@ -1,14 +1,8 @@  <?php
 -/*
 - * Created on 29/04/2006
 - */
 -
 -// See TActivePageAdapter::renderResponse()
 -//TODO: How to render the response, it will contain 3 pieces of data
 -// 1) The arbituary data returned to the client-side callback handler
 -// 2) client-side function call statements
 -// 3) Content body, which may need to be partitioned
 +/**
 + * 
 + */
  class TCallbackResponse extends THttpResponse
  {
  	private $_writers=array();
 @@ -57,4 +51,5 @@ class TCallbackResponseWriter extends TTextWriter  		return $content;
  	}
  }
 -?>
 +
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 46203b0b..20612ce2 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -1,6 +1,6 @@  <?php  /** - * TClientScriptManager class file + * TClientScriptManager and TClientSideOptions class file.   *   * @author Qiang Xue <qiang.xue@gmail.com>   * @link http://www.pradosoft.com/ @@ -164,15 +164,12 @@ class TClientScriptManager extends TApplicationComponent  		}  	} -	public function getCallbackReference($callbackHandler, $options=null) +	public function getCallbackReference(ICallbackEventHandler $callbackHandler, $options=null)  	{  		$options = !is_array($options) ? array() : $options;   		$class = new TReflectionClass($callbackHandler); -		if($class->hasMethod('getClientSide')) -		{ -			$clientSide = $callbackHandler->getClientSide(); -			$options = array_merge($options, $clientSide->getOptions()->toArray()); -		} +		$clientSide = $callbackHandler->getClientSide(); +		$options = array_merge($options, $clientSide->getOptions()->toArray());  		$optionString = TJavascript::encode($options);  		$this->registerPradoScriptInternal('ajax');  		$id = $callbackHandler->getUniqueID(); @@ -532,4 +529,82 @@ class TClientScriptManager extends TApplicationComponent  	}  } +/** + * TClientSideOptions abstract class. + * + * TClientSideOptions manages client-side options for components that have + * common client-side javascript behaviours and client-side events such as + * between ActiveControls and validators. + * + * @author <weizhuo[at]gmail[dot]com> + * @version $Revision: $  $Date: $ + * @package System.Web.UI + * @since 3.0 + */ +abstract class TClientSideOptions extends TComponent +{ +	/** +	 * @var TMap list of client-side options. +	 */ +	private $_options; +	 +	/** +	 * Constructor, initialize the options list. +	 */ +	public function __construct() +	{ +		$this->_options = Prado::createComponent('System.Collections.TMap'); +	} +	 +	/** +	 * Adds on client-side event handler by wrapping the code within a +	 * javascript function block. If the code begins with "javascript:", the +	 * code is assumed to be a javascript function block rather than arbiturary +	 * javascript statements. +	 * @param string option name +	 * @param string javascript statements. +	 */ +	protected function setFunction($name, $code) +	{ +		if(!TJavascript::isFunction($code)) +			$code = TJavascript::quoteFunction($this->ensureFunction($code));		 +		$this->setOption($name, $code); +	} +	 +	/** +	 * @return string gets a particular option, null if not set. +	 */ +	protected function getOption($name) +	{ +		return $this->_options->itemAt($name); +	} +	 +	/** +	 * @param string option name +	 * @param mixed option value. +	 */ +	protected function setOption($name, $value) +	{ +		$this->_options->add($name, $value); +	} +	 +	/** +	 * @return TMap gets the list of options as TMap +	 */ +	public function getOptions() +	{ +		return $this->_options; +	} +	 +	/** +	 * Ensure that the javascript statements are wrapped in a javascript +	 * function block. Default has no wrapping. Override this method to +	 * customize the wrapping javascript function block. +	 */ +	protected function ensureFunction($javascript) +	{ +		return $javascript; +	} +} +  ?>
\ No newline at end of file diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index 860b6baf..3bb893e2 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -997,6 +997,14 @@ class TControl extends TApplicationComponent implements IRenderable, IBindable  	{
  		return isset($this->_rf[self::RF_NAMED_OBJECTS][$name]);
  	}
 +	
 +	/**
 +	 * @return boolean true if the control has been initialized.
 +	 */
 +	public function getIsInitialized()
 +	{
 +		return $this->getControlStage() >= self::CS_CHILD_INITIALIZED;
 +	}
  	/**
  	 * Returns the named registered object.
 diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php index 11ebc1dd..008b7c83 100644 --- a/framework/Web/UI/TPage.php +++ b/framework/Web/UI/TPage.php @@ -153,12 +153,7 @@ class TPage extends TTemplateControl  	 * @var array post data loader IDs.
  	 */
  	private $_postDataLoaders=array();
 -	/**
 -	 * @var boolean true if callback request is allowed to update the client-
 -	 * side contents during callback response.
 -	 */
 -	private $_allowCallbackUpdate=false;
 -	
 +
  	/**
  	 * Constructor.
  	 * Sets the page object to itself.
 @@ -282,8 +277,6 @@ class TPage extends TTemplateControl  		Prado::trace("Page initRecursive()",'System.Web.UI.TPage');
  		$this->initRecursive();
 -		$this->setAllowCallbackUpdate(true);
 -
  		Prado::trace("Page onInitComplete()",'System.Web.UI.TPage');
  		$this->onInitComplete(null);
 @@ -316,11 +309,12 @@ class TPage extends TTemplateControl  		Prado::trace("Page onPreRenderComplete()",'System.Web.UI.TPage');
  		$this->onPreRenderComplete(null);
 -/*		Prado::trace("Page savePageState()",'System.Web.UI.TPage');
 +		Prado::trace("Page savePageState()",'System.Web.UI.TPage');
  		$this->savePageState();
  		Prado::trace("Page onSaveStateComplete()",'System.Web.UI.TPage');
  		$this->onSaveStateComplete(null);
 +/*
  		Prado::trace("Page renderControl()",'System.Web.UI.TPage');
  		$this->renderControl($writer);
  */
 @@ -331,28 +325,6 @@ class TPage extends TTemplateControl  	}
  	/**
 -	 * Returns true if callback request is allowed to update the client- side
 -	 * contents during callback response. Default is true if {@link
 -	 * getIsCallback IsCallback} is true and onInit stage has been completed.
 -	 * @return boolean true to allow client-side update.
 -	 */
 -	public function getAllowCallbackUpdate()
 -	{
 -		return $this->_allowCallbackUpdate;
 -	}
 -	
 -	/**
 -	 * Set to true to allow callback request to update client-side content
 -	 * during callback response. Default is true if {@link getIsCallback
 -	 * IsCallback} is true and onInit stage has been completed.
 -	 * @param boolean true to allow callback to update client-side content.
 -	 */
 -	public function setAllowCallbackUpdate($value)
 -	{
 -		$this->_allowCallbackUpdate = TPropertyValue::ensureBoolean($value);
 -	}
 -	
 -	/**
  	 * Gets the callback client script handler that allows javascript functions
  	 * to be executed during the callback response. 
  	 * @return TCallbackClientScript interface to client-side javascript code.
 diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php index 36562b1b..27bd0ac6 100644 --- a/framework/Web/UI/TTemplateManager.php +++ b/framework/Web/UI/TTemplateManager.php @@ -883,4 +883,4 @@ class TTemplate extends TApplicationComponent implements ITemplate  	}
  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php index ea1a5836..c39db85a 100644 --- a/framework/Web/UI/WebControls/TBaseValidator.php +++ b/framework/Web/UI/WebControls/TBaseValidator.php @@ -80,9 +80,9 @@ abstract class TBaseValidator extends TLabel implements IValidator  	 */  	private $_registered=false;  	/** -	 * @var TValidatorClientScript validator client-script options. +	 * @var TClientSideValidatorOptions validator client-script options.  	 */ -	private $_clientScript; +	private $_clientSide;  	/**  	 * Constructor. @@ -154,14 +154,14 @@ abstract class TBaseValidator extends TLabel implements IValidator  		$options['ControlCssClass'] = $this->getControlCssClass();  		$options['ControlType'] = get_class($control); -		if(!is_null($this->_clientScript)) -			$options = array_merge($options,$this->_clientScript->getOptions()); +		if(!is_null($this->_clientSide)) +			$options = array_merge($options,$this->_clientSide->getOptions()->toArray());  		return $options;  	}  	/** -	 * Gets the TValidatorClientScript that allows modification of the client- +	 * Gets the TClientSideValidatorOptions that allows modification of the client-  	 * side validator events.   	 *   	 * The client-side validator supports the following events. @@ -174,21 +174,21 @@ abstract class TBaseValidator extends TLabel implements IValidator  	 *   	 * You can attach custom javascript code to each of these events  	 *  -	 * @return TValidatorClientScript javascript validator event options. +	 * @return TClientSideValidatorOptions javascript validator event options.  	 */  	public function getClientSide()  	{ -		if(is_null($this->_clientScript)) -			$this->_clientScript = $this->createClientScript(); -		return $this->_clientScript; +		if(is_null($this->_clientSide)) +			$this->_clientSide = $this->createClientSideOptions(); +		return $this->_clientSide;  	}  	/** -	 * @return TValidatorClientScript javascript validator event options. +	 * @return TClientSideValidatorOptions javascript validator event options.  	 */ -	protected function createClientScript() +	protected function createClientSideOptions()  	{ -		return new TValidatorClientScript; +		return new TClientSideValidatorOptions;  	}  	/** @@ -491,11 +491,11 @@ abstract class TBaseValidator extends TLabel implements IValidator  }  /** - * TValidatorClientScript class. + * TClientSideValidatorOptions class.   *    * Client-side validator events can be modified through the {@link   * TBaseValidator::getClientSide ClientSide} property of a validator. The - * subproperties of ClientSide are those of the TValidatorClientScript + * subproperties of ClientSide are those of the TClientSideValidatorOptions   * properties. The client-side validator supports the following events.   *    * The <tt>OnValidate</tt> event is raise before the validator validation @@ -513,27 +513,14 @@ abstract class TBaseValidator extends TLabel implements IValidator   * @package System.Web.UI.WebControls   * @since 3.0   */ -class TValidatorClientScript extends TComponent +class TClientSideValidatorOptions extends TClientSideOptions  {  	/** -	 * @var TMap client-side validator event javascript code. -	 */ -	private $_options; -	 -	/** -	 * Constructor. -	 */ -	public function __construct() -	{ -		$this->_options = new TMap; -	} -	 -	/**  	 * @return string javascript code for client-side OnValidate event.  	 */  	public function getOnValidate()  	{ -		return $this->_options->itemAt['OnValidate'];	 +		return $this->getOption('OnValidate');	  	}  	/** @@ -543,7 +530,7 @@ class TValidatorClientScript extends TComponent  	 */  	public function setOnValidate($javascript)  	{ -		$this->_options->add('OnValidate', $this->ensureFunction($javascript)); +		$this->setFunction('OnValidate', $javascript);  	}  	/** @@ -553,7 +540,7 @@ class TValidatorClientScript extends TComponent  	 */  	public function setOnSuccess($javascript)  	{ -		$this->_options->add('OnSuccess', $this->ensureFunction($javascript)); +		$this->setFunction('OnSuccess', $javascript);  	}  	/** @@ -561,7 +548,7 @@ class TValidatorClientScript extends TComponent  	 */  	public function getOnSuccess()  	{ -		return $this->_options->itemAt('OnSuccess'); +		return $this->getOption('OnSuccess');  	}  	/** @@ -571,7 +558,7 @@ class TValidatorClientScript extends TComponent  	 */  	public function setOnError($javascript)  	{ -		$this->_options->add('OnError', $this->ensureFunction($javascript)); +		$this->setFunction('OnError', $javascript);  	}  	/** @@ -579,15 +566,7 @@ class TValidatorClientScript extends TComponent  	 */  	public function getOnError()  	{ -		return $this->_options->itemAt('OnError'); -	} -	 -	/** -	 * @return array list of client-side event code. -	 */ -	public function getOptions() -	{ -		return $this->_options->toArray(); +		return $this->getOption('OnError');  	}  	/** @@ -597,15 +576,9 @@ class TValidatorClientScript extends TComponent  	 * @param string javascript code.  	 * @return string javascript function code.  	 */ -	private function ensureFunction($javascript) +	protected function ensureFunction($javascript)  	{ -		if(TJavascript::isFunction($javascript)) -			return $javascript; -		else -		{ -			$code = "function(validator, sender){ {$javascript} }"; -			return TJavascript::quoteFunction($code); -		} +		return "function(validator, sender){ {$javascript} }";  	}  } diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php index 681c8748..da389948 100644 --- a/framework/Web/UI/WebControls/TCheckBox.php +++ b/framework/Web/UI/WebControls/TCheckBox.php @@ -378,4 +378,4 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl  }
 -?>
 +?>
\ No newline at end of file diff --git a/framework/Web/UI/WebControls/TValidationSummary.php b/framework/Web/UI/WebControls/TValidationSummary.php index 87821292..8148036b 100644 --- a/framework/Web/UI/WebControls/TValidationSummary.php +++ b/framework/Web/UI/WebControls/TValidationSummary.php @@ -37,9 +37,9 @@  class TValidationSummary extends TWebControl
  {
  	/**
 -	 * @var TValidatorClientScript validator client-script options.
 +	 * @var TClientSideValidationSummaryOptions validation client side options.
  	 */
 -	private $_clientScript;
 +	private $_clientSide;
  	/**
  	 * Constructor.
 @@ -248,30 +248,30 @@ class TValidationSummary extends TWebControl  		$options['ValidationGroup'] =  $this->getValidationGroup();
  		$options['Display'] = $this->getDisplay();
 -		if(!is_null($this->_clientScript))
 -			$options = array_merge($options,$this->_clientScript->getOptions());
 +		if(!is_null($this->_clientSide))
 +			$options = array_merge($options,$this->_clientSide->getOptions()->toArray());
  		return $options;
  	}
  	/**
 -	 * @return TValidationSummaryClientScript client-side validation summary
 +	 * @return TClientSideValidationSummaryOptions client-side validation summary
  	 * event options.
  	 */
  	public function getClientSide()
  	{
 -		if(is_null($this->_clientScript))
 -			$this->_clientScript = $this->createClientScript();
 -		return $this->_clientScript;
 +		if(is_null($this->_clientSide))
 +			$this->_clientSide = $this->createClientScript();
 +		return $this->_clientSide;
  	}
  	/**
 -	 * @return TValidationSummaryClientScript javascript validation summary
 +	 * @return TClientSideValidationSummaryOptions javascript validation summary
  	 * event options.
  	 */
  	protected function createClientScript()
  	{
 -		return new TValidationSummaryClientScript;
 +		return new TClientSideValidationSummaryOptions;
  	}
  	/**
  	 * Get the list of validation error messages.
 @@ -372,7 +372,7 @@ class TValidationSummary extends TWebControl  }
  /**
 - * TValidationSummaryClientScript class.
 + * TClientSideValidationSummaryOptions class.
   * 
   * Client-side validation summary events such as {@link setOnHideSummary
   * OnHideSummary} and {@link setOnShowSummary OnShowSummary} can be modified
 @@ -392,27 +392,14 @@ class TValidationSummary extends TWebControl   * @package System.Web.UI.WebControls
   * @since 3.0
   */
 -class TValidationSummaryClientScript extends TComponent
 +class TClientSideValidationSummaryOptions extends TClientSideOptions
  {
  	/**
 -	 * @var TMap client-side validation summary event javascript code.
 -	 */
 -	private $_options;
 -	
 -	/**
 -	 * Constructor.
 -	 */
 -	public function __construct()
 -	{
 -		$this->_options = new TMap;
 -	}
 -
 -	/**
  	 * @return string javascript code for client-side OnHideSummary event.
  	 */
  	public function getOnHideSummary()
  	{
 -		return $this->_options->itemAt['OnHideSummary'];	
 +		return $this->getOption('OnHideSummary');	
  	}
  	/**
 @@ -423,7 +410,7 @@ class TValidationSummaryClientScript extends TComponent  	 */
  	public function setOnHideSummary($javascript)
  	{
 -		$this->_options->add('OnHideSummary', $this->ensureFunction($javascript));
 +		$this->setFunction('OnHideSummary', $javascript);
  	}
  	/**
 @@ -434,7 +421,7 @@ class TValidationSummaryClientScript extends TComponent  	 */
  	public function setOnShowSummary($javascript)
  	{
 -		$this->_options->add('OnShowSummary', $this->ensureFunction($javascript));
 +		$this->setFunction('OnShowSummary', $javascript);
  	}
  	/**
 @@ -442,15 +429,7 @@ class TValidationSummaryClientScript extends TComponent  	 */
  	public function getOnShowSummary()
  	{
 -		return $this->_options->itemAt('OnShowSummary');
 -	}
 -	
 -	/**
 -	 * @return array list of client-side event code.
 -	 */
 -	public function getOptions()
 -	{
 -		return $this->_options->toArray();
 +		return $this->getOption('OnShowSummary');
  	}
  	/**
 @@ -460,15 +439,9 @@ class TValidationSummaryClientScript extends TComponent  	 * @param string javascript code.
  	 * @return string javascript function code.
  	 */
 -	private function ensureFunction($javascript)
 +	protected function ensureFunction($javascript)
  	{
 -		if(TJavascript::isFunction($javascript))
 -			return $javascript;
 -		else
 -		{
 -			$code = "function(summary, validators){ {$javascript} }";
 -			return TJavascript::quoteFunction($code);
 -		}
 +		return "function(summary, validators){ {$javascript} }";
  	}	
  }
 diff --git a/framework/interfaces.php b/framework/interfaces.php index eb9084b3..fc830140 100644 --- a/framework/interfaces.php +++ b/framework/interfaces.php @@ -315,6 +315,11 @@ interface ICallbackEventHandler  	 * @param TCallbackEventParameter the parameter associated with the callback event
  	 */
  	public function raiseCallbackEvent($eventArgument);
 +	
 +	/**
 +	 * @return TCallbackClientSideOptions client-side options.
 +	 */
 +	public function getClientSide(); 
  }
  ?>
\ No newline at end of file  | 
