diff options
Diffstat (limited to 'framework/Web')
| -rw-r--r-- | framework/Web/THttpResponse.php | 78 | ||||
| -rw-r--r-- | framework/Web/UI/ActiveControls/TActiveControlAdapter.php | 10 | ||||
| -rwxr-xr-x | framework/Web/UI/ActiveControls/TDraggable.php | 19 | ||||
| -rwxr-xr-x | framework/Web/UI/ActiveControls/TDropContainer.php | 13 | ||||
| -rw-r--r-- | framework/Web/UI/TClientScriptManager.php | 67 | ||||
| -rw-r--r-- | framework/Web/UI/TForm.php | 28 | ||||
| -rw-r--r-- | framework/Web/UI/THtmlWriter.php | 3 | ||||
| -rw-r--r-- | framework/Web/UI/TPage.php | 27 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TBaseValidator.php | 3 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/THtmlArea.php | 18 | 
10 files changed, 223 insertions, 43 deletions
diff --git a/framework/Web/THttpResponse.php b/framework/Web/THttpResponse.php index 50ac4d7d..07d11a2c 100644 --- a/framework/Web/THttpResponse.php +++ b/framework/Web/THttpResponse.php @@ -116,6 +116,14 @@ class THttpResponse extends TModule implements ITextWriter  	 * @var THttpResponseAdapter adapter.
  	 */
  	private $_adapter;
 +	/**
 +	 * @var boolean whether http response header has been sent
 +	 */
 +	private $_httpHeaderSent;
 +	/**
 +	 * @var boolean whether content-type header has been sent
 +	 */
 +	private $_contentTypeHeaderSent;
  	/**
  	 * Destructor.
 @@ -203,6 +211,8 @@ class THttpResponse extends TModule implements ITextWriter  	 */
  	public function setContentType($type)
  	{
 +		if ($this->_contentTypeHeaderSent)
 +			throw new Exception('Unable to alter content-type as it has been already sent');
  		$this->_contentType = $type;
  	}
 @@ -268,6 +278,8 @@ class THttpResponse extends TModule implements ITextWriter  	 */
  	public function setStatusCode($status, $reason=null)
  	{
 +		if ($this->_httpHeaderSent)
 +			throw new Exception('Unable to alter response as HTTP header already sent');
  		$status=TPropertyValue::ensureInteger($status);
  		if(isset(self::$HTTP_STATUS_CODES[$status])) {
  			$this->_reason=self::$HTTP_STATUS_CODES[$status];
 @@ -308,6 +320,9 @@ class THttpResponse extends TModule implements ITextWriter  	 */
  	public function write($str)
  	{
 +		// when starting output make sure we send the headers first
 +		if (!$this->_bufferOutput and !$this->_httpHeaderSent)
 +			$this->ensureHeadersSent();
  		echo $str;
  	}
 @@ -435,36 +450,79 @@ class THttpResponse extends TModule implements ITextWriter  	/**
  	 * Flush the response contents and headers.
  	 */
 -	public function flush()
 +	public function flush($continueBuffering = true)
  	{
  		if($this->getHasAdapter())
 -			$this->_adapter->flushContent();
 +			$this->_adapter->flushContent($continueBuffering);
  		else
 -			$this->flushContent();
 +			$this->flushContent($continueBuffering);
 +	}
 +
 +	/**
 +	 * Ensures that HTTP response and content-type headers are sent
 +	 */
 +	public function ensureHeadersSent()
 +	{
 +		$this->ensureHttpHeaderSent();
 +		$this->ensureContentTypeHeaderSent();
  	}
  	/**
  	 * Outputs the buffered content, sends content-type and charset header.
  	 * This method is used internally. Please use {@link flush} instead.
 +	 * @param boolean whether to continue buffering after flush if buffering was active
  	 */
 -	public function flushContent()
 +	public function flushContent($continueBuffering = true)
  	{
  		Prado::trace("Flushing output",'System.Web.THttpResponse');
 -		$this->sendHttpHeader();
 -		$this->sendContentTypeHeader();
 -		if($this->_bufferOutput)
 -			ob_flush();
 +		$this->ensureHeadersSent();
 + 		if($this->_bufferOutput)
 +		{
 +			// avoid forced send of http headers (ob_flush() does that) if there's no output yet
 +			if (ob_get_length()>0) 
 +			{
 +				if (!$continueBuffering)
 +					{
 +						$this->_bufferOutput = false;
 +						ob_end_flush();
 +					}
 +				else
 +						ob_flush();
 +				flush();
 +			}
 +		}
 +		else
 +			flush();
 +	}
 +
 +	/**
 +	 * Ensures that the HTTP header with the status code and status reason are sent
 +	 */
 +	protected function ensureHttpHeaderSent()
 +	{
 +		if (!$this->_httpHeaderSent)
 +			$this->sendHttpHeader();
  	}
  	/**
  	 * Send the HTTP header with the status code (defaults to 200) and status reason (defaults to OK)
  	 */
 -	protected function sendHttpHeader ()
 +	protected function sendHttpHeader()
  	{
  		if (($version=$this->getRequest()->getHttpProtocolVersion())==='')
  			header (' ', true, $this->_status);
  		else
  			header($version.' '.$this->_status.' '.$this->_reason, true, $this->_status);
 +		$this->_httpHeaderSent = true;
 +	}
 +
 +	/**
 +	 * Ensures that the HTTP header with the status code and status reason are sent
 +	 */
 +	protected function ensureContentTypeHeaderSent()
 +	{
 +		if (!$this->_contentTypeHeaderSent)
 +			$this->sendContentTypeHeader();
  	}
  	/**
 @@ -484,6 +542,8 @@ class THttpResponse extends TModule implements ITextWriter  		if($charset==='') $charset = self::DEFAULT_CHARSET;
  		$this->appendHeader('Content-Type: '.$contentType.';charset='.$charset);
 +
 +		$this->_contentTypeHeaderSent = true;
  	}
  	/**
 diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php index e8f947af..99c5e71e 100644 --- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php +++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php @@ -75,6 +75,15 @@ class TActiveControlAdapter extends TControlAdapter  			$this->_activeControlType = $type;
  	}
 + 	/**
 +	 * Publish the ajax script
 +	 */
 +	public function onPreRender($param)
 +	{
 +		parent::onPreRender($param);
 +		$this->getPage()->getClientScript()->registerPradoScript('ajax');
 +	}
 +
  	/**
  	 * Renders the callback client scripts.
  	 */
 @@ -93,7 +102,6 @@ class TActiveControlAdapter extends TControlAdapter  		$key = 'Prado.CallbackRequest.addPostLoaders';
  		if(!$cs->isEndScriptRegistered($key))
  		{
 -			$cs->registerPradoScript('ajax');
  			$data = $this->getPage()->getPostDataLoaders();
  			if(count($data) > 0)
  			{
 diff --git a/framework/Web/UI/ActiveControls/TDraggable.php b/framework/Web/UI/ActiveControls/TDraggable.php index 34d8c548..10e78b9b 100755 --- a/framework/Web/UI/ActiveControls/TDraggable.php +++ b/framework/Web/UI/ActiveControls/TDraggable.php @@ -136,6 +136,20 @@ class TDraggable extends TPanel  		$this->setViewState('Constraint', TPropertyValue::ensureEnum($value, 'TDraggableConstraint'), TDraggableConstraint::None);  	} +	/** +	 * Registers clientscripts +	 * +	 * This method overrides the parent implementation and is invoked before render. +	 * @param mixed event parameter +	 */ +	public function onPreRender($param) +	{ +		parent::onPreRender($param); +		if ($this->getGhosting()==TDraggableGhostingOptions::SuperGhosting) +			$cs->registerPradoScript('dragdropextra'); +		else +			$cs->registerPradoScript('dragdrop'); +	}  	/**  	 * Ensure that the ID attribute is rendered and registers the javascript code @@ -145,11 +159,6 @@ class TDraggable extends TPanel  	{  		parent::addAttributesToRender($writer);  		$writer->addAttribute('id',$this->getClientID()); -		$cs=$this->getPage()->getClientScript(); -		if ($this->getGhosting()==TDraggableGhostingOptions::SuperGhosting) -			$cs->registerPradoScript('dragdropextra'); -		else -			$cs->registerPradoScript('dragdrop');  		$options=TJavascript::encode($this->getPostBackOptions());  		$class=$this->getClientClassName();  		$code="new {$class}('{$this->getClientId()}', {$options}) "; diff --git a/framework/Web/UI/ActiveControls/TDropContainer.php b/framework/Web/UI/ActiveControls/TDropContainer.php index 915aa8f9..e6933147 100755 --- a/framework/Web/UI/ActiveControls/TDropContainer.php +++ b/framework/Web/UI/ActiveControls/TDropContainer.php @@ -172,6 +172,17 @@ class TDropContainer extends TPanel implements IActiveControl, ICallbackEventHan  		return 'Prado.WebUI.DropContainer';  	}	 +	/** +	 * Registers clientscripts +	 * +	 * This method overrides the parent implementation and is invoked before render. +	 * @param mixed event parameter +	 */ +	public function onPreRender($param) +	{ +		parent::onPreRender($param); +		$this->getPage()->getClientScript()->registerPradoScript('dragdrop'); +	}  	/**  	 * Ensure that the ID attribute is rendered and registers the javascript code @@ -182,8 +193,6 @@ class TDropContainer extends TPanel implements IActiveControl, ICallbackEventHan  		parent::addAttributesToRender($writer);  		$writer->addAttribute('id',$this->getClientID()); -		$this->getPage()->getClientScript()->registerPradoScript('dragdrop'); -  		$this->getActiveControl()->registerCallbackClientScript(  			$this->getClientClassName(), $this->getPostBackOptions());  	} diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 8f246d3d..eec347eb 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -82,6 +82,12 @@ class TClientScriptManager extends TApplicationComponent  	 */  	private static $_pradoPackages; +	private $_renderedHiddenFields; + +	private $_renderedScriptFiles; + +	private $_renderedPradoScripts; +  	/**  	 * Constructor.  	 * @param TPage page that owns this client script manager @@ -118,6 +124,7 @@ class TClientScriptManager extends TApplicationComponent  	 */  	private function registerPradoScriptInternal($name)  	{ +		// $this->checkIfNotInRender();  		if(!isset($this->_registeredPradoScripts[$name]))  		{  			if(self::$_pradoScripts === null) @@ -149,9 +156,11 @@ class TClientScriptManager extends TApplicationComponent  	 * Renders the HTML tags for PRADO js files  	 * @param THtmlWriter writer  	 */ -	protected function renderPradoScripts($writer) +	protected function renderPradoScriptsInt($writer, $initial)  	{ -		if(($packages=array_keys($this->_registeredPradoScripts))!==array()) +		if($initial) $this->_renderedPradoScripts = array(); +		$addedScripts = array_diff($this->_registeredPradoScripts,$this->_renderedPradoScripts); +		if(($packages=array_keys($addedScripts))!==array())  		{  			if (Prado::getApplication()->getMode()!==TApplicationMode::Debug)  			{ @@ -178,6 +187,7 @@ class TClientScriptManager extends TApplicationComponent  				}  				$writer->write(TJavaScript::renderScriptFiles($packagesUrl));  			} +			$this->_renderedPradoScripts = $this->_registeredPradoScripts;  		}  	} @@ -420,6 +430,7 @@ class TClientScriptManager extends TApplicationComponent  	 */  	public function registerHeadScriptFile($key,$url)  	{ +		$this->checkIfNotInRender();  		$this->_headScriptFiles[$key]=$url;  		$params=func_get_args(); @@ -433,6 +444,7 @@ class TClientScriptManager extends TApplicationComponent  	 */  	public function registerHeadScript($key,$script)  	{ +		$this->checkIfNotInRender();  		$this->_headScripts[$key]=$script;  		$params=func_get_args(); @@ -446,6 +458,7 @@ class TClientScriptManager extends TApplicationComponent  	 */  	public function registerScriptFile($key,$url)  	{ +		$this->checkIfNotInRender();  		$this->_scriptFiles[$key]=$url;  		$params=func_get_args(); @@ -459,6 +472,7 @@ class TClientScriptManager extends TApplicationComponent  	 */  	public function registerBeginScript($key,$script)  	{ +		$this->checkIfNotInRender();  		$this->_beginScripts[$key]=$script;  		$params=func_get_args(); @@ -486,6 +500,7 @@ class TClientScriptManager extends TApplicationComponent  	 */  	public function registerHiddenField($name,$value)  	{ +		$this->checkIfNotInRender();  		$this->_hiddenFields[$name]=$value;  		$params=func_get_args(); @@ -621,14 +636,30 @@ class TClientScriptManager extends TApplicationComponent  		$writer->write(TJavaScript::renderScriptBlocks($this->_headScripts));  	} +	public function renderScriptFilesBegin($writer) +	{ +		$this->renderScriptFilesInt($writer,true); +	} + +	public function renderScriptFilesEnd($writer) +	{ +		$this->renderScriptFilesInt($writer,false); +	} +  	/**  	 * @param THtmlWriter writer for the rendering purpose  	 */ -	public function renderScriptFiles($writer) +	public function renderScriptFilesInt($writer, $initial)  	{ -		$this->renderPradoScripts($writer); +		if ($initial) $this->_renderedScriptFiles = array(); +		$this->renderPradoScriptsInt($writer, $initial);  		if(!empty($this->_scriptFiles)) -			$writer->write(TJavaScript::renderScriptFiles($this->_scriptFiles)); +		{ +			$addedScripts = array_diff($this->_scriptFiles,$this->_renderedScriptFiles); +			if (count($addedScripts)>0) +				$writer->write(TJavaScript::renderScriptFiles($addedScripts)); +			$this->_renderedScriptFiles = $this->_scriptFiles; +		}  	}  	/** @@ -647,14 +678,26 @@ class TClientScriptManager extends TApplicationComponent  		$writer->write(TJavaScript::renderScriptBlocks($this->_endScripts));  	} +	public function renderHiddenFieldsBegin($writer) +	{ +		$this->renderHiddenFieldsInt($writer,true); +	} + +	public function renderHiddenFieldsEnd($writer) +	{ +		$this->renderHiddenFieldsInt($writer,false); +	} +  	/**  	 * @param THtmlWriter writer for the rendering purpose  	 */ -	public function renderHiddenFields($writer) -	{ +	protected function renderHiddenFieldsInt($writer, $initial) + 	{ +		if ($initial) $this->_renderedHiddenFields = array();  		$str='';  		foreach($this->_hiddenFields as $name=>$value)  		{ +			if (in_array($name,$this->_renderedHiddenFields)) continue;  			$id=strtr($name,':','_');  			if(is_array($value))  			{ @@ -665,10 +708,20 @@ class TClientScriptManager extends TApplicationComponent  			{  				$str.='<input type="hidden" name="'.$name.'" id="'.$id.'" value="'.THttpUtility::htmlEncode($value)."\" />\n";  			} +			$this->_renderedHiddenFields[] = $name;  		}  		if($str!=='')  			$writer->write("<div style=\"visibility:hidden;\">\n".$str."</div>\n");  	} + +	/** +	 * Checks whether page rendering has not begun yet +	 */ +	protected function checkIfNotInRender() +	{ +		if ($form = $this->_page->InFormRender) +			throw new Exception('Operation invalid when page is already rendering'); +	}  }  /** diff --git a/framework/Web/UI/TForm.php b/framework/Web/UI/TForm.php index 561b59cb..f1e8df5a 100644 --- a/framework/Web/UI/TForm.php +++ b/framework/Web/UI/TForm.php @@ -4,7 +4,7 @@   *
   * @author Qiang Xue <qiang.xue@gmail.com>
   * @link http://www.pradosoft.com/
 - * @copyright Copyright © 2005-2011 PradoSoft + * @copyright Copyright © 2005-2011 PradoSoft
   * @license http://www.pradosoft.com/license/
   * @version $Id$
   * @package System.Web.UI
 @@ -72,11 +72,6 @@ class TForm extends TControl  	public function render($writer)
  	{
  		$page=$this->getPage();
 -		$page->beginFormRender($writer);
 -		$htmlWriter = Prado::createComponent($this->GetResponse()->getHtmlWriterType(), new TTextWriter());
 -		$this->renderChildren( $htmlWriter );
 -		$content = $htmlWriter->flush();
 -		$page->endFormRender($writer);
  		$this->addAttributesToRender($writer);
  		$writer->renderBeginTag('form');
 @@ -84,18 +79,27 @@ class TForm extends TControl  		$cs=$page->getClientScript();
  		if($page->getClientSupportsJavaScript())
  		{
 -			$cs->renderHiddenFields($writer);
 -			$cs->renderScriptFiles($writer);
 +			$cs->renderHiddenFieldsBegin($writer);
 +			$cs->renderScriptFilesBegin($writer);
  			$cs->renderBeginScripts($writer);
 -			$writer->write($content);
 -
 + 			$page->beginFormRender($writer);
 + 			$this->renderChildren($writer);
 +			$cs->renderHiddenFieldsEnd($writer);
 + 			$page->endFormRender($writer);
 + 
 +			$cs->renderScriptFilesEnd($writer);
  			$cs->renderEndScripts($writer);
  		}
  		else
  		{
 -			$cs->renderHiddenFields($writer);
 -			$writer->write($content);
 +			$cs->renderHiddenFieldsBegin($writer);
 +
 +			$page->beginFormRender($writer);
 +			$this->renderChildren($writer);
 +			$page->endFormRender($writer);
 +
 +			$cs->renderHiddenFieldsEnd($writer);
  		}
  		$writer->renderEndTag();
 diff --git a/framework/Web/UI/THtmlWriter.php b/framework/Web/UI/THtmlWriter.php index e90ca8e8..beb439b8 100644 --- a/framework/Web/UI/THtmlWriter.php +++ b/framework/Web/UI/THtmlWriter.php @@ -4,7 +4,7 @@   *
   * @author Qiang Xue <qiang.xue@gmail.com>
   * @link http://www.pradosoft.com/
 - * @copyright Copyright © 2005-2011 PradoSoft + * @copyright Copyright © 2005-2011 PradoSoft
   * @license http://www.pradosoft.com/license/
   * @version $Id$
   * @package System.Web.UI
 @@ -181,6 +181,7 @@ class THtmlWriter extends TApplicationComponent implements ITextWriter  	/**
  	 * Flushes the rendering result.
  	 * This will invoke the underlying writer's flush method.
 +	 * @return string the content being flushed
  	 */
  	public function flush()
  	{
 diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php index 43b2f421..f3060dcc 100644 --- a/framework/Web/UI/TPage.php +++ b/framework/Web/UI/TPage.php @@ -167,6 +167,10 @@ class TPage extends TTemplateControl implements IPageEvents  	 * @var boolean whether client supports javascript
  	 */
  	private $_enableJavaScript=true;
 +	/**
 +	 * @var THtmlWriter current html render writer
 +	 */
 +	private $_writer;
  	/**
  	 * Constructor.
 @@ -186,6 +190,8 @@ class TPage extends TTemplateControl implements IPageEvents  	public function run($writer)
  	{
  		Prado::trace("Running page life cycles",'System.Web.UI.TPage');
 +		$this->_writer = $writer;
 +
  		$this->determinePostBackMode();
  		if($this->getIsPostBack())
 @@ -197,6 +203,8 @@ class TPage extends TTemplateControl implements IPageEvents  		}
  		else
  			$this->processNormalRequest($writer);
 +
 +		$this->_writer = null;
  	}
  	protected function processNormalRequest($writer)
 @@ -933,6 +941,14 @@ class TPage extends TTemplateControl implements IPageEvents  	}
  	/**
 +	 * @return boolean Whether form rendering is in progress
 +	 */
 +	public function getInFormRender()
 +	{
 +		return $this->_inFormRender;
 +	}
 +
 +	/**
  	 * Ensures the control is rendered within a form.
  	 * @param TControl the control to be rendered
  	 * @throws TConfigurationException if the control is outside of the form
 @@ -951,8 +967,8 @@ class TPage extends TTemplateControl implements IPageEvents  		if($this->_formRendered)
  			throw new TConfigurationException('page_form_duplicated');
  		$this->_formRendered=true;
 -		$this->_inFormRender=true;
  		$this->getClientScript()->registerHiddenField(self::FIELD_PAGESTATE,$this->getClientState());
 +		$this->_inFormRender=true;
  	}
  	/**
 @@ -1199,6 +1215,15 @@ class TPage extends TTemplateControl implements IPageEvents  			$this->_cachingStack=new TStack;
  		return $this->_cachingStack;
  	}
 +
 +	/**
 +	 * Flushes output
 +	 */
 +	public function flushWriter()
 +	{
 +		if ($this->_writer)
 +			$this->Response->write($this->_writer->flush());
 +	}
  }
 diff --git a/framework/Web/UI/WebControls/TBaseValidator.php b/framework/Web/UI/WebControls/TBaseValidator.php index c9917a2b..c90f4d9d 100644 --- a/framework/Web/UI/WebControls/TBaseValidator.php +++ b/framework/Web/UI/WebControls/TBaseValidator.php @@ -239,7 +239,6 @@ abstract class TBaseValidator extends TLabel implements IValidator  		{
  			$manager['FormID'] = $formID;
  			$options = TJavaScript::encode($manager);
 -			$scripts->registerPradoScript('validator');
  			$scripts->registerEndScript($scriptKey, "new Prado.ValidationManager({$options});");
  		}
  		if($this->getEnableClientScript())
 @@ -254,6 +253,8 @@ abstract class TBaseValidator extends TLabel implements IValidator  	{
  		parent::onPreRender($param);
  		$this->updateControlCssClass();
 +		if ($this->getEnableClientScript())
 +			$this->getPage()->getClientScript()->registerPradoScript('validator');
  	}
  	/**
 diff --git a/framework/Web/UI/WebControls/THtmlArea.php b/framework/Web/UI/WebControls/THtmlArea.php index 0af7a979..b11778bd 100644 --- a/framework/Web/UI/WebControls/THtmlArea.php +++ b/framework/Web/UI/WebControls/THtmlArea.php @@ -341,6 +341,20 @@ class THtmlArea extends TTextBox  	}
  	/**
 +	 * Registers clientscripts
 +	 *
 +	 * This method overrides the parent implementation and is invoked before render.
 +	 * @param mixed event parameter
 +	 */
 +	public function onPreRender($param)
 +	{
 +		parent::onPreRender($param);
 +		$this->loadJavascriptLibrary();
 +		if($this->getEnableCompression())
 +			$this->preLoadCompressedScript();
 +	}
 +
 +	/**
  	 * Adds attribute name-value pairs to renderer.
  	 * This method overrides the parent implementation by registering
  	 * additional javacript code.
 @@ -354,10 +368,6 @@ class THtmlArea extends TTextBox  			$this->registerEditorClientScript($writer);
  		}
 -		$this->loadJavascriptLibrary();
 -		if($this->getEnableCompression())
 -			$this->preLoadCompressedScript();
 -
  		parent::addAttributesToRender($writer);
  	}
  | 
