]> git.wh0rd.org - tt-rss.git/blob - lib/htmlpurifier/library/HTMLPurifier/ChildDef/Table.php
update HTMLPurifier; enable embedded flash video in articles
[tt-rss.git] / lib / htmlpurifier / 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