diff options
-rw-r--r-- | framework/Exceptions/messages.txt | 9 | ||||
-rw-r--r-- | framework/Web/Javascripts/TJavaScript.php | 74 | ||||
-rw-r--r-- | framework/Web/THttpUtility.php | 12 | ||||
-rw-r--r-- | framework/Web/UI/TClientScriptManager.php | 9 | ||||
-rw-r--r-- | framework/Web/UI/THtmlWriter.php | 244 | ||||
-rw-r--r-- | framework/Web/UI/TPage.php | 2 | ||||
-rw-r--r-- | framework/Web/UI/TTemplateManager.php | 4 | ||||
-rw-r--r-- | framework/Web/UI/WebControls/TStyle.php | 3 | ||||
-rw-r--r-- | framework/core.php | 28 |
9 files changed, 225 insertions, 160 deletions
diff --git a/framework/Exceptions/messages.txt b/framework/Exceptions/messages.txt index dc5024a7..481bb42d 100644 --- a/framework/Exceptions/messages.txt +++ b/framework/Exceptions/messages.txt @@ -151,6 +151,15 @@ templatecontrol_mastercontrol_invalid = Master control must be of type TTemplate templatecontrol_contentid_duplicated = TContent ID '%s' is duplicated.
templatecontrol_placeholderid_duplicated= TContentPlaceHolder ID '%s' is duplicated.
+page_form_duplicated = A page can contain at most one TForm. Use regular HTML form tags for the rest forms.
+page_isvalid_unknown = TPage.IsValid has not been evaluated yet.
+page_postbackcontrol_invalid = Unable to determine postback control '%s'.
+page_control_outofform = Control '%s' must be enclosed within TForm.
+page_head_duplicated = A page can contain at most one THead.
+page_statepersister_invalid = Page state persister must implement IPageStatePersister interface.
+
+csmanager_pradoscript_invalid = Unknown Prado script library name '%s'.
+
contentplaceholder_id_required = TContentPlaceHolder must have an ID.
content_id_required = TContent must have an ID.
diff --git a/framework/Web/Javascripts/TJavaScript.php b/framework/Web/Javascripts/TJavaScript.php index 47d506fb..0d081e02 100644 --- a/framework/Web/Javascripts/TJavaScript.php +++ b/framework/Web/Javascripts/TJavaScript.php @@ -13,7 +13,7 @@ /**
* TJavaScript class.
*
- * TJavaScript is a utility class containing commonly used javascript-related
+ * TJavaScript is a utility class containing commonly-used javascript-related
* functions.
*
* @author Wei Zhuo<weizhuo[at]gmail[dot]com>
@@ -23,6 +23,11 @@ */
class TJavaScript
{
+ /**
+ * Renders a list of javascript files
+ * @param array URLs to the javascript files
+ * @return string rendering result
+ */
public static function renderScriptFiles($files)
{
$str='';
@@ -31,11 +36,21 @@ class TJavaScript return $str;
}
+ /**
+ * Renders a javascript file
+ * @param string URL to the javascript file
+ * @return string rendering result
+ */
public static function renderScriptFile($file)
{
return '<script type="text/javascript" src="'.THttpUtility::htmlEncode($file)."\"></script>\n";
}
+ /**
+ * Renders a list of javascript blocks
+ * @param array javascript blocks
+ * @return string rendering result
+ */
public static function renderScriptBlocks($scripts)
{
if(count($scripts))
@@ -44,33 +59,24 @@ class TJavaScript return '';
}
+ /**
+ * Renders javascript block
+ * @param string javascript block
+ * @return string rendering result
+ */
public static function renderScriptBlock($script)
{
return "<script type=\"text/javascript\">\n/*<![CDATA[*/\n{$script}\n/*]]>*/\n</script>\n";
}
- public static function renderArrayDeclarations($arrays)
- {
- if(count($arrays))
- {
- $str="<script type=\"text/javascript\">\n/*<![CDATA[*/\n";
- foreach($arrays as $name=>$array)
- $str.="var $name=new Array(".implode(',',$array).");\n";
- $str.="\n/*]]>*/\n</script>\n";
- return $str;
- }
- else
- return '';
- }
-
- public static function renderArrayDeclaration($array)
- {
- $str="<script type=\"text/javascript\">\n/*<![CDATA[*/\n";
- $str.="var $name=new Array(".implode(',',$array).");\n";
- $str.="\n/*]]>*/\n</script>\n";
- return $str;
- }
-
+ /**
+ * Quotes a javascript string.
+ * After processing, the string can be safely enclosed within a pair of
+ * quotation marks and serve as a javascript string.
+ * @param string string to be quoted
+ * @param boolean whether this string is used as a URL
+ * @return string the quoted string
+ */
public static function quoteString($js,$forUrl=false)
{
if($forUrl)
@@ -86,13 +92,17 @@ class TJavaScript * <code>
* $options['onLoading'] = "doit";
* $options['onComplete'] = "more";
- * $js = new TJavascriptSerializer($options);
- * echo $js->toMap();
+ * echo TJavaScript::encode($options);
* //expects the following javascript code
* // {'onLoading':'doit','onComplete':'more'}
* </code>
*
- * For higher complexity data structures use TJSON to serialize and unserialize.
+ * For higher complexity data structures use {@link jsonEncode} and {@link jsonDecode}
+ * to serialize and unserialize.
+ *
+ * @param mixed PHP variable to be encoded
+ * @param boolean whether the output is a map or a list.
+ * @return string the encoded string
*/
public static function encode($value,$toMap=true)
{
@@ -144,12 +154,24 @@ class TJavaScript return '';
}
+ /**
+ * Encodes a PHP variable into javascript string.
+ * This method invokes {@TJSON} utility class to perform the encoding.
+ * @param mixed variable to be encoded
+ * @return string encoded string
+ */
public static function jsonEncode($value)
{
Prado::using('System.Web.Javascripts.TJSON');
return TJSON::encode($value);
}
+ /**
+ * Decodes a javascript string into PHP variable.
+ * This method invokes {@TJSON} utility class to perform the decoding.
+ * @param string string to be decoded
+ * @return mixed decoded variable
+ */
public static function jsonDecode($value)
{
Prado::using('System.Web.Javascripts.TJSON');
diff --git a/framework/Web/THttpUtility.php b/framework/Web/THttpUtility.php index 34f1a8a4..398b3cf3 100644 --- a/framework/Web/THttpUtility.php +++ b/framework/Web/THttpUtility.php @@ -22,11 +22,23 @@ class THttpUtility {
private static $_entityTable=null;
+ /**
+ * HTML-encodes a string.
+ * It is equivalent to {@link htmlspeicalchars} PHP function.
+ * @param string string to be encoded
+ * @return string encoded string
+ */
public static function htmlEncode($s)
{
return htmlspecialchars($s);
}
+ /**
+ * HTML-decodes a string.
+ * It is the inverse of {@link htmlEncode}.
+ * @param string string to be decoded
+ * @return string decoded string
+ */
public static function htmlDecode($s)
{
if(!self::$_entityTable)
diff --git a/framework/Web/UI/TClientScriptManager.php b/framework/Web/UI/TClientScriptManager.php index 5ff5dba6..17d680c3 100644 --- a/framework/Web/UI/TClientScriptManager.php +++ b/framework/Web/UI/TClientScriptManager.php @@ -136,6 +136,11 @@ class TClientScriptManager extends TApplicationComponent } } + /** + * Registers postback javascript for a control. + * @param TControl control to be registered with postback js + * @param string js namespace for the control + */ public function registerPostBackControl($control,$namespace='Prado.WebUI') { $options = $this->getPostBackOptions($control); @@ -149,6 +154,10 @@ class TClientScriptManager extends TApplicationComponent $this->registerPradoScript('prado'); } + /** + * @param TControl postback control + * @return array postback options for the control + */ protected function getPostBackOptions($control) { $postback = $control->getPostBackOptions(); diff --git a/framework/Web/UI/THtmlWriter.php b/framework/Web/UI/THtmlWriter.php index 613d58dc..8a092460 100644 --- a/framework/Web/UI/THtmlWriter.php +++ b/framework/Web/UI/THtmlWriter.php @@ -10,13 +10,27 @@ * @package System.Web.UI
*/
-// todo: test if an attribute is a url
-// keep nonclosing tag only
-// add more utility methods (e.g. render....)
-// implment encoding (for text and url)
/**
* THtmlWriter class
*
+ * THtmlWriter is a writer that renders valid XHTML outputs.
+ * It provides functions to render tags, their attributes and stylesheet fields.
+ * Attribute and stylesheet values will be automatically HTML-encoded if
+ * they require so. For example, the 'value' attribute in an input tag
+ * will be encoded.
+ *
+ * A common usage of THtmlWriter is as the following sequence:
+ * <code>
+ * $writer->addAttribute($name1,$value1);
+ * $writer->addAttribute($name2,$value2);
+ * $writer->renderBeginTag($tagName);
+ * // ... render contents enclosed within the tag here
+ * $writer->renderEndTag();
+ * </code>
+ * Make sure each invocation of {@link renderBeginTag} is accompanied with
+ * a {@link renderEndTag} and they are properly nested, like nesting
+ * tags in HTML and XHTML.
+ *
* @author Qiang Xue <qiang.xue@gmail.com>
* @version $Revision: $ $Date: $
* @package System.Web.UI
@@ -24,110 +38,28 @@ */
class THtmlWriter extends TApplicationComponent implements ITextWriter
{
- const TAG_INLINE=0;
- const TAG_NONCLOSING=1;
- const TAG_OTHER=2;
- const CHAR_NEWLINE="\n";
- const CHAR_TAB="\t";
- private static $_tagTypes=array(
- '*'=>2,
- 'a'=>0,
- 'acronym'=>0,
- 'address'=>2,
- 'area'=>1,
- 'b'=>0,
- 'base'=>1,
- 'basefont'=>1,
- 'bdo'=>0,
- 'bgsound'=>1,
- 'big'=>0,
- 'blockquote'=>2,
- 'body'=>2,
- 'br'=>2,
- 'button'=>0,
- 'caption'=>2,
- 'center'=>2,
- 'cite'=>0,
- 'code'=>0,
- 'col'=>1,
- 'colgroup'=>2,
- 'del'=>0,
- 'dd'=>0,
- 'dfn'=>0,
- 'dir'=>2,
- 'div'=>2,
- 'dl'=>2,
- 'dt'=>0,
- 'em'=>0,
- 'embed'=>1,
- 'fieldset'=>2,
- 'font'=>0,
- 'form'=>2,
- 'frame'=>1,
- 'frameset'=>2,
- 'h1'=>2,
- 'h2'=>2,
- 'h3'=>2,
- 'h4'=>2,
- 'h5'=>2,
- 'h6'=>2,
- 'head'=>2,
- 'hr'=>1,
- 'html'=>2,
- 'i'=>0,
- 'iframe'=>2,
- 'img'=>1,
- 'input'=>1,
- 'ins'=>0,
- 'isindex'=>1,
- 'kbd'=>0,
- 'label'=>0,
- 'legend'=>2,
- 'li'=>0,
- 'link'=>1,
- 'map'=>2,
- 'marquee'=>2,
- 'menu'=>2,
- 'meta'=>1,
- 'nobr'=>0,
- 'noframes'=>2,
- 'noscript'=>2,
- 'object'=>2,
- 'ol'=>2,
- 'option'=>2,
- 'p'=>0,
- 'param'=>2,
- 'pre'=>2,
- 'ruby'=>2,
- 'rt'=>2,
- 'q'=>0,
- 's'=>0,
- 'samp'=>0,
- 'script'=>2,
- 'select'=>2,
- 'small'=>2,
- 'span'=>0,
- 'strike'=>0,
- 'strong'=>0,
- 'style'=>2,
- 'sub'=>0,
- 'sup'=>0,
- 'table'=>2,
- 'tbody'=>2,
- 'td'=>0,
- 'textarea'=>0,
- 'tfoot'=>2,
- 'th'=>0,
- 'thead'=>2,
- 'title'=>2,
- 'tr'=>2,
- 'tt'=>0,
- 'u'=>0,
- 'ul'=>2,
- 'var'=>0,
- 'wbr'=>1,
- 'xml'=>2
+ /**
+ * @var array list of tags are do not need a closing tag
+ */
+ private static $_simpleTags=array(
+ 'area'=>true,
+ 'base'=>true,
+ 'basefont'=>true,
+ 'bgsound'=>true,
+ 'col'=>true,
+ 'embed'=>true,
+ 'frame'=>true,
+ 'hr'=>true,
+ 'img'=>true,
+ 'input'=>true,
+ 'isindex'=>true,
+ 'link'=>true,
+ 'meta'=>true,
+ 'wbr'=>true,
);
+ /**
+ * @var array list of attributes that need HTML encoding
+ */
private static $_attrEncode=array(
'abbr'=>true,
'accesskey'=>true,
@@ -145,81 +77,138 @@ class THtmlWriter extends TApplicationComponent implements ITextWriter 'title'=>true,
'value'=>true
);
+ /**
+ * @var array list of stylesheet attributes that need HTML encoding
+ */
private static $_styleEncode=array(
'background-image'=>true,
'list-style-image'=>true
);
+ /**
+ * @var array list of attributes to be rendered for a tag
+ */
private $_attributes=array();
+ /**
+ * @var array list of openning tags
+ */
private $_openTags=array();
- private $_writer=null;
+ /**
+ * @var array list of style attributes
+ */
private $_styles=array();
+ /**
+ * @var ITextWriter writer
+ */
+ private $_writer=null;
+ /**
+ * Constructor.
+ * @param ITextWriter a writer that THtmlWriter will pass its rendering result to
+ */
public function __construct($writer)
{
$this->_writer=$writer;
}
- public function isValidFormAttribute($name)
- {
- return true;
- }
-
+ /**
+ * Adds a list of attributes to be rendered.
+ * @param array list of attributes to be rendered
+ */
public function addAttributes($attrs)
{
foreach($attrs as $name=>$value)
$this->_attributes[$name]=isset(self::$_attrEncode[$name])?THttpUtility::htmlEncode($value):$value;
}
+ /**
+ * Adds an attribute to be rendered.
+ * @param string name of the attribute
+ * @param string value of the attribute
+ */
public function addAttribute($name,$value)
{
$this->_attributes[$name]=isset(self::$_attrEncode[$name])?THttpUtility::htmlEncode($value):$value;
}
+ /**
+ * Removes the named attribute from rendering
+ * @param string name of the attribute to be removed
+ */
public function removeAttribute($name)
{
- if(isset($this->_attributes[$name]))
- unset($this->_attributes[$name]);
+ unset($this->_attributes[$name]);
}
-
+
+ /**
+ * Adds a list of stylesheet attributes to be rendered.
+ * @param array list of stylesheet attributes to be rendered
+ */
+ public function addStyleAttributes($attrs)
+ {
+ foreach($attrs as $name=>$value)
+ $this->_styles[$name]=isset(self::$_styleEncode[$name])?THttpUtility::htmlEncode($value):$value;
+ }
+
+ /**
+ * Adds a stylesheet attribute to be rendered
+ * @param string stylesheet attribute name
+ * @param string stylesheet attribute value
+ */
public function addStyleAttribute($name,$value)
{
$this->_styles[$name]=isset(self::$_styleEncode[$name])?THttpUtility::htmlEncode($value):$value;
}
+ /**
+ * Removes the named stylesheet attribute from rendering
+ * @param string name of the stylesheet attribute to be removed
+ */
public function removeStyleAttribute($name)
{
- if(isset($this->_styles[$name]))
- unset($this->_styles[$name]);
+ unset($this->_styles[$name]);
}
+ /**
+ * Flushes the rendering result.
+ * This will invoke the underlying writer's flush method.
+ */
public function flush()
{
$this->_writer->flush();
}
+ /**
+ * Renders a string.
+ * @param string string to be rendered
+ */
public function write($str)
{
$this->_writer->write($str);
}
+ /**
+ * Renders a string and appends a newline to it.
+ * @param string string to be rendered
+ */
public function writeLine($str='')
{
- $this->_writer->write($str.self::CHAR_NEWLINE);
+ $this->_writer->write($str."\n");
}
+ /**
+ * Renders an HTML break.
+ */
public function writeBreak()
{
$this->_writer->write('<br/>');
}
- public function writeAttribute($name,$value,$encode=false)
- {
- $this->_writer->write(' '.$name.='"'.($encode?THttpUtility::htmlEncode($value):$value).'"');
- }
-
+ /**
+ * Renders the openning tag.
+ * @param string tag name
+ */
public function renderBeginTag($tagName)
{
- $tagType=isset(self::$_tagTypes[$tagName])?self::$_tagTypes[$tagName]:self::TAG_OTHER;
$str='<'.$tagName;
foreach($this->_attributes as $name=>$value)
$str.=' '.$name.'="'.$value.'"';
@@ -230,7 +219,7 @@ class THtmlWriter extends TApplicationComponent implements ITextWriter $str.=$name.':'.$value.';';
$str.='"';
}
- if($tagType===self::TAG_NONCLOSING)
+ if(isset(self::$_simpleTags[$tagName]))
{
$str.=' />';
array_push($this->_openTags,'');
@@ -245,6 +234,9 @@ class THtmlWriter extends TApplicationComponent implements ITextWriter $this->_styles=array();
}
+ /**
+ * Renders the closing tag.
+ */
public function renderEndTag()
{
if(!empty($this->_openTags) && ($tagName=array_pop($this->_openTags))!=='')
diff --git a/framework/Web/UI/TPage.php b/framework/Web/UI/TPage.php index aa188a03..f0525e76 100644 --- a/framework/Web/UI/TPage.php +++ b/framework/Web/UI/TPage.php @@ -663,7 +663,7 @@ class TPage extends TTemplateControl public function ensureRenderInForm($control)
{
if(!$this->_inFormRender)
- throw new TConfigurationException('page_control_outofform',get_class($control),$control->getUniqueID());
+ throw new TConfigurationException('page_control_outofform',$control->getUniqueID());
}
/**
diff --git a/framework/Web/UI/TTemplateManager.php b/framework/Web/UI/TTemplateManager.php index 404be231..75f6268f 100644 --- a/framework/Web/UI/TTemplateManager.php +++ b/framework/Web/UI/TTemplateManager.php @@ -100,8 +100,8 @@ class TTemplateManager extends TModule */
protected function getLocalizedTemplate($filename)
{
- $app = $this->getApplication()->getGlobalization();
- if(is_null($app)) return $filename;
+ if(($app=$this->getApplication()->getGlobalization())===null)
+ return $filename;
foreach($app->getLocalizedResource($filename) as $file)
{
if(($file=realpath($file))!==false && is_file($file))
diff --git a/framework/Web/UI/WebControls/TStyle.php b/framework/Web/UI/WebControls/TStyle.php index ab7e8568..e1636145 100644 --- a/framework/Web/UI/WebControls/TStyle.php +++ b/framework/Web/UI/WebControls/TStyle.php @@ -329,8 +329,7 @@ class TStyle extends TComponent $writer->addStyleAttribute(trim($arr[0]),trim($arr[1]));
}
}
- foreach($this->_fields as $name=>$value)
- $writer->addStyleAttribute($name,$value);
+ $writer->addStyleAttributes($this->_fields);
if($this->_font!==null)
$this->_font->addAttributesToRender($writer);
if($this->_class!==null)
diff --git a/framework/core.php b/framework/core.php index d660fb81..c3ac048b 100644 --- a/framework/core.php +++ b/framework/core.php @@ -807,10 +807,26 @@ class PradoBase }
}
+/**
+ * TTextWriter class.
+ *
+ * TTextWriter implements a memory-based text writer.
+ * Content written by TTextWriter are stored in memory
+ * and can be obtained by calling {@link flush()}.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Revision: $ $Date: $
+ * @package System
+ * @since 3.0
+ */
class TTextWriter extends TComponent implements ITextWriter
{
private $_str='';
+ /**
+ * Flushes the content that has been written.
+ * @return string the content being flushed
+ */
public function flush()
{
$str=$this->_str;
@@ -818,18 +834,24 @@ class TTextWriter extends TComponent implements ITextWriter return $str;
}
+ /**
+ * Writes a string.
+ * @param string string to be written
+ */
public function write($str)
{
$this->_str.=$str;
}
+ /**
+ * Writers a string and terminates it with a newline.
+ * @param string content to be written
+ * @see write
+ */
public function writeLine($str='')
{
$this->write($str."\n");
}
}
-class TDate extends TComponent
-{
-}
?>
\ No newline at end of file |