From 4f6d016dc7752668cbff62a3a431f7447deb57b1 Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Wed, 20 Jan 2016 18:44:43 +0800 Subject: [PATCH] improve quote and escape - avoid excessive attribute value character escaping - choose between ' and " if quoteCharacter unspecified --- src/htmlminifier.js | 24 ++++++++++++++++++++---- src/htmlparser.js | 5 +---- tests/minifier.js | 23 +++++++++++++++++++---- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/htmlminifier.js b/src/htmlminifier.js index f43bf6f..8d490ec 100644 --- a/src/htmlminifier.js +++ b/src/htmlminifier.js @@ -242,7 +242,7 @@ if (options.minifyJS) { var wrappedCode = '(function(){' + attrValue + '})()'; var minified = minifyJS(wrappedCode, options.minifyJS); - return minified.slice(12, minified.length - 4).replace(/"/g, '"'); + return minified.slice(12, minified.length - 4); } return attrValue; } @@ -387,8 +387,8 @@ function normalizeAttribute(attr, attrs, tag, hasUnarySlash, index, options, isLast) { var attrName = options.caseSensitive ? attr.name : attr.name.toLowerCase(), - attrValue = options.preventAttributesEscaping ? attr.value : attr.escaped, - attrQuote = options.preventAttributesEscaping ? attr.quote : (options.quoteCharacter === '\'' ? '\'' : '"'), + attrValue = attr.value, + attrQuote = attr.quote, attrFragment, emittedAttrValue; @@ -412,6 +412,22 @@ if (attrValue !== undefined && !options.removeAttributeQuotes || !canRemoveAttributeQuotes(attrValue)) { + if (!options.preventAttributesEscaping) { + if (options.quoteCharacter !== undefined) { + attrQuote = options.quoteCharacter === '\'' ? '\'' : '"'; + } + else { + var apos = (attrValue.match(/'/g) || []).length; + var quot = (attrValue.match(/"/g) || []).length; + attrQuote = apos < quot ? '\'' : '"'; + } + if (attrQuote === '"') { + attrValue = attrValue.replace(/"/g, '"'); + } + else { + attrValue = attrValue.replace(/'/g, '''); + } + } emittedAttrValue = attrQuote + attrValue + attrQuote; } // make sure trailing slash is not interpreted as HTML self-closing tag @@ -664,7 +680,7 @@ var insert = buffer.length; for (var i = attrs.length; --i >= 0; ) { if (lint) { - lint.testAttribute(tag, attrs[i].name.toLowerCase(), attrs[i].escaped); + lint.testAttribute(tag, attrs[i].name.toLowerCase(), attrs[i].value); } token = normalizeAttribute(attrs[i], attrs, tag, hasUnarySlash, i, options, isLast); if (token) { diff --git a/src/htmlparser.js b/src/htmlparser.js index 3fc5988..c1e07c9 100644 --- a/src/htmlparser.js +++ b/src/htmlparser.js @@ -362,9 +362,6 @@ attrs.push({ name: name, value: value, - escaped: value && value.replace(/(^|.)("+)/g, function(match) { - return match.replace(/"/g, '"'); - }), customAssign: customAssign || '=', customOpen: customOpen || '', customClose: customClose || '', @@ -424,7 +421,7 @@ results += '<' + tag; for ( var i = 0; i < attrs.length; i++ ) { - results += ' ' + attrs[i].name + '="' + attrs[i].escaped + '"'; + results += ' ' + attrs[i].name + '="' + (attrs[i].value || '').replace(/"/g, '"') + '"'; } results += (unary ? '/' : '') + '>'; diff --git a/tests/minifier.js b/tests/minifier.js index 732c48b..18533b8 100644 --- a/tests/minifier.js +++ b/tests/minifier.js @@ -976,8 +976,11 @@ test('nested quotes', function() { input = '
'; - output = '
'; - equal(minify(input), output); + equal(minify(input), input); + equal(minify(input, { quoteCharacter: '\'' }), input); + + output = '
'; + equal(minify(input, { quoteCharacter: '"' }), output); }); test('script minification', function() { @@ -1056,14 +1059,26 @@ equal(minify(input, { minifyJS: true }), output); input = ' foobar'; - output = ' foobar'; + output = ' foobar'; equal(minify(input, { minifyJS: { mangle: false } }), output); + equal(minify(input, { minifyJS: { mangle: false }, quoteCharacter: '\'' }), output); + + input = ' foobar'; + output = ' foobar'; + + equal(minify(input, { minifyJS: { mangle: false }, quoteCharacter: '"' }), output); input = ''; - output = ''; + output = ''; equal(minify(input, { minifyJS: true }), output); + equal(minify(input, { minifyJS: true, quoteCharacter: '\'' }), output); + + input = ''; + output = ''; + + equal(minify(input, { minifyJS: true, quoteCharacter: '"' }), output); input = ''; output = ''; -- 2.34.1