From 670fc5cdd2a2446fc51634daf6eddedfc73074a5 Mon Sep 17 00:00:00 2001 From: Mateusz Turcza Date: Tue, 14 Aug 2018 23:24:31 +0200 Subject: [PATCH] Add element (#25) --- library/HTMLPurifier/HTML5Config.php | 2 +- library/HTMLPurifier/HTML5Definition.php | 3 + .../HTMLPurifier/HTMLModule/HTML5/Ruby.php | 36 +++++ .../HTMLModule/HTML5/RubyTest.php | 147 ++++++++++++++++++ 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 library/HTMLPurifier/HTMLModule/HTML5/Ruby.php create mode 100644 tests/HTMLPurifier/HTMLModule/HTML5/RubyTest.php diff --git a/library/HTMLPurifier/HTML5Config.php b/library/HTMLPurifier/HTML5Config.php index a88e4f4..42cfc4d 100644 --- a/library/HTMLPurifier/HTML5Config.php +++ b/library/HTMLPurifier/HTML5Config.php @@ -2,7 +2,7 @@ class HTMLPurifier_HTML5Config extends HTMLPurifier_Config { - const REVISION = 2018061701; + const REVISION = 2018081401; /** * @param string|array|HTMLPurifier_Config $config diff --git a/library/HTMLPurifier/HTML5Definition.php b/library/HTMLPurifier/HTML5Definition.php index db98066..644a3a2 100644 --- a/library/HTMLPurifier/HTML5Definition.php +++ b/library/HTMLPurifier/HTML5Definition.php @@ -17,6 +17,9 @@ public static function setup(HTMLPurifier_HTMLDefinition $def) // add support for Floating point number attributes $def->manager->attrTypes->set('Float', new HTMLPurifier_AttrDef_Float()); + // add support for Ruby markup + $def->manager->addModule('HTML5_Ruby'); + // http://developers.whatwg.org/sections.html $def->addElement('section', 'Block', 'Flow', 'Common'); $def->addElement('nav', 'Block', 'Flow', 'Common'); diff --git a/library/HTMLPurifier/HTMLModule/HTML5/Ruby.php b/library/HTMLPurifier/HTMLModule/HTML5/Ruby.php new file mode 100644 index 0000000..45fdd82 --- /dev/null +++ b/library/HTMLPurifier/HTMLModule/HTML5/Ruby.php @@ -0,0 +1,36 @@ +addElement( + 'ruby', + 'Inline', + 'Custom: ((rb | Inline | #PCDATA)*, (rt | (rp, rt, rp) | rtc))+', + 'Common' + ); + $this->addElement('rtc', false, 'Custom: (rt | rp | Inline | #PCDATA)*', 'Common'); + $this->addElement('rb', false, 'Custom: (Inline | #PCDATA)*', 'Common'); + $this->addElement('rt', false, 'Custom: (Inline | #PCDATA)*', 'Common'); + $this->addElement('rp', false, 'Custom: (Inline | #PCDATA)*', 'Common'); + + // elements can be nested as children of , , and + // https://www.w3.org/TR/2014/NOTE-html-ruby-extensions-20140204/#changes-compared-to-the-current-ruby-model + } +} diff --git a/tests/HTMLPurifier/HTMLModule/HTML5/RubyTest.php b/tests/HTMLPurifier/HTMLModule/HTML5/RubyTest.php new file mode 100644 index 0000000..4530a7e --- /dev/null +++ b/tests/HTMLPurifier/HTMLModule/HTML5/RubyTest.php @@ -0,0 +1,147 @@ +set('Cache.DefinitionImpl', null); + $purifier = new HTMLPurifier($config); + return $purifier; + } + + public function rubyInput() + { + return array( + array( + '明日(あした)', + ), + array( + '明日あした', + ), + array( + '明日', + ), + array( + '明日', + ), + array( + 'Foo', + 'Foo', + ), + array( + // Element ruby is missing a required instance of child element rp. + 'Foo', + '', + ), + array( + // Element ruby is missing a required instance of one or more of + // the following child elements: rp, rt, rtc. + 'Foo', + '', + ), + array( + // Element ruby is missing a required instance of one or more of + // the following child elements: rp, rt, rtc. + 'Foo', + '', + ), + array( + 'BarBaz', + ), + array( + // Text before element + 'FooBarBaz', + ), + array( + 'Bar(Baz)', + ), + array( + // Multiple sequences of elements + 'BarBazQuxQuux', + ), + array( + // Text after element + 'BarBazQux', + ), + array( + // Multiple consecutive elements + 'BarBazQuxQuuxQuuz', + ), + array( + // Element ruby is missing a required instance of one or more of + // the following child elements: rp, rt, rtc. + 'FooBarBazQux', + '', + ), + array( + // Inline element in + 'Foo', + ), + array( + // Block-level elements are moved outside + '
Foo
', + '
Foo
', + ), + array( + 'FooBar' + ), + array( + 'FooBarBazQuxQuux', + ), + array( + // Empty element + '', + ), + array( + // Properly auto-close element + 'FooBar', + 'FooBar', + ), + array( + // Multiple elements + 'FooBarBaz', + ), + array( + // Block-level elements are moved outside + '
Foo
', + '
Foo
', + ), + array( + // element can only be child of and elements + 'Foo', + 'Foo', + ), + array( + // element can only be child of and elements + 'Foo', + 'Foo', + ), + array( + // element can only be child of element + 'Foo', + 'Foo', + ), + array( + // element can only be child of element + 'Foo', + 'Foo', + ), + array( + // Nested elements + 'FooBar', + ), + ); + } + + /** + * @param string $input + * @param string $expectedOutput OPTIONAL + * @dataProvider rubyInput + */ + public function testRuby($input, $expectedOutput = null) + { + $output = $this->getPurifier()->purify($input); + $this->assertEquals($expectedOutput !== null ? $expectedOutput : $input, $output); + } +}