mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-12-22 08:21:52 +00:00
Extract FixNesting strategy from Definition object.
git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@113 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
2e6a5c10b3
commit
d98f1742ec
102
library/HTMLPurifier/Strategy/FixNesting.php
Normal file
102
library/HTMLPurifier/Strategy/FixNesting.php
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
require_once 'HTMLPurifier/Strategy.php';
|
||||
require_once 'HTMLPurifier/Definition.php';
|
||||
|
||||
class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy
|
||||
{
|
||||
|
||||
var $definition;
|
||||
|
||||
function HTMLPurifier_Definition() {
|
||||
$this->definition = HTMLPurifier_Definition::instance();
|
||||
}
|
||||
|
||||
function execute($tokens) {
|
||||
// insert implicit "parent" node, will be removed at end
|
||||
array_unshift($tokens, new HTMLPurifier_Token_Start('div'));
|
||||
$tokens[] = new HTMLPurifier_Token_End('div');
|
||||
|
||||
for ($i = 0, $size = count($tokens) ; $i < $size; ) {
|
||||
|
||||
$child_tokens = array();
|
||||
|
||||
// scroll to the end of this node, and report number
|
||||
for ($j = $i, $depth = 0; ; $j++) {
|
||||
if ($tokens[$j]->type == 'start') {
|
||||
$depth++;
|
||||
// skip token assignment on first iteration
|
||||
if ($depth == 1) continue;
|
||||
} elseif ($tokens[$j]->type == 'end') {
|
||||
$depth--;
|
||||
// skip token assignment on last iteration
|
||||
if ($depth == 0) break;
|
||||
}
|
||||
$child_tokens[] = $tokens[$j];
|
||||
}
|
||||
|
||||
// $i is index of start token
|
||||
// $j is index of end token
|
||||
|
||||
// have DTD child def validate children
|
||||
$element_def = $this->definition->info[$tokens[$i]->name];
|
||||
$result = $element_def->child_def->validateChildren($child_tokens);
|
||||
|
||||
// process result
|
||||
if ($result === true) {
|
||||
|
||||
// leave the nodes as is
|
||||
|
||||
} elseif($result === false) {
|
||||
|
||||
// WARNING WARNING WARNING!!!
|
||||
// While for the original DTD, there will never be
|
||||
// cascading removal, more complex ones may have such
|
||||
// a problem.
|
||||
|
||||
// If you modify the info array such that an element
|
||||
// that requires children may contain a child that requires
|
||||
// children, you need to also scroll back and re-check that
|
||||
// elements parent node
|
||||
|
||||
$length = $j - $i + 1;
|
||||
|
||||
// remove entire node
|
||||
array_splice($tokens, $i, $length);
|
||||
|
||||
// change size
|
||||
$size -= $length;
|
||||
|
||||
// ensure that we scroll to the next node
|
||||
$i--;
|
||||
|
||||
} else {
|
||||
|
||||
$length = $j - $i - 1;
|
||||
|
||||
// replace node with $result
|
||||
array_splice($tokens, $i + 1, $length, $result);
|
||||
|
||||
// change size
|
||||
$size -= $length;
|
||||
$size += count($result);
|
||||
|
||||
}
|
||||
|
||||
// scroll to next node
|
||||
$i++;
|
||||
while ($i < $size and $tokens[$i]->type != 'start') $i++;
|
||||
|
||||
}
|
||||
|
||||
// remove implicit divs
|
||||
array_shift($tokens);
|
||||
array_pop($tokens);
|
||||
|
||||
return $tokens;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
Loading…
Reference in New Issue
Block a user