From 0d42be79b9dfeaa7686fb7da11920af4eb0561d7 Mon Sep 17 00:00:00 2001 From: xue <> Date: Sat, 3 Dec 2005 04:42:14 +0000 Subject: --- framework/Web/Services/TPageService.php | 48 +- framework/Web/TAssetManager.php | 2 +- framework/Web/THiddenFieldPageStatePersister.php | 80 +++ framework/Web/TThemeManager.php | 15 +- framework/Web/UI/TClientScriptManager.php | 174 +++---- framework/Web/UI/TControl.php | 2 +- .../Web/UI/THiddenFieldPageStatePersister.php | 37 +- framework/Web/UI/TPage.php | 567 +++++++++++++-------- framework/Web/UI/WebControls/TButton.php | 2 +- framework/Web/UI/WebControls/TCheckBox.php | 4 +- framework/Web/UI/WebControls/TImageButton.php | 2 +- 11 files changed, 604 insertions(+), 329 deletions(-) create mode 100644 framework/Web/THiddenFieldPageStatePersister.php (limited to 'framework/Web') diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php index 6ef07d03..078f8706 100644 --- a/framework/Web/Services/TPageService.php +++ b/framework/Web/Services/TPageService.php @@ -17,6 +17,7 @@ Prado::using('System.Web.UI.TPage'); Prado::using('System.Web.TTemplateManager'); Prado::using('System.Web.TThemeManager'); Prado::using('System.Web.TAssetManager'); +Prado::using('System.Web.THiddenFieldPageStatePersister'); /** * TPageService class. @@ -101,6 +102,10 @@ class TPageService extends TComponent implements IService * @var string requested page type */ private $_pageType; + /** + * @var TPage the requested page + */ + private $_page=null; /** * @var array list of initial page property values */ @@ -125,6 +130,10 @@ class TPageService extends TComponent implements IService * @var TTemplateManager template manager */ private $_templateManager=null; + /** + * @var IPageStatePersister page state persister + */ + private $_pageStatePersister=null; /** * Initializes the service. @@ -311,6 +320,27 @@ class TPageService extends TComponent implements IService $this->_themeManager=$value; } + /** + * @return IPageStatePersister page state persister + */ + public function getPageStatePersister() + { + if(!$this->_pageStatePersister) + { + $this->_pageStatePersister=new THiddenFieldPageStatePersister; + $this->_pageStatePersister->init($this->_application,null); + } + return $this->_pageStatePersister; + } + + /** + * @param IPageStatePersister page state persister + */ + public function setPageStatePersister(IPageStatePersister $value) + { + $this->_pageStatePersister=$value; + } + /** * @return string the requested page path */ @@ -319,6 +349,14 @@ class TPageService extends TComponent implements IService return $this->_pagePath; } + /** + * @return TPage the requested page + */ + public function getRequestedPage() + { + return $this->_page; + } + /** * @return string default page path to be served if no explicit page is request */ @@ -391,11 +429,11 @@ class TPageService extends TComponent implements IService } } if(class_exists($className,false)) - $page=new $className($this->_properties); + $this->_page=new $className($this->_properties); else throw new THttpException(404,'pageservice_page_unknown',$this->_pageType); $writer=$this->_application->getResponse()->createHtmlWriter(); - $page->run($writer); + $this->_page->run($writer); $writer->flush(); } @@ -624,7 +662,7 @@ class TPageConfiguration extends TComponent foreach($modulesNode->getElementsByTagName('module') as $node) { $properties=$node->getAttributes(); - $type=$properties->remove('type'); + $type=$properties->remove('class'); if(($id=$properties->itemAt('id'))===null) throw new TConfigurationException('pageserviceconf_module_invalid',$configPath); if(isset($this->_modules[$id])) @@ -660,7 +698,7 @@ class TPageConfiguration extends TComponent $properties=$node->getAttributes(); if(($id=$properties->remove('id'))===null) throw new TConfigurationException('pageserviceconf_parameter_invalid',$configPath); - if(($type=$properties->remove('type'))===null) + if(($type=$properties->remove('class'))===null) $this->_parameters[$id]=$node->getValue(); else $this->_parameters[$id]=array($type,$properties->toArray()); @@ -704,7 +742,7 @@ class TPageConfiguration extends TComponent foreach($pagesNode->getElementsByTagName('page') as $node) { $properties=$node->getAttributes(); - $type=$properties->remove('type'); + $type=$properties->remove('class'); $id=$properties->itemAt('id'); if($id===null || $type===null) throw new TConfigurationException('pageserviceconf_page_invalid',$configPath); diff --git a/framework/Web/TAssetManager.php b/framework/Web/TAssetManager.php index 3e7df967..e2b9f9a8 100644 --- a/framework/Web/TAssetManager.php +++ b/framework/Web/TAssetManager.php @@ -58,7 +58,7 @@ class TAssetManager extends TComponent implements IModule /** * @var string module ID */ - private $_id; + private $_id='asset'; /** * @var boolean whether to use timestamp checking to ensure files are published with up-to-date versions. */ diff --git a/framework/Web/THiddenFieldPageStatePersister.php b/framework/Web/THiddenFieldPageStatePersister.php new file mode 100644 index 00000000..3d305668 --- /dev/null +++ b/framework/Web/THiddenFieldPageStatePersister.php @@ -0,0 +1,80 @@ +_application=$application; + } + + /** + * @return string id of this module + */ + public function getID() + { + return $this->_id; + } + + /** + * @param string id of this module + */ + public function setID($value) + { + $this->_id=$value; + } + + public function save($state) + { + $data=Prado::serialize($state); + $hmac=$this->computeHMAC($data,$this->getKey()); + if(function_exists('gzuncompress') && function_exists('gzcompress')) + $data=gzcompress($hmac.$data); + else + $data=$hmac.$data; + $this->_application->getService()->getRequestedPage()->saveStateField($data); + } + + public function load() + { + $str=$this->_application->getService()->getRequestedPage()->loadStateField(); + if($str==='') + return null; + if(function_exists('gzuncompress') && function_exists('gzcompress')) + $data=gzuncompress($str); + else + $data=$str; + if($data!==false && strlen($data)>32) + { + $hmac=substr($data,0,32); + $state=substr($data,32); + if($hmac===$this->computeHMAC($state,$this->getKey())) + return Prado::unserialize($state); + } + throw new Exception('viewstate data is corrupted.'); + } + + private function getKey() + { + return 'abcdefe'; + } + + private function computeHMAC($data,$key) + { + if (strlen($key) > 64) + $key = pack('H32', md5($key)); + else if (strlen($key) < 64) + $key = str_pad($key, 64, "\0"); + return md5((str_repeat("\x5c", 64) ^ substr($key, 0, 64)) . pack('H32', md5((str_repeat("\x36", 64) ^ substr($key, 0, 64)) . $data))); + } +} + +?> \ No newline at end of file diff --git a/framework/Web/TThemeManager.php b/framework/Web/TThemeManager.php index 0a54cf8e..504e8ecb 100644 --- a/framework/Web/TThemeManager.php +++ b/framework/Web/TThemeManager.php @@ -45,7 +45,7 @@ class TThemeManager extends TComponent implements IModule /** * @var string module ID */ - private $_id; + private $_id='theme'; /** * @var boolean whether this module has been initialized */ @@ -212,6 +212,10 @@ class TTheme extends TComponent * @var array list of skins for the theme */ private $_skins=null; + /** + * @var string theme name + */ + private $_name=''; /** * Constructor. @@ -223,6 +227,7 @@ class TTheme extends TComponent public function __construct($application,$themePath,$themeUrl) { $this->_themeUrl=$themeUrl; + $this->_name=basename($themePath); if(($cache=$application->getCache())!==null) { $array=$cache->get(self::THEME_CACHE_PREFIX.$themePath); @@ -283,6 +288,14 @@ class TTheme extends TComponent } } + /** + * @return string theme name + */ + public function getName() + { + return $this->_name; + } + /** * Applies the theme to a particular control. * The control's class name and SkinID value will be used to diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 7bbbbdfa..d4aea650 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -33,7 +33,13 @@ class TPostBackOptions extends TComponent class TClientScriptManager extends TComponent { - const POSTBACK_FUNC='__doPostBack'; + const SCRIPT_DIR='Web/Javascripts/js'; + const POSTBACK_FUNC='Prado.PostBack.perform'; + const POSTBACK_OPTIONS='Prado.PostBack.Options'; + const FIELD_POSTBACK_TARGET='PRADO_POSTBACK_TARGET'; + const FIELD_POSTBACK_PARAMETER='PRADO_POSTBACK_PARAMETER'; + const FIELD_LASTFOCUS='PRADO_LASTFOCUS'; + const FIELD_PAGE_STATE='PRADO_PAGE_STATE'; private $_owner; private $_hiddenFields=array(); private $_scriptBlocks=array(); @@ -48,78 +54,89 @@ class TClientScriptManager extends TComponent $this->_owner=$owner; } - public function getPostBackEventReference($options,$javascriptPrefix=true) + public function getPostBackEventReference($control,$parameter='',$options=null,$javascriptPrefix=true) { - $str=$javascriptPrefix?'javascript:':''; - if($options->AutoPostBack) - $str.="setTimeout('"; - if(!$options->PerformValidation && !$options->TrackFocus && $options->ClientSubmit && $options->ActionUrl==='') + if($options) { - $this->registerPostBackScript(); - $postback=self::POSTBACK_FUNC.'(\''.$options->TargetControl->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($options->Argument).'\')'; - if($options->AutoPostBack) + $flag=false; + $opt='new '.self::POSTBACK_OPTIONS.'('; + if($options->PerformValidation) { - $str.=THttpUtility::quoteJavaScriptString($postback); - $str.="',0)"; + $flag=true; + $this->registerValidationScript(); + $opt.='true,'; } else - $str.=$postback; - return $str; - } - $str.='WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("'; - $str.=$options->TargetControl->getUniqueID().'", '; - if(($arg=$options->Argument)==='') - $str.='"", '; - else - $str.='"'.THttpUtility::quoteJavaScriptString($arg).'", '; - $flag=false; - if($options->PerformValidation) - { - $flag=true; - $str.='true, '; - } - else - $str.='false, '; - if($options->ValidationGroup!=='') - { - $flag=true; - $str.='"'.$options->ValidationGroup.'", '; - } - else - $str.='"", '; - if($options->ActionUrl!=='') - { - $flag=true; - $this->_owner->setContainsCrossPagePost(true); - $str.='"'.THttpUtility::quoteJavaScriptString($options->ActionUrl).'", '; - } - else - $str.='"", '; - if($options->TrackFocus) - { - $this->_owner->registerFocusScript(); - $flag=true; - $str.='true, '; - } - else - $str.='false, '; - if($options->ClientSubmit) - { - $flag=true; - $this->_owner->registerPostBackScript(); - $str.='true))'; - } - else - $str.='false))'; - if($options->AutoPostBack) - $str.="', 0)"; - if($flag) - { - $this->_owner->registerWebFormsScript(); - return $str; + $opt.='false,'; + if($options->ValidationGroup!=='') + { + $flag=true; + $opt.='"'.$options->ValidationGroup.'",'; + } + else + $opt.='"",'; + if($options->ActionUrl!=='') + { + $flag=true; + $this->_owner->setCrossPagePostBack(true); + $opt.='"'.THttpUtility::quoteJavaScriptString($options->ActionUrl).'",'; + } + else + $opt.='"",'; + if($options->TrackFocus) + { + $flag=true; + $this->registerFocusScript(); + $opt.='true,'; + } + else + $opt.='false,'; + if($options->ClientSubmit) + { + $flag=true; + $opt.='true)'; + } + else + $opt.='false)'; + //if(!$flag) + // return ''; } else - return ''; + $opt='null'; + $this->registerPostBackScript(); + $formID=$this->_owner->getForm()->getUniqueID(); + $postback=self::POSTBACK_FUNC.'(\''.$formID.'\',\''.$control->getUniqueID().'\',\''.THttpUtility::quoteJavaScriptString($parameter).'\','.$opt.')'; + if($options && $options->AutoPostBack) + $postback='setTimeout(\''.THttpUtility::quoteJavaScriptString($postback).'\',0)'; + return $javascriptPrefix?'javascript:'.$postback:$postback; + } + + protected function registerPostBackScript() + { + $this->registerHiddenField(self::FIELD_POSTBACK_TARGET,''); + $this->registerHiddenField(self::FIELD_POSTBACK_PARAMETER,''); + $am=$this->_owner->getService()->getAssetManager(); + $url=$am->publishFilePath(Prado::getFrameworkPath().'/'.self::SCRIPT_DIR.'/base.js'); + $this->registerScriptInclude('prado:base',$url); + } + + public function registerFocusScript() + { + // need Focus.js + } + + public function registerScrollScript() + { + $this->registerHiddenField(self::FIELD_SCROLL_X,$this->_owner->getScrollPositionX()); + $this->registerHiddenField(self::FIELD_SCROLL_Y,$this->_owner->getScrollPositionY()); + /* + this.ClientScript.RegisterStartupScript(typeof(Page), "PageScrollPositionScript", "\r\ntheForm.oldSubmit = theForm.submit;\r\ntheForm.submit = WebForm_SaveScrollPositionSubmit;\r\n\r\ntheForm.oldOnSubmit = theForm.onsubmit;\r\ntheForm.onsubmit = WebForm_SaveScrollPositionOnSubmit;\r\n" + (this.IsPostBack ? "\r\ntheForm.oldOnLoad = window.onload;\r\nwindow.onload = WebForm_RestoreScrollPosition;\r\n" : string.Empty), true); + need base.js + */ + } + + public function registerValidationScript() + { } public function isHiddenFieldRegistered($key) @@ -226,11 +243,14 @@ class TClientScriptManager extends TComponent public function renderStartupScripts($writer) { + $str=''; + foreach($this->_scriptIncludes as $include) + $str.="\n"; if(count($this->_startupScripts)) { - $str="\n\n"; $writer->write($str); } @@ -292,24 +312,6 @@ class TClientScriptManager extends TComponent public void ValidateEvent(string uniqueId, string argument); public function getCallbackEventReference() */ - - public function registerPostBackScript() - { - $this->registerHiddenField('__EVENTTARGET',''); - $this->registerHiddenField('__EVENTPARAM',''); - $id=$this->_owner->getForm()->getUniqueID(); - $script=<<registerStartupScript('form',$script); - } } ?> \ No newline at end of file diff --git a/framework/Web/UI/TControl.php b/framework/Web/UI/TControl.php index a3c031f4..0e601386 100644 --- a/framework/Web/UI/TControl.php +++ b/framework/Web/UI/TControl.php @@ -983,7 +983,7 @@ class TControl extends TComponent if($this->_stage_stage=self::CS_CHILD_INITIALIZED; - if(($page=$this->getPage()) && $page->getContainsTheme() && $this->getEnableTheming() && !($this->_flags & self::IS_SKIN_APPLIED)) + if(($page=$this->getPage()) && $this->getEnableTheming() && !($this->_flags & self::IS_SKIN_APPLIED)) { $page->applyControlSkin($this); $this->_flags |= self::IS_SKIN_APPLIED; diff --git a/framework/Web/UI/THiddenFieldPageStatePersister.php b/framework/Web/UI/THiddenFieldPageStatePersister.php index 24ef5491..3d305668 100644 --- a/framework/Web/UI/THiddenFieldPageStatePersister.php +++ b/framework/Web/UI/THiddenFieldPageStatePersister.php @@ -1,14 +1,35 @@ _application=$application; + } + + /** + * @return string id of this module + */ + public function getID() + { + return $this->_id; + } - public function __construct($page) + /** + * @param string id of this module + */ + public function setID($value) { - $this->_page=$page; + $this->_id=$value; } public function save($state) @@ -19,12 +40,12 @@ class THiddenFieldPageStatePersister extends TPageStatePersister $data=gzcompress($hmac.$data); else $data=$hmac.$data; - $this->_page->saveStateField($data); + $this->_application->getService()->getRequestedPage()->saveStateField($data); } public function load() { - $str=$this->_page->loadStateField(); + $str=$this->_application->getService()->getRequestedPage()->loadStateField(); if($str==='') return null; if(function_exists('gzuncompress') && function_exists('gzcompress')) diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php index 902a0212..9eb50cde 100644 --- a/framework/Web/UI/TPage.php +++ b/framework/Web/UI/TPage.php @@ -5,19 +5,44 @@ Prado::using('System.Web.UI.WebControls.*'); class TPage extends TTemplateControl { + /** + * @var TApplication application instance + */ private $_application; - private $_contentTemplateCollection=null; + /** + * @var TPageService page service instance + */ + private $_pageService; + /** + * @var string template file name + */ + private $_templateFile=null; + /** + * @var array list of registered validators + */ + private $_validators=array(); + /** + * @var boolean if validation has been performed + */ + private $_validated=false; + /** + * @var TTheme page theme + */ + private $_theme=null; + /** + * @var TTheme page stylesheet theme + */ + private $_styleSheet=null; + /** + * @var TClientScriptManager client script manager + */ + private $_clientScript=null; + private $_maxPageStateFieldLength=10; private $_enableViewStateMac=true; private $_performPreRendering=true; private $_performRendering=true; - private $_supportsStyleSheet=true; - private $_theme=null; - private $_themeName=''; - private $_styleSheet=null; - private $_styleSheetName=''; - private $_clientScript=null; private $_form=null; private $_formRendered=false; private $_inFormRender=false; @@ -34,18 +59,20 @@ class TPage extends TTemplateControl private $_controlsRequiringPostBack=array(); private $_registeredControlThatRequireRaiseEvent=null; private $_registeredControlsThatRequirePostBack=null; - private $_validators=array(); - private $_validated=false; private $_autoPostBackControl=null; private $_webFormsScriptRendered=false; private $_requireWebFormsScript=false; private static $_systemPostFields=array('__EVENTTARGET','__EVENTPARAM','__STATE','__PREVPAGE','__CALLBACKID','__CALLBACKPARAM','__LASTFOCUS'); - private $_contents=array(); - private $_templateFile=null; + /** + * Constructor. + * If initial property values are given, they will be set to the page. + * @param array initial property values for the page. + */ public function __construct($initProperties=null) { $this->_application=Prado::getApplication(); + $this->_pageService=$this->_application->getService(); $this->setPage($this); if(is_array($initProperties)) { @@ -56,7 +83,9 @@ class TPage extends TTemplateControl } /** - * Loads and parses the control template + * Loads and parses the page template. + * This method overrides the parent implementation by allowing loading + * a page template from a specified template file. * @return ITemplate the parsed template structure */ protected function loadTemplate() @@ -65,125 +94,376 @@ class TPage extends TTemplateControl return parent::loadTemplate(); else { - $template=Prado::getApplication()->getService()->getTemplateManager()->getTemplateByFileName(Prado::getPathOfNamespace($this->_templateFile,'.tpl')); + $template=$this->_pageService->getTemplateManager()->getTemplateByFileName($this->_templateFile); $this->setTemplate($template); return $template; } } + /** + * @return string the user-specified template file, defaults to null. + */ public function getTemplateFile() { return $this->_templateFile; } + /** + * Sets the user-specified template file. + * The template file must be specified in a namespace format. + * @param string the user-specified template file. + * @throws TInvalidDataValueException if the file is not in namespace format. + */ public function setTemplateFile($value) { - $this->_templateFile=$value; + if(($templateFile=Prado::getPathOfNamespace($value,TTemplateManager::TEMPLATE_FILE_EXT))===null) + throw new TInvalidDataValueException('page_templatefile_invalid',$value); + else + $this->_templateFile=$templateFile; } - final public function setForm($form) + /** + * Registers a TForm instance to the page. + * Note, a page can contain at most one TForm instance. + * @param TForm the form on the page + * @throws TInvalidOperationException if this method is invoked twice or more. + */ + public function setForm(TForm $form) { - $this->_form=$form; + if($this->_form===null) + $this->_form=$form; + else + throw new TInvalidOperationException('page_form_duplicated'); } - final public function getForm() + /** + * @return TForm the form on the page + */ + public function getForm() { return $this->_form; } - public function validate($validationGroup='') + /** + * Returns a list of registered validators. + * If validation group is specified, only the validators in that group will be returned. + * @param string validation group + * @return TList registered validators + */ + public function getValidators($validationGroup='') { - $this->_validated=true; + if(!$this->_validators) + $this->_validators=new TList; if($validationGroup==='') - { - foreach($this->_validators as $validator) - $validator->validate(); - } + return $this->_validators; else { + $list=new TList; foreach($this->_validators as $validator) if($validator->getValidationGroup()===$validationGroup) - $validator->validate(); + $list->add($validator); + return $list; } } - public function RegisterEnabledControl($control) + /** + * Performs input validation. + * This method will invoke the registered validators to perform the actual validation. + * If validation group is specified, only the validators in that group will be invoked. + * @param string validation group + */ + public function validate($validationGroup='') { - $this->getEna.EnabledControls.Add(control); + $this->_validated=true; + if($this->_validators && $this->_validators->getCount()) + { + if($validationGroup==='') + { + foreach($this->_validators as $validator) + $validator->validate(); + } + else + { + foreach($this->_validators as $validator) + if($validator->getValidationGroup()===$validationGroup) + $validator->validate(); + } + } } - - /** - * @internal + * Returns whether user input is valid or not. + * This method must be invoked after {@link validate} is called. + * @return boolean whether the user input is valid or not. + * @throws TInvalidOperationException if {@link validate} is not invoked yet. */ - public function registerPostBackScript() + public function getIsValid() { - if($this->getClientSupportsJavaScript() && !$this->_postBackScriptRendered) + if($this->_validated) { - if(!$this->_requirePostBackScript) + if($this->_validators && $this->_validators->getCount()) { - $this->getClientScript()->registerHiddenField('__EVENTTARGET',''); - $this->getClientScript()->registerHiddenField('__EVENTPARAM',''); - $this->_requirePostBackScript=true; + foreach($this->_validators as $validator) + if(!$validator->getIsValid()) + return false; } + return true; } + else + throw new TInvalidOperationException('page_isvalid_unknown'); } - public function registerWebFormsScript() + /** + * @return TTheme the theme used for the page. Defaults to null. + */ + public function getTheme() { - if($this->getClientSupportsJavaScript() && !$this->_webFormsScriptRendered) - { - $this->registerPostBackScript(); - $this->_requireWebFormsScript=true; - } + if(is_string($this->_theme)) + $this->_theme=$this->_pageService->getThemeManager()->getTheme($this->_theme); + return $this->_theme; } + /** + * Sets the theme to be used for the page. + * @param string|TTheme the theme name or the theme object to be used for the page. + * @throws TInvalidDataTypeException if the parameter is neither a string nor a TTheme object + */ + public function setTheme($value) + { + $this->_theme=$value; + } - public function ensureRenderInForm($control) + + /** + * @return TTheme the stylesheet theme used for the page. Defaults to null. + */ + public function getStyleSheetTheme() { - if(!$this->_inFormRender) - throw new THttpException('control_not_in_form',$control->getUniqueID()); + if(is_string($this->_styleSheet)) + $this->_styleSheet=$this->_pageService->getThemeManager()->getTheme($this->_styleSheet); + return $this->_styleSheet; } /** - * @internal + * Sets the stylesheet theme to be used for the page. + * @param string|TTheme the stylesheet theme name or the stylesheet theme object to be used for the page. + * @throws TInvalidDataTypeException if the parameter is neither a string nor a TTheme object */ - final protected function addContentTemplate($name,$template) + public function setStyleSheetTheme($value) { - if(!$this->_contentTemplateCollection) - $this->_contentTemplateCollection=new TMap; - if($this->_contentTemplateCollection->has($name)) - throw new Exception("Content '$name' duplicated."); - $this->_contentTemplateCollection->add($name,$template); + $this->_styleSheet=$value; } /** - * @internal + * Applies a skin in the current theme to a control. + * This method should only be used by framework developers. + * @param TControl a control to be applied skin with + */ + public function applyControlSkin($control) + { + if(($theme=$this->getTheme())!==null) + $theme->applySkin($control); + } + + /** + * Applies a stylesheet skin in the current theme to a control. + * This method should only be used by framework developers. + * @param TControl a control to be applied stylesheet skin with + */ + public function applyControlStyleSheet($control) + { + if(($theme=$this->getStyleSheetTheme())!==null) + $theme->applySkin($control); + } + + /** + * @return TClientScriptManager client script manager + */ + public function getClientScript() + { + if(!$this->_clientScript) + $this->_clientScript=new TClientScriptManager($this); + return $this->_clientScript; + } + + /** + * Raises PreInit event. + * This method is invoked right before {@link onInit Init} stage. + * You may override this method to provide additional initialization that + * should be done before {@link onInit Init} (e.g. setting {@link setTheme Theme} or + * {@link setStyleSheetTheme StyleSheetTheme}). + * Remember to call the parent implementation to ensure PreInit event is raised. + * @param mixed event parameter + */ + protected function onPreInit($param) + { + $this->raiseEvent('PreInit',$this,$param); + } + + /** + * Raises InitComplete event. + * This method is invoked right after {@link onInit Init} stage and before {@link onLoad Load} stage. + * You may override this method to provide additional initialization that + * should be done after {@link onInit Init}. + * Remember to call the parent implementation to ensure InitComplete event is raised. + * @param mixed event parameter + */ + protected function onInitComplete($param) + { + $this->raiseEvent('InitComplete',$this,$param); + } + + /** + * Raises PreLoad event. + * This method is invoked right before {@link onLoad Load} stage. + * You may override this method to provide additional page loading logic that + * should be done before {@link onLoad Load}. + * Remember to call the parent implementation to ensure PreLoad event is raised. + * @param mixed event parameter + */ + protected function onPreLoad($param) + { + $this->raiseEvent('PreLoad',$this,$param); + } + + /** + * Raises LoadComplete event. + * This method is invoked right after {@link onLoad Load} stage. + * You may override this method to provide additional page loading logic that + * should be done after {@link onLoad Load}. + * Remember to call the parent implementation to ensure LoadComplete event is raised. + * @param mixed event parameter + */ + protected function onLoadComplete($param) + { + $this->raiseEvent('LoadComplete',$this,$param); + } + + /** + * Raises PreRenderComplete event. + * This method is invoked right after {@link onPreRender PreRender} stage. + * You may override this method to provide additional preparation for page rendering + * that should be done after {@link onPreRender PreRender}. + * Remember to call the parent implementation to ensure PreRenderComplete event is raised. + * @param mixed event parameter + */ + protected function onPreRenderComplete($param) + { + $this->raiseEvent('PreRenderComplete',$this,$param); + } + + /** + * Raises SaveStateComplete event. + * This method is invoked right after {@link onSaveState SaveState} stage. + * You may override this method to provide additional logic after page state is saved. + * Remember to call the parent implementation to ensure SaveStateComplete event is raised. + * @param mixed event parameter + */ + protected function onSaveStateComplete($param) + { + $this->raiseEvent('SaveStateComplete',$this,$param); + } + + /** + * Determines whether the current page request is a postback. + * Call {@link getIsPostBack} to get the result. + */ + private function determinePostBackMode() + { + $postData=$this->_application->getRequest()->getItems(); + if($postData->contains(TClientScriptManager::FIELD_PAGE_STATE) || $postData->contains(TClientScriptManager::FIELD_POSTBACK_TARGET)) + $this->_postData=$postData; + } + + /** + * @return boolean whether the current page request is a postback */ - final public function applyControlSkin($control) + public function getIsPostBack() { - if($this->_theme) - $this->_theme->applySkin($control); + return $this->_postData!==null; } + /** + * @return IPageStatePersister page state persister + */ + protected function getPageStatePersister() + { + return $this->_pageService->getPageStatePersister(); + } + + /** + * Loads page state from persistent storage. + */ + protected function loadPageState() + { + $state=$this->getPageStatePersister()->load(); + $this->loadStateRecursive($state,$this->getEnableViewState()); + } + + /** + * Saves page state from persistent storage. + */ + protected function savePageState() + { + $state=&$this->saveStateRecursive($this->getEnableViewState()); + $this->getPageStatePersister()->save($state); + } + + /** + * Loads page state data from a hidden field. + * @return string page state data stored in hidden field + */ + public function loadStateField() + { + return base64_decode($this->_postData->itemAt(TClientScriptManager::FIELD_PAGE_STATE)); + } + + /** + * Saves page state data in a hidden field. + * @param string string representation of the page state data. + */ + public function saveStateField($state) + { + $this->getClientScript()->registerHiddenField(TClientScriptManager::FIELD_PAGE_STATE,base64_encode($state)); + } + + public function RegisterEnabledControl($control) + { + $this->getEna.EnabledControls.Add(control); + } + + + /** * @internal */ - final public function applyControlStyleSheet($control) + public function registerPostBackScript() { - if($this->_styleSheet) + if($this->getClientSupportsJavaScript() && !$this->_postBackScriptRendered) { - $this->_styleSheet->applySkin($control); - return true; + if(!$this->_requirePostBackScript) + { + $this->getClientScript()->registerHiddenField('__EVENTTARGET',''); + $this->getClientScript()->registerHiddenField('__EVENTPARAM',''); + $this->_requirePostBackScript=true; + } } - else - return false; } - private function renderStateFields($writer) + public function registerWebFormsScript() { - $writer->write("\n_pageState."\" />\n"); + if($this->getClientSupportsJavaScript() && !$this->_webFormsScriptRendered) + { + $this->registerPostBackScript(); + $this->_requireWebFormsScript=true; + } + } + + + public function ensureRenderInForm($control) + { + if(!$this->_inFormRender) + throw new THttpException('control_not_in_form',$control->getUniqueID()); } private function renderPostBackScript($writer) @@ -232,7 +512,6 @@ EOD; $this->_inFormRender=true; $this->getClientScript()->renderHiddenFields($writer); - //$this->renderStateFields($writer); if($this->getClientSupportsJavaScript()) { /* @@ -280,13 +559,6 @@ EOD; $this->_inFormRender=false; } - final public function getClientScript() - { - if(!$this->_clientScript) - $this->_clientScript=new TClientScriptManager($this); - return $this->_clientScript; - } - final public function getClientOnSubmitEvent() { // todo @@ -296,40 +568,10 @@ EOD; return ''; } - final public function getValidators($validationGroup='') - { - if(!$this->_validators) - $this->_validators=new TList; - if($validationGroup==='') - return $this->_validators; - $list=new TList; - foreach($this->_validators as $validator) - if($validator->getValidationGroup()===$validationGroup) - $list->add($validator); - return $list; - } - protected function initializeCulture() { } - /** - * @internal - */ - public function initializeStyleSheet() - { - if($this->_styleSheet!=='') - $this->_styleSheet=new TTheme($this->_styleSheetName); - } - - private function initializeThemes() - { - if($this->_themeName!=='') - $this->_theme=$this->getService()->getThemeManager()->getTheme($this->_themeName); - if($this->_styleSheetName!=='') - $this->_styleSheet=$this->getService()->getThemeManager()->getTheme($this->_styleSheetName); - } - /** * @internal */ @@ -344,44 +586,6 @@ EOD; } } - protected function onInit($param) - { - parent::onInit($param);/* - if($this->_theme) - $this->_theme->setStyleSheet(); - if($this->_styleSheet) - $this->_styleSheet->setStyleSheet();*/ - } - - protected function onInitComplete($param) - { - $this->raiseEvent('InitComplete',$this,$param); - } - - protected function onLoadComplete($param) - { - $this->raiseEvent('LoadComplete',$this,$param); - } - - protected function onPreInit($param) - { - $this->raiseEvent('PreInit',$this,$param); - } - - protected function onPreLoad($param) - { - $this->raiseEvent('PreLoad',$this,$param); - } - - protected function onPreRenderComplete($param) - { - $this->raiseEvent('PreRenderComplete',$this,$param); - } - - protected function onSaveStateComplete($param) - { - $this->raiseEvent('SaveStateComplete',$this,$param); - } final public function registerAsyncTask() { @@ -404,64 +608,6 @@ EOD; return $this->_application; } - public function loadStateField() - { - return base64_decode($this->_postData->itemAt('__STATE')); - } - - public function saveStateField($state) - { - $this->getClientScript()->registerHiddenField('__STATE',base64_encode($state)); - } - - protected function determinePostBackMode() - { - /* - $application=$this->getApplication(); - if($application->getPreventPostBack()) - return null; - */ - $postData=new TMap($this->_application->getRequest()->getItems()); - if($postData->itemAt('__STATE')!==null || $postData->itemAt('__EVENTTARGET')!==null) - return $postData; - else - return null; - } - - final public function getIsPostBack() - { - if($this->_postData) - { - if($this->_isCrossPagePostBack) - return true; - if($this->_previousPagePath!=='') - return false; - return !$this->_pageStateChanged; - } - else - return false; - } - - protected function getPageStatePersister() - { - require_once(PRADO_DIR.'/Web/UI/THiddenFieldPageStatePersister.php'); - return new THiddenFieldPageStatePersister($this); - } - - protected function loadPageState() - { - $persister=$this->getPageStatePersister(); - $state=$persister->load(); - $this->loadStateRecursive($state,$this->getEnableViewState()); - } - - protected function savePageState() - { - $state=&$this->saveStateRecursive($this->getEnableViewState()); - $persister=$this->getPageStatePersister(); - $persister->save($state); - } - protected function processPostData($postData,$beforeLoad) { $eventTarget=$postData->itemAt('__EVENTTARGET'); @@ -551,11 +697,10 @@ EOD; public function run($writer) { - $this->_postData=$this->determinePostBackMode(); + $this->determinePostBackMode(); $this->_restPostData=new TMap; $this->onPreInit(null); - $this->initializeThemes(); $this->_preInitWorkComplete=true; $this->initRecursive(null); @@ -587,30 +732,6 @@ EOD; $this->unloadRecursive(); } - public function getTheme() - { - return $this->_themeName; - } - - public function setTheme($value) - { - $this->_themeName=$value; - } - - public function getStyleSheetTheme() - { - return $this->_styleSheetName; - } - - public function setStyleSheetTheme($value) - { - $this->_styleSheetName=$value; - } - - public function getContainsTheme() - { - return $this->_theme!==null; - } } ?> \ No newline at end of file diff --git a/framework/Web/UI/WebControls/TButton.php b/framework/Web/UI/WebControls/TButton.php index 4eb8e093..6c423d84 100644 --- a/framework/Web/UI/WebControls/TButton.php +++ b/framework/Web/UI/WebControls/TButton.php @@ -78,7 +78,7 @@ class TButton extends TWebControl implements IPostBackEventHandler $onclick=$this->getOnClientClick(); if($onclick!=='') $onclick=rtrim($onclick,';').';'; - $onclick.=$page->getClientScript()->getPostBackEventReference($this->getPostBackOptions()); + $onclick.=$page->getClientScript()->getPostBackEventReference($this,'',$this->getPostBackOptions(),false); } else if($this->getEnabled()) // in this case, parent will not render 'disabled' $writer->addAttribute('disabled','disabled'); diff --git a/framework/Web/UI/WebControls/TCheckBox.php b/framework/Web/UI/WebControls/TCheckBox.php index 756fb2ea..7b9d4702 100644 --- a/framework/Web/UI/WebControls/TCheckBox.php +++ b/framework/Web/UI/WebControls/TCheckBox.php @@ -381,10 +381,10 @@ class TCheckBox extends TWebControl implements IPostBackDataHandler, IValidatabl $option->AutoPostBack=true; if(!empty($onclick)) $onclick=rtrim($onclick,';').';'; - $onclick.=$page->getClientScript()->getPostBackEventReference($option); + $onclick.=$page->getClientScript()->getPostBackEventReference($this,'',$option,false); } if(!empty($onclick)) - $writer->addAttribute('onclick',$onclick); + $writer->addAttribute('onclick','javascript:'.$onclick); if(($accesskey=$this->getAccessKey())!=='') $writer->addAttribute('accesskey',$accesskey); if(($tabindex=$this->getTabIndex())>0) diff --git a/framework/Web/UI/WebControls/TImageButton.php b/framework/Web/UI/WebControls/TImageButton.php index d715480d..b0fb5a8b 100644 --- a/framework/Web/UI/WebControls/TImageButton.php +++ b/framework/Web/UI/WebControls/TImageButton.php @@ -74,7 +74,7 @@ class TImageButton extends TImage implements IPostBackDataHandler, IPostBackEven $onclick=$this->getOnClientClick(); if($onclick!=='') $onclick=rtrim($onclick,';').';'; - $onclick.=$page->getClientScript()->getPostBackEventReference($this->getPostBackOptions()); + $onclick.=$page->getClientScript()->getPostBackEventReference($this,'',$this->getPostBackOptions(),false); } else if($this->getEnabled()) // in this case, parent will not render 'disabled' $writer->addAttribute('disabled','disabled'); -- cgit v1.2.3