Procházet zdrojové kódy

ZF-12287: HeadScript breaks text/x-jquery-tmpl by surrounding script with comments (Backport ZF2-349)

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@24960 44c647ce-9c0f-0410-b52a-842ac1e357ba
adamlundrigan před 13 roky
rodič
revize
8a6d58ed6b

+ 27 - 0
documentation/manual/en/module_specs/Zend_View-Helpers-HeadScript.xml

@@ -101,6 +101,33 @@ $this->headScript()->appendFile(
         </example>
     </note>
 
+    <note>
+        <title>Preventing HTML style comments or CDATA wrapping of scripts</title>
+
+        <para>
+            By default <classname>HeadScript</classname> will wrap scripts with HTML
+            comments or it wraps scripts with XHTML cdata. This behavior can be
+            problematic when you intend to use the script tag in an alternative way by
+            setting the type to something other then 'text/javascript'. To prevent such
+            escaping, pass an <varname>noescape</varname> with a value of true as part of
+            the <varname>$attrs</varname> parameter in the method calls.
+        </para>
+
+        <example xml:id="zend.view.helpers.initial.headscript.noescape">
+            <title>Create an jQuery template with the headScript</title>
+
+            <programlisting language="php"><![CDATA[
+// jquery template
+$template = '<div class="book">{{:title}}</div>';
+$this->headScript()->appendScript(
+    $template,
+    'text/x-jquery-tmpl',
+    array('id='tmpl-book', 'noescape' => true)
+);
+]]></programlisting>
+        </example>
+    </note>
+
     <para>
         <classname>HeadScript</classname> also allows capturing scripts; this can be
         useful if you want to create the client-side script programmatically,

+ 17 - 3
library/Zend/View/Helper/HeadScript.php

@@ -410,8 +410,8 @@ class Zend_View_Helper_HeadScript extends Zend_View_Helper_Placeholder_Container
         $attrString = '';
         if (!empty($item->attributes)) {
             foreach ($item->attributes as $key => $value) {
-                if (!$this->arbitraryAttributesAllowed()
-                    && !in_array($key, $this->_optionalAttributes))
+                if ((!$this->arbitraryAttributesAllowed() && !in_array($key, $this->_optionalAttributes))
+                    || in_array($key, array('conditional', 'noescape')))
                 {
                     continue;
                 }
@@ -422,10 +422,24 @@ class Zend_View_Helper_HeadScript extends Zend_View_Helper_Placeholder_Container
             }
         }
 
+        $addScriptEscape = !(isset($item->attributes['noescape']) && filter_var($item->attributes['noescape'], FILTER_VALIDATE_BOOLEAN));
+
         $type = ($this->_autoEscape) ? $this->_escape($item->type) : $item->type;
         $html  = '<script type="' . $type . '"' . $attrString . '>';
         if (!empty($item->source)) {
-              $html .= PHP_EOL . $indent . '    ' . $escapeStart . PHP_EOL . $item->source . $indent . '    ' . $escapeEnd . PHP_EOL . $indent;
+            $html .= PHP_EOL ;
+
+            if ($addScriptEscape) {
+                $html .= $indent . '    ' . $escapeStart . PHP_EOL;
+            }
+
+            $html .= $indent . '    ' . $item->source;
+
+            if ($addScriptEscape) {
+                $html .= $indent . '    ' . $escapeEnd . PHP_EOL;
+            }
+
+            $html .= $indent;
         }
         $html .= '</script>';
 

+ 56 - 0
tests/Zend/View/Helper/HeadScriptTest.php

@@ -465,6 +465,62 @@ document.write(bar.strlen());');
         $test = $this->helper->toString();
         $this->assertEquals($expected, $test);
     }
+
+    /**
+     * @group ZF-12287
+     */
+    public function testConditionalWithAllowArbitraryAttributesDoesNotIncludeConditionalScript()
+    {
+        $this->helper->setAllowArbitraryAttributes(true);
+        $this->helper->appendFile(
+            '/js/foo.js', 'text/javascript', array('conditional' => 'lt IE 7')
+        );
+        $test = $this->helper->toString();
+
+        $this->assertNotContains('conditional', $test);
+    }
+
+    /**
+     * @group ZF-12287
+     */
+    public function testNoEscapeWithAllowArbitraryAttributesDoesNotIncludeNoEscapeScript()
+    {
+        $this->helper->setAllowArbitraryAttributes(true);
+        $this->helper->appendScript(
+            '// some script', 'text/javascript', array('noescape' => true)
+        );
+        $test = $this->helper->toString();
+
+        $this->assertNotContains('noescape', $test);
+    }
+
+    /**
+     * @group ZF-12287
+     */
+    public function testNoEscapeDefaultsToFalse()
+    {
+        $this->helper->appendScript(
+            '// some script' . PHP_EOL, 'text/javascript', array()
+        );
+        $test = $this->helper->toString();
+
+        $this->assertContains('//<!--', $test);
+        $this->assertContains('//-->', $test);
+    }
+
+    /**
+     * @group ZF-12287
+     */
+    public function testNoEscapeTrue()
+    {
+        $this->helper->appendScript(
+            '// some script' . PHP_EOL, 'text/javascript', array('noescape' => true)
+        );
+        $test = $this->helper->toString();
+
+        $this->assertNotContains('//<!--', $test);
+        $this->assertNotContains('//-->', $test);
+    }
 }
 
 // Call Zend_View_Helper_HeadScriptTest::main() if this source file is executed directly.