1
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2025-08-05 05:37:49 +02:00

Implement "carryover" functionality, requested by Kinderlehrer <bitweaver@7doves.com>

This commit is a limited implementation of the "active formatting
elements" algorithm implemented in HTML5, which preserves certain
formatting elements such as <a> and <b> when exiting or entering nodes.

Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
This commit is contained in:
Edward Z. Yang
2008-12-20 13:06:00 -05:00
parent 119ebcda71
commit bfe474042f
17 changed files with 121 additions and 33 deletions

View File

@@ -159,12 +159,9 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
continue;
}
// if all goes well, this token will be passed through unharmed
$token = $tokens[$t];
//echo '<hr>';
//printTokens($tokens, $t);
//var_dump($this->stack);
//echo '<br>'; printTokens($tokens, $t); printTokens($this->stack);
// quick-check: if it's not a tag, no need to process
if (empty($token->is_tag)) {
@@ -214,18 +211,36 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
$this->stack[] = $parent;
if (isset($definition->info[$parent->name])) {
$elements = $definition->info[$parent->name]->child->getNonAutoCloseElements($config);
$elements = $definition->info[$parent->name]->child->getAllowedElements($config);
$autoclose = !isset($elements[$token->name]);
} else {
$autoclose = false;
}
$carryover = false;
if ($autoclose && $definition->info[$parent->name]->formatting) {
$carryover = true;
}
if ($autoclose) {
if ($e) $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent);
// insert parent end tag before this tag
// errors need to be updated
$new_token = new HTMLPurifier_Token_End($parent->name);
$new_token->start = $parent;
$this->insertBefore($new_token);
if ($carryover) {
$element = clone $parent;
$element->armor['MakeWellFormed_TagClosedError'] = true;
$element->carryover = true;
$this->processToken(array($new_token, $token, $element));
} else {
$this->insertBefore($new_token);
}
if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) {
if (!$carryover) {
$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent);
} else {
$e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent);
}
}
$reprocess = true;
continue;
}
@@ -339,12 +354,20 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
}
// insert tags, in FORWARD $j order: c,b,a with </a></b></c>
$replace = array($token);
for ($j = 1; $j < $c; $j++) {
// ...as well as from the insertions
$new_token = new HTMLPurifier_Token_End($skipped_tags[$j]->name);
$new_token->start = $skipped_tags[$j];
$this->insertBefore($new_token);
array_unshift($replace, $new_token);
if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) {
$element = clone $skipped_tags[$j];
$element->carryover = true;
$element->armor['MakeWellFormed_TagClosedError'] = true;
$replace[] = $element;
}
}
$this->processToken($replace);
$reprocess = true;
continue;
}