Files
tolaria/patches/@blocknote__core@0.46.2.patch

1099 lines
346 KiB
Diff
Raw Permalink Normal View History

2026-05-01 12:55:23 +02:00
diff --git a/dist/TrailingNode-CxM966vN.js b/dist/TrailingNode-CxM966vN.js
index 3ac6fe16aa9ae605a59916f8343b8440befda89e..ee009c533fa3826819df0b83a12755b6300db400 100644
2026-05-01 12:55:23 +02:00
--- a/dist/TrailingNode-CxM966vN.js
+++ b/dist/TrailingNode-CxM966vN.js
@@ -80,7 +80,7 @@ function be(n, e, t, o) {
let l = document.createTextNode(
c.textContent
);
- for (const u of c.marks.toReversed())
+ for (const u of Array.from(c.marks).reverse())
if (u.type.name in n.schema.styleSpecs) {
const h = (n.schema.styleSpecs[u.type.name].implementation.toExternalHTML ?? n.schema.styleSpecs[u.type.name].implementation.render)(u.attrs.stringValue, n);
h.contentDOM.appendChild(l), l = h.dom;
2026-05-01 12:55:23 +02:00
@@ -1183,6 +1183,10 @@ class Ft {
b(this, "updateState", (e) => {
this.state = e, this.emitUpdate(this.state);
});
+ b(this, "hideMenu", () => {
+ var e;
+ (e = this.state) != null && e.show && (this.state.show = !1, this.updateState(this.state));
+ });
b(this, "updateStateFromMousePos", () => {
var o, r, s, i, a;
if (this.menuFrozen || !this.mousePos)
@@ -1192,33 +1196,39 @@ class Ft {
clientY: this.mousePos.y
});
if ((e == null ? void 0 : e.element) !== this.pmView.dom || e.distance > se) {
- (o = this.state) != null && o.show && (this.state.show = !1, this.updateState(this.state));
+ this.hideMenu();
return;
}
const t = Ht(this.mousePos, this.pmView);
if (!t || !this.editor.isEditable) {
- (r = this.state) != null && r.show && (this.state.show = !1, this.updateState(this.state));
+ this.hideMenu();
2026-05-02 10:58:46 +02:00
+ return;
+ }
2026-05-01 12:55:23 +02:00
+ if ((s = this.state) != null && s.show && ((i = this.hoveredBlock) != null && i.hasAttribute("data-id")) && ((a = this.hoveredBlock) == null ? void 0 : a.getAttribute("data-id")) === t.id)
+ return;
+ this.hoveredBlock = t.node;
+ const c = this.hoveredBlock.getAttribute("data-id"), l = c ? this.editor.getBlock(c) : void 0;
+ if (!l) {
+ this.hideMenu();
2026-05-02 10:58:46 +02:00
return;
}
- if (!((s = this.state) != null && s.show && ((i = this.hoveredBlock) != null && i.hasAttribute("data-id")) && ((a = this.hoveredBlock) == null ? void 0 : a.getAttribute("data-id")) === t.id) && (this.hoveredBlock = t.node, this.editor.isEditable)) {
- const c = t.node.getBoundingClientRect(), l = t.node.closest("[data-node-type=column]");
2026-05-01 12:55:23 +02:00
+ if (this.editor.isEditable) {
+ const u = t.node.getBoundingClientRect(), h = t.node.closest("[data-node-type=column]");
this.state = {
show: !0,
referencePos: new DOMRect(
- l ? (
+ h ? (
// We take the first child as column elements have some default
// padding. This is a little weird since this child element will
// be the first block, but since it's always non-nested and we
// only take the x coordinate, it's ok.
- l.firstElementChild.getBoundingClientRect().x
+ h.firstElementChild.getBoundingClientRect().x
) : this.pmView.dom.firstChild.getBoundingClientRect().x,
- c.y,
- c.width,
- c.height
+ u.y,
+ u.width,
+ u.height
),
- block: this.editor.getBlock(
- this.hoveredBlock.getAttribute("data-id")
- )
+ block: l
}, this.updateState(this.state);
}
});
2026-05-02 10:58:46 +02:00
@@ -1522,6 +1532,30 @@ function Ut(n) {
function M(n) {
return Array.prototype.indexOf.call(n.parentElement.childNodes, n);
}
+function isValidTablePosition(n) {
+ return Number.isInteger(n) && n >= 0;
+}
+function isValidCellIndex(n) {
+ return Number.isInteger(n) && n >= 0;
+}
+function isValidRelativeCell(n) {
+ return isValidCellIndex(n.row) && isValidCellIndex(n.col);
+}
+function resolveCellPosition(n, e, t) {
+ if (!isValidTablePosition(e) || !isValidRelativeCell(t))
+ return;
+ try {
+ const o = n.doc.resolve(e + 1);
+ if (t.row >= o.node().childCount)
+ return;
+ const r = n.doc.resolve(
+ o.posAtIndex(t.row) + 1
+ );
+ return t.col >= r.node().childCount ? void 0 : n.doc.resolve(r.posAtIndex(t.col));
+ } catch {
+ return;
+ }
+}
function _t(n) {
let e = n;
for (; e && e.nodeName !== "TD" && e.nodeName !== "TH" && !e.classList.contains("tableWrapper"); ) {
@@ -1557,6 +1591,12 @@ class Kt {
2026-05-01 12:55:23 +02:00
b(this, "menuFrozen", !1);
b(this, "mouseState", "up");
b(this, "prevWasEditable", null);
+ b(this, "hideHandles", (e = {}) => {
+ const { resetCell: t = !1, resetDragging: o = !1 } = e;
+ if (!this.state || !this.state.show && !t && !o)
+ return;
+ this.state.show = !1, this.state.showAddOrRemoveRowsButton = !1, this.state.showAddOrRemoveColumnsButton = !1, o && (this.state.draggingState = void 0), t && (this.state.rowIndex = void 0, this.state.colIndex = void 0, this.state.referencePosCell = void 0), this.emitUpdate();
+ });
b(this, "viewMousedownHandler", () => {
this.mouseState = "down";
});
2026-05-02 10:58:46 +02:00
@@ -1569,11 +1609,11 @@ class Kt {
2026-05-01 12:55:23 +02:00
return;
const t = _t(e.target);
if ((t == null ? void 0 : t.type) === "cell" && this.mouseState === "down" && !((l = this.state) != null && l.draggingState)) {
- this.mouseState = "selecting", (u = this.state) != null && u.show && (this.state.show = !1, this.state.showAddOrRemoveRowsButton = !1, this.state.showAddOrRemoveColumnsButton = !1, this.emitUpdate());
+ this.mouseState = "selecting", this.hideHandles();
return;
}
if (!t || !this.editor.isEditable) {
- (h = this.state) != null && h.show && (this.state.show = !1, this.state.showAddOrRemoveRowsButton = !1, this.state.showAddOrRemoveColumnsButton = !1, this.emitUpdate());
+ this.hideHandles();
return;
}
if (!t.tbodyNode)
@@ -1603,7 +1643,7 @@ class Kt {
const w = e.clientY >= o.bottom - 1 && // -1 to account for fractions of pixels in "bottom"
e.clientY < o.bottom + 20, y = e.clientX >= o.right - 1 && e.clientX < o.right + 20, C = (
// always hide handles when the actively hovered table changed
- ((m = this.state) == null ? void 0 : m.block.id) !== s.id || // make sure we don't hide existing handles (keep col / row index) when
+ ((p = (m = this.state) == null ? void 0 : m.block) == null ? void 0 : p.id) !== s.id || // make sure we don't hide existing handles (keep col / row index) when
// we're hovering just above or to the right of a table
e.clientX > o.right || e.clientY > o.bottom
);
2026-05-02 10:58:46 +02:00
@@ -1671,9 +1711,7 @@ class Kt {
2026-05-01 12:55:23 +02:00
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 new Error(
- "Attempted to drop table row or column, but no table block was hovered prior."
- );
+ return e.preventDefault(), this.hideHandles({ resetCell: !0, resetDragging: !0 }), !1;
e.preventDefault();
const { draggingState: t, colIndex: o, rowIndex: r } = this.state, s = this.state.block.content.columnWidths;
if (t.draggedCellOrientation === "row") {
@@ -1735,26 +1773,31 @@ class Kt {
var r;
if (!this.state || !this.state.show)
return;
- if (this.state.block = this.editor.getBlock(this.state.block.id), !this.state.block || this.state.block.type !== "table" || // when collaborating, the table element might be replaced and out of date
+ const e = this.state.block;
+ if (!e) {
+ this.hideHandles({ resetCell: !0, resetDragging: !0 });
+ return;
+ }
+ if (this.state.block = this.editor.getBlock(e.id), !this.state.block || this.state.block.type !== "table" || // when collaborating, the table element might be replaced and out of date
2026-05-01 12:55:23 +02:00
// because yjs replaces the element when for example you change the color via the side menu
!((r = this.tableElement) != null && r.isConnected)) {
- this.state.show = !1, this.state.showAddOrRemoveRowsButton = !1, this.state.showAddOrRemoveColumnsButton = !1, this.emitUpdate();
+ this.hideHandles();
return;
}
- const { height: e, width: t } = Ve(
+ const { height: t, width: o } = Ve(
this.state.block
2026-05-01 12:55:23 +02:00
);
- this.state.rowIndex !== void 0 && this.state.colIndex !== void 0 && (this.state.rowIndex >= e && (this.state.rowIndex = e - 1), this.state.colIndex >= t && (this.state.colIndex = t - 1));
- const o = this.tableElement.querySelector("tbody");
2026-05-01 12:55:23 +02:00
- if (!o)
- throw new Error(
- "Table block does not contain a 'tbody' HTML element. This should never happen."
- );
+ this.state.rowIndex !== void 0 && this.state.colIndex !== void 0 && (this.state.rowIndex >= t && (this.state.rowIndex = t - 1), this.state.colIndex >= o && (this.state.colIndex = o - 1));
+ const i = this.tableElement.querySelector("tbody");
+ if (!i) {
2026-05-01 12:55:23 +02:00
+ this.hideHandles({ resetCell: !0 });
+ return;
+ }
if (this.state.rowIndex !== void 0 && this.state.colIndex !== void 0) {
- const i = o.children[this.state.rowIndex].children[this.state.colIndex];
- i ? this.state.referencePosCell = i.getBoundingClientRect() : (this.state.rowIndex = void 0, this.state.colIndex = void 0);
+ const a = i.children[this.state.rowIndex].children[this.state.colIndex];
+ a ? this.state.referencePosCell = a.getBoundingClientRect() : (this.state.rowIndex = void 0, this.state.colIndex = void 0);
}
- this.state.referencePosTable = o.getBoundingClientRect(), this.emitUpdate();
+ this.state.referencePosTable = i.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(
@@ -1838,10 +1881,10 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-01 12:55:23 +02:00
* is used as the column drag handle.
*/
colDragStart(o) {
- if (e === void 0 || e.state === void 0 || e.state.colIndex === void 0)
- throw new Error(
- "Attempted to drag table column, but no table block was hovered prior."
- );
+ if (e === void 0 || e.state === void 0 || e.state.colIndex === void 0 || e.tablePos === void 0) {
+ e == null || e.hideHandles({ resetCell: !0, resetDragging: !0 });
+ return;
+ }
e.state.draggingState = {
draggedCellOrientation: "col",
originalIndex: e.state.colIndex,
@@ -1860,10 +1903,10 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-01 12:55:23 +02:00
* is used as the row drag handle.
*/
rowDragStart(o) {
- if (e.state === void 0 || e.state.rowIndex === void 0)
- throw new Error(
- "Attempted to drag table row, but no table block was hovered prior."
- );
+ if (e === void 0 || e.state === void 0 || e.state.rowIndex === void 0 || e.tablePos === void 0) {
+ e == null || e.hideHandles({ resetCell: !0, resetDragging: !0 });
+ return;
+ }
e.state.draggingState = {
draggedCellOrientation: "row",
originalIndex: e.state.rowIndex,
@@ -1882,10 +1925,10 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-01 12:55:23 +02:00
* used as the row drag handle, and the one used as the column drag handle.
*/
dragEnd() {
- if (e.state === void 0)
- throw new Error(
- "Attempted to drag table row, but no table block was hovered prior."
- );
+ if (e === void 0 || e.state === void 0) {
+ n.headless || Ut(n.prosemirrorView.root);
+ return;
+ }
e.state.draggingState = void 0, e.emitUpdate(), n.transact((o) => o.setMeta(D, null)), !n.headless && Ut(n.prosemirrorView.root);
},
/**
@@ -1918,30 +1961,38 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-02 10:58:46 +02:00
setCellSelection(o, r, s = r) {
if (!e)
throw new Error("Table handles view not initialized");
- const i = o.doc.resolve(e.tablePos + 1), a = o.doc.resolve(
- i.posAtIndex(r.row) + 1
- ), c = o.doc.resolve(
- // No need for +1, since CellSelection expects the position before the cell
- a.posAtIndex(r.col)
- ), l = o.doc.resolve(
- i.posAtIndex(s.row) + 1
- ), u = o.doc.resolve(
- // No need for +1, since CellSelection expects the position before the cell
- l.posAtIndex(s.col)
- ), h = o.tr;
- return h.setSelection(
- new yt(c, u)
- ), o.apply(h);
+ const i = resolveCellPosition(
+ o,
+ e.tablePos,
+ r
+ ), a = resolveCellPosition(
+ o,
+ e.tablePos,
+ s
+ );
+ if (!i || !a)
+ return;
+ const c = o.tr;
+ return c.setSelection(
+ new yt(i, a)
+ ), o.apply(c);
},
/**
* Adds a row or column to the table using prosemirror-table commands
*/
addRowOrColumn(o, r) {
+ if (!e || !isValidTablePosition(e.tablePos) || !isValidCellIndex(o)) {
+ e == null || e.hideHandles({ resetCell: !0 });
+ return;
+ }
n.exec((s, i) => {
const a = this.setCellSelection(
s,
r.orientation === "row" ? { row: o, col: 0 } : { row: 0, col: o }
);
+ if (!a)
+ return e == null || e.hideHandles({ resetCell: !0 }), !1;
return r.orientation === "row" ? r.side === "above" ? pt(a, i) : ft(a, i) : r.side === "left" ? gt(a, i) : wt(a, i);
});
+ e == null || e.hideHandles({ resetCell: !0, resetDragging: !0 });
2026-05-02 10:58:46 +02:00
},
@@ -1949,17 +2000,23 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-02 10:58:46 +02:00
* Removes a row or column from the table using prosemirror-table commands
*/
removeRowOrColumn(o, r) {
+ if (!isValidCellIndex(o))
+ return !1;
return r === "row" ? n.exec((s, i) => {
const a = this.setCellSelection(s, {
row: o,
col: 0
});
+ if (!a)
+ return !1;
return ht(a, i);
}) : n.exec((s, i) => {
const a = this.setCellSelection(s, {
row: 0,
col: o
});
+ if (!a)
+ return !1;
return mt(a, i);
});
},
@@ -1973,6 +2029,8 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-02 10:58:46 +02:00
o.relativeStartCell,
o.relativeEndCell
) : r;
+ if (!i)
+ return !1;
return ut(i, s);
});
},
@@ -1983,6 +2041,8 @@ const D = new P("TableHandlesPlugin"), Po = k(({ editor: n }) => {
2026-05-02 10:58:46 +02:00
splitCell(o) {
return n.exec((r, s) => {
const i = o ? this.setCellSelection(r, o) : r;
+ if (!i)
+ return !1;
return dt(i, s);
});
},
diff --git a/dist/TrailingNode-D-CZ76FS.cjs b/dist/TrailingNode-D-CZ76FS.cjs
index 8406fda31f41172a823c26412698616a56800aae..2696bca794fd423b6cb6c41bf32c3a11f46e0ab6 100644
--- a/dist/TrailingNode-D-CZ76FS.cjs
+++ b/dist/TrailingNode-D-CZ76FS.cjs
@@ -1,2 +1,2 @@
-"use strict";var we=Object.defineProperty;var be=(n,e,t)=>e in n?we(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var b=(n,e,t)=>be(n,typeof e!="symbol"?e+"":e,t);const C=require("prosemirror-state"),R=require("@tiptap/core"),ke=require("fast-deep-equal"),k=require("./blockToNode-CumVjgem.cjs"),O=require("./defaultBlocks-DosClM5E.cjs"),v=require("./BlockNoteExtension-BWw0r8Gy.cjs"),M=require("y-prosemirror"),Ce=require("yjs"),V=require("@tiptap/pm/state"),ve=require("prosemirror-dropcursor"),q=require("@tiptap/pm/history"),D=require("prosemirror-view"),Se=require("uuid"),Z=require("@tiptap/pm/model"),H=require("prosemirror-model"),xe=require("rehype-parse"),Ee=require("rehype-remark"),Ie=require("remark-gfm"),Pe=require("remark-stringify"),Te=require("unified"),Be=require("hast-util-from-dom"),De=require("unist-util-visit"),T=require("prosemirror-tables"),F=n=>n&&typeof n=="object"&&"default"in n?n:{default:n};function Oe(n){if(n&&typeof n=="object"&&"default"in n)return n;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const o=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,o.get?o:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const Me=F(ke),B=Oe(Ce),Ae=F(xe),Ne=F(Ee),Le=F(Ie),Re=F(Pe);function ae(n){const e=Array.from(n.classList).filter(t=>!t.startsWith("bn-"))||[];e.length>0?n.className=e.join(" "):n.removeAttribute("class")}function le(n,e,t,o){var a;let r;if(e)if(typeof e=="string")r=k.inlineContentToNodes([e],n.pmSchema);else if(Array.isArray(e))r=k.inlineContentToNodes(e,n.pmSchema);else if(e.type==="tableContent")r=k.tableContentToNodes(e,n.pmSchema);else throw new k.UnreachableCaseError(e.type);else throw new Error("blockContent is required");const i=((o==null?void 0:o.document)??document).createDocumentFragment();for(const c of r)if(c.type.name!=="text"&&n.schema.inlineContentSchema[c.type.name]){const l=n.schema.inlineContentSpecs[c.type.name].implementation;if(l){const u=k.nodeToCustomInlineContent(c,n.schema.inlineContentSchema,n.schema.styleSchema),h=l.toExternalHTML?l.toExternalHTML(u,n):l.render.call({renderType:"dom",props:void 0},u,()=>{},n);if(h){if(i.appendChild(h.dom),h.contentDOM){const g=t.serializeFragment(c.content,o);h.contentDOM.dataset.editable="",h.contentDOM.appendChild(g)}continue}}}else if(c.type.name==="text"){let l=document.createTextNode(c.textContent);for(const u of c.marks.toReversed())if(u.type.name in n.schema.styleSpecs){const h=(n.schema.styleSpecs[u.type.name].implementation.toExternalHTML??n.schema.styleSpecs[u.type.name].implementation.render)(u.attrs.stringValue,n);h.contentDOM.appendChild(l),l=h.dom}else{const h=u.type.spec.toDOM(u,!0),g=H.DOMSerializer.renderSpec(document,h);g.contentDOM.appendChild(l),l=g.dom}i.appendChild(l)}else{const l=t.serializeFragment(H.Fragment.from([c]),o);i.appendChild(l)}return i.childNodes.length===1&&((a=i.firstChild)==null?void 0:a.nodeType)===1&&ae(i.firstChild),i}function Ve(n,e,t,o,r,s,i,a){var y,w,x,L,X,W,G,J,Q;const c=(a==null?void 0:a.document)??document,l=e.pmSchema.nodes.blockContainer,u=t.props||{};for(const[S,I]of Object.entries(e.schema.blockSchema[t.type].propSchema))!(S in u)&&I.default!==void 0&&(u[S]=I.default);const h=(w=(y=l.spec)==null?void 0:y.toDOM)==null?void 0:w.call(y,l.create({id:t.id,...u})),g=Array.from(h.dom.attributes),m=e.blockImplementations[t.type].implementation,p=((x=m.toExternalHTML)==null?void 0:x.call({},{...t,props:u},e,{nestingLevel:i}))||m.render.call({},{...t,props:u},e),d=c.createDocumentFragment();if(p.dom.classList.contains("bn-block-content")){const S=[...g,...Array.from(p.dom.attributes)].filter(I=>I.name.startsWith("data")&&I.name!=="data-content-type"&&I.name!=="data-file-block"&&I.name!=="data-node-view-wrapper"&&I.name!=="data-node-type"&&I.name!=="data-id"&&I.name!=="data-editable");for(const I of S)p.dom.firstChild.setAttribute(I.name,I.value);ae(p.dom.firstChild),i>0&&p.dom.firstChild.setAttribute("data-nesting-level",i.toString()),d.append(...Array.from(p.dom.childNodes))}els
+"use strict";var we=Object.defineProperty;var be=(n,e,t)=>e in n?we(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var b=(n,e,t)=>be(n,typeof e!="symbol"?e+"":e,t);const C=require("prosemirror-state"),R=require("@tiptap/core"),ke=require("fast-deep-equal"),k=require("./blockToNode-CumVjgem.cjs"),O=require("./defaultBlocks-DosClM5E.cjs"),v=require("./BlockNoteExtension-BWw0r8Gy.cjs"),M=require("y-prosemirror"),Ce=require("yjs"),V=require("@tiptap/pm/state"),ve=require("prosemirror-dropcursor"),q=require("@tiptap/pm/history"),D=require("prosemirror-view"),Se=require("uuid"),Z=require("@tiptap/pm/model"),H=require("prosemirror-model"),xe=require("rehype-parse"),Ee=require("rehype-remark"),Ie=require("remark-gfm"),Pe=require("remark-stringify"),Te=require("unified"),Be=require("hast-util-from-dom"),De=require("unist-util-visit"),T=require("prosemirror-tables"),F=n=>n&&typeof n=="object"&&"default"in n?n:{default:n};function Oe(n){if(n&&typeof n=="object"&&"default"in n)return n;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const o=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,o.get?o:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const Me=F(ke),B=Oe(Ce),Ae=F(xe),Ne=F(Ee),Le=F(Ie),Re=F(Pe);function ae(n){const e=Array.from(n.classList).filter(t=>!t.startsWith("bn-"))||[];e.length>0?n.className=e.join(" "):n.removeAttribute("class")}function le(n,e,t,o){var a;let r;if(e)if(typeof e=="string")r=k.inlineContentToNodes([e],n.pmSchema);else if(Array.isArray(e))r=k.inlineContentToNodes(e,n.pmSchema);else if(e.type==="tableContent")r=k.tableContentToNodes(e,n.pmSchema);else throw new k.UnreachableCaseError(e.type);else throw new Error("blockContent is required");const i=((o==null?void 0:o.document)??document).createDocumentFragment();for(const c of r)if(c.type.name!=="text"&&n.schema.inlineContentSchema[c.type.name]){const l=n.schema.inlineContentSpecs[c.type.name].implementation;if(l){const u=k.nodeToCustomInlineContent(c,n.schema.inlineContentSchema,n.schema.styleSchema),h=l.toExternalHTML?l.toExternalHTML(u,n):l.render.call({renderType:"dom",props:void 0},u,()=>{},n);if(h){if(i.appendChild(h.dom),h.contentDOM){const g=t.serializeFragment(c.content,o);h.contentDOM.dataset.editable="",h.contentDOM.appendChild(g)}continue}}}else if(c.type.name==="text"){let l=document.createTextNode(c.textContent);for(const u of Array.from(c.marks).reverse())if(u.type.name in n.schema.styleSpecs){const h=(n.schema.styleSpecs[u.type.name].implementation.toExternalHTML??n.schema.styleSpecs[u.type.name].implementation.render)(u.attrs.stringValue,n);h.contentDOM.appendChild(l),l=h.dom}else{const h=u.type.spec.toDOM(u,!0),g=H.DOMSerializer.renderSpec(document,h);g.contentDOM.appendChild(l),l=g.dom}i.appendChild(l)}else{const l=t.serializeFragment(H.Fragment.from([c]),o);i.appendChild(l)}return i.childNodes.length===1&&((a=i.firstChild)==null?void 0:a.nodeType)===1&&ae(i.firstChild),i}function Ve(n,e,t,o,r,s,i,a){var y,w,x,L,X,W,G,J,Q;const c=(a==null?void 0:a.document)??document,l=e.pmSchema.nodes.blockContainer,u=t.props||{};for(const[S,I]of Object.entries(e.schema.blockSchema[t.type].propSchema))!(S in u)&&I.default!==void 0&&(u[S]=I.default);const h=(w=(y=l.spec)==null?void 0:y.toDOM)==null?void 0:w.call(y,l.create({id:t.id,...u})),g=Array.from(h.dom.attributes),m=e.blockImplementations[t.type].implementation,p=((x=m.toExternalHTML)==null?void 0:x.call({},{...t,props:u},e,{nestingLevel:i}))||m.render.call({},{...t,props:u},e),d=c.createDocumentFragment();if(p.dom.classList.contains("bn-block-content")){const S=[...g,...Array.from(p.dom.attributes)].filter(I=>I.name.startsWith("data")&&I.name!=="data-content-type"&&I.name!=="data-file-block"&&I.name!=="data-node-view-wrapper"&&I.name!=="data-node-type"&&I.name!=="data-id"&&I.name!=="data-editable");for(const I of S)p.dom.firstChild.setAttribute(I.name,I.value);ae(p.dom.firstChild),i>0&&p.dom.firstChild.setAttribute("data-nesting-level",i.toString()),d.append(...Array.from(p.dom.childNo
//# sourceMappingURL=TrailingNode-D-CZ76FS.cjs.map
diff --git a/dist/blocknote.cjs b/dist/blocknote.cjs
index 778ed7a4062755747312db827f920e47a5aff127..f9e34b3ceb54a976b734fd70ac7fc183e0070c2b 100644
--- a/dist/blocknote.cjs
+++ b/dist/blocknote.cjs
@@ -1,5 +1,5 @@
"use strict";var Ee=Object.defineProperty;var Te=(o,e,t)=>e in o?Ee(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var k=(o,e,t)=>Te(o,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const x=require("prosemirror-model"),L=require("prosemirror-transform"),u=require("./blockToNode-CumVjgem.cjs"),c=require("./defaultBlocks-DosClM5E.cjs"),b=require("./TrailingNode-D-CZ76FS.cjs"),M=require("./BlockNoteSchema-DmFDeA0n.cjs"),B=require("@tiptap/core"),R=require("./EventEmitter-CLwfmbqG.cjs"),A=require("@tiptap/pm/model"),xe=require("./en-Cl87Uuyf.cjs"),K=require("@handlewithcare/prosemirror-inputrules"),Me=require("@tiptap/pm/keymap"),F=require("./BlockNoteExtension-BWw0r8Gy.cjs"),Ie=require("@tiptap/extensions/gap-cursor"),Pe=require("@tiptap/extension-link"),we=require("@tiptap/extension-text"),C=require("prosemirror-state"),N=require("prosemirror-tables"),ve=require("./ShowSelection-BxnbRvy4.cjs"),Ae=require("remark-gfm"),Ne=require("remark-parse"),H=require("remark-rehype"),Le=require("rehype-stringify"),_e=require("unified"),De=require("@tiptap/pm/state"),O=o=>o&&typeof o=="object"&&"default"in o?o:{default:o},Fe=O(Ae),Oe=O(Ne),He=O(H),$e=O(Le);function oe(o,e){const t=[{tag:`[data-inline-content-type="${o.type}"]`,contentElement:n=>{const r=n;return r.matches("[data-editable]")?r:r.querySelector("[data-editable]")||r}}];return e&&t.push({tag:"*",getAttrs(n){if(typeof n=="string")return!1;const r=e==null?void 0:e(n);return r===void 0?!1:r}}),t}function Ue(o,e){var n;const t=B.Node.create({name:o.type,inline:!0,group:"inline",draggable:(n=e.meta)==null?void 0:n.draggable,selectable:o.content==="styled",atom:o.content==="none",content:o.content==="styled"?"inline*":"",addAttributes(){return c.propsToAttributes(o.propSchema)},addKeyboardShortcuts(){return c.addInlineContentKeyboardShortcuts(o)},parseHTML(){return oe(o,e.parse)},renderHTML({node:r}){const s=this.options.editor,i=e.render.call({renderType:"dom",props:void 0},u.nodeToCustomInlineContent(r,s.schema.inlineContentSchema,s.schema.styleSchema),()=>{},s);return c.addInlineContentAttributes(i,o.type,r.attrs,o.propSchema)},addNodeView(){return r=>{const{node:s,getPos:i}=r,l=this.options.editor,a=e.render.call({renderType:"nodeView",props:r},u.nodeToCustomInlineContent(s,l.schema.inlineContentSchema,l.schema.styleSchema),d=>{const p=u.inlineContentToNodes([d],l.pmSchema),f=i();f&&l.transact(h=>h.replaceWith(f,f+s.nodeSize,p))},l);return c.addInlineContentAttributes(a,o.type,s.attrs,o.propSchema)}}});return c.createInlineContentSpecFromTipTapNode(t,o.propSchema,{...e,toExternalHTML:e.toExternalHTML,render(r,s,i){const l=e.render(r,s,i);return c.addInlineContentAttributes(l,o.type,r.props,o.propSchema)}})}function ne(o,e,t,n="before"){const r=typeof t=="string"?t:t.id,s=u.getPmSchema(o),i=e.map(p=>u.blockToNode(p,s)),l=c.getNodeById(r,o.doc);if(!l)throw new Error(`Block with ID ${r} not found`);let a=l.posBeforeNode;return n==="after"&&(a+=l.node.nodeSize),o.step(new L.ReplaceStep(a,a,new x.Slice(x.Fragment.from(i),0,0))),i.map(p=>u.nodeToBlock(p,s))}function _(o){if(!o||o.type.name!=="column")throw new Error("Invalid columnPos: does not point to column node.");const e=o.firstChild;if(!e)throw new Error("Invalid column: does not have child node.");const t=e.firstChild;if(!t)throw new Error("Invalid blockContainer: does not have child node.");return o.childCount===1&&e.childCount===1&&t.type.name==="paragraph"&&t.content.content.length===0}function re(o,e){const t=o.doc.resolve(e),n=t.nodeAfter;if(!n||n.type.name!=="columnList")throw new Error("Invalid columnListPos: does not point to columnList node.");for(let r=n.childCount-1;r>=0;r--){const s=o.doc.resolve(t.pos+1).posAtIndex(r),l=o.doc.resolve(s).nodeAfter;if(!l||l.type.name!=="column")throw new Error("Invalid columnPos: does not point to column node.");_(l)&&o.delete(s,s+l.nodeSize)}}function D(o,e){re(o,e);const n=o.doc.resolve(e).nodeAfter;if(!n||n.type.name!=="columnList")throw new Error("Invalid columnListPos: does not point to columnList node.");if(
-`);throw Error("Blocks with the following IDs could not be found in the editor: "+f)}return l.forEach(f=>D(o,f)),{insertedBlocks:r.map(f=>u.nodeToBlock(f,n)),removedBlocks:i}}function Ve(o,e,t,n,r){let s;if(e)if(typeof e=="string")s=u.inlineContentToNodes([e],o.pmSchema,n);else if(Array.isArray(e))s=u.inlineContentToNodes(e,o.pmSchema,n);else if(e.type==="tableContent")s=u.tableContentToNodes(e,o.pmSchema);else throw new u.UnreachableCaseError(e.type);else throw new Error("blockContent is required");const l=((r==null?void 0:r.document)??document).createDocumentFragment();for(const a of s)if(a.type.name!=="text"&&o.schema.inlineContentSchema[a.type.name]){const d=o.schema.inlineContentSpecs[a.type.name].implementation;if(d){const p=u.nodeToCustomInlineContent(a,o.schema.inlineContentSchema,o.schema.styleSchema),f=d.render.call({renderType:"dom",props:void 0},p,()=>{},o);if(f){if(l.appendChild(f.dom),f.contentDOM){const h=t.serializeFragment(a.content,r);f.contentDOM.dataset.editable="",f.contentDOM.appendChild(h)}continue}}}else if(a.type.name==="text"){let d=document.createTextNode(a.textContent);for(const p of a.marks.toReversed())if(p.type.name in o.schema.styleSpecs){const f=o.schema.styleSpecs[p.type.name].implementation.render(p.attrs.stringValue,o);f.contentDOM.appendChild(d),d=f.dom}else{const f=p.type.spec.toDOM(p,!0),h=x.DOMSerializer.renderSpec(document,f);h.contentDOM.appendChild(d),d=h.dom}l.appendChild(d)}else{const d=t.serializeFragment(x.Fragment.from([a]),r);l.appendChild(d)}return l}function Re(o,e,t,n){var f,h,g,m,S;const r=o.pmSchema.nodes.blockContainer,s=e.props||{};for(const[y,E]of Object.entries(o.schema.blockSchema[e.type].propSchema))!(y in s)&&E.default!==void 0&&(s[y]=E.default);const i=e.children||[],a=o.blockImplementations[e.type].implementation.render.call({renderType:"dom",props:void 0},{...e,props:s,children:i},o);if(a.contentDOM&&e.content){const y=Ve(o,e.content,t,e.type,n);a.contentDOM.appendChild(y)}if(o.pmSchema.nodes[e.type].isInGroup("bnBlock")){if(e.children&&e.children.length>0){const y=se(o,e.children,t,n);(f=a.contentDOM)==null||f.append(y)}return a.dom}const p=(g=(h=r.spec)==null?void 0:h.toDOM)==null?void 0:g.call(h,r.create({id:e.id,...s}));return(m=p.contentDOM)==null||m.appendChild(a.dom),e.children&&e.children.length>0&&((S=p.contentDOM)==null||S.appendChild(ie(o,e.children,t,n))),p.dom}function se(o,e,t,n){const s=((n==null?void 0:n.document)??document).createDocumentFragment();for(const i of e){const l=Re(o,i,t,n);s.appendChild(l)}return s}const ie=(o,e,t,n)=>{var l;const r=o.pmSchema.nodes.blockGroup,s=r.spec.toDOM(r.create({})),i=se(o,e,t,n);return(l=s.contentDOM)==null||l.appendChild(i),s.dom},ze=o=>(o.querySelectorAll('[data-content-type="numberedListItem"]').forEach(t=>{var r,s;const n=(s=(r=t.closest(".bn-block-outer"))==null?void 0:r.previousElementSibling)==null?void 0:s.querySelector('[data-content-type="numberedListItem"]');if(!n)t.setAttribute("data-index",t.getAttribute("data-start")||"1");else{const i=n.getAttribute("data-index");t.setAttribute("data-index",(parseInt(i||"0")+1).toString())}}),o),Ge=o=>(o.querySelectorAll('[data-content-type="checkListItem"] input').forEach(t=>{t.disabled=!0}),o),qe=o=>(o.querySelectorAll('.bn-toggle-wrapper[data-show-children="false"]').forEach(t=>{t.setAttribute("data-show-children","true")}),o),We=o=>(o.querySelectorAll('[data-content-type="table"] table').forEach(t=>{t.setAttribute("style",`--default-cell-min-width: ${c.EMPTY_CELL_WIDTH}px;`),t.setAttribute("data-show-children","true")}),o),je=o=>(o.querySelectorAll('[data-content-type="table"] table').forEach(t=>{var s;const n=document.createElement("div");n.className="tableWrapper";const r=document.createElement("div");r.className="tableWrapper-inner",n.appendChild(r),(s=t.parentElement)==null||s.appendChild(n),n.appendChild(t)}),o),Ke=o=>(o.querySelectorAll(".bn-inline-content:empty").forEach(t=>{const n=document.createElement("span");n.className="ProseMirror-trailingBreak",n.setAttribute("style","display: inline-block;"),t.appendChild(n)}),o),ce=(o,e)=>{const t=x.D
+`);throw Error("Blocks with the following IDs could not be found in the editor: "+f)}return l.forEach(f=>D(o,f)),{insertedBlocks:r.map(f=>u.nodeToBlock(f,n)),removedBlocks:i}}function Ve(o,e,t,n,r){let s;if(e)if(typeof e=="string")s=u.inlineContentToNodes([e],o.pmSchema,n);else if(Array.isArray(e))s=u.inlineContentToNodes(e,o.pmSchema,n);else if(e.type==="tableContent")s=u.tableContentToNodes(e,o.pmSchema);else throw new u.UnreachableCaseError(e.type);else throw new Error("blockContent is required");const l=((r==null?void 0:r.document)??document).createDocumentFragment();for(const a of s)if(a.type.name!=="text"&&o.schema.inlineContentSchema[a.type.name]){const d=o.schema.inlineContentSpecs[a.type.name].implementation;if(d){const p=u.nodeToCustomInlineContent(a,o.schema.inlineContentSchema,o.schema.styleSchema),f=d.render.call({renderType:"dom",props:void 0},p,()=>{},o);if(f){if(l.appendChild(f.dom),f.contentDOM){const h=t.serializeFragment(a.content,r);f.contentDOM.dataset.editable="",f.contentDOM.appendChild(h)}continue}}}else if(a.type.name==="text"){let d=document.createTextNode(a.textContent);for(const p of Array.from(a.marks).reverse())if(p.type.name in o.schema.styleSpecs){const f=o.schema.styleSpecs[p.type.name].implementation.render(p.attrs.stringValue,o);f.contentDOM.appendChild(d),d=f.dom}else{const f=p.type.spec.toDOM(p,!0),h=x.DOMSerializer.renderSpec(document,f);h.contentDOM.appendChild(d),d=h.dom}l.appendChild(d)}else{const d=t.serializeFragment(x.Fragment.from([a]),r);l.appendChild(d)}return l}function Re(o,e,t,n){var f,h,g,m,S;const r=o.pmSchema.nodes.blockContainer,s=e.props||{};for(const[y,E]of Object.entries(o.schema.blockSchema[e.type].propSchema))!(y in s)&&E.default!==void 0&&(s[y]=E.default);const i=e.children||[],a=o.blockImplementations[e.type].implementation.render.call({renderType:"dom",props:void 0},{...e,props:s,children:i},o);if(a.contentDOM&&e.content){const y=Ve(o,e.content,t,e.type,n);a.contentDOM.appendChild(y)}if(o.pmSchema.nodes[e.type].isInGroup("bnBlock")){if(e.children&&e.children.length>0){const y=se(o,e.children,t,n);(f=a.contentDOM)==null||f.append(y)}return a.dom}const p=(g=(h=r.spec)==null?void 0:h.toDOM)==null?void 0:g.call(h,r.create({id:e.id,...s}));return(m=p.contentDOM)==null||m.appendChild(a.dom),e.children&&e.children.length>0&&((S=p.contentDOM)==null||S.appendChild(ie(o,e.children,t,n))),p.dom}function se(o,e,t,n){const s=((n==null?void 0:n.document)??document).createDocumentFragment();for(const i of e){const l=Re(o,i,t,n);s.appendChild(l)}return s}const ie=(o,e,t,n)=>{var l;const r=o.pmSchema.nodes.blockGroup,s=r.spec.toDOM(r.create({})),i=se(o,e,t,n);return(l=s.contentDOM)==null||l.appendChild(i),s.dom},ze=o=>(o.querySelectorAll('[data-content-type="numberedListItem"]').forEach(t=>{var r,s;const n=(s=(r=t.closest(".bn-block-outer"))==null?void 0:r.previousElementSibling)==null?void 0:s.querySelector('[data-content-type="numberedListItem"]');if(!n)t.setAttribute("data-index",t.getAttribute("data-start")||"1");else{const i=n.getAttribute("data-index");t.setAttribute("data-index",(parseInt(i||"0")+1).toString())}}),o),Ge=o=>(o.querySelectorAll('[data-content-type="checkListItem"] input').forEach(t=>{t.disabled=!0}),o),qe=o=>(o.querySelectorAll('.bn-toggle-wrapper[data-show-children="false"]').forEach(t=>{t.setAttribute("data-show-children","true")}),o),We=o=>(o.querySelectorAll('[data-content-type="table"] table').forEach(t=>{t.setAttribute("style",`--default-cell-min-width: ${c.EMPTY_CELL_WIDTH}px;`),t.setAttribute("data-show-children","true")}),o),je=o=>(o.querySelectorAll('[data-content-type="table"] table').forEach(t=>{var s;const n=document.createElement("div");n.className="tableWrapper";const r=document.createElement("div");r.className="tableWrapper-inner",n.appendChild(r),(s=t.parentElement)==null||s.appendChild(n),n.appendChild(t)}),o),Ke=o=>(o.querySelectorAll(".bn-inline-content:empty").forEach(t=>{const n=document.createElement("span");n.className="ProseMirror-trailingBreak",n.setAttribute("style","display: inline-block;"),t.appendChild(n)}),o),ce=(o,e)=>{co
`)}</code></pre>`),!0):!1}function Nt({event:o,editor:e,prioritizeMarkdownOverHTML:t,plainTextAsMarkdown:n}){var l;if(e.transact(a=>a.selection.$from.parent.type.spec.code&&a.selection.$to.parent.type.spec.code)){const a=(l=o.clipboardData)==null?void 0:l.getData("text/plain");if(a)return e.pasteText(a),!0}let s;for(const a of q)if(o.clipboardData.types.includes(a)){s=a;break}if(!s)return!0;if(s==="vscode-editor-data")return At(o,e.prosemirrorView),!0;if(s==="Files")return be(o,e),!0;const i=o.clipboardData.getData(s);if(s==="blocknote/html")return e.pasteHTML(i,!0),!0;if(s==="text/markdown")return e.pasteMarkdown(i),!0;if(t){const a=o.clipboardData.getData("text/plain");if(vt(a))return e.pasteMarkdown(a),!0}return s==="text/html"?(e.pasteHTML(i),!0):n?(e.pasteMarkdown(i),!0):(e.pasteText(i),!0)}const Lt=(o,e)=>B.Extension.create({name:"pasteFromClipboard",addProseMirrorPlugins(){return[new C.Plugin({props:{handleDOMEvents:{paste(t,n){if(n.preventDefault(),!!o.isEditable)return e({event:n,editor:o,defaultPasteHandler:({prioritizeMarkdownOverHTML:r=!0,plainTextAsMarkdown:s=!0}={})=>Nt({event:n,editor:o,prioritizeMarkdownOverHTML:r,plainTextAsMarkdown:s})})}}}})]}});function _t(o,e,t){var l;let n=!1;const r=o.state.selection instanceof N.CellSelection;if(!r){const a=o.state.doc.slice(o.state.selection.from,o.state.selection.to,!1).content,d=[];for(let p=0;p<a.childCount;p++)d.push(a.child(p));n=d.find(p=>p.type.isInGroup("bnBlock")||p.type.name==="blockGroup"||p.type.spec.group==="blockContent")===void 0,n&&(e=a)}let s;const i=b.createExternalHTMLExporter(o.state.schema,t);if(r){((l=e.firstChild)==null?void 0:l.type.name)==="table"&&(e=e.firstChild.content);const a=u.contentNodeToTableContent(e,t.schema.inlineContentSchema,t.schema.styleSchema);s=`<table>${i.exportInlineContent(a,{})}</table>`}else if(n){const a=u.contentNodeToInlineContent(e,t.schema.inlineContentSchema,t.schema.styleSchema);s=i.exportInlineContent(a,{})}else{const a=b.fragmentToBlocks(e);s=i.exportBlocks(a,{})}return s}function W(o,e){"node"in o.state.selection&&o.state.selection.node.type.spec.group==="blockContent"&&e.transact(i=>i.setSelection(new C.NodeSelection(i.doc.resolve(o.state.selection.from-1))));const t=o.serializeForClipboard(o.state.selection.content()).dom.innerHTML,n=o.state.selection.content().content,r=_t(o,n,e),s=b.cleanHTMLToMarkdown(r);return{clipboardHTML:t,externalHTML:r,markdown:s}}const X=()=>{const o=window.getSelection();if(!o||o.isCollapsed)return!0;let e=o.focusNode;for(;e;){if(e instanceof HTMLElement&&e.getAttribute("contenteditable")==="false")return!0;e=e.parentElement}return!1},Z=(o,e,t)=>{t.preventDefault(),t.clipboardData.clearData();const{clipboardHTML:n,externalHTML:r,markdown:s}=W(e,o);t.clipboardData.setData("blocknote/html",n),t.clipboardData.setData("text/html",r),t.clipboardData.setData("text/plain",s)},Dt=o=>B.Extension.create({name:"copyToClipboard",addProseMirrorPlugins(){return[new C.Plugin({props:{handleDOMEvents:{copy(e,t){return X()||Z(o,e,t),!0},cut(e,t){return X()||(Z(o,e,t),e.editable&&e.dispatch(e.state.tr.deleteSelection())),!0},dragstart(e,t){if(!("node"in e.state.selection)||e.state.selection.node.type.spec.group!=="blockContent")return;o.transact(i=>i.setSelection(new C.NodeSelection(i.doc.resolve(e.state.selection.from-1)))),t.preventDefault(),t.dataTransfer.clearData();const{clipboardHTML:n,externalHTML:r,markdown:s}=W(e,o);return t.dataTransfer.setData("blocknote/html",n),t.dataTransfer.setData("text/html",r),t.dataTransfer.setData("text/plain",s),!0}}}})]}}),Ft=B.Extension.create({name:"blockBackgroundColor",addGlobalAttributes(){return[{types:["tableCell","tableHeader"],attributes:{backgroundColor:c.getBackgroundColorAttribute()}}]}}),Ot=B.Node.create({name:"hardBreak",inline:!0,group:"inline",selectable:!1,linebreakReplacement:!0,priority:10,parseHTML(){return[{tag:"br"}]},renderHTML({HTMLAttributes:o}){return["br",B.mergeAttributes(this.options.HTMLAttributes,o)]},renderText(){return`
`}}),V=(o,e)=>{const t=o.resolve(e),n=t.index();if(n===0)return;const r=t.posAtIndex(n-1);return u.getBlockInfoFromResolvedPos(o.resolve(r))},Se=(o,e)=>{for(;e.childContainer;){const t=e.childContainer.node,n=o.resolve(e.childContainer.beforePos+1).posAtIndex(t.childCount-1);e=u.getBlockInfoFromResolvedPos(o.resolve(n))}return e},Ht=(o,e)=>o.isBlockContainer&&o.blockContent.node.type.spec.content==="inline*"&&o.blockContent.node.childCount>0&&e.isBlockContainer&&e.blockContent.node.type.spec.content==="inline*",$t=(o,e,t,n)=>{if(!n.isBlockContainer)throw new Error(`Attempted to merge block at position ${n.bnBlock.beforePos} into previous block at position ${t.bnBlock.beforePos}, but next block is not a block container`);if(n.childContainer){const r=o.doc.resolve(n.childContainer.beforePos+1),s=o.doc.resolve(n.childContainer.afterPos-1),i=r.blockRange(s);if(e){const l=o.doc.resolve(n.bnBlock.beforePos);o.tr.lift(i,l.depth)}}if(e){if(!t.isBlockContainer)throw new Error(`Attempted to merge block at position ${n.bnBlock.beforePos} into previous block at position ${t.bnBlock.beforePos}, but previous block is not a block container`);e(o.tr.delete(t.blockContent.afterPos-1,n.blockContent.beforePos+1))}return!0},ee=o=>({state:e,dispatch:t})=>{const n=e.doc.resolve(o),r=u.getBlockInfoFromResolvedPos(n),s=V(e.doc,r.bnBlock.beforePos);if(!s)return!1;const i=Se(e.doc,s);return Ht(i,r)?$t(e,t,i,r):!1},Ut=B.Extension.create({priority:50,addKeyboardShortcuts(){const o=()=>this.editor.commands.first(({chain:n,commands:r})=>[()=>r.deleteSelection(),()=>r.undoInputRule(),()=>r.command(({state:s})=>{const i=u.getBlockInfoFromSelection(s);if(!i.isBlockContainer)return!1;const l=s.selection.from===i.blockContent.beforePos+1,a=i.blockContent.node.type.name==="paragraph";return l&&!a?r.command(c.updateBlockCommand(i.bnBlock.beforePos,{type:"paragraph",props:{}})):!1}),()=>r.command(({state:s})=>{const i=u.getBlockInfoFromSelection(s);if(!i.isBlockContainer)return!1;const{blockContent:l}=i;return s.selection.from===l.beforePos+1?r.liftListItem("blockContainer"):!1}),()=>r.command(({state:s})=>{const i=u.getBlockInfoFromSelection(s);if(!i.isBlockContainer)return!1;const{bnBlock:l,blockContent:a}=i,d=s.selection.from===a.beforePos+1,p=s.selection.empty,f=l.beforePos;return d&&p?n().command(ee(f)).scrollIntoView().run():!1}),()=>r.command(({state:s,tr:i,dispatch:l})=>{const a=u.getBlockInfoFromSelection(s);if(!a.isBlockContainer||!(i.selection.from===a.blockContent.beforePos+1))return!1;const p=i.doc.resolve(a.bnBlock.beforePos);if(p.nodeBefore||p.node().type.name!=="column")return!1;const g=i.doc.resolve(a.bnBlock.beforePos),m=i.doc.resolve(g.before()),S=m.before();if(l){const y=i.doc.slice(a.bnBlock.beforePos,a.bnBlock.afterPos).content;i.delete(a.bnBlock.beforePos,a.bnBlock.afterPos),m.index()===0?(D(i,S),i.insert(S,y),i.setSelection(C.TextSelection.near(i.doc.resolve(S)))):(i.insert(m.pos-1,y),i.setSelection(C.TextSelection.near(i.doc.resolve(m.pos-1))),D(i,S))}return!0}),()=>r.command(({state:s})=>{const i=u.getBlockInfoFromSelection(s);if(!i.isBlockContainer)return!1;if(i.blockContent.node.childCount===0&&i.blockContent.node.type.spec.content==="inline*"){const a=V(s.doc,i.bnBlock.beforePos);if(!a||!a.isBlockContainer)return!1;let d=n();if(a.blockContent.node.type.spec.content==="tableRow+"){const m=i.bnBlock.beforePos-1-1-1-1-1;d=d.setTextSelection(m)}else if(a.blockContent.node.type.spec.content===""){const p=a.blockContent.afterPos-a.blockContent.node.nodeSize;d=d.setNodeSelection(p)}else{const p=a.blockContent.afterPos-a.blockContent.node.nodeSize;d=d.setTextSelection(p)}return d.deleteRange({from:i.bnBlock.beforePos,to:i.bnBlock.afterPos}).scrollIntoView().run()}return!1}),()=>r.command(({state:s})=>{const i=u.getBlockInfoFromSelection(s);if(!i.isBlockContainer)throw new Error("todo");const l=s.selection.from===i.blockContent.beforePos+1,a=s.selection.empty,d=V(s.doc,i.bnBlock.beforePos);if(d&&l&&a){const p=Se(s.doc,d);if(!p.isBlockContainer)throw new Error("todo");if(p.blockContent.node.type.spec.content===""||p.blockContent.node.typ
//# sourceMappingURL=blocknote.cjs.map
2026-05-01 12:55:23 +02:00
diff --git a/dist/blocknote.js b/dist/blocknote.js
index 0f97dc48ddedfb9661b81c7469ce504dc974e284..e1af7dbc1e590a4cc7cdd4ec921b7b683c3ebb97 100644
2026-05-01 12:55:23 +02:00
--- a/dist/blocknote.js
+++ b/dist/blocknote.js
@@ -313,7 +313,7 @@ function Qt(o, e, t, n, s) {
let l = document.createTextNode(
i.textContent
);
- for (const d of i.marks.toReversed())
+ for (const d of Array.from(i.marks).reverse())
if (d.type.name in o.schema.styleSpecs) {
const u = o.schema.styleSpecs[d.type.name].implementation.render(d.attrs.stringValue, o);
u.contentDOM.appendChild(l), l = u.dom;
2026-05-01 12:55:23 +02:00
@@ -2037,7 +2037,9 @@ const de = () => {
]
})
);
-let fe = !1;
+const bnLinkifyProtocolFlag = "__tolariaBlockNoteLinkifyProtocolsRegistered";
+const bnGlobalObject = typeof globalThis > "u" ? void 0 : globalThis;
+let fe = Boolean(bnGlobalObject && bnGlobalObject[bnLinkifyProtocolFlag]);
function mn(o, e) {
const t = [
I.ClipboardTextSerializer,
@@ -2062,7 +2064,10 @@ function mn(o, e) {
}).configure({
defaultProtocol: Ct,
// only call this once if we have multiple editors installed. Or fix https://github.com/ueberdosis/tiptap/issues/5450
- protocols: fe ? [] : Bt
+ // Tolaria routes editor link clicks through its guarded native opener.
+ openOnClick: !1,
+ // Tolaria pre-registers BlockNote's non-native protocols before linkify initializes.
+ protocols: []
}),
...Object.values(o.schema.styleSpecs).map((n) => n.implementation.mark.configure({
editor: o
@@ -2112,7 +2117,7 @@ function mn(o, e) {
),
Do(o)
];
- return fe = !0, t;
+ return fe = !0, bnGlobalObject && (bnGlobalObject[bnLinkifyProtocolFlag] = !0), t;
}
function kn(o, e) {
const t = [
diff --git a/dist/defaultBlocks-DE5GNdJH.js b/dist/defaultBlocks-DE5GNdJH.js
index b2761001278486a8b2ac1d10c82420b4994e96d9..059837e3da55611d9c09437bcdb1014587451332 100644
--- a/dist/defaultBlocks-DE5GNdJH.js
+++ b/dist/defaultBlocks-DE5GNdJH.js
2026-05-01 12:55:23 +02:00
@@ -1120,6 +1120,8 @@ const Ut = ({ defaultLanguage: e = "text" }) => ({
2026-04-30 04:19:10 +02:00
), i.value = t.props.language || e.defaultLanguage || "text", n.isEditable) {
const l = (u) => {
const d = u.target.value;
+ if (!n.getBlock(t.id))
+ return;
n.updateBlock(t.id, { props: { language: d } });
};
i.addEventListener("change", l), s = () => i.removeEventListener("change", l);
@@ -1167,9 +1169,7 @@ const Ut = ({ defaultLanguage: e = "text" }) => ({
const { block: o, nextBlock: r } = t.getTextCursorPosition();
if (o.type !== "codeBlock")
return !1;
- const { $from: a } = n.selection, s = a.parentOffset === a.parent.nodeSize - 2, i = a.parent.textContent.endsWith(`
-
-`);
+ const { $from: a } = n.selection, s = a.parentOffset === a.parent.nodeSize - 2, i = a.parent.textContent.endsWith("\n ");
if (s && i) {
if (n.delete(a.pos - 2, a.pos), r)
return t.setTextCursorPosition(r, "start"), !0;
@@ -1801,7 +1801,10 @@ const sn = () => ({
2026-05-03 17:27:03 +02:00
render(e, t) {
const n = document.createDocumentFragment(), o = document.createElement("input");
o.type = "checkbox", o.checked = e.props.checked, e.props.checked && o.setAttribute("checked", ""), o.addEventListener("change", () => {
- t.updateBlock(e, { props: { checked: !e.props.checked } });
+ const r = t.getBlock(e.id);
+ if (!r)
+ return;
+ t.updateBlock(r, { props: { checked: !r.props.checked } });
});
const r = document.createElement("p"), a = document.createElement("div");
return a.contentEditable = "false", a.appendChild(o), n.appendChild(a), n.appendChild(r), {
@@ -2621,6 +2624,9 @@ class On {
this.state.referencePos = o.getBoundingClientRect().toJSON(), this.emitUpdate(this.pluginState.triggerCharacter);
}
});
+ M(this, "hideMenu", (t) => {
+ this.state && (this.state.show = !1, this.emitUpdate(t));
+ });
M(this, "closeMenu", () => {
this.editor.transact((t) => t.setMeta(B, null));
});
@@ -2634,7 +2640,7 @@ class On {
this.editor = t, this.pluginState = void 0, this.emitUpdate = (a) => {
var s;
if (!this.state)
- throw new Error("Attempting to update uninitialized suggestions menu");
+ return;
n(a, {
...this.state,
ignoreQueryLength: (s = this.pluginState) == null ? void 0 : s.ignoreQueryLength
@@ -2649,17 +2655,21 @@ class On {
if (!a && !(o !== void 0 && r !== void 0) && !s)
return;
if (this.pluginState = s ? o : r, s || !this.editor.isEditable) {
- this.state && (this.state.show = !1), this.emitUpdate(this.pluginState.triggerCharacter);
+ this.hideMenu(this.pluginState.triggerCharacter);
return;
}
const c = (l = this.rootEl) == null ? void 0 : l.querySelector(
`[data-decoration-id="${this.pluginState.decorationId}"]`
);
- this.editor.isEditable && c && (this.state = {
+ if (!c) {
+ this.hideMenu(this.pluginState.triggerCharacter);
+ return;
+ }
+ this.state = {
show: !0,
referencePos: c.getBoundingClientRect().toJSON(),
query: this.pluginState.query
- }, this.emitUpdate(this.pluginState.triggerCharacter));
+ }, this.emitUpdate(this.pluginState.triggerCharacter);
}
destroy() {
var t;
@@ -2761,7 +2771,7 @@ const B = new Ze("SuggestionMenuPlugin"), _n = k(({ editor: e }) => {
if (a === s) {
const c = r.state.doc;
for (const l of t) {
- const u = l.length > 1 ? c.textBetween(a - l.length, a) + i : i;
+ const u = l.length > 1 ? c.textBetween(a - (l.length - 1), a) + i : i;
if (l === u)
return r.dispatch(r.state.tr.insertText(i)), r.dispatch(
r.state.tr.setMeta(B, {
diff --git a/dist/defaultBlocks-DosClM5E.cjs b/dist/defaultBlocks-DosClM5E.cjs
index ea3664446059a2515aa149d10b1e1ee924388300..c6165d082fa12c83a72efbbce82da189f081ba90 100644
--- a/dist/defaultBlocks-DosClM5E.cjs
+++ b/dist/defaultBlocks-DosClM5E.cjs
@@ -1,6 +1,4 @@
"use strict";var Nt=Object.defineProperty;var It=(e,t,n)=>t in e?Nt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var P=(e,t,n)=>It(e,typeof t!="symbol"?t+"":t,n);const T=require("prosemirror-tables"),S=require("@tiptap/core"),z=require("prosemirror-state"),$=require("prosemirror-view"),ye=require("prosemirror-transform"),j=require("y-prosemirror"),y=require("./BlockNoteExtension-BWw0r8Gy.cjs"),m=require("./blockToNode-CumVjgem.cjs"),Ht=require("@tiptap/extension-bold"),Dt=require("@tiptap/extension-code"),_t=require("@tiptap/extension-italic"),Ot=require("@tiptap/extension-strike"),Vt=require("@tiptap/extension-underline"),R=require("@tiptap/pm/model"),Ft=require("prosemirror-highlight"),Rt=require("prosemirror-highlight/shiki"),N=require("prosemirror-model"),fe=require("@tiptap/pm/state"),ee=require("@tiptap/pm/view"),q=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},Wt=q(Ht),qt=q(Dt),Ut=q(_t),$t=q(Ot),jt=q(Vt),ve=()=>typeof navigator<"u"&&(/Mac/.test(navigator.platform)||/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent));function B(e,t="Ctrl"){return ve()?e.replace("Mod","⌘"):e.replace("Mod",t)}function V(...e){return[...new Set(e.filter(t=>t).join(" ").split(" "))].join(" ")}const Gt=()=>/^((?!chrome|android).)*safari/i.test(navigator.userAgent);function Se(e,t,n,o){const r=document.createElement("div");r.className=V("bn-block-content",n.class),r.setAttribute("data-content-type",e);for(const[s,i]of Object.entries(n))s!=="class"&&r.setAttribute(s,i);const a=document.createElement(t);a.className=V("bn-inline-content",o.class);for(const[s,i]of Object.entries(o))s!=="class"&&a.setAttribute(s,i);return r.appendChild(a),{dom:r,contentDOM:a}}const te=(e,t)=>{let n=m.blockToNode(e,t.pmSchema);n.type.name==="blockContainer"&&(n=n.firstChild);const o=t.pmSchema.nodes[n.type.name].spec.toDOM;if(o===void 0)throw new Error("This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.");const r=o(n);if(typeof r!="object"||!("dom"in r))throw new Error("Cannot use this block's default HTML serialization as its corresponding TipTap node's `renderHTML` function does not return an object with the `dom` property.");return r};function Ee(e,t="<br>"){const n=e.querySelectorAll("p");if(n.length>1){const o=n[0];for(let r=1;r<n.length;r++){const a=n[r];o.innerHTML+=t+a.innerHTML,a.remove()}}}function W(e){return"data-"+e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function Zt(e){const t=e.split("/");return!t.length||t[t.length-1]===""?e:t[t.length-1]}function zt(e){var n;const t=["mp4","webm","ogg","mov","mkv","flv","avi","wmv","m4v"];try{const r=((n=new URL(e).pathname.split(".").pop())==null?void 0:n.toLowerCase())||"";return t.includes(r)}catch{return!1}}function xe(e){const t={};return Object.entries(e).forEach(([n,o])=>{t[n]={default:o.default,keepOnSplit:!0,parseHTML:r=>{const a=r.getAttribute(W(n));if(a===null)return null;if(o.default===void 0&&o.type==="boolean"||o.default!==void 0&&typeof o.default=="boolean")return a==="true"?!0:a==="false"?!1:null;if(o.default===void 0&&o.type==="number"||o.default!==void 0&&typeof o.default=="number"){const s=parseFloat(a);return!Number.isNaN(s)&&Number.isFinite(s)?s:null}return a},renderHTML:r=>r[n]!==o.default?{[W(n)]:r[n]}:{}}}),t}function Me(e,t,n,o){const r=e();if(r===void 0)throw new Error("Cannot find node position");const s=n.state.doc.resolve(r).node().attrs.id;if(!s)throw new Error("Block doesn't have id");const i=t.getBlock(s);if(i.type!==o)throw new Error("Block type does not match");return i}function Z(e,t,n,o,r=!1,a){const s=document.createElement("div");if(a!==void 0)for(const[i,c]of Object.entries(a))i!=="class"&&s.setAttribute(i,c);s.className=V("bn-block-content",(a==null?void 0:a.class)||""),s.setAttribute("data-content-type",t);for(const[i,c]of Object.entries(n)){const u=o[i].default;c!==u&&s.setAttribute(W(i),c)}return r&&s.setAttribute("data-file-block",""),s.appendChild(e.dom),e.contentDOM&&(e.contentDOM.className=V("bn-inline-content",e.contentDOM.className)),{.
-`:"<br>"),R.DOMParser.fromSchema(r).parse(i,{topNode:r.nodes.paragraph.create(),preserveWhitespace:!0}).content}return R.Fragment.empty}:void 0}),n}function Kt(e,t,n,o){var a,s,i,c;const r=t.node||S.Node.create({name:e.type,content:e.content==="inline"?"inline*":e.content==="none"?"":e.content,group:"blockContent",selectable:((a=t.meta)==null?void 0:a.selectable)??!0,isolating:((s=t.meta)==null?void 0:s.isolating)??!0,code:((i=t.meta)==null?void 0:i.code)??!1,defining:((c=t.meta)==null?void 0:c.defining)??!0,priority:o,addAttributes(){return xe(e.propSchema)},parseHTML(){return Be(e,t)},renderHTML({HTMLAttributes:l}){var d;const u=document.createElement("div");return Z({dom:u,contentDOM:e.content==="inline"?u:void 0},e.type,{},e.propSchema,((d=t.meta)==null?void 0:d.fileBlockAccept)!==void 0,l)},addNodeView(){return l=>{var f,x;const u=this.options.editor,d=Me(l.getPos,u,this.editor,e.type),p=((f=this.options.domAttributes)==null?void 0:f.blockContent)||{},h=t.render.call({blockContentDOMAttributes:p,props:l,renderType:"nodeView"},d,u);return((x=t.meta)==null?void 0:x.selectable)===!1&&we(h,this.editor),h}}});if(r.name!==e.type)throw new Error("Node name does not match block type. This is a bug in BlockNote.");return{config:e,implementation:{...t,node:r,render(l,u){var p;const d=((p=r.options.domAttributes)==null?void 0:p.blockContent)||{};return t.render.call({blockContentDOMAttributes:d,props:void 0,renderType:"dom"},l,u)},toExternalHTML:(l,u,d)=>{var h,f;const p=((h=r.options.domAttributes)==null?void 0:h.blockContent)||{};return((f=t.toExternalHTML)==null?void 0:f.call({blockContentDOMAttributes:p},l,u,d))??t.render.call({blockContentDOMAttributes:p,renderType:"dom",props:void 0},l,u)}},extensions:n}}function Xt(e){return e}function E(e,t,n){return(o={})=>{const r=typeof e=="function"?e(o):e,a=typeof t=="function"?t(o):t,s=n?typeof n=="function"?n(o):n:void 0;return{config:r,implementation:{...a,toExternalHTML(i,c,l){var d,p;const u=(d=a.toExternalHTML)==null?void 0:d.call({blockContentDOMAttributes:this.blockContentDOMAttributes},i,c,l);if(u!==void 0)return Z(u,i.type,i.props,r.propSchema,((p=a.meta)==null?void 0:p.fileBlockAccept)!==void 0)},render(i,c){var d;const l=a.render.call({blockContentDOMAttributes:this.blockContentDOMAttributes,renderType:this.renderType,props:this.props},i,c);return Z(l,i.type,i.props,r.propSchema,((d=a.meta)==null?void 0:d.fileBlockAccept)!==void 0,this.blockContentDOMAttributes)}},extensions:s}}}function Qt(e,t,n,o){return e.dom.setAttribute("data-inline-content-type",t),Object.entries(n).filter(([r,a])=>{const s=o[r];return a!==s.default}).map(([r,a])=>[W(r),a]).forEach(([r,a])=>e.dom.setAttribute(r,a)),e.contentDOM&&e.contentDOM.setAttribute("data-editable",""),e}function Yt(e){return{Backspace:({editor:t})=>{const n=t.state.selection.$from;return t.state.selection.empty&&n.node().type.name===e.type&&n.parentOffset===0}}}function Te(e,t){return{config:e,implementation:t}}function Jt(e,t,n){return Te({type:e.name,propSchema:t,content:e.config.content==="inline*"?"styled":"none"},{...n,node:e})}function Ae(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n.config]))}function Pe(e){return e==="boolean"?{}:{stringValue:{default:void 0,keepOnSplit:!0,parseHTML:t=>t.getAttribute("data-value"),renderHTML:t=>t.stringValue!==void 0?{"data-value":t.stringValue}:{}}}}function F(e,t,n,o){return e.dom.setAttribute("data-style-type",t),o==="string"&&e.dom.setAttribute("data-value",n),e.contentDOM&&e.contentDOM.setAttribute("data-editable",""),e}function oe(e,t){return{config:e,implementation:t}}function _(e,t){return oe({type:e.name,propSchema:t},{mark:e,render(n,o){const r=o.pmSchema.marks[e.name].spec.toDOM;if(r===void 0)throw new Error("This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.");const a=o.pmSchema.mark(e.name,{stringValue:n}),s=R.DOMSerializer.renderSpec(document,r(a,!0));if(typeof s!="object"||!("dom"in s))throw new Error("Cannot use this block's default HTML serialization as its corresponding TipTap mark's `r
-
-`);if(s&&i){if(n.delete(a.pos-2,a.pos),r)return t.setTextCursorPosition(r,"start"),!0;const[c]=t.insertBlocks([{type:"paragraph"}],o,"after");return t.setTextCursorPosition(c,"start"),!0}return n.insertText(`
-`),!0}),"Shift-Enter":({editor:t})=>t.transact(()=>{const{block:n}=t.getTextCursorPosition();if(n.type!=="codeBlock")return!1;const[o]=t.insertBlocks([{type:"paragraph"}],n,"after");return t.setTextCursorPosition(o,"start"),!0})},inputRules:[{find:/^```(.*?)\s$/,replace:({match:t})=>{const n=t[1].trim();return{type:"codeBlock",props:{language:{language:ie(e,n)??n}.language},content:[]}}}]})]);function ie(e,t){var n;return(n=Object.entries(e.supportedLanguages??{}).find(([o,{aliases:r}])=>(r==null?void 0:r.includes(t))||o===t))==null?void 0:n[0]}const je=()=>({type:"divider",propSchema:{},content:"none"}),Ge=E(je,{meta:{isolating:!1},parse(e){if(e.tagName==="HR")return{}},render(){return{dom:document.createElement("hr")}}},[y.createExtension({key:"divider-block-shortcuts",inputRules:[{find:new RegExp("^---$"),replace(){return{type:"divider",props:{},content:[]}}}]})]),me=e=>({url:e.src||void 0}),Ze=()=>({type:"file",propSchema:{backgroundColor:g.backgroundColor,name:{default:""},url:{default:""},caption:{default:""}},content:"none"}),ze=()=>e=>{if(e.tagName==="EMBED"){if(e.closest("figure"))return;const{backgroundColor:t}=v(e);return{...me(e),backgroundColor:t}}if(e.tagName==="FIGURE"){const t=X(e,"embed");if(!t)return;const{targetElement:n,caption:o}=t,{backgroundColor:r}=v(e);return{...me(n),backgroundColor:r,caption:o}}},Ke=E(Ze,{meta:{fileBlockAccept:["*/*"]},parse:ze(),render(e,t){return ae(e,t)},toExternalHTML(e){if(!e.props.url){const n=document.createElement("p");return n.textContent="Add file",{dom:n}}const t=document.createElement("a");return t.href=e.props.url,t.textContent=e.props.name||e.props.url,e.props.caption?Q(t,e.props.caption):{dom:t}}}),Xe={set:(e,t)=>window.localStorage.setItem(`toggle-${e.id}`,t?"true":"false"),get:e=>window.localStorage.getItem(`toggle-${e.id}`)==="true"},ce=(e,t,n,o=Xe)=>{if("isToggleable"in e.props&&!e.props.isToggleable)return{dom:n};const r=document.createElement("div"),a=document.createElement("div");a.className="bn-toggle-wrapper";const s=document.createElement("button");s.className="bn-toggle-button",s.type="button",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="CURRENTCOLOR"><path d="M320-200v-560l440 280-440 280Z"/></svg>';const i=f=>f.preventDefault();s.addEventListener("mousedown",i);const c=()=>{var f;a.getAttribute("data-show-children")==="true"?(a.setAttribute("data-show-children","false"),o.set(t.getBlock(e),!1),r.contains(l)&&r.removeChild(l)):(a.setAttribute("data-show-children","true"),o.set(t.getBlock(e),!0),t.isEditable&&((f=t.getBlock(e))==null?void 0:f.children.length)===0&&!r.contains(l)&&r.appendChild(l))};s.addEventListener("click",c),a.appendChild(s),a.appendChild(n);const l=document.createElement("button");l.className="bn-toggle-add-block-button",l.type="button",l.textContent=t.dictionary.toggle_blocks.add_block_button;const u=f=>f.preventDefault();l.addEventListener("mousedown",u);const d=()=>{t.transact(()=>{const f=t.updateBlock(e,{children:[{}]});t.setTextCursorPosition(f.children[0].id,"end"),t.focus()})};l.addEventListener("click",d),r.appendChild(a);let p=e.children.length;const h=t.onChange(()=>{var x;const f=((x=t.getBlock(e))==null?void 0:x.children.length)??0;f>p?(a.getAttribute("data-show-children")==="false"&&(a.setAttribute("data-show-children","true"),o.set(t.getBlock(e),!0)),r.contains(l)&&r.removeChild(l)):f===0&&f<p&&(a.getAttribute("data-show-children")==="true"&&(a.setAttribute("data-show-children","false"),o.set(t.getBlock(e),!1)),r.contains(l)&&r.removeChild(l)),p=f});return o.get(e)?(a.setAttribute("data-show-children","true"),t.isEditable&&e.children.length===0&&r.appendChild(l)):a.setAttribute("data-show-children","false"),{dom:r,ignoreMutation:f=>f instanceof MutationRecord&&(f.type==="attributes"&&f.target===a&&f.attributeName==="data-show-children"||f.type==="childList"&&(f.addedNodes[0]===l||f.removedNodes[0]===l)),destroy:()=>{s.removeEventListener("mousedown",i),s.removeEventListener("click",c),l.removeEventListener("mousedown",u),l.removeEventListener("click"
+`:"<br>"),R.DOMParser.fromSchema(r).parse(i,{topNode:r.nodes.paragraph.create(),preserveWhitespace:!0}).content}return R.Fragment.empty}:void 0}),n}function Kt(e,t,n,o){var a,s,i,c;const r=t.node||S.Node.create({name:e.type,content:e.content==="inline"?"inline*":e.content==="none"?"":e.content,group:"blockContent",selectable:((a=t.meta)==null?void 0:a.selectable)??!0,isolating:((s=t.meta)==null?void 0:s.isolating)??!0,code:((i=t.meta)==null?void 0:i.code)??!1,defining:((c=t.meta)==null?void 0:c.defining)??!0,priority:o,addAttributes(){return xe(e.propSchema)},parseHTML(){return Be(e,t)},renderHTML({HTMLAttributes:l}){var d;const u=document.createElement("div");return Z({dom:u,contentDOM:e.content==="inline"?u:void 0},e.type,{},e.propSchema,((d=t.meta)==null?void 0:d.fileBlockAccept)!==void 0,l)},addNodeView(){return l=>{var f,x;const u=this.options.editor,d=Me(l.getPos,u,this.editor,e.type),p=((f=this.options.domAttributes)==null?void 0:f.blockContent)||{},h=t.render.call({blockContentDOMAttributes:p,props:l,renderType:"nodeView"},d,u);return((x=t.meta)==null?void 0:x.selectable)===!1&&we(h,this.editor),h}}});if(r.name!==e.type)throw new Error("Node name does not match block type. This is a bug in BlockNote.");return{config:e,implementation:{...t,node:r,render(l,u){var p;const d=((p=r.options.domAttributes)==null?void 0:p.blockContent)||{};return t.render.call({blockContentDOMAttributes:d,props:void 0,renderType:"dom"},l,u)},toExternalHTML:(l,u,d)=>{var h,f;const p=((h=r.options.domAttributes)==null?void 0:h.blockContent)||{};return((f=t.toExternalHTML)==null?void 0:f.call({blockContentDOMAttributes:p},l,u,d))??t.render.call({blockContentDOMAttributes:p,renderType:"dom",props:void 0},l,u)}},extensions:n}}function Xt(e){return e}function E(e,t,n){return(o={})=>{const r=typeof e=="function"?e(o):e,a=typeof t=="function"?t(o):t,s=n?typeof n=="function"?n(o):n:void 0;return{config:r,implementation:{...a,toExternalHTML(i,c,l){var d,p;const u=(d=a.toExternalHTML)==null?void 0:d.call({blockContentDOMAttributes:this.blockContentDOMAttributes},i,c,l);if(u!==void 0)return Z(u,i.type,i.props,r.propSchema,((p=a.meta)==null?void 0:p.fileBlockAccept)!==void 0)},render(i,c){var d;const l=a.render.call({blockContentDOMAttributes:this.blockContentDOMAttributes,renderType:this.renderType,props:this.props},i,c);return Z(l,i.type,i.props,r.propSchema,((d=a.meta)==null?void 0:d.fileBlockAccept)!==void 0,this.blockContentDOMAttributes)}},extensions:s}}}function Qt(e,t,n,o){return e.dom.setAttribute("data-inline-content-type",t),Object.entries(n).filter(([r,a])=>{const s=o[r];return a!==s.default}).map(([r,a])=>[W(r),a]).forEach(([r,a])=>e.dom.setAttribute(r,a)),e.contentDOM&&e.contentDOM.setAttribute("data-editable",""),e}function Yt(e){return{Backspace:({editor:t})=>{const n=t.state.selection.$from;return t.state.selection.empty&&n.node().type.name===e.type&&n.parentOffset===0}}}function Te(e,t){return{config:e,implementation:t}}function Jt(e,t,n){return Te({type:e.name,propSchema:t,content:e.config.content==="inline*"?"styled":"none"},{...n,node:e})}function Ae(e){return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n.config]))}function Pe(e){return e==="boolean"?{}:{stringValue:{default:void 0,keepOnSplit:!0,parseHTML:t=>t.getAttribute("data-value"),renderHTML:t=>t.stringValue!==void 0?{"data-value":t.stringValue}:{}}}}function F(e,t,n,o){return e.dom.setAttribute("data-style-type",t),o==="string"&&e.dom.setAttribute("data-value",n),e.contentDOM&&e.contentDOM.setAttribute("data-editable",""),e}function oe(e,t){return{config:e,implementation:t}}function _(e,t){return oe({type:e.name,propSchema:t},{mark:e,render(n,o){const r=o.pmSchema.marks[e.name].spec.toDOM;if(r===void 0)throw new Error("This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.");const a=o.pmSchema.mark(e.name,{stringValue:n}),s=R.DOMSerializer.renderSpec(document,r(a,!0));if(typeof s!="object"||!("dom"in s))throw new Error("Cannot use this block's default HTML serialization as its corresponding TipTap mark's `r
+`),!0}),"Shift-Enter":({editor:t})=>t.transact(()=>{const{block:n}=t.getTextCursorPosition();if(n.type!=="codeBlock")return!1;const[o]=t.insertBlocks([{type:"paragraph"}],n,"after");return t.setTextCursorPosition(o,"start"),!0})},inputRules:[{find:/^```(.*?)\s$/,replace:({match:t})=>{const n=t[1].trim();return{type:"codeBlock",props:{language:{language:ie(e,n)??n}.language},content:[]}}}]})]);function ie(e,t){var n;return(n=Object.entries(e.supportedLanguages??{}).find(([o,{aliases:r}])=>(r==null?void 0:r.includes(t))||o===t))==null?void 0:n[0]}const je=()=>({type:"divider",propSchema:{},content:"none"}),Ge=E(je,{meta:{isolating:!1},parse(e){if(e.tagName==="HR")return{}},render(){return{dom:document.createElement("hr")}}},[y.createExtension({key:"divider-block-shortcuts",inputRules:[{find:new RegExp("^---$"),replace(){return{type:"divider",props:{},content:[]}}}]})]),me=e=>({url:e.src||void 0}),Ze=()=>({type:"file",propSchema:{backgroundColor:g.backgroundColor,name:{default:""},url:{default:""},caption:{default:""}},content:"none"}),ze=()=>e=>{if(e.tagName==="EMBED"){if(e.closest("figure"))return;const{backgroundColor:t}=v(e);return{...me(e),backgroundColor:t}}if(e.tagName==="FIGURE"){const t=X(e,"embed");if(!t)return;const{targetElement:n,caption:o}=t,{backgroundColor:r}=v(e);return{...me(n),backgroundColor:r,caption:o}}},Ke=E(Ze,{meta:{fileBlockAccept:["*/*"]},parse:ze(),render(e,t){return ae(e,t)},toExternalHTML(e){if(!e.props.url){const n=document.createElement("p");return n.textContent="Add file",{dom:n}}const t=document.createElement("a");return t.href=e.props.url,t.textContent=e.props.name||e.props.url,e.props.caption?Q(t,e.props.caption):{dom:t}}}),Xe={set:(e,t)=>window.localStorage.setItem(`toggle-${e.id}`,t?"true":"false"),get:e=>window.localStorage.getItem(`toggle-${e.id}`)==="true"},ce=(e,t,n,o=Xe)=>{if("isToggleable"in e.props&&!e.props.isToggleable)return{dom:n};const r=document.createElement("div"),a=document.createElement("div");a.className="bn-toggle-wrapper";const s=document.createElement("button");s.className="bn-toggle-button",s.type="button",s.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="CURRENTCOLOR"><path d="M320-200v-560l440 280-440 280Z"/></svg>';const i=f=>f.preventDefault();s.addEventListener("mousedown",i);const c=()=>{var f;a.getAttribute("data-show-children")==="true"?(a.setAttribute("data-show-children","false"),o.set(t.getBlock(e),!1),r.contains(l)&&r.removeChild(l)):(a.setAttribute("data-show-children","true"),o.set(t.getBlock(e),!0),t.isEditable&&((f=t.getBlock(e))==null?void 0:f.children.length)===0&&!r.contains(l)&&r.appendChild(l))};s.addEventListener("click",c),a.appendChild(s),a.appendChild(n);const l=document.createElement("button");l.className="bn-toggle-add-block-button",l.type="button",l.textContent=t.dictionary.toggle_blocks.add_block_button;const u=f=>f.preventDefault();l.addEventListener("mousedown",u);const d=()=>{t.transact(()=>{const f=t.updateBlock(e,{children:[{}]});t.setTextCursorPosition(f.children[0].id,"end"),t.focus()})};l.addEventListener("click",d),r.appendChild(a);let p=e.children.length;const h=t.onChange(()=>{var x;const f=((x=t.getBlock(e))==null?void 0:x.children.length)??0;f>p?(a.getAttribute("data-show-children")==="false"&&(a.setAttribute("data-show-children","true"),o.set(t.getBlock(e),!0)),r.contains(l)&&r.removeChild(l)):f===0&&f<p&&(a.getAttribute("data-show-children")==="true"&&(a.setAttribute("data-show-children","false"),o.set(t.getBlock(e),!1)),r.contains(l)&&r.removeChild(l)),p=f});return o.get(e)?(a.setAttribute("data-show-children","true"),t.isEditable&&e.children.length===0&&r.appendChild(l)):a.setAttribute("data-show-children","false"),{dom:r,ignoreMutation:f=>f instanceof MutationRecord&&(f.type==="attributes"&&f.target===a&&f.attributeName==="data-show-children"||f.type==="childList"&&(f.addedNodes[0]===l||f.removedNodes[0]===l)),destroy:()=>{s.removeEventListener("mousedown",i),s.removeEventListener("click",c),l.removeEventListener("mousedown",u),l.removeEventListener("click"
//# sourceMappingURL=defaultBlocks-DosClM5E.cjs.map
diff --git a/src/api/exporters/html/util/serializeBlocksExternalHTML.ts b/src/api/exporters/html/util/serializeBlocksExternalHTML.ts
index fb993f8309d9509df9b2dea85456dd587157d13a..d6dc4a08714d441ccadc297189a4ff8b20bc26ad 100644
--- a/src/api/exporters/html/util/serializeBlocksExternalHTML.ts
+++ b/src/api/exporters/html/util/serializeBlocksExternalHTML.ts
@@ -116,7 +116,7 @@ export function serializeInlineContentExternalHTML<
node.textContent,
);
// Reverse the order of marks to maintain the correct priority.
- for (const mark of node.marks.toReversed()) {
+ for (const mark of Array.from(node.marks).reverse()) {
if (mark.type.name in editor.schema.styleSpecs) {
const newDom = (
editor.schema.styleSpecs[mark.type.name].implementation
diff --git a/src/api/exporters/html/util/serializeBlocksInternalHTML.ts b/src/api/exporters/html/util/serializeBlocksInternalHTML.ts
index 0f890b77abec5ec6271b1280368a0efdd1be2aa5..9f0d95e21b9758bd04fd70d7fc542d31dff58d25 100644
--- a/src/api/exporters/html/util/serializeBlocksInternalHTML.ts
+++ b/src/api/exporters/html/util/serializeBlocksInternalHTML.ts
@@ -97,7 +97,7 @@ export function serializeInlineContentInternalHTML<
node.textContent,
);
// Reverse the order of marks to maintain the correct priority.
- for (const mark of node.marks.toReversed()) {
+ for (const mark of Array.from(node.marks).reverse()) {
if (mark.type.name in editor.schema.styleSpecs) {
const newDom = editor.schema.styleSpecs[
mark.type.name
2026-05-01 12:55:23 +02:00
diff --git a/src/blocks/Code/block.ts b/src/blocks/Code/block.ts
index dbb7fc33a9add7a96488349876bc56ad60111a3f..58c3cf181f25467d85cd8c3788b5b73dec88175a 100644
2026-04-30 04:19:10 +02:00
--- a/src/blocks/Code/block.ts
+++ b/src/blocks/Code/block.ts
2026-05-01 12:55:23 +02:00
@@ -134,6 +134,10 @@ export const createCodeBlockSpec = createBlockSpec(
2026-04-30 04:19:10 +02:00
const handleLanguageChange = (event: Event) => {
const language = (event.target as HTMLSelectElement).value;
2026-05-02 10:58:46 +02:00
2026-04-30 04:19:10 +02:00
+ if (!editor.getBlock(block.id)) {
+ return;
+ }
2026-05-01 12:55:23 +02:00
+
2026-04-30 04:19:10 +02:00
editor.updateBlock(block.id, { props: { language } });
};
2026-05-01 12:55:23 +02:00
select.addEventListener("change", handleLanguageChange);
2026-05-03 17:27:03 +02:00
diff --git a/src/blocks/ListItem/CheckListItem/block.ts b/src/blocks/ListItem/CheckListItem/block.ts
index b32ee408eaf81ccbabb39e5b0f95a2fa73358b0f..92aaa7cf2ec1cec169235c59ade06f0cb4519fb7 100644
2026-05-03 17:27:03 +02:00
--- a/src/blocks/ListItem/CheckListItem/block.ts
+++ b/src/blocks/ListItem/CheckListItem/block.ts
@@ -83,7 +83,12 @@ export const createCheckListItemBlockSpec = createBlockSpec(
2026-05-03 17:27:03 +02:00
checkbox.setAttribute("checked", "");
}
checkbox.addEventListener("change", () => {
- editor.updateBlock(block, { props: { checked: !block.props.checked } });
+ const liveBlock = editor.getBlock(block.id);
+ if (!liveBlock) {
+ return;
+ }
+
+ editor.updateBlock(liveBlock, { props: { checked: !liveBlock.props.checked } });
});
// We use a <p> tag, because for <li> tags we'd need a <ul> element to put
// them in to be semantically correct, which we can't have due to the
2026-05-01 12:55:23 +02:00
diff --git a/src/editor/managers/ExtensionManager/extensions.ts b/src/editor/managers/ExtensionManager/extensions.ts
index 45f0acf8e5d869eb13a3c3d70e6f67059f86c598..2a4d15c8e8465181cc009ed9912cd284e0930251 100644
--- a/src/editor/managers/ExtensionManager/extensions.ts
+++ b/src/editor/managers/ExtensionManager/extensions.ts
2026-05-01 12:55:23 +02:00
@@ -84,7 +84,10 @@ export function getDefaultTiptapExtensions(
}).configure({
defaultProtocol: DEFAULT_LINK_PROTOCOL,
// only call this once if we have multiple editors installed. Or fix https://github.com/ueberdosis/tiptap/issues/5450
- protocols: LINKIFY_INITIALIZED ? [] : VALID_LINK_PROTOCOLS,
2026-04-30 05:06:00 +02:00
+ // Tolaria routes editor link clicks through its guarded native opener.
+ openOnClick: false,
+ // Tolaria pre-registers BlockNote's non-native protocols before linkify initializes.
+ protocols: [],
}),
...(Object.values(editor.schema.styleSpecs).map((styleSpec) => {
return styleSpec.implementation.mark.configure({
2026-05-01 12:55:23 +02:00
diff --git a/src/extensions/SideMenu/SideMenu.ts b/src/extensions/SideMenu/SideMenu.ts
index 769e4a17154db2d88472696638db96e20131dfdb..a6c7f1a76eaa4db7b58774ae71ef47ab62805f66 100644
--- a/src/extensions/SideMenu/SideMenu.ts
+++ b/src/extensions/SideMenu/SideMenu.ts
2026-05-01 12:55:23 +02:00
@@ -194,6 +194,15 @@ export class SideMenuView<
this.emitUpdate(this.state);
};
2026-05-02 10:58:46 +02:00
+ private hideMenu = () => {
+ if (!this.state?.show) {
+ return;
+ }
+
+ this.state.show = false;
+ this.updateState(this.state);
+ };
+
updateStateFromMousePos = () => {
if (this.menuFrozen || !this.mousePos) {
return;
2026-05-01 12:55:23 +02:00
@@ -208,10 +217,7 @@ export class SideMenuView<
closestEditor?.element !== this.pmView.dom ||
closestEditor.distance > DISTANCE_TO_CONSIDER_EDITOR_BOUNDS
) {
- if (this.state?.show) {
- this.state.show = false;
- this.updateState(this.state);
- }
+ this.hideMenu();
return;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
@@ -219,11 +225,7 @@ export class SideMenuView<
2026-05-02 10:58:46 +02:00
// Closes the menu if the mouse cursor is beyond the editor vertically.
if (!block || !this.editor.isEditable) {
- if (this.state?.show) {
- this.state.show = false;
- this.updateState(this.state);
- }
-
+ this.hideMenu();
return;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
@@ -237,6 +239,15 @@ export class SideMenuView<
}
2026-05-02 10:58:46 +02:00
this.hoveredBlock = block.node;
+ const hoveredBlockId = this.hoveredBlock.getAttribute("data-id");
+ const hoveredEditorBlock = hoveredBlockId
+ ? this.editor.getBlock(hoveredBlockId)
+ : undefined;
+
+ if (!hoveredEditorBlock) {
+ this.hideMenu();
+ return;
+ }
2026-05-02 10:58:46 +02:00
// Shows or updates elements.
if (this.editor.isEditable) {
2026-05-01 12:55:23 +02:00
@@ -258,9 +269,7 @@ export class SideMenuView<
blockContentBoundingBox.width,
blockContentBoundingBox.height,
),
- block: this.editor.getBlock(
- this.hoveredBlock!.getAttribute("data-id")!,
- )!,
+ block: hoveredEditorBlock,
};
this.updateState(this.state);
}
2026-05-01 12:55:23 +02:00
diff --git a/src/extensions/SuggestionMenu/SuggestionMenu.ts b/src/extensions/SuggestionMenu/SuggestionMenu.ts
index 029103600a98bf8ccd3054a5c43ffa2fd9115c06..d1678ed4761baca0b3495dafc8d751525d528b4e 100644
--- a/src/extensions/SuggestionMenu/SuggestionMenu.ts
+++ b/src/extensions/SuggestionMenu/SuggestionMenu.ts
2026-05-01 12:55:23 +02:00
@@ -32,7 +32,7 @@ class SuggestionMenuView {
2026-05-02 10:58:46 +02:00
this.emitUpdate = (menuName: string) => {
if (!this.state) {
- throw new Error("Attempting to update uninitialized suggestions menu");
+ return;
}
2026-05-02 10:58:46 +02:00
emitUpdate(menuName, {
2026-05-01 12:55:23 +02:00
@@ -64,6 +64,15 @@ class SuggestionMenuView {
}
};
2026-05-02 10:58:46 +02:00
+ private hideMenu = (menuName: string) => {
+ if (!this.state) {
+ return;
+ }
+
+ this.state.show = false;
+ this.emitUpdate(menuName);
+ };
+
update(view: EditorView, prevState: EditorState) {
const prev: SuggestionPluginState =
suggestionMenuPluginKey.getState(prevState);
2026-05-01 12:55:23 +02:00
@@ -84,11 +93,7 @@ class SuggestionMenuView {
this.pluginState = stopped ? prev : next;
2026-05-02 10:58:46 +02:00
if (stopped || !this.editor.isEditable) {
- if (this.state) {
- this.state.show = false;
- }
- this.emitUpdate(this.pluginState!.triggerCharacter);
-
+ this.hideMenu(this.pluginState!.triggerCharacter);
return;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
@@ -96,17 +101,20 @@ class SuggestionMenuView {
`[data-decoration-id="${this.pluginState!.decorationId}"]`,
);
2026-05-02 10:58:46 +02:00
- if (this.editor.isEditable && decorationNode) {
- this.state = {
- show: true,
- referencePos: decorationNode
- .getBoundingClientRect()
- .toJSON() as DOMRect,
- query: this.pluginState!.query,
- };
-
- this.emitUpdate(this.pluginState!.triggerCharacter!);
+ if (!decorationNode) {
+ this.hideMenu(this.pluginState!.triggerCharacter!);
+ return;
}
+
+ this.state = {
+ show: true,
+ referencePos: decorationNode
+ .getBoundingClientRect()
+ .toJSON() as DOMRect,
+ query: this.pluginState!.query,
+ };
+
+ this.emitUpdate(this.pluginState!.triggerCharacter!);
}
2026-05-02 10:58:46 +02:00
destroy() {
2026-05-01 12:55:23 +02:00
diff --git a/src/extensions/TableHandles/TableHandles.ts b/src/extensions/TableHandles/TableHandles.ts
index 3063774..9813bed 100644
--- a/src/extensions/TableHandles/TableHandles.ts
+++ b/src/extensions/TableHandles/TableHandles.ts
2026-05-02 10:58:46 +02:00
@@ -99,6 +99,46 @@ function getChildIndex(node: Element) {
return Array.prototype.indexOf.call(node.parentElement!.childNodes, node);
}
+function isValidTablePosition(tablePos: number | undefined): tablePos is number {
+ return Number.isInteger(tablePos) && tablePos >= 0;
+}
+
+function isValidCellIndex(index: number | undefined): index is number {
+ return Number.isInteger(index) && index >= 0;
+}
+
+function isValidRelativeCell(cell: RelativeCellIndices) {
+ return isValidCellIndex(cell.row) && isValidCellIndex(cell.col);
+}
+
+function resolveCellPosition(
+ state: EditorState,
+ tablePos: number | undefined,
+ relativeCell: RelativeCellIndices,
+) {
+ if (!isValidTablePosition(tablePos) || !isValidRelativeCell(relativeCell)) {
+ return undefined;
+ }
+
+ try {
+ const tableResolvedPos = state.doc.resolve(tablePos + 1);
+ if (relativeCell.row >= tableResolvedPos.node().childCount) {
+ return undefined;
+ }
+
+ const rowResolvedPos = state.doc.resolve(
+ tableResolvedPos.posAtIndex(relativeCell.row) + 1,
+ );
+ if (relativeCell.col >= rowResolvedPos.node().childCount) {
+ return undefined;
+ }
+
+ return state.doc.resolve(rowResolvedPos.posAtIndex(relativeCell.col));
+ } catch {
+ return undefined;
+ }
+}
+
// Finds the DOM element corresponding to the table cell that the target element
// is currently in. If the target element is not in a table cell, returns null.
function domCellAround(target: Element) {
@@ -187,6 +227,32 @@ export class TableHandlesView implements PluginView {
);
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
+ hideHandles = ({
+ resetCell = false,
+ resetDragging = false,
+ } = {}) => {
+ if (!this.state) {
+ return;
+ }
+
+ if (!this.state.show && !resetCell && !resetDragging) {
+ return;
+ }
+
+ this.state.show = false;
+ this.state.showAddOrRemoveRowsButton = false;
+ this.state.showAddOrRemoveColumnsButton = false;
2026-05-01 12:55:23 +02:00
+ if (resetDragging) {
+ this.state.draggingState = undefined;
+ }
+ if (resetCell) {
+ this.state.rowIndex = undefined;
+ this.state.colIndex = undefined;
+ this.state.referencePosCell = undefined;
+ }
+ this.emitUpdate();
+ };
+
viewMousedownHandler = () => {
this.mouseState = "down";
};
2026-05-02 10:58:46 +02:00
@@ -222,22 +288,12 @@ export class TableHandlesView implements PluginView {
// hide draghandles when selecting text as they could be in the way of the user
this.mouseState = "selecting";
2026-05-02 10:58:46 +02:00
- if (this.state?.show) {
- this.state.show = false;
- this.state.showAddOrRemoveRowsButton = false;
- this.state.showAddOrRemoveColumnsButton = false;
- this.emitUpdate();
- }
+ this.hideHandles();
return;
}
2026-05-02 10:58:46 +02:00
if (!target || !this.editor.isEditable) {
- if (this.state?.show) {
- this.state.show = false;
- this.state.showAddOrRemoveRowsButton = false;
- this.state.showAddOrRemoveColumnsButton = false;
- this.emitUpdate();
- }
+ this.hideHandles();
return;
}
2026-05-02 10:58:46 +02:00
@@ -298,7 +354,7 @@ export class TableHandlesView implements PluginView {
const hideHandles =
// always hide handles when the actively hovered table changed
- this.state?.block.id !== tableBlock.id ||
+ this.state?.block?.id !== tableBlock.id ||
// make sure we don't hide existing handles (keep col / row index) when
// we're hovering just above or to the right of a table
event.clientX > tableRect.right ||
2026-05-02 10:58:46 +02:00
@@ -458,9 +514,9 @@ export class TableHandlesView implements PluginView {
2026-05-01 12:55:23 +02:00
this.state.rowIndex === undefined ||
this.state.colIndex === undefined
) {
- throw new Error(
- "Attempted to drop table row or column, but no table block was hovered prior.",
- );
+ event.preventDefault();
+ this.hideHandles({ resetCell: true, resetDragging: true });
+ return false;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
event.preventDefault();
@@ -533,7 +589,13 @@ export class TableHandlesView implements PluginView {
}
// Hide handles if the table block has been removed.
- this.state.block = this.editor.getBlock(this.state.block.id)!;
+ const currentBlock = this.state.block;
+ if (!currentBlock) {
+ this.hideHandles({ resetCell: true, resetDragging: true });
+ return;
+ }
+
+ this.state.block = this.editor.getBlock(currentBlock.id)!;
if (
!this.state.block ||
this.state.block.type !== "table" ||
@@ -541,11 +603,7 @@ export class TableHandlesView implements PluginView {
// because yjs replaces the element when for example you change the color via the side menu
!this.tableElement?.isConnected
) {
- this.state.show = false;
- this.state.showAddOrRemoveRowsButton = false;
- this.state.showAddOrRemoveColumnsButton = false;
- this.emitUpdate();
-
+ this.hideHandles();
return;
}
2026-05-02 10:58:46 +02:00
@@ -572,9 +630,8 @@ export class TableHandlesView implements PluginView {
const tableBody = this.tableElement!.querySelector("tbody");
2026-05-02 10:58:46 +02:00
if (!tableBody) {
- throw new Error(
- "Table block does not contain a 'tbody' HTML element. This should never happen.",
- );
+ this.hideHandles({ resetCell: true });
+ return;
}
2026-05-02 10:58:46 +02:00
if (
@@ -796,11 +853,11 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-01 12:55:23 +02:00
if (
view === undefined ||
view.state === undefined ||
- view.state.colIndex === undefined
+ view.state.colIndex === undefined ||
+ view.tablePos === undefined
) {
- throw new Error(
- "Attempted to drag table column, but no table block was hovered prior.",
- );
+ view?.hideHandles({ resetCell: true, resetDragging: true });
+ return;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
view.state.draggingState = {
@@ -837,26 +894,30 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-01 12:55:23 +02:00
dataTransfer: DataTransfer | null;
clientY: number;
}) {
- if (view!.state === undefined || view!.state.rowIndex === undefined) {
- throw new Error(
- "Attempted to drag table row, but no table block was hovered prior.",
- );
+ if (
+ view === undefined ||
+ view.state === undefined ||
+ view.state.rowIndex === undefined ||
+ view.tablePos === undefined
+ ) {
+ view?.hideHandles({ resetCell: true, resetDragging: true });
+ return;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
- view!.state.draggingState = {
+ view.state.draggingState = {
draggedCellOrientation: "row",
- originalIndex: view!.state.rowIndex,
+ originalIndex: view.state.rowIndex,
mousePos: event.clientY,
};
- view!.emitUpdate();
+ view.emitUpdate();
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
editor.transact((tr) =>
tr.setMeta(tableHandlesPluginKey, {
draggedCellOrientation:
- view!.state!.draggingState!.draggedCellOrientation,
- originalIndex: view!.state!.rowIndex,
- newIndex: view!.state!.rowIndex,
- tablePos: view!.tablePos,
+ view.state!.draggingState!.draggedCellOrientation,
+ originalIndex: view.state!.rowIndex,
+ newIndex: view.state!.rowIndex,
+ tablePos: view.tablePos,
}),
);
2026-05-02 10:58:46 +02:00
@@ -874,14 +935,15 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-01 12:55:23 +02:00
* used as the row drag handle, and the one used as the column drag handle.
*/
dragEnd() {
- if (view!.state === undefined) {
- throw new Error(
- "Attempted to drag table row, but no table block was hovered prior.",
- );
+ if (view === undefined || view.state === undefined) {
+ if (!editor.headless) {
+ unsetHiddenDragImage(editor.prosemirrorView.root);
+ }
+ return;
}
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
- view!.state.draggingState = undefined;
- view!.emitUpdate();
+ view.state.draggingState = undefined;
+ view.emitUpdate();
2026-05-02 10:58:46 +02:00
2026-05-01 12:55:23 +02:00
editor.transact((tr) => tr.setMeta(tableHandlesPluginKey, null));
2026-05-02 10:58:46 +02:00
@@ -938,22 +1000,21 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
throw new Error("Table handles view not initialized");
}
- const tableResolvedPos = state.doc.resolve(view.tablePos! + 1);
- const startRowResolvedPos = state.doc.resolve(
- tableResolvedPos.posAtIndex(relativeStartCell.row) + 1,
- );
- const startCellResolvedPos = state.doc.resolve(
- // No need for +1, since CellSelection expects the position before the cell
- startRowResolvedPos.posAtIndex(relativeStartCell.col),
+ const startCellResolvedPos = resolveCellPosition(
+ state,
+ view.tablePos,
+ relativeStartCell,
);
- const endRowResolvedPos = state.doc.resolve(
- tableResolvedPos.posAtIndex(relativeEndCell.row) + 1,
- );
2026-05-02 10:58:46 +02:00
- const endCellResolvedPos = state.doc.resolve(
- // No need for +1, since CellSelection expects the position before the cell
- endRowResolvedPos.posAtIndex(relativeEndCell.col),
+ const endCellResolvedPos = resolveCellPosition(
+ state,
+ view.tablePos,
+ relativeEndCell,
);
+ if (!startCellResolvedPos || !endCellResolvedPos) {
+ return undefined;
+ }
+
// Begin a new transaction to set the selection
const tr = state.tr;
@@ -975,6 +1036,15 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
| { orientation: "row"; side: "above" | "below" }
| { orientation: "column"; side: "left" | "right" },
) {
+ if (
+ !view ||
+ !isValidTablePosition(view.tablePos) ||
+ !isValidCellIndex(index)
+ ) {
+ view?.hideHandles({ resetCell: true });
+ return;
+ }
+
editor.exec((beforeState, dispatch) => {
const state = this.setCellSelection(
beforeState,
@@ -983,6 +1053,11 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
: { row: 0, col: index },
);
+ if (!state) {
+ view?.hideHandles({ resetCell: true });
+ return false;
+ }
+
if (direction.orientation === "row") {
if (direction.side === "above") {
return addRowBefore(state, dispatch);
@@ -997,6 +1072,7 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
}
}
});
+ view?.hideHandles({ resetCell: true, resetDragging: true });
},
/**
@@ -1006,12 +1082,19 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
index: RelativeCellIndices["row"] | RelativeCellIndices["col"],
direction: "row" | "column",
) {
+ if (!isValidCellIndex(index)) {
+ return false;
+ }
+
if (direction === "row") {
return editor.exec((beforeState, dispatch) => {
const state = this.setCellSelection(beforeState, {
row: index,
col: 0,
});
+ if (!state) {
+ return false;
+ }
return deleteRow(state, dispatch);
});
} else {
@@ -1020,6 +1103,9 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
row: 0,
col: index,
});
+ if (!state) {
+ return false;
+ }
return deleteColumn(state, dispatch);
});
2026-05-01 23:45:38 +02:00
}
@@ -1041,6 +1127,10 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
)
: beforeState;
+ if (!state) {
+ return false;
+ }
+
return mergeCells(state, dispatch);
});
},
@@ -1055,6 +1145,10 @@ export const TableHandlesExtension = createExtension(({ editor }) => {
2026-05-02 10:58:46 +02:00
? this.setCellSelection(beforeState, relativeCellToSplit)
: beforeState;
+ if (!state) {
+ return false;
+ }
+
return splitCell(state, dispatch);
});
2026-05-01 23:45:38 +02:00
},