Skip to content

Commit 78204d1

Browse files
committed
Merge pull request #107 from bem/issue106
Issue106
2 parents 5998b9c + 47d7dc3 commit 78204d1

9 files changed

Lines changed: 51 additions & 14 deletions

File tree

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,26 @@ The following two code samples will be considered to be equivalent:
9292

9393
* **compareAttributesAsJSON: [ Array ]**
9494

95-
Sets what kind of respective attributes' content will be compared as JSON objects, but not as strings (default: `[]`).
95+
Sets what kind of respective attributes' content will be compared as JSON objects, but not as strings (default: `[]`).<br>
96+
In cases when the value of the attribute is an invalid JSON or can not be wrapped into a function, it will be compared as `undefined`.
9697

9798
**Example**: `[{ name: 'data', isFunction: false }, { name: 'onclick', isFunction: true }]`<br>
9899
The following two code samples will be considered to be equivalent:
99100

100101
```html
101102
<div data='{"bla":{"first":"ololo","second":"trololo"}}'></div>
102103
<span onclick='return {"aaa":"bbb","bbb":"aaa"}'></span>
104+
105+
<button data='REALLY BAD JSON'></button>
106+
<button onclick='REALLY BAD FUNCTION'></button>
103107
```
104108

105109
```html
106110
<div data='{"bla":{"second":"trololo","first":"ololo"}}'></div>
107111
<span onclick='return {"bbb":"aaa","aaa":"bbb"}'></span>
112+
113+
<button data='undefined'></button>
114+
<button onclick='undefined'></button>
108115
```
109116

110117
**REMARK!**<br>

README.ru.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,26 @@ var HtmlDiffer = require('html-differ').HtmlDiffer,
9292

9393
* **compareAttributesAsJSON: [ Array ]**
9494

95-
Устанавливает, значения каких атрибутов следует сравнивать как JSON-объекты, а не как строки (по умолчанию: `[]`).
95+
Устанавливает, значения каких атрибутов следует сравнивать как JSON-объекты, а не как строки (по умолчанию: `[]`).<br>
96+
В тех случаях, когда в качестве значения атрибута выступает некорректный JSON или это значение нельзя обернуть в функцию, то оно будет сравниваться как `undefined`.
9697

9798
**Пример**: `[{ name: 'data', isFunction: false }, { name: 'onclick', isFunction: true }]`<br>
9899
Следующие два HTML будут считаться эквивалентными:
99100

100101
```html
101102
<div data='{"bla":{"first":"ololo","second":"trololo"}}'></div>
102103
<span onclick='return {"aaa":"bbb","bbb":"aaa"}'></span>
104+
105+
<button data='REALLY BAD JSON'></button>
106+
<button onclick='REALLY BAD FUNCTION'></button>
103107
```
104108

105109
```html
106110
<div data='{"bla":{"second":"trololo","first":"ololo"}}'></div>
107111
<span onclick='return {"bbb":"aaa","aaa":"bbb"}'></span>
112+
113+
<button data='undefined'></button>
114+
<button onclick='undefined'></button>
108115
```
109116

110117
**ПРИМЕЧАНИЕ!**<br>

lib/utils/utils.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,24 @@ function sortAttrsValues(attrs, compareAttributesAsJSON) {
9595
}
9696

9797
/**
98-
* Parses the given JSON in HTML attribute
98+
* Parses the given in HTML attribute JSON
9999
* @param {String} val
100100
* @param {Boolean} [isClick]
101101
* @returns {Object}
102102
*/
103103
function _parseAttr(val, isClick) {
104-
if (isClick) {
105-
/*jshint evil: true */
106-
var fn = Function(val);
104+
try {
105+
if (isClick) {
106+
/*jshint evil: true */
107+
var fn = Function(val);
107108

108-
return fn ? fn() : {};
109-
}
109+
return fn ? fn() : {};
110+
}
110111

111-
return JSON.parse(val);
112+
return JSON.parse(val);
113+
} catch (err) {
114+
return undefined;
115+
}
112116
}
113117

114118
_.forEach(compareAttributesAsJSON, function (attr) {
@@ -125,10 +129,10 @@ function sortAttrsValues(attrs, compareAttributesAsJSON) {
125129

126130
_.forEach(attrIndexes, function (index) {
127131
attrValue = _parseAttr(attrs[index].value, isFunction);
128-
attrValue = _sortObj(attrValue);
129-
attrValue = JSON.stringify(attrValue);
130132

131-
attrs[index].value = (isFunction ? 'return ' : '') + attrValue;
133+
attrValue && (attrValue = JSON.stringify(_sortObj(attrValue)));
134+
135+
attrs[index].value = (isFunction && attrValue ? 'return ' : '') + attrValue;
132136
});
133137
});
134138

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button onclick="{&quot;button&quot;:{}};"></button>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button data-bem="{&quot;button&quot;:{invalid}}"></button>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button onclick="undefined"></button>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<button data-bem="undefined"></button>

test/diff/getDiffText.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var diffLoger = require('../../lib/logger');
22

33
require('colors');
44

5-
describe('\'diffHtml\'', function () {
5+
describe('\'getDiffText\'', function () {
66
it('must return an empty string', function () {
77
var inp = [ {
88
value: 'text',

test/diff/isEqual.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,19 @@ describe('\'isEqual\'', function () {
4747
});
4848

4949
it('must sort values of attributes as JSON when the content is not a function', function () {
50-
var htmlDiffer = new HtmlDiffer({ compareAttributesAsJSON: [ 'a', { name: 'b', isFunction: false }] }),
50+
var htmlDiffer = new HtmlDiffer({ compareAttributesAsJSON: ['a', { name: 'b', isFunction: false }] }),
5151
files = readFiles('sort-values-in-json-format');
5252

5353
htmlDiffer.isEqual(files.html1, files.html2).must.be.true();
5454
});
5555

56+
it('must handle invalid JSON', function () {
57+
var htmlDiffer = new HtmlDiffer({ compareAttributesAsJSON: ['data-bem'] }),
58+
files = readFiles('invalid-json');
59+
60+
htmlDiffer.isEqual(files.html1, files.html2).must.be.true();
61+
});
62+
5663
it('must sort values of attributes as JSON when the content is a function', function () {
5764
var options = {
5865
compareAttributesAsJSON: [
@@ -66,6 +73,14 @@ describe('\'isEqual\'', function () {
6673
htmlDiffer.isEqual(files.html1, files.html2).must.be.true();
6774
});
6875

76+
it('must handle invalid function', function () {
77+
var options = { compareAttributesAsJSON: [{ name: 'onclick', isFunction: true }] },
78+
htmlDiffer = new HtmlDiffer(options),
79+
files = readFiles('invalid-function');
80+
81+
htmlDiffer.isEqual(files.html1, files.html2).must.be.true();
82+
});
83+
6984
it('must work option \'ignoreAttributes\'', function () {
7085
var htmlDiffer = new HtmlDiffer({ ignoreAttributes: ['id', 'for'] }),
7186
files = readFiles('ignore-attributes');

0 commit comments

Comments
 (0)