UNPKG

edix

Version:

An experimental, type-safe, framework agnostic and small (5kB+) contenteditable state manager.

793 lines (781 loc) 28.5 kB
const t = Math.min, {keys: e, is: n} = Object, r = t => "string" == typeof t, o = t => "function" == typeof t, s = o(queueMicrotask) ? queueMicrotask : t => { Promise.resolve().then(t); }, i = (e, n) => { const r = t(e.length, n.length); for (let t = 0; t < r; t++) { const r = e[t], o = n[t]; if (r < o) return -1; if (r > o) return 1; } return 0; }, c = ([t, e], [n, r]) => { const o = i(t, n); return 0 === o ? e === r ? 0 : e < r ? -1 : 1 : o; }, l = ([t, e]) => 1 === c(t, e) ? [ e, t ] : [ t, e ], u = (t, e = t => m(t) ? t.text : "") => t.children.reduce((t, n, r) => { const o = k(n); return 0 !== r && o && (t += "\n"), t + (o ? n.children.reduce((t, n) => t + e(n), "") : ""); }, ""), f = (t, e, n) => t.split("\n").map(t => ({ ...n, children: [ { ...e, text: t } ] })), a = "delete", d = "insert_text", h = "insert_node", p = "set_attr", x = "set_node_attr", y = ({type: t}) => t === h || t === p || t === x; class g { t; constructor(t) { this.t = t ? t.slice() : []; } get ops() { return this.t; } insertText(t, e) { return this.t.push({ type: d, at: t, text: e }), this; } insertFragment(t, e) { return this.t.push({ type: h, at: t, fragment: e }), this; } delete(t, e) { return this.t.push({ type: a, start: t, end: e }), this; } format(t, e, n, r) { return this.t.push({ type: p, start: t, end: e, key: n, value: r }), this; } attr(t, e, n) { return this.t.push({ type: x, path: t, key: e, value: n }), this; } transform(t) { return this.t.reduce((t, e) => B(t, e), t); } } const m = t => "text" in t, k = t => "children" in t, w = (t, r) => { const o = e(t); return o.length === e(r).length && o.every(e => e in r && ("text" === e || n(t[e], r[e]))); }, b = t => k(t) ? t.children.reduce((t, e) => t + b(e), 0) : m(t) ? t.text.length : 1, _ = (t, e = 0, n = t.length - 1) => { let r = e + 1; for (;r <= n; ) { const e = t[r - 1], o = t[r]; m(e) && m(o) && w(e, o) ? (t[r - 1] = { ...e, text: e.text + o.text }, t.splice(r, 1), n--) : r++; } for (r = e; r <= n; ) { const e = t[r]; m(e) && !e.text && t.length > 1 ? (t.splice(r, 1), n--) : r++; } }, v = (t, e = 0, n = t.length - 1) => { let r = e + 1; for (;r <= n; ) { const e = t[r - 1], o = t[r]; t[r - 1] = E(e, o), t.splice(r, 1), n--; } }, D = (t, e, n) => { if (e.length) { const r = t.length; t.push(...e), r && n(t, r - 1, r); } }, E = (...t) => ({ ...t[0], children: t.reduce((t, e) => (D(t, e.children, _), t), []) }), M = ({children: t}, e) => { for (let n = 0; n < t.length; n++) { const r = t[n], o = b(r); if (o > e) return { o: r, i: n, l: e }; e -= o; } return null; }, O = (t, e, n = 0) => { const r = t.children, o = e[0]; if (n < o.length) { const s = o[n], [i, c] = O(r[s], e, n + 1), l = r.slice(0, s), u = r.slice(s + 1); return l.push(i), u.unshift(c), [ { ...t, children: l }, { ...t, children: u } ]; } { const n = M(t, e[1]); if (n) { const {o: e, l: o, i: s} = n, i = r.slice(0, s), c = r.slice(s + 1); if (m(e)) { const t = e.text.slice(0, o), n = e.text.slice(o); !t && i.length || i.push({ ...e, text: t }), !n && c.length || c.unshift({ ...e, text: n }); } else c.unshift(e); return [ { ...t, children: i }, { ...t, children: c } ]; } return [ t, { ...t, children: [] } ]; } }, S = t => t.length ? t[0] : 0, C = (t, e) => { for (let n = 0; n < e.length; n++) t = t.children[e[n]]; return t; }, I = (t, e, n, r) => [ [ S(t[0]) + e ], t[1] + (r ? n : 0) ], A = (t, e, n, r = 0) => { if (r < e.length) { const o = e[r]; return ((t, e, n, r) => { const o = t.children.slice(); return o.splice(e, n - e + 1, ...r), { ...t, children: o }; })(t, o, o, [ A(t.children[o], e, n, r + 1) ]); } return n; }, H = (t, e, n, r) => { const [o, s] = O(t, e), i = -1 === c(e, n) ? O(t, n)[1] : s, l = o.children.slice(); return D(l, r, v), D(l, i.children, v), { ...t, children: l }; }, P = (t, e, n) => -1 !== c(e, n) ? [] : O(O(t, n)[0], e)[1].children, R = (t, [e, n]) => { const r = C(t, e); return !!(r && n >= 0 && n <= b(r)); }, B = (t, e) => { switch (e.type) { case a: { const {start: n, end: r} = e; if (-1 !== c(t, n)) return -1 !== c(r, t) ? n : I(t, S(n[0]) - S(r[0]), n[1] - r[1], 0 === i(r[0], t[0])); break; } case d: case h: { const n = e.at; if (-1 !== c(t, n)) { const r = e.type === d ? f(e.text) : e.fragment, o = r.length, s = o - 1; return I(t, s, b(r[o - 1]) - (0 === s ? 0 : n[1]), 0 === i(n[0], t[0])); } break; } } return t; }, F = (t, e) => [ B(t[0], e), B(t[1], e) ], T = (t, e, n) => { switch (n.type) { case a: { const {start: r, end: o} = n; R(t, r) && R(t, o) && -1 === c(r, o) && (t = H(t, r, o, []), e = F(e, n)); break; } case d: { const {at: r, text: o} = n; if (R(t, r) && o) { const s = C(t, r[0]), i = M(s, r[1] - 1); let c; if (i) { const t = i.o; m(t) && (c = t); } t = H(t, r, r, f(o, c, s)), e = F(e, n); } break; } case h: { const {at: r, fragment: o} = n; R(t, r) && o.length && (t = H(t, r, r, o), e = F(e, n)); break; } case p: { const {start: e, end: r, key: o, value: s} = n; R(t, e) && R(t, r) && -1 === c(e, r) && (t = H(t, e, r, P(t, e, r).map(t => ({ ...t, children: t.children.map(t => m(t) ? { ...t, [o]: s } : t) })))); break; } case x: { const {path: e, key: r, value: o} = n, s = C(t, e); s && (t = A(t, e, { ...s, [r]: o })); break; } } return [ t, e ]; }; let V = null, L = null, N = null, q = null, z = null; const J = t => 1 === t.nodeType, U = t => 8 === t.nodeType, G = () => L, j = () => { const t = W(); return 1 === t ? L.data.length : 2 === t ? 1 : 0; }, W = () => { if (null != N) return N; if (L) if ((t => 3 === t.nodeType)(L)) { const t = L.data; if (t) return N = "\n" === t ? Q() ? 3 : 6 : 1; } else if (J(L)) { if ("BR" === L.tagName) return N = Q() ? 3 : 5; if (q.u(L)) return N = 2; if (q.h(L)) return N = 4; } return N = 0; }, X = () => (N = null, L = V.nextNode()), Y = () => { for (;(N = null) || (L = V.nextSibling()); ) if (4 === W()) return; }, K = () => { for (;(N = null) || (L = V.parentNode()); ) if (4 === W()) return; }, Q = () => { const t = L.parentNode; return z(() => { for (;X(); ) { if (W()) return !0; if (!t.contains(L)) break; } return !1; }); }, Z = () => { for (;;) { if (2 === W()) { const t = L; for (;X() && t.contains(L); ) ; } else X(); if (!L) break; const t = W(); if (t) return t; } }, $ = new Set([ "DIV", "H1", "H2", "H3", "H4", "H5", "H6", "P", "PRE", "LI", "DT", "DD", "TR" ]), tt = t => $.has(t.tagName), et = new Set([ "EMBED", "IMG", "PICTURE", "AUDIO", "VIDEO", "SVG", "CANVAS", "MATH", "IFRAME", "OBJECT" ]), nt = t => "false" === t.contentEditable || et.has(t.tagName), rt = (t, e) => t.compareDocumentPosition(e), ot = t => t.ownerDocument, st = t => ot(t).getSelection(), it = (t, e) => { if (t.rangeCount) { const n = t.getRangeAt(0); if (e.contains(n.commonAncestorContainer)) return n; } }, ct = (t, e, n, r) => { const o = st(t); (n || it(o, t)) && (o.removeAllRanges(), o.addRange(e), r && (o.collapseToEnd(), o.extend(e.startContainer, e.startOffset))); }, lt = (t, e, [n, r], o, s) => { const i = c(n, r), l = 0 === i, u = 1 === i, f = u ? r : n, a = u ? n : r; if (0 === f[0].length && 0 === f[1] && l && !e.hasChildNodes()) { const n = t.createRange(); return n.setStart(e, 0), n.setEnd(e, 0), ct(e, n, s); } const d = ut(e, f, o); if (!d) return; const h = l ? d : ut(e, a, o); if (!h) return; const p = t.createRange(), [x, y] = d, [g, m] = h; J(x) ? y < 1 ? p.setStartBefore(x) : p.setStartAfter(x) : p.setStart(x, y), J(g) ? m < 1 ? p.setEndBefore(g) : p.setEndAfter(g) : p.setEnd(g, m), ct(e, p, s, u); }, ut = (t, [e, n], r) => r(() => { let t, r = 0; for (;t = Z(); ) if (4 === t) { if (r < e.length) for (let t = e[r++]; t > 0; t--) Y(); } else { const t = j(); if (n <= t) return [ G(), n ]; n -= t; } }, t), ft = (e, n, r, o) => { let s = !0; if (e === n && !n.hasChildNodes()) return [ [ 0 ], 0 ]; if (J(n) && n.hasChildNodes()) { const e = t(r, n.childNodes.length - 1); n = n.childNodes[e], s = e === r, r = 0; } return o(() => { 4 !== W() && K(); const t = o(() => { const t = []; let n; for (;(n = G()) && n !== e; ) t.unshift(n), K(); if (!t.length) return [ 0 ]; let r = 0, o = t[t.length - 1]; for (;o = o.previousElementSibling; ) r++; return [ r ]; }); let i = 0; for (;Z(); ) { const t = rt(n, G()); if (0 === t || 16 & t) { if (s) break; } else if (4 & t) break; i += j(); } return [ t, i + r ]; }, e, n); }, at = (t, e, {startOffset: n, startContainer: r, endOffset: o, endContainer: s}) => { const i = ft(t, r, n, e); return [ i, r === s && n === o ? i : ft(t, s, o, e) ]; }, dt = t => (e, n) => { e.setData("text/plain", u({ children: n }, t)); }, ht = "application/x-edix-editor", pt = (t, e, {mod: n, shift: r = !1, alt: o = !1} = {}) => (t = t.toLowerCase(), s => { if (s.key.toLowerCase() === t && (!n || s.ctrlKey || s.metaKey) && r === s.shiftKey && o === s.altKey) return e(s), !0; }), xt = [], yt = () => {}, gt = ({doc: t, readonly: e = !1, schema: i, keyboard: u, copy: f = [ dt() ], paste: a = [ t => t.getData("text/plain") ], isBlock: d = tt, onChange: h, onError: p = console.error}) => { let x = [ [ [ 0 ], 0 ], [ [ 0 ], 0 ] ]; const m = (t, e) => { if (!i) return e("An unsafe operation was detected. We recommend using schema option."), !0; const n = i["~standard"].validate(t); if (n instanceof Promise) e("async validate is not supported."); else { if (!n.issues) return !0; e(n.issues.map(t => t.message).join("\n")); } return !1; }; let k; if (!m(t, t => { k = t; }) && k) throw Error(k); const w = new Map, b = t => w.get(t) || xt, _ = new Map, v = t => { const e = _.get(t); e && !e[1] && (e[1] = !0, s(() => { e[1] = !1, e[0].forEach(t => { t(); }); })); }, D = r => { if (!e) { const e = t, o = b("apply"), s = o.length; for (let e of r.ops) { let n = 0; const r = () => { if (n < s) { const t = n; o[n](e, i), t === n && i(); } else if (n === s) { n++; try { const [n, r] = T(t, x, e); y(e) && !m(n, p) || (t = n, x = r); } catch (t) { p("rollback operation: " + t); } } }, i = t => { t && (e = t), n++, r(); }; r(); } n(e, t) || v("change"); } }, E = e => { ((t, [e, n]) => R(t, e) && R(t, n))(t, e) && (c(x[0], e[0]) || c(x[1], e[1])) && (x = e, v("selectionchange")); }, M = { get doc() { return t; }, get selection() { return x; }, get readonly() { return e; }, set readonly(t) { e = t, v("readonly"); }, apply: (t, ...e) => (o(t) ? t.call(M, ...e) : D(t), M), on: (t, e) => { let n = _.get(t); n || _.set(t, n = [ new Set, !1 ]); const r = n[0]; return r.add(e), () => { r.delete(e); }; }, hook: (t, e) => { let n = w.get(t); return n || w.set(t, n = []), n.push(e), () => { const t = n.indexOf(e); -1 !== t && n.splice(t, 1); }; }, use: (t, ...e) => (t.call(M, ...e), M), input: n => { if (!window.InputEvent || !o(InputEvent.prototype.getTargetRanges)) return p("beforeinput event is not supported."), yt; const {contentEditable: s, role: i, ariaMultiLine: u, ariaReadOnly: h} = n, y = n.style.whiteSpace; n.role = "textbox", n.style.whiteSpace = "pre-wrap", n.ariaMultiLine = "true"; let m = !1, k = null, w = !1, _ = !1, v = !1; const O = ot(n), S = (t => { const e = (n, r, o) => { const s = q, i = z, c = V, l = L, u = N; try { return V || (q = t, z = e, V = q.p.createTreeWalker(r, 5)), o && (V.currentNode = L = o), n(); } finally { q = s, z = i, V = c, L = l, N = u, V && l && (V.currentNode = l); } }; return e; })({ p: O, h: d, u: nt }), C = () => { n.contentEditable = e ? "false" : "true", n.ariaReadOnly = e ? "true" : null; }; C(); const I = M.on("change", () => { _ || requestAnimationFrame(() => { _ || n.focus({ preventScroll: !0 }); }); }), A = M.on("readonly", C), H = t => { for (const e of a) { const n = e(t, S); if (n) return n; } p("failed to serialize pasted data"); }, R = ((t, e) => { let n = !1; const r = [], o = t => { n && r.push(...t); }, s = new MutationObserver(t => { o(t), n || e(); }), i = () => { o(s.takeRecords()); }, c = () => (i(), r.splice(0)); return s.observe(t, { characterData: !0, characterDataOldValue: !0, childList: !0, subtree: !0 }), { m: t => { let e; for (;e = t.pop(); ) if ("childList" === e.type) { const {target: t, removedNodes: n, addedNodes: r, nextSibling: o} = e; for (let e = n.length - 1; e >= 0; e--) t.insertBefore(n[e], o); for (let e = r.length - 1; e >= 0; e--) t.removeChild(r[e]); } else e.target.data = e.oldValue; c(); }, k: t => { !n && t && i(), n = t; }, _: c, v: () => { r.splice(0), s.disconnect(); } }; })(n, () => { lt(O, n, x, S); }), B = () => { E(((t, e) => { const n = st(t), r = it(n, t); if (!r) return [ [ [ 0 ], 0 ], [ [ 0 ], 0 ] ]; const o = at(t, e, r), s = rt(n.anchorNode, n.focusNode); return (0 === s ? n.anchorOffset > n.focusOffset : 2 & s) ? [ o[1], o[0] ] : o; })(n, S)); }, F = () => { const t = R._(); R.k(!1), t.length && (R.m(t), O.removeEventListener("selectionchange", Y), lt(O, n, x, S, !0), O.addEventListener("selectionchange", Y)), k && (E(k[1]), D(k[0]), k = null), w = !1; }, T = t => { if (!w) for (const e of b("keyboard")) if (e(t)) return t.preventDefault(), void R.k(!1); }, J = () => { w || F(); }, U = t => { t.preventDefault(); const e = t.inputType; if (e.startsWith("format")) return; if ("historyUndo" === e || "historyRedo" === e) return; w ? R.k(!0) : B(); const r = t.getTargetRanges()[0]; if (r) { const o = at(n, S, r); let s, i = "insertParagraph" === e || "insertLineBreak" === e ? "\n" : t.data; if (null == i) { const e = t.dataTransfer; e && (i = e.getData("text/plain")); } k || (k = [ new g, x ]), s = k[0], 0 !== c(...o) && s.delete(...o), i && s.insertText(o[0], i); } w || F(); }, G = () => { w || B(), w = !0; }, j = () => { F(); }, W = () => { _ = !0, B(); }, X = () => { _ = !1; }, Y = () => { !_ || w || v || B(); }, K = e => { if (B(), 0 !== c(...x)) { const r = P(t, ...l(x)); for (const t of f) t(e, r, n); } }, Q = t => { t.preventDefault(), K(t.clipboardData); }, Z = t => { t.preventDefault(), e || (K(t.clipboardData), D((new g).delete(...l(x)))); }, $ = t => { t.preventDefault(); const e = H(t.clipboardData); if (e) { const [t, n] = l(x), o = (new g).delete(t, n); r(e) ? o.insertText(t, e) : o.insertFragment(t, e), D(o); } }, tt = t => { t.preventDefault(); const e = t.dataTransfer, o = ((t, e, {clientX: n, clientY: r}, o) => { if (t.caretPositionFromPoint) { const s = t.caretPositionFromPoint(n, r); if (s) return ft(e, s.offsetNode, s.offset, o); } else if (t.caretRangeFromPoint) { const s = t.caretRangeFromPoint(n, r); if (s) return ft(e, s.startContainer, s.startOffset, o); } })(O, n, t, S); if (e && o) { let t; const n = new g; v && n.delete(...l(x)); const s = H(e); if (s) { const e = n.transform(o); r(s) ? n.insertText(e, s) : n.insertFragment(e, s), t = [ e, n.transform(o) ]; } D(n), t && E(t); } }, et = t => { v = !0, K(t.dataTransfer); }, ct = () => { v = !1; }; O.addEventListener("selectionchange", Y), n.addEventListener("keydown", T), n.addEventListener("input", J), n.addEventListener("beforeinput", U), n.addEventListener("compositionstart", G), n.addEventListener("compositionend", j), n.addEventListener("focus", W), n.addEventListener("blur", X), n.addEventListener("copy", Q), n.addEventListener("cut", Z), n.addEventListener("paste", $), n.addEventListener("drop", tt), n.addEventListener("dragstart", et), n.addEventListener("dragend", ct); const ut = b("mount"), dt = []; return ut.forEach(t => { const e = t(n); e && dt.push(e); }), () => { m || (m = !0, I(), A(), n.contentEditable = s, n.role = i, n.ariaMultiLine = u, n.ariaReadOnly = h, n.style.whiteSpace = y, R.v(), O.removeEventListener("selectionchange", Y), n.removeEventListener("keydown", T), n.removeEventListener("input", J), n.removeEventListener("beforeinput", U), n.removeEventListener("compositionstart", G), n.removeEventListener("compositionend", j), n.removeEventListener("focus", W), n.removeEventListener("blur", X), n.removeEventListener("copy", Q), n.removeEventListener("cut", Z), n.removeEventListener("paste", $), n.removeEventListener("drop", tt), n.removeEventListener("dragstart", et), n.removeEventListener("dragend", ct), dt.forEach(t => { t(); })); }; } }, O = (t => { let e = 0, r = 0; const o = Date.now, s = [ [ t.doc, t.selection, [] ] ], i = () => s[e]; return t.hook("apply", (i, c) => { const l = t.doc, u = t.selection; c(i); const f = t.doc; if (!n(l, f)) { const t = o(); if (0 === e || t - r >= 500) { e++; const t = [ l, u, [] ]; e >= s.length ? s.push(t) : s[e] = t; } r = t, s[e][0] = f, s[e][2].push(i), s.splice(e + 1), e > 500 && (e--, s.shift()); } }), { undo: () => { if (e > 0) { const t = i()[1]; return e--, [ i()[0], t ]; } }, redo: () => { if (e < s.length - 1) { e++; const t = i()[0], n = i()[1]; return [ t, i()[2].reduce((t, e) => F(t, e), n) ]; } } }; })(M); return M.on("change", () => { h(t); }), M.hook("keyboard", pt("z", () => { if (!e) { const e = O.undo(); e && (t = e[0], E(e[1]), v("change")); } }, { mod: !0 })), M.hook("keyboard", pt("z", () => { if (!e) { const e = O.redo(); e && (t = e[0], E(e[1]), v("change")); } }, { mod: !0, shift: !0 })), u && u.forEach(t => { M.hook("keyboard", t); }), M; }; function mt() { this.hook("mount", t => { t.ariaMultiLine = null; }), this.hook("apply", (t, e) => { "insert_text" === t.type ? t = { ...t, text: t.text.replaceAll("\n", "") } : "insert_node" === t.type && (t = { ...t, fragment: [ E(...t.fragment) ] }), e(t); }); } exports.Delete = function(t = l(this.selection)) { this.apply((new g).delete(...t)); }, exports.Format = function(t, e, n = l(this.selection)) { this.apply((new g).format(...n, t, e)); }, exports.InsertNode = function(t, e = this.selection[0]) { this.apply((new g).insertFragment(e, [ { children: [ t ] } ])); }, exports.InsertText = function(t, e = this.selection[0]) { this.apply((new g).insertText(e, t)); }, exports.ReplaceAll = function(t) { const e = this.doc; this.apply((new g).delete([ [], 0 ], [ [ e.children.length - 1 ], b(e.children[e.children.length - 1]) ]).insertText([ [], 0 ], t)); }, exports.ReplaceText = function(t) { const [e, n] = l(this.selection); this.apply((new g).delete(e, n).insertText(e, t)); }, exports.SetBlockAttr = function(t, e, n = this.selection[0][0]) { this.apply((new g).attr(n, t, e)); }, exports.ToggleBlockAttr = function(t, e, n, r = this.selection[0][0]) { const o = C(this.doc, r); this.apply((new g).attr(r, t, o[t] === e ? n : e)); }, exports.ToggleFormat = function(t, e = l(this.selection)) { const n = P(this.doc, ...e).flatMap(t => t.children.filter(m)); n.length && this.apply((new g).format(...e, t, !!n.some(e => !e[t]))); }, exports.Transaction = g, exports.createEditor = gt, exports.createPlainEditor = ({text: t, singleline: e, onChange: n, ...r}) => { const o = gt({ ...r, doc: { children: f(t) }, onChange: t => { n(u(t)); } }); return e && o.use(mt), o; }, exports.debugPlugin = function() { const t = this; t.hook("apply", t => { console.log("apply", t); }), t.on("change", () => { console.log("change", t.doc); }), t.on("selectionchange", () => { console.log("selectionchange", t.selection); }); }, exports.filePaste = t => e => { for (const n of e.items) if ("file" === n.kind) { const e = t[n.type]; if (e) { const t = n.getAsFile(); if (t) return [ { children: [ e(t) ] } ]; } } return null; }, exports.hotkey = pt, exports.htmlCopy = () => (t, e, n) => { const r = document.createElement("div"); r.appendChild(it(st(n), n).cloneContents()), t.setData("text/html", r.innerHTML); }, exports.htmlPaste = (t, e = []) => (n, r) => { const o = n.getData("text/html"); if (o) { let n = (new DOMParser).parseFromString(o, "text/html").body, s = !1; for (const t of [ ...n.childNodes ]) U(t) ? "StartFragment" === t.data ? (s = !0, n = new DocumentFragment) : "EndFragment" === t.data && (s = !1) : s && n.appendChild(t); return ((t, e, n, r) => e(() => { let t, e = null, o = "", s = !1; const i = [], c = () => { o && (e || (e = []), e.push(n(o)), o = ""); }, l = () => { c(), !e && s && (e = []), e && i.push({ children: e }), e = null, s = !1; }; for (;t = Z(); ) if (4 === t) l(); else if (s = !0, 1 === t) o += G().data; else if (2 === t) { c(); const t = r(G()); t && e.push(t); } else 3 === t && l(); return l(), i.length || i.push({ children: [] }), i; }, t))(n, r, t, t => { for (const n of e) { const e = n(t); if (e) return e; } }); } return null; }, exports.internalCopy = ({key: t = ht} = {}) => (e, n) => { e.setData(t, JSON.stringify(n)); }, exports.internalPaste = ({key: t = ht} = {}) => e => { try { return JSON.parse(e.getData(t)); } catch (t) { return null; } }, exports.plainCopy = dt, exports.plainPaste = () => t => t.getData("text/plain"), exports.singlelinePlugin = mt; //# sourceMappingURL=index.cjs.map