142 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
	
		
			5.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /**
 | |
|  * Definition for tables
 | |
|  */
 | |
| class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
 | |
| {
 | |
|     public $allow_empty = false;
 | |
|     public $type = 'table';
 | |
|     public $elements = array('tr' => true, 'tbody' => true, 'thead' => true,
 | |
|         'tfoot' => true, 'caption' => true, 'colgroup' => true, 'col' => true);
 | |
|     public function __construct() {}
 | |
|     public function validateChildren($tokens_of_children, $config, $context) {
 | |
|         if (empty($tokens_of_children)) return false;
 | |
| 
 | |
|         // this ensures that the loop gets run one last time before closing
 | |
|         // up. It's a little bit of a hack, but it works! Just make sure you
 | |
|         // get rid of the token later.
 | |
|         $tokens_of_children[] = false;
 | |
| 
 | |
|         // only one of these elements is allowed in a table
 | |
|         $caption = false;
 | |
|         $thead   = false;
 | |
|         $tfoot   = false;
 | |
| 
 | |
|         // as many of these as you want
 | |
|         $cols    = array();
 | |
|         $content = array();
 | |
| 
 | |
|         $nesting = 0; // current depth so we can determine nodes
 | |
|         $is_collecting = false; // are we globbing together tokens to package
 | |
|                                 // into one of the collectors?
 | |
|         $collection = array(); // collected nodes
 | |
|         $tag_index = 0; // the first node might be whitespace,
 | |
|                             // so this tells us where the start tag is
 | |
| 
 | |
|         foreach ($tokens_of_children as $token) {
 | |
|             $is_child = ($nesting == 0);
 | |
| 
 | |
|             if ($token === false) {
 | |
|                 // terminating sequence started
 | |
|             } elseif ($token instanceof HTMLPurifier_Token_Start) {
 | |
|                 $nesting++;
 | |
|             } elseif ($token instanceof HTMLPurifier_Token_End) {
 | |
|                 $nesting--;
 | |
|             }
 | |
| 
 | |
|             // handle node collection
 | |
|             if ($is_collecting) {
 | |
|                 if ($is_child) {
 | |
|                     // okay, let's stash the tokens away
 | |
|                     // first token tells us the type of the collection
 | |
|                     switch ($collection[$tag_index]->name) {
 | |
|                         case 'tr':
 | |
|                         case 'tbody':
 | |
|                             $content[] = $collection;
 | |
|                             break;
 | |
|                         case 'caption':
 | |
|                             if ($caption !== false) break;
 | |
|                             $caption = $collection;
 | |
|                             break;
 | |
|                         case 'thead':
 | |
|                         case 'tfoot':
 | |
|                             // access the appropriate variable, $thead or $tfoot
 | |
|                             $var = $collection[$tag_index]->name;
 | |
|                             if ($$var === false) {
 | |
|                                 $$var = $collection;
 | |
|                             } else {
 | |
|                                 // transmutate the first and less entries into
 | |
|                                 // tbody tags, and then put into content
 | |
|                                 $collection[$tag_index]->name = 'tbody';
 | |
|                                 $collection[count($collection)-1]->name = 'tbody';
 | |
|                                 $content[] = $collection;
 | |
|                             }
 | |
|                             break;
 | |
|                          case 'colgroup':
 | |
|                             $cols[] = $collection;
 | |
|                             break;
 | |
|                     }
 | |
|                     $collection = array();
 | |
|                     $is_collecting = false;
 | |
|                     $tag_index = 0;
 | |
|                 } else {
 | |
|                     // add the node to the collection
 | |
|                     $collection[] = $token;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // terminate
 | |
|             if ($token === false) break;
 | |
| 
 | |
|             if ($is_child) {
 | |
|                 // determine what we're dealing with
 | |
|                 if ($token->name == 'col') {
 | |
|                     // the only empty tag in the possie, we can handle it
 | |
|                     // immediately
 | |
|                     $cols[] = array_merge($collection, array($token));
 | |
|                     $collection = array();
 | |
|                     $tag_index = 0;
 | |
|                     continue;
 | |
|                 }
 | |
|                 switch($token->name) {
 | |
|                     case 'caption':
 | |
|                     case 'colgroup':
 | |
|                     case 'thead':
 | |
|                     case 'tfoot':
 | |
|                     case 'tbody':
 | |
|                     case 'tr':
 | |
|                         $is_collecting = true;
 | |
|                         $collection[] = $token;
 | |
|                         continue;
 | |
|                     default:
 | |
|                         if (!empty($token->is_whitespace)) {
 | |
|                             $collection[] = $token;
 | |
|                             $tag_index++;
 | |
|                         }
 | |
|                         continue;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (empty($content)) return false;
 | |
| 
 | |
|         $ret = array();
 | |
|         if ($caption !== false) $ret = array_merge($ret, $caption);
 | |
|         if ($cols !== false)    foreach ($cols as $token_array) $ret = array_merge($ret, $token_array);
 | |
|         if ($thead !== false)   $ret = array_merge($ret, $thead);
 | |
|         if ($tfoot !== false)   $ret = array_merge($ret, $tfoot);
 | |
|         foreach ($content as $token_array) $ret = array_merge($ret, $token_array);
 | |
|         if (!empty($collection) && $is_collecting == false){
 | |
|             // grab the trailing space
 | |
|             $ret = array_merge($ret, $collection);
 | |
|         }
 | |
| 
 | |
|         array_pop($tokens_of_children); // remove phantom token
 | |
| 
 | |
|         return ($ret === $tokens_of_children) ? true : $ret;
 | |
| 
 | |
|     }
 | |
| }
 | |
| 
 | |
| // vim: et sw=4 sts=4
 |