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