]> git.mxchange.org Git - friendica.git/blob - library/HTMLPurifier/ChildDef/Table.php
34f0227dd2cc549f4dacef4efd9d6ae8b43680d9
[friendica.git] / library / HTMLPurifier / ChildDef / Table.php
1 <?php
2
3 /**
4  * Definition for tables
5  */
6 class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
7 {
8     public $allow_empty = false;
9     public $type = 'table';
10     public $elements = array('tr' => true, 'tbody' => true, 'thead' => true,
11         'tfoot' => true, 'caption' => true, 'colgroup' => true, 'col' => true);
12     public function __construct() {}
13     public function validateChildren($tokens_of_children, $config, $context) {
14         if (empty($tokens_of_children)) return false;
15
16         // this ensures that the loop gets run one last time before closing
17         // up. It's a little bit of a hack, but it works! Just make sure you
18         // get rid of the token later.
19         $tokens_of_children[] = false;
20
21         // only one of these elements is allowed in a table
22         $caption = false;
23         $thead   = false;
24         $tfoot   = false;
25
26         // as many of these as you want
27         $cols    = array();
28         $content = array();
29
30         $nesting = 0; // current depth so we can determine nodes
31         $is_collecting = false; // are we globbing together tokens to package
32                                 // into one of the collectors?
33         $collection = array(); // collected nodes
34         $tag_index = 0; // the first node might be whitespace,
35                             // so this tells us where the start tag is
36
37         foreach ($tokens_of_children as $token) {
38             $is_child = ($nesting == 0);
39
40             if ($token === false) {
41                 // terminating sequence started
42             } elseif ($token instanceof HTMLPurifier_Token_Start) {
43                 $nesting++;
44             } elseif ($token instanceof HTMLPurifier_Token_End) {
45                 $nesting--;
46             }
47
48             // handle node collection
49             if ($is_collecting) {
50                 if ($is_child) {
51                     // okay, let's stash the tokens away
52                     // first token tells us the type of the collection
53                     switch ($collection[$tag_index]->name) {
54                         case 'tr':
55                         case 'tbody':
56                             $content[] = $collection;
57                             break;
58                         case 'caption':
59                             if ($caption !== false) break;
60                             $caption = $collection;
61                             break;
62                         case 'thead':
63                         case 'tfoot':
64                             // access the appropriate variable, $thead or $tfoot
65                             $var = $collection[$tag_index]->name;
66                             if ($$var === false) {
67                                 $$var = $collection;
68                             } else {
69                                 // transmutate the first and less entries into
70                                 // tbody tags, and then put into content
71                                 $collection[$tag_index]->name = 'tbody';
72                                 $collection[count($collection)-1]->name = 'tbody';
73                                 $content[] = $collection;
74                             }
75                             break;
76                          case 'colgroup':
77                             $cols[] = $collection;
78                             break;
79                     }
80                     $collection = array();
81                     $is_collecting = false;
82                     $tag_index = 0;
83                 } else {
84                     // add the node to the collection
85                     $collection[] = $token;
86                 }
87             }
88
89             // terminate
90             if ($token === false) break;
91
92             if ($is_child) {
93                 // determine what we're dealing with
94                 if ($token->name == 'col') {
95                     // the only empty tag in the possie, we can handle it
96                     // immediately
97                     $cols[] = array_merge($collection, array($token));
98                     $collection = array();
99                     $tag_index = 0;
100                     continue;
101                 }
102                 switch($token->name) {
103                     case 'caption':
104                     case 'colgroup':
105                     case 'thead':
106                     case 'tfoot':
107                     case 'tbody':
108                     case 'tr':
109                         $is_collecting = true;
110                         $collection[] = $token;
111                         continue;
112                     default:
113                         if (!empty($token->is_whitespace)) {
114                             $collection[] = $token;
115                             $tag_index++;
116                         }
117                         continue;
118                 }
119             }
120         }
121
122         if (empty($content)) return false;
123
124         $ret = array();
125         if ($caption !== false) $ret = array_merge($ret, $caption);
126         if ($cols !== false)    foreach ($cols as $token_array) $ret = array_merge($ret, $token_array);
127         if ($thead !== false)   $ret = array_merge($ret, $thead);
128         if ($tfoot !== false)   $ret = array_merge($ret, $tfoot);
129         foreach ($content as $token_array) $ret = array_merge($ret, $token_array);
130         if (!empty($collection) && $is_collecting == false){
131             // grab the trailing space
132             $ret = array_merge($ret, $collection);
133         }
134
135         array_pop($tokens_of_children); // remove phantom token
136
137         return ($ret === $tokens_of_children) ? true : $ret;
138
139     }
140 }
141
142 // vim: et sw=4 sts=4