Add option to strip CDATA sections from script and style elements.
authorJuriy Zaytsev <kangax@gmail.com>
Wed, 10 Feb 2010 22:21:03 +0000 (17:21 -0500)
committerJuriy Zaytsev <kangax@gmail.com>
Wed, 10 Feb 2010 22:21:03 +0000 (17:21 -0500)
index.html
master.js
src/htmlminifier.js
tests/index.html

index b398087..f7dad7e 100644 (file)
               <input type="checkbox" id="remove-comments" checked>
               <label for="remove-comments">Remove comments (</label>
               <input type="checkbox" id="remove-comments-from-cdata" checked>
-              <label for="remove-comments-from-cdata">also from scripts and styles</label> )
+              <label for="remove-comments-from-cdata">also from scripts and styles )</label>
+            </li>
+            <li>
+              <input type="checkbox" id="remove-cdata-sections-from-cdata" checked>
+              <label for="remove-cdata-sections-from-cdata">Remove CDATA sections from scripts and styles</label>
             </li>
             <li>
               <input type="checkbox" id="collapse-whitespace" checked>
           <li>Figure out when it is safe to remove optional closing tags, so that it doesn't affect document tree</li>
           <li>Do not strip IE conditional comments</li>
           <li>Remove as many empty/blank attributes as possible (not just core ones)</li>
-          <li>Add option to remove CDATA sections from scripts/styles</li>
           <li>Parser trips over xml declarations (need to ignore or strip them)</li>
           <li>Generate a report of all applied transformations</li>
         </ul>
index 3601abc..72dc7b8 100644 (file)
--- a/master.js
+++ b/master.js
   
   function getOptions() {
     return {
-      removeComments:             byId('remove-comments').checked,
-      removeCommentsFromCDATA:    byId('remove-comments-from-cdata').checked,
-      collapseWhitespace:         byId('collapse-whitespace').checked,
-      collapseBooleanAttributes:  byId('collapse-boolean-attributes').checked,
-      removeAttributeQuotes:      byId('remove-attribute-quotes').checked,
-      removeRedundantAttributes:  byId('remove-redundant-attributes').checked,
-      useShortDoctype:            byId('use-short-doctype').checked,
-      removeEmptyAttributes:      byId('remove-empty-attributes').checked,
-      removeEmptyElements:        byId('remove-empty-elements').checked
+      removeComments:               byId('remove-comments').checked,
+      removeCommentsFromCDATA:      byId('remove-comments-from-cdata').checked,
+      removeCDATASectionsFromCDATA: byId('remove-cdata-sections-from-cdata').checked,
+      collapseWhitespace:           byId('collapse-whitespace').checked,
+      collapseBooleanAttributes:    byId('collapse-boolean-attributes').checked,q
+      removeAttributeQuotes:        byId('remove-attribute-quotes').checked,  
+      removeRedundantAttributes:    byId('remove-redundant-attributes').checked,
+      useShortDoctype:              byId('use-short-doctype').checked,
+      removeEmptyAttributes:        byId('remove-empty-attributes').checked,
+      removeEmptyElements:          byId('remove-empty-elements').checked
     };
   }
   
index 2216942..36a8cf3 100644 (file)
         currentChars = '';
       },
       chars: function( text ) {
-        if (options.removeCommentsFromCDATA &&
-            (currentTag === 'script' || currentTag === 'style')) {
-          text = text.replace(/^\s*<!--/, '').replace(/-->\s*$/, '');
+        if (currentTag === 'script' || currentTag === 'style') {
+          if (options.removeCommentsFromCDATA) {
+            text = text.replace(/^\s*<!--/, '').replace(/-->\s*$/, '');
+          }
+          if (options.removeCDATASectionsFromCDATA) {
+            text = text
+              // /* <![[CDATA */ or // <![[CDATA
+              .replace(/^(?:\s*\/\*\s*<!\[\[CDATA\[\s*\*\/|\s*\/\/\s*<!\[\[CDATA\[.*)/, '')
+              // /* ]]> */ or // ]]>
+              .replace(/(?:\/\*\s*\]\]>\s*\*\/|\/\/\s*\]\]>.*)$/, '');
+          }
         }
         if (options.collapseWhitespace) {
           if (canTrimWhitespace(currentTag)) {
index dd970ba..80b7530 100644 (file)
           equals(minify(input, { removeCommentsFromCDATA: true }), output);
         });
         
+        test('remove CDATA sections from scripts/styles', function(){
+          var input = '<script>/*<![[CDATA[*/alert(1)/*]]>*/<\/script>';
+          var output = '<script>alert(1)<\/script>';
+          equals(minify(input, { removeCDATASectionsFromCDATA: true }), output);
+          
+          input = '<script>//<![[CDATA[\nalert(1)\n//]]><\/script>';
+          output = '<script>\nalert(1)\n<\/script>';
+          equals(minify(input, { removeCDATASectionsFromCDATA: true }), output);
+          
+          input = '<script type="text/javascript"> /* \n\t  <![[CDATA[  */ alert(1) /*  ]]>  */<\/script>';
+          output = '<script type="text/javascript"> alert(1) <\/script>';
+          equals(minify(input, { removeCDATASectionsFromCDATA: true }), output);
+          
+          input = '<style>/* <![[CDATA[ */p { color: red } // ]]><\/style>';
+          output = '<style>p { color: red } </style>';
+          equals(minify(input, { removeCDATASectionsFromCDATA: true }), output);
+        });
+        
         test('empty attributes', function(){
           var input = '<p id="" class="" STYLE=" " title="\n" lang="" dir="">x</p>';
           equals(minify(input, { removeEmptyAttributes: true }), '<p>x</p>');