--- /dev/null
+<?php\r
+\r
+/**\r
+ * Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node,\r
+ * and back again.\r
+ *\r
+ * @note This transformation is not an equivalence. We mutate the input\r
+ * token stream to make it so; see all [MUT] markers in code.\r
+ */\r
+class HTMLPurifier_Arborize\r
+{\r
+ public static function arborize($tokens, $config, $context) {\r
+ $definition = $config->getHTMLDefinition();\r
+ $parent = new HTMLPurifier_Token_Start($definition->info_parent);\r
+ $stack = array($parent->toNode());\r
+ foreach ($tokens as $token) {\r
+ $token->skip = null; // [MUT]\r
+ $token->carryover = null; // [MUT]\r
+ if ($token instanceof HTMLPurifier_Token_End) {\r
+ $token->start = null; // [MUT]\r
+ $r = array_pop($stack);\r
+ assert($r->name === $token->name);\r
+ assert(empty($token->attr));\r
+ $r->endCol = $token->col;\r
+ $r->endLine = $token->line;\r
+ $r->endArmor = $token->armor;\r
+ continue;\r
+ }\r
+ $node = $token->toNode();\r
+ $stack[count($stack)-1]->children[] = $node;\r
+ if ($token instanceof HTMLPurifier_Token_Start) {\r
+ $stack[] = $node;\r
+ }\r
+ }\r
+ assert(count($stack) == 1);\r
+ return $stack[0];\r
+ }\r
+\r
+ public static function flatten($node, $config, $context) {\r
+ $level = 0;\r
+ $nodes = array($level => new HTMLPurifier_Queue(array($node)));\r
+ $closingTokens = array();\r
+ $tokens = array();\r
+ do {\r
+ while (!$nodes[$level]->isEmpty()) {\r
+ $node = $nodes[$level]->shift(); // FIFO\r
+ list($start, $end) = $node->toTokenPair();\r
+ if ($level > 0) {\r
+ $tokens[] = $start;\r
+ }\r
+ if ($end !== NULL) {\r
+ $closingTokens[$level][] = $end;\r
+ }\r
+ if ($node instanceof HTMLPurifier_Node_Element) {\r
+ $level++;\r
+ $nodes[$level] = new HTMLPurifier_Queue();\r
+ foreach ($node->children as $childNode) {\r
+ $nodes[$level]->push($childNode);\r
+ }\r
+ }\r
+ }\r
+ $level--;\r
+ if ($level && isset($closingTokens[$level])) {\r
+ while ($token = array_pop($closingTokens[$level])) {\r
+ $tokens[] = $token;\r
+ }\r
+ }\r
+ } while ($level > 0);\r
+ return $tokens;\r
+ }\r
+}\r