New feature: "ignored" tags.
authorMicky Hulse <mickyhulse@gmail.com>
Wed, 21 Aug 2013 10:15:34 +0000 (03:15 -0700)
committerMicky Hulse <mickyhulse@gmail.com>
Wed, 21 Aug 2013 10:15:34 +0000 (03:15 -0700)
Still a work in progress.

dist/all.js
index.html
master.js
src/htmlminifier.js
src/htmlparser.js
tests/minifier.js

index 5333f9a..aa7f6d8 100644 (file)
@@ -54,7 +54,7 @@
   var reCache = { }, stackedTag, reStackedTag, tagMatch;
 
   var HTMLParser = global.HTMLParser = function( html, handler ) {
-    var index, chars, match, stack = [], last = html, prevTag, nextTag;
+    var index, chars, ignored = [], match, stack = [], last = html, prevTag, nextTag;
     stack.last = function(){
       return this[ this.length - 1 ];
     };
             chars = false;
           }
         }
+
+        // Ignored elements?
+        else if ((ignored[1] = (html.indexOf('<%') === 0)) || (ignored[2] = (html.indexOf('<?') === 0))) { // Determine "kind".
+          index = html.indexOf(ignored[1] ? '%>' : '?>'); // Find closing tag.
+          if (index >= 0) { // Found?
+            handler.ignore && handler.ignore(html.substring(0, index + 2)); // Return ignored string if callback exists.
+            html = html.substring(index + 2); // Next starting point for parser.
+            chars = false; // Chars flag.
+          }
+        }
+
         else if ( (match = doctype.exec( html )) ) {
           if ( handler.doctype )
             handler.doctype( match[0] );
       },
       comment: function( text ) {
         results += "<!--" + text + "-->";
+      },
+      ignore: function(text) {
+        // Need to test this.
       }
     });
 
       },
       comment: function( /*text*/ ) {
         // create comment node
+      },
+      ignore: function(text) {
+        // Need to test this.
       }
     });
 
         }
         buffer.push(text);
       },
+      ignore: function(text) {
+        // `text` === strings that start with `<?` or `<%` and end with `?>` or `%>`.
+        buffer.push(options.removeIgnored ? '' : trimWhitespace(text)); // `text` allowed by default.
+      },
       doctype: function(doctype) {
         buffer.push(options.useShortDoctype ? '<!DOCTYPE html>' : collapseWhitespace(doctype));
       }
index b51d2fb..5555826 100644 (file)
                 </span>
               </label>
             </li>
+            <li>
+              <input type="checkbox" id="remove-ignored">
+              <label for="remove-ignored">
+                Remove ignored tags
+                <br>
+                <span class="quiet short">
+                  Currently, only tags starting and ending with: 
+                  <code>&lt;% ... %></code> 
+                  and 
+                  <code>&lt;? ... ?></code>
+                </span>
+              </label>
+            </li>
             <li>
               <input type="checkbox" id="remove-empty-elements">
               <label for="remove-empty-elements" class="unsafe">
index 2697b32..364890b 100644 (file)
--- a/master.js
+++ b/master.js
@@ -10,6 +10,7 @@
   
   function getOptions() {
     return {
+      removeIgnored:                  byId('remove-ignored').checked,
       removeComments:                 byId('remove-comments').checked,
       removeCommentsFromCDATA:        byId('remove-comments-from-cdata').checked,
       removeCDATASectionsFromCDATA:   byId('remove-cdata-sections-from-cdata').checked,
index acde7dc..c0dbccb 100644 (file)
         }
         buffer.push(text);
       },
+      ignore: function(text) {
+        // `text` === strings that start with `<?` or `<%` and end with `?>` or `%>`.
+        buffer.push(options.removeIgnored ? '' : trimWhitespace(text)); // `text` allowed by default.
+      },
       doctype: function(doctype) {
         buffer.push(options.useShortDoctype ? '<!DOCTYPE html>' : collapseWhitespace(doctype));
       }
index bee8b79..28aaf1d 100644 (file)
@@ -54,7 +54,7 @@
   var reCache = { }, stackedTag, reStackedTag, tagMatch;
 
   var HTMLParser = global.HTMLParser = function( html, handler ) {
-    var index, chars, match, stack = [], last = html, prevTag, nextTag;
+    var index, chars, ignored = [], match, stack = [], last = html, prevTag, nextTag;
     stack.last = function(){
       return this[ this.length - 1 ];
     };
             chars = false;
           }
         }
+
+        // Ignored elements?
+        else if ((ignored[1] = (html.indexOf('<%') === 0)) || (ignored[2] = (html.indexOf('<?') === 0))) { // Determine "kind".
+          index = html.indexOf(ignored[1] ? '%>' : '?>'); // Find closing tag.
+          if (index >= 0) { // Found?
+            handler.ignore && handler.ignore(html.substring(0, index + 2)); // Return ignored string if callback exists.
+            html = html.substring(index + 2); // Next starting point for parser.
+            chars = false; // Chars flag.
+          }
+        }
+
         else if ( (match = doctype.exec( html )) ) {
           if ( handler.doctype )
             handler.doctype( match[0] );
       },
       comment: function( text ) {
         results += "<!--" + text + "-->";
+      },
+      ignore: function(text) {
+        // Need to test this.
       }
     });
 
       },
       comment: function( /*text*/ ) {
         // create comment node
+      },
+      ignore: function(text) {
+        // Need to test this.
       }
     });
 
index 8013f55..475f5b0 100644 (file)
     equal(minify(input, { html5: true }), minify(input));
   });
 
+  test('Ignored tags: enabled by default', function() {
+    
+    // https://github.com/kangax/html-minifier/issues/10
+    input = 'This is the start. <% ... %>\r\n<%= ... %>\r\n<? ... ?>\r\n<!-- This is the middle, and a comment. -->\r\nNo comment, but middle.\r\n<?= ... ?>\r\n<?php ... ?>\r\n<?xml ... ?>\r\nHello, this is the end!';
+    output = 'This is the start.<% ... %><%= ... %><? ... ?>No comment, but middle.<?= ... ?><?php ... ?><?xml ... ?>Hello, this is the end!';
+    equal(minify(input, {}), input);
+    equal(minify(input, { removeComments: true, collapseWhitespace: true }), output);
+    
+    output = 'This is the start.No comment, but middle.Hello, this is the end!';
+    equal(minify(input, { removeComments: true, collapseWhitespace: true, removeIgnored: true }), output);
+    
+  });
+
 })(typeof exports === 'undefined' ? window : exports);