UNPKG

vue-diff-text

Version:

A simple Vue 3 component to display the difference between two blocks of text.

394 lines (393 loc) 11.2 kB
import { defineComponent as L, computed as $, createElementBlock as p, openBlock as a, Fragment as q, renderList as z, toDisplayString as E, normalizeClass as W } from "vue"; function x() { } x.prototype = { diff: function(e, n) { var r, s = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}, o = s.callback; typeof s == "function" && (o = s, s = {}), this.options = s; var i = this; function f(l) { return o ? (setTimeout(function() { o(void 0, l); }, 0), !0) : l; } e = this.castInput(e), n = this.castInput(n), e = this.removeEmpty(this.tokenize(e)), n = this.removeEmpty(this.tokenize(n)); var u = n.length, c = e.length, m = 1, d = u + c; s.maxEditLength && (d = Math.min(d, s.maxEditLength)); var C = (r = s.timeout) !== null && r !== void 0 ? r : 1 / 0, O = Date.now() + C, v = [{ oldPos: -1, lastComponent: void 0 }], h = this.extractCommon(v[0], n, e, 0); if (v[0].oldPos + 1 >= c && h + 1 >= u) return f([{ value: this.join(n), count: n.length }]); var T = -1 / 0, _ = 1 / 0; function R() { for (var l = Math.max(T, -m); l <= Math.min(_, m); l += 2) { var y = void 0, w = v[l - 1], D = v[l + 1]; w && (v[l - 1] = void 0); var M = !1; if (D) { var B = D.oldPos - l; M = D && 0 <= B && B < u; } var S = w && w.oldPos + 1 < c; if (!M && !S) { v[l] = void 0; continue; } if (!S || M && w.oldPos + 1 < D.oldPos ? y = i.addToPath(D, !0, void 0, 0) : y = i.addToPath(w, void 0, !0, 1), h = i.extractCommon(y, n, e, l), y.oldPos + 1 >= c && h + 1 >= u) return f(H(i, y.lastComponent, n, e, i.useLongestToken)); v[l] = y, y.oldPos + 1 >= c && (_ = Math.min(_, l - 1)), h + 1 >= u && (T = Math.max(T, l + 1)); } m++; } if (o) (function l() { setTimeout(function() { if (m > d || Date.now() > O) return o(); R() || l(); }, 0); })(); else for (; m <= d && Date.now() <= O; ) { var k = R(); if (k) return k; } }, addToPath: function(e, n, r, s) { var o = e.lastComponent; return o && o.added === n && o.removed === r ? { oldPos: e.oldPos + s, lastComponent: { count: o.count + 1, added: n, removed: r, previousComponent: o.previousComponent } } : { oldPos: e.oldPos + s, lastComponent: { count: 1, added: n, removed: r, previousComponent: o } }; }, extractCommon: function(e, n, r, s) { for (var o = n.length, i = r.length, f = e.oldPos, u = f - s, c = 0; u + 1 < o && f + 1 < i && this.equals(n[u + 1], r[f + 1]); ) u++, f++, c++; return c && (e.lastComponent = { count: c, previousComponent: e.lastComponent }), e.oldPos = f, u; }, equals: function(e, n) { return this.options.comparator ? this.options.comparator(e, n) : e === n || this.options.ignoreCase && e.toLowerCase() === n.toLowerCase(); }, removeEmpty: function(e) { for (var n = [], r = 0; r < e.length; r++) e[r] && n.push(e[r]); return n; }, castInput: function(e) { return e; }, tokenize: function(e) { return e.split(""); }, join: function(e) { return e.join(""); } }; function H(t, e, n, r, s) { for (var o = [], i; e; ) o.push(e), i = e.previousComponent, delete e.previousComponent, e = i; o.reverse(); for (var f = 0, u = o.length, c = 0, m = 0; f < u; f++) { var d = o[f]; if (d.removed) { if (d.value = t.join(r.slice(m, m + d.count)), m += d.count, f && o[f - 1].added) { var O = o[f - 1]; o[f - 1] = o[f], o[f] = O; } } else { if (!d.added && s) { var C = n.slice(c, c + d.count); C = C.map(function(h, T) { var _ = r[m + T]; return _.length > h.length ? _ : h; }), d.value = t.join(C); } else d.value = t.join(n.slice(c, c + d.count)); c += d.count, d.added || (m += d.count); } } var v = o[u - 1]; return u > 1 && typeof v.value == "string" && (v.added || v.removed) && t.equals("", v.value) && (o[u - 2].value += v.value, o.pop()), o; } var Q = new x(); function U(t, e, n) { return Q.diff(t, e, n); } function X(t, e) { if (typeof t == "function") e.callback = t; else if (t) for (var n in t) t.hasOwnProperty(n) && (e[n] = t[n]); return e; } var V = /^[A-Za-z\xC0-\u02C6\u02C8-\u02D7\u02DE-\u02FF\u1E00-\u1EFF]+$/, Z = /\S/, F = new x(); F.equals = function(t, e) { return this.options.ignoreCase && (t = t.toLowerCase(), e = e.toLowerCase()), t === e || this.options.ignoreWhitespace && !Z.test(t) && !Z.test(e); }; F.tokenize = function(t) { for (var e = t.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/), n = 0; n < e.length - 1; n++) !e[n + 1] && e[n + 2] && V.test(e[n]) && V.test(e[n + 2]) && (e[n] += e[n + 2], e.splice(n + 1, 2), n--); return e; }; function Y(t, e, n) { return n = X(n, { ignoreWhitespace: !0 }), F.diff(t, e, n); } function j(t, e, n) { return F.diff(t, e, n); } var N = new x(); N.tokenize = function(t) { this.options.stripTrailingCr && (t = t.replace(/\r\n/g, ` `)); var e = [], n = t.split(/(\n|\r\n)/); n[n.length - 1] || n.pop(); for (var r = 0; r < n.length; r++) { var s = n[r]; r % 2 && !this.options.newlineIsToken ? e[e.length - 1] += s : (this.options.ignoreWhitespace && (s = s.trim()), e.push(s)); } return e; }; function P(t, e, n) { return N.diff(t, e, n); } var G = new x(); G.tokenize = function(t) { return t.split(/(\S.+?[.!?])(?=\s+|$)/); }; function K(t, e, n) { return G.diff(t, e, n); } var b = new x(); b.tokenize = function(t) { return t.split(/([{}:;,]|\s+)/); }; function I(t) { "@babel/helpers - typeof"; return typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? I = function(e) { return typeof e; } : I = function(e) { return e && typeof Symbol == "function" && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e; }, I(t); } var ee = Object.prototype.toString, g = new x(); g.useLongestToken = !0; g.tokenize = N.tokenize; g.castInput = function(t) { var e = this.options, n = e.undefinedReplacement, r = e.stringifyReplacer, s = r === void 0 ? function(o, i) { return typeof i > "u" ? n : i; } : r; return typeof t == "string" ? t : JSON.stringify(A(t, null, null, s), s, " "); }; g.equals = function(t, e) { return x.prototype.equals.call(g, t.replace(/,([\r\n])/g, "$1"), e.replace(/,([\r\n])/g, "$1")); }; function A(t, e, n, r, s) { e = e || [], n = n || [], r && (t = r(s, t)); var o; for (o = 0; o < e.length; o += 1) if (e[o] === t) return n[o]; var i; if (ee.call(t) === "[object Array]") { for (e.push(t), i = new Array(t.length), n.push(i), o = 0; o < t.length; o += 1) i[o] = A(t[o], e, n, r, s); return e.pop(), n.pop(), i; } if (t && t.toJSON && (t = t.toJSON()), I(t) === "object" && t !== null) { e.push(t), i = {}, n.push(i); var f = [], u; for (u in t) t.hasOwnProperty(u) && f.push(u); for (f.sort(), o = 0; o < f.length; o += 1) u = f[o], i[u] = A(t[u], e, n, r, u); e.pop(), n.pop(); } else i = t; return i; } var J = new x(); J.tokenize = function(t) { return t.slice(); }; J.join = J.removeEmpty = function(t) { return t; }; const te = { class: "text-diff text-diff-chars" }, ne = ["textContent"], pe = /* @__PURE__ */ L({ __name: "DiffChars", props: { oldText: { type: String, required: !0 }, newText: { type: String, required: !0 }, options: { type: Object, default: () => ({}) } }, setup(t) { const e = t, n = $(() => U(e.oldText, e.newText, e.options)); return (r, s) => (a(), p("div", te, [ (a(!0), p(q, null, z(n.value, (o, i) => (a(), p("span", { key: i, class: W({ "diff-added": o.added, "diff-removed": o.removed }), textContent: E(o.value) }, null, 10, ne))), 128)) ])); } }), oe = { class: "text-diff text-diff-words" }, re = ["textContent"], ae = /* @__PURE__ */ L({ __name: "DiffWords", props: { oldText: { type: String, required: !0 }, newText: { type: String, required: !0 }, options: { type: Object, default: () => ({}) } }, setup(t) { const e = t, n = $(() => Y(e.oldText, e.newText, e.options)); return (r, s) => (a(), p("div", oe, [ (a(!0), p(q, null, z(n.value, (o, i) => (a(), p("span", { key: i, class: W({ "diff-added": o.added, "diff-removed": o.removed }), textContent: E(o.value) }, null, 10, re))), 128)) ])); } }), ie = { class: "text-diff text-diff-words-with-space" }, se = ["textContent"], ve = /* @__PURE__ */ L({ __name: "DiffWordsWithSpace", props: { oldText: { type: String, required: !0 }, newText: { type: String, required: !0 }, options: { type: Object, default: () => ({}) } }, setup(t) { const e = t, n = $(() => j(e.oldText, e.newText, e.options)); return (r, s) => (a(), p("div", ie, [ (a(!0), p(q, null, z(n.value, (o, i) => (a(), p("span", { key: i, class: W({ "diff-added": o.added, "diff-removed": o.removed }), textContent: E(o.value) }, null, 10, se))), 128)) ])); } }), fe = { class: "text-diff text-diff-lines" }, ue = ["textContent"], me = /* @__PURE__ */ L({ __name: "DiffLines", props: { oldText: { type: String, required: !0 }, newText: { type: String, required: !0 }, options: { type: Object, default: () => ({}) } }, setup(t) { const e = t, n = $(() => P(e.oldText, e.newText, e.options)); return (r, s) => (a(), p("div", fe, [ (a(!0), p(q, null, z(n.value, (o, i) => (a(), p("span", { key: i, class: W({ "diff-added": o.added, "diff-removed": o.removed }), textContent: E(o.value) }, null, 10, ue))), 128)) ])); } }), de = { class: "text-diff text-diff-sentences" }, le = ["textContent"], xe = /* @__PURE__ */ L({ __name: "DiffSentences", props: { oldText: { type: String, required: !0 }, newText: { type: String, required: !0 }, options: { type: Object, default: () => ({}) } }, setup(t) { const e = t, n = $(() => K(e.oldText, e.newText, e.options)); return (r, s) => (a(), p("div", de, [ (a(!0), p(q, null, z(n.value, (o, i) => (a(), p("span", { key: i, class: W({ "diff-added": o.added, "diff-removed": o.removed }), textContent: E(o.value) }, null, 10, le))), 128)) ])); } }); export { pe as DiffChars, me as DiffLines, xe as DiffSentences, ae as DiffWords, ve as DiffWordsWithSpace, ve as TextDiff };