| 1 |
efrain |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
/**
|
|
|
4 |
* Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node,
|
|
|
5 |
* and back again.
|
|
|
6 |
*
|
|
|
7 |
* @note This transformation is not an equivalence. We mutate the input
|
|
|
8 |
* token stream to make it so; see all [MUT] markers in code.
|
|
|
9 |
*/
|
|
|
10 |
class HTMLPurifier_Arborize
|
|
|
11 |
{
|
|
|
12 |
public static function arborize($tokens, $config, $context) {
|
|
|
13 |
$definition = $config->getHTMLDefinition();
|
|
|
14 |
$parent = new HTMLPurifier_Token_Start($definition->info_parent);
|
|
|
15 |
$stack = array($parent->toNode());
|
|
|
16 |
foreach ($tokens as $token) {
|
|
|
17 |
$token->skip = null; // [MUT]
|
|
|
18 |
$token->carryover = null; // [MUT]
|
|
|
19 |
if ($token instanceof HTMLPurifier_Token_End) {
|
|
|
20 |
$token->start = null; // [MUT]
|
|
|
21 |
$r = array_pop($stack);
|
|
|
22 |
//assert($r->name === $token->name);
|
|
|
23 |
//assert(empty($token->attr));
|
|
|
24 |
$r->endCol = $token->col;
|
|
|
25 |
$r->endLine = $token->line;
|
|
|
26 |
$r->endArmor = $token->armor;
|
|
|
27 |
continue;
|
|
|
28 |
}
|
|
|
29 |
$node = $token->toNode();
|
|
|
30 |
$stack[count($stack)-1]->children[] = $node;
|
|
|
31 |
if ($token instanceof HTMLPurifier_Token_Start) {
|
|
|
32 |
$stack[] = $node;
|
|
|
33 |
}
|
|
|
34 |
}
|
|
|
35 |
//assert(count($stack) == 1);
|
|
|
36 |
return $stack[0];
|
|
|
37 |
}
|
|
|
38 |
|
|
|
39 |
public static function flatten($node, $config, $context) {
|
|
|
40 |
$level = 0;
|
|
|
41 |
$nodes = array($level => new HTMLPurifier_Queue(array($node)));
|
|
|
42 |
$closingTokens = array();
|
|
|
43 |
$tokens = array();
|
|
|
44 |
do {
|
|
|
45 |
while (!$nodes[$level]->isEmpty()) {
|
|
|
46 |
$node = $nodes[$level]->shift(); // FIFO
|
|
|
47 |
list($start, $end) = $node->toTokenPair();
|
|
|
48 |
if ($level > 0) {
|
|
|
49 |
$tokens[] = $start;
|
|
|
50 |
}
|
|
|
51 |
if ($end !== NULL) {
|
|
|
52 |
$closingTokens[$level][] = $end;
|
|
|
53 |
}
|
|
|
54 |
if ($node instanceof HTMLPurifier_Node_Element) {
|
|
|
55 |
$level++;
|
|
|
56 |
$nodes[$level] = new HTMLPurifier_Queue();
|
|
|
57 |
foreach ($node->children as $childNode) {
|
|
|
58 |
$nodes[$level]->push($childNode);
|
|
|
59 |
}
|
|
|
60 |
}
|
|
|
61 |
}
|
|
|
62 |
$level--;
|
|
|
63 |
if ($level && isset($closingTokens[$level])) {
|
|
|
64 |
while ($token = array_pop($closingTokens[$level])) {
|
|
|
65 |
$tokens[] = $token;
|
|
|
66 |
}
|
|
|
67 |
}
|
|
|
68 |
} while ($level > 0);
|
|
|
69 |
return $tokens;
|
|
|
70 |
}
|
|
|
71 |
}
|