File indexing completed on 2024-12-22 05:36:21
0001 <?php 0002 0003 /** 0004 * Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node, 0005 * and back again. 0006 * 0007 * @note This transformation is not an equivalence. We mutate the input 0008 * token stream to make it so; see all [MUT] markers in code. 0009 */ 0010 class HTMLPurifier_Arborize 0011 { 0012 public static function arborize($tokens, $config, $context) { 0013 $definition = $config->getHTMLDefinition(); 0014 $parent = new HTMLPurifier_Token_Start($definition->info_parent); 0015 $stack = array($parent->toNode()); 0016 foreach ($tokens as $token) { 0017 $token->skip = null; // [MUT] 0018 $token->carryover = null; // [MUT] 0019 if ($token instanceof HTMLPurifier_Token_End) { 0020 $token->start = null; // [MUT] 0021 $r = array_pop($stack); 0022 //assert($r->name === $token->name); 0023 //assert(empty($token->attr)); 0024 $r->endCol = $token->col; 0025 $r->endLine = $token->line; 0026 $r->endArmor = $token->armor; 0027 continue; 0028 } 0029 $node = $token->toNode(); 0030 $stack[count($stack)-1]->children[] = $node; 0031 if ($token instanceof HTMLPurifier_Token_Start) { 0032 $stack[] = $node; 0033 } 0034 } 0035 //assert(count($stack) == 1); 0036 return $stack[0]; 0037 } 0038 0039 public static function flatten($node, $config, $context) { 0040 $level = 0; 0041 $nodes = array($level => new HTMLPurifier_Queue(array($node))); 0042 $closingTokens = array(); 0043 $tokens = array(); 0044 do { 0045 while (!$nodes[$level]->isEmpty()) { 0046 $node = $nodes[$level]->shift(); // FIFO 0047 list($start, $end) = $node->toTokenPair(); 0048 if ($level > 0) { 0049 $tokens[] = $start; 0050 } 0051 if ($end !== NULL) { 0052 $closingTokens[$level][] = $end; 0053 } 0054 if ($node instanceof HTMLPurifier_Node_Element) { 0055 $level++; 0056 $nodes[$level] = new HTMLPurifier_Queue(); 0057 foreach ($node->children as $childNode) { 0058 $nodes[$level]->push($childNode); 0059 } 0060 } 0061 } 0062 $level--; 0063 if ($level && isset($closingTokens[$level])) { 0064 while ($token = array_pop($closingTokens[$level])) { 0065 $tokens[] = $token; 0066 } 0067 } 0068 } while ($level > 0); 0069 return $tokens; 0070 } 0071 }