From 817da66e1cb3548f728db9ff4a96e783ed7522b5 Mon Sep 17 00:00:00 2001 From: wei <> Date: Thu, 22 Jun 2006 11:55:46 +0000 Subject: Update callback adapter --- .../UI/ActiveControls/TActiveControlAdapter.php | 357 +++++++++++++++++++-- 1 file changed, 328 insertions(+), 29 deletions(-) (limited to 'framework/Web/UI/ActiveControls') diff --git a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php index de6310a6..e6e8585f 100644 --- a/framework/Web/UI/ActiveControls/TActiveControlAdapter.php +++ b/framework/Web/UI/ActiveControls/TActiveControlAdapter.php @@ -157,6 +157,14 @@ class TActiveControlAdapter extends TControlAdapter } parent::saveState(); } + + /** + * @return TCallbackPageStateTracker state tracker. + */ + public function getStateTracker() + { + return $this->_stateTracker; + } } /** @@ -168,87 +176,378 @@ class TActiveControlAdapter extends TControlAdapter * * @author Wei Zhuo * @version $Revision: $ Sun Jun 18 20:51:25 EST 2006 $ - * @package System + * @package System.Web.UI.ActiveControls * @since 3.0 */ class TCallbackPageStateTracker { - private $_states = array('Visible', 'Enabled', 'Attributes', 'Style', 'TabIndex', 'ToolTip', 'AccessKey'); + /** + * @var TMap new view state data + */ + private $_states; + /** + * @var TMap old view state data + */ private $_existingState; + /** + * @var TControl the control tracked + */ private $_control; + /** + * @var object null object. + */ private $_nullObject; - + + /** + * Constructor. Add a set of default states to track. + * @param TControl control to track. + */ public function __construct($control) { $this->_control = $control; $this->_existingState = new TMap; $this->_nullObject = new stdClass; + $this->_states = new TMap; + $this->addStatesToTrack(); } - public function trackChanges() + /** + * Add a list of view states to track. Each state is added + * to the StatesToTrack property with the view state name as key. + * The value should be an array with two enteries. The first entery + * is the name of the class that will calculate the state differences. + * The second entry is a php function/method callback that handles + * the changes in the viewstate. + */ + protected function addStatesToTrack() { - foreach($this->_states as $name) - $this->_existingState[$name] = $this->_control->getViewState($name); + $states = $this->getStatesToTrack(); + $states['Visible'] = array('TScalarDiff', array($this, 'updateVisible')); + $states['Enabled'] = array('TScalarDiff', array($this, 'updateEnabled')); + $states['Attributes'] = array('TMapCollectionDiff', array($this, 'updateAttributes')); + $states['Style'] = array('TStyleDiff', array($this, 'updateStyle')); + $states['TabIndex'] = array('TScalarDiff', array($this, 'updateTabIndex')); + $states['ToolTip'] = array('TScalarDiff', array($this, 'updateToolTip')); + $states['AccessKey'] = array('TScalarDiff', array($this, 'updateAccessKey')); } - protected function getChanges() + /** + * @return TMap list of viewstates to track. + */ + protected function getStatesToTrack() { - $diff = array(); - foreach($this->_states as $name) - { - $state = $this->_control->getViewState($name); - // echo " $name "; - $changes = $this->difference($state, $this->_existingState[$name]); - // echo " \n "; - if($changes !== $this->_nullObject) - $diff[$name] = $changes; - } - return $diff; + return $this->_states; } - - protected function difference($value1, $value2) + + /** + * Start tracking view state changes. The clone function on objects are called + * for those viewstate having an object as value. + */ + public function trackChanges() { -// var_dump($value1, $value2); - if(gettype($value1) === gettype($value2) - && $value1 === $value2) return $this->_nullObject; - return $value1; + foreach($this->_states as $name => $value) + { + $obj = $this->_control->getViewState($name); + $this->_existingState[$name] = is_object($obj) ? clone($obj) : $obj; + } } - public function respondToChanges() + /** + * @array list of viewstate and the changed data. + */ + protected function getChanges() { - foreach($this->getChanges() as $property => $value) + $changes = array(); + foreach($this->_states as $name => $details) { - $this->{'update'.$property}($value); + $new = $this->_control->getViewState($name); + $old = $this->_existingState[$name]; + if($new !== $old) + { + $diff = new $details[0]($new, $old, $this->_nullObject); + if(($change = $diff->getDifference()) !== $this->_nullObject) + $changes[] = array($details[1],array($change)); + } } + return $changes; + } + + /** + * For each of the changes call the corresponding change handlers. + */ + public function respondToChanges() + { + foreach($this->getChanges() as $change) + call_user_func_array($change[0], $change[1]); } + /** + * @return TCallbackClientScript callback client scripting + */ protected function client() { return $this->_control->getPage()->getCallbackClient(); } + /** + * Updates the tooltip. + * @param string new tooltip + */ protected function updateToolTip($value) { $this->client()->setAttribute($this->_control, 'title', $value); } + /** + * Updates the tab index. + * @param integer tab index + */ + protected function updateTabIndex($value) + { + $this->client()->setAttribute($this->_control, 'tabindex', $value); + } + + /** + * Updates the modifier access key + * @param string access key + */ + protected function updateAccessKey($value) + { + $this->client()->setAttribute($this->_control, 'accesskey', $value); + } + + /** + * Hides or shows the control on the client-side. The control must be + * already rendered on the client-side. + * @param boolean true to show the control, false to hide. + */ protected function updateVisible($visible) { - var_dump($visible); if($visible === false) $this->client()->hide($this->_control); else $this->client()->show($this->_control); } + /** + * Enables or Disables the control on the client-side. + * @param boolean true to enable the control, false to disable. + */ protected function updateEnabled($enable) { $this->client()->setAttribute($this->_control, 'disabled', $enable===false); } + /** + * Updates the CSS style on the control on the client-side. + * @param array list of new CSS style declarations. + */ protected function updateStyle($style) { - var_dump($style); + if(!is_null($style['CssClass'])) + $this->client()->setAttribute($this->_control, 'class', $style['CssClass']); + if(count($style['Style']) > 0) + $this->client()->setStyle($this->_control, $style['Style']); + } + + /** + * Updates/adds a list of attributes on the control. + * @param array list of attribute name-value pairs. + */ + protected function updateAttributes($attributes) + { + foreach($attributes as $name => $value) + $this->client()->setAttribute($this->_control, $name, $value); + } +} + +/** + * Calculates the viewstate changes during the request. + * + * @author Wei Zhuo + * @version $Revision: $ Thu Jun 22 02:50:45 EST 2006 $ + * @package System.Web.UI.ActiveControls + * @since 3.0 + */ +abstract class TViewStateDiff +{ + /** + * @var mixed updated viewstate + */ + protected $_new; + /** + * @var mixed viewstate value at the begining of the request. + */ + protected $_old; + /** + * @var object null value. + */ + protected $_null; + + /** + * Constructor. + * @param mixed updated viewstate value. + * @param mixed viewstate value at the begining of the request. + * @param object representing the null value. + */ + public function __construct($new, $old, $null) + { + $this->_new = $new; + $this->_old = $old; + $this->_null = $null; + } + + /** + * @return mixed view state changes, nullObject if no difference. + */ + public abstract function getDifference(); +} + +/** + * TScalarDiff class. + * + * Calculate the changes to a scalar value. + * + * @author Wei Zhuo + * @version $Revision: $ Thu Jun 22 02:54:42 EST 2006 $ + * @package System.Web.UI.ActiveControls + * @since 3.0 + */ +class TScalarDiff extends TViewStateDiff +{ + /** + * @return mixed update viewstate value. + */ + public function getDifference() + { + if(gettype($this->_new) === gettype($this->_old) + && $this->_new === $this->_old) + return $this->_null; + else + return $this->_new; + } +} + +/** + * TStyleDiff class. + * + * Calculates the changes to the Style properties. + * + * @author Wei Zhuo + * @version $Revision: $ Thu Jun 22 02:55:47 EST 2006 $ + * @package System.Web.UI.ActiveControls + * @since 3.0 + */ +class TStyleDiff extends TViewStateDiff +{ + /** + * @param TStyle control style + * @return array all the style properties combined. + */ + protected function getCombinedStyle($obj) + { + if(!($obj instanceof TStyle)) + return array(); + $style = $obj->getStyleFields(); + $style = array_merge($style,$this->getStyleFromString($obj->getCustomStyle())); + if($obj->hasFont()) + $style = array_merge($style, $this->getStyleFromString($obj->getFont()->toString())); + return $style; + } + + /** + * @param string CSS custom style string. + * @param array CSS style as name-value array. + */ + protected function getStyleFromString($string) + { + $style = array(); + if(!is_string($string)) return $style; + + foreach(explode(';',$string) as $sub) + { + $arr=explode(':',$sub); + if(isset($arr[1]) && trim($arr[0])!=='') + $style[trim($arr[0])] = trim($arr[1]); + } + return $style; + } + + /** + * @return string changes to the CSS class name. + */ + protected function getCssClassDiff() + { + if(is_null($this->_old)) + { + return !is_null($this->_new) && $this->_new->hasCssClass() + ? $this->_new->getCssClass() : null; + } + else + { + return $this->_old->getCssClass() !== $this->_new->getCssClass() ? + $this->_new->getCssClass() : null; + } + } + + /** + * @return array list of changes to the control style. + */ + protected function getStyleDiff() + { + $diff = array_diff_assoc( + $this->getCombinedStyle($this->_new), + $this->getCombinedStyle($this->_old)); + return count($diff) > 0 ? $diff : null; + } + + /** + * @return array list of changes to the control style and CSS class name. + */ + public function getDifference() + { + if(is_null($this->_new)) + return $this->_null; + else + { + $css = $this->getCssClassDiff(); + $style = $this->getStyleDiff(); + if(!is_null($css) || !is_null($style)) + return array('CssClass' => $css, 'Style' => $style); + else + $this->_null; + } + } +} + +/** + * TAttributesDiff class. + * + * Calculate the changes to attributes collection. + * + * @author Wei Zhuo + * @version $Revision: $ Thu Jun 22 02:54:42 EST 2006 $ + * @package System.Web.UI.ActiveControls + * @since 3.0 + */ +class TMapCollectionDiff extends TViewStateDiff +{ + /** + * @return array updates to the attributes collection. + */ + public function getDifference() + { + if(is_null($this->_old)) + { + return !is_null($this->_new) ? $this->_new->toArray() : $this->_null; + } + else + { + $new = $this->_new->toArray(); + $old = $this->_old->toArray(); + $diff = array_diff_assoc($new, $old); + return count($diff) > 0 ? $diff : $this->_null; + } } } -- cgit v1.2.3