UNPKG

advanced-editor-react

Version:

A modern WYSIWYG rich text editor based on tiptap and shadcn ui for React

1,515 lines (1,514 loc) 195 kB
import Ye from "tippy.js"; import { E as Xe, a as Qe, P as H, b as $, S as G, k as Ze, T as D, D as tn, c as Ee, F as V, N as en, d as xt, w as nn, e as rn, f as sn, g as dt, h as tt, s as on, i as te, j as an, l as ln, m as cn, n as dn, o as un, A as pn, p as hn, q as fn, r as mn, t as gn, u as yn, v as vn, x as bn, y as Te, z as Mn, B as Sn, C as kn, G as wn, H as En, I as Tn, J as Cn, K as zt, R as xn, L as An, M as On, O as Ln, Q as ee, U as _n, V as Ce, W as Pn, X as Rn, Y as Hn, Z as $n, _ as In, $ as pt, a0 as Vt, a1 as Dn, a2 as Nn, a3 as Bn, a4 as xe, a5 as jn, a6 as ne, a7 as Fn, a8 as re, a9 as se, aa as zn, ab as oe, ac as Vn, ad as Wn, ae as Kn, af as Un, ag as qn, ah as Gn, ai as Jn } from "./vendor-Bl3sK4kL.js"; import O, { useRef as Yn, useState as Wt, useDebugValue as Ae, useEffect as Kt, forwardRef as Xn, useLayoutEffect as Qn, useContext as Oe, createContext as Le } from "react"; import Zn, { flushSync as tr } from "react-dom"; function gt(e) { const { state: t, transaction: n } = e; let { selection: r } = n, { doc: s } = n, { storedMarks: o } = n; return { ...t, apply: t.apply.bind(t), applyTransaction: t.applyTransaction.bind(t), plugins: t.plugins, schema: t.schema, reconfigure: t.reconfigure.bind(t), toJSON: t.toJSON.bind(t), get storedMarks() { return o; }, get selection() { return r; }, get doc() { return s; }, get tr() { return r = n.selection, s = n.doc, o = n.storedMarks, n; } }; } class yt { constructor(t) { this.editor = t.editor, this.rawCommands = this.editor.extensionManager.commands, this.customState = t.state; } get hasCustomState() { return !!this.customState; } get state() { return this.customState || this.editor.state; } get commands() { const { rawCommands: t, editor: n, state: r } = this, { view: s } = n, { tr: o } = r, i = this.buildProps(o); return Object.fromEntries(Object.entries(t).map(([a, c]) => [a, (...u) => { const d = c(...u)(i); return !o.getMeta("preventDispatch") && !this.hasCustomState && s.dispatch(o), d; }])); } get chain() { return () => this.createChain(); } get can() { return () => this.createCan(); } createChain(t, n = !0) { const { rawCommands: r, editor: s, state: o } = this, { view: i } = s, a = [], c = !!t, l = t || o.tr, u = () => (!c && n && !l.getMeta("preventDispatch") && !this.hasCustomState && i.dispatch(l), a.every((p) => p === !0)), d = { ...Object.fromEntries(Object.entries(r).map(([p, h]) => [p, (...f) => { const g = this.buildProps(l, n), y = h(...f)(g); return a.push(y), d; }])), run: u }; return d; } createCan(t) { const { rawCommands: n, state: r } = this, s = !1, o = t || r.tr, i = this.buildProps(o, s); return { ...Object.fromEntries(Object.entries(n).map(([c, l]) => [c, (...u) => l(...u)({ ...i, dispatch: void 0 })])), chain: () => this.createChain(o, s) }; } buildProps(t, n = !0) { const { rawCommands: r, editor: s, state: o } = this, { view: i } = s, a = { tr: t, editor: s, view: i, state: gt({ state: o, transaction: t }), dispatch: n ? () => { } : void 0, chain: () => this.createChain(t, n), can: () => this.createCan(t), get commands() { return Object.fromEntries(Object.entries(r).map(([c, l]) => [c, (...u) => l(...u)(a)])); } }; return a; } } class er { constructor() { this.callbacks = {}; } on(t, n) { return this.callbacks[t] || (this.callbacks[t] = []), this.callbacks[t].push(n), this; } emit(t, ...n) { const r = this.callbacks[t]; return r && r.forEach((s) => s.apply(this, n)), this; } off(t, n) { const r = this.callbacks[t]; return r && (n ? this.callbacks[t] = r.filter((s) => s !== n) : delete this.callbacks[t]), this; } once(t, n) { const r = (...s) => { this.off(t, r), n.apply(this, s); }; return this.on(t, r); } removeAllListeners() { this.callbacks = {}; } } function S(e, t, n) { return e.config[t] === void 0 && e.parent ? S(e.parent, t, n) : typeof e.config[t] == "function" ? e.config[t].bind({ ...n, parent: e.parent ? S(e.parent, t, n) : null }) : e.config[t]; } function vt(e) { const t = e.filter((s) => s.type === "extension"), n = e.filter((s) => s.type === "node"), r = e.filter((s) => s.type === "mark"); return { baseExtensions: t, nodeExtensions: n, markExtensions: r }; } function _e(e) { const t = [], { nodeExtensions: n, markExtensions: r } = vt(e), s = [...n, ...r], o = { default: null, rendered: !0, renderHTML: null, parseHTML: null, keepOnSplit: !0, isRequired: !1 }; return e.forEach((i) => { const a = { name: i.name, options: i.options, storage: i.storage, extensions: s }, c = S(i, "addGlobalAttributes", a); if (!c) return; c().forEach((u) => { u.types.forEach((d) => { Object.entries(u.attributes).forEach(([p, h]) => { t.push({ type: d, name: p, attribute: { ...o, ...h } }); }); }); }); }), s.forEach((i) => { const a = { name: i.name, options: i.options, storage: i.storage }, c = S(i, "addAttributes", a); if (!c) return; const l = c(); Object.entries(l).forEach(([u, d]) => { const p = { ...o, ...d }; typeof (p == null ? void 0 : p.default) == "function" && (p.default = p.default()), p != null && p.isRequired && (p == null ? void 0 : p.default) === void 0 && delete p.default, t.push({ type: i.name, name: u, attribute: p }); }); }), t; } function R(e, t) { if (typeof e == "string") { if (!t.nodes[e]) throw Error(`There is no node type named '${e}'. Maybe you forgot to add the extension?`); return t.nodes[e]; } return e; } function C(...e) { return e.filter((t) => !!t).reduce((t, n) => { const r = { ...t }; return Object.entries(n).forEach(([s, o]) => { if (!r[s]) { r[s] = o; return; } if (s === "class") { const a = o ? String(o).split(" ") : [], c = r[s] ? r[s].split(" ") : [], l = a.filter((u) => !c.includes(u)); r[s] = [...c, ...l].join(" "); } else if (s === "style") { const a = o ? o.split(";").map((u) => u.trim()).filter(Boolean) : [], c = r[s] ? r[s].split(";").map((u) => u.trim()).filter(Boolean) : [], l = /* @__PURE__ */ new Map(); c.forEach((u) => { const [d, p] = u.split(":").map((h) => h.trim()); l.set(d, p); }), a.forEach((u) => { const [d, p] = u.split(":").map((h) => h.trim()); l.set(d, p); }), r[s] = Array.from(l.entries()).map(([u, d]) => `${u}: ${d}`).join("; "); } else r[s] = o; }), r; }, {}); } function ht(e, t) { return t.filter((n) => n.type === e.type.name).filter((n) => n.attribute.rendered).map((n) => n.attribute.renderHTML ? n.attribute.renderHTML(e.attrs) || {} : { [n.name]: e.attrs[n.name] }).reduce((n, r) => C(n, r), {}); } function Pe(e) { return typeof e == "function"; } function E(e, t = void 0, ...n) { return Pe(e) ? t ? e.bind(t)(...n) : e(...n) : e; } function nr(e = {}) { return Object.keys(e).length === 0 && e.constructor === Object; } function rr(e) { return typeof e != "string" ? e : e.match(/^[+-]?(?:\d*\.)?\d+$/) ? Number(e) : e === "true" ? !0 : e === "false" ? !1 : e; } function ie(e, t) { return "style" in e ? e : { ...e, getAttrs: (n) => { const r = e.getAttrs ? e.getAttrs(n) : e.attrs; if (r === !1) return !1; const s = t.reduce((o, i) => { const a = i.attribute.parseHTML ? i.attribute.parseHTML(n) : rr(n.getAttribute(i.name)); return a == null ? o : { ...o, [i.name]: a }; }, {}); return { ...r, ...s }; } }; } function ae(e) { return Object.fromEntries( // @ts-ignore Object.entries(e).filter(([t, n]) => t === "attrs" && nr(n) ? !1 : n != null) ); } function sr(e, t) { var n; const r = _e(e), { nodeExtensions: s, markExtensions: o } = vt(e), i = (n = s.find((l) => S(l, "topNode"))) === null || n === void 0 ? void 0 : n.name, a = Object.fromEntries(s.map((l) => { const u = r.filter((y) => y.type === l.name), d = { name: l.name, options: l.options, storage: l.storage, editor: t }, p = e.reduce((y, M) => { const v = S(M, "extendNodeSchema", d); return { ...y, ...v ? v(l) : {} }; }, {}), h = ae({ ...p, content: E(S(l, "content", d)), marks: E(S(l, "marks", d)), group: E(S(l, "group", d)), inline: E(S(l, "inline", d)), atom: E(S(l, "atom", d)), selectable: E(S(l, "selectable", d)), draggable: E(S(l, "draggable", d)), code: E(S(l, "code", d)), whitespace: E(S(l, "whitespace", d)), linebreakReplacement: E(S(l, "linebreakReplacement", d)), defining: E(S(l, "defining", d)), isolating: E(S(l, "isolating", d)), attrs: Object.fromEntries(u.map((y) => { var M; return [y.name, { default: (M = y == null ? void 0 : y.attribute) === null || M === void 0 ? void 0 : M.default }]; })) }), m = E(S(l, "parseHTML", d)); m && (h.parseDOM = m.map((y) => ie(y, u))); const f = S(l, "renderHTML", d); f && (h.toDOM = (y) => f({ node: y, HTMLAttributes: ht(y, u) })); const g = S(l, "renderText", d); return g && (h.toText = g), [l.name, h]; })), c = Object.fromEntries(o.map((l) => { const u = r.filter((g) => g.type === l.name), d = { name: l.name, options: l.options, storage: l.storage, editor: t }, p = e.reduce((g, y) => { const M = S(y, "extendMarkSchema", d); return { ...g, ...M ? M(l) : {} }; }, {}), h = ae({ ...p, inclusive: E(S(l, "inclusive", d)), excludes: E(S(l, "excludes", d)), group: E(S(l, "group", d)), spanning: E(S(l, "spanning", d)), code: E(S(l, "code", d)), attrs: Object.fromEntries(u.map((g) => { var y; return [g.name, { default: (y = g == null ? void 0 : g.attribute) === null || y === void 0 ? void 0 : y.default }]; })) }), m = E(S(l, "parseHTML", d)); m && (h.parseDOM = m.map((g) => ie(g, u))); const f = S(l, "renderHTML", d); return f && (h.toDOM = (g) => f({ mark: g, HTMLAttributes: ht(g, u) })), [l.name, h]; })); return new Ee({ topNode: i, nodes: a, marks: c }); } function At(e, t) { return t.nodes[e] || t.marks[e] || null; } function le(e, t) { return Array.isArray(t) ? t.some((n) => (typeof n == "string" ? n : n.name) === e.name) : t; } function Ut(e, t) { const n = tn.fromSchema(t).serializeFragment(e), s = document.implementation.createHTMLDocument().createElement("div"); return s.appendChild(n), s.innerHTML; } const or = (e, t = 500) => { let n = ""; const r = e.parentOffset; return e.parent.nodesBetween(Math.max(0, r - t), r, (s, o, i, a) => { var c, l; const u = ((l = (c = s.type.spec).toText) === null || l === void 0 ? void 0 : l.call(c, { node: s, pos: o, parent: i, index: a })) || s.textContent || "%leaf%"; n += s.isAtom && !s.isText ? u : u.slice(0, Math.max(0, r - o)); }), n; }; function qt(e) { return Object.prototype.toString.call(e) === "[object RegExp]"; } class bt { constructor(t) { this.find = t.find, this.handler = t.handler; } } const ir = (e, t) => { if (qt(t)) return t.exec(e); const n = t(e); if (!n) return null; const r = [n.text]; return r.index = n.index, r.input = e, r.data = n.data, n.replaceWith && (n.text.includes(n.replaceWith) || console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'), r.push(n.replaceWith)), r; }; function ot(e) { var t; const { editor: n, from: r, to: s, text: o, rules: i, plugin: a } = e, { view: c } = n; if (c.composing) return !1; const l = c.state.doc.resolve(r); if ( // check for code node l.parent.type.spec.code || !((t = l.nodeBefore || l.nodeAfter) === null || t === void 0) && t.marks.find((p) => p.type.spec.code) ) return !1; let u = !1; const d = or(l) + o; return i.forEach((p) => { if (u) return; const h = ir(d, p.find); if (!h) return; const m = c.state.tr, f = gt({ state: c.state, transaction: m }), g = { from: r - (h[0].length - o.length), to: s }, { commands: y, chain: M, can: v } = new yt({ editor: n, state: f }); p.handler({ state: f, range: g, match: h, commands: y, chain: M, can: v }) === null || !m.steps.length || (m.setMeta(a, { transform: m, from: r, to: s, text: o }), c.dispatch(m), u = !0); }), u; } function ar(e) { const { editor: t, rules: n } = e, r = new H({ state: { init() { return null; }, apply(s, o, i) { const a = s.getMeta(r); if (a) return a; const c = s.getMeta("applyInputRules"); return !!c && setTimeout(() => { let { text: u } = c; typeof u == "string" ? u = u : u = Ut(V.from(u), i.schema); const { from: d } = c, p = d + u.length; ot({ editor: t, from: d, to: p, text: u, rules: n, plugin: r }); }), s.selectionSet || s.docChanged ? null : o; } }, props: { handleTextInput(s, o, i, a) { return ot({ editor: t, from: o, to: i, text: a, rules: n, plugin: r }); }, handleDOMEvents: { compositionend: (s) => (setTimeout(() => { const { $cursor: o } = s.state.selection; o && ot({ editor: t, from: o.pos, to: o.pos, text: "", rules: n, plugin: r }); }), !1) }, // add support for input rules to trigger on enter // this is useful for example for code blocks handleKeyDown(s, o) { if (o.key !== "Enter") return !1; const { $cursor: i } = s.state.selection; return i ? ot({ editor: t, from: i.pos, to: i.pos, text: ` `, rules: n, plugin: r }) : !1; } }, // @ts-ignore isInputRules: !0 }); return r; } function lr(e) { return Object.prototype.toString.call(e).slice(8, -1); } function it(e) { return lr(e) !== "Object" ? !1 : e.constructor === Object && Object.getPrototypeOf(e) === Object.prototype; } function Mt(e, t) { const n = { ...e }; return it(e) && it(t) && Object.keys(t).forEach((r) => { it(t[r]) && it(e[r]) ? n[r] = Mt(e[r], t[r]) : n[r] = t[r]; }), n; } class N { constructor(t = {}) { this.type = "mark", this.name = "mark", this.parent = null, this.child = null, this.config = { name: this.name, defaultOptions: {} }, this.config = { ...this.config, ...t }, this.name = this.config.name, t.defaultOptions && Object.keys(t.defaultOptions).length > 0 && console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`), this.options = this.config.defaultOptions, this.config.addOptions && (this.options = E(S(this, "addOptions", { name: this.name }))), this.storage = E(S(this, "addStorage", { name: this.name, options: this.options })) || {}; } static create(t = {}) { return new N(t); } configure(t = {}) { const n = this.extend({ ...this.config, addOptions: () => Mt(this.options, t) }); return n.name = this.name, n.parent = this.parent, n; } extend(t = {}) { const n = new N(t); return n.parent = this, this.child = n, n.name = t.name ? t.name : n.parent.name, t.defaultOptions && Object.keys(t.defaultOptions).length > 0 && console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${n.name}".`), n.options = E(S(n, "addOptions", { name: n.name })), n.storage = E(S(n, "addStorage", { name: n.name, options: n.options })), n; } static handleExit({ editor: t, mark: n }) { const { tr: r } = t.state, s = t.state.selection.$from; if (s.pos === s.end()) { const i = s.marks(); if (!!!i.find((l) => (l == null ? void 0 : l.type.name) === n.name)) return !1; const c = i.find((l) => (l == null ? void 0 : l.type.name) === n.name); return c && r.removeStoredMark(c), r.insertText(" ", s.pos), t.view.dispatch(r), !0; } return !1; } } function cr(e) { return typeof e == "number"; } class dr { constructor(t) { this.find = t.find, this.handler = t.handler; } } const ur = (e, t, n) => { if (qt(t)) return [...e.matchAll(t)]; const r = t(e, n); return r ? r.map((s) => { const o = [s.text]; return o.index = s.index, o.input = e, o.data = s.data, s.replaceWith && (s.text.includes(s.replaceWith) || console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".'), o.push(s.replaceWith)), o; }) : []; }; function pr(e) { const { editor: t, state: n, from: r, to: s, rule: o, pasteEvent: i, dropEvent: a } = e, { commands: c, chain: l, can: u } = new yt({ editor: t, state: n }), d = []; return n.doc.nodesBetween(r, s, (h, m) => { if (!h.isTextblock || h.type.spec.code) return; const f = Math.max(r, m), g = Math.min(s, m + h.content.size), y = h.textBetween(f - m, g - m, void 0, ""); ur(y, o.find, i).forEach((v) => { if (v.index === void 0) return; const b = f + v.index + 1, w = b + v[0].length, k = { from: n.tr.mapping.map(b), to: n.tr.mapping.map(w) }, T = o.handler({ state: n, range: k, match: v, commands: c, chain: l, can: u, pasteEvent: i, dropEvent: a }); d.push(T); }); }), d.every((h) => h !== null); } let at = null; const hr = (e) => { var t; const n = new ClipboardEvent("paste", { clipboardData: new DataTransfer() }); return (t = n.clipboardData) === null || t === void 0 || t.setData("text/html", e), n; }; function fr(e) { const { editor: t, rules: n } = e; let r = null, s = !1, o = !1, i = typeof ClipboardEvent < "u" ? new ClipboardEvent("paste") : null, a; try { a = typeof DragEvent < "u" ? new DragEvent("drop") : null; } catch { a = null; } const c = ({ state: u, from: d, to: p, rule: h, pasteEvt: m }) => { const f = u.tr, g = gt({ state: u, transaction: f }); if (!(!pr({ editor: t, state: g, from: Math.max(d - 1, 0), to: p.b - 1, rule: h, pasteEvent: m, dropEvent: a }) || !f.steps.length)) { try { a = typeof DragEvent < "u" ? new DragEvent("drop") : null; } catch { a = null; } return i = typeof ClipboardEvent < "u" ? new ClipboardEvent("paste") : null, f; } }; return n.map((u) => new H({ // we register a global drag handler to track the current drag source element view(d) { const p = (m) => { var f; r = !((f = d.dom.parentElement) === null || f === void 0) && f.contains(m.target) ? d.dom.parentElement : null, r && (at = t); }, h = () => { at && (at = null); }; return window.addEventListener("dragstart", p), window.addEventListener("dragend", h), { destroy() { window.removeEventListener("dragstart", p), window.removeEventListener("dragend", h); } }; }, props: { handleDOMEvents: { drop: (d, p) => { if (o = r === d.dom.parentElement, a = p, !o) { const h = at; h && setTimeout(() => { const m = h.state.selection; m && h.commands.deleteRange({ from: m.from, to: m.to }); }, 10); } return !1; }, paste: (d, p) => { var h; const m = (h = p.clipboardData) === null || h === void 0 ? void 0 : h.getData("text/html"); return i = p, s = !!(m != null && m.includes("data-pm-slice")), !1; } } }, appendTransaction: (d, p, h) => { const m = d[0], f = m.getMeta("uiEvent") === "paste" && !s, g = m.getMeta("uiEvent") === "drop" && !o, y = m.getMeta("applyPasteRules"), M = !!y; if (!f && !g && !M) return; if (M) { let { text: w } = y; typeof w == "string" ? w = w : w = Ut(V.from(w), h.schema); const { from: k } = y, T = k + w.length, x = hr(w); return c({ rule: u, state: h, from: k, to: { b: T }, pasteEvt: x }); } const v = p.doc.content.findDiffStart(h.doc.content), b = p.doc.content.findDiffEnd(h.doc.content); if (!(!cr(v) || !b || v === b.b)) return c({ rule: u, state: h, from: v, to: b, pasteEvt: i }); } })); } function mr(e) { const t = e.filter((n, r) => e.indexOf(n) !== r); return Array.from(new Set(t)); } class Z { constructor(t, n) { this.splittableMarks = [], this.editor = n, this.extensions = Z.resolve(t), this.schema = sr(this.extensions, n), this.setupExtensions(); } /** * Returns a flattened and sorted extension list while * also checking for duplicated extensions and warns the user. * @param extensions An array of Tiptap extensions * @returns An flattened and sorted array of Tiptap extensions */ static resolve(t) { const n = Z.sort(Z.flatten(t)), r = mr(n.map((s) => s.name)); return r.length && console.warn(`[tiptap warn]: Duplicate extension names found: [${r.map((s) => `'${s}'`).join(", ")}]. This can lead to issues.`), n; } /** * Create a flattened array of extensions by traversing the `addExtensions` field. * @param extensions An array of Tiptap extensions * @returns A flattened array of Tiptap extensions */ static flatten(t) { return t.map((n) => { const r = { name: n.name, options: n.options, storage: n.storage }, s = S(n, "addExtensions", r); return s ? [n, ...this.flatten(s())] : n; }).flat(10); } /** * Sort extensions by priority. * @param extensions An array of Tiptap extensions * @returns A sorted array of Tiptap extensions by priority */ static sort(t) { return t.sort((r, s) => { const o = S(r, "priority") || 100, i = S(s, "priority") || 100; return o > i ? -1 : o < i ? 1 : 0; }); } /** * Get all commands from the extensions. * @returns An object with all commands where the key is the command name and the value is the command function */ get commands() { return this.extensions.reduce((t, n) => { const r = { name: n.name, options: n.options, storage: n.storage, editor: this.editor, type: At(n.name, this.schema) }, s = S(n, "addCommands", r); return s ? { ...t, ...s() } : t; }, {}); } /** * Get all registered Prosemirror plugins from the extensions. * @returns An array of Prosemirror plugins */ get plugins() { const { editor: t } = this, n = Z.sort([...this.extensions].reverse()), r = [], s = [], o = n.map((i) => { const a = { name: i.name, options: i.options, storage: i.storage, editor: t, type: At(i.name, this.schema) }, c = [], l = S(i, "addKeyboardShortcuts", a); let u = {}; if (i.type === "mark" && S(i, "exitable", a) && (u.ArrowRight = () => N.handleExit({ editor: t, mark: i })), l) { const f = Object.fromEntries(Object.entries(l()).map(([g, y]) => [g, () => y({ editor: t })])); u = { ...u, ...f }; } const d = Ze(u); c.push(d); const p = S(i, "addInputRules", a); le(i, t.options.enableInputRules) && p && r.push(...p()); const h = S(i, "addPasteRules", a); le(i, t.options.enablePasteRules) && h && s.push(...h()); const m = S(i, "addProseMirrorPlugins", a); if (m) { const f = m(); c.push(...f); } return c; }).flat(); return [ ar({ editor: t, rules: r }), ...fr({ editor: t, rules: s }), ...o ]; } /** * Get all attributes from the extensions. * @returns An array of attributes */ get attributes() { return _e(this.extensions); } /** * Get all node views from the extensions. * @returns An object with all node views where the key is the node name and the value is the node view function */ get nodeViews() { const { editor: t } = this, { nodeExtensions: n } = vt(this.extensions); return Object.fromEntries(n.filter((r) => !!S(r, "addNodeView")).map((r) => { const s = this.attributes.filter((c) => c.type === r.name), o = { name: r.name, options: r.options, storage: r.storage, editor: t, type: R(r.name, this.schema) }, i = S(r, "addNodeView", o); if (!i) return []; const a = (c, l, u, d, p) => { const h = ht(c, s); return i()({ // pass-through node: c, view: l, getPos: u, decorations: d, innerDecorations: p, // tiptap-specific editor: t, extension: r, HTMLAttributes: h }); }; return [r.name, a]; })); } /** * Go through all extensions, create extension storages & setup marks * & bind editor event listener. */ setupExtensions() { this.extensions.forEach((t) => { var n; this.editor.extensionStorage[t.name] = t.storage; const r = { name: t.name, options: t.options, storage: t.storage, editor: this.editor, type: At(t.name, this.schema) }; t.type === "mark" && (!((n = E(S(t, "keepOnSplit", r))) !== null && n !== void 0) || n) && this.splittableMarks.push(t.name); const s = S(t, "onBeforeCreate", r), o = S(t, "onCreate", r), i = S(t, "onUpdate", r), a = S(t, "onSelectionUpdate", r), c = S(t, "onTransaction", r), l = S(t, "onFocus", r), u = S(t, "onBlur", r), d = S(t, "onDestroy", r); s && this.editor.on("beforeCreate", s), o && this.editor.on("create", o), i && this.editor.on("update", i), a && this.editor.on("selectionUpdate", a), c && this.editor.on("transaction", c), l && this.editor.on("focus", l), u && this.editor.on("blur", u), d && this.editor.on("destroy", d); }); } } class P { constructor(t = {}) { this.type = "extension", this.name = "extension", this.parent = null, this.child = null, this.config = { name: this.name, defaultOptions: {} }, this.config = { ...this.config, ...t }, this.name = this.config.name, t.defaultOptions && Object.keys(t.defaultOptions).length > 0 && console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`), this.options = this.config.defaultOptions, this.config.addOptions && (this.options = E(S(this, "addOptions", { name: this.name }))), this.storage = E(S(this, "addStorage", { name: this.name, options: this.options })) || {}; } static create(t = {}) { return new P(t); } configure(t = {}) { const n = this.extend({ ...this.config, addOptions: () => Mt(this.options, t) }); return n.name = this.name, n.parent = this.parent, n; } extend(t = {}) { const n = new P({ ...this.config, ...t }); return n.parent = this, this.child = n, n.name = t.name ? t.name : n.parent.name, t.defaultOptions && Object.keys(t.defaultOptions).length > 0 && console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${n.name}".`), n.options = E(S(n, "addOptions", { name: n.name })), n.storage = E(S(n, "addStorage", { name: n.name, options: n.options })), n; } } function Re(e, t, n) { const { from: r, to: s } = t, { blockSeparator: o = ` `, textSerializers: i = {} } = n || {}; let a = ""; return e.nodesBetween(r, s, (c, l, u, d) => { var p; c.isBlock && l > r && (a += o); const h = i == null ? void 0 : i[c.type.name]; if (h) return u && (a += h({ node: c, pos: l, parent: u, index: d, range: t })), !1; c.isText && (a += (p = c == null ? void 0 : c.text) === null || p === void 0 ? void 0 : p.slice(Math.max(r, l) - l, s - l)); }), a; } function He(e) { return Object.fromEntries(Object.entries(e.nodes).filter(([, t]) => t.spec.toText).map(([t, n]) => [t, n.spec.toText])); } const gr = P.create({ name: "clipboardTextSerializer", addOptions() { return { blockSeparator: void 0 }; }, addProseMirrorPlugins() { return [ new H({ key: new $("clipboardTextSerializer"), props: { clipboardTextSerializer: () => { const { editor: e } = this, { state: t, schema: n } = e, { doc: r, selection: s } = t, { ranges: o } = s, i = Math.min(...o.map((u) => u.$from.pos)), a = Math.max(...o.map((u) => u.$to.pos)), c = He(n); return Re(r, { from: i, to: a }, { ...this.options.blockSeparator !== void 0 ? { blockSeparator: this.options.blockSeparator } : {}, textSerializers: c }); } } }) ]; } }), yr = () => ({ editor: e, view: t }) => (requestAnimationFrame(() => { var n; e.isDestroyed || (t.dom.blur(), (n = window == null ? void 0 : window.getSelection()) === null || n === void 0 || n.removeAllRanges()); }), !0), vr = (e = !1) => ({ commands: t }) => t.setContent("", e), br = () => ({ state: e, tr: t, dispatch: n }) => { const { selection: r } = t, { ranges: s } = r; return n && s.forEach(({ $from: o, $to: i }) => { e.doc.nodesBetween(o.pos, i.pos, (a, c) => { if (a.type.isText) return; const { doc: l, mapping: u } = t, d = l.resolve(u.map(c)), p = l.resolve(u.map(c + a.nodeSize)), h = d.blockRange(p); if (!h) return; const m = Cn(h); if (a.type.isTextblock) { const { defaultType: f } = d.parent.contentMatchAt(d.index()); t.setNodeMarkup(h.start, f); } (m || m === 0) && t.lift(h, m); }); }), !0; }, Mr = (e) => (t) => e(t), Sr = () => ({ state: e, dispatch: t }) => Tn(e, t), kr = (e, t) => ({ editor: n, tr: r }) => { const { state: s } = n, o = s.doc.slice(e.from, e.to); r.deleteRange(e.from, e.to); const i = r.mapping.map(t); return r.insert(i, o.content), r.setSelection(new D(r.doc.resolve(i - 1))), !0; }, wr = () => ({ tr: e, dispatch: t }) => { const { selection: n } = e, r = n.$anchor.node(); if (r.content.size > 0) return !1; const s = e.selection.$anchor; for (let o = s.depth; o > 0; o -= 1) if (s.node(o).type === r.type) { if (t) { const a = s.before(o), c = s.after(o); e.delete(a, c).scrollIntoView(); } return !0; } return !1; }, Er = (e) => ({ tr: t, state: n, dispatch: r }) => { const s = R(e, n.schema), o = t.selection.$anchor; for (let i = o.depth; i > 0; i -= 1) if (o.node(i).type === s) { if (r) { const c = o.before(i), l = o.after(i); t.delete(c, l).scrollIntoView(); } return !0; } return !1; }, Tr = (e) => ({ tr: t, dispatch: n }) => { const { from: r, to: s } = e; return n && t.delete(r, s), !0; }, Cr = () => ({ state: e, dispatch: t }) => En(e, t), xr = () => ({ commands: e }) => e.keyboardShortcut("Enter"), Ar = () => ({ state: e, dispatch: t }) => wn(e, t); function ft(e, t, n = { strict: !0 }) { const r = Object.keys(t); return r.length ? r.every((s) => n.strict ? t[s] === e[s] : qt(t[s]) ? t[s].test(e[s]) : t[s] === e[s]) : !0; } function $e(e, t, n = {}) { return e.find((r) => r.type === t && ft( // Only check equality for the attributes that are provided Object.fromEntries(Object.keys(n).map((s) => [s, r.attrs[s]])), n )); } function ce(e, t, n = {}) { return !!$e(e, t, n); } function Gt(e, t, n) { var r; if (!e || !t) return; let s = e.parent.childAfter(e.parentOffset); if ((!s.node || !s.node.marks.some((u) => u.type === t)) && (s = e.parent.childBefore(e.parentOffset)), !s.node || !s.node.marks.some((u) => u.type === t) || (n = n || ((r = s.node.marks[0]) === null || r === void 0 ? void 0 : r.attrs), !$e([...s.node.marks], t, n))) return; let i = s.index, a = e.start() + s.offset, c = i + 1, l = a + s.node.nodeSize; for (; i > 0 && ce([...e.parent.child(i - 1).marks], t, n); ) i -= 1, a -= e.parent.child(i).nodeSize; for (; c < e.parent.childCount && ce([...e.parent.child(c).marks], t, n); ) l += e.parent.child(c).nodeSize, c += 1; return { from: a, to: l }; } function K(e, t) { if (typeof e == "string") { if (!t.marks[e]) throw Error(`There is no mark type named '${e}'. Maybe you forgot to add the extension?`); return t.marks[e]; } return e; } const Or = (e, t = {}) => ({ tr: n, state: r, dispatch: s }) => { const o = K(e, r.schema), { doc: i, selection: a } = n, { $from: c, from: l, to: u } = a; if (s) { const d = Gt(c, o, t); if (d && d.from <= l && d.to >= u) { const p = D.create(i, d.from, d.to); n.setSelection(p); } } return !0; }, Lr = (e) => (t) => { const n = typeof e == "function" ? e(t) : e; for (let r = 0; r < n.length; r += 1) if (n[r](t)) return !0; return !1; }; function Jt(e) { return e instanceof D; } function F(e = 0, t = 0, n = 0) { return Math.min(Math.max(e, t), n); } function Ie(e, t = null) { if (!t) return null; const n = G.atStart(e), r = G.atEnd(e); if (t === "start" || t === !0) return n; if (t === "end") return r; const s = n.from, o = r.to; return t === "all" ? D.create(e, F(0, s, o), F(e.content.size, s, o)) : D.create(e, F(t, s, o), F(t, s, o)); } function De() { return navigator.platform === "Android" || /android/i.test(navigator.userAgent); } function St() { return [ "iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod" ].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document; } const _r = (e = null, t = {}) => ({ editor: n, view: r, tr: s, dispatch: o }) => { t = { scrollIntoView: !0, ...t }; const i = () => { (St() || De()) && r.dom.focus(), requestAnimationFrame(() => { n.isDestroyed || (r.focus(), t != null && t.scrollIntoView && n.commands.scrollIntoView()); }); }; if (r.hasFocus() && e === null || e === !1) return !0; if (o && e === null && !Jt(n.state.selection)) return i(), !0; const a = Ie(s.doc, e) || n.state.selection, c = n.state.selection.eq(a); return o && (c || s.setSelection(a), c && s.storedMarks && s.setStoredMarks(s.storedMarks), i()), !0; }, Pr = (e, t) => (n) => e.every((r, s) => t(r, { ...n, index: s })), Rr = (e, t) => ({ tr: n, commands: r }) => r.insertContentAt({ from: n.selection.from, to: n.selection.to }, e, t), Ne = (e) => { const t = e.childNodes; for (let n = t.length - 1; n >= 0; n -= 1) { const r = t[n]; r.nodeType === 3 && r.nodeValue && /^(\n\s\s|\n)$/.test(r.nodeValue) ? e.removeChild(r) : r.nodeType === 1 && Ne(r); } return e; }; function lt(e) { const t = `<body>${e}</body>`, n = new window.DOMParser().parseFromString(t, "text/html").body; return Ne(n); } function mt(e, t, n) { if (e instanceof en || e instanceof V) return e; n = { slice: !0, parseOptions: {}, ...n }; const r = typeof e == "object" && e !== null, s = typeof e == "string"; if (r) try { if (Array.isArray(e) && e.length > 0) return V.fromArray(e.map((a) => t.nodeFromJSON(a))); const i = t.nodeFromJSON(e); return n.errorOnInvalidContent && i.check(), i; } catch (o) { if (n.errorOnInvalidContent) throw new Error("[tiptap error]: Invalid JSON content", { cause: o }); return console.warn("[tiptap warn]: Invalid content.", "Passed value:", e, "Error:", o), mt("", t, n); } if (s) { if (n.errorOnInvalidContent) { let i = !1, a = ""; const c = new Ee({ topNode: t.spec.topNode, marks: t.spec.marks, // Prosemirror's schemas are executed such that: the last to execute, matches last // This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle nodes: t.spec.nodes.append({ __tiptap__private__unknown__catch__all__node: { content: "inline*", group: "block", parseDOM: [ { tag: "*", getAttrs: (l) => (i = !0, a = typeof l == "string" ? l : l.outerHTML, null) } ] } }) }); if (n.slice ? xt.fromSchema(c).parseSlice(lt(e), n.parseOptions) : xt.fromSchema(c).parse(lt(e), n.parseOptions), n.errorOnInvalidContent && i) throw new Error("[tiptap error]: Invalid HTML content", { cause: new Error(`Invalid element found: ${a}`) }); } const o = xt.fromSchema(t); return n.slice ? o.parseSlice(lt(e), n.parseOptions).content : o.parse(lt(e), n.parseOptions); } return mt("", t, n); } function Hr(e, t, n) { const r = e.steps.length - 1; if (r < t) return; const s = e.steps[r]; if (!(s instanceof xn || s instanceof An)) return; const o = e.mapping.maps[r]; let i = 0; o.forEach((a, c, l, u) => { i === 0 && (i = u); }), e.setSelection(G.near(e.doc.resolve(i), n)); } const $r = (e) => !("type" in e), Ir = (e, t, n) => ({ tr: r, dispatch: s, editor: o }) => { var i; if (s) { n = { parseOptions: o.options.parseOptions, updateSelection: !0, applyInputRules: !1, applyPasteRules: !1, ...n }; let a; try { a = mt(t, o.schema, { parseOptions: { preserveWhitespace: "full", ...n.parseOptions }, errorOnInvalidContent: (i = n.errorOnInvalidContent) !== null && i !== void 0 ? i : o.options.enableContentCheck }); } catch (m) { return o.emit("contentError", { editor: o, error: m, disableCollaboration: () => { o.storage.collaboration && (o.storage.collaboration.isDisabled = !0); } }), !1; } let { from: c, to: l } = typeof e == "number" ? { from: e, to: e } : { from: e.from, to: e.to }, u = !0, d = !0; if (($r(a) ? a : [a]).forEach((m) => { m.check(), u = u ? m.isText && m.marks.length === 0 : !1, d = d ? m.isBlock : !1; }), c === l && d) { const { parent: m } = r.doc.resolve(c); m.isTextblock && !m.type.spec.code && !m.childCount && (c -= 1, l += 1); } let h; if (u) { if (Array.isArray(t)) h = t.map((m) => m.text || "").join(""); else if (t instanceof V) { let m = ""; t.forEach((f) => { f.text && (m += f.text); }), h = m; } else typeof t == "object" && t && t.text ? h = t.text : h = t; r.insertText(h, c, l); } else h = a, r.replaceWith(c, l, h); n.updateSelection && Hr(r, r.steps.length - 1, -1), n.applyInputRules && r.setMeta("applyInputRules", { from: c, text: h }), n.applyPasteRules && r.setMeta("applyPasteRules", { from: c, text: h }); } return !0; }, Dr = () => ({ state: e, dispatch: t }) => yn(e, t), Nr = () => ({ state: e, dispatch: t }) => Sn(e, t), Br = () => ({ state: e, dispatch: t }) => kn(e, t), jr = () => ({ state: e, dispatch: t }) => Mn(e, t), Fr = () => ({ state: e, dispatch: t, tr: n }) => { try { const r = Te(e.doc, e.selection.$from.pos, -1); return r == null ? !1 : (n.join(r, 2), t && t(n), !0); } catch { return !1; } }, zr = () => ({ state: e, dispatch: t, tr: n }) => { try { const r = Te(e.doc, e.selection.$from.pos, 1); return r == null ? !1 : (n.join(r, 2), t && t(n), !0); } catch { return !1; } }, Vr = () => ({ state: e, dispatch: t }) => bn(e, t), Wr = () => ({ state: e, dispatch: t }) => vn(e, t); function Be() { return typeof navigator < "u" ? /Mac/.test(navigator.platform) : !1; } function Kr(e) { const t = e.split(/-(?!$)/); let n = t[t.length - 1]; n === "Space" && (n = " "); let r, s, o, i; for (let a = 0; a < t.length - 1; a += 1) { const c = t[a]; if (/^(cmd|meta|m)$/i.test(c)) i = !0; else if (/^a(lt)?$/i.test(c)) r = !0; else if (/^(c|ctrl|control)$/i.test(c)) s = !0; else if (/^s(hift)?$/i.test(c)) o = !0; else if (/^mod$/i.test(c)) St() || Be() ? i = !0 : s = !0; else throw new Error(`Unrecognized modifier name: ${c}`); } return r && (n = `Alt-${n}`), s && (n = `Ctrl-${n}`), i && (n = `Meta-${n}`), o && (n = `Shift-${n}`), n; } const Ur = (e) => ({ editor: t, view: n, tr: r, dispatch: s }) => { const o = Kr(e).split(/-(?!$)/), i = o.find((l) => !["Alt", "Ctrl", "Meta", "Shift"].includes(l)), a = new KeyboardEvent("keydown", { key: i === "Space" ? " " : i, altKey: o.includes("Alt"), ctrlKey: o.includes("Ctrl"), metaKey: o.includes("Meta"), shiftKey: o.includes("Shift"), bubbles: !0, cancelable: !0 }), c = t.captureTransaction(() => { n.someProp("handleKeyDown", (l) => l(n, a)); }); return c == null || c.steps.forEach((l) => { const u = l.map(r.mapping); u && s && r.maybeStep(u); }), !0; }; function st(e, t, n = {}) { const { from: r, to: s, empty: o } = e.selection, i = t ? R(t, e.schema) : null, a = []; e.doc.nodesBetween(r, s, (d, p) => { if (d.isText) return; const h = Math.max(r, p), m = Math.min(s, p + d.nodeSize); a.push({ node: d, from: h, to: m }); }); const c = s - r, l = a.filter((d) => i ? i.name === d.node.type.name : !0).filter((d) => ft(d.node.attrs, n, { strict: !1 })); return o ? !!l.length : l.reduce((d, p) => d + p.to - p.from, 0) >= c; } const qr = (e, t = {}) => ({ state: n, dispatch: r }) => { const s = R(e, n.schema); return st(n, s, t) ? gn(n, r) : !1; }, Gr = () => ({ state: e, dispatch: t }) => mn(e, t), Jr = (e) => ({ state: t, dispatch: n }) => { const r = R(e, t.schema); return fn(r)(t, n); }, Yr = () => ({ state: e, dispatch: t }) => hn(e, t); function kt(e, t) { return t.nodes[e] ? "node" : t.marks[e] ? "mark" : null; } function de(e, t) { const n = typeof t == "string" ? [t] : t; return Object.keys(e).reduce((r, s) => (n.includes(s) || (r[s] = e[s]), r), {}); } const Xr = (e, t) => ({ tr: n, state: r, dispatch: s }) => { let o = null, i = null; const a = kt(typeof e == "string" ? e : e.name, r.schema); return a ? (a === "node" && (o = R(e, r.schema)), a === "mark" && (i = K(e, r.schema)), s && n.selection.ranges.forEach((c) => { r.doc.nodesBetween(c.$from.pos, c.$to.pos, (l, u) => { o && o === l.type && n.setNodeMarkup(u, void 0, de(l.attrs, t)), i && l.marks.length && l.marks.forEach((d) => { i === d.type && n.addMark(u, u + l.nodeSize, i.create(de(d.attrs, t))); }); }); }), !0) : !1; }, Qr = () => ({ tr: e, dispatch: t }) => (t && e.scrollIntoView(), !0), Zr = () => ({ tr: e, dispatch: t }) => { if (t) { const n = new pn(e.doc); e.setSelection(n); } return !0; }, ts = () => ({ state: e, dispatch: t }) => un(e, t), es = () => ({ state: e, dispatch: t }) => dn(e, t), ns = () => ({ state: e, dispatch: t }) => cn(e, t), rs = () => ({ state: e, dispatch: t }) => ln(e, t), ss = () => ({ state: e, dispatch: t }) => an(e, t); function $t(e, t, n = {}, r = {}) { return mt(e, t, { slice: !1, parseOptions: n, errorOnInvalidContent: r.errorOnInvalidContent }); } const os = (e, t = !1, n = {}, r = {}) => ({ editor: s, tr: o, dispatch: i, commands: a }) => { var c, l; const { doc: u } = o; if (n.preserveWhitespace !== "full") { const d = $t(e, s.schema, n, { errorOnInvalidContent: (c = r.errorOnInvalidContent) !== null && c !== void 0 ? c : s.options.enableContentCheck }); return i && o.replaceWith(0, u.content.size, d).setMeta("preventUpdate", !t), !0; } return i && o.setMeta("preventUpdate", !t), a.insertContentAt({ from: 0, to: u.content.size }, e, { parseOptions: n, errorOnInvalidContent: (l = r.errorOnInvalidContent) !== null && l !== void 0 ? l : s.options.enableContentCheck }); }; function je(e, t) { const n = K(t, e.schema), { from: r, to: s, empty: o } = e.selection, i = []; o ? (e.storedMarks && i.push(...e.storedMarks), i.push(...e.selection.$head.marks())) : e.doc.nodesBetween(r, s, (c) => { i.push(...c.marks); }); const a = i.find((c) => c.type.name === n.name); return a ? { ...a.attrs } : {}; } function is(e, t) { const n = new Ln(e); return t.forEach((r) => { r.steps.forEach((s) => { n.step(s); }); }), n; } function as(e) { for (let t = 0; t < e.edgeCount; t += 1) { const { type: n } = e.edge(t); if (n.isTextblock && !n.hasRequiredAttrs()) return n; } return null; } function si(e, t) { const n = []; return e.descendants((r, s) => { t(r) && n.push({ node: r, pos: s }); }), n; } function ls(e, t, n) { const r = []; return e.nodesBetween(t.from, t.to, (s, o) => { n(s) && r.push({ node: s, pos: o }); }), r; } function Fe(e, t) { for (let n = e.depth; n > 0; n -= 1) { const r = e.node(n); if (t(r)) return { pos: n > 0 ? e.before(n) : 0, start: e.start(n), depth: n, node: r }; } } function Yt(e) { return (t) => Fe(t.$from, e); } function cs(e, t) { const n = { from: 0, to: e.content.size }; return Re(e, n, t); } function ds(e, t) { const n = R(t, e.schema), { from: r, to: s } = e.selection, o = []; e.doc.nodesBetween(r, s, (a) => { o.push(a); }); const i = o.reverse().find((a) => a.type.name === n.name); return i ? { ...i.attrs } : {}; } function ze(e, t) { const n = kt(typeof t == "string" ? t : t.name, e.schema); return n === "node" ? ds(e, t) : n === "mark" ? je(e, t) : {}; } function us(e, t = JSON.stringify) { const n = {}; return e.filter((r) => { const s = t(r); return Object.prototype.hasOwnProperty.call(n, s) ? !1 : n[s] = !0; }); } function ps(e) { const t = us(e); return t.length === 1 ? t : t.filter((n, r) => !t.filter((o, i) => i !== r).some((o) => n.oldRange.from >= o.oldRange.from && n.oldRange.to <= o.oldRange.to && n.newRange.from >= o.newRange.from && n.newRange.to <= o.newRange.to)); } function hs(e) { const { mapping: t, steps: n } = e, r = []; return t.maps.forEach((s, o) => { const i = []; if (s.ranges.length) s.forEach((a, c) => { i.push({ from: a, to: c }); }); else { const { from: a, to: c } = n[o]; if (a === void 0 || c === void 0) return; i.push({ from: a, to: c }); } i.forEach(({ from: a, to: c }) => { const l = t.slice(o).map(a, -1), u = t.slice(o).map(c), d = t.invert().map(l, -1), p = t.invert().map(u); r.push({ oldRange: { from: d, to: p }, newRange: { from: l, to: u } }); }); }), ps(r); } function Xt(e, t, n) { const r = []; return e === t ? n.resolve(e).marks().forEach((s) => { const o = n.resolve(e), i = Gt(o, s.type); i && r.push({ mark: s, ...i }); }) : n.nodesBetween(e, t, (s, o) => { !s || (s == null ? void 0 : s.nodeSize) === void 0 || r.push(...s.marks.map((i) => ({ from: o, to: o + s.nodeSize, mark: i }))); }), r; } function ut(e, t, n) { return Object.fromEntries(Object.entries(n).filter(([r]) => { const s = e.find((o) => o.type === t && o.name === r); return s ? s.attribute.keepOnSplit : !1; })); } function It(e, t, n = {}) { const { empty: r, ranges: s } = e.selection, o = t ? K(t, e.schema) : null; if (r) return !!(e.storedMarks || e.selection.$from.marks()).filter((d) => o ? o.name === d.type.name : !0).find((d) => ft(d.attrs, n, { strict: !1 })); let i = 0; const a = []; if (s.forEach(({ $from: d, $to: p }) => { const h = d.pos, m = p.pos; e.doc.nodesBetween(h, m, (f, g) => { if (!f.isText && !f.marks.length) return; const y = Math.max(h, g), M = Math.min(m, g + f.nodeSize), v = M - y; i += v, a.push(...f.marks.map((b) => ({ mark: b, from: y, to: M }))); }); }), i === 0) return !1; const c = a.filter((d) => o ? o.name === d.mark.type.name : !0).filter((d) => ft(d.mark.attrs, n, { strict: !1 })).reduce((d, p) => d + p.to - p.from, 0), l = a.filter((d) => o ? d.mark.type !== o && d.mark.type.excludes(o) : !0).reduce((d, p) => d + p.to - p.from, 0); return (c > 0 ? c + l : c) >= i; } function fs(e, t, n = {}) { if (!t) return st(e, null, n) || It(e, null, n); const r = kt(t, e.schema); return r === "node" ? st(e, t, n) :