mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-11-09 15:28:40 +00:00
Implement auto-formatter that removes empty span tags.
Signed-off-by: Paul Stone <patches@pdjs.co.uk> Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
This commit is contained in:
parent
aea7d02dfe
commit
9a9036c689
@ -176,6 +176,7 @@ require 'HTMLPurifier/Injector/DisplayLinkURI.php';
|
|||||||
require 'HTMLPurifier/Injector/Linkify.php';
|
require 'HTMLPurifier/Injector/Linkify.php';
|
||||||
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
require 'HTMLPurifier/Injector/PurifierLinkify.php';
|
||||||
require 'HTMLPurifier/Injector/RemoveEmpty.php';
|
require 'HTMLPurifier/Injector/RemoveEmpty.php';
|
||||||
|
require 'HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
|
||||||
require 'HTMLPurifier/Injector/SafeObject.php';
|
require 'HTMLPurifier/Injector/SafeObject.php';
|
||||||
require 'HTMLPurifier/Lexer/DOMLex.php';
|
require 'HTMLPurifier/Lexer/DOMLex.php';
|
||||||
require 'HTMLPurifier/Lexer/DirectLex.php';
|
require 'HTMLPurifier/Lexer/DirectLex.php';
|
||||||
|
@ -170,6 +170,7 @@ require_once $__dir . '/HTMLPurifier/Injector/DisplayLinkURI.php';
|
|||||||
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
require_once $__dir . '/HTMLPurifier/Injector/Linkify.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
require_once $__dir . '/HTMLPurifier/Injector/PurifierLinkify.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
|
require_once $__dir . '/HTMLPurifier/Injector/RemoveEmpty.php';
|
||||||
|
require_once $__dir . '/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
|
require_once $__dir . '/HTMLPurifier/Injector/SafeObject.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
require_once $__dir . '/HTMLPurifier/Lexer/DOMLex.php';
|
||||||
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
require_once $__dir . '/HTMLPurifier/Lexer/DirectLex.php';
|
||||||
|
Binary file not shown.
@ -0,0 +1,11 @@
|
|||||||
|
AutoFormat.RemoveSpansWithoutAttributes
|
||||||
|
TYPE: bool
|
||||||
|
VERSION: 4.0.1
|
||||||
|
DEFAULT: false
|
||||||
|
--DESCRIPTION--
|
||||||
|
<p>
|
||||||
|
This directive causes <code>span</code> tags without any attributes
|
||||||
|
to be removed. It will also remove spans that had all attributes
|
||||||
|
removed during processing.
|
||||||
|
</p>
|
||||||
|
--# vim: et sw=4 sts=4
|
60
library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php
Executable file
60
library/HTMLPurifier/Injector/RemoveSpansWithoutAttributes.php
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injector that removes spans with no attributes
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_Injector
|
||||||
|
{
|
||||||
|
public $name = 'RemoveSpansWithoutAttributes';
|
||||||
|
public $needed = array('span');
|
||||||
|
|
||||||
|
private $attrValidator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by AttrValidator
|
||||||
|
*/
|
||||||
|
private $config;
|
||||||
|
private $context;
|
||||||
|
|
||||||
|
public function prepare($config, $context) {
|
||||||
|
$this->attrValidator = new HTMLPurifier_AttrValidator();
|
||||||
|
$this->config = $config;
|
||||||
|
$this->context = $context;
|
||||||
|
return parent::prepare($config, $context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleElement(&$token) {
|
||||||
|
if ($token->name !== 'span' || !$token instanceof HTMLPurifier_Token_Start) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to validate the attributes now since this doesn't normally
|
||||||
|
// happen until after MakeWellFormed. If all the attributes are removed
|
||||||
|
// the span needs to be removed too.
|
||||||
|
$this->attrValidator->validateToken($token, $this->config, $this->context);
|
||||||
|
$token->armor['ValidateAttributes'] = true;
|
||||||
|
|
||||||
|
if (!empty($token->attr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$nesting = 0;
|
||||||
|
$spanContentTokens = array();
|
||||||
|
while ($this->forwardUntilEndToken(&$i, &$current, &$nesting)) {}
|
||||||
|
|
||||||
|
if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') {
|
||||||
|
// Mark closing span tag for deletion
|
||||||
|
$current->markForDeletion = true;
|
||||||
|
// Delete open span tag
|
||||||
|
$token = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleEnd(&$token) {
|
||||||
|
if ($token->markForDeletion) {
|
||||||
|
$token = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: et sw=4 sts=4
|
99
tests/HTMLPurifier/Injector/RemoveSpansWithoutAttributesTest.php
Executable file
99
tests/HTMLPurifier/Injector/RemoveSpansWithoutAttributesTest.php
Executable file
@ -0,0 +1,99 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_Injector_RemoveSpansWithoutAttributesTest extends HTMLPurifier_InjectorHarness
|
||||||
|
{
|
||||||
|
function setup() {
|
||||||
|
parent::setup();
|
||||||
|
$this->config->set('HTML.Allowed', 'span[class],div,p,strong,em');
|
||||||
|
$this->config->set('AutoFormat.RemoveSpansWithoutAttributes', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSingleSpan() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<span>foo</span>',
|
||||||
|
'foo'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSingleSpanWithAttributes() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<span class="bar">foo</span>',
|
||||||
|
'<span class="bar">foo</span>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSingleNestedSpan() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<p><span>foo</span></p>',
|
||||||
|
'<p>foo</p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSingleNestedSpanWithAttributes() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<p><span class="bar">foo</span></p>',
|
||||||
|
'<p><span class="bar">foo</span></p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testSpanWithChildren() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<span>foo <strong>bar</strong> <em>baz</em></span>',
|
||||||
|
'foo <strong>bar</strong> <em>baz</em>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSpanWithSiblings() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<p>before <span>inside</span> <strong>after</strong></p>',
|
||||||
|
'<p>before inside <strong>after</strong></p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNestedSpanWithSiblingsAndChildren() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<p>a <span>b <em>c</em> d</span> e</p>',
|
||||||
|
'<p>a b <em>c</em> d e</p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNestedSpansWithoutAttributes() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<span>one<span>two<span>three</span></span></span>',
|
||||||
|
'onetwothree'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDeeplyNestedSpan() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<div><div><div><span class="a">a <span>b</span> c</span></div></div></div>',
|
||||||
|
'<div><div><div><span class="a">a b c</span></div></div></div>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSpanWithInvalidAttributes() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<p><span snorkel buzzer="emu">foo</span></p>',
|
||||||
|
'<p>foo</p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNestedAlternateSpans() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<span>a <span class="x">b <span>c <span class="y">d <span>e <span class="z">f
|
||||||
|
</span></span></span></span></span></span>',
|
||||||
|
'a <span class="x">b c <span class="y">d e <span class="z">f
|
||||||
|
</span></span></span>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSpanWithSomeInvalidAttributes() {
|
||||||
|
$this->assertResult(
|
||||||
|
'<p><span buzzer="emu" class="bar">foo</span></p>',
|
||||||
|
'<p><span class="bar">foo</span></p>'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: et sw=4 sts=4
|
Loading…
Reference in New Issue
Block a user