Skip to content

Commit

Permalink
Merge pull request #720 from kangax/minify-custom-fragments
Browse files Browse the repository at this point in the history
handle line-breaks around custom fragments gracefully
  • Loading branch information
alexlamsl authored Sep 22, 2016
2 parents 89c2968 + 3391adc commit 3640d84
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 18 deletions.
24 changes: 13 additions & 11 deletions src/htmlminifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
});
}
Expand Down Expand Up @@ -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;
Expand Down
47 changes: 40 additions & 7 deletions tests/minifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ QUnit.test('space normalization around text', function(assert) {
assert.equal(minify('<p>foo<wbr>bar</p>', { collapseWhitespace: true }), '<p>foo<wbr>bar</p>');
assert.equal(minify('<p>foo <wbr>bar</p>', { collapseWhitespace: true }), '<p>foo <wbr>bar</p>');
assert.equal(minify('<p>foo<wbr> bar</p>', { collapseWhitespace: true }), '<p>foo<wbr> bar</p>');
assert.equal(minify('<p>foo <wbr baz moo=""> bar</p>', { collapseWhitespace: true }), '<p>foo<wbr baz moo=""> bar</p>');
assert.equal(minify('<p>foo<wbr baz moo="">bar</p>', { collapseWhitespace: true }), '<p>foo<wbr baz moo="">bar</p>');
assert.equal(minify('<p>foo <wbr baz moo="">bar</p>', { collapseWhitespace: true }), '<p>foo <wbr baz moo="">bar</p>');
assert.equal(minify('<p>foo<wbr baz moo=""> bar</p>', { collapseWhitespace: true }), '<p>foo<wbr baz moo=""> bar</p>');
assert.equal(minify('<p> <a href="#"> <code>foo</code></a> bar</p>', { collapseWhitespace: true }), '<p><a href="#"><code>foo</code></a> bar</p>');
assert.equal(minify('<p><a href="#"><code>foo </code></a> bar</p>', { collapseWhitespace: true }), '<p><a href="#"><code>foo</code></a> bar</p>');
assert.equal(minify('<p> <a href="#"> <code> foo</code></a> bar </p>', { collapseWhitespace: true }), '<p><a href="#"><code>foo</code></a> bar</p>');
Expand Down Expand Up @@ -1887,16 +1891,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);
});

Expand Down Expand Up @@ -1989,7 +2022,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,
Expand All @@ -2007,7 +2040,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,
Expand Down

0 comments on commit 3640d84

Please sign in to comment.