root/afridex/plugins/Flutter/purifier_lib/HTMLPurifier/ChildDef/Table.php @ 21

Revision 21, 5.7 kB (checked in by admin, 18 years ago)
Line 
1<?php
2
3/**
4 * Definition for tables
5 */
6class 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 ($token instanceof HTMLPurifier_Token_Text && $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
Note: See TracBrowser for help on using the browser.