From 3f6f256f195fe916be97141a98eafb62a980f51e Mon Sep 17 00:00:00 2001 From: sxend Date: Thu, 17 Nov 2016 18:39:37 +0900 Subject: [PATCH] removeEmptyAttr predicate function --- README.md | 2 +- src/htmlminifier.js | 13 ++++++++----- tests/minifier.js | 4 ++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 85db897..af26496 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ How does HTMLMinifier compare to other solutions — [HTML Minifier from Will Pe | `quoteCharacter` | Type of quote to use for attribute values (' or ") | | | `removeAttributeQuotes` | [Remove quotes around attributes when possible](http://perfectionkills.com/experimenting-with-html-minifier/#remove_attribute_quotes) | `false` | | `removeComments` | [Strip HTML comments](http://perfectionkills.com/experimenting-with-html-minifier/#remove_comments) | `false` | -| `removeEmptyAttributes` | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes) | `false` | +| `removeEmptyAttributes` | [Remove all attributes with whitespace-only values](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_or_blank_attributes) | `false` (could be true, Function(attrName, tag)) | | `removeEmptyElements` | [Remove all elements with empty contents](http://perfectionkills.com/experimenting-with-html-minifier/#remove_empty_elements) | `false` | | `removeOptionalTags` | [Remove optional tags](http://perfectionkills.com/experimenting-with-html-minifier/#remove_optional_tags) | `false` | | `removeRedundantAttributes` | [Remove attributes when value matches default.](http://perfectionkills.com/experimenting-with-html-minifier/#remove_redundant_attributes) | `false` | diff --git a/src/htmlminifier.js b/src/htmlminifier.js index 6848216..61ade0b 100644 --- a/src/htmlminifier.js +++ b/src/htmlminifier.js @@ -455,12 +455,15 @@ var reEmptyAttribute = new RegExp( '^(?:class|id|style|title|lang|dir|on(?:focus|blur|change|click|dblclick|mouse(' + '?:down|up|over|move|out)|key(?:press|down|up)))$'); -function canDeleteEmptyAttribute(tag, attrName, attrValue) { +function canDeleteEmptyAttribute(tag, attrName, attrValue, options) { var isValueEmpty = !attrValue || /^\s*$/.test(attrValue); - if (isValueEmpty) { - return tag === 'input' && attrName === 'value' || reEmptyAttribute.test(attrName); + if (!isValueEmpty) { + return false; } - return false; + if (typeof options.removeEmptyAttributes === 'function') { + return options.removeEmptyAttributes(attrName, tag); + } + return tag === 'input' && attrName === 'value' || reEmptyAttribute.test(attrName); } function hasAttrName(name, attrs) { @@ -530,7 +533,7 @@ function normalizeAttr(attr, attrs, tag, options) { attrValue = cleanAttributeValue(tag, attrName, attrValue, options, attrs); if (options.removeEmptyAttributes && - canDeleteEmptyAttribute(tag, attrName, attrValue)) { + canDeleteEmptyAttribute(tag, attrName, attrValue, options)) { return; } diff --git a/tests/minifier.js b/tests/minifier.js index 91fe7c3..3c0d41a 100644 --- a/tests/minifier.js +++ b/tests/minifier.js @@ -792,6 +792,10 @@ QUnit.test('empty attributes', function(assert) { // remove recognized attrs with unspecified values input = '
'; assert.equal(minify(input, { removeEmptyAttributes: true }), '
'); + + // additional remove attributes + input = ''; + assert.equal(minify(input, { removeEmptyAttributes: function(attrName, tag) { return tag === 'img' && attrName === 'src'; } }), ''); }); QUnit.test('cleaning class/style attributes', function(assert) { -- 2.34.1