handle line-breaks around custom fragments gracefully
authoralexlamsl <alexlamsl@gmail.com>
Wed, 21 Sep 2016 10:19:22 +0000 (18:19 +0800)
committeralexlamsl <alexlamsl@gmail.com>
Wed, 21 Sep 2016 13:23:04 +0000 (21:23 +0800)
src/htmlminifier.js
tests/minifier.js

index a4b5442..8f4f497 100644 (file)
@@ -858,36 +858,38 @@ function minify(value, options, partialMarkup) {
     return token;
   });
 
+  function escapeFragments(text) {
+    return text.replace(uidPattern, function(match, prefix, index) {
+      var chunks = ignoredCustomMarkupChunks[+index];
+      return chunks[1] + uidAttr + index + chunks[2];
+    });
+  }
+
   var customFragments = options.ignoreCustomFragments.map(function(re) {
     return re.source;
   });
   if (customFragments.length) {
-    var reCustomIgnore = new RegExp('\\s*(?:' + customFragments.join('|') + ')+\\s*', 'g');
+    var reCustomIgnore = new RegExp('(\\s*)(?:' + customFragments.join('|') + ')+(\\s*)', 'g');
     // temporarily replace custom ignored fragments with unique attributes
-    value = value.replace(reCustomIgnore, function(match) {
+    value = value.replace(reCustomIgnore, function(match, prefix, suffix) {
       if (!uidAttr) {
         uidAttr = uniqueId(value);
         uidPattern = new RegExp('(\\s*)' + uidAttr + '([0-9]+)(\\s*)', 'g');
         var minifyCSS = options.minifyCSS;
         if (minifyCSS) {
           options.minifyCSS = function(text) {
-            return minifyCSS(text).replace(uidPattern, function(match, prefix, index, suffix) {
-              return (prefix && '\t') + uidAttr + index + (suffix && '\t');
-            });
+            return minifyCSS(escapeFragments(text));
           };
         }
         var minifyJS = options.minifyJS;
         if (minifyJS) {
-          var pattern = new RegExp('(\\\\t|)' + uidAttr + '([0-9]+)(\\\\t|)', 'g');
           options.minifyJS = function(text, inline) {
-            return minifyJS(text, inline).replace(pattern, function(match, prefix, index, suffix) {
-              return (prefix && '\t') + uidAttr + index + (suffix && '\t');
-            });
+            return minifyJS(escapeFragments(text), inline);
           };
         }
       }
       var token = uidAttr + ignoredCustomMarkupChunks.length;
-      ignoredCustomMarkupChunks.push(match);
+      ignoredCustomMarkupChunks.push([match, prefix, suffix]);
       return '\t' + token + '\t';
     });
   }
@@ -1248,7 +1250,7 @@ function minify(value, options, partialMarkup) {
 
   if (uidPattern) {
     str = str.replace(uidPattern, function(match, prefix, index, suffix) {
-      var chunk = ignoredCustomMarkupChunks[+index];
+      var chunk = ignoredCustomMarkupChunks[+index][0];
       if (options.collapseWhitespace) {
         if (prefix !== '\t') {
           chunk = prefix + chunk;
index 61c8ec2..538501c 100644 (file)
@@ -1887,16 +1887,45 @@ QUnit.test('minification of scripts with different mimetypes', function(assert)
 
   input = '<script type="text/html"><!-- ko if: true -->\n\n\n<div></div>\n\n\n<!-- /ko --></script>';
   assert.equal(minify(input, { minifyJS: true }), input);
+});
+
+QUnit.test('minification of scripts with custom fragments', function(assert) {
+  var input, output;
 
-  input = '<script type=""><?php ?></script>';
+  input = '<script><?php ?></script>';
   assert.equal(minify(input, { minifyJS: true }), input);
 
-  input = '<script type="">function f(){  return <?php ?>  }</script>';
-  output = '<script type="">function f(){return <?php ?>  }</script>';
+  input = '<script>\n<?php ?></script>';
+  assert.equal(minify(input, { minifyJS: true }), input);
+
+  input = '<script><?php ?>\n</script>';
+  assert.equal(minify(input, { minifyJS: true }), input);
+
+  input = '<script>\n<?php ?>\n</script>';
+  assert.equal(minify(input, { minifyJS: true }), input);
+
+  input = '<script>// <% ... %></script>';
+  output = '<script></script>';
   assert.equal(minify(input, { minifyJS: true }), output);
 
-  input = '<script type="">function f(){  return "<?php ?>"  }</script>';
-  output = '<script type="">function f(){return"<?php ?>"}</script>';
+  input = '<script>// \n<% ... %></script>';
+  output = '<script> \n<% ... %></script>';
+  assert.equal(minify(input, { minifyJS: true }), output);
+
+  input = '<script>// <% ... %>\n</script>';
+  output = '<script></script>';
+  assert.equal(minify(input, { minifyJS: true }), output);
+
+  input = '<script>// \n<% ... %>\n</script>';
+  output = '<script> \n<% ... %>\n</script>';
+  assert.equal(minify(input, { minifyJS: true }), output);
+
+  input = '<script>function f(){  return <?php ?>  }</script>';
+  output = '<script>function f(){return <?php ?>  }</script>';
+  assert.equal(minify(input, { minifyJS: true }), output);
+
+  input = '<script>function f(){  return "<?php ?>"  }</script>';
+  output = '<script>function f(){return"<?php ?>"}</script>';
   assert.equal(minify(input, { minifyJS: true }), output);
 });
 
@@ -1989,7 +2018,7 @@ QUnit.test('style minification', function(assert) {
 
   input = '<div style="background: url(\'images/<% image %>\')"></div>';
   assert.equal(minify(input), input);
-  output = '<div style="background:url(\'images/<% image %>\')"></div>';
+  output = '<div style="background:url(images/<% image %>)"></div>';
   assert.equal(minify(input, { minifyCSS: true }), output);
   assert.equal(minify(input, {
     collapseWhitespace: true,
@@ -2007,7 +2036,7 @@ QUnit.test('style minification', function(assert) {
 
   input = '<style>p { background: url("images/<% image %>") }</style>';
   assert.equal(minify(input), input);
-  output = '<style>p{background:url("images/<% image %>")}</style>';
+  output = '<style>p{background:url(images/<% image %>)}</style>';
   assert.equal(minify(input, { minifyCSS: true }), output);
   assert.equal(minify(input, {
     collapseWhitespace: true,