| | |
| | | 'cellpadding', 'valign', 'bgcolor', 'color', 'border', 'bordercolorlight', |
| | | 'bordercolordark', 'face', 'marginwidth', 'marginheight', 'axis', 'border', |
| | | 'abbr', 'char', 'charoff', 'clear', 'compact', 'coords', 'vspace', 'hspace', |
| | | 'cellborder', 'size', 'lang', 'dir', |
| | | 'cellborder', 'size', 'lang', 'dir', 'usemap', |
| | | // attributes of form elements |
| | | 'type', 'rows', 'cols', 'disabled', 'readonly', 'checked', 'multiple', 'value' |
| | | ); |
| | | |
| | | /* Block elements which could be empty but cannot be returned in short form (<tag />) */ |
| | | static $block_elements = array('div', 'p', 'pre', 'blockquote', 'a', 'font', 'center', |
| | | 'table', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'dl', 'strong', 'i', 'b', 'u'); |
| | | 'table', 'ul', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'dl', 'strong', 'i', 'b', 'u', 'span'); |
| | | |
| | | /* State for linked objects in HTML */ |
| | | public $extlinks = false; |
| | |
| | | |
| | | |
| | | /* Constructor */ |
| | | public function __construct($p = array()) { |
| | | public function __construct($p = array()) |
| | | { |
| | | $this->_html_elements = array_flip((array)$p['html_elements']) + array_flip(self::$html_elements) ; |
| | | $this->_html_attribs = array_flip((array)$p['html_attribs']) + array_flip(self::$html_attribs); |
| | | $this->_ignore_elements = array_flip((array)$p['ignore_elements']) + array_flip(self::$ignore_elements); |
| | |
| | | } |
| | | |
| | | /* Check CSS style */ |
| | | private function wash_style($style) { |
| | | private function wash_style($style) |
| | | { |
| | | $s = ''; |
| | | |
| | | foreach (explode(';', $style) as $declaration) { |
| | |
| | | } |
| | | |
| | | /* Take a node and return allowed attributes and check values */ |
| | | private function wash_attribs($node) { |
| | | private function wash_attribs($node) |
| | | { |
| | | $t = ''; |
| | | $washed; |
| | | |
| | |
| | | $key = strtolower($key); |
| | | $value = $node->getAttribute($key); |
| | | if (isset($this->_html_attribs[$key]) || |
| | | ($key == 'href' && preg_match('!^(http:|https:|ftp:|mailto:|//|#).+!i', $value))) |
| | | ($key == 'href' && preg_match('!^([a-z][a-z0-9.+-]+:|//|#).+!i', $value))) |
| | | $t .= ' ' . $key . '="' . htmlspecialchars($value, ENT_QUOTES) . '"'; |
| | | else if ($key == 'style' && ($style = $this->wash_style($value))) { |
| | | $quot = strpos($style, '"') !== false ? "'" : '"'; |
| | |
| | | /* The main loop that recurse on a node tree. |
| | | * It output only allowed tags with allowed attributes |
| | | * and allowed inline styles */ |
| | | private function dumpHtml($node) { |
| | | private function dumpHtml($node) |
| | | { |
| | | if(!$node->hasChildNodes()) |
| | | return ''; |
| | | |
| | |
| | | else if (isset($this->_html_elements[$tagName])) { |
| | | $content = $this->dumpHtml($node); |
| | | $dump .= '<' . $tagName . $this->wash_attribs($node) . |
| | | // create closing tag for block elements, but also for elements |
| | | // with content or with some attributes (eg. style, class) (#1486812) |
| | | ($content != '' || $node->hasAttributes() || isset($this->_block_elements[$tagName]) ? ">$content</$tagName>" : ' />'); |
| | | ($content != '' || isset($this->_block_elements[$tagName]) ? ">$content</$tagName>" : ' />'); |
| | | } |
| | | else if (isset($this->_ignore_elements[$tagName])) { |
| | | $dump .= '<!-- ' . htmlspecialchars($tagName, ENT_QUOTES) . ' not allowed -->'; |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | ?> |