diff --git a/NEWS b/NEWS index 6f2f3acc..d55dcf17 100644 --- a/NEWS +++ b/NEWS @@ -18,6 +18,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier performed on it, ensuring that its internal state stays consistent. To revert this behavior, you can set the $autoFinalize member variable off, but it's not recommended. +# New compact syntax for AttrDef objects that can be used to instantiate + new objects via make() - Deprecated and removed EnableRedundantUTF8Cleaning. It didn't even work! . Unit test for ElementDef created, ElementDef behavior modified to be more flexible diff --git a/library/HTMLPurifier/AttrDef.php b/library/HTMLPurifier/AttrDef.php index 334a7ace..3efc8e69 100644 --- a/library/HTMLPurifier/AttrDef.php +++ b/library/HTMLPurifier/AttrDef.php @@ -62,6 +62,20 @@ class HTMLPurifier_AttrDef $string = str_replace(array("\r", "\t"), ' ', $string); return $string; } + + /** + * Factory method for creating this class from a string. + * @param $string String construction info + * @return Created AttrDef object corresponding to $string + * @public + */ + function make($string) { + // default implementation, return flyweight of this object + // if overloaded, it is *necessary* for you to clone the + // object (usually by instantiating a new copy) and return that + return $this; + } + } ?> \ No newline at end of file diff --git a/library/HTMLPurifier/AttrDef/Enum.php b/library/HTMLPurifier/AttrDef/Enum.php index 91a075f8..870d5294 100644 --- a/library/HTMLPurifier/AttrDef/Enum.php +++ b/library/HTMLPurifier/AttrDef/Enum.php @@ -45,6 +45,15 @@ class HTMLPurifier_AttrDef_Enum extends HTMLPurifier_AttrDef return $result ? $string : false; } + /** + * @param $string In form of comma-delimited list of case-insensitive + * valid values. Example: "foo,bar,baz" + */ + function make($string) { + $values = explode(',', $string); + return new HTMLPurifier_AttrDef_Enum($values); + } + } ?> \ No newline at end of file diff --git a/library/HTMLPurifier/AttrDef/HTML/Bool.php b/library/HTMLPurifier/AttrDef/HTML/Bool.php index dfbfb838..24bd1de6 100644 --- a/library/HTMLPurifier/AttrDef/HTML/Bool.php +++ b/library/HTMLPurifier/AttrDef/HTML/Bool.php @@ -11,13 +11,20 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef var $name; var $minimized = true; - function HTMLPurifier_AttrDef_HTML_Bool($name) {$this->name = $name;} + function HTMLPurifier_AttrDef_HTML_Bool($name = false) {$this->name = $name;} function validate($string, $config, &$context) { if (empty($string)) return false; return $name; } + /** + * @param $string Name of attribute + */ + function make($string) { + return new HTMLPurifier_AttrDef_HTML_Bool($string); + } + } ?> \ No newline at end of file diff --git a/library/HTMLPurifier/AttrTypes.php b/library/HTMLPurifier/AttrTypes.php index 091ae2c9..4064de78 100644 --- a/library/HTMLPurifier/AttrTypes.php +++ b/library/HTMLPurifier/AttrTypes.php @@ -1,6 +1,8 @@ info['Enum'] = new HTMLPurifier_AttrDef_Enum(); + $this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool(); + $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text(); $this->info['ID'] = new HTMLPurifier_AttrDef_HTML_ID(); $this->info['Length'] = new HTMLPurifier_AttrDef_HTML_Length(); @@ -39,6 +45,7 @@ class HTMLPurifier_AttrTypes $this->info['Color'] = new HTMLPurifier_AttrDef_HTML_Color(); // number is really a positive integer (one or more digits) + // FIXME: ^^ not always, see start and value of list items $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); } @@ -48,13 +55,18 @@ class HTMLPurifier_AttrTypes * @return Object AttrDef for type */ function get($type) { - // If $type is complicated, we may to clone the attribute - // definition and make custom changes + + // determine if there is any extra info tacked on + if (strpos($type, '#') !== false) list($type, $string) = explode('#', $type, 2); + else $string = ''; + if (!isset($this->info[$type])) { trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR); return; } - return $this->info[$type]; + + return $this->info[$type]->make($string); + } /** diff --git a/library/HTMLPurifier/HTMLModule/Bdo.php b/library/HTMLPurifier/HTMLModule/Bdo.php index 3b9081c0..84b9a0b0 100644 --- a/library/HTMLPurifier/HTMLModule/Bdo.php +++ b/library/HTMLPurifier/HTMLModule/Bdo.php @@ -16,21 +16,17 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule ); function HTMLPurifier_HTMLModule_Bdo() { - $dir = new HTMLPurifier_AttrDef_Enum(array('ltr','rtl'), false); $bdo =& $this->addElement( 'bdo', true, 'Inline', 'Inline', array('Core', 'Lang'), array( - 'dir' => $dir, // required + 'dir' => 'Enum#ltr,rtl', // required // The Abstract Module specification has the attribute - // inclusions wrong for bdo: bdo allows - // xml:lang too (and we'll toss in lang for good measure, - // though it is not allowed for XHTML 1.1, this will - // be managed with a global attribute transform) + // inclusions wrong for bdo: bdo allows Lang ) ); $bdo->attr_transform_post['required-dir'] = new HTMLPurifier_AttrTransform_BdoDir(); - $this->attr_collections['I18N']['dir'] = $dir; + $this->attr_collections['I18N']['dir'] = 'Enum#ltr,rtl'; } } diff --git a/library/HTMLPurifier/HTMLModule/Legacy.php b/library/HTMLPurifier/HTMLModule/Legacy.php index d0f87357..e5ee2717 100644 --- a/library/HTMLPurifier/HTMLModule/Legacy.php +++ b/library/HTMLPurifier/HTMLModule/Legacy.php @@ -35,7 +35,7 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule )); $this->addElement('center', true, 'Block', 'Flow', 'Common'); $this->addElement('dir', true, 'Block', 'Required: li', 'Common', array( - 'compact' => new HTMLPurifier_AttrDef_HTML_Bool('compact') + 'compact' => 'Bool#compact' )); $this->addElement('font', true, 'Inline', 'Inline', array('Core', 'I18N'), array( 'color' => 'Color', @@ -43,7 +43,7 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule 'size' => 'Text', // tighten it )); $this->addElement('menu', true, 'Block', 'Required: li', 'Common', array( - 'compact' => new HTMLPurifier_AttrDef_HTML_Bool('compact') + 'compact' => 'Bool#compact' )); $this->addElement('s', true, 'Inline', 'Inline', 'Common'); $this->addElement('strike', true, 'Inline', 'Inline', 'Common'); @@ -57,7 +57,7 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule $ol =& $this->addBlankElement('ol'); $ol->attr['start'] = new HTMLPurifier_AttrDef_Integer(); - $align = new HTMLPurifier_AttrDef_Enum(array('left', 'right', 'center', 'justify')); + $align = 'Enum#left,right,center,justify'; $address =& $this->addBlankElement('address'); $address->content_model = 'Inline | #PCDATA | p'; @@ -70,15 +70,16 @@ class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule $blockquote->child = false; $br =& $this->addBlankElement('br'); - $br->attr['clear'] = new HTMLPurifier_AttrDef_Enum(array('left', 'all', 'right', 'none')); + $br->attr['clear'] = 'Enum#left,all,right,none'; $caption =& $this->addBlankElement('caption'); - $caption->attr['align'] = new HTMLPurifier_AttrDef_Enum(array('top', 'bottom', 'left', 'right')); + $caption->attr['align'] = 'Enum#top,bottom,left,right'; $div =& $this->addBlankElement('div'); $div->attr['align'] = $align; - // dl.compact omitted + $dl =& $this->addBlankElement('dl'); + $dl->attr['compact'] = 'Bool#compact'; for ($i = 1; $i <= 6; $i++) { $h =& $this->addBlankElement("h$i"); diff --git a/library/HTMLPurifier/HTMLModule/Scripting.php b/library/HTMLPurifier/HTMLModule/Scripting.php index 1c2fe83a..56eff967 100644 --- a/library/HTMLPurifier/HTMLModule/Scripting.php +++ b/library/HTMLPurifier/HTMLModule/Scripting.php @@ -46,6 +46,9 @@ class HTMLPurifier_HTMLModule_Scripting extends HTMLPurifier_HTMLModule // blockquote's custom definition (we would use it but // blockquote's contents are optional while noscript's contents // are required) + + // TODO: convert this to new syntax, main problem is getting + // both content sets working foreach ($this->elements as $element) { $this->info[$element] = new HTMLPurifier_ElementDef(); $this->info[$element]->safe = false; diff --git a/library/HTMLPurifier/HTMLModule/Tables.php b/library/HTMLPurifier/HTMLModule/Tables.php index d962da2a..1e92db28 100644 --- a/library/HTMLPurifier/HTMLModule/Tables.php +++ b/library/HTMLPurifier/HTMLModule/Tables.php @@ -21,13 +21,8 @@ class HTMLPurifier_HTMLModule_Tables extends HTMLPurifier_HTMLModule 'border' => 'Pixels', 'cellpadding' => 'Length', 'cellspacing' => 'Length', - 'frame' => new HTMLPurifier_AttrDef_Enum(array( - 'void', 'above', 'below', 'hsides', 'lhs', 'rhs', - 'vsides', 'box', 'border' - ), false), - 'rules' => new HTMLPurifier_AttrDef_Enum(array( - 'none', 'groups', 'rows', 'cols', 'all' - ), false), + 'frame' => 'Enum#void,above,below,hsides,lhs,rhs,vsides,box,border', + 'rules' => 'Enum#none,groups,rows,cols,all', 'summary' => 'Text', 'width' => 'Length' ) @@ -35,13 +30,9 @@ class HTMLPurifier_HTMLModule_Tables extends HTMLPurifier_HTMLModule // common attributes $cell_align = array( - 'align' => new HTMLPurifier_AttrDef_Enum(array( - 'left', 'center', 'right', 'justify', 'char' - ), false), + 'align' => 'Enum#left,center,right,justify,char', 'charoff' => 'Length', - 'valign' => new HTMLPurifier_AttrDef_Enum(array( - 'top', 'middle', 'bottom', 'baseline' - ), false), + 'valign' => 'Enum#top,middle,bottom,baseline', ); $cell_t = array_merge( diff --git a/tests/HTMLPurifier/AttrDef/EnumTest.php b/tests/HTMLPurifier/AttrDef/EnumTest.php index 2842b214..79669be3 100644 --- a/tests/HTMLPurifier/AttrDef/EnumTest.php +++ b/tests/HTMLPurifier/AttrDef/EnumTest.php @@ -7,29 +7,27 @@ class HTMLPurifier_AttrDef_EnumTest extends HTMLPurifier_AttrDefHarness { function testCaseInsensitive() { - $this->def = new HTMLPurifier_AttrDef_Enum(array('one', 'two')); - $this->assertDef('one'); $this->assertDef('ONE', 'one'); - } function testCaseSensitive() { - $this->def = new HTMLPurifier_AttrDef_Enum(array('one', 'two'), true); - $this->assertDef('one'); $this->assertDef('ONE', false); - } function testFixing() { - $this->def = new HTMLPurifier_AttrDef_Enum(array('one')); - $this->assertDef(' one ', 'one'); - + } + + function test_make() { + $factory = new HTMLPurifier_AttrDef_Enum(); + $def = $factory->make('foo,bar'); + $def2 = new HTMLPurifier_AttrDef_Enum(array('foo', 'bar')); + $this->assertIdentical($def, $def2); } } diff --git a/tests/HTMLPurifier/AttrDef/HTML/BoolTest.php b/tests/HTMLPurifier/AttrDef/HTML/BoolTest.php new file mode 100644 index 00000000..47a31fc3 --- /dev/null +++ b/tests/HTMLPurifier/AttrDef/HTML/BoolTest.php @@ -0,0 +1,25 @@ +def = new HTMLPurifier_AttrDef_HTML_Bool('foo'); + $this->assertDef('foo'); + $this->assertDef('', false); + $this->assertDef('bar', false); + } + + function test_make() { + $factory = new HTMLPurifier_AttrDef_HTML_Bool(); + $def = $factory->make('foo'); + $def2 = new HTMLPurifier_AttrDef_HTML_Bool('foo'); + $this->assertIdentical($def, $def2); + } + +} + +?> \ No newline at end of file diff --git a/tests/HTMLPurifier/AttrDefTest.php b/tests/HTMLPurifier/AttrDefTest.php index 1edb3747..a8963bc4 100644 --- a/tests/HTMLPurifier/AttrDefTest.php +++ b/tests/HTMLPurifier/AttrDefTest.php @@ -17,6 +17,14 @@ class HTMLPurifier_AttrDefTest extends UnitTestCase } + function test_make() { + + $def = new HTMLPurifier_AttrDef(); + $def2 = $def->make(''); + $this->assertIdentical($def, $def2); + + } + } ?> \ No newline at end of file diff --git a/tests/HTMLPurifier/AttrTypesTest.php b/tests/HTMLPurifier/AttrTypesTest.php index 1acb6bfc..9d919a83 100644 --- a/tests/HTMLPurifier/AttrTypesTest.php +++ b/tests/HTMLPurifier/AttrTypesTest.php @@ -16,10 +16,10 @@ class HTMLPurifier_AttrTypesTest extends UnitTestCase $this->expectError('Cannot retrieve undefined attribute type foobar'); $types->get('foobar'); - //$this->assertIdentical( - // $types->get('Enum#foo,bar'), - // new HTMLPurifier_AttrDef_Enum(array('foo', 'bar')) - //); + $this->assertIdentical( + $types->get('Enum#foo,bar'), + new HTMLPurifier_AttrDef_Enum(array('foo', 'bar')) + ); } diff --git a/tests/HTMLPurifier/HTMLModuleManagerTest.php b/tests/HTMLPurifier/HTMLModuleManagerTest.php index a8581bfe..b677b1dc 100644 --- a/tests/HTMLPurifier/HTMLModuleManagerTest.php +++ b/tests/HTMLPurifier/HTMLModuleManagerTest.php @@ -9,9 +9,12 @@ class HTMLPurifier_HTMLModuleManagerTest extends UnitTestCase $manager = new HTMLPurifier_HTMLModuleManager(); $manager->doctypes->register('Blank'); // doctype normally is blank... + $attrdef_nmtokens = 1; // magic number + generate_mock_once('HTMLPurifier_AttrDef'); - $attrdef_nmtokens =& new HTMLPurifier_AttrDefMock($this); - $manager->attrTypes->info['NMTOKENS'] =& $attrdef_nmtokens; + $attrdef =& new HTMLPurifier_AttrDefMock($this); + $attrdef->setReturnValue('make', $attrdef_nmtokens); + $manager->attrTypes->info['NMTOKENS'] =& $attrdef; // ...but we add user modules