ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
Generator.php
Go to the documentation of this file.
1<?php
2
11{
12
17 private $_xhtml = true;
18
23 private $_scriptFix = false;
24
30 private $_def;
31
36 private $_sortAttr;
37
43
49
55 private $_flashStack = array();
56
61 protected $config;
62
67 public function __construct($config, $context)
68 {
69 $this->config = $config;
70 $this->_scriptFix = $config->get('Output.CommentScriptContents');
71 $this->_innerHTMLFix = $config->get('Output.FixInnerHTML');
72 $this->_sortAttr = $config->get('Output.SortAttr');
73 $this->_flashCompat = $config->get('Output.FlashCompat');
74 $this->_def = $config->getHTMLDefinition();
75 $this->_xhtml = $this->_def->doctype->xml;
76 }
77
83 public function generateFromTokens($tokens)
84 {
85 if (!$tokens) {
86 return '';
87 }
88
89 // Basic algorithm
90 $html = '';
91 for ($i = 0, $size = count($tokens); $i < $size; $i++) {
92 if ($this->_scriptFix && $tokens[$i]->name === 'script'
93 && $i + 2 < $size && $tokens[$i+2] instanceof HTMLPurifier_Token_End) {
94 // script special case
95 // the contents of the script block must be ONE token
96 // for this to work.
97 $html .= $this->generateFromToken($tokens[$i++]);
98 $html .= $this->generateScriptFromToken($tokens[$i++]);
99 }
100 $html .= $this->generateFromToken($tokens[$i]);
101 }
102
103 // Tidy cleanup
104 if (extension_loaded('tidy') && $this->config->get('Output.TidyFormat')) {
105 $tidy = new Tidy;
106 $tidy->parseString(
107 $html,
108 array(
109 'indent'=> true,
110 'output-xhtml' => $this->_xhtml,
111 'show-body-only' => true,
112 'indent-spaces' => 2,
113 'wrap' => 68,
114 ),
115 'utf8'
116 );
117 $tidy->cleanRepair();
118 $html = (string) $tidy; // explicit cast necessary
119 }
120
121 // Normalize newlines to system defined value
122 if ($this->config->get('Core.NormalizeNewlines')) {
123 $nl = $this->config->get('Output.Newline');
124 if ($nl === null) {
125 $nl = PHP_EOL;
126 }
127 if ($nl !== "\n") {
128 $html = str_replace("\n", $nl, $html);
129 }
130 }
131 return $html;
132 }
133
139 public function generateFromToken($token)
140 {
141 if (!$token instanceof HTMLPurifier_Token) {
142 trigger_error('Cannot generate HTML from non-HTMLPurifier_Token object', E_USER_WARNING);
143 return '';
144
145 } elseif ($token instanceof HTMLPurifier_Token_Start) {
146 $attr = $this->generateAttributes($token->attr, $token->name);
147 if ($this->_flashCompat) {
148 if ($token->name == "object") {
149 $flash = new stdclass();
150 $flash->attr = $token->attr;
151 $flash->param = array();
152 $this->_flashStack[] = $flash;
153 }
154 }
155 return '<' . $token->name . ($attr ? ' ' : '') . $attr . '>';
156
157 } elseif ($token instanceof HTMLPurifier_Token_End) {
158 $_extra = '';
159 if ($this->_flashCompat) {
160 if ($token->name == "object" && !empty($this->_flashStack)) {
161 // doesn't do anything for now
162 }
163 }
164 return $_extra . '</' . $token->name . '>';
165
166 } elseif ($token instanceof HTMLPurifier_Token_Empty) {
167 if ($this->_flashCompat && $token->name == "param" && !empty($this->_flashStack)) {
168 $this->_flashStack[count($this->_flashStack)-1]->param[$token->attr['name']] = $token->attr['value'];
169 }
170 $attr = $this->generateAttributes($token->attr, $token->name);
171 return '<' . $token->name . ($attr ? ' ' : '') . $attr .
172 ( $this->_xhtml ? ' /': '' ) // <br /> v. <br>
173 . '>';
174
175 } elseif ($token instanceof HTMLPurifier_Token_Text) {
176 return $this->escape($token->data, ENT_NOQUOTES);
177
178 } elseif ($token instanceof HTMLPurifier_Token_Comment) {
179 return '<!--' . $token->data . '-->';
180 } else {
181 return '';
182
183 }
184 }
185
193 public function generateScriptFromToken($token)
194 {
195 if (!$token instanceof HTMLPurifier_Token_Text) {
196 return $this->generateFromToken($token);
197 }
198 // Thanks <http://lachy.id.au/log/2005/05/script-comments>
199 $data = preg_replace('#//\s*$#', '', $token->data);
200 return '<!--//--><![CDATA[//><!--' . "\n" . trim($data) . "\n" . '//--><!]]>';
201 }
202
211 public function generateAttributes($assoc_array_of_attributes, $element = '')
212 {
213 $html = '';
214 if ($this->_sortAttr) {
215 ksort($assoc_array_of_attributes);
216 }
217 foreach ($assoc_array_of_attributes as $key => $value) {
218 if (!$this->_xhtml) {
219 // Remove namespaced attributes
220 if (strpos($key, ':') !== false) {
221 continue;
222 }
223 // Check if we should minimize the attribute: val="val" -> val
224 if ($element && !empty($this->_def->info[$element]->attr[$key]->minimized)) {
225 $html .= $key . ' ';
226 continue;
227 }
228 }
229 // Workaround for Internet Explorer innerHTML bug.
230 // Essentially, Internet Explorer, when calculating
231 // innerHTML, omits quotes if there are no instances of
232 // angled brackets, quotes or spaces. However, when parsing
233 // HTML (for example, when you assign to innerHTML), it
234 // treats backticks as quotes. Thus,
235 // <img alt="``" />
236 // becomes
237 // <img alt=`` />
238 // becomes
239 // <img alt='' />
240 // Fortunately, all we need to do is trigger an appropriate
241 // quoting style, which we do by adding an extra space.
242 // This also is consistent with the W3C spec, which states
243 // that user agents may ignore leading or trailing
244 // whitespace (in fact, most don't, at least for attributes
245 // like alt, but an extra space at the end is barely
246 // noticeable). Still, we have a configuration knob for
247 // this, since this transformation is not necesary if you
248 // don't process user input with innerHTML or you don't plan
249 // on supporting Internet Explorer.
250 if ($this->_innerHTMLFix) {
251 if (strpos($value, '`') !== false) {
252 // check if correct quoting style would not already be
253 // triggered
254 if (strcspn($value, '"\' <>') === strlen($value)) {
255 // protect!
256 $value .= ' ';
257 }
258 }
259 }
260 $html .= $key.'="'.$this->escape($value).'" ';
261 }
262 return rtrim($html);
263 }
264
275 public function escape($string, $quote = null)
276 {
277 // Workaround for APC bug on Mac Leopard reported by sidepodcast
278 // http://htmlpurifier.org/phorum/read.php?3,4823,4846
279 if ($quote === null) {
280 $quote = ENT_COMPAT;
281 }
282 return htmlspecialchars($string, $quote, 'UTF-8');
283 }
284}
285
286// vim: et sw=4 sts=4
$size
Definition: RandomTest.php:79
Generates HTML from tokens.
Definition: Generator.php:11
$_scriptFix
:HACK: Whether or not generator should comment the insides of <script> tags.
Definition: Generator.php:23
generateScriptFromToken($token)
Special case processor for the contents of script tags.
Definition: Generator.php:193
$_innerHTMLFix
Cache of Output.FixInnerHTML.
Definition: Generator.php:48
$config
Configuration for the generator @type HTMLPurifier_Config.
Definition: Generator.php:61
$_sortAttr
Cache of Output.SortAttr.
Definition: Generator.php:36
generateFromToken($token)
Generates HTML from a single token.
Definition: Generator.php:139
generateFromTokens($tokens)
Generates HTML from an array of tokens.
Definition: Generator.php:83
generateAttributes($assoc_array_of_attributes, $element='')
Generates attribute declarations from attribute array.
Definition: Generator.php:211
escape($string, $quote=null)
Escapes raw text data.
Definition: Generator.php:275
$_xhtml
Whether or not generator should produce XML output.
Definition: Generator.php:17
$_flashStack
Stack for keeping track of object information when outputting IE compatibility code.
Definition: Generator.php:55
__construct($config, $context)
Definition: Generator.php:67
$_flashCompat
Cache of Output.FlashCompat.
Definition: Generator.php:42
$_def
Cache of HTMLDefinition during HTML output to determine whether or not attributes should be minimized...
Definition: Generator.php:30
Concrete comment token class.
Definition: Comment.php:7
Concrete empty token class.
Definition: Empty.php:7
Concrete end token class.
Definition: End.php:11
Concrete start token class.
Definition: Start.php:7
Concrete text token class.
Definition: Text.php:13
Abstract base token class that all others inherit from.
Definition: Token.php:7
$html
Definition: example_001.php:87
$data