weekly release 2.7dev
[moodle.git] / lib / htmlpurifier / HTMLPurifier / Printer / HTMLDefinition.php
CommitLineData
510d1903
PS
1<?php\r
2\r
3class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer\r
4{\r
5\r
6 /**\r
7 * Instance of HTMLPurifier_HTMLDefinition, for easy access\r
8 */\r
9 protected $def;\r
10\r
11 public function render($config) {\r
12 $ret = '';\r
13 $this->config =& $config;\r
14\r
15 $this->def = $config->getHTMLDefinition();\r
16\r
17 $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer'));\r
18\r
19 $ret .= $this->renderDoctype();\r
20 $ret .= $this->renderEnvironment();\r
21 $ret .= $this->renderContentSets();\r
22 $ret .= $this->renderInfo();\r
23\r
24 $ret .= $this->end('div');\r
25\r
26 return $ret;\r
27 }\r
28\r
29 /**\r
30 * Renders the Doctype table\r
31 */\r
32 protected function renderDoctype() {\r
33 $doctype = $this->def->doctype;\r
34 $ret = '';\r
35 $ret .= $this->start('table');\r
36 $ret .= $this->element('caption', 'Doctype');\r
37 $ret .= $this->row('Name', $doctype->name);\r
38 $ret .= $this->row('XML', $doctype->xml ? 'Yes' : 'No');\r
39 $ret .= $this->row('Default Modules', implode($doctype->modules, ', '));\r
40 $ret .= $this->row('Default Tidy Modules', implode($doctype->tidyModules, ', '));\r
41 $ret .= $this->end('table');\r
42 return $ret;\r
43 }\r
44\r
45\r
46 /**\r
47 * Renders environment table, which is miscellaneous info\r
48 */\r
49 protected function renderEnvironment() {\r
50 $def = $this->def;\r
51\r
52 $ret = '';\r
53\r
54 $ret .= $this->start('table');\r
55 $ret .= $this->element('caption', 'Environment');\r
56\r
57 $ret .= $this->row('Parent of fragment', $def->info_parent);\r
58 $ret .= $this->renderChildren($def->info_parent_def->child);\r
59 $ret .= $this->row('Block wrap name', $def->info_block_wrapper);\r
60\r
61 $ret .= $this->start('tr');\r
62 $ret .= $this->element('th', 'Global attributes');\r
63 $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr),0,0);\r
64 $ret .= $this->end('tr');\r
65\r
66 $ret .= $this->start('tr');\r
67 $ret .= $this->element('th', 'Tag transforms');\r
68 $list = array();\r
69 foreach ($def->info_tag_transform as $old => $new) {\r
70 $new = $this->getClass($new, 'TagTransform_');\r
71 $list[] = "<$old> with $new";\r
72 }\r
73 $ret .= $this->element('td', $this->listify($list));\r
74 $ret .= $this->end('tr');\r
75\r
76 $ret .= $this->start('tr');\r
77 $ret .= $this->element('th', 'Pre-AttrTransform');\r
78 $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre));\r
79 $ret .= $this->end('tr');\r
80\r
81 $ret .= $this->start('tr');\r
82 $ret .= $this->element('th', 'Post-AttrTransform');\r
83 $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post));\r
84 $ret .= $this->end('tr');\r
85\r
86 $ret .= $this->end('table');\r
87 return $ret;\r
88 }\r
89\r
90 /**\r
91 * Renders the Content Sets table\r
92 */\r
93 protected function renderContentSets() {\r
94 $ret = '';\r
95 $ret .= $this->start('table');\r
96 $ret .= $this->element('caption', 'Content Sets');\r
97 foreach ($this->def->info_content_sets as $name => $lookup) {\r
98 $ret .= $this->heavyHeader($name);\r
99 $ret .= $this->start('tr');\r
100 $ret .= $this->element('td', $this->listifyTagLookup($lookup));\r
101 $ret .= $this->end('tr');\r
102 }\r
103 $ret .= $this->end('table');\r
104 return $ret;\r
105 }\r
106\r
107 /**\r
108 * Renders the Elements ($info) table\r
109 */\r
110 protected function renderInfo() {\r
111 $ret = '';\r
112 $ret .= $this->start('table');\r
113 $ret .= $this->element('caption', 'Elements ($info)');\r
114 ksort($this->def->info);\r
115 $ret .= $this->heavyHeader('Allowed tags', 2);\r
116 $ret .= $this->start('tr');\r
117 $ret .= $this->element('td', $this->listifyTagLookup($this->def->info), array('colspan' => 2));\r
118 $ret .= $this->end('tr');\r
119 foreach ($this->def->info as $name => $def) {\r
120 $ret .= $this->start('tr');\r
121 $ret .= $this->element('th', "<$name>", array('class'=>'heavy', 'colspan' => 2));\r
122 $ret .= $this->end('tr');\r
123 $ret .= $this->start('tr');\r
124 $ret .= $this->element('th', 'Inline content');\r
125 $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No');\r
126 $ret .= $this->end('tr');\r
127 if (!empty($def->excludes)) {\r
128 $ret .= $this->start('tr');\r
129 $ret .= $this->element('th', 'Excludes');\r
130 $ret .= $this->element('td', $this->listifyTagLookup($def->excludes));\r
131 $ret .= $this->end('tr');\r
132 }\r
133 if (!empty($def->attr_transform_pre)) {\r
134 $ret .= $this->start('tr');\r
135 $ret .= $this->element('th', 'Pre-AttrTransform');\r
136 $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre));\r
137 $ret .= $this->end('tr');\r
138 }\r
139 if (!empty($def->attr_transform_post)) {\r
140 $ret .= $this->start('tr');\r
141 $ret .= $this->element('th', 'Post-AttrTransform');\r
142 $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post));\r
143 $ret .= $this->end('tr');\r
144 }\r
145 if (!empty($def->auto_close)) {\r
146 $ret .= $this->start('tr');\r
147 $ret .= $this->element('th', 'Auto closed by');\r
148 $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close));\r
149 $ret .= $this->end('tr');\r
150 }\r
151 $ret .= $this->start('tr');\r
152 $ret .= $this->element('th', 'Allowed attributes');\r
153 $ret .= $this->element('td',$this->listifyAttr($def->attr), array(), 0);\r
154 $ret .= $this->end('tr');\r
155\r
156 if (!empty($def->required_attr)) {\r
157 $ret .= $this->row('Required attributes', $this->listify($def->required_attr));\r
158 }\r
159\r
160 $ret .= $this->renderChildren($def->child);\r
161 }\r
162 $ret .= $this->end('table');\r
163 return $ret;\r
164 }\r
165\r
166 /**\r
167 * Renders a row describing the allowed children of an element\r
168 * @param $def HTMLPurifier_ChildDef of pertinent element\r
169 */\r
170 protected function renderChildren($def) {\r
171 $context = new HTMLPurifier_Context();\r
172 $ret = '';\r
173 $ret .= $this->start('tr');\r
174 $elements = array();\r
175 $attr = array();\r
176 if (isset($def->elements)) {\r
177 if ($def->type == 'strictblockquote') {\r
178 $def->validateChildren(array(), $this->config, $context);\r
179 }\r
180 $elements = $def->elements;\r
181 }\r
182 if ($def->type == 'chameleon') {\r
183 $attr['rowspan'] = 2;\r
184 } elseif ($def->type == 'empty') {\r
185 $elements = array();\r
186 } elseif ($def->type == 'table') {\r
187 $elements = array_flip(array('col', 'caption', 'colgroup', 'thead',\r
188 'tfoot', 'tbody', 'tr'));\r
189 }\r
190 $ret .= $this->element('th', 'Allowed children', $attr);\r
191\r
192 if ($def->type == 'chameleon') {\r
193\r
194 $ret .= $this->element('td',\r
195 '<em>Block</em>: ' .\r
196 $this->escape($this->listifyTagLookup($def->block->elements)),0,0);\r
197 $ret .= $this->end('tr');\r
198 $ret .= $this->start('tr');\r
199 $ret .= $this->element('td',\r
200 '<em>Inline</em>: ' .\r
201 $this->escape($this->listifyTagLookup($def->inline->elements)),0,0);\r
202\r
203 } elseif ($def->type == 'custom') {\r
204\r
205 $ret .= $this->element('td', '<em>'.ucfirst($def->type).'</em>: ' .\r
206 $def->dtd_regex);\r
207\r
208 } else {\r
209 $ret .= $this->element('td',\r
210 '<em>'.ucfirst($def->type).'</em>: ' .\r
211 $this->escape($this->listifyTagLookup($elements)),0,0);\r
212 }\r
213 $ret .= $this->end('tr');\r
214 return $ret;\r
215 }\r
216\r
217 /**\r
218 * Listifies a tag lookup table.\r
219 * @param $array Tag lookup array in form of array('tagname' => true)\r
220 */\r
221 protected function listifyTagLookup($array) {\r
222 ksort($array);\r
223 $list = array();\r
224 foreach ($array as $name => $discard) {\r
225 if ($name !== '#PCDATA' && !isset($this->def->info[$name])) continue;\r
226 $list[] = $name;\r
227 }\r
228 return $this->listify($list);\r
229 }\r
230\r
231 /**\r
232 * Listifies a list of objects by retrieving class names and internal state\r
233 * @param $array List of objects\r
234 * @todo Also add information about internal state\r
235 */\r
236 protected function listifyObjectList($array) {\r
237 ksort($array);\r
238 $list = array();\r
239 foreach ($array as $discard => $obj) {\r
240 $list[] = $this->getClass($obj, 'AttrTransform_');\r
241 }\r
242 return $this->listify($list);\r
243 }\r
244\r
245 /**\r
246 * Listifies a hash of attributes to AttrDef classes\r
247 * @param $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef)\r
248 */\r
249 protected function listifyAttr($array) {\r
250 ksort($array);\r
251 $list = array();\r
252 foreach ($array as $name => $obj) {\r
253 if ($obj === false) continue;\r
254 $list[] = "$name&nbsp;=&nbsp;<i>" . $this->getClass($obj, 'AttrDef_') . '</i>';\r
255 }\r
256 return $this->listify($list);\r
257 }\r
258\r
259 /**\r
260 * Creates a heavy header row\r
261 */\r
262 protected function heavyHeader($text, $num = 1) {\r
263 $ret = '';\r
264 $ret .= $this->start('tr');\r
265 $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy'));\r
266 $ret .= $this->end('tr');\r
267 return $ret;\r
268 }\r
269\r
270}\r
271\r
272// vim: et sw=4 sts=4\r