/* * Javascript Diff Algorithm * By John Resig (http://ejohn.org/) * Modified by Chu Alan "sprite" * * Released under the MIT license. * * More Info: * http://ejohn.org/projects/javascript-diff-algorithm/ * * Usage: QUnit.diff(expected, actual) * * QUnit.diff( "the quick brown fox jumped over", "the quick fox jumps over" ) == "the quick brown fox jumped jumps over" */ const htmlDiff: (v1: string, v2: string) => string = (() => { // eslint-disable-next-line @typescript-eslint/unbound-method const hasOwn = Object.prototype.hasOwnProperty; /* jshint eqeqeq:false, eqnull:true */ const diff = (o, n) => { let i; const ns = {}; const os = {}; for (i = 0; i < n.length; i++) { if (!hasOwn.call(ns, n[i])) { ns[n[i]] = { rows: [], o: null }; } ns[n[i]].rows.push(i); } for (i = 0; i < o.length; i++) { if (!hasOwn.call(os, o[i])) { os[o[i]] = { rows: [], n: null }; } os[o[i]].rows.push(i); } for (i in ns) { if (hasOwn.call(ns, i)) { if (ns[i].rows.length === 1 && hasOwn.call(os, i) && os[i].rows.length === 1) { n[ns[i].rows[0]] = { text: n[ns[i].rows[0]], row: os[i].rows[0] }; o[os[i].rows[0]] = { text: o[os[i].rows[0]], row: ns[i].rows[0] }; } } } for (i = 0; i < n.length - 1; i++) { if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i + 1] === o[n[i].row + 1]) { n[i + 1] = { text: n[i + 1], row: n[i].row + 1 }; o[n[i].row + 1] = { text: o[n[i].row + 1], row: i + 1 }; } } for (i = n.length - 1; i > 0; i--) { if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && n[i - 1] === o[n[i].row - 1]) { n[i - 1] = { text: n[i - 1], row: n[i].row - 1 }; o[n[i].row - 1] = { text: o[n[i].row - 1], row: i - 1 }; } } return { o, n }; }; return (o, n) => { o = o.replace(/\s+$/, ''); n = n.replace(/\s+$/, ''); let i, pre, str = '', oSpace = o.match(/\s+/g), nSpace = n.match(/\s+/g); const out = diff(o === '' ? [] : o.split(/\s+/), n === '' ? [] : n.split(/\s+/)); if (oSpace == null) { oSpace = [ ' ' ]; } else { oSpace.push(' '); } if (nSpace == null) { nSpace = [ ' ' ]; } else { nSpace.push(' '); } if (out.n.length === 0) { for (i = 0; i < out.o.length; i++) { str += '' + out.o[i] + oSpace[i] + ''; } } else { if (out.n[0].text == null) { for (let j = 0; j < out.o.length && out.o[j].text == null; j++) { str += '' + out.o[j] + oSpace[j] + ''; } } for (i = 0; i < out.n.length; i++) { if (out.n[i].text == null) { str += '' + out.n[i] + nSpace[i] + ''; } else { // `pre` initialized at top of scope pre = ''; for (let j = out.n[i].row + 1; j < out.o.length && out.o[j].text == null; j++) { pre += '' + out.o[j] + oSpace[j] + ''; } str += ' ' + out.n[i].text + nSpace[i] + pre; } } } return str; }; })(); export { htmlDiff };