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 }