diff --git a/README.md b/README.md
index 4b1c4d4d..dabc70dd 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@ Compares two HTML.
- [ignoreComments](#ignorecomments-boolean)
- [ignoreEndTags](#ignoreendtags-boolean)
- [ignoreDuplicateAttributes](#ignoreduplicateattributes-boolean)
+ - [ignoreEmptyAttributes](#ignoreemptyattributes-boolean)
- [Presets](#presets)
- [Usage](#usage)
- [Methods](#methods)
@@ -269,6 +270,38 @@ For example, the following two code samples will be considered to be equivalent:
Text
```
+
+##### ignoreEmptyAttributes: Boolean
+
+Makes **html-differ** ignore tags' attributes with empty values during the comparison.
+From the list of the same tag's attributes, the attributes which have empty values will be ignored (default: `false`).
+
+**Example**: `true`
+For example, the following two code samples will be considered to be equivalent:
+
+```html
+
+```
+
+```html
+
+```
+
+This option can also be used to completely ignore attributes specified by the `ignoreAttributes` option, even if they are present in one example, but not in the other.
+
+**Example**: `ignoreAttributes: ['id', 'for'], ignoreEmptyAttributes: true`
+For example, the following two code samples will be considered to be equivalent:
+
+```html
+
+
+```
+
+```html
+
+
+```
+
#### Presets
* [bem](https://github.com/bem/html-differ/blob/master/presets/bem.json) - sets predefined options for [BEM](http://bem.info/).
diff --git a/lib/HtmlDiff.js b/lib/HtmlDiff.js
index cb2ed74b..f21a49e9 100644
--- a/lib/HtmlDiff.js
+++ b/lib/HtmlDiff.js
@@ -13,6 +13,7 @@ var diff = require('diff'),
* @param {Boolean} [options.ignoreComments]
* @param {Boolean} [options.ignoreEndTags=false]
* @param {Boolean} [options.ignoreDuplicateAttributes=false]
+ * @param {Boolean} [options.ignoreEmptyAttributes=false]
*/
var HtmlDiff = function (options) {
this.options = defaults(options);
diff --git a/lib/defaults.js b/lib/defaults.js
index 33246355..d25582fe 100644
--- a/lib/defaults.js
+++ b/lib/defaults.js
@@ -14,6 +14,7 @@ var presets = {
* @param {Boolean} [options.ignoreComments=true]
* @param {Boolean} [options.ignoreEndTags=false]
* @param {Boolean} [options.ignoreDuplicateAttributes=false]
+ * @param {Boolean} [options.ignoreEmptyAttributes=false]
* returns {Object}
*/
module.exports = function (options) {
@@ -39,7 +40,8 @@ var presets = {
ignoreComments: true,
ignoreEndTags: false,
- ignoreDuplicateAttributes: false
+ ignoreDuplicateAttributes: false,
+ ignoreEmptyAttributes: false
});
};
diff --git a/lib/index.js b/lib/index.js
index e5f5d63a..be8c69db 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -25,6 +25,7 @@ HtmlDiff.prototype.tokenize = function (html) {
* @param {Boolean} [options.ignoreComments=true]
* @param {Boolean} [options.ignoreEndTags=false]
* @param {Boolean} [options.ignoreDuplicateAttributes=false]
+ * @param {Boolean} [options.ignoreEmptyAttributes=false]
*/
var HtmlDiffer = function (options) {
options = defaults(options);
diff --git a/lib/utils/modify.js b/lib/utils/modify.js
index 6789b347..0b027e5f 100644
--- a/lib/utils/modify.js
+++ b/lib/utils/modify.js
@@ -12,6 +12,7 @@ var SimpleApiParser = require('parse5').SimpleApiParser,
* @param {Boolean} [options.ignoreComments=true]
* @param {Boolean} [options.ignoreEndTags=false]
* @param {Boolean} [options.ignoreDuplicateAttributes=false]
+ * @param {Boolean} [options.ignoreEmptyAttributes=false]
* returns {String}
*/
function modify(value, options) {
@@ -42,6 +43,10 @@ function modify(value, options) {
utils.sortAttrsValues(attrs, options.compareAttributesAsJSON) &&
utils.removeAttrsValues(attrs, options.ignoreAttributes);
+ if (options.ignoreEmptyAttributes) {
+ attrs = utils.removeEmptyAttributes(attrs);
+ }
+
modifiedValue += serialize.startTag(tagName, attrs, selfClosing);
},
/**
diff --git a/lib/utils/utils.js b/lib/utils/utils.js
index a57d2c14..74e6b82f 100644
--- a/lib/utils/utils.js
+++ b/lib/utils/utils.js
@@ -193,6 +193,18 @@ function removeDuplicateAttributes(attrs) {
return res;
}
+function removeEmptyAttributes(attrs) {
+ var res = [];
+
+ _.forEach(attrs, function (attr) {
+ if (attr.value !== '') {
+ res.push(attr);
+ }
+ });
+
+ return res;
+}
+
/**
* Processes a conditional comment
* @param {String} comment
@@ -228,6 +240,7 @@ module.exports = {
removeAttrsValues: removeAttrsValues,
removeWhitespaces: removeWhitespaces,
removeDuplicateAttributes: removeDuplicateAttributes,
+ removeEmptyAttributes: removeEmptyAttributes,
getConditionalComment: getConditionalComment
};
diff --git a/test/differ/fixtures/first/ignore-attributes-empty.html b/test/differ/fixtures/first/ignore-attributes-empty.html
new file mode 100644
index 00000000..f1109c3f
--- /dev/null
+++ b/test/differ/fixtures/first/ignore-attributes-empty.html
@@ -0,0 +1,2 @@
+
+
diff --git a/test/differ/fixtures/first/ignore-empty-attributes.html b/test/differ/fixtures/first/ignore-empty-attributes.html
new file mode 100644
index 00000000..16839deb
--- /dev/null
+++ b/test/differ/fixtures/first/ignore-empty-attributes.html
@@ -0,0 +1 @@
+
diff --git a/test/differ/fixtures/second/ignore-attributes-empty.html b/test/differ/fixtures/second/ignore-attributes-empty.html
new file mode 100644
index 00000000..ff39878d
--- /dev/null
+++ b/test/differ/fixtures/second/ignore-attributes-empty.html
@@ -0,0 +1,2 @@
+
+
diff --git a/test/differ/fixtures/second/ignore-empty-attributes.html b/test/differ/fixtures/second/ignore-empty-attributes.html
new file mode 100644
index 00000000..7c89b545
--- /dev/null
+++ b/test/differ/fixtures/second/ignore-empty-attributes.html
@@ -0,0 +1 @@
+
diff --git a/test/differ/isEqual.js b/test/differ/isEqual.js
index d495cf5a..95e2ca44 100644
--- a/test/differ/isEqual.js
+++ b/test/differ/isEqual.js
@@ -136,6 +136,34 @@ describe('\'isEqual\'', function () {
htmlDiffer.isEqual(files.html1, files.html2).must.be.false();
});
+ it('must work option \'ignoreEmptyAttributes\'', function () {
+ var htmlDiffer = new HtmlDiffer({ ignoreEmptyAttributes: true }),
+ files = readFiles('ignore-empty-attributes');
+
+ htmlDiffer.isEqual(files.html1, files.html2).must.be.true();
+ });
+
+ it('must not ignore empty attributes', function () {
+ var htmlDiffer = new HtmlDiffer({ ignoreEmptyAttributes: false }),
+ files = readFiles('ignore-empty-attributes');
+
+ htmlDiffer.isEqual(files.html1, files.html2).must.be.false();
+ });
+
+ it('must work options \'ignoreAttributes\' and \'ignoreEmptyAttributes\'', function () {
+ var htmlDiffer = new HtmlDiffer({ ignoreAttributes: ['id', 'for'], ignoreEmptyAttributes: true }),
+ files = readFiles('ignore-attributes-empty');
+
+ htmlDiffer.isEqual(files.html1, files.html2).must.be.true();
+ });
+
+ it('must not ignore attributes', function () {
+ var htmlDiffer = new HtmlDiffer({ }),
+ files = readFiles('ignore-attributes-empty');
+
+ htmlDiffer.isEqual(files.html1, files.html2).must.be.false();
+ });
+
it('must work \'bem\' preset', function () {
var htmlDiffer = new HtmlDiffer('bem'),
files = readFiles('bem-preset');