From 626cfc11721f82daacf2c00d5b8bf82910cd16b1 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Wed, 2 Aug 2006 02:24:03 +0000 Subject: [PATCH] Implement center, menu and dir tag transformations. Font transform pending. git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@140 48356398-32a2-884e-a903-53898d9a118a --- library/HTMLPurifier/Definition.php | 9 ++ .../Strategy/RemoveForeignElements.php | 14 ++- library/HTMLPurifier/TagTransform.php | 88 +++++++++++++++++ .../Strategy/RemoveForeignElementsTest.php | 8 ++ tests/HTMLPurifier/TagTransformTest.php | 98 +++++++++++++++++++ tests/index.php | 4 + 6 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 library/HTMLPurifier/TagTransform.php create mode 100644 tests/HTMLPurifier/TagTransformTest.php diff --git a/library/HTMLPurifier/Definition.php b/library/HTMLPurifier/Definition.php index 0965bc69..9223a440 100644 --- a/library/HTMLPurifier/Definition.php +++ b/library/HTMLPurifier/Definition.php @@ -6,6 +6,7 @@ require_once 'HTMLPurifier/AttrDef.php'; require_once 'HTMLPurifier/ChildDef.php'; require_once 'HTMLPurifier/Generator.php'; require_once 'HTMLPurifier/Token.php'; +require_once 'HTMLPurifier/TagTransform.php'; /** * Defines the purified HTML type with large amounts of objects. @@ -39,6 +40,9 @@ class HTMLPurifier_Definition // used solely by HTMLPurifier_Strategy_FixNesting var $info_parent = 'div'; + // used solely by HTMLPurifier_Strategy_RemoveForeignElements + var $info_tag_transform = array(); + function instance() { static $instance = null; if (!$instance) { @@ -212,6 +216,11 @@ class HTMLPurifier_Definition // dir -> ul // center -> div / css: text-align: center; + //$this->info_tag_transform['font'] = new HTMLPurifier_TagTransform_Font(); + $this->info_tag_transform['menu'] = new HTMLPurifier_TagTransform_Simple('ul'); + $this->info_tag_transform['dir'] = new HTMLPurifier_TagTransform_Simple('ul'); + $this->info_tag_transform['center'] = new HTMLPurifier_TagTransform_Center(); + ////////////////////////////////////////////////////////////////////// // info[]->auto_close : tags that automatically close another diff --git a/library/HTMLPurifier/Strategy/RemoveForeignElements.php b/library/HTMLPurifier/Strategy/RemoveForeignElements.php index ff8eb001..1f55b512 100644 --- a/library/HTMLPurifier/Strategy/RemoveForeignElements.php +++ b/library/HTMLPurifier/Strategy/RemoveForeignElements.php @@ -3,6 +3,7 @@ require_once 'HTMLPurifier/Strategy.php'; require_once 'HTMLPurifier/Definition.php'; require_once 'HTMLPurifier/Generator.php'; +require_once 'HTMLPurifier/TagTransform.php'; /** * Removes all unrecognized tags from the list of tokens. @@ -27,7 +28,18 @@ class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy foreach($tokens as $token) { if (!empty( $token->is_tag )) { // DEFINITION CALL - if (!isset($this->definition->info[$token->name])) { + if (isset($this->definition->info[$token->name])) { + // leave untouched + } elseif ( + isset($this->definition->info_tag_transform[$token->name]) + ) { + // there is a transformation for this tag + // DEFINITION CALL + $token = $this-> + definition-> + info_tag_transform[$token->name]-> + transform($token); + } else { // invalid tag, generate HTML and insert in $token = new HTMLPurifier_Token_Text( $this->generator->generateFromToken($token) diff --git a/library/HTMLPurifier/TagTransform.php b/library/HTMLPurifier/TagTransform.php new file mode 100644 index 00000000..230c348a --- /dev/null +++ b/library/HTMLPurifier/TagTransform.php @@ -0,0 +1,88 @@ +transform_to = $transform_to; + } + + function transform($tag) { + switch ($tag->type) { + case 'end': + $new_tag = new HTMLPurifier_Token_End($this->transform_to); + break; + case 'start': + $new_tag = new HTMLPurifier_Token_Start($this->transform_to, + $tag->attributes); + break; + case 'empty': + $new_tag = new HTMLPurifier_Token_Empty($this->transform_to, + $tag->attributes); + break; + default: + trigger_error('Failed tag transformation', E_USER_WARNING); + return; + } + return $new_tag; + } + +} + +class HTMLPurifier_TagTransform_Center extends HTMLPurifier_TagTransform +{ + function transform($tag) { + $attributes = $this->normalizeAttributes($tag->attributes); + $prepend_css = 'text-align:center;'; + if (isset($attributes['style'])) { + $attributes['style'] = $prepend_css . $attributes['style']; + } else { + $attributes['style'] = $prepend_css; + } + switch ($tag->type) { + case 'end': + $new_tag = new HTMLPurifier_Token_End('div'); + break; + case 'start': + $new_tag = new HTMLPurifier_Token_Start('div', $attributes); + break; + case 'empty': + $new_tag = new HTMLPurifier_Token_Empty('div', $attributes); + break; + default: + trigger_error('Failed tag transformation', E_USER_WARNING); + return; + } + return $new_tag; + } +} + +?> \ No newline at end of file diff --git a/tests/HTMLPurifier/Strategy/RemoveForeignElementsTest.php b/tests/HTMLPurifier/Strategy/RemoveForeignElementsTest.php index 1d2741c6..3fe26452 100644 --- a/tests/HTMLPurifier/Strategy/RemoveForeignElementsTest.php +++ b/tests/HTMLPurifier/Strategy/RemoveForeignElementsTest.php @@ -24,6 +24,14 @@ class HTMLPurifier_Strategy_RemoveForeignElementsTest $inputs[2] = 'BlingBong'; $expect[2] = htmlspecialchars($inputs[2]); + // test simple transform + $inputs[3] = '
  • Item 1
  • '; + $expect[3] = ''; + + // test center transform + $inputs[4] = '
    Look I am Centered!
    '; + $expect[4] = '
    Look I am Centered!
    '; + $this->assertStrategyWorks($strategy, $inputs, $expect); } diff --git a/tests/HTMLPurifier/TagTransformTest.php b/tests/HTMLPurifier/TagTransformTest.php new file mode 100644 index 00000000..b578abdf --- /dev/null +++ b/tests/HTMLPurifier/TagTransformTest.php @@ -0,0 +1,98 @@ +assertEqual( + new HTMLPurifier_Token_Start($expect_name, $expect_added_attributes), + $transformer->transform( + new HTMLPurifier_Token_Start($name)) + ); + + // start tag transform with attributes + $this->assertEqual( + new HTMLPurifier_Token_Start($expect_name, $expect_attributes), + $transformer->transform( + new HTMLPurifier_Token_Start($name, $attributes) + ) + ); + + // end tag transform + $this->assertEqual( + new HTMLPurifier_Token_End($expect_name), + $transformer->transform(new HTMLPurifier_Token_End($name)) + ); + + // empty tag transform + $this->assertEqual( + new HTMLPurifier_Token_Empty($expect_name, $expect_added_attributes), + $transformer->transform(new HTMLPurifier_Token_Empty($name)) + ); + + // empty tag transform with attributes + $this->assertEqual( + new HTMLPurifier_Token_Empty($expect_name, $expect_attributes), + $transformer->transform( + new HTMLPurifier_Token_Empty($name, $attributes)) + ); + + + } + + function test_normalizeAttributes() { + + $transformer = new HTMLPurifier_TagTransform(); + + $this->assertEqual(array(), $transformer->normalizeAttributes(array())); + $this->assertEqual(array('class'=>'foo'), + $transformer->normalizeAttributes(array('class'=>'foo'))); + $this->assertEqual(array('class'=>'foo'), + $transformer->normalizeAttributes(array('CLASS'=>'foo'))); + + } + + function testSimple() { + + $transformer = new HTMLPurifier_TagTransform_Simple('ul'); + + $this->assertTransformation( + $transformer, + 'menu', array('class' => 'boom'), + 'ul', array('class' => 'boom') + ); + + } + + function testCenter() { + + $transformer = new HTMLPurifier_TagTransform_Center(); + + $this->assertTransformation( + $transformer, + 'center', array('class' => 'boom', 'style'=>'font-weight:bold;'), + 'div', array('class' => 'boom', 'style'=>'text-align:center;font-weight:bold;'), + array('style'=>'text-align:center;') + ); + + // test special case, uppercase attribute key + $this->assertTransformation( + $transformer, + 'center', array('STYLE'=>'font-weight:bold;'), + 'div', array('style'=>'text-align:center;font-weight:bold;'), + array('style'=>'text-align:center;') + ); + + } + +} + +?> \ No newline at end of file diff --git a/tests/index.php b/tests/index.php index 21ab870e..f6adc716 100644 --- a/tests/index.php +++ b/tests/index.php @@ -2,6 +2,9 @@ error_reporting(E_ALL); +// wishlist: automated calling of this file from multiple PHP versions so we +// don't have to constantly switch around + // load files, assume that simpletest directory is in path require_once 'simpletest/unit_tester.php'; require_once 'simpletest/reporter.php'; @@ -37,6 +40,7 @@ $test->addTestFile('HTMLPurifier/Strategy/ValidateAttributesTest.php'); $test->addTestFile('HTMLPurifier/AttrDef/EnumTest.php'); $test->addTestFile('HTMLPurifier/AttrDef/IDTest.php'); $test->addTestFile('HTMLPurifier/IDAccumulatorTest.php'); +$test->addTestFile('HTMLPurifier/TagTransformTest.php'); if (SimpleReporter::inCli()) $reporter = new TextReporter(); else $reporter = new HTMLReporter();