mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-12-22 16:31:53 +00:00
Implement %AutoFormat.RemoveEmpty.RemoveNbsp, by popular demand.
Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
This commit is contained in:
parent
398a02039e
commit
e3c2063f69
4
NEWS
4
NEWS
@ -20,6 +20,10 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
! Implement %HTML.Attr.Name.UseCDATA, which relaxes validation rules on
|
! Implement %HTML.Attr.Name.UseCDATA, which relaxes validation rules on
|
||||||
the name attribute when set. Use with care. Thanks Ian Cook for
|
the name attribute when set. Use with care. Thanks Ian Cook for
|
||||||
sponsoring.
|
sponsoring.
|
||||||
|
! Implement %AutoFormat.RemoveEmpty.RemoveNbsp, which removes empty
|
||||||
|
tags that contain non-breaking spaces as well other whitespace. You
|
||||||
|
can also modify which tags should have maintained with
|
||||||
|
%AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.
|
||||||
|
|
||||||
3.3.0, released 2009-02-16
|
3.3.0, released 2009-02-16
|
||||||
! Implement CSS property 'overflow' when %CSS.AllowTricky is true.
|
! Implement CSS property 'overflow' when %CSS.AllowTricky is true.
|
||||||
|
Binary file not shown.
@ -0,0 +1,11 @@
|
|||||||
|
AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions
|
||||||
|
TYPE: lookup
|
||||||
|
VERSION: 4.0.0
|
||||||
|
DEFAULT: array('td' => true, 'th' => true)
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
When %AutoFormat.RemoveEmpty and %AutoFormat.RemoveEmpty.RemoveNbsp
|
||||||
|
are enabled, this directive defines what HTML elements should not be
|
||||||
|
removede if they have only a non-breaking space in them.
|
||||||
|
</p>
|
||||||
|
--# vim: et sw=4 sts=4
|
@ -0,0 +1,15 @@
|
|||||||
|
AutoFormat.RemoveEmpty.RemoveNbsp
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 4.0.0
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
When enabled, HTML Purifier will treat any elements that contain only
|
||||||
|
non-breaking spaces as well as regular whitespace as empty, and remove
|
||||||
|
them when %AutoForamt.RemoveEmpty is enabled.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements
|
||||||
|
that don't have this behavior applied to them.
|
||||||
|
</p>
|
||||||
|
--# vim: et sw=4 sts=4
|
@ -31,7 +31,8 @@ DEFAULT: false
|
|||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Elements that contain only whitespace will be treated as empty. Non-breaking
|
Elements that contain only whitespace will be treated as empty. Non-breaking
|
||||||
spaces, however, do not count as whitespace.
|
spaces, however, do not count as whitespace. See
|
||||||
|
%AutoFormat.RemoveEmpty.RemoveNbsp for alternate behavior.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This algorithm is not perfect; you may still notice some empty tags,
|
This algorithm is not perfect; you may still notice some empty tags,
|
||||||
@ -39,7 +40,7 @@ DEFAULT: false
|
|||||||
because they were not permitted in that context, or tags that, after
|
because they were not permitted in that context, or tags that, after
|
||||||
being auto-closed by another tag, where empty. This is for safety reasons
|
being auto-closed by another tag, where empty. This is for safety reasons
|
||||||
to prevent clever code from breaking validation. The general rule of thumb:
|
to prevent clever code from breaking validation. The general rule of thumb:
|
||||||
if a tag looked empty on the way end, it will get removed; if HTML Purifier
|
if a tag looked empty on the way in, it will get removed; if HTML Purifier
|
||||||
made it empty, it will stay.
|
made it empty, it will stay.
|
||||||
</p>
|
</p>
|
||||||
--# vim: et sw=4 sts=4
|
--# vim: et sw=4 sts=4
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
|
class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
|
||||||
{
|
{
|
||||||
|
|
||||||
private $context, $config;
|
private $context, $config, $attrValidator, $removeNbsp, $removeNbspExceptions;
|
||||||
|
|
||||||
public function prepare($config, $context) {
|
public function prepare($config, $context) {
|
||||||
parent::prepare($config, $context);
|
parent::prepare($config, $context);
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->context = $context;
|
$this->context = $context;
|
||||||
|
$this->removeNbsp = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp');
|
||||||
|
$this->removeNbspExceptions = $config->get('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions');
|
||||||
$this->attrValidator = new HTMLPurifier_AttrValidator();
|
$this->attrValidator = new HTMLPurifier_AttrValidator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +19,14 @@ class HTMLPurifier_Injector_RemoveEmpty extends HTMLPurifier_Injector
|
|||||||
$next = false;
|
$next = false;
|
||||||
for ($i = $this->inputIndex + 1, $c = count($this->inputTokens); $i < $c; $i++) {
|
for ($i = $this->inputIndex + 1, $c = count($this->inputTokens); $i < $c; $i++) {
|
||||||
$next = $this->inputTokens[$i];
|
$next = $this->inputTokens[$i];
|
||||||
if ($next instanceof HTMLPurifier_Token_Text && $next->is_whitespace) continue;
|
if ($next instanceof HTMLPurifier_Token_Text) {
|
||||||
|
if ($next->is_whitespace) continue;
|
||||||
|
if ($this->removeNbsp && !isset($this->removeNbspExceptions[$token->name])) {
|
||||||
|
$plain = str_replace("\xC2\xA0", "", $next->data);
|
||||||
|
$isWsOrNbsp = $plain === '' || ctype_space($plain);
|
||||||
|
if ($isWsOrNbsp) continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
|
if (!$next || ($next instanceof HTMLPurifier_Token_End && $next->name == $token->name)) {
|
||||||
|
@ -72,6 +72,8 @@ class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy
|
|||||||
$custom_injectors = $injectors['Custom'];
|
$custom_injectors = $injectors['Custom'];
|
||||||
unset($injectors['Custom']); // special case
|
unset($injectors['Custom']); // special case
|
||||||
foreach ($injectors as $injector => $b) {
|
foreach ($injectors as $injector => $b) {
|
||||||
|
// XXX: Fix with a legitimate lookup table of enabled filters
|
||||||
|
if (strpos($injector, '.') !== false) continue;
|
||||||
$injector = "HTMLPurifier_Injector_$injector";
|
$injector = "HTMLPurifier_Injector_$injector";
|
||||||
if (!$b) continue;
|
if (!$b) continue;
|
||||||
$this->injectors[] = new $injector;
|
$this->injectors[] = new $injector;
|
||||||
|
@ -54,6 +54,27 @@ class HTMLPurifier_Injector_RemoveEmptyTest extends HTMLPurifier_InjectorHarness
|
|||||||
$this->assertResult('<b> <i> <u> </u> </i> </b>', '');
|
$this->assertResult('<b> <i> <u> </u> </i> </b>', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testRemoveNbsp() {
|
||||||
|
$this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true);
|
||||||
|
$this->assertResult('<b> </b>', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRemoveNbspMix() {
|
||||||
|
$this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true);
|
||||||
|
$this->assertResult('<b> </b>', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDontRemoveNbsp() {
|
||||||
|
$this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true);
|
||||||
|
$this->assertResult('<td> </b>', "<td>\xC2\xA0</td>");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRemoveNbspExceptionsSpecial() {
|
||||||
|
$this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp', true);
|
||||||
|
$this->config->set('AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions', 'b');
|
||||||
|
$this->assertResult('<b> </b>', "<b>\xC2\xA0</b>");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// vim: et sw=4 sts=4
|
// vim: et sw=4 sts=4
|
||||||
|
Loading…
Reference in New Issue
Block a user