Kaynağa Gözat

Zend_Markup: refactor to remove bitmask checks for empty/paired tags

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@20290 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew 16 yıl önce
ebeveyn
işleme
1f48cbd111

+ 3 - 2
library/Zend/Markup/Renderer/Html.php

@@ -209,6 +209,7 @@ class Zend_Markup_Renderer_Html extends Zend_Markup_Renderer_RendererAbstract
             'type'    => 9, // self::TYPE_REPLACE | self::TAG_SINGLE
             'type'    => 9, // self::TYPE_REPLACE | self::TAG_SINGLE
             'tag'     => 'hr',
             'tag'     => 'hr',
             'group'   => 'block',
             'group'   => 'block',
+            'empty'   => true,
         ),
         ),
         // aliases
         // aliases
         'bold' => array(
         'bold' => array(
@@ -277,8 +278,8 @@ class Zend_Markup_Renderer_Html extends Zend_Markup_Renderer_RendererAbstract
         ),
         ),
         'color' => array(
         'color' => array(
             'type' => 16,
             'type' => 16,
-            'name' => 'span'
-        )
+            'name' => 'span',
+        ),
     );
     );
 
 
     /**
     /**

+ 45 - 25
library/Zend/Markup/Renderer/RendererAbstract.php

@@ -44,9 +44,6 @@ require_once 'Zend/Markup/Renderer/TokenConverterInterface.php';
  */
  */
 abstract class Zend_Markup_Renderer_RendererAbstract
 abstract class Zend_Markup_Renderer_RendererAbstract
 {
 {
-    const TAG_SINGLE    = 1;
-    const TAG_NORMAL    = 2;
-
     const TYPE_CALLBACK = 4;
     const TYPE_CALLBACK = 4;
     const TYPE_REPLACE  = 8;
     const TYPE_REPLACE  = 8;
     const TYPE_ALIAS    = 16;
     const TYPE_ALIAS    = 16;
@@ -228,7 +225,7 @@ abstract class Zend_Markup_Renderer_RendererAbstract
                 'name' => $options['name']
                 'name' => $options['name']
             );
             );
         } else {
         } else {
-            if ($type & self::TAG_SINGLE) {
+            if ($type && array_key_exists('empty', $options) && $options['empty']) {
                 // add a single replace tag
                 // add a single replace tag
                 $options['type']   = $type;
                 $options['type']   = $type;
                 $options['filter'] = $filter;
                 $options['filter'] = $filter;
@@ -372,55 +369,56 @@ abstract class Zend_Markup_Renderer_RendererAbstract
             return $return;
             return $return;
         }
         }
 
 
-        $name = $this->_getTagName($token);
-        $tag  = $this->_markups[$name];
+        $name   = $this->_getMarkupName($token);
+        $markup = (!$name) ? false : $this->_markups[$name];
+        $empty  = (is_array($markup) && array_key_exists('empty', $markup) && $markup['empty']);
 
 
         // check if the tag has content
         // check if the tag has content
-        if (($tag['type'] & self::TAG_NORMAL) && !$token->hasChildren()) {
+        if (!$empty && !$token->hasChildren()) {
             return '';
             return '';
         }
         }
 
 
         // check for the context
         // check for the context
-        if (!in_array($tag['group'], $this->_groups[$this->_group])) {
+        if (is_array($markup) && !in_array($markup['group'], $this->_groups[$this->_group])) {
             $oldToken  = $this->_token;
             $oldToken  = $this->_token;
-            $return = $this->_filter($token->getTag()) . $this->_render($token) . $token->getStopper();
+            $return    = $this->_filter($token->getTag()) . $this->_render($token) . $token->getStopper();
             $this->_token = $oldToken;
             $this->_token = $oldToken;
             return $return;
             return $return;
         }
         }
 
 
         // check for the filter
         // check for the filter
-        if (!isset($tag['filter'])
-        || (!($tag['filter'] instanceof Zend_Filter_Interface) && ($tag['filter'] !== false))) {
+        if (!isset($markup['filter'])
+            || (!($markup['filter'] instanceof Zend_Filter_Interface) && ($markup['filter'] !== false))) {
             $this->_markups[$name]['filter'] = $this->getDefaultFilter();
             $this->_markups[$name]['filter'] = $this->getDefaultFilter();
         }
         }
 
 
         // callback
         // callback
-        if ($tag['type'] & self::TYPE_CALLBACK) {
+        if (is_array($markup) && ($markup['type'] & self::TYPE_CALLBACK)) {
             // load the callback if the tag doesn't exist
             // load the callback if the tag doesn't exist
-            if (!($tag['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
+            if (!($markup['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
                 $class = $this->getPluginLoader()->load($name);
                 $class = $this->getPluginLoader()->load($name);
 
 
-                $tag['callback'] = new $class;
+                $markup['callback'] = new $class;
 
 
-                if (!($tag['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
+                if (!($markup['callback'] instanceof Zend_Markup_Renderer_TokenConverterInterface)) {
                     require_once 'Zend/Markup/Renderer/Exception.php';
                     require_once 'Zend/Markup/Renderer/Exception.php';
                     throw new Zend_Markup_Renderer_Exception("Callback for tag '$name' found, but it isn't valid.");
                     throw new Zend_Markup_Renderer_Exception("Callback for tag '$name' found, but it isn't valid.");
                 }
                 }
 
 
-                if (method_exists($tag['callback'], 'setRenderer')) {
-                    $tag['callback']->setRenderer($this);
+                if (method_exists($markup['callback'], 'setRenderer')) {
+                    $markup['callback']->setRenderer($this);
                 }
                 }
             }
             }
-            if ($tag['type'] & self::TAG_NORMAL) {
-                return $tag['callback']->convert($token, $this->_render($token));
+            if ($markup['type'] && !$empty) {
+                return $markup['callback']->convert($token, $this->_render($token));
             }
             }
-            return $tag['callback']->convert($token, null);
+            return $markup['callback']->convert($token, null);
         }
         }
         // replace
         // replace
-        if ($tag['type'] & self::TAG_NORMAL) {
-            return $this->_executeReplace($token, $tag);
+        if ($markup['type'] && !$empty) {
+            return $this->_executeReplace($token, $markup);
         }
         }
-        return $this->_executeSingleReplace($token, $tag);
+        return $this->_executeSingleReplace($token, $markup);
     }
     }
 
 
     /**
     /**
@@ -445,12 +443,17 @@ abstract class Zend_Markup_Renderer_RendererAbstract
      *
      *
      * @return string
      * @return string
      */
      */
-    protected function _getTagName(Zend_Markup_Token $token)
+    protected function _getMarkupName(Zend_Markup_Token $token)
     {
     {
         $name = $token->getName();
         $name = $token->getName();
+        if (empty($name)) {
+            return false;
+        }
 
 
         // process the aliases
         // process the aliases
-        while ($this->_markups[$name]['type'] & self::TYPE_ALIAS) {
+        while (($type = $this->_getMarkupType($name)) 
+               && ($type & self::TYPE_ALIAS)
+        ) {
             $name = $this->_markups[$name]['name'];
             $name = $this->_markups[$name]['name'];
         }
         }
 
 
@@ -458,6 +461,23 @@ abstract class Zend_Markup_Renderer_RendererAbstract
     }
     }
 
 
     /**
     /**
+     * Retrieve markup type
+     * 
+     * @param  string $name 
+     * @return false|int
+     */
+    protected function _getMarkupType($name)
+    {
+        if (!isset($this->_markups[$name])) {
+            return false;
+        }
+        if (!isset($this->_markups[$name]['type'])) {
+            return false;
+        }
+        return $this->_markups[$name]['type'];
+    }
+
+    /**
      * Execute a replace token
      * Execute a replace token
      *
      *
      * @param  Zend_Markup_Token $token
      * @param  Zend_Markup_Token $token

+ 31 - 18
tests/Zend/Markup/BbcodeAndHtmlTest.php

@@ -153,14 +153,14 @@ class Zend_Markup_BbcodeAndHtmlTest extends PHPUnit_Framework_TestCase
         );
         );
 
 
         $this->_markup->addMarkup('bar',
         $this->_markup->addMarkup('bar',
-            Zend_Markup_Renderer_RendererAbstract::TYPE_CALLBACK | Zend_Markup_Renderer_RendererAbstract::TAG_NORMAL,
+            Zend_Markup_Renderer_RendererAbstract::TYPE_CALLBACK,
             array('group' => 'inline'));
             array('group' => 'inline'));
         $this->_markup->addMarkup('suppp',
         $this->_markup->addMarkup('suppp',
-            Zend_Markup_Renderer_RendererAbstract::TYPE_REPLACE | Zend_Markup_Renderer_RendererAbstract::TAG_NORMAL,
+            Zend_Markup_Renderer_RendererAbstract::TYPE_REPLACE,
             array('start' => '<sup>', 'end' => '</sup>', 'group' => 'inline'));
             array('start' => '<sup>', 'end' => '</sup>', 'group' => 'inline'));
         $this->_markup->addMarkup('zend',
         $this->_markup->addMarkup('zend',
-            Zend_Markup_Renderer_RendererAbstract::TYPE_REPLACE | Zend_Markup_Renderer_RendererAbstract::TAG_SINGLE,
-            array('replace' => 'Zend Framework', 'group' => 'inline'));
+            Zend_Markup_Renderer_RendererAbstract::TYPE_REPLACE,
+            array('replace' => 'Zend Framework', 'group' => 'inline', 'empty' => true));
         $this->_markup->addMarkup('line', Zend_Markup_Renderer_RendererAbstract::TYPE_ALIAS,
         $this->_markup->addMarkup('line', Zend_Markup_Renderer_RendererAbstract::TYPE_ALIAS,
             array('name' => 'hr'));
             array('name' => 'hr'));
 
 
@@ -174,12 +174,16 @@ class Zend_Markup_BbcodeAndHtmlTest extends PHPUnit_Framework_TestCase
             $this->_markup->render('[suppp]test aap[/suppp]test'));
             $this->_markup->render('[suppp]test aap[/suppp]test'));
     }
     }
 
 
-    public function testHtmlUrlTitleIsRenderedCorrectly() {
-        $this->assertEquals('<a href="http://exampl.com" title="foo">test</a>',
-            $this->_markup->render('[url=http://exampl.com title=foo]test[/url]'));
+    public function testHtmlUrlTitleIsRenderedCorrectly() 
+    {
+        $this->assertEquals(
+            '<a href="http://exampl.com" title="foo">test</a>',
+            $this->_markup->render('[url=http://exampl.com title=foo]test[/url]')
+        );
     }
     }
 
 
-    public function testValueLessAttributeDoesNotThrowNotice() {
+    public function testValueLessAttributeDoesNotThrowNotice() 
+    {
         // Notice: Uninitialized string offset: 42
         // Notice: Uninitialized string offset: 42
         // in Zend/Markup/Parser/Bbcode.php on line 316
         // in Zend/Markup/Parser/Bbcode.php on line 316
         $expected = '<a href="http://example.com">Example</a>';
         $expected = '<a href="http://example.com">Example</a>';
@@ -203,34 +207,40 @@ class Zend_Markup_BbcodeAndHtmlTest extends PHPUnit_Framework_TestCase
         $this->_markup->render('[url="http://framework.zend.com/"title');
         $this->_markup->render('[url="http://framework.zend.com/"title');
     }
     }
 
 
-    public function testHrTagWorks() {
+    public function testHrTagWorks() 
+    {
         $this->assertEquals('foo<hr />bar', $this->_markup->render('foo[hr]bar'));
         $this->assertEquals('foo<hr />bar', $this->_markup->render('foo[hr]bar'));
     }
     }
 
 
-    public function testFunkyCombos() {
+    public function testFunkyCombos() 
+    {
         $expected = '<span style="text-decoration: underline;">a[/b][hr]b'
         $expected = '<span style="text-decoration: underline;">a[/b][hr]b'
                   . '<strong>c</strong></span><strong>d</strong>[/u]e';
                   . '<strong>c</strong></span><strong>d</strong>[/u]e';
         $outcome = $this->_markup->render('[u]a[/b][hr]b[b]c[/u]d[/b][/u]e');
         $outcome = $this->_markup->render('[u]a[/b][hr]b[b]c[/u]d[/b][/u]e');
         $this->assertEquals($expected, $outcome);
         $this->assertEquals($expected, $outcome);
     }
     }
 
 
-    public function testImgSrcsConstraints() {
+    public function testImgSrcsConstraints() 
+    {
         $this->assertEquals('F/\!ZLrFz',$this->_markup->render('F[img]/\!ZLrFz[/img]'));
         $this->assertEquals('F/\!ZLrFz',$this->_markup->render('F[img]/\!ZLrFz[/img]'));
     }
     }
 
 
-    public function testColorConstraintsAndJs() {
+    public function testColorConstraintsAndJs() 
+    {
         $input = "<kokx> i think you mean? [color=\"onclick='foobar();'\"]your text[/color] DASPRiD";
         $input = "<kokx> i think you mean? [color=\"onclick='foobar();'\"]your text[/color] DASPRiD";
         $expected = "&lt;kokx&gt; i think you mean? <span>your text</span> DASPRiD";
         $expected = "&lt;kokx&gt; i think you mean? <span>your text</span> DASPRiD";
         $this->assertEquals($expected, $this->_markup->render($input));
         $this->assertEquals($expected, $this->_markup->render($input));
     }
     }
 
 
-    public function testNeverEndingAttribute() {
+    public function testNeverEndingAttribute() 
+    {
         $input = "[color=\"green]your text[/color]";
         $input = "[color=\"green]your text[/color]";
         $expected = '<span>your text</span>';
         $expected = '<span>your text</span>';
         $this->assertEquals($expected, $this->_markup->render($input));
         $this->assertEquals($expected, $this->_markup->render($input));
     }
     }
 
 
-    public function testTreatmentNonTags() {
+    public function testTreatmentNonTags() 
+    {
         $input = '[span][acronym][h1][h2][h3][h4][h5][h6][nothing]'
         $input = '[span][acronym][h1][h2][h3][h4][h5][h6][nothing]'
                . '[/h6][/h5][/h4][/h3][/h2][/h1][/acronym][/span]';
                . '[/h6][/h5][/h4][/h3][/h2][/h1][/acronym][/span]';
         $expected = '<span><acronym><h1><h2><h3><h4><h5><h6>[nothing]'
         $expected = '<span><acronym><h1><h2><h3><h4><h5><h6>[nothing]'
@@ -238,7 +248,8 @@ class Zend_Markup_BbcodeAndHtmlTest extends PHPUnit_Framework_TestCase
         $this->assertEquals($expected, $this->_markup->render($input));
         $this->assertEquals($expected, $this->_markup->render($input));
     }
     }
 
 
-    public function testListItems() {
+    public function testListItems() 
+    {
         $input = "[list][*]Foo*bar (item 1)\n[*]Item 2\n[*]Trimmed (Item 3)\n[/list]";
         $input = "[list][*]Foo*bar (item 1)\n[*]Item 2\n[*]Trimmed (Item 3)\n[/list]";
         $expected = "<ul><li>Foo*bar (item 1)</li><li>Item 2</li><li>Trimmed (Item 3)</li></ul>";
         $expected = "<ul><li>Foo*bar (item 1)</li><li>Item 2</li><li>Trimmed (Item 3)</li></ul>";
         $this->assertEquals($expected, $this->_markup->render($input));
         $this->assertEquals($expected, $this->_markup->render($input));
@@ -263,7 +274,8 @@ class Zend_Markup_BbcodeAndHtmlTest extends PHPUnit_Framework_TestCase
         }
         }
     }
     }
 
 
-    public function testHtmlTags() {
+    public function testHtmlTags() 
+    {
         $m = $this->_markup;
         $m = $this->_markup;
 
 
         $this->assertEquals('<strong>foo</strong>', $m->render('[b]foo[/b]'));
         $this->assertEquals('<strong>foo</strong>', $m->render('[b]foo[/b]'));
@@ -306,7 +318,8 @@ class Zend_Markup_BbcodeAndHtmlTest extends PHPUnit_Framework_TestCase
                                 $this->_markup->render('[b]foo[i]bar[/b]kokx[/i]'));
                                 $this->_markup->render('[b]foo[i]bar[/b]kokx[/i]'));
     }
     }
 
 
-    public function testHtmlAliases() {
+    public function testHtmlAliases() 
+    {
         $m = $this->_markup;
         $m = $this->_markup;
 
 
         $this->assertEquals($m->render('[b]F[/b]'), $m->render('[bold]F[/bold]'));
         $this->assertEquals($m->render('[b]F[/b]'), $m->render('[bold]F[/bold]'));
@@ -402,7 +415,7 @@ BBCODE;
         $filter = new Zend_Filter_HtmlEntities();
         $filter = new Zend_Filter_HtmlEntities();
 
 
         $this->_markup->addMarkup('suppp',
         $this->_markup->addMarkup('suppp',
-            Zend_Markup_Renderer_RendererAbstract::TYPE_REPLACE | Zend_Markup_Renderer_RendererAbstract::TAG_NORMAL,
+            Zend_Markup_Renderer_RendererAbstract::TYPE_REPLACE,
             array('start' => '<sup>', 'end' => '</sup>', 'group' => 'inline', 'filter' => $filter));
             array('start' => '<sup>', 'end' => '</sup>', 'group' => 'inline', 'filter' => $filter));
         $this->assertEquals("filter<br />\n<sup>filter\n&amp;\nfilter</sup>",
         $this->assertEquals("filter<br />\n<sup>filter\n&amp;\nfilter</sup>",
             $m->render("filter\n[suppp]filter\n&\nfilter[/suppp]"));
             $m->render("filter\n[suppp]filter\n&\nfilter[/suppp]"));