| | |
| | | | program/include/html.php | |
| | | | | |
| | | | This file is part of the Roundcube Webmail client | |
| | | | Copyright (C) 2005-2010, The Roundcube Dev Team | |
| | | | Licensed under the GNU GPL | |
| | | | Copyright (C) 2005-2011, The Roundcube Dev Team | |
| | | | | |
| | | | Licensed under the GNU General Public License version 3 or | |
| | | | any later version with exceptions for skins & plugins. | |
| | | | See the README file for a full license statement. | |
| | | | | |
| | | | PURPOSE: | |
| | | | Helper class to create valid XHTML code | |
| | |
| | | protected $allowed = array(); |
| | | protected $content; |
| | | |
| | | public static $doctype = 'xhtml'; |
| | | public static $lc_tags = true; |
| | | public static $common_attrib = array('id','class','style','title','align'); |
| | | public static $containers = array('iframe','div','span','p','h1','h2','h3','form','textarea','table','thead','tbody','tr','th','td','style','script'); |
| | |
| | | |
| | | $tagname = self::$lc_tags ? strtolower($tagname) : $tagname; |
| | | if (isset($content) || in_array($tagname, self::$containers)) { |
| | | $templ = $attrib['noclose'] ? "<%s%s>%s" : "<%s%s>%s</%s>%s"; |
| | | unset($attrib['noclose']); |
| | | return sprintf($templ, $tagname, self::attrib_string($attrib, $allowed_attrib), $content, $tagname, $suffix); |
| | | $suffix = $attrib['noclose'] ? $suffix : '</' . $tagname . '>' . $suffix; |
| | | unset($attrib['noclose'], $attrib['nl']); |
| | | return '<' . $tagname . self::attrib_string($attrib, $allowed_attrib) . '>' . $content . $suffix; |
| | | } |
| | | else { |
| | | return sprintf("<%s%s />%s", $tagname, self::attrib_string($attrib, $allowed_attrib), $suffix); |
| | | return '<' . $tagname . self::attrib_string($attrib, $allowed_attrib) . '>' . $suffix; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * |
| | | */ |
| | | public static function doctype($type) |
| | | { |
| | | $doctypes = array( |
| | | 'html5' => '<!DOCTYPE html>', |
| | | 'xhtml' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', |
| | | 'xhtml-trans' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', |
| | | 'xhtml-strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', |
| | | ); |
| | | |
| | | if ($doctypes[$type]) { |
| | | self::$doctype = preg_replace('/-\w+$/', '', $type); |
| | | return $doctypes[$type]; |
| | | } |
| | | |
| | | return ''; |
| | | } |
| | | |
| | | /** |
| | |
| | | $attr = array('src' => $attr); |
| | | } |
| | | return self::tag('iframe', $attr, $cont, array_merge(self::$common_attrib, |
| | | array('src','name','width','height','border','frameborder'))); |
| | | array('src','name','width','height','border','frameborder'))); |
| | | } |
| | | |
| | | /** |
| | | * Derrived method to create <script> tags |
| | | * |
| | | * @param mixed $attr Hash array with tag attributes or string with script source (src) |
| | | * @param string $cont Javascript code to be placed as tag content |
| | | * @return string HTML code |
| | | * @see html::tag() |
| | | */ |
| | | public static function script($attr, $cont = null) |
| | | { |
| | | if (is_string($attr)) { |
| | | $attr = array('src' => $attr); |
| | | } |
| | | if ($cont) { |
| | | if (self::$doctype == 'xhtml') |
| | | $cont = "\n/* <![CDATA[ */\n" . $cont . "\n/* ]]> */\n"; |
| | | else |
| | | $cont = "\n" . $cont . "\n"; |
| | | } |
| | | |
| | | return self::tag('script', $attr + array('type' => 'text/javascript', 'nl' => true), |
| | | $cont, array_merge(self::$common_attrib, array('src','type','charset'))); |
| | | } |
| | | |
| | | /** |
| | |
| | | // attributes with no value |
| | | if (in_array($key, array('checked', 'multiple', 'disabled', 'selected'))) { |
| | | if ($value) { |
| | | $attrib_arr[] = sprintf('%s="%s"', $key, $key); |
| | | $attrib_arr[] = $key . '="' . $key . '"'; |
| | | } |
| | | } |
| | | else if ($key=='value') { |
| | | $attrib_arr[] = sprintf('%s="%s"', $key, Q($value, 'strict', false)); |
| | | $attrib_arr[] = $key . '="' . Q($value, 'strict', false) . '"'; |
| | | } |
| | | else { |
| | | $attrib_arr[] = sprintf('%s="%s"', $key, Q($value)); |
| | | $attrib_arr[] = $key . '="' . Q($value) . '"'; |
| | | } |
| | | } |
| | | return count($attrib_arr) ? ' '.implode(' ', $attrib_arr) : ''; |
| | |
| | | { |
| | | protected $tagname = 'table'; |
| | | protected $allowed = array('id','class','style','width','summary', |
| | | 'cellpadding','cellspacing','border'); |
| | | 'cellpadding','cellspacing','border'); |
| | | |
| | | private $header = array(); |
| | | private $rows = array(); |
| | |
| | | */ |
| | | public function __construct($attrib = array()) |
| | | { |
| | | $this->attrib = array_merge($attrib, array('summary' => '', 'border' => 0)); |
| | | $default_attrib = self::$doctype == 'xhtml' ? array('summary' => '', 'border' => 0) : array(); |
| | | $this->attrib = array_merge($attrib, $default_attrib); |
| | | } |
| | | |
| | | /** |
| | |
| | | public function remove_column($class) |
| | | { |
| | | // Remove the header |
| | | foreach($this->header as $index=>$header){ |
| | | if($header->attrib['class'] == $class){ |
| | | foreach ($this->header as $index=>$header){ |
| | | if ($header->attrib['class'] == $class){ |
| | | unset($this->header[$index]); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | // Remove cells from rows |
| | | foreach($this->rows as $i=>$row){ |
| | | foreach($row->cells as $j=>$cell){ |
| | | if($cell->attrib['class'] == $class){ |
| | | foreach ($this->rows as $i=>$row){ |
| | | foreach ($row->cells as $j=>$cell){ |
| | | if ($cell->attrib['class'] == $class){ |
| | | unset($this->rows[$i]->cells[$j]); |
| | | break; |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Set current row attrib |
| | | * Set row attributes |
| | | * |
| | | * @param array $attr Row attributes |
| | | * @param array $attr Row attributes |
| | | * @param int $index Optional row index (default current row index) |
| | | */ |
| | | public function set_row_attribs($attr = array()) |
| | | public function set_row_attribs($attr = array(), $index = null) |
| | | { |
| | | if (is_string($attr)) |
| | | $attr = array('class' => $attr); |
| | | |
| | | $this->rows[$this->rowindex]->attrib = $attr; |
| | | if ($index === null) |
| | | $index = $this->rowindex; |
| | | |
| | | $this->rows[$index]->attrib = $attr; |
| | | } |
| | | |
| | | /** |
| | | * Get row attributes |
| | | * |
| | | * @param int $index Row index |
| | | * |
| | | * @return array Row attributes |
| | | */ |
| | | public function get_row_attribs($index = null) |
| | | { |
| | | if ($index === null) |
| | | $index = $this->rowindex; |
| | | |
| | | return $this->rows[$index] ? $this->rows[$index]->attrib : null; |
| | | } |
| | | |
| | | /** |
| | |
| | | { |
| | | if (is_array($attrib)) |
| | | $this->attrib = array_merge($this->attrib, $attrib); |
| | | |
| | | |
| | | $thead = $tbody = ""; |
| | | |
| | | // include <thead> |
| | |
| | | foreach ($this->header as $c => $col) { |
| | | $rowcontent .= self::tag('td', $col->attrib, $col->content); |
| | | } |
| | | $thead = self::tag('thead', null, self::tag('tr', null, $rowcontent)); |
| | | $thead = self::tag('thead', null, self::tag('tr', null, $rowcontent, parent::$common_attrib)); |
| | | } |
| | | |
| | | foreach ($this->rows as $r => $row) { |
| | |
| | | } |
| | | |
| | | if ($r < $this->rowindex || count($row->cells)) { |
| | | $tbody .= self::tag('tr', $row->attrib, $rowcontent); |
| | | $tbody .= self::tag('tr', $row->attrib, $rowcontent, parent::$common_attrib); |
| | | } |
| | | } |
| | | |
| | |
| | | unset($this->attrib['cols'], $this->attrib['rowsonly']); |
| | | return parent::show(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Count number of rows |
| | | * |