@blocknote/core
Version:
A "Notion-style" block-based extensible text editor built on top of Prosemirror and Tiptap.
2,095 lines • 75.6 kB
JavaScript
import { Bt as e, En as t, Ft as n, Gt as r, Ht as i, Jt as a, Kt as o, Lt as s, Pt as c, Rt as l, Tn as u, Un as d, Ut as f, Vt as p, Wt as m, _ as h, g, or as _, qt as ee, r as te, v, zt as ne } from "./blocks-CzQLehlc.js";
import { n as y, t as b } from "./BlockNoteExtension-CbvDA0F7.js";
import { n as re } from "./UserStore-C4TzkGEn.js";
import { DOMSerializer as ie, Fragment as x, Slice as ae } from "prosemirror-model";
import { Mapping as oe, dropPoint as se } from "prosemirror-transform";
import { combineTransactionSteps as ce, findChildrenInRange as S, posToDOMRect as le } from "@tiptap/core";
import { uuidv4 as ue } from "lib0/random";
import { NodeSelection as de, Plugin as C, PluginKey as w, Selection as T, TextSelection as E } from "prosemirror-state";
import { DOMParser as fe, Slice as pe } from "@tiptap/pm/model";
import { CellSelection as me, addColumnAfter as he, addColumnBefore as ge, addRowAfter as _e, addRowBefore as ve, deleteColumn as ye, deleteRow as be, mergeCells as xe, splitCell as Se } from "prosemirror-tables";
import { Plugin as Ce, PluginKey as we, TextSelection as Te } from "@tiptap/pm/state";
import { Decoration as D, DecorationSet as O } from "prosemirror-view";
import Ee from "fast-deep-equal";
import { history as De, redo as Oe, undo as ke } from "@tiptap/pm/history";
import { createHighlightPlugin as Ae } from "prosemirror-highlight";
import { createParser as je } from "prosemirror-highlight/shiki";
function Me(e) {
let t = Array.from(e.classList).filter((e) => !e.startsWith("bn-")) || [];
t.length > 0 ? e.className = t.join(" ") : e.removeAttribute("class");
}
function Ne(e, n, r, i) {
let a;
if (!n) throw Error("blockContent is required");
if (typeof n == "string") a = s([n], e.pmSchema, i?.blockType);
else if (Array.isArray(n)) a = s(n, e.pmSchema, i?.blockType);
else if (n.type === "tableContent") a = l(n, e.pmSchema);
else throw new d(n.type);
let o = (i?.document ?? document).createDocumentFragment();
for (let n of a) if (n.type.name !== "text" && e.schema.inlineContentSchema[n.type.name]) {
let a = e.schema.inlineContentSpecs[n.type.name].implementation;
if (a) {
let s = t(n, e.schema.inlineContentSchema, e.schema.styleSchema), c = a.toExternalHTML ? a.toExternalHTML(s, e) : a.render.call({
renderType: "dom",
props: void 0
}, s, () => {}, e);
if (c) {
if (o.appendChild(c.dom), c.contentDOM) {
let e = r.serializeFragment(n.content, i);
c.contentDOM.dataset.editable = "", c.contentDOM.appendChild(e);
}
continue;
}
}
} else if (n.type.name === "text") {
let t = document.createTextNode(n.textContent);
for (let r of n.marks.toReversed()) if (r.type.name in e.schema.styleSpecs) {
let n = (e.schema.styleSpecs[r.type.name].implementation.toExternalHTML ?? e.schema.styleSpecs[r.type.name].implementation.render)(r.attrs.stringValue, e);
n.contentDOM.appendChild(t), t = n.dom;
} else {
let e = r.type.spec.toDOM(r, !0), n = ie.renderSpec(document, e);
n.contentDOM.appendChild(t), t = n.dom;
}
o.appendChild(t);
} else {
let e = r.serializeFragment(x.from([n]), i);
o.appendChild(e);
}
return o.childNodes.length === 1 && o.firstChild?.nodeType === 1 && Me(o.firstChild), o;
}
function Pe(e, t, n, r, i, a, o, s) {
let c = s?.document ?? document, l = t.pmSchema.nodes.blockContainer, u = n.props || {};
for (let [e, r] of Object.entries(t.schema.blockSchema[n.type].propSchema)) !(e in u) && r.default !== void 0 && (u[e] = r.default);
let d = l.spec?.toDOM?.(l.create({
id: n.id,
...u
})), f = Array.from(d.dom.attributes), p = t.blockImplementations[n.type].implementation, m = p.toExternalHTML?.call({}, {
...n,
props: u
}, t, { nestingLevel: o }) || p.render.call({}, {
...n,
props: u
}, t), h = c.createDocumentFragment();
if (m.dom.classList.contains("bn-block-content")) {
let e = [...f, ...Array.from(m.dom.attributes)].filter((e) => e.name.startsWith("data") && e.name !== "data-content-type" && e.name !== "data-file-block" && e.name !== "data-node-view-wrapper" && e.name !== "data-node-type" && e.name !== "data-id" && e.name !== "data-editable");
for (let t of e) m.dom.firstChild.setAttribute(t.name, t.value);
Me(m.dom.firstChild), o > 0 && m.dom.firstChild.setAttribute("data-nesting-level", o.toString()), h.append(...Array.from(m.dom.childNodes));
} else h.append(m.dom), o > 0 && m.dom.setAttribute("data-nesting-level", o.toString());
if (m.contentDOM) {
if (n.content) {
let e = Ne(t, n.content, r, {
...s,
blockType: n.type
});
m.contentDOM.appendChild(e);
}
let e = t.pmSchema.nodes[n.type];
e?.inlineContent && !e.spec.code && m.contentDOM.childNodes.length === 0 && m.contentDOM.appendChild(c.createTextNode(""));
}
let g;
if (i.has(n.type) ? g = "OL" : a.has(n.type) && (g = "UL"), g) {
if (e.lastChild?.nodeName !== g) {
let t = c.createElement(g);
g === "OL" && "start" in u && u.start && u?.start !== 1 && t.setAttribute("start", String(u.start)), e.append(t);
}
e.lastChild.appendChild(h);
} else e.append(h);
if (n.children && n.children.length > 0) {
let l = c.createDocumentFragment();
if (Fe(l, t, n.children, r, i, a, o + 1, s), e.lastChild?.nodeName === "UL" || e.lastChild?.nodeName === "OL") for (; l.firstChild?.nodeName === "UL" || l.firstChild?.nodeName === "OL";) e.lastChild.lastChild.appendChild(l.firstChild);
"childrenDOM" in m && m.childrenDOM ? m.childrenDOM.append(l) : t.pmSchema.nodes[n.type].isInGroup("blockContent") ? e.append(l) : m.contentDOM?.append(l);
}
}
var Fe = (e, t, n, r, i, a, o = 0, s) => {
for (let c of n) Pe(e, t, c, r, i, a, o, s);
}, Ie = (e, t, n, r, i, a) => {
let o = (a?.document ?? document).createDocumentFragment();
return Fe(o, e, t, n, r, i, 0, a), o;
}, k = (e, t) => {
let n = ie.fromSchema(e);
return {
exportBlocks: (e, r) => {
let i = Ie(t, e, n, /* @__PURE__ */ new Set(["numberedListItem"]), /* @__PURE__ */ new Set([
"bulletListItem",
"checkListItem",
"toggleListItem"
]), r), a = document.createElement("div");
return a.append(i), a.innerHTML;
},
exportInlineContent: (e, r) => {
let i = Ne(t, e, n, r), a = document.createElement("div");
return a.append(i.cloneNode(!0)), a.innerHTML;
}
};
};
//#endregion
//#region src/api/getBlocksChangedByTransaction.ts
function Le(e, t) {
if (t === 0) return;
let r = e.resolve(t);
for (let t = r.depth; t > 0; t--) {
let i = r.node(t);
if (n(i)) return _(i, e);
}
}
function Re(e) {
return e.getMeta("paste") ? { type: "paste" } : e.getMeta("uiEvent") === "drop" ? { type: "drop" } : e.getMeta("history$") ? { type: e.getMeta("history$").redo ? "redo" : "undo" } : e.getMeta("y-sync$") ? e.getMeta("y-sync$").isUndoRedoOperation ? { type: "undo-redo" } : { type: "yjs-remote" } : { type: "local" };
}
function ze(e) {
let t = {}, r = {};
return e.descendants((i, a) => {
if (!n(i)) return !0;
let o = Le(e, a), s = o ?? "__root__";
r[s] || (r[s] = []);
let c = u(i, e), l = _(i, e);
return t[l] = {
block: c,
parentId: o
}, r[s].push(l), !0;
}), {
byId: t,
childrenByParent: r
};
}
function Be(e, t) {
let n = /* @__PURE__ */ new Set();
if (!e || !t) return n;
let r = new Set(e), i = t.filter((e) => r.has(e)), a = e.filter((e) => i.includes(e));
if (a.length <= 1 || i.length <= 1) return n;
let o = {};
for (let e = 0; e < a.length; e++) o[a[e]] = e;
let s = i.map((e) => o[e]), c = s.length, l = [], u = [], d = Array(c).fill(-1), f = (e, t) => {
let n = 0, r = e.length;
for (; n < r;) {
let i = n + r >>> 1;
e[i] < t ? n = i + 1 : r = i;
}
return n;
};
for (let e = 0; e < c; e++) {
let t = s[e], n = f(l, t);
n > 0 && (d[e] = u[n - 1]), n === l.length ? (l.push(t), u.push(e)) : (l[n] = t, u[n] = e);
}
let p = /* @__PURE__ */ new Set(), m = u[u.length - 1] ?? -1;
for (; m !== -1;) p.add(m), m = d[m];
for (let e = 0; e < i.length; e++) p.has(e) || n.add(i[e]);
return n;
}
function Ve(e, t = []) {
let n = Re(e), r = ce(e.before, [e, ...t]), i = ze(r.before), a = ze(r.doc), o = [], s = /* @__PURE__ */ new Set();
Object.keys(a.byId).filter((e) => !(e in i.byId)).forEach((e) => {
o.push({
type: "insert",
block: a.byId[e].block,
source: n,
prevBlock: void 0
}), s.add(e);
}), Object.keys(i.byId).filter((e) => !(e in a.byId)).forEach((e) => {
o.push({
type: "delete",
block: i.byId[e].block,
source: n,
prevBlock: void 0
}), s.add(e);
}), Object.keys(a.byId).filter((e) => e in i.byId).forEach((e) => {
let t = i.byId[e], r = a.byId[e];
t.parentId === r.parentId ? Ee({
...t.block,
children: void 0
}, {
...r.block,
children: void 0
}) || (o.push({
type: "update",
block: r.block,
prevBlock: t.block,
source: n
}), s.add(e)) : (o.push({
type: "move",
block: r.block,
prevBlock: t.block,
source: n,
prevParent: t.parentId ? i.byId[t.parentId]?.block : void 0,
currentParent: r.parentId ? a.byId[r.parentId]?.block : void 0
}), s.add(e));
});
let c = i.childrenByParent, l = a.childrenByParent, u = /* @__PURE__ */ new Set([...Object.keys(c), ...Object.keys(l)]), d = /* @__PURE__ */ new Set();
return u.forEach((e) => {
let t = Be(c[e], l[e]);
t.size !== 0 && t.forEach((t) => {
let r = i.byId[t], c = a.byId[t];
!r || !c || r.parentId === c.parentId && (s.has(t) || (r.parentId ?? "__root__") === e && (d.has(t) || (d.add(t), o.push({
type: "move",
block: c.block,
prevBlock: r.block,
source: n,
prevParent: r.parentId ? i.byId[r.parentId]?.block : void 0,
currentParent: c.parentId ? a.byId[c.parentId]?.block : void 0
}), s.add(t))));
});
}), o;
}
//#endregion
//#region src/extensions/BlockChange/BlockChange.ts
var He = b(() => {
let e = [];
return {
key: "blockChange",
prosemirrorPlugins: [new C({
key: new w("blockChange"),
filterTransaction: (t) => {
let n;
return e.reduce((e, r) => e === !1 ? e : r({
getChanges() {
return n || (n = Ve(t), n);
},
tr: t
}) !== !1, !0);
}
})],
subscribe(t) {
return e.push(t), () => {
e.splice(e.indexOf(t), 1);
};
}
};
});
//#endregion
//#region src/extensions/DropCursor/utils.ts
function Ue(e, t) {
return !e || !t ? !1 : !!e.closest(`.${t}`);
}
function We(e, t, n, r, i) {
let a = e.state.doc.resolve(t.pos);
if (a.parent.inlineContent || t.orientation === "inline") return null;
let o = a.nodeBefore, s = a.nodeAfter;
if (!o && !s) return null;
let c = t.orientation === "block-vertical-left" || t.orientation === "block-vertical-right", l = c ? t.pos : t.pos - (o ? o.nodeSize : 0), u = e.nodeDOM(l);
if (!u) return null;
let d = u.getBoundingClientRect();
if (c) {
let e = n / 2 * r, i = t.orientation === "block-vertical-left" ? d.left : d.right;
return {
left: i - e,
right: i + e,
top: d.top,
bottom: d.bottom
};
}
let f = o ? d.bottom : d.top;
o && s && (f = (f + e.nodeDOM(t.pos).getBoundingClientRect().top) / 2);
let p = n / 2 * i;
return {
left: d.left,
right: d.right,
top: f - p,
bottom: f + p
};
}
function Ge(e, t, n, r) {
let i = e.coordsAtPos(t.pos), a = n / 2 * r;
return {
left: i.left - a,
right: i.left + a,
top: i.top,
bottom: i.bottom
};
}
function Ke(e, t) {
e.classList.toggle("prosemirror-dropcursor-inline", t === "inline"), e.classList.toggle("prosemirror-dropcursor-block-horizontal", t === "block-horizontal"), e.classList.toggle("prosemirror-dropcursor-block-vertical-left", t === "block-vertical-left"), e.classList.toggle("prosemirror-dropcursor-block-vertical-right", t === "block-vertical-right"), e.classList.toggle("prosemirror-dropcursor-block", t === "block-horizontal"), e.classList.toggle("prosemirror-dropcursor-vertical", t === "block-vertical-left" || t === "block-vertical-right");
}
function qe(e) {
if (!e || e === document.body && getComputedStyle(e).position === "static") return {
parentLeft: -window.pageXOffset,
parentTop: -window.pageYOffset
};
let t = e.getBoundingClientRect(), n = t.width / e.offsetWidth, r = t.height / e.offsetHeight;
return {
parentLeft: t.left - e.scrollLeft * n,
parentTop: t.top - e.scrollTop * r
};
}
//#endregion
//#region src/extensions/DropCursor/DropCursor.ts
var Je = "bn-drag-exclude", Ye = b(({ editor: e, options: t }) => {
let n = null, r = null, i = -1, a = null, o = {
width: t.dropCursor?.width ?? 5,
color: t.dropCursor?.color ?? "#ddeeff",
exclude: t.dropCursor?.exclude ?? "bn-drag-exclude",
hooks: t.dropCursor?.hooks
}, s = (e) => {
(e?.pos !== n?.pos || e?.orientation !== n?.orientation) && (n = e, e == null ? (r && r.parentNode && r.parentNode.removeChild(r), r = null) : c());
}, c = () => {
if (!n) return;
let t = e.prosemirrorView, i = t.dom, a = i.getBoundingClientRect(), s = a.width / i.offsetWidth, c = a.height / i.offsetHeight, l = We(t, n, o.width, s, c) ?? Ge(t, n, o.width, s), u = t.dom.offsetParent;
r || (r = u.appendChild(document.createElement("div")), r.style.cssText = "position: absolute; z-index: 50; pointer-events: none;", o.color && (r.style.backgroundColor = o.color)), Ke(r, n.orientation);
let { parentLeft: d, parentTop: f } = qe(u);
r.style.left = (l.left - d) / s + "px", r.style.top = (l.top - f) / c + "px", r.style.width = (l.right - l.left) / s + "px", r.style.height = (l.bottom - l.top) / c + "px";
}, l = (e) => {
clearTimeout(i), i = window.setTimeout(() => s(null), e);
}, u = (e) => {
let t = e;
a = t.target instanceof Element ? t.target : null;
}, d = (t) => {
let n = t;
if (a && Ue(a, o.exclude) || n.target instanceof Element && Ue(n.target, o.exclude)) return;
let r = e.prosemirrorView;
if (!r.editable) return;
let i = r.posAtCoords({
left: n.clientX,
top: n.clientY
}), c = i && i.inside >= 0 && r.state.doc.nodeAt(i.inside), u = c && c.type.spec.disableDropCursor, d = typeof u == "function" ? u(r, i, n) : u;
if (i && !d) {
let t = i.pos;
if (r.dragging && r.dragging.slice) {
let e = se(r.state.doc, t, r.dragging.slice);
e != null && (t = e);
}
let a = !r.state.doc.resolve(t).parent.inlineContent, c = {
pos: t,
orientation: a ? "block-horizontal" : "inline"
}, u = c;
if (o.hooks?.computeDropPosition) {
let t = o.hooks.computeDropPosition({
editor: e,
event: n,
view: r,
defaultPosition: c
});
if (t === null) {
s(null);
return;
}
u = t;
}
s(u), l(5e3);
}
}, f = (t) => {
let n = t;
(!(n.relatedTarget instanceof Node) || !e.prosemirrorView.dom.contains(n.relatedTarget)) && s(null);
}, p = () => {
l(20);
}, m = () => {
l(20), a = null;
};
return {
key: "dropCursor",
mount({ signal: e, dom: t, root: n }) {
n.addEventListener("dragstart", u, {
capture: !0,
signal: e
}), t.addEventListener("dragover", d, { signal: e }), t.addEventListener("dragleave", f, { signal: e }), t.addEventListener("drop", p, { signal: e }), t.addEventListener("dragend", m, { signal: e }), e.addEventListener("abort", () => {
clearTimeout(i), s(null);
});
}
};
}), Xe = b(() => ({
key: "history",
prosemirrorPlugins: [De()],
undoCommand: ke,
redoCommand: Oe
})), Ze = new w("inline-content-boundary-edit");
function Qe(e, t, n) {
if (!e.empty) return e.from <= n.from && e.to >= n.to;
let r = n.to - n.from === 1;
return t === "Backspace" ? r && e.from === n.to : r && e.from === n.from;
}
var $e = b(() => ({
key: "inlineContentBoundaryEdit",
prosemirrorPlugins: [new C({
key: Ze,
props: { handleKeyDown: (e, t) => {
if (!e.editable) return !1;
let n = t.key.length === 1 && !t.ctrlKey && !t.metaKey;
if (!n && t.key !== "Backspace" && t.key !== "Delete") return !1;
let { selection: r } = e.state, i = r.$from.node();
if (!i.type.spec.inline) return !1;
let a = r.$from.before(), o = a + 1, s = a + 1 + i.content.size;
if (n && i.content.size === 0) {
let n = e.state.tr.insert(o, e.state.schema.text(t.key));
return n.setSelection(E.create(n.doc, o + t.key.length)), e.dispatch(n), !0;
}
if (i.content.size > 0 && Qe(r, t.key, {
from: o,
to: s
})) {
let t = e.state.tr.delete(o, s);
return t.setSelection(E.create(t.doc, o)), e.dispatch(t), !0;
}
return !1;
} }
})]
})), et = b(({ editor: e }) => {
function t(t) {
let n = e.prosemirrorView.nodeDOM(t);
for (; n && n.parentElement;) {
if (n.nodeName === "A") return n;
n = n.parentElement;
}
return null;
}
function n(t) {
let n = e.getLinkMarkAtPos(t);
if (n) return {
range: {
from: n.from,
to: n.to
},
mark: { attrs: { href: n.href } },
get text() {
return n.text;
},
get position() {
return le(e.prosemirrorView, n.from, n.to).toJSON();
}
};
}
function r() {
return e.transact((e) => {
if (e.selection.empty) return n(e.selection.anchor);
});
}
return {
key: "linkToolbar",
getLinkAtSelection: r,
getLinkElementAtPos: t,
getMarkAtPos(e, t) {
return n(e);
},
getLinkAtElement(t) {
return e.transact(() => n(e.prosemirrorView.posAtDOM(t, 0) + 1));
},
editLink(t, n, r = e.transact((e) => e.selection.anchor)) {
e.editLink(t, n, r);
},
deleteLink(t = e.transact((e) => e.selection.anchor)) {
e.deleteLink(t);
}
};
}), tt = [
"http",
"https",
"ftp",
"ftps",
"mailto",
"tel",
"callto",
"sms",
"cid",
"xmpp"
], nt = "https", rt = new w("node-selection-keyboard"), it = b(() => ({
key: "nodeSelectionKeyboard",
prosemirrorPlugins: [new C({
key: rt,
props: { handleKeyDown: (e, t) => {
if ("node" in e.state.selection) {
if (t.ctrlKey || t.metaKey) return !1;
if (t.key.length === 1) return t.preventDefault(), !0;
if (t.key === "Enter" && !t.isComposing && !t.shiftKey && !t.altKey && !t.ctrlKey && !t.metaKey) {
let t = e.state.tr;
return e.dispatch(t.insert(e.state.tr.selection.$to.after(), e.state.schema.nodes.paragraph.createChecked()).setSelection(new E(t.doc.resolve(e.state.tr.selection.$to.after() + 1)))), !0;
}
}
return !1;
} }
})]
})), at = new w("blocknote-placeholder"), ot = b(({ editor: e, options: t }) => {
let n = t.placeholders;
return {
key: "placeholder",
prosemirrorPlugins: [new C({
key: at,
view: (t) => {
let r = `placeholder-selector-${ue()}`;
t.dom.classList.add(r);
let i = document.createElement("style"), a = e._tiptapEditor.options.injectNonce;
a && i.setAttribute("nonce", a), t.root instanceof window.ShadowRoot ? t.root.append(i) : t.root.head.appendChild(i);
let o = i.sheet, s = (e = "") => `.${r} .bn-block-content${e}:has(.ProseMirror-trailingBreak:only-child):after`;
try {
let { default: e, emptyDocument: t, ...r } = n || {};
for (let [e, t] of Object.entries(r)) {
let n = `[data-content-type="${e}"]`;
o.insertRule(`${s(n)} { content: ${JSON.stringify(t)}; }`);
}
o.insertRule(`${s("[data-is-only-empty-block]")} { content: ${JSON.stringify(t)}; }`), o.insertRule(`${s("[data-is-empty-and-focused]")} { content: ${JSON.stringify(e)}; }`);
} catch (e) {
console.warn("Failed to insert placeholder CSS rule - this is likely due to the browser not supporting certain CSS pseudo-element selectors (:has, :only-child:, or :before)", e);
}
return { destroy: () => {
t.root instanceof window.ShadowRoot ? t.root.removeChild(i) : t.root.head.removeChild(i);
} };
},
props: { decorations: (t) => {
let { doc: n, selection: r } = t;
if (!e.isEditable || !r.empty || r.$from.parent.type.spec.code) return;
let i = [];
t.doc.content.size === 6 && i.push(D.node(2, 4, { "data-is-only-empty-block": "true" }));
let a = r.$anchor, o = a.parent;
if (o.content.size === 0) {
let e = a.before();
i.push(D.node(e, e + o.nodeSize, { "data-is-empty-and-focused": "true" }));
}
return O.create(n, i);
} }
})]
};
}), st = b(({ editor: e }) => {
let t = new oe(), n = 0;
function r() {
t = new oe(), n = 0;
}
let i = typeof FinalizationRegistry < "u" ? new FinalizationRegistry(() => {
n--, n === 0 && r();
}) : null;
return e.on("create", () => {
e._tiptapEditor.on("transaction", ({ transaction: e }) => {
n !== 0 && t.appendMapping(e.mapping);
}), e._tiptapEditor.on("destroy", () => {
r();
});
}), {
key: "positionMapping",
mapPosition: (e, r = "left") => {
n++;
let a = t.maps.length, o = () => t.slice(a).map(e, r === "left" ? -1 : 1);
return i && i.register(o, void 0), o;
}
};
}), A = new w("previous-blocks"), ct = {
index: "index",
level: "level",
type: "type",
depth: "depth",
"depth-change": "depth-change"
}, lt = b(() => {
let e;
return {
key: "previousBlockType",
prosemirrorPlugins: [new C({
key: A,
view(t) {
return {
update: async (t, n) => {
this.key?.getState(t.state).updatedBlocks.size > 0 && (e = setTimeout(() => {
t.dispatch(t.state.tr.setMeta(A, { clearUpdate: !0 }));
}, 0));
},
destroy: () => {
e && clearTimeout(e);
}
};
},
state: {
init() {
return {
prevTransactionOldBlockAttrs: {},
currentTransactionOldBlockAttrs: {},
updatedBlocks: /* @__PURE__ */ new Set()
};
},
apply(e, t, n, r) {
if (t.currentTransactionOldBlockAttrs = {}, t.updatedBlocks.clear(), !e.docChanged) return t;
let i = e.changedRange();
if (!i) return t;
let a = e.mapping.invert(), o = {
from: a.map(i.from, -1),
to: a.map(i.to, 1)
}, s = {}, c = S(n.doc, o, (e) => e.attrs.id), l = new Map(c.map((e) => [_(e.node, n.doc), e])), u = S(r.doc, i, (e) => e.attrs.id);
for (let e of u) {
let i = _(e.node, r.doc), a = l.get(i), o = a?.node.firstChild, c = e.node.firstChild;
if (a && o && c) {
let l = {
index: c.attrs.index,
level: c.attrs.level,
type: c.type.name,
depth: r.doc.resolve(e.pos).depth
}, u = {
index: o.attrs.index,
level: o.attrs.level,
type: o.type.name,
depth: n.doc.resolve(a.pos).depth
};
s[i] = u, t.currentTransactionOldBlockAttrs[i] = u, (u.index !== l.index || u.level !== l.level || u.type !== l.type || u.depth !== l.depth) && (u["depth-change"] = u.depth - l.depth, t.updatedBlocks.add(i));
}
}
return t.prevTransactionOldBlockAttrs = s, t;
}
},
props: { decorations(e) {
let t = this.getState(e);
if (t.updatedBlocks.size === 0) return;
let n = [];
return e.doc.descendants((r, i) => {
if (!r.attrs.id) return;
let a = _(r, e.doc);
if (!t.updatedBlocks.has(a)) return;
let o = t.currentTransactionOldBlockAttrs[a], s = {};
for (let [e, t] of Object.entries(o)) s["data-prev-" + ct[e]] = t || "none";
n.push(D.node(i, i + r.nodeSize, { ...s }));
}), O.create(e.doc, n);
} }
})]
};
});
//#endregion
//#region src/extensions/getDraggableBlockFromElement.ts
function ut(e, t) {
for (; e && e.parentElement && e.parentElement !== t.dom && e.getAttribute?.("data-node-type") !== "blockContainer";) e = e.parentElement;
if (e.getAttribute?.("data-node-type") === "blockContainer") return {
node: e,
id: e.getAttribute("data-id")
};
}
//#endregion
//#region src/api/exporters/markdown/htmlToMarkdown.ts
function dt(e) {
let t = document.createElement("div");
return t.innerHTML = e, j(t, {
indent: "",
inListItem: !1
}).trim() + "\n";
}
function j(e, t) {
let n = "", r = Array.from(e.childNodes);
for (let e = 0; e < r.length; e++) {
let i = r[e];
n += M(i, t);
}
return n;
}
function M(e, t) {
if (e.nodeType === 3) return e.textContent || "";
if (e.nodeType !== 1) return "";
let n = e;
switch (n.tagName.toLowerCase()) {
case "p": return ft(n, t);
case "h1":
case "h2":
case "h3":
case "h4":
case "h5":
case "h6": return pt(n, t);
case "blockquote": return mt(n, t);
case "pre": return ht(n, t);
case "ul": return bt(n, t);
case "ol": return xt(n, t);
case "table": return wt(n, t);
case "hr": return t.indent + "***\n\n";
case "math": return _t(n, t);
case "img": return Dt(n, t);
case "video": return Ot(n, t);
case "audio": return kt(n, t);
case "embed": return At(n, t);
case "figure": return jt(n, t);
case "a": return I(n, t);
case "details": return Pt(n, t);
case "div": return j(n, t);
case "br": return "";
default: return j(n, t);
}
}
function ft(e, t) {
let n = Ft(R(e));
return t.inListItem ? n : t.indent + n + "\n\n";
}
function pt(e, t) {
let n = parseInt(e.tagName[1], 10), r = "#".repeat(n) + " ", i = R(e);
return t.indent + r + i + "\n\n";
}
function mt(e, t) {
let n = Array.from(e.children).filter((e) => {
let t = e.tagName.toLowerCase();
return [
"p",
"ul",
"ol",
"pre",
"blockquote",
"table",
"hr"
].includes(t);
}), r;
if (n.length > 0) {
let e = [];
for (let t of n) t.tagName.toLowerCase() === "p" ? e.push(R(t)) : e.push(M(t, {
indent: "",
inListItem: !1
}).trim());
r = e.join("\n\n");
} else r = R(e);
return r.split("\n").map((e) => t.indent + "> " + e).join("\n") + "\n\n";
}
function ht(e, t) {
let n = e.querySelector("code");
if (!n) return "";
let r = n.getAttribute("data-language") || yt(n.className) || "", i = vt(n), a = Math.max(0, ...(i.match(/`+/g) ?? []).map((e) => e.length)), o = "`".repeat(Math.max(3, a + 1));
return i ? [
o + r,
...(i.endsWith("\n") ? i.slice(0, -1) : i).split("\n"),
o
].map((e) => e && t.indent + e).join("\n") + "\n\n" : t.indent + o + r + "\n" + t.indent + o + "\n\n";
}
function gt(e) {
return (e.querySelector("annotation[encoding=\"application/x-tex\"]")?.textContent ?? e.textContent ?? "").trim();
}
function _t(e, t) {
return [
"$$",
...gt(e).split("\n"),
"$$"
].map((e) => e && t.indent + e).join("\n") + "\n\n";
}
function vt(e) {
let t = "";
for (let n of Array.from(e.childNodes)) n.nodeType === 3 ? t += n.textContent || "" : n.nodeType === 1 && (n.tagName.toLowerCase() === "br" ? t += "\n" : t += vt(n));
return t;
}
function yt(e) {
let t = e.match(/language-(\S+)/);
return t ? t[1] : "";
}
function bt(e, t) {
let n = "", r = Array.from(e.children).filter((e) => e.tagName.toLowerCase() === "li");
for (let e of r) n += St(e, "bullet", t);
return t.inListItem || (n += "\n"), n;
}
function xt(e, t) {
let n = "", r = Array.from(e.children).filter((e) => e.tagName.toLowerCase() === "li"), i = parseInt(e.getAttribute("start") || "1", 10);
for (let e = 0; e < r.length; e++) {
let a = i + e;
n += St(r[e], "ordered", t, a);
}
return t.inListItem || (n += "\n"), n;
}
function St(e, t, n, r) {
let i = null, a = null;
for (let t of Array.from(e.children)) {
let e = t.tagName.toLowerCase();
e === "input" && t.type === "checkbox" && (i = t), e === "details" && (a = t);
}
let o, s;
i ? (o = `* ${i.checked ? "[x]" : "[ ]"} `, s = 2) : t === "ordered" ? (o = `${r}. `, s = o.length) : (o = "* ", s = 2);
let c, l;
if (a) {
let e = a.querySelector("summary")?.querySelector("p");
l = a, c = e ? R(e) : "";
} else l = Ct(e, i), c = l ? R(l) : "";
let u = n.indent + o + c + "\n", d = n.indent + " ".repeat(s), f = {
indent: d,
inListItem: !0
};
if (a) {
let e = a.querySelector("summary");
for (let t of Array.from(a.children)) if (t !== e) {
if (t.tagName.toLowerCase() === "p") {
let e = R(t);
u += "\n" + d + e + "\n";
} else u += M(t, f);
}
}
let p = Array.from(e.children);
for (let e of p) {
let t = e.tagName.toLowerCase();
if (e !== l && e !== i && t !== "input") {
if (t === "ul" || t === "ol") u += M(e, f);
else if (t === "p") {
let t = R(e);
u += "\n" + d + t + "\n";
} else u += "\n" + M(e, f);
}
}
return u;
}
function Ct(e, t) {
for (let n of Array.from(e.children)) {
if (n === t || n.tagName.toLowerCase() === "input") continue;
let e = n.tagName.toLowerCase();
if (e === "p" || e === "span") return n;
}
return null;
}
function wt(e, t) {
let n = e.querySelector("colgroup"), r = 0;
n && (r = n.querySelectorAll("col").length);
let i = [], a = !1, o = e.querySelectorAll("tr"), s = [];
o.forEach((e, t) => {
s[t] || (s[t] = []);
let n = e.querySelectorAll("th, td"), i = 0;
n.forEach((e) => {
for (; s[t][i] !== void 0;) i++;
t === 0 && e.tagName.toLowerCase() === "th" && (a = !0);
let n = Tt(R(e).trim()), r = parseInt(e.getAttribute("colspan") || "1", 10), o = parseInt(e.getAttribute("rowspan") || "1", 10);
for (let e = 0; e < o; e++) for (let a = 0; a < r; a++) {
let r = t + e;
s[r] || (s[r] = []), s[r][i + a] = e === 0 && a === 0 ? n : "";
}
i += r;
}), s[t] && (r = Math.max(r, s[t].length));
});
for (let e of s) {
let t = [];
for (let n = 0; n < r; n++) t.push(e && e[n] !== void 0 ? e[n] ?? "" : "");
i.push(t);
}
if (i.length === 0) return "";
let c = [];
for (let e = 0; e < r; e++) {
let t = 3;
for (let n of i) {
let r = e < n.length ? n[e].length : 0;
t = Math.max(t, r);
}
c.push(Math.max(t, 10));
}
let l = "";
if (a) {
l += t.indent + N(i[0], c, r) + "\n", l += t.indent + Et(c, r) + "\n";
for (let e = 1; e < i.length; e++) l += t.indent + N(i[e], c, r) + "\n";
} else {
let e = Array(r).fill("");
l += t.indent + N(e, c, r) + "\n", l += t.indent + Et(c, r) + "\n";
for (let e of i) l += t.indent + N(e, c, r) + "\n";
}
return l += "\n", l;
}
function Tt(e) {
return e.replace(/\|/g, "\\|");
}
function N(e, t, n) {
let r = [];
for (let i = 0; i < n; i++) {
let n = i < e.length ? e[i] : "";
r.push(" " + n.padEnd(t[i]) + " ");
}
return "|" + r.join("|") + "|";
}
function Et(e, t) {
let n = [];
for (let r = 0; r < t; r++) n.push(" " + "-".repeat(e[r]) + " ");
return "|" + n.join("|") + "|";
}
function Dt(e, t) {
let n = e.getAttribute("src") || "", r = e.getAttribute("alt") || "";
return n ? t.indent + `\n\n` : "\n\n";
}
function Ot(e, t) {
let n = e.getAttribute("src") || e.getAttribute("data-url") || "", r = e.getAttribute("data-name") || e.getAttribute("title") || "";
return n ? t.indent + `\n\n` : "\n\n";
}
function kt(e, t) {
let n = e.getAttribute("src") || "";
return n ? t.indent + `<audio src="${F(n)}" controls></audio>\n\n` : "\n\n";
}
function At(e, t) {
let n = e.getAttribute("src") || "";
return n ? t.indent + `[](${n})\n\n` : "\n\n";
}
function jt(e, t) {
let n = e.querySelector("img"), r = e.querySelector("video"), i = e.querySelector("audio"), a = e.querySelector("a"), o = e.querySelector("figcaption")?.textContent?.trim() || "";
return n ? P("img", n.getAttribute("src") || "", n.getAttribute("alt") || "", o, t) : r ? P("video", r.getAttribute("src") || r.getAttribute("data-url") || "", r.getAttribute("data-name") || r.getAttribute("title") || "", o, t) : i ? P("audio", i.getAttribute("src") || "", "", o, t) : a ? I(a, t) : "";
}
function P(e, t, n, r, i) {
if (!t) return "";
if (!r && e !== "audio") return i.indent + `\n\n`;
let a = n && n !== r ? e === "img" ? ` alt="${F(n)}"` : e === "video" ? ` data-name="${F(n)}"` : "" : "", o = e === "img" ? `<img${a} src="${F(t)}">` : `<${e} src="${F(t)}"${a} controls></${e}>`, s = r ? `<figcaption>${Mt(r)}</figcaption>` : "";
return i.indent + `<figure>${o}${s}</figure>\n\n`;
}
function F(e) {
return e.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
}
function Mt(e) {
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
}
function I(e, t) {
let n = e.getAttribute("href") || "", r = e.textContent?.trim() || "";
return n ? t.indent + L(r, n) + "\n\n" : t.indent + r + "\n\n";
}
function L(e, t) {
return !e || e === t ? t : `[${e}](${Nt(t)})`;
}
function Nt(e) {
return e.replace(/[\\()]/g, "\\$&");
}
function Pt(e, t) {
let n = e.querySelector("summary");
if (!n) return j(e, t);
let r = n.querySelector("h1, h2, h3, h4, h5, h6");
if (r) {
let i = pt(r, t);
for (let r of Array.from(e.children)) r !== n && (i += M(r, t));
return i;
}
return j(n, t);
}
function R(e) {
let t = "";
for (let n of Array.from(e.childNodes)) if (n.nodeType === 3) t += n.textContent || "";
else if (n.nodeType === 1) {
let e = n;
switch (e.tagName.toLowerCase()) {
case "strong":
case "b": {
let { content: n, trailing: r } = z(R(e));
t += n ? `**${n}**${r}` : r;
break;
}
case "em":
case "i": {
let { content: n, trailing: r } = z(R(e));
t += n ? `*${n}*${r}` : r;
break;
}
case "s":
case "del":
t += `~~${R(e)}~~`;
break;
case "code": {
let n = e.textContent || "", r = Math.max(0, ...(n.match(/`+/g) ?? []).map((e) => e.length)), i = "`".repeat(r + 1), a = n.startsWith("`") || n.endsWith("`");
t += i + (a ? ` ${n} ` : n) + i;
break;
}
case "u":
t += R(e);
break;
case "a": {
let n = e.getAttribute("href") || "", r = R(e);
t += L(r, n);
break;
}
case "br":
t += "\\\n";
break;
case "math": {
let n = gt(e).split("\n").map((e) => e.trim()).join(" ");
t += `$${n}$`;
break;
}
case "span":
t += R(e);
break;
case "img": {
let n = e.getAttribute("src") || "", r = e.getAttribute("alt") || "";
t += ``;
break;
}
case "video": {
let n = e.getAttribute("src") || e.getAttribute("data-url") || "", r = e.getAttribute("data-name") || e.getAttribute("title") || "";
t += ``;
break;
}
case "p":
t += R(e);
break;
case "input": break;
default: t += R(e);
}
}
return t;
}
function z(e) {
let t = e.match(/^(.*?)(\s*)$/);
return t ? {
content: t[1],
trailing: t[2]
} : {
content: e,
trailing: ""
};
}
function Ft(e) {
let t = e.replace(/^(\\\n)+/, "");
return t = t.replace(/(\\\n)+$/, ""), t;
}
//#endregion
//#region src/api/exporters/markdown/markdownExporter.ts
function B(e) {
return dt(e.split("").join(""));
}
function It(e, t, n, r) {
return B(k(t, n).exportBlocks(e, r));
}
//#endregion
//#region src/api/nodeConversions/fragmentToBlocks.ts
function Lt(e) {
let t = [];
return e.descendants((e) => e.type.name === "blockContainer" && e.firstChild?.type.name === "blockGroup" ? !0 : e.type.name === "columnList" && e.childCount === 1 ? (e.firstChild?.forEach((n) => {
t.push(u(n, e));
}), !1) : !e.type.isInGroup("bnBlock") || (t.push(u(e, e)), !1)), t;
}
//#endregion
//#region src/extensions/SideMenu/MultipleNodeSelection.ts
var V = class e extends T {
nodes;
constructor(e, t) {
super(e, t);
let n = e.node();
this.nodes = [], e.doc.nodesBetween(e.pos, t.pos, (e, t, r) => {
if (r !== null && r.eq(n)) return this.nodes.push(e), !1;
});
}
static create(t, n, r = n) {
return new e(t.resolve(n), t.resolve(r));
}
content() {
return new ae(x.from(this.nodes), 0, 0);
}
eq(t) {
if (!(t instanceof e) || this.nodes.length !== t.nodes.length || this.from !== t.from || this.to !== t.to) return !1;
for (let e = 0; e < this.nodes.length; e++) if (!this.nodes[e].eq(t.nodes[e])) return !1;
return !0;
}
map(t, n) {
let r = n.mapResult(this.from), i = n.mapResult(this.to);
return i.deleted ? T.near(t.resolve(r.pos)) : r.deleted ? T.near(t.resolve(i.pos)) : new e(t.resolve(r.pos), t.resolve(i.pos));
}
toJSON() {
return {
type: "multiple-node",
anchor: this.anchor,
head: this.head
};
}
};
T.jsonID("multiple-node", V);
//#endregion
//#region src/extensions/SideMenu/dragging.ts
var H;
function Rt(e, t) {
let n, r, i = t.resolve(e.from).node().type.spec.group === "blockContent", a = t.resolve(e.to).node().type.spec.group === "blockContent", o = Math.min(e.$anchor.depth, e.$head.depth);
if (i && a) {
let i = e.$from.start(o - 1), a = e.$to.end(o - 1);
n = t.resolve(i - 1).pos, r = t.resolve(a + 1).pos;
} else n = e.from, r = e.to;
return {
from: n,
to: r
};
}
function zt(e, t, n = t) {
t === n && (n += e.state.doc.resolve(t + 1).node().nodeSize);
let r = e.domAtPos(t).node.cloneNode(!0), i = e.domAtPos(t).node, a = (e, t) => Array.prototype.indexOf.call(e.children, t), o = a(i, e.domAtPos(t + 1).node.parentElement), s = a(i, e.domAtPos(n - 1).node.parentElement);
for (let e = i.childElementCount - 1; e >= 0; e--) (e > s || e < o) && r.removeChild(r.children[e]);
Bt(e.root), H = r, H.querySelectorAll("iframe, embed, object").forEach((e) => e.parentElement?.removeChild(e));
let c = e.dom.className.split(" ").filter((e) => e !== "ProseMirror" && e !== "bn-root" && e !== "bn-editor").join(" ");
H.className = H.className + " bn-drag-preview " + c, e.root instanceof ShadowRoot ? e.root.appendChild(H) : e.root.body.appendChild(H);
}
function Bt(e) {
H !== void 0 && (e instanceof ShadowRoot ? e.removeChild(H) : e.body.removeChild(H), H = void 0);
}
function Vt(e, t, n) {
if (!e.dataTransfer || n.headless) return;
let r = n.prosemirrorView, i = c(t.id, r.state.doc);
if (!i) throw Error(`Block with ID ${t.id} not found`);
let a = i.posBeforeNode;
if (a != null) {
let t = r.state.selection, i = r.state.doc, { from: o, to: s } = Rt(t, i), c = o <= a && a < s, l = t.$anchor.node() !== t.$head.node() || t instanceof V;
c && l ? (r.dispatch(r.state.tr.setSelection(V.create(i, o, s))), zt(r, o, s)) : (r.dispatch(r.state.tr.setSelection(de.create(r.state.doc, a))), zt(r, a));
let u = r.state.selection.content(), d = n.pmSchema, f = r.serializeForClipboard(u).dom.innerHTML, p = k(d, n), m = Lt(u.content), h = p.exportBlocks(m, {}), g = B(h);
e.dataTransfer.clearData(), e.dataTransfer.setData("blocknote/html", f), e.dataTransfer.setData("text/html", h), e.dataTransfer.setData("text/plain", g), e.dataTransfer.effectAllowed = "move", e.dataTransfer.setDragImage(H, 0, 0);
}
}
//#endregion
//#region src/extensions/SideMenu/SideMenu.ts
var Ht = 250;
function U(e, t, n = !0) {
let r = e.root.elementsFromPoint(t.left, t.top);
for (let i of r) if (e.dom.contains(i)) return n && i.closest("[data-node-type=columnList]") ? U(e, {
left: t.left + 50,
top: t.top
}, !1) : ut(i, e);
}
function Ut(e, t) {
if (!t.dom.firstChild) return;
let n = t.dom.firstChild.getBoundingClientRect(), r = U(t, {
left: Math.min(Math.max(n.left + 10, e.x), n.right - 10),
top: e.y
});
if (r) return U(t, {
left: r.node.getBoundingClientRect().right - 10,
top: e.y
}, !1);
}
var Wt = class {
editor;
pmView;
state;
emitUpdate;
mousePos;
hoveredBlock;
menuFrozen = !1;
isDragOrigin = !1;
constructor(e, t, n) {
this.editor = e, this.pmView = t, this.emitUpdate = () => {
if (!this.state) throw Error("Attempting to update uninitialized side menu");
n(this.state);
}, this.pmView.root.addEventListener("dragstart", this.onDragStart), this.pmView.root.addEventListener("dragover", this.onDragOver), this.pmView.root.addEventListener("drop", this.onDrop, !0), this.pmView.root.addEventListener("dragend", this.onDragEnd, !0), this.pmView.root.addEventListener("mousemove", this.onMouseMove, !0), this.pmView.root.addEventListener("keydown", this.onKeyDown, !0);
}
updateState = (e) => {
this.state = e, this.emitUpdate(this.state);
};
updateStateFromMousePos = () => {
if (this.menuFrozen || !this.mousePos) return;
let e = this.findClosestEditorElement({
clientX: this.mousePos.x,
clientY: this.mousePos.y
});
if (e?.element !== this.pmView.dom || e.distance > Ht) {
this.state?.show && (this.state.show = !1, this.updateState(this.state));
return;
}
let t = Ut(this.mousePos, this.pmView);
if (!t || !this.editor.isEditable) {
this.state?.show && (this.state.show = !1, this.updateState(this.state));
return;
}
if (!(this.state?.show && this.hoveredBlock?.hasAttribute("data-id") && this.hoveredBlock?.getAttribute("data-id") === t.id) && (this.hoveredBlock = t.node, this.editor.isEditable)) {
let e = t.node.getBoundingClientRect(), n = t.node.closest("[data-node-type=column]"), r = this.editor.getBlock(this.hoveredBlock.getAttribute("data-id"));
if (!r) {
this.state?.show && (this.state.show = !1, this.hoveredBlock = void 0, this.emitUpdate(this.state));
return;
}
this.state = {
show: !0,
referencePos: new DOMRect(n ? n.firstElementChild.getBoundingClientRect().x : this.pmView.dom.firstChild.getBoundingClientRect().x, e.y, e.width, e.height),
block: r
}, this.updateState(this.state);
}
};
onDragStart = (e) => {
let t = e.dataTransfer?.getData("blocknote/html");
if (!t || this.pmView.dragging) return;
let n = document.createElement("div");
n.innerHTML = t;
let r = fe.fromSchema(this.pmView.state.schema).parse(n, { topNode: this.pmView.state.schema.nodes.blockGroup.create() });
this.pmView.dragging = {
slice: new pe(r.content, 0, 0),
move: !0
};
};
findClosestEditorElement = (e) => {
let t = Array.from(this.pmView.root.querySelectorAll(".bn-editor"));
if (t.length === 0) return null;
let n = t[0], r = Number.MAX_VALUE;
return t.forEach((t) => {
let i = t.querySelector(".bn-block-group").getBoundingClientRect(), a = e.clientX < i.left ? i.left - e.clientX : e.clientX > i.right ? e.clientX - i.right : 0, o = e.clientY < i.top ? i.top - e.clientY : e.clientY > i.bottom ? e.clientY - i.bottom : 0, s = Math.sqrt(a ** 2 + o ** 2);
s < r && (r = s, n = t);
}), {
element: n,
distance: r
};
};
onDragOver = (e) => {
if (e.synthetic || !(this.pmView.dragging !== null || this.isDragOrigin || e.dataTransfer?.types.includes("blocknote/html") || e.target instanceof Node && this.pmView.dom.contains(e.target))) return;
let t = this.getDragEventContext(e);
if (!t || !t.isDropPoint) {
this.closeDropCursor();
return;
}
t.isDropPoint && !t.isDropWithinEditorBounds && this.dispatchSyntheticEvent(e);
};
closeDropCursor = () => {
let e = new Event("dragleave", { bubbles: !1 });
e.synthetic = !0, this.pmView.dom.dispatchEvent(e);
};
getDragEventContext = (e) => {
if (!(this.pmView.dragging !== null || this.isDragOrigin || e.dataTransfer?.types.includes("blocknote/html") || e.target instanceof Node && this.pmView.dom.contains(e.target))) return;
let t = !e.dataTransfer?.types.includes("blocknote/html") && !!this.pmView.dragging, n = !!this.isDragOrigin, r = t || n, i = this.findClosestEditorElement(e);
if (!i || i.distance > Ht) return;
let a = i.element === this.pmView.dom, o = a && i.distance === 0;
if (!(!a && !r)) return {
isDropPoint: a,
isDropWithinEditorBounds: o,
isDragOrigin: r
};
};
onDrop = (e) => {
if (e.synthetic || !(this.pmView.dragging !== null || this.isDragOrigin || e.dataTransfer?.types.includes("blocknote/html") || e.target instanceof Node && this.pmView.dom.contains(e.target))) return;
let t = this.getDragEventContext(e);
if (!t) {
this.closeDropCursor();
return;
}
let { isDropPoint: n, isDropWithinEditorBounds: r, isDragOrigin: i } = t;
if (!r && n && this.dispatchSyntheticEvent(e), n) {
if (this.pmView.dragging) return;
this.pmView.dispatch(this.pmView.state.tr.setSelection(Te.create(this.pmView.state.tr.doc, this.pmView.state.tr.selection.anchor)));
return;
}
if (i) {
setTimeout(() => this.pmView.dispatch(this.pmView.state.tr.deleteSelection()), 0);
return;
}
};
onDragEnd = (e) => {
e.synthetic || (this.pmView.dragging = null);
};
onKeyDown = (e) => {
this.state?.show && this.editor.isFocused() && (this.state.show = !1, this.emitUpdate(this.state));
};
onMouseMove = (e) => {
if (this.menuFrozen || !Number.isFinite(e.clientX) || !Number.isFinite(e.clientY)) return;
this.mousePos = {
x: e.clientX,
y: e.clientY
};
let t = this.pmView.dom.getBoundingClientRect();
if (this.mousePos.x > t.left && this.mousePos.x < t.right && this.mousePos.y > t.top && this.mousePos.y < t.bottom && e && e.target && !this.editor.isWithinEditor(e.target)) {
this.state?.show && (this.state.show = !1, this.emitUpdate(this.state));
return;
}
this.updateStateFromMousePos();
};
dispatchSyntheticEvent(e) {
let t = new Event(e.type, e), n = this.pmView.dom.firstChild.getBoundingClientRect();
t.clientX = e.clientX, t.clientY = e.clientY, t.clientX = Math.min(Math.max(e.clientX, n.left), n.left + n.width), t.clientY = Math.min(Math.max(e.clientY, n.top), n.top + n.height), t.dataTransfer = e.dataTransfer, t.preventDefault = () => e.preventDefault(), t.synthetic = !0, this.pmView.dom.dispatchEvent(t);
}
update(e, t) {
!t.doc.eq(this.pmView.state.doc) && this.state?.show && this.updateStateFromMousePos();
}
destroy() {
this.state?.show && (this.state.show = !1, this.emitUpdate(this.state)), this.pmView.root.removeEventListener("mousemove", this.onMouseMove, !0), this.pmView.root.removeEventListener("dragstart", this.onDragStart), this.pmView.root.removeEventListener("dragover", this.onDragOver), this.pmView.root.removeEventListener("drop", this.onDrop, !0), this.pmView.root.removeEventListener("dragend", this.onDragEnd, !0), this.pmView.root.removeEventListener("keydown", this.onKeyDown, !0);
}
}, Gt = new we("SideMenuPlugin"), Kt = b(({ editor: e }) => {
let t, n = y(void 0);
return {
key: "sideMenu",
store: n,
prosemirrorPlugins: [new Ce({
key: Gt,
view: (r) => (t = new Wt(e, r, (e) => {
n.setState({ ...e });
}), t)
})],
blockDragStart(n, r) {
t && (t.isDragOrigin = !0), Vt(n, r, e);
},
blockDragEnd() {
Bt(e.prosemirrorView.root), t && (t.isDragOrigin = !1), e.blur();
},
get menuFrozen() {
return t.menuFrozen;
},
freezeMenu() {
t.menuFrozen = !0, t.state.show = !0, t.emitUpdate(t.state);
},
unfreezeMenu() {
t.menuFrozen = !1, t.state.show = !1, t.emitUpdate(t.state);
},
hideMenuIfNotFrozen() {
!t.menuFrozen && t.state?.show && (t.state.show = !1, t.emitUpdate(t.state));
}
};
}), qt = b(({ editor: e }) => {
let t = y({
popupOpen: void 0,
selected: void 0
}), n = (t) => !!e.schema.blockSpecs[t.type]?.implementation?.meta?.hasPreview, r = (e) => ({ editor: r }) => {
let { block: i, prevBlock: a, nextBlock: o } = r.getTextCursorPosition();
if (!n(i) || t.state.popupOpen === i.id) return !1;
let s = e === "prev" ? a : o;
return s ? (r.setTextCursorPosition(s.id, e === "prev" ? "end" : "start"), !0) : !1;
};
return {
key: "sourceBlockWithPreview",
store: t,
keyboardShortcuts: {
Enter: ({ editor: e }) => {
let { block: r } = e.getTextCursorPosition();
if (!n(r)) return !1;
if (t.state.popupOpen === r.id && e.schema.blockSpecs[r.type]?.implementation?.meta?.hardBreakShortcut === "enter") {
let t = e.prosemirrorView;
return t.dispatch(t.state.tr.insertText("\n")), !0;
}
return e.setTextCursorPosition(r.id, "end"), t.setState((e) => ({
...e,
popupOpen: t.state.popupOpen === r.id ? void 0 : r.id
})), !0;
},
Escape: ({ editor: e }) => {
let { block: r } = e.getTextCursorPosition();
return !n(r) || t.state.popupOpen !== r.id ? !1 : (e.setTextCursorPosition(r.id, "end"), t.setState((e) => ({
...e,
popupOpen: void 0
})), !0);
},
"Mod-a": ({ editor: e }) => {
let { block: r } = e.getTextCursorPosition();
if (!n(r) || t.state.popupOpen !== r.id) return !1;
let i = e.prosemirrorView, { $from: a } = i.state.selection;
return a.parent.type.name === r.type && (i.dispatch(i.state.tr.setSelection(E.create(i.state.doc, a.start(), a.end()))), !0);
},
ArrowUp: r("prev"),
ArrowLeft: r("prev"),
ArrowDown: r("next"),
ArrowRight: r("next")
},
mount: ({ dom: r, signal: i }) => {
let a = e.onSelectionChange(() => {
let { block: r } = e.getTextCursorPosition(), i = n(r) ? r.id : void 0, a = t.state.popupOpen && t.state.popupOpen !== r.id ? void 0 : t.state.popupOpen;
(i !== t.state.selected || a !== t.state.popupOpen) && t.setState((e) => ({
...e,
selected: i,
popupOpen: a
}));
});
i.addEventListener("abort", a), r.addEventListener("keydown", (r) => {
if (!e.isEditable) return;
let { block: i } = e.getTextCursorPosition();
if (!(!n(i) || t.state.popupOpen === i.id)) {
if (r.key === "Backspace" || r.key === "Delete") {
r.preventDefault(), r.stopImmediatePropagation(), e.removeBlocks([i.id]);
return;
}
(r.key.length === 1 && !r.ctrlKey && !r.metaKey || r.key === "Tab") && (r.preventDefault(), r.stopImmediatePropagation());
}
}, {
capture: !0,
signal: i
}), r.addEventListener("blur", () => t.setState((e) => ({
...e,
popupOpen: void 0
})), {
capture: !0,
signal: i
});
}
};
}), Jt = b(({ editor: e }) => {
let t = y({ selected: void 0 }), n = (t) => !!e.schema.inlineContentSpecs[t]?.implementation?.meta?.hasPreview, r = (e) => ({ editor: t }) => {
let { $from: r } = t.prosemirrorState.selection, i = r.node();
if (!n(i.type.name)) return !1;
let a = t.prosemirrorView, o = T.near(a.state.doc.resolve(e === "before" ? r.before() : r.after()), e === "before" ? -1 : 1);
return a.dispatch(a.state.tr.setSelection(o)), !0;
};
return {
key: "sourceInlineContentWithPreview",
store: t,
keyboardShortcuts: {
Enter: r("after"),
"Shift-Enter": r("after"),
Escape: r("after"),
ArrowUp: r("before"),
ArrowDown: r("after"),
"Mod-a": ({ editor: e }) => {
let { $from: t } = e.prosemirrorState.selection;
if (!n(t.node().type.name)) return !1;
let r = e.prosemirrorView;
return r.dispatch(r.state.tr.setSelection(E.create(r.state.doc, t.start(), t.end()))), !0;
}
},
mount: ({ dom: r, signal: i }) => {
let a = e.onSelectionChange(() => {
let { $from: r } = e.prosemirrorState.selection, i = r.node();
t.setState({ selected: n(i.type.name) ? r.before() : void 0 });
});
i.addEventListener("abort", a), r.addEventListener("keydown", (t) => {
if (t.key !== "ArrowUp" && t.key !== "ArrowDown") return;
let { $from: i } = e.prosemirrorState.selection;
n(i.node().type.name) || (r.classList.add("bn-suppress-source-popup-caret"), requestAnimationFrame(() => r.classList.remove("bn-suppress-source-popup-caret")));
}, {
capture: !0,
signal: i
}), r.addEventListener("blur", () => t.setState({ selected: void 0 }), {
capture: !0,
signal: i
});
}
};
}), Yt = Symbol.for("blocknote.shikiParser"), W = Symbol.for("blocknote.shikiHighlighterPromise"), Xt = [
"text",
"none",
"plaintext",
"txt"
];
function Zt(e, t, n) {
let r = globalThis, i, a, o = /* @__PURE__ */ new Set();
return Ae({
parser: (t) => {
if (!e.createHighlighter) return [];
if (!i) return r[W] = r[W] || e.createHighlighter(), r[W].then((e) => {
i = e;
});
let n = t.language;
return !n || Xt.includes(n) || o.has(n) ? [] : i.getLoadedLanguages().includes(n) ? (a || (a = r[Yt] || je(i, Qt(i)), r[Yt] = a), a(t)) : i.loadLanguage(n).catch(() => {
o.add(n);
});
},
languageExtractor: (e) => {
let t = {
type: e.type.name,
props: e.attrs
};
return (n.blockSpecs[t.type] || n.inlineContentSpecs[t.type])?.implementation?.meta?.highlight?.(t) ?? void 0;
},
nodeTypes: t
});
}
function Qt(e) {
let t = e.getLoadedThemes(), n = t.find((e) => /light/i.test(e)), r = t.find((e) => /dark/i.test(e));
if (n && r) return {
themes: {
light: n,
dark: r
},
defaultColor: !1
};
}
//#endregion
//#region src/extensions/SyntaxHighlighting/SyntaxHighlighting.ts
function $t(e) {
let t = Object.values(e.blockSpecs).filter((e) => typeof e?.config == "object" && e.config.content === "plain" && !!e.implementation?.meta?.highlight).map((e) => e.config.type), n = Object.values(e.inlineContentSpecs).filter((e) => typeof e?.config == "object" && e.config.content === "plain" && !!e.implementation?.meta?.highlight).map((e) => e.config.type);
return [...t, ...n];
}
var en = b(({ editor: e, options: t }) => ({
key: "syntaxHighlighting",
prosemirrorPlugins: [Zt(t, $t(e.schema), e.schema)]
})), G;
async function tn() {
return G || (G = (async () => {
let [e, t] = await Promise.all([import("emoji-mart"), import("@emoji-mart/data")]), n = "default" in e ? e.default : e, r = "default" in t ? t.default : t;
return await n.init({ data: r }), {
emojiMart: n,
emojiData: r
};
})(), G);
}
async function nn(e, t) {
if (!("text" in e.schema.inlineContentSchema) || e.schema.inlineContentSchema.text !== te.text) return [];
let { emojiData: n, emojiMart: r } = await tn();
return (t.trim() === "" ? Object.values(n.emojis) : await r.SearchIndex.search(t)).map((t) => ({
id: t.skins[0].native,
onItemClick: () => e.insertInlineContent(t.skins[0].native + " ")
}));
}
//#endregion
//#region src/extensions/TableHandles/TableHandles.ts
var K;
function rn(e) {
K || (K = document.createElement("div"), K.innerHTML = "_", K.style.opacity = "0", K.style.height = "1px", K.style.width = "1px", e instanceof Document ? e.body.appendChild(K) : e.appendChild(K));
}
function an(e) {
K &&= (e instanceof Document ? e.body.removeChild(K) : e.removeChild(K), void 0);
}
function q(e) {
return Array.prototype.indexOf.call(e.parentElement.childNodes, e);
}
function on(e) {
let t = e;
for (; t && t.nodeName !== "TD" && t.nodeName !== "TH" && !t.classList.contains("tableWrapper");) {
if (t.classList.contains("ProseMirror")) return;
let e = t.parentNode;
if (!e || !(e instanceof Element)) return;
t = e;
}
return t.nodeName === "TD" || t.nodeName === "TH" ? {
type: "cell",
domNode: t,
tbodyNode: t.closest("tbody")
} : {
type: "wrapper",
domNode: t,
tbodyNode: t.querySelector("tbody")
};
}
function sn(e, t) {
let n = t.querySelectorAll(e);
for (let e = 0; e < n.length; e++) n[e].style.visibility = "hidden";
}
var cn = class {
editor;
pmView;
state;
emitUpdate;
tableId;
tablePos;
tableElement;
menuFrozen = !1;
mouseState = "up";
prevWasEditable = null;
constructor(e, t, n) {
this.editor = e, this.pmView = t, this.emitUpdate = () => {
n(this.state);
}, t.dom.addEventListener("mousemove", this.mouseMoveHandler), t.dom.addEventListener("mousedown", this.viewMousedownHandler), window.addEventListener("mouseup", this.mouseUpHandler), t.root.addEventListener("dragover", this.dragOverHandler), t.root.addEventListener("drop", this.dropHandler);
}
viewMousedownHandler = () => {
this.mouseState = "down";
};
mouseUpHandler = (e) => {
this.mouseState = "up", this.mouseMoveHandler(e);
};
mouseMoveHandler = (e) => {
if (this.menuFrozen || this.mouseState === "selecting" || !(e.target instanceof Element) || !this.pmView.dom.contains(e.target)) return;
let t = on(e.target);
if (t?.type === "cell" && this.mouseState === "down" && !this.state?.draggingState) {
this.mouseState = "selecting", this.state?.show && (this.state.show = !1, this.state.showAddOrRemoveRowsButton = !1, this.state.showAddOrRemoveColumnsButton = !1, this.emitUpdate());
return;
}
if (!t || !this.editor.isEditable) {
this.state?.show && (this.state.show = !1, this.state.showAddOrRemoveRowsButton = !1, this.state.showAddOrRemoveColumnsButton = !1, this.emitUpdate());
return;
}
if (!t.tbodyNode) return;
let n = t.tbodyNode.getBoundingClientRect(), r = ut(t.domNode, this.pmView);
if (!r) return;
this.tableElement = r.node;
let i, { pmNodeInfo: a, doc: o } = this.editor.transact((e) => ({
pmNodeInfo: c(r.id, e.doc),
doc: e.doc
}));
if (!a) throw Error(`Block with ID ${r.id} not found`);
let s = u(a.node, o);
if (g(this.editor, "table") && (this.tablePos = a.posBeforeNode + 1, i = s), !i) return;
this.tableId = r.id;
let l = t.domNode.closest(".tableWrapper")?.querySelector(".table-widgets-container");
if (t?.type === "wrapper") {
let t = e.clientY >= n.bottom - 1 && e.clientY < n.bottom + 20, r = e.clientX >= n.right - 1 && e.clientX < n.right + 20, a = this.state?.block?.id !== i.id || e.clientX > n.right || e.clientY > n.bottom;
this.state = {
...this.state,
show: !0,
showAddOrRemoveRowsButton: t,
showAddOrRemoveColumnsButton: r,
referencePosTable: n,
block: i,
widgetContainer: l,
colIndex: a ? void 0 : this.state?.colIndex,
rowIndex: a ? void 0 : this.state?.rowIndex,
referencePosCell: a ? void 0 : this.state?.referencePosCell
};
} else {
let e = q(t.domNode), a = q(t.domNode.parentElement), o = t.domNode.getBoundingClientRect();
if (this.state !== void 0 && this.state.show && this.tableId === r.id && this.state.rowIndex === a && this.state.colIndex === e) return;
this.state = {
show: !0,
showAddOrRemoveColumnsButton: e === i.content.rows[0].cells.length - 1,
showAddOrRemoveRowsButton: a === i.content.rows.length - 1,
referencePosTable: n,
block: i,
draggingState: void 0,
referencePosCell: o,
colIndex: e,
rowIndex: a,
widgetContainer: l
};
}
return this.emitUpdate(), !1;
};
dragOverHandler = (e) => {
if (this.state?.draggingState === void 0) return;
e.preventDefault(), e.dataTransfer.dropEffect = "move", sn(".prosemirror-dropcursor-block, .prosemirror-dropcursor-inline", this.pmView.root);
let t = {
left: Math.min(Math.max(e.clientX, this.state.referencePosTable.left + 1), this.state.referencePosTable.right - 1),
top: Math.min(Math.max(e.clientY, this.state.referencePosTable.top + 1), this.state.referencePosTable.bottom - 1)
}, n = this.pmView.root.elementsFromPoint(t.left, t.top).filter((e) => e.tagName === "TD" || e.tagName === "TH");
if (n.length === 0) return;
let r = n[0], i = !1, a = q(r.parentElement), o = q(r), s = this.state.draggingState.draggedCellOrientation === "row" ? this.state.rowIndex : this.state.colIndex, c = (this.state.draggingState.draggedCellOrientation === "row" ? a : o) !== s;
(this.state.rowIndex !== a || this.state.colIndex !== o) && (this.state.rowIndex = a, this.state.colIndex = o, this.state.referencePosCell = r.getBoundingClientRect(), i = !0);
let l = this.state.draggingState.draggedCellOrientation === "row" ? t.top : t.left;
this.state.draggingState.mousePos !== l && (this.state.draggingState.mousePos = l, i = !0), i && this.emitUpdate(), c && this.editor.transact((e) => e.setMeta(J, !0));
};
dropHandler = (e) => {
if (this.mouseState = "up", this.state === void 0 || this.state.draggingState === void 0) return !1;
if (this.state.rowIndex === void 0 || this.state.colIndex === void 0) throw Error("Attempted to drop table row or column, but no table block was hovered prior.");
e.preventDefault();
let { draggingState: t, colIndex: n, rowIndex: r } = this.state;
this.state.draggingState = void 0;
let o = this.state.block.content.columnWidths;
if (t.draggedCellOrientation === "row") {
if (!i(this.state.block, t.originalIndex, r)) return !1;
let e = a(this.state.block, t.originalIndex, r);
this.editor.updateBlock(this.state.block, {
type: "table",
content: {
...this.state.block.content,
rows: e
}
});
} else {
if (!p(this.state.block, t.originalIndex, n)) return !1;
let e = ee(this.state.block, t.originalIndex, n), [r] = o.splice(t.originalIndex, 1);
o.splice(n, 0, r), this.editor.updateBlock(this.state.block, {
type: "table",
content: {
...this.state.block.content,
columnWidths: o,
rows: e
}
});
}
return this.editor.setTextCursorPosition(this.state.block.id), !0;
};
update() {
if (!this.state || !this.state.show) return;
let e = this.editor.getBlock(this.state.block.id);
if (!e || e.type !== "table" || !this.tableElement?.isConnected) {
this.state = void 0, this.tableId = void 0, this.tableElement = void 0, this.emitUpdate();
return;
}
this.state.block = e;
let { height: t, width: n } = o(this.state.block);
this.state.rowIndex !== void 0 && this.state.colIndex !== void 0 && (this.state.rowIndex >= t && (this.state.rowIndex = t - 1), this.state.colIndex >= n && (this.state.colIndex = n - 1));
let r = this.tableElement.querySelector("tbody");
if (!r) throw Error("Table block does not contain a 'tbody' HTML element. This should never happen.");
if (this.state.rowIndex !== void 0 && this.state.colIndex !== void 0) {
let e = r.children[this.state.rowIndex].children[this.state.colIndex];
e ? this.state.referencePosCell = e.getBoundingClientRect() : (this.state.rowIndex = void 0, this.state.colIndex = void 0);
}
this.state.referencePosTable = r.getBoundingClientRect(), this.emitUpdate();
}
destroy() {
this.pmView.dom.removeEventListener("mousemove", this.mouseMoveHandler), window.removeEventListener("mouseup", this.mouseUpHandler), this.pmView.dom.removeEventListener("mousedown", this.viewMousedownHandler), this.pmView.root.removeEventListener("dragover", this.dragOverHandler), this.pmView.root.removeEventListener("drop", this.dropHandler);
}
}, J = new w("TableHandlesPlugin"), ln = b(({ editor: t }) => {
let n, a = y(void 0);
return {
key: "tableHandles",
store: a,
prosemirrorPlugins: [new C({
key: J,
view: (e) => (n = new cn(t, e, (e) => {
a.setState(e?.block ? {
...e,
draggingState: e.draggingState ? { ...e.draggingState } : void 0
} : void 0);
}), n),
props: { decorations: (e) => {
if (n === void 0 || n.state === void 0 || n.state.draggingState === void 0 || n.tablePos === void 0) return;
let t = n.state.draggingState.draggedCellOrientation === "row" ? n.state.rowIndex : n.state.colIndex;
if (t === void 0) return;
let a = [], { block: o, draggingState: s } = n.state, { originalIndex: c, draggedCellOrientation: l } = s;
if (t === c || !o || l === "row" && !i(o, c, t) || l === "col" && !p(o, c, t)) return O.create(e.doc, a);
let u = e.doc.resolve(n.tablePos + 1);
return n.state.draggingState.draggedCellOrientation === "row" ? r(n.state.block, t).forEach(({ row: n, col: r }) => {
let i = e.doc.resolve(u.posAtIndex(n) + 1), o = e.doc.resolve(i.posAtIndex(r) + 1), s = o.node(), l = o.pos + (t > c ? s.nodeSize - 2 : 0);
a.push(D.widget(l, () => {
let e = document.createElement("div");
return e.className = "bn-table-drop-cursor", e.style.left = "0", e.style.right = "0", t > c ? e.style.bottom = "-2px" : e.style.top = "-3px", e.style.height = "4px", e;
}));
}) : m(n.state.block, t).forEach(({ row: n, col: r }) => {
let i = e.doc.resolve(u.posAtIndex(n) + 1), o = e.doc.resolve(i.posAtIndex(r) + 1), s = o.node(), l = o.pos + (t > c ? s.nodeSize - 2 : 0);
a.push(D.widget(l, () => {
let e = document.createElement("div");
return e.className = "bn-table-drop-cursor", e.style.top = "0", e.style.bottom = "0", t > c ? e.style.right = "-2px" : e.style.left = "-3px", e.style.width = "4px", e;
}));
}), O.create(e.doc, a);
} }
})],
colDragStart(e) {
if (n === void 0 || n.state === void 0 || n.state.colIndex === void 0) throw Error("Attempted to drag table column, but no table block was hovered prior.");
n.state.draggingState = {
draggedCellOrientation: "col",
originalIndex: n.state.colIndex,
mousePos: e.clientX
}, n.emitUpdate(), t.transact((e) => e.setMeta(J, {
draggedCellOrientation: n.state.draggingState.draggedCellOrientation,
originalIndex: n.state.colIndex,
newIndex: n.state.colIndex,
tablePos: n.tablePos
})), !t.headless && (rn(t.prosemirrorView.root), e.dataTransfer.setDragImage(K, 0, 0), e.dataTransfer.effectAllowed = "move");
},
rowDragStart(e) {
if (n.state === void 0 || n.state.rowIndex === void 0) throw Error("Attempted to drag table row, but no table block was hovered prior.");
n.state.draggingState = {
draggedCellOrientation: "row",
originalIndex: n.state.rowIndex,
mousePos: e.clientY
}, n.emitUpdate(), t.transact((e) => e.setMeta(J, {
draggedCellOrientation: n.state.draggingState.draggedCellOrientation,
originalIndex: n.state.rowIndex,
newIndex: n.state.rowIndex,
tablePos: n.tablePos
})), !t.headless && (rn(t.prosemirrorView.root), e.dataTransfer.setDragImage(K, 0, 0), e.dataTransfer.effectAllowed = "copyMove");
},
dragEnd() {
if (n.state === void 0) throw Error("Attempted to drag table row, but no table block was hovered prior.");
n.state.draggingState = void 0, n.emitUpdate(), t.transact((e) => e.setMeta(J, null)), !t.headless && an(t.prosemirrorView.root);
},
freezeHandles() {
n.menuFrozen = !0;
},
unfreezeHandles() {
n.menuFrozen = !1;
},
hideHandlesIfNotFrozen() {
!n.menuFrozen && n.state?.show && (n.state.show = !1, n.state.showAddOrRemoveRowsButton = !1, n.state.showAddOrRemoveColumnsButton = !1, n.emitUpdate());
},
getCellsAtRowHandle(e, t) {
return r(e, t);
},
getCellsAtColumnHandle(e, t) {
return m(e, t);
},
setCellSelection(e, t, r = t) {
if (!n) throw Error("Table handles view not initialized");
let i = e.doc.resolve(n.tablePos + 1), a = e.doc.resolve(i.posAtIndex(t.row) + 1), o = e.doc.resolve(a.posAtIndex(t.col)), s = e.doc.resolve(i.posAtIndex(r.row) + 1), c = e.doc.resolve(s.posAtIndex(r.col)), l = e.tr;
return l.setSelection(new me(o, c)), e.apply(l);
},
addRowOrColumn(e, n) {
t.exec((t, r) => {
let i = this.setCellSelection(t, n.orientation === "row" ? {
row: e,
col: 0
} : {
row: 0,
col: e
});
return n.orientation === "row" ? n.side === "above" ? ve(i, r) : _e(i, r) : n.side === "left" ? ge(i, r) : he(i, r);
});
},
removeRowOrColumn(e, n) {
return n === "row" ? t.exec((t, n) => {
let r = this.setCellSelection(t, {
row: e,
col: 0
});
return be(r, n);
}) : t.exec((t, n) => {
let r = this.setCellSelection(t, {
row: 0,
col: e
});
return ye(r, n);
});
},
mergeCells(e) {
return t.exec((t, n) => {
let r = e ? this.setCellSelection(t, e.relativeStartCell, e.relativeEndCell) : t;
return xe(r, n);
});
},
splitCell(e) {
return t.exec((t, n) => {
let r = e ? this.setCellSelection(t, e) : t;
return Se(r, n);
});
},
getCellSelection() {
return t.transact((e) => {
let t = e.selection, n = t.$from, r = t.$to;
if (v(t)) {
let { ranges: e } = t;
e.forEach((e) => {
n = e.$from.min(n ?? e.$from), r = e.$to.max(r ?? e.$to);
});
} else {
let i = t.$from.pos - t.$from.parentOffset - 1, a = t.$to.pos - t.$to.parentOffset - 1;
if (i < 0 || a < 0 || (n = e.doc.resolve(i), r = e.doc.resolve(a), !h(n.parent) || !h(r.parent))) return;
}
let i = e.doc.resolve(n.pos - n.parentOffset - 1), a = e.doc.resolve(r.pos - r.parentOffset - 1), o = e.doc.resolve(i.pos - i.parentOffset - 1), s = n.index(i.depth), c = i.index(o.depth), l = r.index(a.depth), u = a.index(o.depth), d = [];
for (let e = c; e <= u; e++) for (let t = s; t <= l; t++) d.push({
row: e,
col: t
});
return {
from: {
row: c,
col: s
},
to: {
row: u,
col: l
},
cells: d
};
});
},
getMergeDirection(n) {
return t.transact((t) => {
let r = v(t.selection) ? t.selection : void 0;
if (!r || !n || r.ranges.length <= 1) return;
let i = this.getCellSelection();
if (i) return e(i.from, i.to, n) ? "vertical" : "horizontal";
});
},
cropEmptyRowsOrColumns(e, t) {
return f(e, t);
},
addRowsOrColumns(e, t, n) {
return ne(e, t, n);
}
};
}), Y = new w("trailingNode");
function X(e) {
let t = e.lastChild, n = t?.firstChild;
return t?.type.name !== "blockContainer" || n?.type.name !== "paragraph" || n.content.size !== 0;
}
function un(e) {
if (!e.type.schema.nodes.column) {
let t = e.lastChild;
return t && X(t) ? [e.content.size - 1] : [];
}
let t = [];
return e.descendants((e, n, r) => !e.isTextblock && ((e.type.name === "column" || e.type.name === "blockGroup" && r?.type.name === "doc") && X(e) && t.push(n + e.nodeSize - 1), !0)), t;
}
var dn = b(({ editor: e }) => {
function t(t) {
return D.widget(t, () => {
let t = document.createElement("div");
return t.className = "bn-trailing-block", t.contentEditable = "false", t.addEventListener("mousedown", (n) => {
n.preventDefault();
let r = e.prosemirrorView;
if (!r) return;
let i = r.state.doc.resolve(r.posAtDOM(t, 0)).parent.lastChild?.attrs.id;
i && (e.transact((t) => {
let [n] = e.insertBlocks([{ type: "paragraph" }], i, "after");
e.setTextCursorPosition(n, "start"), t.scrollIntoView();
}), r.focus());
}), t;
}, { side: 1 });
}
function n(e, n, r) {
let i = n.map(e.mapping, e.doc), a = new Set(r ? un(e.doc) : []), o = /* @__PURE__ */ new Set(), s = [];
for (let e of i.find()) a.has(e.from) && !o.has(e.from) ? o.add(e.from) : s.push(e);
let c = [...a].filter((e) => !o.has(e)), l = i;
return s.length > 0 && (l = l.remove(s)), c.length > 0 && (l = l.add(e.doc, c.map(t))), l;
}
return {
key: "trailingNode",
prosemirrorPlugins: [new C({
key: Y,
state: {
init: (t, r) => n(r.tr, O.empty, e.isEditable),
apply: (t, r) => !t.docChanged && !t.getMeta(Y) ? r : n(t, r, e.isEditable)
},
view(e) {
let t = e.editable;
return { update(e) {
e.editable !== t && (t = e.editable, e.dispatch(e.state.tr.setMeta(Y, !0)));
} };
},
props: {
decorations: (e) => Y.getState(e),
handleKeyDown: (t, n) => {
if (n.key !== "ArrowRight" && n.key !== "ArrowDown") return !1;
let { selection: r } = t.state;
if (!r.empty) return !1;
let i = T.atEnd(t.state.doc);
if (r.$head.pos !== i.$head.pos) return !1;
let a = t.state.doc.lastChild;
return !e.isEditable || !a || !X(a) ? !1 : (n.preventDefault(), !0);
}
}
})]
};
}), Z = Symbol("bn-current-version");
function Q(e) {
return [...e].sort((e, t) => t.createdAt - e.createdAt);
}
function $(e) {
let t = typeof e == "object" ? e.id : e;
throw Error(`Snapshot not found: ${String(t)}`);
}
var fn = b(({ options: e, editor: t }) => {
let { endpoints: n, preview: r, getCurrentDocument: i, serializeCurrentContent: a, resolveUsers: o } = typeof e == "function" ? e(t) : e, s = typeof n == "function" ? n(t) : n, c = re(o), l = y({
snapshots: [],
previewedSnapshotId: void 0,
compareToSnapshotId: void 0
}), u = (e) => {
let t = typeof e == "object" ? e.id : e;
return l.state.snapshots.find((e) => e.id === t);
}, d = async () => {
let e = Q(await s.list());
return l.setState((t) => ({
...t,
snapshots: e
})), e;
}, f = async (e, t) => {
let n = u(e);
n || $(e);
let i = t?.compareTo ? u(t.compareTo) : void 0;
l.setState((e) => ({
...e,
previewedSnapshotId: n.id,
compareToSnapshotId: i?.id
}));
let a, o;
i && (a = await s.getContent(i), s.getAttributions && (o = await s.getAttributions(n, i)));
let c = await s.getContent(n);
r.enterPreview(c, a, o, {
snapshot: n,
compareTo: i
});
}, p = async (e) => {
if (!a) throw Error("previewCurrentVersion requires `serializeCurrentContent` to be provided to the VersioningExtension options.");
let t = e?.compareTo ? u(e.compareTo) : void 0;
l.setState((e) => ({
...e,
previewedSnapshotId: Z,
compareToSnapshotId: t?.id
}));
let n = {
id: Z,
createdAt: Date.now(),
updatedAt: Date.now()
}, i, o;
t && (i = await s.getContent(t), s.getAttributions && (o = await s.getAttributions(n, t)));
let c = await a();
r.enterPreview(c, i, o, {
snapshot: n,
compareTo: t
});
}, m = () => {
l.setState((e) => ({
...e,
previewedSnapshotId: void 0,
compareToSnapshotId: void 0
})), r.exitPreview();
};
return {
key: "versioning",
store: l,
userStore: c,
list: async () => await d(),
get canCompare() {
return r.supportsComparison !== !1;
},
canCreate: s.create !== void 0,
create: s.create ? async (e) => {
let t = await s.create(i(), {
name: e?.name,
restoredFromSnapshot: u(e?.restoredFromSnapshot)
});
l.setState((e) => ({
...e,
snapshots: Q([...e.snapshots, t])
}));
let n = await s.list();
return l.setState((e) => ({
...e,
snapshots: Q(n.some((e) => e.id === t.id) ? n : [...n, t])
})), t;
} : void 0,
canRestore: s.restore !== void 0,
restore: s.restore ? async (e) => {
m();
let t = u(e);
t || $(e);
let n = await s.restore(i(), t);
return r.applyRestore(n), await d(), n;
} : void 0,
canRename: s.rename !== void 0,
rename: s.rename ? async (e, t) => {
let n = u(e);
n || $(e), await s.rename(n, t), l.setState((n) => ({
...n,
snapshots: n.snapshots.map((n) => n.id === e ? {
...n,
name: t,
updatedAt: Date.now()
} : n)
}));
} : void 0,
canRemove: s.remove !== void 0,
remove: s.remove ? async (e) => {
let t = u(e);
t || $(e), (l.state.previewedSnapshotId === t.id || l.state.compareToSnapshotId === t.id) && m(), await s.remove(t), l.setState((e) => ({
...e,
snapshots: e.snapshots.filter((e) => e.id !== t.id)
})), await d();
} : void 0,
previewSnapshot: f,
canPreviewCurrent: a !== void 0,
previewCurrentVersion: a ? p : void 0,
exitPreview: m
};
});
//#endregion
//#region src/extensions/Versioning/inMemoryVersioning.ts
function pn(e) {
return e.id === Z ? "Current version" : e.name ?? "Unnamed version";
}
function mn(e) {
let t, n = !1, r = (t) => {
e.replaceBlocks(e.document, t);
}, i = () => e.getExtension("diffVersioning");
return {
get supportsComparison() {
return i() !== void 0;
},
enterPreview(a, o, s, c) {
t === void 0 && (t = e.document);
let l = i();
if (o && l) {
l.renderDiff(a, o, c && pn(c.snapshot)), n = !0;
return;
}
n = !1, r(a);
},
exitPreview() {
if (t !== void 0) {
let e = i();
n && e ? e.clearDiff(t) : r(t), t = void 0, n = !1;
}
},
applyRestore(e) {
let a = i();
n && a ? a.clearDiff(e) : r(e), t = void 0, n = !1;
}
};
}
function hn() {
let e = [], t = /* @__PURE__ */ new Map(), n = 1, r = 0;
function i() {
return r = Math.max(Date.now(), r + 1), r;
}
return {
async list() {
return Q([...e]);
},
async create(r, a) {
let o = i(), s = String(n++), c = {
id: s,
name: a?.name,
createdAt: o,
updatedAt: o
};
return e.push(c), t.set(s, structuredClone(r)), c;
},
async restore(r, a) {
let o = String(a.id), s = t.get(o);
if (!s) throw Error(`Snapshot ${o} not found`);
let c = i(), l = String(n++), u = {
id: l,
name: "Before restore",
createdAt: c,
updatedAt: c,
restoredFromSnapshotId: o
};
return e.push(u), t.set(l, structuredClone(r)), structuredClone(s);
},
async getContent(e) {
let n = String(e.id), r = t.get(n);
if (!r) throw Error(`Snapshot ${n} not found`);
return structuredClone(r);
},
async rename(t, n) {
let r = e.find((e) => e.id === t.id);
if (!r) throw Error(`Snapshot ${String(t.id)} not found`);
r.name = n, r.updatedAt = i();
},
async remove(n) {
let r = e.findIndex((e) => e.id === n.id);
if (r === -1) throw Error(`Snapshot ${String(n.id)} not found`);
e.splice(r, 1), t.delete(String(n.id));
}
};
}
function gn(e) {
let t = hn();
return {
endpoints: {
...t,
list: async () => [{
id: Z,
createdAt: Date.now(),
updatedAt: Date.now()
}, ...await t.list()]
},
preview: mn(e),
getCurrentDocument: () => e.document,
serializeCurrentContent: () => e.document
};
}
//#endregion
export { Xe as A, st as C, tt as D, nt as E, k as F, Ye as M, He as N, et as O, Ve as P, lt as S, it as T, Wt as _, fn as a, It as b, ln as c, nn as d, en as f, Kt as g, qt as h, Z as i, Je as j, $e as k, cn as l, Jt as m, gn as n, Q as o, $t as p, hn as r, dn as s, mn as t, J as u, Gt as v, ot as w, B as x, Lt as y };
//# sourceMappingURL=extensions-DGuhtOgB.js.map