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