@matrixreq/htmldiff 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/js/htmldiff.js CHANGED
@@ -332,9 +332,12 @@
332
332
  return '<' + (tagName[1].toLowerCase()) + '>';
333
333
  }
334
334
 
335
- // Otherwise, the token is text, collapse the whitespace.
335
+ // Otherwise, the token is text, collapse the whitespace
336
+ // (except new lines, see https://matrixreq.atlassian.net/browse/MATRIX-7880)
337
+ // potentially, this also causing the problems with prettified HTML (with "\n" between the tags),
338
+ // so it's required to "flatten" html before passing it to the diffing function
336
339
  if (token) {
337
- return token.replace(/(\s+|&nbsp;|&#160;)/g, ' ');
340
+ return token.replace(/([^\S\r\n]+|&nbsp;|&#160;)/g, ' ');
338
341
  }
339
342
  return token;
340
343
  }
@@ -907,7 +910,15 @@
907
910
  var val = tokens.map(function(token){
908
911
  return token.string;
909
912
  });
910
- return wrap('ins', val, opIndex, dataPrefix, className);
913
+
914
+ const res = wrap('ins', val, opIndex, dataPrefix, className);
915
+
916
+ // handling inserted tags, see https://matrixreq.atlassian.net/browse/MATRIX-7876
917
+ if (/^<[^.\/]+?>$/.exec(res)) {
918
+ return `${res.slice(0, res.length - 1)} data-inserted="true">`;
919
+ }
920
+
921
+ return res;
911
922
  },
912
923
  'delete': function(op, beforeTokens, afterTokens, opIndex, dataPrefix, className){
913
924
  var tokens = beforeTokens.slice(op.startInBefore, op.endInBefore + 1);
@@ -916,7 +927,7 @@
916
927
  });
917
928
  const res = wrap("del", val, opIndex, dataPrefix, className);
918
929
 
919
- // handling cases like deleted </p><p>
930
+ // handling cases like deleted </p><p>, see https://matrixreq.atlassian.net/browse/MATRIX-7688
920
931
  if (/^<\/.+?><.+?>$/.exec(res) && !res.includes("del")) {
921
932
  return `<del>${val.slice(1, val.length - 1).join("")}</del>`;
922
933
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@matrixreq/htmldiff",
3
3
  "description": "Diff and markup HTML with <ins> and <del> tags",
4
4
  "companyname": "Matrix Requirements",
5
- "version": "1.0.0",
5
+ "version": "1.2.0",
6
6
  "keywords": [
7
7
  "diff",
8
8
  "html",
package/test/diff.spec.js CHANGED
@@ -29,9 +29,9 @@ describe('Diff', function(){
29
29
 
30
30
  describe('Whitespace differences', function(){
31
31
  it('should collapse adjacent whitespace', function(){
32
- expect(cut('Much \n\t spaces', 'Much spaces')).to.equal('Much spaces');
32
+ expect(cut('Much \t spaces', 'Much spaces')).to.equal('Much spaces');
33
33
  });
34
-
34
+
35
35
  it('should consider non-breaking spaces as equal', function(){
36
36
  expect(cut('Hello&nbsp;world', 'Hello&#160;world')).to.equal('Hello&#160;world');
37
37
  });
@@ -2,30 +2,40 @@ const diff = require('../js/htmldiff');
2
2
 
3
3
  describe('Edge cases', () => {
4
4
  it('removes deleted closing-opening tag pair', () => {
5
- const before = `
6
- <div>
7
- <p><img src="img1.jpg" /></p>
8
- <p><img src="img2.jpg" /></p>
9
- <p>something</p>
10
- </div>
11
- `;
12
- const after = `
13
- <div>
14
- <p>
15
- <img src="img1.jpg" />
16
- <img src="img2.jpg" />
17
- </p>
18
- <p>something</p>
19
- </div>
20
- `;
21
- const res = `
22
- <div>
23
- <p><img src="img1.jpg" /><del>
24
- </del><img src="img2.jpg" /></p>
25
- <p>something</p>
26
- </div>
27
- `;
5
+ const before = `<div><p><img src="img1.jpg" /></p><p><img src="img2.jpg" /></p><p>something</p></div>`;
6
+ const after = `<div><p><img src="img1.jpg" /><img src="img2.jpg" /></p><p>something</p></div>`;
7
+ const res = `<div><p><img src="img1.jpg" /><del></del><img src="img2.jpg" /></p><p>something</p></div>`;
28
8
 
29
9
  expect(diff(before, after)).to.eql(res);
30
10
  });
31
- });
11
+
12
+ it('preserves new lines', () => {
13
+ const before = `<div>this isain text control Donec ullamcorper tortor quis augue egestas ultricies. Aenean vehicula molestie ex. Praesent id dolor at mauris efficitur ultrices. Vestibulum rutrum sit amet odio quis gravida. Praesent id augue maximus, faucibus tellus in, mattis augue. Pellentesque ullamcorper, ante et vestibulum tempus, libero nisl consequat massa, vel aliquam massa nibh in sapie</div>`;
14
+ const after = `<div>this isain text control Donec ullamcorper tortor quis augue egestas ultricies. Aenean vehicula molestie ex. Praesent id do at mauris efficitur ultrices. Vestibulum rutrum sit amet odio quis gravida. Praesent id augue maximus, faucibus tellus in, mattisugue. Pellentesque ullamcorper, ante et tempus, libero nisl consequat massa, vel aliquam massa nibh
15
+
16
+ jndfoewnf[owe 1123123242
17
+ %^&amp;*()(*&amp;^%$#@#$%^&amp;*()
18
+
19
+ BNXOISAN'FOSER3154
20
+ 65+
21
+ 5SSDC</div>`;
22
+ const res = `<div>this isain text control Donec ullamcorper tortor quis augue egestas ultricies. Aenean vehicula molestie ex. Praesent id <del data-operation-index="1">dolor</del><ins data-operation-index="1">do</ins> at mauris efficitur ultrices. Vestibulum rutrum sit amet odio quis gravida. Praesent id augue maximus, faucibus tellus in, <del data-operation-index="3">mattis augue.</del><ins data-operation-index="3">mattisugue.</ins> Pellentesque ullamcorper, ante et<del data-operation-index="5"> vestibulum</del> tempus, libero nisl consequat massa, vel aliquam massa nibh<del data-operation-index="7"> in sapie</del><ins data-operation-index="7">
23
+
24
+ jndfoewnf[owe 1123123242
25
+ %^&amp;*()(*&amp;^%$#@#$%^&amp;*()
26
+
27
+ BNXOISAN'FOSER3154
28
+ 65+
29
+ 5SSDC</ins></div>`;
30
+
31
+ expect(diff(before, after)).to.eql(res);
32
+ });
33
+
34
+ it('adds data-inserted="true" to inserted tags', () => {
35
+ const before = `<div>some content</div>`;
36
+ const after = `<div><strong>some content</strong></div>`;
37
+ const res = `<div><strong data-inserted="true">some content</strong></div>`;
38
+
39
+ expect(diff(before, after)).to.eql(res);
40
+ });
41
+ });