Skip to content

Commit a66118e

Browse files
committed
Add supporting of masks
1 parent a7d7411 commit a66118e

2 files changed

Lines changed: 94 additions & 4 deletions

File tree

lib/index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
var _ = require('lodash'),
22
HtmlDiff = require('./HtmlDiff'),
33
modifyHtmlAccordingToOptions = require('./utils/modify'),
4-
defaults = require('./utils/defaults');
4+
defaults = require('./utils/defaults'),
5+
handleMasks = require('./utils/mask');
56

67
/**
78
* Tokenizes the given HTML
@@ -11,7 +12,7 @@ var _ = require('lodash'),
1112
HtmlDiff.prototype.tokenize = function (html) {
1213
html = modifyHtmlAccordingToOptions(html, this.options);
1314

14-
return _.filter(html.split(/([{}:;,<>"'\[\]\/]|\s+)/));
15+
return _.filter(html.split(/({{.+?[^\\]}}(?!})|[{}=:;,<>"'\[\]\/]|\s+)/));
1516
};
1617

1718
/**
@@ -40,9 +41,10 @@ var HtmlDiffer = function (options) {
4041
* @returns {Diff}
4142
*/
4243
HtmlDiffer.prototype.diffHtml = function (html1, html2) {
43-
var htmlDiffer = new HtmlDiff(this.options);
44+
var htmlDiffer = new HtmlDiff(this.options),
45+
diff = htmlDiffer.diff(html1, html2);
4446

45-
return htmlDiffer.diff(html1, html2);
47+
return handleMasks(diff);
4648
};
4749

4850
/**

lib/utils/mask.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* Mask
3+
* ====
4+
*
5+
* {{RegExp}}
6+
*/
7+
var MASK_REGEXP = /(.*){{(.+[^\\])}}(?!})(.*)/;
8+
9+
/**
10+
* Checks whether the given part of the diff should be added or removed
11+
* @param {Diff} part
12+
* @returns {Boolean}
13+
*/
14+
function _isDiffPart(part) {
15+
return part.added || part.removed;
16+
}
17+
18+
/**
19+
* Removes diff parts which are equal by mask
20+
* @param {Diff[]} diff
21+
* @returns {Diff[]}
22+
*/
23+
function _revealMasks(diff) {
24+
for (var i = 0; i < diff.length; i++) {
25+
var currPart = diff[i];
26+
27+
if (!_isDiffPart(currPart)) continue;
28+
29+
var prevPart = diff[i - 1],
30+
nextPart = diff[i + 1],
31+
matchedMask = currPart.value.match(MASK_REGEXP);
32+
33+
if (!matchedMask) continue;
34+
35+
var regExp = new RegExp('^' + matchedMask[1] + matchedMask[2] + matchedMask[3] + '$');
36+
if (currPart.added && nextPart && nextPart.removed) {
37+
if (nextPart.value.match(regExp)) {
38+
nextPart.removed = undefined;
39+
diff.splice(i--, 1);
40+
}
41+
} else if (currPart.removed && prevPart && prevPart.added) {
42+
if (prevPart.value.match(regExp)) {
43+
prevPart.added = undefined;
44+
diff.splice(i--, 1);
45+
}
46+
}
47+
}
48+
49+
return diff;
50+
}
51+
52+
/**
53+
* Concats not diff parts which go one by one
54+
* @param {Diff[]} diff
55+
* @returns {Diff[]}
56+
*/
57+
function _concatNotDiffParts(diff) {
58+
for (var i = 1; i < diff.length; i++) {
59+
var currPart = diff[i],
60+
prevPart = diff[i - 1];
61+
62+
if (!_isDiffPart(currPart) && !_isDiffPart(prevPart)) {
63+
prevPart.value += currPart.value;
64+
65+
diff.splice(i--, 1);
66+
}
67+
}
68+
69+
return diff;
70+
}
71+
72+
/**
73+
* @typedef {Object} Diff
74+
* @property {String} value
75+
* @property {String|undefined} added
76+
* @property {String|undefined} removed
77+
*/
78+
79+
/**
80+
* Handles masks in the given diff
81+
* @param {Diff[]} diff
82+
* @returns {Diff[]}
83+
*/
84+
module.exports = function (diff) {
85+
diff = _revealMasks(diff);
86+
87+
return _concatNotDiffParts(diff);
88+
};

0 commit comments

Comments
 (0)