@blocknote/core 0.39.0 → 0.39.1-capitol-test
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteSchema-DmZ6UQfY.cjs → BlockNoteSchema-Bsa_tSAC.cjs} +8 -8
- package/dist/BlockNoteSchema-Bsa_tSAC.cjs.map +1 -0
- package/dist/{BlockNoteSchema-oR047ACf.js → BlockNoteSchema-CZez1nQf.js} +586 -617
- package/dist/BlockNoteSchema-CZez1nQf.js.map +1 -0
- package/dist/blocknote.cjs +4 -4
- package/dist/blocknote.cjs.map +1 -1
- package/dist/blocknote.js +1172 -1185
- package/dist/blocknote.js.map +1 -1
- package/dist/blocks.cjs +1 -1
- package/dist/blocks.js +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +1 -2
- package/src/api/clipboard/fromClipboard/handleFileInsertion.ts +2 -2
- package/src/api/clipboard/fromClipboard/pasteExtension.ts +1 -1
- package/src/blocks/Code/block.ts +1 -5
- package/src/editor/BlockNoteEditor.ts +23 -19
- package/src/extensions/Placeholder/PlaceholderPlugin.ts +6 -6
- package/src/extensions/SideMenu/SideMenuPlugin.ts +1 -3
- package/src/extensions/SideMenu/dragging.ts +2 -2
- package/src/extensions/SuggestionMenu/SuggestionPlugin.ts +4 -2
- package/src/extensions/TableHandles/TableHandlesPlugin.ts +6 -6
- package/types/src/api/exporters/markdown/util/convertVideoToMarkdownRehypePlugin.d.ts +2 -0
- package/types/src/api/exporters/markdown/util/removeUnderlinesRehypePlugin.d.ts +6 -0
- package/types/src/blocks/Divider/block.d.ts +3 -0
- package/types/src/editor/BlockNoteEditor.d.ts +3 -1
- package/types/src/editor/managers/BlockManager.d.ts +114 -0
- package/types/src/editor/managers/CollaborationManager.d.ts +115 -0
- package/types/src/editor/managers/EventManager.d.ts +58 -0
- package/types/src/editor/managers/ExportManager.d.ts +64 -0
- package/types/src/editor/managers/ExtensionManager.d.ts +68 -0
- package/types/src/editor/managers/SelectionManager.d.ts +54 -0
- package/types/src/editor/managers/StateManager.d.ts +115 -0
- package/types/src/editor/managers/StyleManager.d.ts +48 -0
- package/types/src/editor/managers/index.d.ts +8 -0
- package/dist/BlockNoteSchema-DmZ6UQfY.cjs.map +0 -1
- package/dist/BlockNoteSchema-oR047ACf.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/blocks/Code/shiki.ts +0 -73
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlockNoteSchema-CZez1nQf.js","sources":["../src/extensions/UniqueID/UniqueID.ts","../src/schema/inlineContent/types.ts","../src/util/table.ts","../src/util/typescript.ts","../src/util/browser.ts","../src/blocks/defaultBlockHelpers.ts","../src/util/string.ts","../src/schema/blocks/internal.ts","../src/schema/blocks/createSpec.ts","../src/api/getBlockInfoFromPos.ts","../src/api/pmUtil.ts","../src/api/nodeConversions/nodeToBlock.ts","../src/schema/inlineContent/internal.ts","../src/schema/styles/internal.ts","../src/schema/styles/createSpec.ts","../src/util/topo-sort.ts","../src/schema/schema.ts","../src/api/blockManipulation/tables/tables.ts","../src/api/nodeConversions/blockToNode.ts","../src/api/nodeUtil.ts","../src/api/blockManipulation/commands/updateBlock/updateBlock.ts","../src/editor/defaultColors.ts","../src/blocks/defaultProps.ts","../src/blocks/File/helpers/parse/parseFigureElement.ts","../src/blocks/File/helpers/render/createAddFileButton.ts","../src/blocks/File/helpers/render/createFileNameWithIcon.ts","../src/blocks/File/helpers/render/createFileBlockWrapper.ts","../src/blocks/File/helpers/toExternalHTML/createFigureWithCaption.ts","../src/blocks/File/helpers/toExternalHTML/createLinkWithCaption.ts","../src/blocks/Audio/parseAudioElement.ts","../src/blocks/Audio/block.ts","../src/util/EventEmitter.ts","../src/editor/BlockNoteExtension.ts","../src/blocks/Code/block.ts","../src/blocks/File/helpers/parse/parseEmbedElement.ts","../src/blocks/File/block.ts","../src/blocks/ToggleWrapper/createToggleWrapper.ts","../src/blocks/Heading/block.ts","../src/blocks/File/helpers/render/createResizableFileBlockWrapper.ts","../src/blocks/Image/parseImageElement.ts","../src/blocks/Image/block.ts","../src/api/blockManipulation/commands/splitBlock/splitBlock.ts","../src/blocks/utils/listItemEnterHandler.ts","../src/blocks/ListItem/getListItemContent.ts","../src/blocks/ListItem/BulletListItem/block.ts","../src/blocks/ListItem/CheckListItem/block.ts","../src/blocks/ListItem/NumberedListItem/IndexingPlugin.ts","../src/blocks/ListItem/NumberedListItem/block.ts","../src/blocks/ListItem/ToggleListItem/block.ts","../src/blocks/PageBreak/block.ts","../src/blocks/Paragraph/block.ts","../src/blocks/Quote/block.ts","../src/blocks/Table/TableExtension.ts","../src/blocks/Table/block.ts","../src/blocks/Video/parseVideoElement.ts","../src/blocks/Video/block.ts","../src/blocks/File/helpers/uploadToTmpFilesDotOrg_DEV_ONLY.ts","../src/blocks/defaultBlockTypeGuards.ts","../src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts","../src/blocks/PageBreak/getPageBreakSlashMenuItems.ts","../src/blocks/defaultBlocks.ts","../src/blocks/BlockNoteSchema.ts"],"sourcesContent":["import {\n combineTransactionSteps,\n Extension,\n findChildrenInRange,\n getChangedRanges,\n} from \"@tiptap/core\";\nimport { Fragment, Slice } from \"prosemirror-model\";\nimport { Plugin, PluginKey } from \"prosemirror-state\";\nimport { v4 } from \"uuid\";\n\n/**\n * Code from Tiptap UniqueID extension (https://tiptap.dev/api/extensions/unique-id)\n * This extension is licensed under MIT (even though it's part of Tiptap pro).\n *\n * If you're a user of BlockNote, we still recommend to support their awesome work and become a sponsor!\n * https://tiptap.dev/pro\n */\n\n/**\n * Removes duplicated values within an array.\n * Supports numbers, strings and objects.\n */\nfunction removeDuplicates(array: any, by = JSON.stringify) {\n const seen: any = {};\n return array.filter((item: any) => {\n const key = by(item);\n return Object.prototype.hasOwnProperty.call(seen, key)\n ? false\n : (seen[key] = true);\n });\n}\n\n/**\n * Returns a list of duplicated items within an array.\n */\nfunction findDuplicates(items: any) {\n const filtered = items.filter(\n (el: any, index: number) => items.indexOf(el) !== index,\n );\n const duplicates = removeDuplicates(filtered);\n return duplicates;\n}\n\nconst UniqueID = Extension.create({\n name: \"uniqueID\",\n // we’ll set a very high priority to make sure this runs first\n // and is compatible with `appendTransaction` hooks of other extensions\n priority: 10000,\n addOptions() {\n return {\n attributeName: \"id\",\n types: [],\n setIdAttribute: false,\n generateID: () => {\n // Use mock ID if tests are running.\n if (typeof window !== \"undefined\" && (window as any).__TEST_OPTIONS) {\n const testOptions = (window as any).__TEST_OPTIONS;\n if (testOptions.mockID === undefined) {\n testOptions.mockID = 0;\n } else {\n testOptions.mockID++;\n }\n\n return testOptions.mockID.toString() as string;\n }\n\n return v4();\n },\n filterTransaction: null,\n };\n },\n addGlobalAttributes() {\n return [\n {\n types: this.options.types,\n attributes: {\n [this.options.attributeName]: {\n default: null,\n parseHTML: (element) =>\n element.getAttribute(`data-${this.options.attributeName}`),\n renderHTML: (attributes) => {\n const defaultIdAttributes = {\n [`data-${this.options.attributeName}`]:\n attributes[this.options.attributeName],\n };\n if (this.options.setIdAttribute) {\n return {\n ...defaultIdAttributes,\n id: attributes[this.options.attributeName],\n };\n } else {\n return defaultIdAttributes;\n }\n },\n },\n },\n },\n ];\n },\n // check initial content for missing ids\n // onCreate() {\n // // Don’t do this when the collaboration extension is active\n // // because this may update the content, so Y.js tries to merge these changes.\n // // This leads to empty block nodes.\n // // See: https://github.com/ueberdosis/tiptap/issues/2400\n // if (\n // this.editor.extensionManager.extensions.find(\n // (extension) => extension.name === \"collaboration\"\n // )\n // ) {\n // return;\n // }\n // const { view, state } = this.editor;\n // const { tr, doc } = state;\n // const { types, attributeName, generateID } = this.options;\n // const nodesWithoutId = findChildren(doc, (node) => {\n // return (\n // types.includes(node.type.name) && node.attrs[attributeName] === null\n // );\n // });\n // nodesWithoutId.forEach(({ node, pos }) => {\n // tr.setNodeMarkup(pos, undefined, {\n // ...node.attrs,\n // [attributeName]: generateID(),\n // });\n // });\n // tr.setMeta(\"addToHistory\", false);\n // view.dispatch(tr);\n // },\n addProseMirrorPlugins() {\n let dragSourceElement: any = null;\n let transformPasted = false;\n return [\n new Plugin({\n key: new PluginKey(\"uniqueID\"),\n appendTransaction: (transactions, oldState, newState) => {\n const docChanges =\n transactions.some((transaction) => transaction.docChanged) &&\n !oldState.doc.eq(newState.doc);\n const filterTransactions =\n this.options.filterTransaction &&\n transactions.some((tr) => !this.options.filterTransaction?.(tr));\n if (!docChanges || filterTransactions) {\n return;\n }\n const { tr } = newState;\n const { types, attributeName, generateID } = this.options;\n const transform = combineTransactionSteps(\n oldState.doc,\n transactions as any,\n );\n const { mapping } = transform;\n // get changed ranges based on the old state\n const changes = getChangedRanges(transform);\n\n changes.forEach(({ newRange }) => {\n const newNodes = findChildrenInRange(\n newState.doc,\n newRange,\n (node) => {\n return types.includes(node.type.name);\n },\n );\n const newIds = newNodes\n .map(({ node }) => node.attrs[attributeName])\n .filter((id) => id !== null);\n const duplicatedNewIds = findDuplicates(newIds);\n\n newNodes.forEach(({ node, pos }) => {\n // instead of checking `node.attrs[attributeName]` directly\n // we look at the current state of the node within `tr.doc`.\n // this helps to prevent adding new ids to the same node\n // if the node changed multiple times within one transaction\n const id = tr.doc.nodeAt(pos)?.attrs[attributeName];\n\n if (id === null) {\n // edge case, when using collaboration, yjs will set the id to null in `_forceRerender`\n // when loading the editor\n // this checks for this case and keeps it at initialBlockId so there will be no change\n const initialDoc = oldState.doc.type.createAndFill()!.content;\n const wasInitial =\n oldState.doc.content.findDiffStart(initialDoc) === null;\n\n if (wasInitial) {\n // the old state was the \"initial content\"\n const jsonNode = JSON.parse(\n JSON.stringify(newState.doc.toJSON()),\n );\n jsonNode.content[0].content[0].attrs.id = \"initialBlockId\";\n // would the new state with the fix also be the \"initial content\"?\n if (\n JSON.stringify(jsonNode.content) ===\n JSON.stringify(initialDoc.toJSON())\n ) {\n // yes, apply the fix\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: \"initialBlockId\",\n });\n return;\n }\n }\n\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n });\n return;\n }\n // check if the node doesn’t exist in the old state\n const { deleted } = mapping.invert().mapResult(pos);\n const newNode = deleted && duplicatedNewIds.includes(id);\n if (newNode) {\n tr.setNodeMarkup(pos, undefined, {\n ...node.attrs,\n [attributeName]: generateID(),\n });\n }\n });\n });\n if (!tr.steps.length) {\n return;\n }\n // mark the transaction as having been processed by the uniqueID plugin\n tr.setMeta(\"uniqueID\", true);\n return tr;\n },\n // we register a global drag handler to track the current drag source element\n view(view) {\n const handleDragstart = (event: any) => {\n let _a;\n dragSourceElement = (\n (_a = view.dom.parentElement) === null || _a === void 0\n ? void 0\n : _a.contains(event.target)\n )\n ? view.dom.parentElement\n : null;\n };\n window.addEventListener(\"dragstart\", handleDragstart);\n return {\n destroy() {\n window.removeEventListener(\"dragstart\", handleDragstart);\n },\n };\n },\n props: {\n // `handleDOMEvents` is called before `transformPasted` so we can do\n // some checks before. However, `transformPasted` only runs when\n // editor content is pasted - not external content.\n handleDOMEvents: {\n // only create new ids for dropped content while holding `alt`\n // or content is dragged from another editor\n drop: (view, event: any) => {\n let _a;\n if (\n dragSourceElement !== view.dom.parentElement ||\n ((_a = event.dataTransfer) === null || _a === void 0\n ? void 0\n : _a.effectAllowed) === \"copy\"\n ) {\n transformPasted = true;\n } else {\n transformPasted = false;\n }\n\n dragSourceElement = null;\n\n return false;\n },\n // always create new ids on pasted content\n paste: () => {\n transformPasted = true;\n return false;\n },\n },\n // we’ll remove ids for every pasted node\n // so we can create a new one within `appendTransaction`\n transformPasted: (slice) => {\n if (!transformPasted) {\n return slice;\n }\n const { types, attributeName } = this.options;\n const removeId = (fragment: any) => {\n const list: any[] = [];\n fragment.forEach((node: any) => {\n // don’t touch text nodes\n if (node.isText) {\n list.push(node);\n return;\n }\n // check for any other child nodes\n if (!types.includes(node.type.name)) {\n list.push(node.copy(removeId(node.content)));\n return;\n }\n // remove id\n const nodeWithoutId = node.type.create(\n {\n ...node.attrs,\n [attributeName]: null,\n },\n removeId(node.content),\n node.marks,\n );\n list.push(nodeWithoutId);\n });\n return Fragment.from(list);\n };\n // reset check\n transformPasted = false;\n return new Slice(\n removeId(slice.content),\n slice.openStart,\n slice.openEnd,\n );\n },\n },\n }),\n ];\n },\n});\n\nexport { UniqueID as default, UniqueID };\n","import { Node } from \"@tiptap/core\";\nimport { PropSchema, Props } from \"../propTypes.js\";\nimport { StyleSchema, Styles } from \"../styles/types.js\";\nimport { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport { ViewMutationRecord } from \"prosemirror-view\";\n\nexport type CustomInlineContentConfig = {\n type: string;\n content: \"styled\" | \"none\"; // | \"plain\"\n readonly propSchema: PropSchema;\n};\n// InlineContentConfig contains the \"schema\" info about an InlineContent type\n// i.e. what props it supports, what content it supports, etc.\nexport type InlineContentConfig = CustomInlineContentConfig | \"text\" | \"link\";\n\n// InlineContentImplementation contains the \"implementation\" info about an InlineContent element\n// such as the functions / Nodes required to render and / or serialize it\n// @ts-ignore\nexport type InlineContentImplementation<T extends InlineContentConfig> =\n T extends \"link\" | \"text\"\n ? undefined\n : {\n meta?: {\n draggable?: boolean;\n };\n node: Node;\n toExternalHTML?: (\n inlineContent: any,\n editor: BlockNoteEditor<any, any, any>,\n ) =>\n | {\n dom: HTMLElement | DocumentFragment;\n contentDOM?: HTMLElement;\n }\n | undefined;\n render: (\n inlineContent: any,\n updateInlineContent: (update: any) => void,\n editor: BlockNoteEditor<any, any, any>,\n ) => {\n dom: HTMLElement | DocumentFragment;\n contentDOM?: HTMLElement;\n ignoreMutation?: (mutation: ViewMutationRecord) => boolean;\n destroy?: () => void;\n };\n };\n\nexport type InlineContentSchemaWithInlineContent<\n IType extends string,\n C extends InlineContentConfig,\n> = {\n [k in IType]: C;\n};\n\n// Container for both the config and implementation of InlineContent,\n// and the type of `implementation` is based on that of the config\nexport type InlineContentSpec<T extends InlineContentConfig> = {\n config: T;\n implementation: InlineContentImplementation<T>;\n};\n\n// A Schema contains all the types (Configs) supported in an editor\n// The keys are the \"type\" of InlineContent elements\nexport type InlineContentSchema = Record<string, InlineContentConfig>;\n\nexport type InlineContentSpecs = {\n text: { config: \"text\"; implementation: undefined };\n link: { config: \"link\"; implementation: undefined };\n} & Record<string, InlineContentSpec<InlineContentConfig>>;\n\nexport type InlineContentSchemaFromSpecs<T extends InlineContentSpecs> = {\n [K in keyof T]: T[K][\"config\"];\n};\n\nexport type CustomInlineContentFromConfig<\n I extends CustomInlineContentConfig,\n S extends StyleSchema,\n> = {\n type: I[\"type\"];\n props: Props<I[\"propSchema\"]>;\n content: I[\"content\"] extends \"styled\"\n ? StyledText<S>[]\n : I[\"content\"] extends \"plain\"\n ? string\n : I[\"content\"] extends \"none\"\n ? undefined\n : never;\n};\n\nexport type InlineContentFromConfig<\n I extends InlineContentConfig,\n S extends StyleSchema,\n> = I extends \"text\"\n ? StyledText<S>\n : I extends \"link\"\n ? Link<S>\n : I extends CustomInlineContentConfig\n ? CustomInlineContentFromConfig<I, S>\n : never;\n\nexport type PartialCustomInlineContentFromConfig<\n I extends CustomInlineContentConfig,\n S extends StyleSchema,\n> = {\n type: I[\"type\"];\n props?: Props<I[\"propSchema\"]>;\n content?: I[\"content\"] extends \"styled\"\n ? StyledText<S>[] | string\n : I[\"content\"] extends \"plain\"\n ? string\n : I[\"content\"] extends \"none\"\n ? undefined\n : never;\n};\n\nexport type PartialInlineContentFromConfig<\n I extends InlineContentConfig,\n S extends StyleSchema,\n> = I extends \"text\"\n ? string | StyledText<S>\n : I extends \"link\"\n ? PartialLink<S>\n : I extends CustomInlineContentConfig\n ? PartialCustomInlineContentFromConfig<I, S>\n : never;\n\nexport type StyledText<T extends StyleSchema> = {\n type: \"text\";\n text: string;\n styles: Styles<T>;\n};\n\nexport type Link<T extends StyleSchema> = {\n type: \"link\";\n href: string;\n content: StyledText<T>[];\n};\n\nexport type PartialLink<T extends StyleSchema> = Omit<Link<T>, \"content\"> & {\n content: string | Link<T>[\"content\"];\n};\n\nexport type InlineContent<\n I extends InlineContentSchema,\n T extends StyleSchema,\n> = InlineContentFromConfig<I[keyof I], T>;\n\ntype PartialInlineContentElement<\n I extends InlineContentSchema,\n T extends StyleSchema,\n> = PartialInlineContentFromConfig<I[keyof I], T>;\n\nexport type PartialInlineContent<\n I extends InlineContentSchema,\n T extends StyleSchema,\n> = PartialInlineContentElement<I, T>[] | string;\n\nexport function isLinkInlineContent<T extends StyleSchema>(\n content: InlineContent<any, T>,\n): content is Link<T> {\n return content.type === \"link\";\n}\n\nexport function isPartialLinkInlineContent<T extends StyleSchema>(\n content: PartialInlineContentElement<any, T>,\n): content is PartialLink<T> {\n return typeof content !== \"string\" && content.type === \"link\";\n}\n\nexport function isStyledTextInlineContent<T extends StyleSchema>(\n content: PartialInlineContentElement<any, T>,\n): content is StyledText<T> {\n return typeof content !== \"string\" && content.type === \"text\";\n}\n","import type {\n InlineContentSchema,\n StyleSchema,\n PartialInlineContent,\n InlineContent,\n} from \"../schema\";\nimport { PartialTableCell, TableCell } from \"../schema/blocks/types.js\";\n\n/**\n * This will map a table cell to a TableCell object.\n * This is useful for when we want to get the full table cell object from a partial table cell.\n * It is guaranteed to return a new TableCell object.\n */\nexport function mapTableCell<\n T extends InlineContentSchema,\n S extends StyleSchema,\n>(\n content:\n | PartialInlineContent<T, S>\n | PartialTableCell<T, S>\n | TableCell<T, S>,\n): TableCell<T, S> {\n return isTableCell(content)\n ? { ...content }\n : isPartialTableCell(content)\n ? {\n type: \"tableCell\",\n content: ([] as InlineContent<T, S>[]).concat(content.content as any),\n props: {\n backgroundColor: content.props?.backgroundColor ?? \"default\",\n textColor: content.props?.textColor ?? \"default\",\n textAlignment: content.props?.textAlignment ?? \"left\",\n colspan: content.props?.colspan ?? 1,\n rowspan: content.props?.rowspan ?? 1,\n },\n }\n : {\n type: \"tableCell\",\n content: ([] as InlineContent<T, S>[]).concat(content as any),\n props: {\n backgroundColor: \"default\",\n textColor: \"default\",\n textAlignment: \"left\",\n colspan: 1,\n rowspan: 1,\n },\n };\n}\n\nexport function isPartialTableCell<\n T extends InlineContentSchema,\n S extends StyleSchema,\n>(\n content:\n | TableCell<T, S>\n | PartialInlineContent<T, S>\n | PartialTableCell<T, S>\n | undefined\n | null,\n): content is PartialTableCell<T, S> {\n return (\n content !== undefined &&\n content !== null &&\n typeof content !== \"string\" &&\n !Array.isArray(content) &&\n content.type === \"tableCell\"\n );\n}\n\nexport function isTableCell<\n T extends InlineContentSchema,\n S extends StyleSchema,\n>(\n content:\n | TableCell<T, S>\n | PartialInlineContent<T, S>\n | PartialTableCell<T, S>\n | undefined\n | null,\n): content is TableCell<T, S> {\n return (\n isPartialTableCell(content) &&\n content.props !== undefined &&\n content.content !== undefined\n );\n}\n\nexport function getColspan(\n cell:\n | TableCell<any, any>\n | PartialTableCell<any, any>\n | PartialInlineContent<any, any>,\n): number {\n if (isTableCell(cell)) {\n return cell.props.colspan ?? 1;\n }\n return 1;\n}\n\nexport function getRowspan(\n cell:\n | TableCell<any, any>\n | PartialTableCell<any, any>\n | PartialInlineContent<any, any>,\n): number {\n if (isTableCell(cell)) {\n return cell.props.rowspan ?? 1;\n }\n return 1;\n}\n","export class UnreachableCaseError extends Error {\n constructor(val: never) {\n super(`Unreachable case: ${val}`);\n }\n}\n\nexport function assertEmpty(obj: Record<string, never>, throwError = true) {\n const { \"data-test\": dataTest, ...rest } = obj; // exclude data-test\n\n if (Object.keys(rest).length > 0 && throwError) {\n throw new Error(\"Object must be empty \" + JSON.stringify(obj));\n }\n}\n\n// TODO: change for built-in version of typescript 5.4 after upgrade\nexport type NoInfer<T> = [T][T extends any ? 0 : never];\n","export const isAppleOS = () =>\n typeof navigator !== \"undefined\" &&\n (/Mac/.test(navigator.platform) ||\n (/AppleWebKit/.test(navigator.userAgent) &&\n /Mobile\\/\\w+/.test(navigator.userAgent)));\n\nexport function formatKeyboardShortcut(shortcut: string, ctrlText = \"Ctrl\") {\n if (isAppleOS()) {\n return shortcut.replace(\"Mod\", \"⌘\");\n } else {\n return shortcut.replace(\"Mod\", ctrlText);\n }\n}\n\nexport function mergeCSSClasses(...classes: (string | false | undefined)[]) {\n return [\n // Converts to & from set to remove duplicates.\n ...new Set(\n classes\n .filter((c) => c)\n // Ensures that if multiple classes are passed as a single string, they\n // are split.\n .join(\" \")\n .split(\" \"),\n ),\n ].join(\" \");\n}\n\nexport const isSafari = () =>\n /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n","import { blockToNode } from \"../api/nodeConversions/blockToNode.js\";\nimport type { BlockNoteEditor } from \"../editor/BlockNoteEditor.js\";\nimport type {\n BlockNoDefaults,\n BlockSchema,\n InlineContentSchema,\n StyleSchema,\n} from \"../schema/index.js\";\nimport { mergeCSSClasses } from \"../util/browser.js\";\n\n// Function that creates a ProseMirror `DOMOutputSpec` for a default block.\n// Since all default blocks have the same structure (`blockContent` div with a\n// `inlineContent` element inside), this function only needs the block's name\n// for the `data-content-type` attribute of the `blockContent` element and the\n// HTML tag of the `inlineContent` element, as well as any HTML attributes to\n// add to those.\nexport function createDefaultBlockDOMOutputSpec(\n blockName: string,\n htmlTag: string,\n blockContentHTMLAttributes: Record<string, string>,\n inlineContentHTMLAttributes: Record<string, string>,\n) {\n const blockContent = document.createElement(\"div\");\n blockContent.className = mergeCSSClasses(\n \"bn-block-content\",\n blockContentHTMLAttributes.class,\n );\n blockContent.setAttribute(\"data-content-type\", blockName);\n for (const [attribute, value] of Object.entries(blockContentHTMLAttributes)) {\n if (attribute !== \"class\") {\n blockContent.setAttribute(attribute, value);\n }\n }\n\n const inlineContent = document.createElement(htmlTag);\n inlineContent.className = mergeCSSClasses(\n \"bn-inline-content\",\n inlineContentHTMLAttributes.class,\n );\n for (const [attribute, value] of Object.entries(\n inlineContentHTMLAttributes,\n )) {\n if (attribute !== \"class\") {\n inlineContent.setAttribute(attribute, value);\n }\n }\n\n blockContent.appendChild(inlineContent);\n\n return {\n dom: blockContent,\n contentDOM: inlineContent,\n };\n}\n\n// Function used to convert default blocks to HTML. It uses the corresponding\n// node's `renderHTML` method to do the conversion by using a default\n// `DOMSerializer`.\nexport const defaultBlockToHTML = <\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n block: BlockNoDefaults<BSchema, I, S>,\n editor: BlockNoteEditor<BSchema, I, S>,\n): {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n} => {\n let node = blockToNode(block, editor.pmSchema);\n\n if (node.type.name === \"blockContainer\") {\n // for regular blocks, get the toDOM spec from the blockContent node\n node = node.firstChild!;\n }\n\n const toDOM = editor.pmSchema.nodes[node.type.name].spec.toDOM;\n\n if (toDOM === undefined) {\n throw new Error(\n \"This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.\",\n );\n }\n\n const renderSpec = toDOM(node);\n\n if (typeof renderSpec !== \"object\" || !(\"dom\" in renderSpec)) {\n throw new Error(\n \"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.\",\n );\n }\n\n return renderSpec as {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n };\n};\n\n// Function that merges all paragraphs into a single one separated by line breaks.\n// This is used when parsing blocks like list items and table cells, as they may\n// contain multiple paragraphs that ProseMirror will not be able to handle\n// properly.\nexport function mergeParagraphs(element: HTMLElement, separator = \"<br>\") {\n const paragraphs = element.querySelectorAll(\"p\");\n if (paragraphs.length > 1) {\n const firstParagraph = paragraphs[0];\n for (let i = 1; i < paragraphs.length; i++) {\n const paragraph = paragraphs[i];\n firstParagraph.innerHTML += separator + paragraph.innerHTML;\n paragraph.remove();\n }\n }\n}\n","export function camelToDataKebab(str: string): string {\n return \"data-\" + str.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n}\n\nexport function filenameFromURL(url: string): string {\n const parts = url.split(\"/\");\n if (\n !parts.length || // invalid?\n parts[parts.length - 1] === \"\" // for example, URL ends in a directory-like trailing slash\n ) {\n // in this case just return the original url\n return url;\n }\n return parts[parts.length - 1];\n}\n","import { Attribute, Attributes, Editor, Node } from \"@tiptap/core\";\nimport { defaultBlockToHTML } from \"../../blocks/defaultBlockHelpers.js\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport { BlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { mergeCSSClasses } from \"../../util/browser.js\";\nimport { camelToDataKebab } from \"../../util/string.js\";\nimport { InlineContentSchema } from \"../inlineContent/types.js\";\nimport { PropSchema, Props } from \"../propTypes.js\";\nimport { StyleSchema } from \"../styles/types.js\";\nimport {\n BlockConfig,\n BlockSchemaWithBlock,\n LooseBlockSpec,\n SpecificBlock,\n} from \"./types.js\";\n\n// Function that uses the 'propSchema' of a blockConfig to create a TipTap\n// node's `addAttributes` property.\n// TODO: extract function\nexport function propsToAttributes(propSchema: PropSchema): Attributes {\n const tiptapAttributes: Record<string, Attribute> = {};\n\n Object.entries(propSchema).forEach(([name, spec]) => {\n tiptapAttributes[name] = {\n default: spec.default,\n keepOnSplit: true,\n // Props are displayed in kebab-case as HTML attributes. If a prop's\n // value is the same as its default, we don't display an HTML\n // attribute for it.\n parseHTML: (element) => {\n const value = element.getAttribute(camelToDataKebab(name));\n\n if (value === null) {\n return null;\n }\n\n if (\n (spec.default === undefined && spec.type === \"boolean\") ||\n (spec.default !== undefined && typeof spec.default === \"boolean\")\n ) {\n if (value === \"true\") {\n return true;\n }\n\n if (value === \"false\") {\n return false;\n }\n\n return null;\n }\n\n if (\n (spec.default === undefined && spec.type === \"number\") ||\n (spec.default !== undefined && typeof spec.default === \"number\")\n ) {\n const asNumber = parseFloat(value);\n const isNumeric =\n !Number.isNaN(asNumber) && Number.isFinite(asNumber);\n\n if (isNumeric) {\n return asNumber;\n }\n\n return null;\n }\n\n return value;\n },\n renderHTML: (attributes) => {\n // don't render to html if the value is the same as the default\n return attributes[name] !== spec.default\n ? {\n [camelToDataKebab(name)]: attributes[name],\n }\n : {};\n },\n };\n });\n\n return tiptapAttributes;\n}\n\n// Used to figure out which block should be rendered. This block is then used to\n// create the node view.\nexport function getBlockFromPos<\n BType extends string,\n Config extends BlockConfig,\n BSchema extends BlockSchemaWithBlock<BType, Config>,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n getPos: () => number | undefined,\n editor: BlockNoteEditor<BSchema, I, S>,\n tipTapEditor: Editor,\n type: BType,\n) {\n const pos = getPos();\n // Gets position of the node\n if (pos === undefined) {\n throw new Error(\"Cannot find node position\");\n }\n // Gets parent blockContainer node\n const blockContainer = tipTapEditor.state.doc.resolve(pos!).node();\n // Gets block identifier\n const blockIdentifier = blockContainer.attrs.id;\n\n if (!blockIdentifier) {\n throw new Error(\"Block doesn't have id\");\n }\n\n // Gets the block\n const block = editor.getBlock(blockIdentifier)! as SpecificBlock<\n BSchema,\n BType,\n I,\n S\n >;\n if (block.type !== type) {\n throw new Error(\"Block type does not match\");\n }\n\n return block;\n}\n\n// Function that wraps the `dom` element returned from 'blockConfig.render' in a\n// `blockContent` div, which contains the block type and props as HTML\n// attributes. If `blockConfig.render` also returns a `contentDOM`, it also adds\n// an `inlineContent` class to it.\nexport function wrapInBlockStructure<\n BType extends string,\n PSchema extends PropSchema,\n>(\n element: {\n dom: HTMLElement | DocumentFragment;\n contentDOM?: HTMLElement;\n destroy?: () => void;\n },\n blockType: BType,\n blockProps: Partial<Props<PSchema>>,\n propSchema: PSchema,\n isFileBlock = false,\n domAttributes?: Record<string, string>,\n): {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n destroy?: () => void;\n} {\n // Creates `blockContent` element\n const blockContent = document.createElement(\"div\");\n\n // Adds custom HTML attributes\n if (domAttributes !== undefined) {\n for (const [attr, value] of Object.entries(domAttributes)) {\n if (attr !== \"class\") {\n blockContent.setAttribute(attr, value);\n }\n }\n }\n // Sets blockContent class\n blockContent.className = mergeCSSClasses(\n \"bn-block-content\",\n domAttributes?.class || \"\",\n );\n // Sets content type attribute\n blockContent.setAttribute(\"data-content-type\", blockType);\n // Adds props as HTML attributes in kebab-case with \"data-\" prefix. Skips props\n // which are already added as HTML attributes to the parent `blockContent`\n // element (inheritedProps) and props set to their default values.\n for (const [prop, value] of Object.entries(blockProps)) {\n const spec = propSchema[prop];\n const defaultValue = spec.default;\n if (value !== defaultValue) {\n blockContent.setAttribute(camelToDataKebab(prop), value);\n }\n }\n // Adds file block attribute\n if (isFileBlock) {\n blockContent.setAttribute(\"data-file-block\", \"\");\n }\n\n blockContent.appendChild(element.dom);\n\n if (element.contentDOM) {\n element.contentDOM.className = mergeCSSClasses(\n \"bn-inline-content\",\n element.contentDOM.className,\n );\n }\n\n return {\n ...element,\n dom: blockContent,\n };\n}\n\nexport function createBlockSpecFromTiptapNode<\n const T extends {\n node: Node;\n type: string;\n content: \"inline\" | \"table\" | \"none\";\n },\n P extends PropSchema,\n>(\n config: T,\n propSchema: P,\n extensions?: BlockNoteExtension<any>[],\n): LooseBlockSpec<T[\"type\"], P, T[\"content\"]> {\n return {\n config: {\n type: config.type as T[\"type\"],\n content: config.content,\n propSchema,\n },\n implementation: {\n node: config.node,\n render: defaultBlockToHTML,\n toExternalHTML: defaultBlockToHTML,\n },\n extensions,\n };\n}\n","import { Editor, Node } from \"@tiptap/core\";\nimport { DOMParser, Fragment, TagParseRule } from \"@tiptap/pm/model\";\nimport { NodeView } from \"@tiptap/pm/view\";\nimport { mergeParagraphs } from \"../../blocks/defaultBlockHelpers.js\";\nimport { BlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { PropSchema } from \"../propTypes.js\";\nimport {\n getBlockFromPos,\n propsToAttributes,\n wrapInBlockStructure,\n} from \"./internal.js\";\nimport {\n BlockConfig,\n BlockImplementation,\n BlockSpec,\n LooseBlockSpec,\n} from \"./types.js\";\n\n// Function that causes events within non-selectable blocks to be handled by the\n// browser instead of the editor.\nexport function applyNonSelectableBlockFix(nodeView: NodeView, editor: Editor) {\n nodeView.stopEvent = (event) => {\n // Blurs the editor on mouse down as the block is non-selectable. This is\n // mainly done to prevent UI elements like the formatting toolbar from being\n // visible while content within a non-selectable block is selected.\n if (event.type === \"mousedown\") {\n setTimeout(() => {\n editor.view.dom.blur();\n }, 10);\n }\n\n return true;\n };\n}\n\n// Function that uses the 'parse' function of a blockConfig to create a\n// TipTap node's `parseHTML` property. This is only used for parsing content\n// from the clipboard.\nexport function getParseRules<\n TName extends string,\n TProps extends PropSchema,\n TContent extends \"inline\" | \"none\" | \"table\",\n>(\n config: BlockConfig<TName, TProps, TContent>,\n implementation: BlockImplementation<TName, TProps, TContent>,\n) {\n const rules: TagParseRule[] = [\n {\n tag: \"[data-content-type=\" + config.type + \"]\",\n contentElement: \".bn-inline-content\",\n },\n ];\n\n if (implementation.parse) {\n rules.push({\n tag: \"*\",\n getAttrs(node: string | HTMLElement) {\n if (typeof node === \"string\") {\n return false;\n }\n\n const props = implementation.parse?.(node);\n\n if (props === undefined) {\n return false;\n }\n\n return props;\n },\n getContent:\n config.content === \"inline\" || config.content === \"none\"\n ? (node, schema) => {\n if (implementation.parseContent) {\n return implementation.parseContent({\n el: node as HTMLElement,\n schema,\n });\n }\n\n if (config.content === \"inline\") {\n // Parse the inline content if it exists\n const element = node as HTMLElement;\n\n // Clone to avoid modifying the original\n const clone = element.cloneNode(true) as HTMLElement;\n\n // Merge multiple paragraphs into one with line breaks\n mergeParagraphs(\n clone,\n implementation.meta?.code ? \"\\n\" : \"<br>\",\n );\n\n // Parse the content directly as a paragraph to extract inline content\n const parser = DOMParser.fromSchema(schema);\n const parsed = parser.parse(clone, {\n topNode: schema.nodes.paragraph.create(),\n });\n\n return parsed.content;\n }\n return Fragment.empty;\n }\n : undefined,\n });\n }\n // getContent(node, schema) {\n // const block = blockConfig.parse?.(node as HTMLElement);\n //\n // if (block !== undefined && block.content !== undefined) {\n // return Fragment.from(\n // typeof block.content === \"string\"\n // ? schema.text(block.content)\n // : inlineContentToNodes(block.content, schema)\n // );\n // }\n //\n // return Fragment.empty;\n // },\n // });\n // }\n\n return rules;\n}\n\n// A function to create custom block for API consumers\n// we want to hide the tiptap node from API consumers and provide a simpler API surface instead\nexport function addNodeAndExtensionsToSpec<\n TName extends string,\n TProps extends PropSchema,\n TContent extends \"inline\" | \"none\" | \"table\",\n>(\n blockConfig: BlockConfig<TName, TProps, TContent>,\n blockImplementation: BlockImplementation<TName, TProps, TContent>,\n extensions?: BlockNoteExtension<any>[],\n priority?: number,\n): LooseBlockSpec<TName, TProps, TContent> {\n const node =\n ((blockImplementation as any).node as Node) ||\n Node.create({\n name: blockConfig.type,\n content: (blockConfig.content === \"inline\"\n ? \"inline*\"\n : blockConfig.content === \"none\"\n ? \"\"\n : blockConfig.content) as TContent extends \"inline\" ? \"inline*\" : \"\",\n group: \"blockContent\",\n selectable: blockImplementation.meta?.selectable ?? true,\n isolating: blockImplementation.meta?.isolating ?? true,\n code: blockImplementation.meta?.code ?? false,\n defining: blockImplementation.meta?.defining ?? true,\n priority,\n addAttributes() {\n return propsToAttributes(blockConfig.propSchema);\n },\n\n parseHTML() {\n return getParseRules(blockConfig, blockImplementation);\n },\n\n renderHTML({ HTMLAttributes }) {\n // renderHTML is used for copy/pasting content from the editor back into\n // the editor, so we need to make sure the `blockContent` element is\n // structured correctly as this is what's used for parsing blocks. We\n // just render a placeholder div inside as the `blockContent` element\n // already has all the information needed for proper parsing.\n const div = document.createElement(\"div\");\n return wrapInBlockStructure(\n {\n dom: div,\n contentDOM: blockConfig.content === \"inline\" ? div : undefined,\n },\n blockConfig.type,\n {},\n blockConfig.propSchema,\n blockImplementation.meta?.fileBlockAccept !== undefined,\n HTMLAttributes,\n );\n },\n\n addNodeView() {\n return (props) => {\n // Gets the BlockNote editor instance\n const editor = this.options.editor;\n // Gets the block\n const block = getBlockFromPos(\n props.getPos,\n editor,\n this.editor,\n blockConfig.type,\n );\n // Gets the custom HTML attributes for `blockContent` nodes\n const blockContentDOMAttributes =\n this.options.domAttributes?.blockContent || {};\n\n const nodeView = blockImplementation.render.call(\n { blockContentDOMAttributes, props, renderType: \"nodeView\" },\n block as any,\n editor as any,\n );\n\n if (blockImplementation.meta?.selectable === false) {\n applyNonSelectableBlockFix(nodeView, this.editor);\n }\n\n // See explanation for why `update` is not implemented for NodeViews\n // https://github.com/TypeCellOS/BlockNote/pull/1904#discussion_r2313461464\n return nodeView;\n };\n },\n });\n\n if (node.name !== blockConfig.type) {\n throw new Error(\n \"Node name does not match block type. This is a bug in BlockNote.\",\n );\n }\n\n return {\n config: blockConfig,\n implementation: {\n node,\n render(block, editor) {\n const blockContentDOMAttributes =\n node.options.domAttributes?.blockContent || {};\n\n return blockImplementation.render.call(\n {\n blockContentDOMAttributes,\n props: undefined,\n renderType: \"dom\",\n },\n block as any,\n editor as any,\n );\n },\n // TODO: this should not have wrapInBlockStructure and generally be a lot simpler\n // post-processing in externalHTMLExporter should not be necessary\n toExternalHTML: (block, editor) => {\n const blockContentDOMAttributes =\n node.options.domAttributes?.blockContent || {};\n\n return (\n blockImplementation.toExternalHTML?.call(\n { blockContentDOMAttributes },\n block as any,\n editor as any,\n ) ??\n blockImplementation.render.call(\n { blockContentDOMAttributes, renderType: \"dom\", props: undefined },\n block as any,\n editor as any,\n )\n );\n },\n },\n extensions,\n };\n}\n\n/**\n * Helper function to create a block config.\n */\nexport function createBlockConfig<\n TCallback extends (\n options: Partial<Record<string, any>>,\n ) => BlockConfig<any, any, any>,\n TOptions extends Parameters<TCallback>[0],\n TName extends ReturnType<TCallback>[\"type\"],\n TProps extends ReturnType<TCallback>[\"propSchema\"],\n TContent extends ReturnType<TCallback>[\"content\"],\n>(\n callback: TCallback,\n): TOptions extends undefined\n ? () => BlockConfig<TName, TProps, TContent>\n : (options: TOptions) => BlockConfig<TName, TProps, TContent> {\n return callback as any;\n}\n\n/**\n * Helper function to create a block definition.\n * Can accept either functions that return the required objects, or the objects directly.\n */\nexport function createBlockSpec<\n const TName extends string,\n const TProps extends PropSchema,\n const TContent extends \"inline\" | \"none\",\n const TOptions extends Partial<Record<string, any>> | undefined = undefined,\n>(\n blockConfigOrCreator: BlockConfig<TName, TProps, TContent>,\n blockImplementationOrCreator:\n | BlockImplementation<TName, TProps, TContent>\n | (TOptions extends undefined\n ? () => BlockImplementation<TName, TProps, TContent>\n : (\n options: Partial<TOptions>,\n ) => BlockImplementation<TName, TProps, TContent>),\n extensionsOrCreator?:\n | BlockNoteExtension<any>[]\n | (TOptions extends undefined\n ? () => BlockNoteExtension<any>[]\n : (options: Partial<TOptions>) => BlockNoteExtension<any>[]),\n): (options?: Partial<TOptions>) => BlockSpec<TName, TProps, TContent>;\nexport function createBlockSpec<\n const TName extends string,\n const TProps extends PropSchema,\n const TContent extends \"inline\" | \"none\",\n const BlockConf extends BlockConfig<TName, TProps, TContent>,\n const TOptions extends Partial<Record<string, any>>,\n>(\n blockCreator: (options: Partial<TOptions>) => BlockConf,\n blockImplementationOrCreator:\n | BlockImplementation<\n BlockConf[\"type\"],\n BlockConf[\"propSchema\"],\n BlockConf[\"content\"]\n >\n | (TOptions extends undefined\n ? () => BlockImplementation<\n BlockConf[\"type\"],\n BlockConf[\"propSchema\"],\n BlockConf[\"content\"]\n >\n : (\n options: Partial<TOptions>,\n ) => BlockImplementation<\n BlockConf[\"type\"],\n BlockConf[\"propSchema\"],\n BlockConf[\"content\"]\n >),\n extensionsOrCreator?:\n | BlockNoteExtension<any>[]\n | (TOptions extends undefined\n ? () => BlockNoteExtension<any>[]\n : (options: Partial<TOptions>) => BlockNoteExtension<any>[]),\n): (\n options?: Partial<TOptions>,\n) => BlockSpec<\n BlockConf[\"type\"],\n BlockConf[\"propSchema\"],\n BlockConf[\"content\"]\n>;\nexport function createBlockSpec<\n const TName extends string,\n const TProps extends PropSchema,\n const TContent extends \"inline\" | \"none\",\n const TOptions extends Partial<Record<string, any>> | undefined = undefined,\n>(\n blockConfigOrCreator:\n | BlockConfig<TName, TProps, TContent>\n | (TOptions extends undefined\n ? () => BlockConfig<TName, TProps, TContent>\n : (options: Partial<TOptions>) => BlockConfig<TName, TProps, TContent>),\n blockImplementationOrCreator:\n | BlockImplementation<TName, TProps, TContent>\n | (TOptions extends undefined\n ? () => BlockImplementation<TName, TProps, TContent>\n : (\n options: Partial<TOptions>,\n ) => BlockImplementation<TName, TProps, TContent>),\n extensionsOrCreator?:\n | BlockNoteExtension<any>[]\n | (TOptions extends undefined\n ? () => BlockNoteExtension<any>[]\n : (options: Partial<TOptions>) => BlockNoteExtension<any>[]),\n): (options?: Partial<TOptions>) => BlockSpec<TName, TProps, TContent> {\n return (options = {} as TOptions) => {\n const blockConfig =\n typeof blockConfigOrCreator === \"function\"\n ? blockConfigOrCreator(options as any)\n : blockConfigOrCreator;\n\n const blockImplementation =\n typeof blockImplementationOrCreator === \"function\"\n ? blockImplementationOrCreator(options as any)\n : blockImplementationOrCreator;\n\n const extensions = extensionsOrCreator\n ? typeof extensionsOrCreator === \"function\"\n ? extensionsOrCreator(options as any)\n : extensionsOrCreator\n : undefined;\n\n return {\n config: blockConfig,\n implementation: {\n ...blockImplementation,\n // TODO: this should not have wrapInBlockStructure and generally be a lot simpler\n // post-processing in externalHTMLExporter should not be necessary\n toExternalHTML(block, editor) {\n const output = blockImplementation.toExternalHTML?.call(\n { blockContentDOMAttributes: this.blockContentDOMAttributes },\n block as any,\n editor as any,\n );\n\n if (output === undefined) {\n return undefined;\n }\n\n return wrapInBlockStructure(\n output,\n block.type,\n block.props,\n blockConfig.propSchema,\n blockImplementation.meta?.fileBlockAccept !== undefined,\n );\n },\n render(block, editor) {\n const output = blockImplementation.render.call(\n {\n blockContentDOMAttributes: this.blockContentDOMAttributes,\n renderType: this.renderType,\n props: this.props as any,\n },\n block as any,\n editor as any,\n );\n\n const nodeView = wrapInBlockStructure(\n output,\n block.type,\n block.props,\n blockConfig.propSchema,\n blockImplementation.meta?.fileBlockAccept !== undefined,\n this.blockContentDOMAttributes,\n ) satisfies NodeView;\n\n return nodeView;\n },\n },\n extensions: extensions,\n };\n };\n}\n","import { Node, ResolvedPos } from \"prosemirror-model\";\nimport { EditorState, Transaction } from \"prosemirror-state\";\n\ntype SingleBlockInfo = {\n node: Node;\n beforePos: number;\n afterPos: number;\n};\n\nexport type BlockInfo = {\n /**\n * The outer node that represents a BlockNote block. This is the node that has the ID.\n * Most of the time, this will be a blockContainer node, but it could also be a Column or ColumnList\n */\n bnBlock: SingleBlockInfo;\n /**\n * The type of BlockNote block that this node represents.\n * When dealing with a blockContainer, this is retrieved from the blockContent node, otherwise it's retrieved from the bnBlock node.\n */\n blockNoteType: string;\n} & (\n | {\n // In case we're not dealing with a BlockContainer, we're dealing with a \"wrapper node\" (like a Column or ColumnList), so it will always have children\n\n /**\n * The Prosemirror node that holds block.children. For non-blockContainer, this node will be the same as bnBlock.\n */\n childContainer: SingleBlockInfo;\n isBlockContainer: false;\n }\n | {\n /**\n * The Prosemirror node that holds block.children. For blockContainers, this is the blockGroup node, if it exists.\n */\n childContainer?: SingleBlockInfo;\n /**\n * The Prosemirror node that wraps block.content and has most of the props\n */\n blockContent: SingleBlockInfo;\n /**\n * Whether bnBlock is a blockContainer node\n */\n isBlockContainer: true;\n }\n);\n\n/**\n * Retrieves the position just before the nearest block node in a ProseMirror\n * doc, relative to a position. If the position is within a block node or its\n * descendants, the position just before it is returned. If the position is not\n * within a block node or its descendants, the position just before the next\n * closest block node is returned. If the position is beyond the last block, the\n * position just before the last block is returned.\n * @param doc The ProseMirror doc.\n * @param pos An integer position in the document.\n * @returns The position just before the nearest blockContainer node.\n */\nexport function getNearestBlockPos(doc: Node, pos: number) {\n const $pos = doc.resolve(pos);\n\n // Checks if the position provided is already just before a block node, in\n // which case we return the position.\n if ($pos.nodeAfter && $pos.nodeAfter.type.isInGroup(\"bnBlock\")) {\n return {\n posBeforeNode: $pos.pos,\n node: $pos.nodeAfter,\n };\n }\n\n // Checks the node containing the position and its ancestors until a\n // block node is found and returned.\n let depth = $pos.depth;\n let node = $pos.node(depth);\n while (depth > 0) {\n if (node.type.isInGroup(\"bnBlock\")) {\n return {\n posBeforeNode: $pos.before(depth),\n node: node,\n };\n }\n\n depth--;\n node = $pos.node(depth);\n }\n\n // If the position doesn't lie within a block node, we instead find the\n // position of the next closest one. If the position is beyond the last block,\n // we return the position of the last block. While running `doc.descendants`\n // is expensive, this case should be very rarely triggered. However, it's\n // possible for the position to sometimes be beyond the last block node. This\n // is a problem specifically when using the collaboration plugin.\n const allBlockContainerPositions: number[] = [];\n doc.descendants((node, pos) => {\n if (node.type.isInGroup(\"bnBlock\")) {\n allBlockContainerPositions.push(pos);\n }\n });\n\n // eslint-disable-next-line no-console\n console.warn(`Position ${pos} is not within a blockContainer node.`);\n\n const resolvedPos = doc.resolve(\n allBlockContainerPositions.find((position) => position >= pos) ||\n allBlockContainerPositions[allBlockContainerPositions.length - 1],\n );\n return {\n posBeforeNode: resolvedPos.pos,\n node: resolvedPos.nodeAfter!,\n };\n}\n\n/**\n * Gets information regarding the ProseMirror nodes that make up a block in a\n * BlockNote document. This includes the main `blockContainer` node, the\n * `blockContent` node with the block's main body, and the optional `blockGroup`\n * node which contains the block's children. As well as the nodes, also returns\n * the ProseMirror positions just before & after each node.\n * @param node The main `blockContainer` node that the block information should\n * be retrieved from,\n * @param bnBlockBeforePosOffset the position just before the\n * `blockContainer` node in the document.\n */\nexport function getBlockInfoWithManualOffset(\n node: Node,\n bnBlockBeforePosOffset: number,\n): BlockInfo {\n if (!node.type.isInGroup(\"bnBlock\")) {\n throw new Error(\n `Attempted to get bnBlock node at position but found node of different type ${node.type.name}`,\n );\n }\n\n const bnBlockNode = node;\n const bnBlockBeforePos = bnBlockBeforePosOffset;\n const bnBlockAfterPos = bnBlockBeforePos + bnBlockNode.nodeSize;\n\n const bnBlock: SingleBlockInfo = {\n node: bnBlockNode,\n beforePos: bnBlockBeforePos,\n afterPos: bnBlockAfterPos,\n };\n\n if (bnBlockNode.type.name === \"blockContainer\") {\n let blockContent: SingleBlockInfo | undefined;\n let blockGroup: SingleBlockInfo | undefined;\n\n bnBlockNode.forEach((node, offset) => {\n if (node.type.spec.group === \"blockContent\") {\n // console.log(beforePos, offset);\n const blockContentNode = node;\n const blockContentBeforePos = bnBlockBeforePos + offset + 1;\n const blockContentAfterPos = blockContentBeforePos + node.nodeSize;\n\n blockContent = {\n node: blockContentNode,\n beforePos: blockContentBeforePos,\n afterPos: blockContentAfterPos,\n };\n } else if (node.type.name === \"blockGroup\") {\n const blockGroupNode = node;\n const blockGroupBeforePos = bnBlockBeforePos + offset + 1;\n const blockGroupAfterPos = blockGroupBeforePos + node.nodeSize;\n\n blockGroup = {\n node: blockGroupNode,\n beforePos: blockGroupBeforePos,\n afterPos: blockGroupAfterPos,\n };\n }\n });\n\n if (!blockContent) {\n throw new Error(\n `blockContainer node does not contain a blockContent node in its children: ${bnBlockNode}`,\n );\n }\n\n return {\n isBlockContainer: true,\n bnBlock,\n blockContent,\n childContainer: blockGroup,\n blockNoteType: blockContent.node.type.name,\n };\n } else {\n if (!bnBlock.node.type.isInGroup(\"childContainer\")) {\n throw new Error(\n `bnBlock node is not in the childContainer group: ${bnBlock.node}`,\n );\n }\n\n return {\n isBlockContainer: false,\n bnBlock: bnBlock,\n childContainer: bnBlock,\n blockNoteType: bnBlock.node.type.name,\n };\n }\n}\n\n/**\n * Gets information regarding the ProseMirror nodes that make up a block in a\n * BlockNote document. This includes the main `blockContainer` node, the\n * `blockContent` node with the block's main body, and the optional `blockGroup`\n * node which contains the block's children. As well as the nodes, also returns\n * the ProseMirror positions just before & after each node.\n * @param posInfo An object with the main `blockContainer` node that the block\n * information should be retrieved from, and the position just before it in the\n * document.\n */\nexport function getBlockInfo(posInfo: { posBeforeNode: number; node: Node }) {\n return getBlockInfoWithManualOffset(posInfo.node, posInfo.posBeforeNode);\n}\n\n/**\n * Gets information regarding the ProseMirror nodes that make up a block from a\n * resolved position just before the `blockContainer` node in the document that\n * corresponds to it.\n * @param resolvedPos The resolved position just before the `blockContainer`\n * node.\n */\nexport function getBlockInfoFromResolvedPos(resolvedPos: ResolvedPos) {\n if (!resolvedPos.nodeAfter) {\n throw new Error(\n `Attempted to get blockContainer node at position ${resolvedPos.pos} but a node at this position does not exist`,\n );\n }\n return getBlockInfoWithManualOffset(resolvedPos.nodeAfter, resolvedPos.pos);\n}\n\n/**\n * Gets information regarding the ProseMirror nodes that make up a block. The\n * block chosen is the one currently containing the current ProseMirror\n * selection.\n * @param state The ProseMirror editor state.\n */\nexport function getBlockInfoFromSelection(state: EditorState) {\n const posInfo = getNearestBlockPos(state.doc, state.selection.anchor);\n\n return getBlockInfo(posInfo);\n}\n\n/**\n * Gets information regarding the ProseMirror nodes that make up a block. The\n * block chosen is the one currently containing the current ProseMirror\n * selection.\n * @param tr The ProseMirror transaction.\n */\nexport function getBlockInfoFromTransaction(tr: Transaction) {\n const posInfo = getNearestBlockPos(tr.doc, tr.selection.anchor);\n\n return getBlockInfo(posInfo);\n}\n","import type { Node, Schema } from \"prosemirror-model\";\nimport { Transform } from \"prosemirror-transform\";\nimport type { BlockNoteEditor } from \"../editor/BlockNoteEditor.js\";\nimport { BlockNoteSchema } from \"../blocks/BlockNoteSchema.js\";\nimport type { BlockSchema } from \"../schema/blocks/types.js\";\nimport type { InlineContentSchema } from \"../schema/inlineContent/types.js\";\nimport type { StyleSchema } from \"../schema/styles/types.js\";\n\nexport function getPmSchema(trOrNode: Transform | Node) {\n if (\"doc\" in trOrNode) {\n return trOrNode.doc.type.schema;\n }\n return trOrNode.type.schema;\n}\n\nfunction getBlockNoteEditor<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(schema: Schema): BlockNoteEditor<BSchema, I, S> {\n return schema.cached.blockNoteEditor as BlockNoteEditor<BSchema, I, S>;\n}\n\nexport function getBlockNoteSchema<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(schema: Schema): BlockNoteSchema<BSchema, I, S> {\n return getBlockNoteEditor(schema).schema as unknown as BlockNoteSchema<\n BSchema,\n I,\n S\n >;\n}\n\nexport function getBlockSchema<BSchema extends BlockSchema>(\n schema: Schema,\n): BSchema {\n return getBlockNoteSchema(schema).blockSchema as BSchema;\n}\n\nexport function getInlineContentSchema<I extends InlineContentSchema>(\n schema: Schema,\n): I {\n return getBlockNoteSchema(schema).inlineContentSchema as I;\n}\n\nexport function getStyleSchema<S extends StyleSchema>(schema: Schema): S {\n return getBlockNoteSchema(schema).styleSchema as S;\n}\n\nexport function getBlockCache(schema: Schema) {\n return getBlockNoteEditor(schema).blockCache;\n}\n","import { Mark, Node, Schema, Slice } from \"@tiptap/pm/model\";\nimport type { Block } from \"../../blocks/defaultBlocks.js\";\nimport UniqueID from \"../../extensions/UniqueID/UniqueID.js\";\nimport type {\n BlockSchema,\n CustomInlineContentConfig,\n CustomInlineContentFromConfig,\n InlineContent,\n InlineContentFromConfig,\n InlineContentSchema,\n StyleSchema,\n Styles,\n TableCell,\n TableContent,\n} from \"../../schema/index.js\";\nimport {\n isLinkInlineContent,\n isStyledTextInlineContent,\n} from \"../../schema/inlineContent/types.js\";\nimport { UnreachableCaseError } from \"../../util/typescript.js\";\nimport { getBlockInfoWithManualOffset } from \"../getBlockInfoFromPos.js\";\nimport {\n getBlockCache,\n getBlockSchema,\n getInlineContentSchema,\n getStyleSchema,\n} from \"../pmUtil.js\";\n\n/**\n * Converts an internal (prosemirror) table node contentto a BlockNote Tablecontent\n */\nexport function contentNodeToTableContent<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(contentNode: Node, inlineContentSchema: I, styleSchema: S) {\n const ret: TableContent<I, S> = {\n type: \"tableContent\",\n columnWidths: [],\n headerRows: undefined,\n headerCols: undefined,\n rows: [],\n };\n\n /**\n * A matrix of boolean values indicating whether a cell is a header.\n * The first index is the row index, the second index is the cell index.\n */\n const headerMatrix: boolean[][] = [];\n\n contentNode.content.forEach((rowNode, _offset, rowIndex) => {\n const row: TableContent<I, S>[\"rows\"][0] = {\n cells: [],\n };\n\n if (rowIndex === 0) {\n rowNode.content.forEach((cellNode) => {\n let colWidth = cellNode.attrs.colwidth as null | undefined | number[];\n if (colWidth === undefined || colWidth === null) {\n colWidth = new Array(cellNode.attrs.colspan ?? 1).fill(undefined);\n }\n ret.columnWidths.push(...colWidth);\n });\n }\n\n row.cells = rowNode.content.content.map((cellNode, cellIndex) => {\n if (!headerMatrix[rowIndex]) {\n headerMatrix[rowIndex] = [];\n }\n // Mark the cell as a header if it is a tableHeader node.\n headerMatrix[rowIndex][cellIndex] = cellNode.type.name === \"tableHeader\";\n // Convert cell content to inline content and merge adjacent styled text nodes\n const content = cellNode.content.content\n .map((child) =>\n contentNodeToInlineContent(child, inlineContentSchema, styleSchema),\n )\n // The reason that we merge this content is that we allow table cells to contain multiple tableParagraph nodes\n // So that we can leverage prosemirror-tables native merging\n // If the schema only allowed a single tableParagraph node, then the merging would not work and cause prosemirror to fit the content into a new cell\n .reduce(\n (acc, contentPartial) => {\n if (!acc.length) {\n return contentPartial;\n }\n\n const last = acc[acc.length - 1];\n const first = contentPartial[0];\n\n // Only merge if the last and first content are both styled text nodes and have the same styles\n if (\n first &&\n isStyledTextInlineContent(last) &&\n isStyledTextInlineContent(first) &&\n JSON.stringify(last.styles) === JSON.stringify(first.styles)\n ) {\n // Join them together if they have the same styles\n last.text += \"\\n\" + first.text;\n acc.push(...contentPartial.slice(1));\n return acc;\n }\n acc.push(...contentPartial);\n return acc;\n },\n [] as InlineContent<I, S>[],\n );\n\n return {\n type: \"tableCell\",\n content,\n props: {\n colspan: cellNode.attrs.colspan,\n rowspan: cellNode.attrs.rowspan,\n backgroundColor: cellNode.attrs.backgroundColor,\n textColor: cellNode.attrs.textColor,\n textAlignment: cellNode.attrs.textAlignment,\n },\n } satisfies TableCell<I, S>;\n });\n\n ret.rows.push(row);\n });\n\n for (let i = 0; i < headerMatrix.length; i++) {\n if (headerMatrix[i]?.every((isHeader) => isHeader)) {\n ret.headerRows = (ret.headerRows ?? 0) + 1;\n }\n }\n\n for (let i = 0; i < headerMatrix[0]?.length; i++) {\n if (headerMatrix?.every((row) => row[i])) {\n ret.headerCols = (ret.headerCols ?? 0) + 1;\n }\n }\n\n return ret;\n}\n\n/**\n * Converts an internal (prosemirror) content node to a BlockNote InlineContent array.\n */\nexport function contentNodeToInlineContent<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(contentNode: Node, inlineContentSchema: I, styleSchema: S) {\n const content: InlineContent<any, S>[] = [];\n let currentContent: InlineContent<any, S> | undefined = undefined;\n\n // Most of the logic below is for handling links because in ProseMirror links are marks\n // while in BlockNote links are a type of inline content\n contentNode.content.forEach((node) => {\n // hardBreak nodes do not have an InlineContent equivalent, instead we\n // add a newline to the previous node.\n if (node.type.name === \"hardBreak\") {\n if (currentContent) {\n // Current content exists.\n if (isStyledTextInlineContent(currentContent)) {\n // Current content is text.\n currentContent.text += \"\\n\";\n } else if (isLinkInlineContent(currentContent)) {\n // Current content is a link.\n currentContent.content[currentContent.content.length - 1].text +=\n \"\\n\";\n } else {\n throw new Error(\"unexpected\");\n }\n } else {\n // Current content does not exist.\n currentContent = {\n type: \"text\",\n text: \"\\n\",\n styles: {},\n };\n }\n\n return;\n }\n\n if (node.type.name !== \"link\" && node.type.name !== \"text\") {\n if (!inlineContentSchema[node.type.name]) {\n // eslint-disable-next-line no-console\n console.warn(\"unrecognized inline content type\", node.type.name);\n return;\n }\n if (currentContent) {\n content.push(currentContent);\n currentContent = undefined;\n }\n\n content.push(\n nodeToCustomInlineContent(node, inlineContentSchema, styleSchema),\n );\n\n return;\n }\n\n const styles: Styles<S> = {};\n let linkMark: Mark | undefined;\n\n for (const mark of node.marks) {\n if (mark.type.name === \"link\") {\n linkMark = mark;\n } else {\n const config = styleSchema[mark.type.name];\n if (!config) {\n if (mark.type.spec.blocknoteIgnore) {\n // at this point, we don't want to show certain marks (such as comments)\n // in the BlockNote JSON output. These marks should be tagged with \"blocknoteIgnore\" in the spec\n continue;\n }\n throw new Error(`style ${mark.type.name} not found in styleSchema`);\n }\n if (config.propSchema === \"boolean\") {\n (styles as any)[config.type] = true;\n } else if (config.propSchema === \"string\") {\n (styles as any)[config.type] = mark.attrs.stringValue;\n } else {\n throw new UnreachableCaseError(config.propSchema);\n }\n }\n }\n\n // Parsing links and text.\n // Current content exists.\n if (currentContent) {\n // Current content is text.\n if (isStyledTextInlineContent(currentContent)) {\n if (!linkMark) {\n // Node is text (same type as current content).\n if (\n JSON.stringify(currentContent.styles) === JSON.stringify(styles)\n ) {\n // Styles are the same.\n currentContent.text += node.textContent;\n } else {\n // Styles are different.\n content.push(currentContent);\n currentContent = {\n type: \"text\",\n text: node.textContent,\n styles,\n };\n }\n } else {\n // Node is a link (different type to current content).\n content.push(currentContent);\n currentContent = {\n type: \"link\",\n href: linkMark.attrs.href,\n content: [\n {\n type: \"text\",\n text: node.textContent,\n styles,\n },\n ],\n };\n }\n } else if (isLinkInlineContent(currentContent)) {\n // Current content is a link.\n if (linkMark) {\n // Node is a link (same type as current content).\n // Link URLs are the same.\n if (currentContent.href === linkMark.attrs.href) {\n // Styles are the same.\n if (\n JSON.stringify(\n currentContent.content[currentContent.content.length - 1]\n .styles,\n ) === JSON.stringify(styles)\n ) {\n currentContent.content[currentContent.content.length - 1].text +=\n node.textContent;\n } else {\n // Styles are different.\n currentContent.content.push({\n type: \"text\",\n text: node.textContent,\n styles,\n });\n }\n } else {\n // Link URLs are different.\n content.push(currentContent);\n currentContent = {\n type: \"link\",\n href: linkMark.attrs.href,\n content: [\n {\n type: \"text\",\n text: node.textContent,\n styles,\n },\n ],\n };\n }\n } else {\n // Node is text (different type to current content).\n content.push(currentContent);\n currentContent = {\n type: \"text\",\n text: node.textContent,\n styles,\n };\n }\n } else {\n // TODO\n }\n }\n // Current content does not exist.\n else {\n // Node is text.\n if (!linkMark) {\n currentContent = {\n type: \"text\",\n text: node.textContent,\n styles,\n };\n }\n // Node is a link.\n else {\n currentContent = {\n type: \"link\",\n href: linkMark.attrs.href,\n content: [\n {\n type: \"text\",\n text: node.textContent,\n styles,\n },\n ],\n };\n }\n }\n });\n\n if (currentContent) {\n content.push(currentContent);\n }\n\n return content as InlineContent<I, S>[];\n}\n\nexport function nodeToCustomInlineContent<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(node: Node, inlineContentSchema: I, styleSchema: S): InlineContent<I, S> {\n if (node.type.name === \"text\" || node.type.name === \"link\") {\n throw new Error(\"unexpected\");\n }\n const props: any = {};\n const icConfig = inlineContentSchema[\n node.type.name\n ] as CustomInlineContentConfig;\n for (const [attr, value] of Object.entries(node.attrs)) {\n if (!icConfig) {\n throw Error(\"ic node is of an unrecognized type: \" + node.type.name);\n }\n\n const propSchema = icConfig.propSchema;\n\n if (attr in propSchema) {\n props[attr] = value;\n }\n }\n\n let content: CustomInlineContentFromConfig<any, any>[\"content\"];\n\n if (icConfig.content === \"styled\") {\n content = contentNodeToInlineContent(\n node,\n inlineContentSchema,\n styleSchema,\n ) as any; // TODO: is this safe? could we have Links here that are undesired?\n } else {\n content = undefined;\n }\n\n const ic = {\n type: node.type.name,\n props,\n content,\n } as InlineContentFromConfig<I[keyof I], S>;\n return ic;\n}\n\n/**\n * Convert a Prosemirror node to a BlockNote block.\n *\n * TODO: test changes\n */\nexport function nodeToBlock<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n node: Node,\n schema: Schema,\n blockSchema: BSchema = getBlockSchema(schema) as BSchema,\n inlineContentSchema: I = getInlineContentSchema(schema) as I,\n styleSchema: S = getStyleSchema(schema) as S,\n blockCache = getBlockCache(schema),\n): Block<BSchema, I, S> {\n if (!node.type.isInGroup(\"bnBlock\")) {\n throw Error(\"Node should be a bnBlock, but is instead: \" + node.type.name);\n }\n\n const cachedBlock = blockCache?.get(node);\n\n if (cachedBlock) {\n return cachedBlock;\n }\n\n const blockInfo = getBlockInfoWithManualOffset(node, 0);\n\n let id = blockInfo.bnBlock.node.attrs.id;\n\n // Only used for blocks converted from other formats.\n if (id === null) {\n id = UniqueID.options.generateID();\n }\n\n const blockSpec = blockSchema[blockInfo.blockNoteType];\n\n if (!blockSpec) {\n throw Error(\"Block is of an unrecognized type: \" + blockInfo.blockNoteType);\n }\n\n const props: any = {};\n for (const [attr, value] of Object.entries({\n ...node.attrs,\n ...(blockInfo.isBlockContainer ? blockInfo.blockContent.node.attrs : {}),\n })) {\n const propSchema = blockSpec.propSchema;\n\n if (\n attr in propSchema &&\n !(propSchema[attr].default === undefined && value === undefined)\n ) {\n props[attr] = value;\n }\n }\n\n const blockConfig = blockSchema[blockInfo.blockNoteType];\n\n const children: Block<BSchema, I, S>[] = [];\n blockInfo.childContainer?.node.forEach((child) => {\n children.push(\n nodeToBlock(\n child,\n schema,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n blockCache,\n ),\n );\n });\n\n let content: Block<any, any, any>[\"content\"];\n\n if (blockConfig.content === \"inline\") {\n if (!blockInfo.isBlockContainer) {\n throw new Error(\"impossible\");\n }\n content = contentNodeToInlineContent(\n blockInfo.blockContent.node,\n inlineContentSchema,\n styleSchema,\n );\n } else if (blockConfig.content === \"table\") {\n if (!blockInfo.isBlockContainer) {\n throw new Error(\"impossible\");\n }\n content = contentNodeToTableContent(\n blockInfo.blockContent.node,\n inlineContentSchema,\n styleSchema,\n );\n } else if (blockConfig.content === \"none\") {\n content = undefined;\n } else {\n throw new UnreachableCaseError(blockConfig.content);\n }\n\n const block = {\n id,\n type: blockConfig.type,\n props,\n content,\n children,\n } as Block<BSchema, I, S>;\n\n blockCache?.set(node, block);\n\n return block;\n}\n\n/**\n * Convert a Prosemirror document to a BlockNote document (array of blocks)\n */\nexport function docToBlocks<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n doc: Node,\n schema: Schema,\n blockSchema: BSchema = getBlockSchema(schema) as BSchema,\n inlineContentSchema: I = getInlineContentSchema(schema) as I,\n styleSchema: S = getStyleSchema(schema) as S,\n blockCache = getBlockCache(schema),\n) {\n const blocks: Block<BSchema, I, S>[] = [];\n doc.firstChild!.descendants((node) => {\n blocks.push(\n nodeToBlock(\n node,\n schema,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n blockCache,\n ),\n );\n return false;\n });\n return blocks;\n}\n\n/**\n *\n * Parse a Prosemirror Slice into a BlockNote selection. The prosemirror schema looks like this:\n *\n * <blockGroup>\n * <blockContainer> (main content of block)\n * <p, heading, etc.>\n * <blockGroup> (only if blocks has children)\n * <blockContainer> (child block)\n * <p, heading, etc.>\n * </blockContainer>\n * <blockContainer> (child block 2)\n * <p, heading, etc.>\n * </blockContainer>\n * </blockContainer>\n * </blockGroup>\n * </blockGroup>\n *\n */\nexport function prosemirrorSliceToSlicedBlocks<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n slice: Slice,\n schema: Schema,\n blockSchema: BSchema = getBlockSchema(schema) as BSchema,\n inlineContentSchema: I = getInlineContentSchema(schema) as I,\n styleSchema: S = getStyleSchema(schema) as S,\n blockCache: WeakMap<Node, Block<BSchema, I, S>> = getBlockCache(schema),\n): {\n /**\n * The blocks that are included in the selection.\n */\n blocks: Block<BSchema, I, S>[];\n /**\n * If a block was \"cut\" at the start of the selection, this will be the id of the block that was cut.\n */\n blockCutAtStart: string | undefined;\n /**\n * If a block was \"cut\" at the end of the selection, this will be the id of the block that was cut.\n */\n blockCutAtEnd: string | undefined;\n} {\n // console.log(JSON.stringify(slice.toJSON()));\n function processNode(\n node: Node,\n openStart: number,\n openEnd: number,\n ): {\n blocks: Block<BSchema, I, S>[];\n blockCutAtStart: string | undefined;\n blockCutAtEnd: string | undefined;\n } {\n if (node.type.name !== \"blockGroup\") {\n throw new Error(\"unexpected\");\n }\n const blocks: Block<BSchema, I, S>[] = [];\n let blockCutAtStart: string | undefined;\n let blockCutAtEnd: string | undefined;\n\n node.forEach((blockContainer, _offset, index) => {\n if (blockContainer.type.name !== \"blockContainer\") {\n throw new Error(\"unexpected\");\n }\n if (blockContainer.childCount === 0) {\n return;\n }\n if (blockContainer.childCount === 0 || blockContainer.childCount > 2) {\n throw new Error(\n \"unexpected, blockContainer.childCount: \" + blockContainer.childCount,\n );\n }\n\n const isFirstBlock = index === 0;\n const isLastBlock = index === node.childCount - 1;\n\n if (blockContainer.firstChild!.type.name === \"blockGroup\") {\n // this is the parent where a selection starts within one of its children,\n // e.g.:\n // A\n // ├── B\n // selection starts within B, then this blockContainer is A, but we don't care about A\n // so let's descend into B and continue processing\n if (!isFirstBlock) {\n throw new Error(\"unexpected\");\n }\n const ret = processNode(\n blockContainer.firstChild!,\n Math.max(0, openStart - 1),\n isLastBlock ? Math.max(0, openEnd - 1) : 0,\n );\n blockCutAtStart = ret.blockCutAtStart;\n if (isLastBlock) {\n blockCutAtEnd = ret.blockCutAtEnd;\n }\n blocks.push(...ret.blocks);\n return;\n }\n\n const block = nodeToBlock(\n blockContainer,\n schema,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n blockCache,\n );\n const childGroup =\n blockContainer.childCount > 1 ? blockContainer.child(1) : undefined;\n\n let childBlocks: Block<BSchema, I, S>[] = [];\n if (childGroup) {\n const ret = processNode(\n childGroup,\n 0, // TODO: can this be anything other than 0?\n isLastBlock ? Math.max(0, openEnd - 1) : 0,\n );\n childBlocks = ret.blocks;\n if (isLastBlock) {\n blockCutAtEnd = ret.blockCutAtEnd;\n }\n }\n\n if (isLastBlock && !childGroup && openEnd > 1) {\n blockCutAtEnd = block.id;\n }\n\n if (isFirstBlock && openStart > 1) {\n blockCutAtStart = block.id;\n }\n\n blocks.push({\n ...(block as any),\n children: childBlocks,\n });\n });\n\n return { blocks, blockCutAtStart, blockCutAtEnd };\n }\n\n if (slice.content.childCount === 0) {\n return {\n blocks: [],\n blockCutAtStart: undefined,\n blockCutAtEnd: undefined,\n };\n }\n\n if (slice.content.childCount !== 1) {\n throw new Error(\n \"slice must be a single block, did you forget includeParents=true?\",\n );\n }\n\n return processNode(\n slice.content.firstChild!,\n Math.max(slice.openStart - 1, 0),\n Math.max(slice.openEnd - 1, 0),\n );\n}\n","import { KeyboardShortcutCommand, Node } from \"@tiptap/core\";\n\nimport { camelToDataKebab } from \"../../util/string.js\";\nimport { PropSchema, Props } from \"../propTypes.js\";\nimport {\n CustomInlineContentConfig,\n InlineContentImplementation,\n InlineContentSchemaFromSpecs,\n InlineContentSpec,\n InlineContentSpecs,\n} from \"./types.js\";\n\n// Function that adds necessary classes and attributes to the `dom` element\n// returned from a custom inline content's 'render' function, to ensure no data\n// is lost on internal copy & paste.\nexport function addInlineContentAttributes<\n IType extends string,\n PSchema extends PropSchema,\n>(\n element: {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n },\n inlineContentType: IType,\n inlineContentProps: Props<PSchema>,\n propSchema: PSchema,\n): {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n} {\n // Sets content type attribute\n element.dom.setAttribute(\"data-inline-content-type\", inlineContentType);\n // Adds props as HTML attributes in kebab-case with \"data-\" prefix. Skips props\n // set to their default values.\n Object.entries(inlineContentProps)\n .filter(([prop, value]) => {\n const spec = propSchema[prop];\n return value !== spec.default;\n })\n .map(([prop, value]) => {\n return [camelToDataKebab(prop), value];\n })\n .forEach(([prop, value]) => element.dom.setAttribute(prop, value));\n\n if (element.contentDOM) {\n element.contentDOM.setAttribute(\"data-editable\", \"\");\n }\n\n return element;\n}\n\n// see https://github.com/TypeCellOS/BlockNote/pull/435\nexport function addInlineContentKeyboardShortcuts<\n T extends CustomInlineContentConfig,\n>(\n config: T,\n): {\n [p: string]: KeyboardShortcutCommand;\n} {\n return {\n Backspace: ({ editor }) => {\n const resolvedPos = editor.state.selection.$from;\n\n return (\n editor.state.selection.empty &&\n resolvedPos.node().type.name === config.type &&\n resolvedPos.parentOffset === 0\n );\n },\n };\n}\n\n// This helper function helps to instantiate a InlineContentSpec with a\n// config and implementation that conform to the type of Config\nexport function createInternalInlineContentSpec<\n const T extends CustomInlineContentConfig,\n>(\n config: T,\n implementation: InlineContentImplementation<NoInfer<T>>,\n): InlineContentSpec<T> {\n return {\n config,\n implementation,\n } as const;\n}\n\nexport function createInlineContentSpecFromTipTapNode<\n T extends Node,\n P extends PropSchema,\n>(\n node: T,\n propSchema: P,\n implementation: Omit<\n InlineContentImplementation<CustomInlineContentConfig>,\n \"node\"\n >,\n) {\n return createInternalInlineContentSpec(\n {\n type: node.name as T[\"name\"],\n propSchema,\n content: node.config.content === \"inline*\" ? \"styled\" : \"none\",\n },\n {\n ...implementation,\n node,\n },\n );\n}\n\nexport function getInlineContentSchemaFromSpecs<T extends InlineContentSpecs>(\n specs: T,\n) {\n return Object.fromEntries(\n Object.entries(specs).map(([key, value]) => [key, value.config]),\n ) as InlineContentSchemaFromSpecs<T>;\n}\n","import { Attributes, Mark } from \"@tiptap/core\";\nimport { DOMSerializer } from \"@tiptap/pm/model\";\nimport {\n StyleConfig,\n StyleImplementation,\n StylePropSchema,\n StyleSchemaFromSpecs,\n StyleSpec,\n StyleSpecs,\n} from \"./types.js\";\n\nexport function stylePropsToAttributes(\n propSchema: StylePropSchema,\n): Attributes {\n if (propSchema === \"boolean\") {\n return {};\n }\n return {\n stringValue: {\n default: undefined,\n keepOnSplit: true,\n parseHTML: (element) => element.getAttribute(\"data-value\"),\n renderHTML: (attributes) =>\n attributes.stringValue !== undefined\n ? {\n \"data-value\": attributes.stringValue,\n }\n : {},\n },\n };\n}\n\n// Function that adds necessary classes and attributes to the `dom` element\n// returned from a custom style's 'render' function, to ensure no data is lost\n// on internal copy & paste.\nexport function addStyleAttributes<\n SType extends string,\n PSchema extends StylePropSchema,\n>(\n element: {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n },\n styleType: SType,\n styleValue: PSchema extends \"boolean\" ? undefined : string,\n propSchema: PSchema,\n): {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n} {\n // Sets content type attribute\n element.dom.setAttribute(\"data-style-type\", styleType);\n // Adds style value as an HTML attribute in kebab-case with \"data-\" prefix, if\n // the style takes a string value.\n if (propSchema === \"string\") {\n element.dom.setAttribute(\"data-value\", styleValue as string);\n }\n\n if (element.contentDOM) {\n element.contentDOM.setAttribute(\"data-editable\", \"\");\n }\n\n return element;\n}\n\n// This helper function helps to instantiate a stylespec with a\n// config and implementation that conform to the type of Config\nexport function createInternalStyleSpec<T extends StyleConfig>(\n config: T,\n implementation: StyleImplementation<T>,\n) {\n return {\n config,\n implementation,\n } satisfies StyleSpec<T>;\n}\n\nexport function createStyleSpecFromTipTapMark<\n T extends Mark,\n P extends StylePropSchema,\n>(mark: T, propSchema: P) {\n return createInternalStyleSpec(\n {\n type: mark.name as T[\"name\"],\n propSchema,\n },\n {\n mark,\n render(value, editor) {\n const toDOM = editor.pmSchema.marks[mark.name].spec.toDOM;\n\n if (toDOM === undefined) {\n throw new Error(\n \"This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.\",\n );\n }\n\n const markInstance = editor.pmSchema.mark(mark.name, {\n stringValue: value,\n });\n\n const renderSpec = DOMSerializer.renderSpec(\n document,\n toDOM(markInstance, true),\n );\n\n if (typeof renderSpec !== \"object\" || !(\"dom\" in renderSpec)) {\n throw new Error(\n \"Cannot use this block's default HTML serialization as its corresponding TipTap mark's `renderHTML` function does not return an object with the `dom` property.\",\n );\n }\n\n return renderSpec as {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n };\n },\n toExternalHTML(value, editor) {\n const toDOM = editor.pmSchema.marks[mark.name].spec.toDOM;\n\n if (toDOM === undefined) {\n throw new Error(\n \"This block has no default HTML serialization as its corresponding TipTap node doesn't implement `renderHTML`.\",\n );\n }\n\n const markInstance = editor.pmSchema.mark(mark.name, {\n stringValue: value,\n });\n\n const renderSpec = DOMSerializer.renderSpec(\n document,\n toDOM(markInstance, true),\n );\n\n if (typeof renderSpec !== \"object\" || !(\"dom\" in renderSpec)) {\n throw new Error(\n \"Cannot use this block's default HTML serialization as its corresponding TipTap mark's `renderHTML` function does not return an object with the `dom` property.\",\n );\n }\n\n return renderSpec as {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n };\n },\n },\n );\n}\n\nexport function getStyleSchemaFromSpecs<T extends StyleSpecs>(specs: T) {\n return Object.fromEntries(\n Object.entries(specs).map(([key, value]) => [key, value.config]),\n ) as StyleSchemaFromSpecs<T>;\n}\n","import { Mark } from \"@tiptap/core\";\n\nimport { ParseRule, TagParseRule } from \"@tiptap/pm/model\";\nimport {\n addStyleAttributes,\n createInternalStyleSpec,\n stylePropsToAttributes,\n} from \"./internal.js\";\nimport { StyleConfig, StyleSpec } from \"./types.js\";\n\nexport type CustomStyleImplementation<T extends StyleConfig> = {\n render: (value: T[\"propSchema\"] extends \"boolean\" ? undefined : string) => {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n };\n toExternalHTML?: (\n value: T[\"propSchema\"] extends \"boolean\" ? undefined : string,\n ) => {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n };\n parse?: (\n element: HTMLElement,\n ) => (T[\"propSchema\"] extends \"boolean\" ? true : string) | undefined;\n};\n\nexport function getStyleParseRules<T extends StyleConfig>(\n config: T,\n customParseFunction?: CustomStyleImplementation<T>[\"parse\"],\n): ParseRule[] {\n const rules: TagParseRule[] = [\n {\n tag: `[data-style-type=\"${config.type}\"]`,\n contentElement: (element) => {\n const htmlElement = element as HTMLElement;\n\n if (htmlElement.matches(\"[data-editable]\")) {\n return htmlElement;\n }\n\n return htmlElement.querySelector(\"[data-editable]\") || htmlElement;\n },\n },\n ];\n\n if (customParseFunction) {\n rules.push({\n tag: \"*\",\n getAttrs(node: string | HTMLElement) {\n if (typeof node === \"string\") {\n return false;\n }\n\n const stringValue = customParseFunction?.(node);\n\n if (stringValue === undefined) {\n return false;\n }\n\n return { stringValue };\n },\n });\n }\n return rules;\n}\n\nexport function createStyleSpec<const T extends StyleConfig>(\n styleConfig: T,\n styleImplementation: CustomStyleImplementation<T>,\n): StyleSpec<T> {\n const mark = Mark.create({\n name: styleConfig.type,\n\n addAttributes() {\n return stylePropsToAttributes(styleConfig.propSchema);\n },\n\n parseHTML() {\n return getStyleParseRules(styleConfig, styleImplementation.parse);\n },\n\n renderHTML({ mark }) {\n const renderResult = (\n styleImplementation.toExternalHTML || styleImplementation.render\n )(mark.attrs.stringValue);\n\n return addStyleAttributes(\n renderResult,\n styleConfig.type,\n mark.attrs.stringValue,\n styleConfig.propSchema,\n );\n },\n\n addMarkView() {\n return ({ mark }) => {\n const renderResult = styleImplementation.render(mark.attrs.stringValue);\n\n return addStyleAttributes(\n renderResult,\n styleConfig.type,\n mark.attrs.stringValue,\n styleConfig.propSchema,\n );\n };\n },\n });\n\n return createInternalStyleSpec(styleConfig, {\n mark,\n render: (value) => {\n const renderResult = styleImplementation.render(value as any);\n\n return addStyleAttributes(\n renderResult,\n styleConfig.type,\n value,\n styleConfig.propSchema,\n );\n },\n toExternalHTML: (value) => {\n const renderResult = (\n styleImplementation.toExternalHTML || styleImplementation.render\n )(value as any);\n\n return addStyleAttributes(\n renderResult,\n styleConfig.type,\n value,\n styleConfig.propSchema,\n );\n },\n });\n}\n","/**\n * Instead of depending on the NPM package, we vendor this file from https://github.com/n1ru4l/toposort/blob/main/src/toposort.ts (MIT)\n *\n * There was a recent publish, despite not having been updated in 2 years, which is suspicious.\n *\n * This file is also simple enough that we can maintain it ourselves.\n */\n\nexport type DirectedAcyclicGraph = Map<string, Iterable<string>>;\nexport type DependencyGraph = DirectedAcyclicGraph;\n\nexport type TaskList = Array<Set<string>>;\n\n// Add more specific types for better type safety\nexport type NodeId = string;\nexport type DependencyMap = Map<NodeId, Set<NodeId>>;\n\nexport function toposort(dag: DirectedAcyclicGraph): TaskList {\n const inDegrees = countInDegrees(dag);\n\n let { roots, nonRoots } = getRootsAndNonRoots(inDegrees);\n\n const sorted: TaskList = [];\n\n while (roots.size) {\n sorted.push(roots);\n\n const newRoots = new Set<NodeId>();\n for (const root of roots) {\n const dependents = dag.get(root);\n if (!dependents) {\n // Handle case where node has no dependents\n continue;\n }\n\n for (const dependent of dependents) {\n const currentDegree = inDegrees.get(dependent);\n if (currentDegree === undefined) {\n // Handle case where dependent node is not in inDegrees\n continue;\n }\n\n const newDegree = currentDegree - 1;\n inDegrees.set(dependent, newDegree);\n\n if (newDegree === 0) {\n newRoots.add(dependent);\n }\n }\n }\n\n roots = newRoots;\n }\n nonRoots = getRootsAndNonRoots(inDegrees).nonRoots;\n\n if (nonRoots.size) {\n throw new Error(\n `Cycle(s) detected; toposort only works on acyclic graphs. Cyclic nodes: ${Array.from(nonRoots).join(\", \")}`,\n );\n }\n\n return sorted;\n}\n\nexport function toposortReverse(deps: DependencyGraph): TaskList {\n const dag = reverse(deps);\n return toposort(dag);\n}\n\ntype InDegrees = Map<NodeId, number>;\n\nfunction countInDegrees(dag: DirectedAcyclicGraph): InDegrees {\n const counts: InDegrees = new Map();\n\n for (const [vx, dependents] of dag.entries()) {\n // Initialize count for current node if not present\n if (!counts.has(vx)) {\n counts.set(vx, 0);\n }\n\n for (const dependent of dependents) {\n const currentCount = counts.get(dependent) ?? 0;\n counts.set(dependent, currentCount + 1);\n }\n }\n\n return counts;\n}\n\nfunction getRootsAndNonRoots(counts: InDegrees) {\n const roots = new Set<NodeId>();\n const nonRoots = new Set<NodeId>();\n\n for (const [id, deg] of counts.entries()) {\n if (deg === 0) {\n roots.add(id);\n } else {\n nonRoots.add(id);\n }\n }\n\n return { roots, nonRoots };\n}\n\nfunction reverse(deps: DirectedAcyclicGraph): DependencyGraph {\n const reversedDeps: DependencyMap = new Map();\n\n for (const [name, dependsOn] of deps.entries()) {\n // Ensure the source node exists in the reversed map\n if (!reversedDeps.has(name)) {\n reversedDeps.set(name, new Set());\n }\n\n for (const dependsOnName of dependsOn) {\n if (!reversedDeps.has(dependsOnName)) {\n reversedDeps.set(dependsOnName, new Set());\n }\n reversedDeps.get(dependsOnName)!.add(name);\n }\n }\n\n return reversedDeps;\n}\n\nexport function createDependencyGraph(): DependencyMap {\n return new Map();\n}\n\nexport function addDependency(\n graph: DependencyMap,\n from: NodeId,\n to: NodeId,\n): DependencyMap {\n if (!graph.has(from)) {\n graph.set(from, new Set());\n }\n graph.get(from)!.add(to);\n return graph;\n}\n\nexport function removeDependency(\n graph: DependencyMap,\n from: NodeId,\n to: NodeId,\n): boolean {\n const dependents = graph.get(from);\n if (!dependents) {\n return false;\n }\n return dependents.delete(to);\n}\n\nexport function hasDependency(\n graph: DependencyMap,\n from: NodeId,\n to: NodeId,\n): boolean {\n const dependents = graph.get(from);\n return dependents ? dependents.has(to) : false;\n}\n","import { BlockNoteEditor } from \"../editor/BlockNoteEditor.js\";\nimport { createDependencyGraph, toposortReverse } from \"../util/topo-sort.js\";\nimport {\n BlockNoDefaults,\n BlockSchema,\n BlockSpecs,\n InlineContentConfig,\n InlineContentSchema,\n InlineContentSpec,\n InlineContentSpecs,\n LooseBlockSpec,\n PartialBlockNoDefaults,\n StyleSchema,\n StyleSpecs,\n addNodeAndExtensionsToSpec,\n getInlineContentSchemaFromSpecs,\n getStyleSchemaFromSpecs,\n} from \"./index.js\";\n\nfunction removeUndefined<T extends Record<string, any> | undefined>(obj: T): T {\n if (!obj) {\n return obj;\n }\n return Object.fromEntries(\n Object.entries(obj).filter(([, value]) => value !== undefined),\n ) as T;\n}\n\nexport class CustomBlockNoteSchema<\n BSchema extends BlockSchema,\n ISchema extends InlineContentSchema,\n SSchema extends StyleSchema,\n> {\n // Helper so that you can use typeof schema.BlockNoteEditor\n public readonly BlockNoteEditor: BlockNoteEditor<BSchema, ISchema, SSchema> =\n \"only for types\" as any;\n\n public readonly Block: BlockNoDefaults<BSchema, ISchema, SSchema> =\n \"only for types\" as any;\n\n public readonly PartialBlock: PartialBlockNoDefaults<\n BSchema,\n ISchema,\n SSchema\n > = \"only for types\" as any;\n\n public inlineContentSpecs: InlineContentSpecs;\n public styleSpecs: StyleSpecs;\n public blockSpecs: {\n [K in keyof BSchema]: K extends string\n ? LooseBlockSpec<K, BSchema[K][\"propSchema\"], BSchema[K][\"content\"]>\n : never;\n };\n\n public blockSchema: BSchema;\n public inlineContentSchema: ISchema;\n public styleSchema: SSchema;\n\n constructor(\n private opts: {\n blockSpecs: BlockSpecs;\n inlineContentSpecs: InlineContentSpecs;\n styleSpecs: StyleSpecs;\n },\n ) {\n const {\n blockSpecs,\n inlineContentSpecs,\n styleSpecs,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n } = this.init();\n this.blockSpecs = blockSpecs;\n this.styleSpecs = styleSpecs;\n this.styleSchema = styleSchema;\n this.inlineContentSpecs = inlineContentSpecs;\n this.blockSchema = blockSchema;\n this.inlineContentSchema = inlineContentSchema;\n }\n\n private init() {\n const dag = createDependencyGraph();\n const defaultSet = new Set<string>();\n dag.set(\"default\", defaultSet);\n\n for (const [key, specDef] of Object.entries(this.opts.blockSpecs)) {\n if (specDef.implementation.runsBefore) {\n dag.set(key, new Set(specDef.implementation.runsBefore));\n } else {\n defaultSet.add(key);\n }\n }\n const sortedSpecs = toposortReverse(dag);\n const defaultIndex = sortedSpecs.findIndex((set) => set.has(\"default\"));\n\n /**\n * The priority of a block is described relative to the \"default\" block (an arbitrary block which can be used as the reference)\n *\n * Since blocks are topologically sorted, we can see what their relative position is to the \"default\" block\n * Each layer away from the default block is 10 priority points (arbitrarily chosen)\n * The default block is fixed at 101 (1 point higher than any tiptap extension, giving priority to custom blocks than any defaults)\n *\n * This is a bit of a hack, but it's a simple way to ensure that custom blocks are always rendered with higher priority than default blocks\n * and that custom blocks are rendered in the order they are defined in the schema\n */\n const getPriority = (key: string) => {\n const index = sortedSpecs.findIndex((set) => set.has(key));\n // the default index should map to 101\n // one before the default index is 91\n // one after is 111\n return 91 + (index + defaultIndex) * 10;\n };\n\n const blockSpecs = Object.fromEntries(\n Object.entries(this.opts.blockSpecs).map(([key, blockSpec]) => {\n return [\n key,\n addNodeAndExtensionsToSpec(\n blockSpec.config,\n blockSpec.implementation,\n blockSpec.extensions,\n getPriority(key),\n ),\n ];\n }),\n ) as {\n [K in keyof BSchema]: K extends string\n ? LooseBlockSpec<K, BSchema[K][\"propSchema\"], BSchema[K][\"content\"]>\n : never;\n };\n\n return {\n blockSpecs,\n blockSchema: Object.fromEntries(\n Object.entries(blockSpecs).map(([key, blockDef]) => {\n return [key, blockDef.config];\n }),\n ) as any,\n inlineContentSpecs: removeUndefined(this.opts.inlineContentSpecs),\n styleSpecs: removeUndefined(this.opts.styleSpecs),\n inlineContentSchema: getInlineContentSchemaFromSpecs(\n this.opts.inlineContentSpecs,\n ) as any,\n styleSchema: getStyleSchemaFromSpecs(this.opts.styleSpecs) as any,\n };\n }\n\n /**\n * Adds additional block specs to the current schema in a builder pattern.\n * This method allows extending the schema after it has been created.\n *\n * @param additionalBlockSpecs - Additional block specs to add to the schema\n * @returns The current schema instance for chaining\n */\n public extend<\n AdditionalBlockSpecs extends BlockSpecs = Record<string, never>,\n AdditionalInlineContentSpecs extends Record<\n string,\n InlineContentSpec<InlineContentConfig>\n > = Record<string, never>,\n AdditionalStyleSpecs extends StyleSpecs = Record<string, never>,\n >(opts: {\n blockSpecs?: AdditionalBlockSpecs;\n inlineContentSpecs?: AdditionalInlineContentSpecs;\n styleSpecs?: AdditionalStyleSpecs;\n }): CustomBlockNoteSchema<\n AdditionalBlockSpecs extends undefined | Record<string, never>\n ? BSchema\n : BSchema & {\n [K in keyof AdditionalBlockSpecs]: K extends string\n ? AdditionalBlockSpecs[K][\"config\"]\n : never;\n },\n AdditionalInlineContentSpecs extends undefined | Record<string, never>\n ? ISchema\n : ISchema & {\n [K in keyof AdditionalInlineContentSpecs]: AdditionalInlineContentSpecs[K][\"config\"];\n },\n AdditionalStyleSpecs extends undefined | Record<string, never>\n ? SSchema\n : SSchema & {\n [K in keyof AdditionalStyleSpecs]: AdditionalStyleSpecs[K][\"config\"];\n }\n > {\n // Merge the new specs with existing ones\n Object.assign(this.opts.blockSpecs, opts.blockSpecs);\n Object.assign(this.opts.inlineContentSpecs, opts.inlineContentSpecs);\n Object.assign(this.opts.styleSpecs, opts.styleSpecs);\n\n // Reinitialize the block specs with the merged specs\n const {\n blockSpecs,\n inlineContentSpecs,\n styleSpecs,\n blockSchema,\n inlineContentSchema,\n styleSchema,\n } = this.init();\n this.blockSpecs = blockSpecs;\n this.styleSpecs = styleSpecs;\n this.styleSchema = styleSchema;\n this.inlineContentSpecs = inlineContentSpecs;\n this.blockSchema = blockSchema;\n this.inlineContentSchema = inlineContentSchema;\n\n return this as any;\n }\n}\n","import { DefaultBlockSchema } from \"../../../blocks/defaultBlocks.js\";\nimport {\n BlockFromConfigNoChildren,\n PartialTableContent,\n TableCell,\n TableContent,\n} from \"../../../schema/blocks/types.js\";\nimport {\n isPartialLinkInlineContent,\n isStyledTextInlineContent,\n} from \"../../../schema/index.js\";\nimport {\n getColspan,\n getRowspan,\n isPartialTableCell,\n mapTableCell,\n} from \"../../../util/table.js\";\n\n/**\n * Here be dragons.\n *\n * Tables are complex because of rowspan and colspan behavior.\n * The majority of this file is concerned with translating between \"relative\" and \"absolute\" indices.\n *\n * The following diagram may help explain the relationship between the different indices:\n *\n * One-based indexing of rows and columns in a table:\n * | 1-1 | 1-2 | 1-3 |\n * | 2-1 | 2-2 | 2-3 |\n * | 3-1 | 3-2 | 3-3 |\n *\n * A complicated table with colspans and rowspans:\n * | 1-1 | 1-2 | 1-2 |\n * | 2-1 | 2-1 | 2-2 |\n * | 2-1 | 2-1 | 3-1 |\n *\n * You can see here that we have:\n * - two cells that contain the value \"1-2\", because it has a colspan of 2.\n * - four cells that contain the value \"2-1\", because it has a rowspan of 2 and a colspan of 2.\n *\n * This would be represented in block note json (roughly) as:\n * [\n * {\n * \"cells\": [\n * {\n * \"type\": \"tableCell\",\n * \"content\": [\"1,1\"],\n * \"props\": {\n * \"colspan\": 1,\n * \"rowspan\": 1\n * },\n * },\n * {\n * \"type\": \"tableCell\",\n * \"content\": [\"1,2\"],\n * \"props\": {\n * \"colspan\": 2,\n * \"rowspan\": 1\n * }\n * }\n * ],\n * },\n * {\n * \"cells\": [\n * {\n * \"type\": \"tableCell\",\n * \"content\": [\"2,1\"],\n * \"props\": {\n * \"colspan\": 2,\n * \"rowspan\": 2\n * }\n * },\n * {\n * \"type\": \"tableCell\",\n * \"content\": [\"2,2\"],\n * \"props\": {\n * \"colspan\": 1,\n * \"rowspan\": 1\n * }\n * ],\n * },\n * {\n * \"cells\": [\n * {\n * \"type\": \"tableCell\",\n * \"content\": [\"3,1\"],\n * \"props\": {\n * \"colspan\": 1,\n * \"rowspan\": 1,\n * }\n * }\n * ]\n * }\n * ]\n *\n * Which maps cleanly to the following HTML:\n *\n * <table>\n * <tr>\n * <td>1-1</td>\n * <td colspan=\"2\">1-2</td>\n * </tr>\n * <tr>\n * <td rowspan=\"2\" colspan=\"2\">2-1</td>\n * <td>2-2</td>\n * </tr>\n * <tr>\n * <td>3-1</td>\n * </tr>\n * </table>\n *\n * We have a problem though, from the block json, there is no way to tell that the cell \"2-1\" is the second cell in the second row.\n * To resolve this, we created the occupancy grid, which is a grid of all the cells in the table, as though they were only 1x1 cells.\n * See {@link OccupancyGrid} for more information.\n *\n */\n\n/**\n * Relative cell indices are relative to the table block's content.\n *\n * This is a sparse representation of the table and is how HTML and BlockNote JSON represent tables.\n *\n * For example, if we have a table with a rowspan of 2, the second row may only have 1 element in a 2x2 table.\n *\n * ```\n * // Visual representation of the table\n * | 1-1 | 1-2 | // has 2 cells\n * | 1-1 | 2-2 | // has only 1 cell\n * // Relative cell indices\n * [{ row: 1, col: 1, rowspan: 2 }, { row: 1, col: 2 }] // has 2 cells\n * [{ row: 1, col: 2 }] // has only 1 cell\n * ```\n */\nexport type RelativeCellIndices = {\n row: number;\n col: number;\n};\n\n/**\n * Absolute cell indices are relative to the table's layout (it's {@link OccupancyGrid}).\n *\n * It is as though the table is a grid of 1x1 cells, and any colspan or rowspan results in multiple 1x1 cells being occupied.\n *\n * For example, if we have a table with a colspan of 2, it will occupy 2 cells in the layout grid.\n *\n * ```\n * // Visual representation of the table\n * | 1-1 | 1-1 | // has 2 cells\n * | 2-1 | 2-2 | // has 2 cell\n * // Absolute cell indices\n * [{ row: 1, col: 1, colspan: 2 }, { row: 1, col: 2, colspan: 2 }] // has 2 cells\n * [{ row: 1, col: 1 }, { row: 1, col: 2 }] // has 2 cells\n * ```\n */\nexport type AbsoluteCellIndices = {\n row: number;\n col: number;\n};\n\n/**\n * An occupancy grid is a grid of the occupied cells in the table.\n * It is used to track the occupied cells in the table to know where to place the next cell.\n *\n * Since it allows us to resolve cell indices both {@link RelativeCellIndices} and {@link AbsoluteCellIndices}, it is the core data structure for table operations.\n */\ntype OccupancyGrid = (RelativeCellIndices & {\n /**\n * The rowspan of the cell.\n */\n rowspan: number;\n /**\n * The colspan of the cell.\n */\n colspan: number;\n /**\n * The cell.\n */\n cell: TableCell<any, any>;\n})[][];\n\n/**\n * This will return the {@link OccupancyGrid} of the table.\n * By laying out the table as though it were a grid of 1x1 cells, we can easily track where the cells are located (both relatively and absolutely).\n *\n * @returns an {@link OccupancyGrid}\n */\nexport function getTableCellOccupancyGrid(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n): OccupancyGrid {\n const { height, width } = getDimensionsOfTable(block);\n\n /**\n * Create a grid to track occupied cells\n * This is used because rowspans and colspans take up multiple spaces\n * So, we need to track the occupied cells in the grid to know where to place the next cell\n */\n const grid: OccupancyGrid = new Array(height)\n .fill(false)\n .map(() => new Array(width).fill(null));\n\n // Find the next unoccupied cell in the table, row-major order\n const findNextAvailable = (row: number, col: number) => {\n for (let i = row; i < height; i++) {\n for (let j = col; j < width; j++) {\n if (!grid[i][j]) {\n return { row: i, col: j };\n }\n }\n }\n\n throw new Error(\n \"Unable to create occupancy grid for table, no more available cells\",\n );\n };\n\n // Build up the grid, trying to fill in the cells with the correct relative row and column indices\n for (let row = 0; row < block.content.rows.length; row++) {\n for (let col = 0; col < block.content.rows[row].cells.length; col++) {\n const cell = mapTableCell(block.content.rows[row].cells[col]);\n const rowspan = getRowspan(cell);\n const colspan = getColspan(cell);\n\n // Rowspan and colspan complicate things, by taking up multiple cells in the grid\n // We need to iterate over the cells that the rowspan and colspan take up\n // and fill in the grid with the correct relative row and column indices\n const { row: startRow, col: startCol } = findNextAvailable(row, col);\n\n // Fill in the rowspan X colspan cells, starting from the next available cell, with the correct relative row and column indices\n for (let i = startRow; i < startRow + rowspan; i++) {\n for (let j = startCol; j < startCol + colspan; j++) {\n if (grid[i][j]) {\n // The cell is already occupied, the table is malformed\n throw new Error(\n `Unable to create occupancy grid for table, cell at ${i},${j} is already occupied`,\n );\n }\n\n grid[i][j] = {\n row,\n col,\n rowspan,\n colspan,\n cell,\n };\n }\n }\n }\n }\n\n // console.log(grid);\n\n return grid;\n}\n\n/**\n * Given an {@link OccupancyGrid}, this will return the {@link TableContent} rows.\n *\n * @note This will remove duplicates from the occupancy grid. And does no bounds checking for validity of the occupancy grid.\n */\nexport function getTableRowsFromOccupancyGrid(\n occupancyGrid: OccupancyGrid,\n): TableContent<any, any>[\"rows\"] {\n // Because a cell can have a rowspan or colspan, it can occupy multiple cells in the occupancy grid\n // So, we need to remove duplicates from the occupancy grid before we can return the table rows\n const seen = new Set<string>();\n\n return occupancyGrid.map((row) => {\n // Just read out the cells in the occupancy grid, removing duplicates\n return {\n cells: row\n .map((cell) => {\n if (seen.has(cell.row + \":\" + cell.col)) {\n return false;\n }\n seen.add(cell.row + \":\" + cell.col);\n return cell.cell;\n })\n .filter((cell): cell is TableCell<any, any> => cell !== false),\n };\n });\n}\n\n/**\n * This will resolve the relative cell indices within the table block to the absolute cell indices within the table, accounting for colspan and rowspan.\n *\n * @note It will return only the first cell (i.e. top-left) that matches the relative cell indices. To find the other absolute cell indices this cell occupies, you can assume it is the rowspan and colspan number of cells away from the top-left cell.\n *\n * @returns The {@link AbsoluteCellIndices} and the {@link TableCell} at the absolute position.\n */\nexport function getAbsoluteTableCells(\n /**\n * The relative position of the cell in the table.\n */\n relativeCellIndices: RelativeCellIndices,\n /**\n * The table block containing the cell.\n */\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n /**\n * The occupancy grid of the table.\n */\n occupancyGrid: OccupancyGrid = getTableCellOccupancyGrid(block),\n): AbsoluteCellIndices & {\n cell: TableCell<any, any>;\n} {\n for (let r = 0; r < occupancyGrid.length; r++) {\n for (let c = 0; c < occupancyGrid[r].length; c++) {\n // console.log(r, c, occupancyGrid);\n const cell = occupancyGrid[r][c];\n if (\n cell.row === relativeCellIndices.row &&\n cell.col === relativeCellIndices.col\n ) {\n return { row: r, col: c, cell: cell.cell };\n }\n }\n }\n\n throw new Error(\n `Unable to resolve relative table cell indices for table, cell at ${relativeCellIndices.row},${relativeCellIndices.col} is not occupied`,\n );\n}\n\n/**\n * This will get the dimensions of the table block.\n *\n * @returns The height and width of the table.\n */\nexport function getDimensionsOfTable(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n): {\n /**\n * The number of rows in the table.\n */\n height: number;\n /**\n * The number of columns in the table.\n */\n width: number;\n} {\n // Due to the way we store the table, the height is always the number of rows\n const height = block.content.rows.length;\n\n // Calculating the width is a bit more complex, as it is the maximum width of any row\n let width = 0;\n block.content.rows.forEach((row) => {\n // Find the width of the row by summing the colspan of each cell\n let rowWidth = 0;\n row.cells.forEach((cell) => {\n rowWidth += getColspan(cell);\n });\n\n // Update the width if the row is wider than the current width\n width = Math.max(width, rowWidth);\n });\n\n return { height, width };\n}\n\n/**\n * This will resolve the absolute cell indices within the table block to the relative cell indices within the table, accounting for colspan and rowspan.\n *\n * @returns The {@link RelativeCellIndices} and the {@link TableCell} at the relative position.\n */\nexport function getRelativeTableCells(\n /**\n * The {@link AbsoluteCellIndices} of the cell in the table.\n */\n absoluteCellIndices: AbsoluteCellIndices,\n /**\n * The table block containing the cell.\n */\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n /**\n * The occupancy grid of the table.\n */\n occupancyGrid: OccupancyGrid = getTableCellOccupancyGrid(block),\n):\n | (RelativeCellIndices & {\n cell: TableContent<any, any>[\"rows\"][number][\"cells\"][number];\n })\n | undefined {\n const occupancyCell =\n occupancyGrid[absoluteCellIndices.row]?.[absoluteCellIndices.col];\n\n // Double check that the cell can be accessed\n if (!occupancyCell) {\n // The cell is not occupied, so it is invalid\n return undefined;\n }\n\n return {\n row: occupancyCell.row,\n col: occupancyCell.col,\n cell: occupancyCell.cell,\n };\n}\n\n/**\n * This will get all the cells within a relative row of a table block.\n *\n * This method always starts the search for the row at the first column of the table.\n *\n * ```\n * // Visual representation of a table\n * | A | B | C |\n * | | D | E |\n * | F | G | H |\n * // \"A\" has a rowspan of 2\n *\n * // getCellsAtRowHandle(0)\n * // returns [\n * { row: 0, col: 0, cell: \"A\" },\n * { row: 0, col: 1, cell: \"B\" },\n * { row: 0, col: 2, cell: \"C\" },\n * ]\n *\n * // getCellsAtColumnHandle(1)\n * // returns [\n * { row: 1, col: 0, cell: \"F\" },\n * { row: 1, col: 1, cell: \"G\" },\n * { row: 1, col: 2, cell: \"H\" },\n * ]\n * ```\n *\n * As you can see, you may not be able to retrieve all nodes given a relative row index, as cells can span multiple rows.\n *\n * @returns All of the cells associated with the relative row of the table. (All cells that have the same relative row index)\n */\nexport function getCellsAtRowHandle(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n relativeRowIndex: RelativeCellIndices[\"row\"],\n) {\n const occupancyGrid = getTableCellOccupancyGrid(block);\n\n if (relativeRowIndex < 0 || relativeRowIndex >= occupancyGrid.length) {\n return [];\n }\n\n // First need to resolve the relative row index to an absolute row index\n let absoluteRow = 0;\n\n // Jump through the occupied cells ${relativeCellIndices.row} times to find the absolute row position\n for (let i = 0; i < relativeRowIndex; i++) {\n const cell = occupancyGrid[absoluteRow]?.[0];\n\n if (!cell) {\n return [];\n }\n\n // Skip the cells that the rowspan takes up\n absoluteRow += cell.rowspan;\n }\n\n // Then for each column, get the cell at the absolute row index as a relative cell index\n const cells = new Array(occupancyGrid[0].length)\n .fill(false)\n .map((_v, col) => {\n return getRelativeTableCells(\n { row: absoluteRow, col },\n block,\n occupancyGrid,\n );\n })\n .filter(\n (a): a is RelativeCellIndices & { cell: TableCell<any, any> } =>\n a !== undefined,\n );\n\n // Filter out duplicates based on row and col properties\n return cells.filter((cell, index) => {\n return (\n cells.findIndex((c) => c.row === cell.row && c.col === cell.col) === index\n );\n });\n}\n\n/**\n * This will get all the cells within a relative column of a table block.\n *\n * This method always starts the search for the column at the first row of the table.\n *\n * ```\n * // Visual representation of a table\n * | A | B |\n * | C | D | E |\n * | F | G | H |\n * // \"A\" has a colspan of 2\n *\n * // getCellsAtColumnHandle(0)\n * // returns [\n * { row: 0, col: 0, cell: \"A\" },\n * { row: 1, col: 0, cell: \"C\" },\n * { row: 2, col: 0, cell: \"F\" },\n * ]\n *\n * // getCellsAtColumnHandle(1)\n * // returns [\n * { row: 0, col: 1, cell: \"B\" },\n * { row: 1, col: 2, cell: \"E\" },\n * { row: 2, col: 2, cell: \"F\" },\n * ]\n * ```\n *\n * As you can see, you may not be able to retrieve all nodes given a relative column index, as cells can span multiple columns.\n *\n * @returns All of the cells associated with the relative column of the table. (All cells that have the same relative column index)\n */\nexport function getCellsAtColumnHandle(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n relativeColumnIndex: RelativeCellIndices[\"col\"],\n) {\n const occupancyGrid = getTableCellOccupancyGrid(block);\n\n if (\n relativeColumnIndex < 0 ||\n relativeColumnIndex >= occupancyGrid[0].length\n ) {\n return [];\n }\n\n // First need to resolve the relative column index to an absolute column index\n let absoluteCol = 0;\n\n // Now that we've already resolved the absolute row position, we can jump through the occupied cells ${relativeCellIndices.col} times to find the absolute column position\n for (let i = 0; i < relativeColumnIndex; i++) {\n const cell = occupancyGrid[0]?.[absoluteCol];\n\n if (!cell) {\n return [];\n }\n\n // Skip the cells that the colspan takes up\n absoluteCol += cell.colspan;\n }\n\n // Then for each row, get the cell at the absolute column index as a relative cell index\n const cells = new Array(occupancyGrid.length)\n .fill(false)\n .map((_v, row) => {\n return getRelativeTableCells(\n { row, col: absoluteCol },\n block,\n occupancyGrid,\n );\n })\n .filter(\n (a): a is RelativeCellIndices & { cell: TableCell<any, any> } =>\n a !== undefined,\n );\n\n // Filter out duplicates based on row and col properties\n return cells.filter((cell, index) => {\n return (\n cells.findIndex((c) => c.row === cell.row && c.col === cell.col) === index\n );\n });\n}\n\n/**\n * This moves a column from one index to another.\n *\n * @note This is a destructive operation, it will modify the provided {@link OccupancyGrid} in place.\n */\nexport function moveColumn(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n fromColIndex: RelativeCellIndices[\"col\"],\n toColIndex: RelativeCellIndices[\"col\"],\n occupancyGrid: OccupancyGrid = getTableCellOccupancyGrid(block),\n): TableContent<any, any>[\"rows\"] {\n // To move cells in a column, we need to layout the whole table\n // and then move the cells accordingly.\n const { col: absoluteSourceCol } = getAbsoluteTableCells(\n {\n row: 0,\n col: fromColIndex,\n },\n block,\n occupancyGrid,\n );\n const { col: absoluteTargetCol } = getAbsoluteTableCells(\n {\n row: 0,\n col: toColIndex,\n },\n block,\n occupancyGrid,\n );\n\n /**\n * Currently, this function assumes that the caller has already checked that the source and target columns are valid.\n * Such as by using {@link canColumnBeDraggedInto}. In the future, we may want to have the move logic be smarter\n * and handle invalid column indices in some way.\n */\n occupancyGrid.forEach((row) => {\n // Move the cell to the target column\n const [sourceCell] = row.splice(absoluteSourceCol, 1);\n row.splice(absoluteTargetCol, 0, sourceCell);\n });\n\n return getTableRowsFromOccupancyGrid(occupancyGrid);\n}\n\n/**\n * This moves a row from one index to another.\n *\n * @note This is a destructive operation, it will modify the {@link OccupancyGrid} in place.\n */\nexport function moveRow(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n fromRowIndex: RelativeCellIndices[\"row\"],\n toRowIndex: RelativeCellIndices[\"row\"],\n occupancyGrid: OccupancyGrid = getTableCellOccupancyGrid(block),\n): TableContent<any, any>[\"rows\"] {\n // To move cells in a column, we need to layout the whole table\n // and then move the cells accordingly.\n const { row: absoluteSourceRow } = getAbsoluteTableCells(\n {\n row: fromRowIndex,\n col: 0,\n },\n block,\n occupancyGrid,\n );\n const { row: absoluteTargetRow } = getAbsoluteTableCells(\n {\n row: toRowIndex,\n col: 0,\n },\n block,\n occupancyGrid,\n );\n\n /**\n * Currently, this function assumes that the caller has already checked that the source and target rows are valid.\n * Such as by using {@link canRowBeDraggedInto}. In the future, we may want to have the move logic be smarter\n * and handle invalid row indices in some way.\n */\n const [sourceRow] = occupancyGrid.splice(absoluteSourceRow, 1);\n occupancyGrid.splice(absoluteTargetRow, 0, sourceRow);\n\n return getTableRowsFromOccupancyGrid(occupancyGrid);\n}\n\n/**\n * This will check if a cell is empty.\n *\n * @returns True if the cell is empty, false otherwise.\n */\nfunction isCellEmpty(\n cell:\n | PartialTableContent<any, any>[\"rows\"][number][\"cells\"][number]\n | undefined,\n): boolean {\n if (!cell) {\n return true;\n }\n if (isPartialTableCell(cell)) {\n return isCellEmpty(cell.content);\n } else if (typeof cell === \"string\") {\n return cell.length === 0;\n } else if (Array.isArray(cell)) {\n return cell.every((c) =>\n typeof c === \"string\"\n ? c.length === 0\n : isStyledTextInlineContent(c)\n ? c.text.length === 0\n : isPartialLinkInlineContent(c)\n ? typeof c.content === \"string\"\n ? c.content.length === 0\n : c.content.every((s) => s.text.length === 0)\n : false,\n );\n } else {\n return false;\n }\n}\n\n/**\n * This will remove empty rows or columns from the table.\n *\n * @note This is a destructive operation, it will modify the {@link OccupancyGrid} in place.\n */\nexport function cropEmptyRowsOrColumns(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n removeEmpty: \"columns\" | \"rows\",\n occupancyGrid: OccupancyGrid = getTableCellOccupancyGrid(block),\n): TableContent<any, any>[\"rows\"] {\n if (removeEmpty === \"columns\") {\n // strips empty columns on the right\n let emptyColsOnRight = 0;\n for (\n let cellIndex = occupancyGrid[0].length - 1;\n cellIndex >= 0;\n cellIndex--\n ) {\n const isEmpty = occupancyGrid.every(\n (row) =>\n isCellEmpty(row[cellIndex].cell) && row[cellIndex].colspan === 1,\n );\n if (!isEmpty) {\n break;\n }\n\n emptyColsOnRight++;\n }\n\n for (let i = occupancyGrid.length - 1; i >= 0; i--) {\n // We maintain at least one cell, even if all the cells are empty\n const cellsToRemove = Math.max(\n occupancyGrid[i].length - emptyColsOnRight,\n 1,\n );\n occupancyGrid[i] = occupancyGrid[i].slice(0, cellsToRemove);\n }\n\n return getTableRowsFromOccupancyGrid(occupancyGrid);\n }\n\n // strips empty rows at the bottom\n let emptyRowsOnBottom = 0;\n for (let rowIndex = occupancyGrid.length - 1; rowIndex >= 0; rowIndex--) {\n const isEmpty = occupancyGrid[rowIndex].every(\n (cell) => isCellEmpty(cell.cell) && cell.rowspan === 1,\n );\n if (!isEmpty) {\n break;\n }\n\n emptyRowsOnBottom++;\n }\n\n // We maintain at least one row, even if all the rows are empty\n const rowsToRemove = Math.min(emptyRowsOnBottom, occupancyGrid.length - 1);\n\n occupancyGrid.splice(occupancyGrid.length - rowsToRemove, rowsToRemove);\n\n return getTableRowsFromOccupancyGrid(occupancyGrid);\n}\n\n/**\n * This will add a specified number of rows or columns to the table (filling with empty cells).\n *\n * @note This is a destructive operation, it will modify the {@link OccupancyGrid} in place.\n */\nexport function addRowsOrColumns(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n addType: \"columns\" | \"rows\",\n /**\n * The number of rows or columns to add.\n *\n * @note if negative, it will remove rows or columns.\n */\n numToAdd: number,\n occupancyGrid: OccupancyGrid = getTableCellOccupancyGrid(block),\n): TableContent<any, any>[\"rows\"] {\n const { width, height } = getDimensionsOfTable(block);\n\n if (addType === \"columns\") {\n // Add empty columns to the right\n occupancyGrid.forEach((row, rowIndex) => {\n if (numToAdd >= 0) {\n for (let i = 0; i < numToAdd; i++) {\n row.push({\n row: rowIndex,\n col: Math.max(...row.map((r) => r.col)) + 1,\n rowspan: 1,\n colspan: 1,\n cell: mapTableCell(\"\"),\n });\n }\n } else {\n // Remove columns on the right\n row.splice(width + numToAdd, -1 * numToAdd);\n }\n });\n } else {\n if (numToAdd > 0) {\n // Add empty rows to the bottom\n for (let i = 0; i < numToAdd; i++) {\n const newRow = new Array(width).fill(null).map((_, colIndex) => ({\n row: height + i,\n col: colIndex,\n rowspan: 1,\n colspan: 1,\n cell: mapTableCell(\"\"),\n }));\n occupancyGrid.push(newRow);\n }\n } else if (numToAdd < 0) {\n // Remove rows at the bottom\n occupancyGrid.splice(height + numToAdd, -1 * numToAdd);\n }\n }\n\n return getTableRowsFromOccupancyGrid(occupancyGrid);\n}\n\n/**\n * Checks if a row can be safely dropped at the target row index without splitting merged cells.\n */\nexport function canRowBeDraggedInto(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n draggingIndex: RelativeCellIndices[\"row\"],\n targetRowIndex: RelativeCellIndices[\"row\"],\n) {\n // Check cells at the target row\n const targetCells = getCellsAtRowHandle(block, targetRowIndex);\n\n // If no cells have rowspans > 1, dragging is always allowed\n const hasMergedCells = targetCells.some((cell) => getRowspan(cell.cell) > 1);\n if (!hasMergedCells) {\n return true;\n }\n\n let endRowIndex = targetRowIndex;\n let startRowIndex = targetRowIndex;\n targetCells.forEach((cell) => {\n const rowspan = getRowspan(cell.cell);\n endRowIndex = Math.max(endRowIndex, cell.row + rowspan - 1);\n startRowIndex = Math.min(startRowIndex, cell.row);\n });\n\n // Check the direction of the drag\n const isDraggingDown = draggingIndex < targetRowIndex;\n\n // Allow dragging only at the start/end of merged cells\n // Otherwise, the target row was within a merged cell which we don't allow\n return isDraggingDown\n ? targetRowIndex === endRowIndex\n : targetRowIndex === startRowIndex;\n}\n\n/**\n * Checks if a column can be safely dropped at the target column index without splitting merged cells.\n */\nexport function canColumnBeDraggedInto(\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n draggingIndex: RelativeCellIndices[\"col\"],\n targetColumnIndex: RelativeCellIndices[\"col\"],\n) {\n // Check cells at the target column\n const targetCells = getCellsAtColumnHandle(block, targetColumnIndex);\n\n // If no cells have colspans > 1, dragging is always allowed\n const hasMergedCells = targetCells.some((cell) => getColspan(cell.cell) > 1);\n if (!hasMergedCells) {\n return true;\n }\n\n let endColumnIndex = targetColumnIndex;\n let startColumnIndex = targetColumnIndex;\n targetCells.forEach((cell) => {\n const colspan = getColspan(cell.cell);\n endColumnIndex = Math.max(endColumnIndex, cell.col + colspan - 1);\n startColumnIndex = Math.min(startColumnIndex, cell.col);\n });\n\n // Check the direction of the drag\n const isDraggingRight = draggingIndex < targetColumnIndex;\n\n // Allow dragging only at the start/end of merged cells\n // Otherwise, the target column was within a merged cell which we don't allow\n return isDraggingRight\n ? targetColumnIndex === endColumnIndex\n : targetColumnIndex === startColumnIndex;\n}\n\n/**\n * Checks if two cells are in the same column.\n *\n * @returns True if the cells are in the same column, false otherwise.\n */\nexport function areInSameColumn(\n from: RelativeCellIndices,\n to: RelativeCellIndices,\n block: BlockFromConfigNoChildren<DefaultBlockSchema[\"table\"], any, any>,\n) {\n // Table indices are relative to the table, so we need to resolve the absolute cell indices\n const anchorAbsoluteCellIndices = getAbsoluteTableCells(from, block);\n\n // Table indices are relative to the table, so we need to resolve the absolute cell indices\n const headAbsoluteCellIndices = getAbsoluteTableCells(to, block);\n\n // Compare the column indices to determine the merge direction\n return anchorAbsoluteCellIndices.col === headAbsoluteCellIndices.col;\n}\n","import { Attrs, Fragment, Mark, Node, Schema } from \"@tiptap/pm/model\";\n\nimport UniqueID from \"../../extensions/UniqueID/UniqueID.js\";\nimport type {\n InlineContentSchema,\n PartialCustomInlineContentFromConfig,\n PartialInlineContent,\n PartialLink,\n PartialTableContent,\n StyleSchema,\n StyledText,\n} from \"../../schema\";\n\nimport type { PartialBlock } from \"../../blocks/defaultBlocks\";\nimport {\n isPartialLinkInlineContent,\n isStyledTextInlineContent,\n} from \"../../schema/inlineContent/types.js\";\nimport { getColspan, isPartialTableCell } from \"../../util/table.js\";\nimport { UnreachableCaseError } from \"../../util/typescript.js\";\nimport { getAbsoluteTableCells } from \"../blockManipulation/tables/tables.js\";\nimport { getStyleSchema } from \"../pmUtil.js\";\n\n/**\n * Convert a StyledText inline element to a\n * prosemirror text node with the appropriate marks\n */\nfunction styledTextToNodes<T extends StyleSchema>(\n styledText: StyledText<T>,\n schema: Schema,\n styleSchema: T,\n blockType?: string,\n): Node[] {\n const marks: Mark[] = [];\n\n for (const [style, value] of Object.entries(styledText.styles || {})) {\n const config = styleSchema[style];\n if (!config) {\n throw new Error(`style ${style} not found in styleSchema`);\n }\n\n if (config.propSchema === \"boolean\") {\n if (value) {\n marks.push(schema.mark(style));\n }\n } else if (config.propSchema === \"string\") {\n if (value) {\n marks.push(schema.mark(style, { stringValue: value }));\n }\n } else {\n throw new UnreachableCaseError(config.propSchema);\n }\n }\n\n const parseHardBreaks = !blockType || !schema.nodes[blockType].spec.code;\n\n if (!parseHardBreaks) {\n return styledText.text.length > 0\n ? [schema.text(styledText.text, marks)]\n : [];\n }\n\n return (\n styledText.text\n // Splits text & line breaks.\n .split(/(\\n)/g)\n // If the content ends with a line break, an empty string is added to the\n // end, which this removes.\n .filter((text) => text.length > 0)\n // Converts text & line breaks to nodes.\n .map((text) => {\n if (text === \"\\n\") {\n return schema.nodes[\"hardBreak\"].createChecked();\n } else {\n return schema.text(text, marks);\n }\n })\n );\n}\n\n/**\n * Converts a Link inline content element to\n * prosemirror text nodes with the appropriate marks\n */\nfunction linkToNodes(\n link: PartialLink<StyleSchema>,\n schema: Schema,\n styleSchema: StyleSchema,\n): Node[] {\n const linkMark = schema.marks.link.create({\n href: link.href,\n });\n\n return styledTextArrayToNodes(link.content, schema, styleSchema).map(\n (node) => {\n if (node.type.name === \"text\") {\n return node.mark([...node.marks, linkMark]);\n }\n\n if (node.type.name === \"hardBreak\") {\n return node;\n }\n throw new Error(\"unexpected node type\");\n },\n );\n}\n\n/**\n * Converts an array of StyledText inline content elements to\n * prosemirror text nodes with the appropriate marks\n */\nfunction styledTextArrayToNodes<S extends StyleSchema>(\n content: string | StyledText<S>[],\n schema: Schema,\n styleSchema: S,\n blockType?: string,\n): Node[] {\n const nodes: Node[] = [];\n\n if (typeof content === \"string\") {\n nodes.push(\n ...styledTextToNodes(\n { type: \"text\", text: content, styles: {} },\n schema,\n styleSchema,\n blockType,\n ),\n );\n return nodes;\n }\n\n for (const styledText of content) {\n nodes.push(\n ...styledTextToNodes(styledText, schema, styleSchema, blockType),\n );\n }\n return nodes;\n}\n\n/**\n * converts an array of inline content elements to prosemirror nodes\n */\nexport function inlineContentToNodes<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n blockContent: PartialInlineContent<I, S>,\n schema: Schema,\n blockType?: string,\n styleSchema: S = getStyleSchema(schema),\n): Node[] {\n const nodes: Node[] = [];\n\n for (const content of blockContent) {\n if (typeof content === \"string\") {\n nodes.push(\n ...styledTextArrayToNodes(content, schema, styleSchema, blockType),\n );\n } else if (isPartialLinkInlineContent(content)) {\n nodes.push(...linkToNodes(content, schema, styleSchema));\n } else if (isStyledTextInlineContent(content)) {\n nodes.push(\n ...styledTextArrayToNodes([content], schema, styleSchema, blockType),\n );\n } else {\n nodes.push(\n blockOrInlineContentToContentNode(content, schema, styleSchema),\n );\n }\n }\n return nodes;\n}\n\n/**\n * converts an array of inline content elements to prosemirror nodes\n */\nexport function tableContentToNodes<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n tableContent: PartialTableContent<I, S>,\n schema: Schema,\n styleSchema: StyleSchema = getStyleSchema(schema),\n): Node[] {\n const rowNodes: Node[] = [];\n // Header rows and columns are used to determine the type of the cell\n // If headerRows is 1, then the first row is a header row\n const headerRows = new Array(tableContent.headerRows ?? 0).fill(true);\n // If headerCols is 1, then the first column is a header column\n const headerCols = new Array(tableContent.headerCols ?? 0).fill(true);\n\n const columnWidths: (number | undefined)[] = tableContent.columnWidths ?? [];\n\n for (let rowIndex = 0; rowIndex < tableContent.rows.length; rowIndex++) {\n const row = tableContent.rows[rowIndex];\n const columnNodes: Node[] = [];\n const isHeaderRow = headerRows[rowIndex];\n for (let cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {\n const cell = row.cells[cellIndex];\n const isHeaderCol = headerCols[cellIndex];\n /**\n * The attributes of the cell to apply to the node\n */\n const attrs: Attrs | undefined = undefined;\n /**\n * The content of the cell to apply to the node\n */\n let content: Fragment | Node | readonly Node[] | null = null;\n\n // Colwidths are absolutely referenced to the table, so we need to resolve the relative cell index to the absolute cell index\n const absoluteCellIndex = getAbsoluteTableCells(\n {\n row: rowIndex,\n col: cellIndex,\n },\n { type: \"table\", content: tableContent } as any,\n );\n\n // Assume the column width is the width of the cell at the absolute cell index\n let colwidth: (number | undefined)[] | null = columnWidths[\n absoluteCellIndex.col\n ]\n ? [columnWidths[absoluteCellIndex.col]]\n : null;\n\n if (!cell) {\n // No-op\n } else if (typeof cell === \"string\") {\n content = schema.text(cell);\n } else if (isPartialTableCell(cell)) {\n if (cell.content) {\n content = inlineContentToNodes(\n cell.content,\n schema,\n \"tableParagraph\",\n styleSchema,\n );\n }\n const colspan = getColspan(cell);\n\n if (colspan > 1) {\n // If the cell has a > 1 colspan, we need to get the column width for each cell in the span\n colwidth = new Array(colspan).fill(false).map((_, i) => {\n // Starting from the absolute column index, get the column width for each cell in the span\n return columnWidths[absoluteCellIndex.col + i] ?? undefined;\n });\n }\n } else {\n content = inlineContentToNodes(\n cell,\n schema,\n \"tableParagraph\",\n styleSchema,\n );\n }\n\n const cellNode = schema.nodes[\n isHeaderCol || isHeaderRow ? \"tableHeader\" : \"tableCell\"\n ].createChecked(\n {\n ...(isPartialTableCell(cell) ? cell.props : {}),\n colwidth,\n },\n schema.nodes[\"tableParagraph\"].createChecked(attrs, content),\n );\n columnNodes.push(cellNode);\n }\n\n const rowNode = schema.nodes[\"tableRow\"].createChecked({}, columnNodes);\n rowNodes.push(rowNode);\n }\n return rowNodes;\n}\n\nfunction blockOrInlineContentToContentNode(\n block:\n | PartialBlock<any, any, any>\n | PartialCustomInlineContentFromConfig<any, any>,\n schema: Schema,\n styleSchema: StyleSchema,\n) {\n let contentNode: Node;\n let type = block.type;\n\n // TODO: needed? came from previous code\n if (type === undefined) {\n type = \"paragraph\";\n }\n\n if (!schema.nodes[type]) {\n throw new Error(`node type ${type} not found in schema`);\n }\n\n if (!block.content) {\n contentNode = schema.nodes[type].createChecked(block.props);\n } else if (typeof block.content === \"string\") {\n const nodes = inlineContentToNodes(\n [block.content],\n schema,\n type,\n styleSchema,\n );\n contentNode = schema.nodes[type].createChecked(block.props, nodes);\n } else if (Array.isArray(block.content)) {\n const nodes = inlineContentToNodes(\n block.content,\n schema,\n type,\n styleSchema,\n );\n contentNode = schema.nodes[type].createChecked(block.props, nodes);\n } else if (block.content.type === \"tableContent\") {\n const nodes = tableContentToNodes(block.content, schema, styleSchema);\n contentNode = schema.nodes[type].createChecked(block.props, nodes);\n } else {\n throw new UnreachableCaseError(block.content.type);\n }\n return contentNode;\n}\n\n/**\n * Converts a BlockNote block to a Prosemirror node.\n */\nexport function blockToNode(\n block: PartialBlock<any, any, any>,\n schema: Schema,\n styleSchema: StyleSchema = getStyleSchema(schema),\n) {\n let id = block.id;\n\n if (id === undefined) {\n id = UniqueID.options.generateID();\n }\n\n const children: Node[] = [];\n\n if (block.children) {\n for (const child of block.children) {\n children.push(blockToNode(child, schema, styleSchema));\n }\n }\n\n const isBlockContent =\n !block.type || // can happen if block.type is not defined (this should create the default node)\n schema.nodes[block.type].isInGroup(\"blockContent\");\n\n if (isBlockContent) {\n // Blocks with a type that matches \"blockContent\" group always need to be wrapped in a blockContainer\n\n const contentNode = blockOrInlineContentToContentNode(\n block,\n schema,\n styleSchema,\n );\n\n const groupNode =\n children.length > 0\n ? schema.nodes[\"blockGroup\"].createChecked({}, children)\n : undefined;\n\n return schema.nodes[\"blockContainer\"].createChecked(\n {\n id: id,\n ...block.props,\n },\n groupNode ? [contentNode, groupNode] : contentNode,\n );\n } else if (schema.nodes[block.type].isInGroup(\"bnBlock\")) {\n // this is a bnBlock node like Column or ColumnList that directly translates to a prosemirror node\n return schema.nodes[block.type].createChecked(\n {\n id: id,\n ...block.props,\n },\n children,\n );\n } else {\n throw new Error(\n `block type ${block.type} doesn't match blockContent or bnBlock group`,\n );\n }\n}\n","import type { Node } from \"prosemirror-model\";\n\n/**\n * Get a TipTap node by id\n */\nexport function getNodeById(\n id: string,\n doc: Node,\n): { node: Node; posBeforeNode: number } | undefined {\n let targetNode: Node | undefined = undefined;\n let posBeforeNode: number | undefined = undefined;\n\n doc.firstChild!.descendants((node, pos) => {\n // Skips traversing nodes after node with target ID has been found.\n if (targetNode) {\n return false;\n }\n\n // Keeps traversing nodes if block with target ID has not been found.\n if (!isNodeBlock(node) || node.attrs.id !== id) {\n return true;\n }\n\n targetNode = node;\n posBeforeNode = pos + 1;\n\n return false;\n });\n\n if (targetNode === undefined || posBeforeNode === undefined) {\n return undefined;\n }\n\n return {\n node: targetNode,\n posBeforeNode: posBeforeNode,\n };\n}\n\nexport function isNodeBlock(node: Node): boolean {\n return node.type.isInGroup(\"bnBlock\");\n}\n","import {\n Fragment,\n type NodeType,\n type Node as PMNode,\n Slice,\n} from \"prosemirror-model\";\nimport { TextSelection, Transaction } from \"prosemirror-state\";\nimport { TableMap } from \"prosemirror-tables\";\nimport { ReplaceStep, Transform } from \"prosemirror-transform\";\n\nimport type { Block, PartialBlock } from \"../../../../blocks/defaultBlocks.js\";\nimport type {\n BlockIdentifier,\n BlockSchema,\n} from \"../../../../schema/blocks/types.js\";\nimport type { InlineContentSchema } from \"../../../../schema/inlineContent/types.js\";\nimport type { StyleSchema } from \"../../../../schema/styles/types.js\";\nimport { UnreachableCaseError } from \"../../../../util/typescript.js\";\nimport {\n type BlockInfo,\n getBlockInfoFromResolvedPos,\n} from \"../../../getBlockInfoFromPos.js\";\nimport {\n blockToNode,\n inlineContentToNodes,\n tableContentToNodes,\n} from \"../../../nodeConversions/blockToNode.js\";\nimport { nodeToBlock } from \"../../../nodeConversions/nodeToBlock.js\";\nimport { getNodeById } from \"../../../nodeUtil.js\";\nimport { getPmSchema } from \"../../../pmUtil.js\";\n\n// for compatibility with tiptap. TODO: remove as we want to remove dependency on tiptap command interface\nexport const updateBlockCommand = <\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n posBeforeBlock: number,\n block: PartialBlock<BSchema, I, S>,\n) => {\n return ({\n tr,\n dispatch,\n }: {\n tr: Transaction;\n dispatch?: () => void;\n }): boolean => {\n if (dispatch) {\n updateBlockTr(tr, posBeforeBlock, block);\n }\n return true;\n };\n};\n\nexport function updateBlockTr<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n tr: Transform | Transaction,\n posBeforeBlock: number,\n block: PartialBlock<BSchema, I, S>,\n replaceFromPos?: number,\n replaceToPos?: number,\n) {\n const blockInfo = getBlockInfoFromResolvedPos(tr.doc.resolve(posBeforeBlock));\n\n let cellAnchor: CellAnchor | null = null;\n if (blockInfo.blockNoteType === \"table\") {\n cellAnchor = captureCellAnchor(tr);\n }\n\n const pmSchema = getPmSchema(tr);\n\n if (\n replaceFromPos !== undefined &&\n replaceToPos !== undefined &&\n replaceFromPos > replaceToPos\n ) {\n throw new Error(\"Invalid replaceFromPos or replaceToPos\");\n }\n\n // Adds blockGroup node with child blocks if necessary.\n\n const oldNodeType = pmSchema.nodes[blockInfo.blockNoteType];\n const newNodeType = pmSchema.nodes[block.type || blockInfo.blockNoteType];\n const newBnBlockNodeType = newNodeType.isInGroup(\"bnBlock\")\n ? newNodeType\n : pmSchema.nodes[\"blockContainer\"];\n\n if (blockInfo.isBlockContainer && newNodeType.isInGroup(\"blockContent\")) {\n const replaceFromOffset =\n replaceFromPos !== undefined &&\n replaceFromPos > blockInfo.blockContent.beforePos &&\n replaceFromPos < blockInfo.blockContent.afterPos\n ? replaceFromPos - blockInfo.blockContent.beforePos - 1\n : undefined;\n\n const replaceToOffset =\n replaceToPos !== undefined &&\n replaceToPos > blockInfo.blockContent.beforePos &&\n replaceToPos < blockInfo.blockContent.afterPos\n ? replaceToPos - blockInfo.blockContent.beforePos - 1\n : undefined;\n\n updateChildren(block, tr, blockInfo);\n // The code below determines the new content of the block.\n // or \"keep\" to keep as-is\n updateBlockContentNode(\n block,\n tr,\n oldNodeType,\n newNodeType,\n blockInfo,\n replaceFromOffset,\n replaceToOffset,\n );\n } else if (!blockInfo.isBlockContainer && newNodeType.isInGroup(\"bnBlock\")) {\n updateChildren(block, tr, blockInfo);\n // old node was a bnBlock type (like column or columnList) and new block as well\n // No op, we just update the bnBlock below (at end of function) and have already updated the children\n } else {\n // switching from blockContainer to non-blockContainer or v.v.\n // currently breaking for column slash menu items converting empty block\n // to column.\n\n // currently, we calculate the new node and replace the entire node with the desired new node.\n // for this, we do a nodeToBlock on the existing block to get the children.\n // it would be cleaner to use a ReplaceAroundStep, but this is a bit simpler and it's quite an edge case\n const existingBlock = nodeToBlock(blockInfo.bnBlock.node, pmSchema);\n tr.replaceWith(\n blockInfo.bnBlock.beforePos,\n blockInfo.bnBlock.afterPos,\n blockToNode(\n {\n children: existingBlock.children, // if no children are passed in, use existing children\n ...block,\n },\n pmSchema,\n ),\n );\n\n return;\n }\n\n // Adds all provided props as attributes to the parent blockContainer node too, and also preserves existing\n // attributes.\n tr.setNodeMarkup(blockInfo.bnBlock.beforePos, newBnBlockNodeType, {\n ...blockInfo.bnBlock.node.attrs,\n ...block.props,\n });\n\n if (cellAnchor) {\n restoreCellAnchor(tr, blockInfo, cellAnchor);\n }\n}\n\nfunction updateBlockContentNode<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n block: PartialBlock<BSchema, I, S>,\n tr: Transform,\n oldNodeType: NodeType,\n newNodeType: NodeType,\n blockInfo: {\n childContainer?:\n | { node: PMNode; beforePos: number; afterPos: number }\n | undefined;\n blockContent: { node: PMNode; beforePos: number; afterPos: number };\n },\n replaceFromOffset?: number,\n replaceToOffset?: number,\n) {\n const pmSchema = getPmSchema(tr);\n let content: PMNode[] | \"keep\" = \"keep\";\n\n // Has there been any custom content provided?\n if (block.content) {\n if (typeof block.content === \"string\") {\n // Adds a single text node with no marks to the content.\n content = inlineContentToNodes(\n [block.content],\n pmSchema,\n newNodeType.name,\n );\n } else if (Array.isArray(block.content)) {\n // Adds a text node with the provided styles converted into marks to the content,\n // for each InlineContent object.\n content = inlineContentToNodes(block.content, pmSchema, newNodeType.name);\n } else if (block.content.type === \"tableContent\") {\n content = tableContentToNodes(block.content, pmSchema);\n } else {\n throw new UnreachableCaseError(block.content.type);\n }\n } else {\n // no custom content has been provided, use existing content IF possible\n // Since some block types contain inline content and others don't,\n // we either need to call setNodeMarkup to just update type &\n // attributes, or replaceWith to replace the whole blockContent.\n if (oldNodeType.spec.content === \"\") {\n // keep old content, because it's empty anyway and should be compatible with\n // any newContentType\n } else if (newNodeType.spec.content !== oldNodeType.spec.content) {\n // the content type changed, replace the previous content\n content = [];\n } else {\n // keep old content, because the content type is the same and should be compatible\n }\n }\n\n // Now, changes the blockContent node type and adds the provided props\n // as attributes. Also preserves all existing attributes that are\n // compatible with the new type.\n //\n // Use either setNodeMarkup or replaceWith depending on whether the\n // content is being replaced or not.\n if (content === \"keep\") {\n // use setNodeMarkup to only update the type and attributes\n tr.setNodeMarkup(blockInfo.blockContent.beforePos, newNodeType, {\n ...blockInfo.blockContent.node.attrs,\n ...block.props,\n });\n } else if (replaceFromOffset !== undefined || replaceToOffset !== undefined) {\n // first update markup of the containing node\n tr.setNodeMarkup(blockInfo.blockContent.beforePos, newNodeType, {\n ...blockInfo.blockContent.node.attrs,\n ...block.props,\n });\n\n const start =\n blockInfo.blockContent.beforePos + 1 + (replaceFromOffset ?? 0);\n const end =\n blockInfo.blockContent.beforePos +\n 1 +\n (replaceToOffset ?? blockInfo.blockContent.node.content.size);\n\n // for content like table cells (where the blockcontent has nested PM nodes),\n // we need to figure out the correct openStart and openEnd for the slice when replacing\n\n const contentDepth = tr.doc.resolve(blockInfo.blockContent.beforePos).depth;\n const startDepth = tr.doc.resolve(start).depth;\n const endDepth = tr.doc.resolve(end).depth;\n\n tr.replace(\n start,\n end,\n new Slice(\n Fragment.from(content),\n startDepth - contentDepth - 1,\n endDepth - contentDepth - 1,\n ),\n );\n } else {\n // use replaceWith to replace the content and the block itself\n // also reset the selection since replacing the block content\n // sets it to the next block.\n tr.replaceWith(\n blockInfo.blockContent.beforePos,\n blockInfo.blockContent.afterPos,\n newNodeType.createChecked(\n {\n ...blockInfo.blockContent.node.attrs,\n ...block.props,\n },\n content,\n ),\n );\n }\n}\n\nfunction updateChildren<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(block: PartialBlock<BSchema, I, S>, tr: Transform, blockInfo: BlockInfo) {\n const pmSchema = getPmSchema(tr);\n if (block.children !== undefined && block.children.length > 0) {\n const childNodes = block.children.map((child) => {\n return blockToNode(child, pmSchema);\n });\n\n // Checks if a blockGroup node already exists.\n if (blockInfo.childContainer) {\n // Replaces all child nodes in the existing blockGroup with the ones created earlier.\n\n // use a replacestep to avoid the fitting algorithm\n tr.step(\n new ReplaceStep(\n blockInfo.childContainer.beforePos + 1,\n blockInfo.childContainer.afterPos - 1,\n new Slice(Fragment.from(childNodes), 0, 0),\n ),\n );\n } else {\n if (!blockInfo.isBlockContainer) {\n throw new Error(\"impossible\");\n }\n // Inserts a new blockGroup containing the child nodes created earlier.\n tr.insert(\n blockInfo.blockContent.afterPos,\n pmSchema.nodes[\"blockGroup\"].createChecked({}, childNodes),\n );\n }\n }\n}\n\nexport function updateBlock<\n BSchema extends BlockSchema = any,\n I extends InlineContentSchema = any,\n S extends StyleSchema = any,\n>(\n tr: Transform,\n blockToUpdate: BlockIdentifier,\n update: PartialBlock<BSchema, I, S>,\n replaceFromPos?: number,\n replaceToPos?: number,\n): Block<BSchema, I, S> {\n const id =\n typeof blockToUpdate === \"string\" ? blockToUpdate : blockToUpdate.id;\n const posInfo = getNodeById(id, tr.doc);\n if (!posInfo) {\n throw new Error(`Block with ID ${id} not found`);\n }\n\n updateBlockTr(\n tr,\n posInfo.posBeforeNode,\n update,\n replaceFromPos,\n replaceToPos,\n );\n\n const blockContainerNode = tr.doc\n .resolve(posInfo.posBeforeNode + 1) // TODO: clean?\n .node();\n\n const pmSchema = getPmSchema(tr);\n return nodeToBlock(blockContainerNode, pmSchema);\n}\n\ntype CellAnchor = { row: number; col: number; offset: number };\n\n/**\n * Captures the cell anchor from the current selection.\n * @param tr - The transaction to capture the cell anchor from.\n *\n * @returns The cell anchor, or null if no cell is selected.\n */\nexport function captureCellAnchor(tr: Transform): CellAnchor | null {\n const sel = \"selection\" in tr ? tr.selection : null;\n if (!(sel instanceof TextSelection)) {\n return null;\n }\n\n const $head = tr.doc.resolve(sel.head);\n // Find enclosing cell and table\n let cellDepth = -1;\n let tableDepth = -1;\n for (let d = $head.depth; d >= 0; d--) {\n const name = $head.node(d).type.name;\n if (cellDepth < 0 && (name === \"tableCell\" || name === \"tableHeader\")) {\n cellDepth = d;\n }\n if (name === \"table\") {\n tableDepth = d;\n break;\n }\n }\n if (cellDepth < 0 || tableDepth < 0) {\n return null;\n }\n\n // Absolute positions (before the cell)\n const cellPos = $head.before(cellDepth);\n const tablePos = $head.before(tableDepth);\n const table = tr.doc.nodeAt(tablePos);\n if (!table || table.type.name !== \"table\") {\n return null;\n }\n\n // Visual grid position via TableMap (handles spans)\n const map = TableMap.get(table);\n const rel = cellPos - (tablePos + 1); // relative to inside table\n const idx = map.map.indexOf(rel);\n if (idx < 0) {\n return null;\n }\n\n const row = Math.floor(idx / map.width);\n const col = idx % map.width;\n\n // Caret offset relative to the start of paragraph text\n const paraPos = cellPos + 1; // pos BEFORE tableParagraph\n const textStart = paraPos + 1; // start of paragraph text\n const offset = Math.max(0, sel.head - textStart);\n\n return { row, col, offset };\n}\n\nfunction restoreCellAnchor(\n tr: Transform | Transaction,\n blockInfo: BlockInfo,\n a: CellAnchor,\n): boolean {\n if (blockInfo.blockNoteType !== \"table\") {\n return false;\n }\n\n // 1) Resolve the table node in the current document\n let tablePos = -1;\n\n if (blockInfo.isBlockContainer) {\n // Prefer the blockContent position when available (points directly at the PM table node)\n tablePos = tr.mapping.map(blockInfo.blockContent.beforePos);\n } else {\n // Fallback: scan within the mapped bnBlock range to find the inner table node\n const start = tr.mapping.map(blockInfo.bnBlock.beforePos);\n const end = start + (tr.doc.nodeAt(start)?.nodeSize || 0);\n tr.doc.nodesBetween(start, end, (node, pos) => {\n if (node.type.name === \"table\") {\n tablePos = pos;\n return false;\n }\n return true;\n });\n }\n\n const table = tablePos >= 0 ? tr.doc.nodeAt(tablePos) : null;\n if (!table || table.type.name !== \"table\") {\n return false;\n }\n\n // 2) Clamp row/col to the table’s current grid\n const map = TableMap.get(table);\n const row = Math.max(0, Math.min(a.row, map.height - 1));\n const col = Math.max(0, Math.min(a.col, map.width - 1));\n\n // 3) Compute the absolute position of the target cell (pos BEFORE the cell)\n const cellIndex = row * map.width + col;\n const relCellPos = map.map[cellIndex]; // relative to (tablePos + 1)\n if (relCellPos == null) {\n return false;\n }\n const cellPos = tablePos + 1 + relCellPos;\n\n // 4) Place the caret inside the cell, clamping the text offset\n const textPos = cellPos + 1;\n const textNode = tr.doc.nodeAt(textPos);\n const textStart = textPos + 1;\n const max = textNode ? textNode.content.size : 0;\n const head = textStart + Math.max(0, Math.min(a.offset, max));\n\n if (\"selection\" in tr) {\n tr.setSelection(TextSelection.create(tr.doc, head));\n }\n return true;\n}\n","export const COLORS_DEFAULT = {\n gray: {\n text: \"#9b9a97\",\n background: \"#ebeced\",\n },\n brown: {\n text: \"#64473a\",\n background: \"#e9e5e3\",\n },\n red: {\n text: \"#e03e3e\",\n background: \"#fbe4e4\",\n },\n orange: {\n text: \"#d9730d\",\n background: \"#f6e9d9\",\n },\n yellow: {\n text: \"#dfab01\",\n background: \"#fbf3db\",\n },\n green: {\n text: \"#4d6461\",\n background: \"#ddedea\",\n },\n blue: {\n text: \"#0b6e99\",\n background: \"#ddebf1\",\n },\n purple: {\n text: \"#6940a5\",\n background: \"#eae4f2\",\n },\n pink: {\n text: \"#ad1a72\",\n background: \"#f4dfeb\",\n },\n} as Record<string, { text: string; background: string }>;\n\nexport const COLORS_DARK_MODE_DEFAULT = {\n gray: {\n text: \"#bebdb8\",\n background: \"#9b9a97\",\n },\n brown: {\n text: \"#8e6552\",\n background: \"#64473a\",\n },\n red: {\n text: \"#ec4040\",\n background: \"#be3434\",\n },\n orange: {\n text: \"#e3790d\",\n background: \"#b7600a\",\n },\n yellow: {\n text: \"#dfab01\",\n background: \"#b58b00\",\n },\n green: {\n text: \"#6b8b87\",\n background: \"#4d6461\",\n },\n blue: {\n text: \"#0e87bc\",\n background: \"#0b6e99\",\n },\n purple: {\n text: \"#8552d7\",\n background: \"#6940a5\",\n },\n pink: {\n text: \"#da208f\",\n background: \"#ad1a72\",\n },\n} as Record<string, { text: string; background: string }>;\n","import { Attribute } from \"@tiptap/core\";\n\nimport { COLORS_DEFAULT } from \"../editor/defaultColors.js\";\nimport type { Props, PropSchema } from \"../schema/index.js\";\n\n// TODO: this system should probably be moved / refactored.\n// The dependency from schema on this file doesn't make sense\n\nexport const defaultProps = {\n backgroundColor: {\n default: \"default\" as const,\n },\n textColor: {\n default: \"default\" as const,\n },\n textAlignment: {\n default: \"left\" as const,\n values: [\"left\", \"center\", \"right\", \"justify\"] as const,\n },\n} satisfies PropSchema;\n\nexport type DefaultProps = Props<typeof defaultProps>;\n\nexport const parseDefaultProps = (element: HTMLElement) => {\n const props: Partial<DefaultProps> = {};\n\n // If the `data-` attribute is found, set the prop to the value, as this most\n // likely means the parsed element was exported by BlockNote originally.\n // Otherwise, just use whatever is found in the inline styles, if anything.\n if (element.hasAttribute(\"data-background-color\")) {\n props.backgroundColor = element.getAttribute(\"data-background-color\")!;\n } else if (element.style.backgroundColor) {\n props.backgroundColor = element.style.backgroundColor;\n }\n\n // If the `data-` attribute is found, set the prop to the value, as this most\n // likely means the parsed element was exported by BlockNote originally.\n // Otherwise, just use whatever is found in the inline styles, if anything.\n if (element.hasAttribute(\"data-text-color\")) {\n props.textColor = element.getAttribute(\"data-text-color\")!;\n } else if (element.style.color) {\n props.textColor = element.style.color;\n }\n\n props.textAlignment = defaultProps.textAlignment.values.includes(\n element.style.textAlign as DefaultProps[\"textAlignment\"],\n )\n ? (element.style.textAlign as DefaultProps[\"textAlignment\"])\n : undefined;\n\n return props;\n};\n\nexport const addDefaultPropsExternalHTML = (\n props: Partial<DefaultProps>,\n element: HTMLElement,\n) => {\n if (\n props.backgroundColor &&\n props.backgroundColor !== defaultProps.backgroundColor.default\n ) {\n // The color can be any string. If the string matches one of the default\n // theme color names, set the theme color. Otherwise, set the color as-is\n // (may be a CSS color name, hex value, RGB value, etc).\n element.style.backgroundColor =\n props.backgroundColor in COLORS_DEFAULT\n ? COLORS_DEFAULT[props.backgroundColor].background\n : props.backgroundColor;\n }\n\n if (props.textColor && props.textColor !== defaultProps.textColor.default) {\n // The color can be any string. If the string matches one of the default\n // theme color names, set the theme color. Otherwise, set the color as-is\n // (may be a CSS color name, hex value, RGB value, etc).\n element.style.color =\n props.textColor in COLORS_DEFAULT\n ? COLORS_DEFAULT[props.textColor].text\n : props.textColor;\n }\n\n if (\n props.textAlignment &&\n props.textAlignment !== defaultProps.textAlignment.default\n ) {\n element.style.textAlign = props.textAlignment;\n }\n};\n\nexport const getBackgroundColorAttribute = (\n attributeName = \"backgroundColor\",\n): Attribute => ({\n default: defaultProps.backgroundColor.default,\n parseHTML: (element) => {\n if (element.hasAttribute(\"data-background-color\")) {\n return element.getAttribute(\"data-background-color\")!;\n }\n\n if (element.style.backgroundColor) {\n return element.style.backgroundColor;\n }\n\n return defaultProps.backgroundColor.default;\n },\n renderHTML: (attributes) => {\n if (attributes[attributeName] === defaultProps.backgroundColor.default) {\n return {};\n }\n\n return {\n \"data-background-color\": attributes[attributeName],\n };\n },\n});\n\nexport const getTextColorAttribute = (\n attributeName = \"textColor\",\n): Attribute => ({\n default: defaultProps.textColor.default,\n parseHTML: (element) => {\n if (element.hasAttribute(\"data-text-color\")) {\n return element.getAttribute(\"data-text-color\")!;\n }\n\n if (element.style.color) {\n return element.style.color;\n }\n\n return defaultProps.textColor.default;\n },\n renderHTML: (attributes) => {\n if (attributes[attributeName] === defaultProps.textColor.default) {\n return {};\n }\n\n return {\n \"data-text-color\": attributes[attributeName],\n };\n },\n});\n\nexport const getTextAlignmentAttribute = (\n attributeName = \"textAlignment\",\n): Attribute => ({\n default: defaultProps.textAlignment.default,\n parseHTML: (element) => {\n if (element.hasAttribute(\"data-text-alignment\")) {\n return element.getAttribute(\"data-text-alignment\");\n }\n\n if (element.style.textAlign) {\n return element.style.textAlign;\n }\n\n return defaultProps.textAlignment.default;\n },\n renderHTML: (attributes) => {\n if (attributes[attributeName] === defaultProps.textAlignment.default) {\n return {};\n }\n\n return {\n \"data-text-alignment\": attributes[attributeName],\n };\n },\n});\n","export const parseFigureElement = (\n figureElement: HTMLElement,\n targetTag: string,\n) => {\n const targetElement = figureElement.querySelector(\n targetTag,\n ) as HTMLElement | null;\n if (!targetElement) {\n return undefined;\n }\n\n const captionElement = figureElement.querySelector(\"figcaption\");\n const caption = captionElement?.textContent ?? undefined;\n\n return { targetElement, caption };\n};\n","import type { BlockNoteEditor } from \"../../../../editor/BlockNoteEditor.js\";\nimport {\n BlockConfig,\n BlockFromConfigNoChildren,\n} from \"../../../../schema/index.js\";\n\nexport const createAddFileButton = (\n block: BlockFromConfigNoChildren<BlockConfig<string, any, \"none\">, any, any>,\n editor: BlockNoteEditor<any, any, any>,\n buttonIcon?: HTMLElement,\n) => {\n const addFileButton = document.createElement(\"div\");\n addFileButton.className = \"bn-add-file-button\";\n\n const addFileButtonIcon = document.createElement(\"div\");\n addFileButtonIcon.className = \"bn-add-file-button-icon\";\n if (buttonIcon) {\n addFileButtonIcon.appendChild(buttonIcon);\n } else {\n addFileButtonIcon.innerHTML =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z\"></path></svg>';\n }\n addFileButton.appendChild(addFileButtonIcon);\n\n const addFileButtonText = document.createElement(\"p\");\n addFileButtonText.className = \"bn-add-file-button-text\";\n addFileButtonText.innerHTML =\n block.type in editor.dictionary.file_blocks.add_button_text\n ? editor.dictionary.file_blocks.add_button_text[block.type]\n : editor.dictionary.file_blocks.add_button_text[\"file\"];\n addFileButton.appendChild(addFileButtonText);\n\n // Prevents focus from moving to the button.\n const addFileButtonMouseDownHandler = (event: MouseEvent) => {\n event.preventDefault();\n };\n // Opens the file toolbar.\n const addFileButtonClickHandler = () => {\n editor.transact((tr) =>\n tr.setMeta(editor.filePanel!.plugins[0], {\n block: block,\n }),\n );\n };\n addFileButton.addEventListener(\n \"mousedown\",\n addFileButtonMouseDownHandler,\n true,\n );\n addFileButton.addEventListener(\"click\", addFileButtonClickHandler, true);\n\n return {\n dom: addFileButton,\n destroy: () => {\n addFileButton.removeEventListener(\n \"mousedown\",\n addFileButtonMouseDownHandler,\n true,\n );\n addFileButton.removeEventListener(\n \"click\",\n addFileButtonClickHandler,\n true,\n );\n },\n };\n};\n","import {\n BlockConfig,\n BlockFromConfigNoChildren,\n} from \"../../../../schema/index.js\";\n\nexport const FILE_ICON_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M3 8L9.00319 2H19.9978C20.5513 2 21 2.45531 21 2.9918V21.0082C21 21.556 20.5551 22 20.0066 22H3.9934C3.44476 22 3 21.5501 3 20.9932V8ZM10 4V9H5V20H19V4H10Z\"></path></svg>`;\n\nexport const createFileNameWithIcon = (\n block: BlockFromConfigNoChildren<\n BlockConfig<\n string,\n {\n name: { default: \"\" };\n },\n \"none\"\n >,\n any,\n any\n >,\n): { dom: HTMLElement; destroy?: () => void } => {\n const file = document.createElement(\"div\");\n file.className = \"bn-file-name-with-icon\";\n\n const icon = document.createElement(\"div\");\n icon.className = \"bn-file-icon\";\n icon.innerHTML = FILE_ICON_SVG;\n file.appendChild(icon);\n\n const fileName = document.createElement(\"p\");\n fileName.className = \"bn-file-name\";\n fileName.textContent = block.props.name;\n file.appendChild(fileName);\n\n return {\n dom: file,\n };\n};\n","import type { BlockNoteEditor } from \"../../../../editor/BlockNoteEditor.js\";\nimport {\n BlockConfig,\n BlockFromConfigNoChildren,\n} from \"../../../../schema/index.js\";\nimport { createAddFileButton } from \"./createAddFileButton.js\";\nimport { createFileNameWithIcon } from \"./createFileNameWithIcon.js\";\n\nexport const createFileBlockWrapper = (\n block: BlockFromConfigNoChildren<\n BlockConfig<\n string,\n {\n backgroundColor: { default: \"default\" };\n name: { default: \"\" };\n url: { default: \"\" };\n caption: { default: \"\" };\n showPreview?: { default: true };\n },\n \"none\"\n >,\n any,\n any\n >,\n editor: BlockNoteEditor<any, any, any>,\n element?: { dom: HTMLElement; destroy?: () => void },\n buttonIcon?: HTMLElement,\n) => {\n const wrapper = document.createElement(\"div\");\n wrapper.className = \"bn-file-block-content-wrapper\";\n\n // Show the add file button if the file has not been uploaded yet. Change to\n // show a loader if a file upload for the block begins.\n if (block.props.url === \"\") {\n const addFileButton = createAddFileButton(block, editor, buttonIcon);\n wrapper.appendChild(addFileButton.dom);\n\n const destroyUploadStartHandler = editor.onUploadStart((blockId) => {\n if (blockId === block.id) {\n wrapper.removeChild(addFileButton.dom);\n\n const loading = document.createElement(\"div\");\n loading.className = \"bn-file-loading-preview\";\n loading.textContent = \"Loading...\";\n wrapper.appendChild(loading);\n }\n });\n\n return {\n dom: wrapper,\n destroy: () => {\n destroyUploadStartHandler();\n addFileButton.destroy();\n },\n };\n }\n\n const ret: { dom: HTMLElement; destroy?: () => void } = { dom: wrapper };\n\n // Show the file preview, or the file name and icon.\n if (block.props.showPreview === false || !element) {\n // Show file name and icon.\n const fileNameWithIcon = createFileNameWithIcon(block);\n wrapper.appendChild(fileNameWithIcon.dom);\n\n ret.destroy = () => {\n fileNameWithIcon.destroy?.();\n };\n } else {\n // Show file preview.\n wrapper.appendChild(element.dom);\n }\n\n // Show the caption if there is one.\n if (block.props.caption) {\n const caption = document.createElement(\"p\");\n caption.className = \"bn-file-caption\";\n caption.textContent = block.props.caption;\n wrapper.appendChild(caption);\n }\n\n return ret;\n};\n","export const createFigureWithCaption = (\n element: HTMLElement,\n caption: string,\n) => {\n const figure = document.createElement(\"figure\");\n const captionElement = document.createElement(\"figcaption\");\n captionElement.textContent = caption;\n\n figure.appendChild(element);\n figure.appendChild(captionElement);\n\n return { dom: figure };\n};\n","export const createLinkWithCaption = (\n element: HTMLElement,\n caption: string,\n) => {\n const wrapper = document.createElement(\"div\");\n const fileCaption = document.createElement(\"p\");\n fileCaption.textContent = caption;\n\n wrapper.appendChild(element);\n wrapper.appendChild(fileCaption);\n\n return {\n dom: wrapper,\n };\n};\n","export const parseAudioElement = (audioElement: HTMLAudioElement) => {\n const url = audioElement.src || undefined;\n\n return { url };\n};\n","import { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport {\n BlockFromConfig,\n createBlockConfig,\n createBlockSpec,\n} from \"../../schema/index.js\";\nimport { defaultProps, parseDefaultProps } from \"../defaultProps.js\";\nimport { parseFigureElement } from \"../File/helpers/parse/parseFigureElement.js\";\nimport { createFileBlockWrapper } from \"../File/helpers/render/createFileBlockWrapper.js\";\nimport { createFigureWithCaption } from \"../File/helpers/toExternalHTML/createFigureWithCaption.js\";\nimport { createLinkWithCaption } from \"../File/helpers/toExternalHTML/createLinkWithCaption.js\";\nimport { parseAudioElement } from \"./parseAudioElement.js\";\n\nexport const FILE_AUDIO_ICON_SVG =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M2 16.0001H5.88889L11.1834 20.3319C11.2727 20.405 11.3846 20.4449 11.5 20.4449C11.7761 20.4449 12 20.2211 12 19.9449V4.05519C12 3.93977 11.9601 3.8279 11.887 3.73857C11.7121 3.52485 11.3971 3.49335 11.1834 3.66821L5.88889 8.00007H2C1.44772 8.00007 1 8.44778 1 9.00007V15.0001C1 15.5524 1.44772 16.0001 2 16.0001ZM23 12C23 15.292 21.5539 18.2463 19.2622 20.2622L17.8445 18.8444C19.7758 17.1937 21 14.7398 21 12C21 9.26016 19.7758 6.80629 17.8445 5.15557L19.2622 3.73779C21.5539 5.75368 23 8.70795 23 12ZM18 12C18 10.0883 17.106 8.38548 15.7133 7.28673L14.2842 8.71584C15.3213 9.43855 16 10.64 16 12C16 13.36 15.3213 14.5614 14.2842 15.2841L15.7133 16.7132C17.106 15.6145 18 13.9116 18 12Z\"></path></svg>';\n\nexport interface AudioOptions {\n icon?: string;\n}\n\nexport type AudioBlockConfig = ReturnType<typeof createAudioBlockConfig>;\n\nexport const createAudioBlockConfig = createBlockConfig(\n (_ctx: AudioOptions) =>\n ({\n type: \"audio\" as const,\n propSchema: {\n backgroundColor: defaultProps.backgroundColor,\n // File name.\n name: {\n default: \"\" as const,\n },\n // File url.\n url: {\n default: \"\" as const,\n },\n // File caption.\n caption: {\n default: \"\" as const,\n },\n\n showPreview: {\n default: true,\n },\n },\n content: \"none\",\n }) as const,\n);\n\nexport const audioParse =\n (_config: AudioOptions = {}) =>\n (element: HTMLElement) => {\n if (element.tagName === \"AUDIO\") {\n // Ignore if parent figure has already been parsed.\n if (element.closest(\"figure\")) {\n return undefined;\n }\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseAudioElement(element as HTMLAudioElement),\n backgroundColor,\n };\n }\n\n if (element.tagName === \"FIGURE\") {\n const parsedFigure = parseFigureElement(element, \"audio\");\n if (!parsedFigure) {\n return undefined;\n }\n\n const { targetElement, caption } = parsedFigure;\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseAudioElement(targetElement as HTMLAudioElement),\n backgroundColor,\n caption,\n };\n }\n\n return undefined;\n };\n\nexport const audioRender =\n (config: AudioOptions = {}) =>\n (\n block: BlockFromConfig<ReturnType<typeof createAudioBlockConfig>, any, any>,\n editor: BlockNoteEditor<\n Record<\"audio\", ReturnType<typeof createAudioBlockConfig>>,\n any,\n any\n >,\n ) => {\n const icon = document.createElement(\"div\");\n icon.innerHTML = config.icon ?? FILE_AUDIO_ICON_SVG;\n\n const audio = document.createElement(\"audio\");\n audio.className = \"bn-audio\";\n if (editor.resolveFileUrl) {\n editor.resolveFileUrl(block.props.url).then((downloadUrl) => {\n audio.src = downloadUrl;\n });\n } else {\n audio.src = block.props.url;\n }\n audio.controls = true;\n audio.contentEditable = \"false\";\n audio.draggable = false;\n\n return createFileBlockWrapper(\n block,\n editor,\n { dom: audio },\n icon.firstElementChild as HTMLElement,\n );\n };\n\nexport const audioToExternalHTML =\n (_config: AudioOptions = {}) =>\n (\n block: BlockFromConfig<ReturnType<typeof createAudioBlockConfig>, any, any>,\n _editor: BlockNoteEditor<\n Record<\"audio\", ReturnType<typeof createAudioBlockConfig>>,\n any,\n any\n >,\n ) => {\n if (!block.props.url) {\n const div = document.createElement(\"p\");\n div.textContent = \"Add audio\";\n\n return {\n dom: div,\n };\n }\n\n let audio;\n if (block.props.showPreview) {\n audio = document.createElement(\"audio\");\n audio.src = block.props.url;\n } else {\n audio = document.createElement(\"a\");\n audio.href = block.props.url;\n audio.textContent = block.props.name || block.props.url;\n }\n\n if (block.props.caption) {\n if (block.props.showPreview) {\n return createFigureWithCaption(audio, block.props.caption);\n } else {\n return createLinkWithCaption(audio, block.props.caption);\n }\n }\n\n return {\n dom: audio,\n };\n };\n\nexport const createAudioBlockSpec = createBlockSpec(\n createAudioBlockConfig,\n (config) => ({\n meta: {\n fileBlockAccept: [\"audio/*\"],\n },\n parse: audioParse(config),\n render: audioRender(config),\n toExternalHTML: audioToExternalHTML(config),\n runsBefore: [\"file\"],\n }),\n);\n","// from https://raw.githubusercontent.com/ueberdosis/tiptap/develop/packages/core/src/EventEmitter.ts (MIT)\n\ntype StringKeyOf<T> = Extract<keyof T, string>;\ntype CallbackType<\n T extends Record<string, any>,\n EventName extends StringKeyOf<T>,\n> = T[EventName] extends any[] ? T[EventName] : [T[EventName]];\ntype CallbackFunction<\n T extends Record<string, any>,\n EventName extends StringKeyOf<T>,\n> = (...props: CallbackType<T, EventName>) => any;\n\nexport class EventEmitter<T extends Record<string, any>> {\n // eslint-disable-next-line @typescript-eslint/ban-types\n private callbacks: { [key: string]: Function[] } = {};\n\n public on<EventName extends StringKeyOf<T>>(\n event: EventName,\n fn: CallbackFunction<T, EventName>,\n ) {\n if (!this.callbacks[event]) {\n this.callbacks[event] = [];\n }\n\n this.callbacks[event].push(fn);\n\n return () => this.off(event, fn);\n }\n\n protected emit<EventName extends StringKeyOf<T>>(\n event: EventName,\n ...args: CallbackType<T, EventName>\n ) {\n const callbacks = this.callbacks[event];\n\n if (callbacks) {\n callbacks.forEach((callback) => callback.apply(this, args));\n }\n }\n\n public off<EventName extends StringKeyOf<T>>(\n event: EventName,\n fn?: CallbackFunction<T, EventName>,\n ) {\n const callbacks = this.callbacks[event];\n\n if (callbacks) {\n if (fn) {\n this.callbacks[event] = callbacks.filter((callback) => callback !== fn);\n } else {\n delete this.callbacks[event];\n }\n }\n }\n\n protected removeAllListeners(): void {\n this.callbacks = {};\n }\n}\n","import { Plugin } from \"prosemirror-state\";\nimport { EventEmitter } from \"../util/EventEmitter.js\";\n\nimport { AnyExtension } from \"@tiptap/core\";\nimport {\n BlockSchema,\n InlineContentSchema,\n PartialBlockNoDefaults,\n StyleSchema,\n} from \"../schema/index.js\";\nimport { BlockNoteEditor } from \"./BlockNoteEditor.js\";\n\nexport abstract class BlockNoteExtension<\n TEvent extends Record<string, any> = any,\n> extends EventEmitter<TEvent> {\n public static key(): string {\n throw new Error(\"You must implement the key method in your extension\");\n }\n\n protected addProsemirrorPlugin(plugin: Plugin) {\n this.plugins.push(plugin);\n }\n\n public readonly plugins: Plugin[] = [];\n public get priority(): number | undefined {\n return undefined;\n }\n\n // eslint-disable-next-line\n constructor(..._args: any[]) {\n super();\n // Allow subclasses to have constructors with parameters\n // without this, we can't easily implement BlockNoteEditor.extension(MyExtension) pattern\n }\n\n /**\n * Input rules for the block\n */\n public inputRules?: InputRule[];\n\n /**\n * A mapping of a keyboard shortcut to a function that will be called when the shortcut is pressed\n *\n * The keys are in the format:\n * - Key names may be strings like `Shift-Ctrl-Enter`—a key identifier prefixed with zero or more modifiers\n * - Key identifiers are based on the strings that can appear in KeyEvent.key\n * - Use lowercase letters to refer to letter keys (or uppercase letters if you want shift to be held)\n * - You may use `Space` as an alias for the \" \" name\n * - Modifiers can be given in any order: `Shift-` (or `s-`), `Alt-` (or `a-`), `Ctrl-` (or `c-` or `Control-`) and `Cmd-` (or `m-` or `Meta-`)\n * - For characters that are created by holding shift, the Shift- prefix is implied, and should not be added explicitly\n * - You can use Mod- as a shorthand for Cmd- on Mac and Ctrl- on other platforms\n *\n * @example\n * ```typescript\n * keyboardShortcuts: {\n * \"Mod-Enter\": (ctx) => { return true; },\n * \"Shift-Ctrl-Space\": (ctx) => { return true; },\n * \"a\": (ctx) => { return true; },\n * \"Space\": (ctx) => { return true; }\n * }\n * ```\n */\n public keyboardShortcuts?: Record<\n string,\n (ctx: {\n editor: BlockNoteEditor<BlockSchema, InlineContentSchema, StyleSchema>;\n }) => boolean\n >;\n\n public tiptapExtensions?: AnyExtension[];\n}\n\nexport type InputRule = {\n /**\n * The regex to match when to trigger the input rule\n */\n find: RegExp;\n /**\n * The function to call when the input rule is matched\n * @returns undefined if the input rule should not be triggered, or an object with the type and props to update the block\n */\n replace: (props: {\n /**\n * The result of the regex match\n */\n match: RegExpMatchArray;\n // TODO this will be a Point, when we have the Location API\n /**\n * The range of the text that was matched\n */\n range: { from: number; to: number };\n /**\n * The editor instance\n */\n editor: BlockNoteEditor<any, any, any>;\n }) => undefined | PartialBlockNoDefaults<any, any, any>;\n};\n\n/**\n * This creates an instance of a BlockNoteExtension that can be used to add to a schema.\n * It is a bit of a hack, but it works.\n */\nexport function createBlockNoteExtension(\n options: Partial<\n Pick<\n BlockNoteExtension,\n \"inputRules\" | \"keyboardShortcuts\" | \"plugins\" | \"tiptapExtensions\"\n >\n > & { key: string },\n) {\n const x = Object.create(BlockNoteExtension.prototype);\n x.key = options.key;\n x.inputRules = options.inputRules;\n x.keyboardShortcuts = options.keyboardShortcuts;\n x.plugins = options.plugins ?? [];\n x.tiptapExtensions = options.tiptapExtensions;\n return x as BlockNoteExtension;\n}\n","import type { HighlighterGeneric } from \"@shikijs/types\";\nimport { createBlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\n\nimport { DOMParser } from \"@tiptap/pm/model\";\n\nexport type CodeBlockOptions = {\n /**\n * Whether to indent lines with a tab when the user presses `Tab` in a code block.\n *\n * @default true\n */\n indentLineWithTab?: boolean;\n /**\n * The default language to use for code blocks.\n *\n * @default \"text\"\n */\n defaultLanguage?: string;\n /**\n * The languages that are supported in the editor.\n *\n * @example\n * {\n * javascript: {\n * name: \"JavaScript\",\n * aliases: [\"js\"],\n * },\n * typescript: {\n * name: \"TypeScript\",\n * aliases: [\"ts\"],\n * },\n * }\n */\n supportedLanguages?: Record<\n string,\n {\n /**\n * The display name of the language.\n */\n name: string;\n /**\n * Aliases for this language.\n */\n aliases?: string[];\n }\n >;\n /**\n * The highlighter to use for code blocks.\n */\n createHighlighter?: () => Promise<HighlighterGeneric<any, any>>;\n};\n\nexport type CodeBlockConfig = ReturnType<typeof createCodeBlockConfig>;\n\nexport const createCodeBlockConfig = createBlockConfig(\n ({ defaultLanguage = \"text\" }: CodeBlockOptions) =>\n ({\n type: \"codeBlock\" as const,\n propSchema: {\n language: {\n default: defaultLanguage,\n },\n },\n content: \"inline\",\n }) as const,\n);\n\nexport const createCodeBlockSpec = createBlockSpec(\n createCodeBlockConfig,\n (options) => ({\n meta: {\n code: true,\n defining: true,\n isolating: false,\n },\n parse: (e) => {\n if (e.tagName !== \"PRE\") {\n return undefined;\n }\n\n if (\n e.childElementCount !== 1 ||\n e.firstElementChild?.tagName !== \"CODE\"\n ) {\n return undefined;\n }\n\n const code = e.firstElementChild!;\n const language =\n code.getAttribute(\"data-language\") ||\n code.className\n .split(\" \")\n .find((name) => name.includes(\"language-\"))\n ?.replace(\"language-\", \"\");\n\n return { language };\n },\n\n parseContent: ({ el, schema }) => {\n const parser = DOMParser.fromSchema(schema);\n const code = el.firstElementChild!;\n\n return parser.parse(code, {\n topNode: schema.nodes[\"codeBlock\"].create(),\n }).content;\n },\n\n render(block, editor) {\n const wrapper = document.createDocumentFragment();\n const pre = document.createElement(\"pre\");\n const code = document.createElement(\"code\");\n pre.appendChild(code);\n\n let removeSelectChangeListener = undefined;\n\n if (options.supportedLanguages) {\n const select = document.createElement(\"select\");\n\n const handleLanguageChange = (event: Event) => {\n const language = (event.target as HTMLSelectElement).value;\n\n editor.updateBlock(block.id, { props: { language } });\n };\n select.addEventListener(\"change\", handleLanguageChange);\n\n const selectWrapper = document.createElement(\"div\");\n selectWrapper.contentEditable = \"false\";\n select.value =\n block.props.language || options.defaultLanguage || \"text\";\n\n Object.entries(options.supportedLanguages ?? {}).forEach(\n ([id, { name }]) => {\n const option = document.createElement(\"option\");\n\n option.value = id;\n option.text = name;\n select.appendChild(option);\n },\n );\n selectWrapper.appendChild(select);\n wrapper.appendChild(selectWrapper);\n\n removeSelectChangeListener = () =>\n select.removeEventListener(\"change\", handleLanguageChange);\n }\n wrapper.appendChild(pre);\n\n return {\n dom: wrapper,\n contentDOM: code,\n destroy: () => {\n removeSelectChangeListener?.();\n },\n };\n },\n toExternalHTML(block) {\n const pre = document.createElement(\"pre\");\n const code = document.createElement(\"code\");\n code.className = `language-${block.props.language}`;\n code.dataset.language = block.props.language;\n pre.appendChild(code);\n return {\n dom: pre,\n contentDOM: code,\n };\n },\n }),\n (options) => {\n return [\n createBlockNoteExtension({\n key: \"code-block-keyboard-shortcuts\",\n keyboardShortcuts: {\n Delete: ({ editor }) => {\n return editor.transact((tr) => {\n const { block } = editor.getTextCursorPosition();\n if (block.type !== \"codeBlock\") {\n return false;\n }\n const { $from } = tr.selection;\n\n // When inside empty codeblock, on `DELETE` key press, delete the codeblock\n if (!$from.parent.textContent) {\n editor.removeBlocks([block]);\n\n return true;\n }\n\n return false;\n });\n },\n Tab: ({ editor }) => {\n if (options.indentLineWithTab === false) {\n return false;\n }\n\n return editor.transact((tr) => {\n const { block } = editor.getTextCursorPosition();\n if (block.type === \"codeBlock\") {\n // TODO should probably only tab when at a line start or already tabbed in\n tr.insertText(\" \");\n return true;\n }\n\n return false;\n });\n },\n Enter: ({ editor }) => {\n return editor.transact((tr) => {\n const { block, nextBlock } = editor.getTextCursorPosition();\n if (block.type !== \"codeBlock\") {\n return false;\n }\n const { $from } = tr.selection;\n\n const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2;\n const endsWithDoubleNewline =\n $from.parent.textContent.endsWith(\"\\n\\n\");\n\n // The user is trying to exit the code block by pressing enter at the end of the code block\n if (isAtEnd && endsWithDoubleNewline) {\n // Remove the double newline\n tr.delete($from.pos - 2, $from.pos);\n\n // If there is a next block, move the cursor to it\n if (nextBlock) {\n editor.setTextCursorPosition(nextBlock, \"start\");\n return true;\n }\n\n // If there is no next block, insert a new paragraph\n const [newBlock] = editor.insertBlocks(\n [{ type: \"paragraph\" }],\n block,\n \"after\",\n );\n // Move the cursor to the new block\n editor.setTextCursorPosition(newBlock, \"start\");\n\n return true;\n }\n\n tr.insertText(\"\\n\");\n return true;\n });\n },\n \"Shift-Enter\": ({ editor }) => {\n return editor.transact(() => {\n const { block } = editor.getTextCursorPosition();\n if (block.type !== \"codeBlock\") {\n return false;\n }\n\n const [newBlock] = editor.insertBlocks(\n // insert a new paragraph\n [{ type: \"paragraph\" }],\n block,\n \"after\",\n );\n // move the cursor to the new block\n editor.setTextCursorPosition(newBlock, \"start\");\n return true;\n });\n },\n },\n inputRules: [\n {\n find: /^```(.*?)\\s$/,\n replace: ({ match }) => {\n const languageName = match[1].trim();\n const attributes = {\n language: getLanguageId(options, languageName) ?? languageName,\n };\n\n return {\n type: \"codeBlock\",\n props: {\n language: attributes.language,\n },\n content: [],\n };\n },\n },\n ],\n }),\n ];\n },\n);\n\nexport function getLanguageId(\n options: CodeBlockOptions,\n languageName: string,\n): string | undefined {\n return Object.entries(options.supportedLanguages ?? {}).find(\n ([id, { aliases }]) => {\n return aliases?.includes(languageName) || id === languageName;\n },\n )?.[0];\n}\n","export const parseEmbedElement = (embedElement: HTMLEmbedElement) => {\n const url = embedElement.src || undefined;\n\n return { url };\n};\n","import { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\nimport { defaultProps, parseDefaultProps } from \"../defaultProps.js\";\nimport { parseEmbedElement } from \"./helpers/parse/parseEmbedElement.js\";\nimport { parseFigureElement } from \"./helpers/parse/parseFigureElement.js\";\nimport { createFileBlockWrapper } from \"./helpers/render/createFileBlockWrapper.js\";\nimport { createLinkWithCaption } from \"./helpers/toExternalHTML/createLinkWithCaption.js\";\n\nexport type FileBlockConfig = ReturnType<typeof createFileBlockConfig>;\n\nexport const createFileBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"file\" as const,\n propSchema: {\n backgroundColor: defaultProps.backgroundColor,\n // File name.\n name: {\n default: \"\" as const,\n },\n // File url.\n url: {\n default: \"\" as const,\n },\n // File caption.\n caption: {\n default: \"\" as const,\n },\n },\n content: \"none\" as const,\n }) as const,\n);\n\nexport const fileParse = () => (element: HTMLElement) => {\n if (element.tagName === \"EMBED\") {\n // Ignore if parent figure has already been parsed.\n if (element.closest(\"figure\")) {\n return undefined;\n }\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseEmbedElement(element as HTMLEmbedElement),\n backgroundColor,\n };\n }\n\n if (element.tagName === \"FIGURE\") {\n const parsedFigure = parseFigureElement(element, \"embed\");\n if (!parsedFigure) {\n return undefined;\n }\n\n const { targetElement, caption } = parsedFigure;\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseEmbedElement(targetElement as HTMLEmbedElement),\n backgroundColor,\n caption,\n };\n }\n\n return undefined;\n};\n\nexport const createFileBlockSpec = createBlockSpec(createFileBlockConfig, {\n meta: {\n fileBlockAccept: [\"*/*\"],\n },\n parse: fileParse(),\n render(block, editor) {\n return createFileBlockWrapper(block, editor);\n },\n toExternalHTML(block) {\n if (!block.props.url) {\n const div = document.createElement(\"p\");\n div.textContent = \"Add file\";\n\n return {\n dom: div,\n };\n }\n\n const fileSrcLink = document.createElement(\"a\");\n fileSrcLink.href = block.props.url;\n fileSrcLink.textContent = block.props.name || block.props.url;\n\n if (block.props.caption) {\n return createLinkWithCaption(fileSrcLink, block.props.caption);\n }\n\n return {\n dom: fileSrcLink,\n };\n },\n});\n","import { ViewMutationRecord } from \"@tiptap/pm/view\";\n\nimport { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport { Block } from \"../defaultBlocks.js\";\n\ntype ToggledState = {\n set: (block: Block<any, any, any>, isToggled: boolean) => void;\n get: (block: Block<any, any, any>) => boolean;\n};\n\nexport const defaultToggledState: ToggledState = {\n set: (block, isToggled: boolean) =>\n window.localStorage.setItem(\n `toggle-${block.id}`,\n isToggled ? \"true\" : \"false\",\n ),\n get: (block) => window.localStorage.getItem(`toggle-${block.id}`) === \"true\",\n};\n\nexport const createToggleWrapper = (\n block: Block<any, any, any>,\n editor: BlockNoteEditor<any, any, any>,\n renderedElement: HTMLElement,\n toggledState: ToggledState = defaultToggledState,\n): {\n dom: HTMLElement;\n contentDOM?: HTMLElement;\n ignoreMutation?: (mutation: ViewMutationRecord) => boolean;\n destroy?: () => void;\n} => {\n if (!(\"isToggleable\" in block.props) || !block.props.isToggleable) {\n return {\n dom: renderedElement,\n };\n }\n\n const dom = document.createElement(\"div\");\n\n const toggleWrapper = document.createElement(\"div\");\n toggleWrapper.className = \"bn-toggle-wrapper\";\n\n const toggleButton = document.createElement(\"button\");\n toggleButton.className = \"bn-toggle-button\";\n toggleButton.type = \"button\";\n toggleButton.innerHTML =\n // https://fonts.google.com/icons?selected=Material+Symbols+Rounded:chevron_right:FILL@0;wght@700;GRAD@0;opsz@24&icon.query=chevron&icon.style=Rounded&icon.size=24&icon.color=%23e8eaed\n '<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>';\n const toggleButtonMouseDown = (event: MouseEvent) => event.preventDefault();\n toggleButton.addEventListener(\"mousedown\", toggleButtonMouseDown);\n const toggleButtonOnClick = () => {\n // Toggles visibility of child blocks. Also adds/removes the \"add block\"\n // button if there are no child blocks.\n if (toggleWrapper.getAttribute(\"data-show-children\") === \"true\") {\n toggleWrapper.setAttribute(\"data-show-children\", \"false\");\n toggledState.set(editor.getBlock(block)!, false);\n\n if (dom.contains(toggleAddBlockButton)) {\n dom.removeChild(toggleAddBlockButton);\n }\n } else {\n toggleWrapper.setAttribute(\"data-show-children\", \"true\");\n toggledState.set(editor.getBlock(block)!, true);\n\n if (\n editor.getBlock(block)?.children.length === 0 &&\n !dom.contains(toggleAddBlockButton)\n ) {\n dom.appendChild(toggleAddBlockButton);\n }\n }\n };\n toggleButton.addEventListener(\"click\", toggleButtonOnClick);\n\n toggleWrapper.appendChild(toggleButton);\n toggleWrapper.appendChild(renderedElement);\n\n const toggleAddBlockButton = document.createElement(\"button\");\n toggleAddBlockButton.className = \"bn-toggle-add-block-button\";\n toggleAddBlockButton.type = \"button\";\n toggleAddBlockButton.textContent =\n editor.dictionary.toggle_blocks.add_block_button;\n const toggleAddBlockButtonMouseDown = (event: MouseEvent) =>\n event.preventDefault();\n toggleAddBlockButton.addEventListener(\n \"mousedown\",\n toggleAddBlockButtonMouseDown,\n );\n const toggleAddBlockButtonOnClick = () => {\n // Adds a single empty child block.\n editor.transact(() => {\n // dom.removeChild(toggleAddBlockButton);\n\n const updatedBlock = editor.updateBlock(block, {\n // Single empty block with default type.\n children: [{}],\n });\n editor.setTextCursorPosition(updatedBlock.children[0].id, \"end\");\n editor.focus();\n });\n };\n toggleAddBlockButton.addEventListener(\"click\", toggleAddBlockButtonOnClick);\n\n dom.appendChild(toggleWrapper);\n\n let childCount = block.children.length;\n const onEditorChange = editor.onChange(() => {\n const newChildCount = editor.getBlock(block)?.children.length ?? 0;\n\n if (newChildCount > childCount) {\n // If a child block is added while children are hidden, show children.\n if (toggleWrapper.getAttribute(\"data-show-children\") === \"false\") {\n toggleWrapper.setAttribute(\"data-show-children\", \"true\");\n toggledState.set(editor.getBlock(block)!, true);\n }\n\n // Remove the \"add block\" button as we want to show child blocks and\n // there is at least one child block.\n if (dom.contains(toggleAddBlockButton)) {\n dom.removeChild(toggleAddBlockButton);\n }\n } else if (newChildCount === 0 && newChildCount < childCount) {\n // If the last child block is removed while children are shown, hide\n // children.\n if (toggleWrapper.getAttribute(\"data-show-children\") === \"true\") {\n toggleWrapper.setAttribute(\"data-show-children\", \"false\");\n toggledState.set(editor.getBlock(block)!, false);\n }\n\n // Remove the \"add block\" button as we want to hide child blocks,\n // regardless of whether there are child blocks or not.\n if (dom.contains(toggleAddBlockButton)) {\n dom.removeChild(toggleAddBlockButton);\n }\n }\n\n childCount = newChildCount;\n });\n\n if (toggledState.get(block)) {\n toggleWrapper.setAttribute(\"data-show-children\", \"true\");\n\n if (block.children.length === 0) {\n // If the toggle is set to show children, but there are no children,\n // we add the \"add block\" button.\n dom.appendChild(toggleAddBlockButton);\n }\n } else {\n toggleWrapper.setAttribute(\"data-show-children\", \"false\");\n }\n\n return {\n dom,\n // Prevents re-renders when the toggle button is clicked.\n ignoreMutation: (mutation) => {\n if (\n mutation instanceof MutationRecord &&\n // We want to prevent re-renders when the view changes, so we ignore\n // all mutations where the `data-show-children` attribute is changed\n // or the \"add block\" button is added/removed.\n ((mutation.type === \"attributes\" &&\n mutation.target === toggleWrapper &&\n mutation.attributeName === \"data-show-children\") ||\n (mutation.type === \"childList\" &&\n (mutation.addedNodes[0] === toggleAddBlockButton ||\n mutation.removedNodes[0] === toggleAddBlockButton)))\n ) {\n return true;\n }\n return false;\n },\n destroy: () => {\n toggleButton.removeEventListener(\"mousedown\", toggleButtonMouseDown);\n toggleButton.removeEventListener(\"click\", toggleButtonOnClick);\n toggleAddBlockButton.removeEventListener(\n \"mousedown\",\n toggleAddBlockButtonMouseDown,\n );\n toggleAddBlockButton.removeEventListener(\n \"click\",\n toggleAddBlockButtonOnClick,\n );\n onEditorChange?.();\n },\n };\n};\n","import { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\nimport { createBlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n parseDefaultProps,\n} from \"../defaultProps.js\";\nimport { createToggleWrapper } from \"../ToggleWrapper/createToggleWrapper.js\";\n\nconst HEADING_LEVELS = [1, 2, 3, 4, 5, 6] as const;\n\nexport interface HeadingOptions {\n defaultLevel?: (typeof HEADING_LEVELS)[number];\n levels?: readonly number[];\n // TODO should probably use composition instead of this\n allowToggleHeadings?: boolean;\n}\n\nexport type HeadingBlockConfig = ReturnType<typeof createHeadingBlockConfig>;\n\nexport const createHeadingBlockConfig = createBlockConfig(\n ({\n defaultLevel = 1,\n levels = HEADING_LEVELS,\n allowToggleHeadings = true,\n }: HeadingOptions = {}) =>\n ({\n type: \"heading\" as const,\n propSchema: {\n ...defaultProps,\n level: { default: defaultLevel, values: levels },\n ...(allowToggleHeadings\n ? { isToggleable: { default: false, optional: true } as const }\n : {}),\n },\n content: \"inline\",\n }) as const,\n);\n\nexport const createHeadingBlockSpec = createBlockSpec(\n createHeadingBlockConfig,\n ({ allowToggleHeadings = true }: HeadingOptions = {}) => ({\n meta: {\n isolating: false,\n },\n parse(e) {\n let level: number;\n switch (e.tagName) {\n case \"H1\":\n level = 1;\n break;\n case \"H2\":\n level = 2;\n break;\n case \"H3\":\n level = 3;\n break;\n case \"H4\":\n level = 4;\n break;\n case \"H5\":\n level = 5;\n break;\n case \"H6\":\n level = 6;\n break;\n default:\n return undefined;\n }\n\n return {\n ...parseDefaultProps(e),\n level,\n };\n },\n render(block, editor) {\n const dom = document.createElement(`h${block.props.level}`);\n\n if (allowToggleHeadings) {\n const toggleWrapper = createToggleWrapper(block, editor, dom);\n return { ...toggleWrapper, contentDOM: dom };\n }\n\n return {\n dom,\n contentDOM: dom,\n };\n },\n toExternalHTML(block) {\n const dom = document.createElement(`h${block.props.level}`);\n addDefaultPropsExternalHTML(block.props, dom);\n\n return {\n dom,\n contentDOM: dom,\n };\n },\n }),\n ({ levels = HEADING_LEVELS }: HeadingOptions = {}) => [\n createBlockNoteExtension({\n key: \"heading-shortcuts\",\n keyboardShortcuts: Object.fromEntries(\n levels.map((level) => [\n `Mod-Alt-${level}`,\n ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"heading\",\n props: {\n level: level as any,\n },\n });\n return true;\n },\n ]) ?? [],\n ),\n inputRules: levels.map((level) => ({\n find: new RegExp(`^(#{${level}})\\\\s$`),\n replace({ match }: { match: RegExpMatchArray }) {\n return {\n type: \"heading\",\n props: {\n level: match[1].length,\n },\n };\n },\n })),\n }),\n ],\n);\n","import type { BlockNoteEditor } from \"../../../../editor/BlockNoteEditor.js\";\nimport {\n BlockConfig,\n BlockFromConfigNoChildren,\n} from \"../../../../schema/index.js\";\nimport { createFileBlockWrapper } from \"./createFileBlockWrapper.js\";\n\nexport const createResizableFileBlockWrapper = (\n block: BlockFromConfigNoChildren<\n BlockConfig<\n string,\n {\n backgroundColor: { default: \"default\" };\n name: { default: \"\" };\n url: { default: \"\" };\n caption: { default: \"\" };\n showPreview?: { default: true };\n previewWidth?: { default: number };\n textAlignment?: { default: \"left\" };\n },\n \"none\"\n >,\n any,\n any\n >,\n editor: BlockNoteEditor<any, any, any>,\n element: { dom: HTMLElement; destroy?: () => void },\n resizeHandlesContainerElement: HTMLElement,\n buttonIcon?: HTMLElement,\n): { dom: HTMLElement; destroy: () => void } => {\n const { dom, destroy } = createFileBlockWrapper(\n block,\n editor,\n element,\n buttonIcon,\n );\n const wrapper = dom;\n wrapper.style.position = \"relative\";\n if (block.props.url && block.props.showPreview) {\n if (block.props.previewWidth) {\n wrapper.style.width = `${block.props.previewWidth}px`;\n } else {\n wrapper.style.width = \"fit-content\";\n }\n }\n\n const leftResizeHandle = document.createElement(\"div\");\n leftResizeHandle.className = \"bn-resize-handle\";\n leftResizeHandle.style.left = \"4px\";\n const rightResizeHandle = document.createElement(\"div\");\n rightResizeHandle.className = \"bn-resize-handle\";\n rightResizeHandle.style.right = \"4px\";\n\n // This element ensures `mousemove` and `mouseup` events are captured while\n // resizing when the cursor is over the wrapper content. This is because\n // embeds are treated as separate HTML documents, so if the content is an\n // embed, the events will only fire within that document.\n const eventCaptureElement = document.createElement(\"div\");\n eventCaptureElement.style.position = \"absolute\";\n eventCaptureElement.style.height = \"100%\";\n eventCaptureElement.style.width = \"100%\";\n\n // Temporary parameters set when the user begins resizing the element, used to\n // calculate the new width of the element.\n let resizeParams:\n | {\n handleUsed: \"left\" | \"right\";\n initialWidth: number;\n initialClientX: number;\n }\n | undefined;\n let width = block.props.previewWidth! as number;\n\n // Updates the element width with an updated width depending on the cursor X\n // offset from when the resize began, and which resize handle is being used.\n const windowMouseMoveHandler = (event: MouseEvent | TouchEvent) => {\n if (!resizeParams) {\n if (\n !editor.isEditable &&\n resizeHandlesContainerElement.contains(leftResizeHandle) &&\n resizeHandlesContainerElement.contains(rightResizeHandle)\n ) {\n resizeHandlesContainerElement.removeChild(leftResizeHandle);\n resizeHandlesContainerElement.removeChild(rightResizeHandle);\n }\n\n return;\n }\n\n let newWidth: number;\n\n const clientX =\n \"touches\" in event ? event.touches[0].clientX : event.clientX;\n\n if (block.props.textAlignment === \"center\") {\n if (resizeParams.handleUsed === \"left\") {\n newWidth =\n resizeParams.initialWidth +\n (resizeParams.initialClientX - clientX) * 2;\n } else {\n newWidth =\n resizeParams.initialWidth +\n (clientX - resizeParams.initialClientX) * 2;\n }\n } else {\n if (resizeParams.handleUsed === \"left\") {\n newWidth =\n resizeParams.initialWidth + resizeParams.initialClientX - clientX;\n } else {\n newWidth =\n resizeParams.initialWidth + clientX - resizeParams.initialClientX;\n }\n }\n\n // Min element width in px.\n const minWidth = 64;\n\n // Ensures the element is not wider than the editor and not narrower than a\n // predetermined minimum width.\n width = Math.min(\n Math.max(newWidth, minWidth),\n editor.domElement?.firstElementChild?.clientWidth || Number.MAX_VALUE,\n );\n wrapper.style.width = `${width}px`;\n };\n // Stops mouse movements from resizing the element and updates the block's\n // `width` prop to the new value.\n const windowMouseUpHandler = (event: MouseEvent | TouchEvent) => {\n // Hides the drag handles if the cursor is no longer over the element.\n if (\n (!event.target ||\n !wrapper.contains(event.target as Node) ||\n !editor.isEditable) &&\n resizeHandlesContainerElement.contains(leftResizeHandle) &&\n resizeHandlesContainerElement.contains(rightResizeHandle)\n ) {\n resizeHandlesContainerElement.removeChild(leftResizeHandle);\n resizeHandlesContainerElement.removeChild(rightResizeHandle);\n }\n\n if (!resizeParams) {\n return;\n }\n\n resizeParams = undefined;\n\n if (wrapper.contains(eventCaptureElement)) {\n wrapper.removeChild(eventCaptureElement);\n }\n\n editor.updateBlock(block, {\n props: {\n previewWidth: width,\n },\n });\n };\n\n // Shows the resize handles when hovering over the wrapper with the cursor.\n const wrapperMouseEnterHandler = () => {\n if (editor.isEditable) {\n resizeHandlesContainerElement.appendChild(leftResizeHandle);\n resizeHandlesContainerElement.appendChild(rightResizeHandle);\n }\n };\n // Hides the resize handles when the cursor leaves the wrapper, unless the\n // cursor moves to one of the resize handles.\n const wrapperMouseLeaveHandler = (event: MouseEvent) => {\n if (\n event.relatedTarget === leftResizeHandle ||\n event.relatedTarget === rightResizeHandle\n ) {\n return;\n }\n\n if (resizeParams) {\n return;\n }\n\n if (\n editor.isEditable &&\n resizeHandlesContainerElement.contains(leftResizeHandle) &&\n resizeHandlesContainerElement.contains(rightResizeHandle)\n ) {\n resizeHandlesContainerElement.removeChild(leftResizeHandle);\n resizeHandlesContainerElement.removeChild(rightResizeHandle);\n }\n };\n\n // Sets the resize params, allowing the user to begin resizing the element by\n // moving the cursor left or right.\n const leftResizeHandleMouseDownHandler = (event: MouseEvent | TouchEvent) => {\n event.preventDefault();\n\n if (!wrapper.contains(eventCaptureElement)) {\n wrapper.appendChild(eventCaptureElement);\n }\n\n const clientX =\n \"touches\" in event ? event.touches[0].clientX : event.clientX;\n\n resizeParams = {\n handleUsed: \"left\",\n initialWidth: wrapper.clientWidth,\n initialClientX: clientX,\n };\n };\n const rightResizeHandleMouseDownHandler = (\n event: MouseEvent | TouchEvent,\n ) => {\n event.preventDefault();\n\n if (!wrapper.contains(eventCaptureElement)) {\n wrapper.appendChild(eventCaptureElement);\n }\n\n const clientX =\n \"touches\" in event ? event.touches[0].clientX : event.clientX;\n\n resizeParams = {\n handleUsed: \"right\",\n initialWidth: wrapper.clientWidth,\n initialClientX: clientX,\n };\n };\n\n window.addEventListener(\"mousemove\", windowMouseMoveHandler);\n window.addEventListener(\"touchmove\", windowMouseMoveHandler);\n window.addEventListener(\"mouseup\", windowMouseUpHandler);\n window.addEventListener(\"touchend\", windowMouseUpHandler);\n wrapper.addEventListener(\"mouseenter\", wrapperMouseEnterHandler);\n wrapper.addEventListener(\"mouseleave\", wrapperMouseLeaveHandler);\n leftResizeHandle.addEventListener(\n \"mousedown\",\n leftResizeHandleMouseDownHandler,\n );\n leftResizeHandle.addEventListener(\n \"touchstart\",\n leftResizeHandleMouseDownHandler,\n );\n rightResizeHandle.addEventListener(\n \"mousedown\",\n rightResizeHandleMouseDownHandler,\n );\n rightResizeHandle.addEventListener(\n \"touchstart\",\n rightResizeHandleMouseDownHandler,\n );\n\n return {\n dom: wrapper,\n destroy: () => {\n destroy?.();\n window.removeEventListener(\"mousemove\", windowMouseMoveHandler);\n window.removeEventListener(\"touchmove\", windowMouseMoveHandler);\n window.removeEventListener(\"mouseup\", windowMouseUpHandler);\n window.removeEventListener(\"touchend\", windowMouseUpHandler);\n wrapper.removeEventListener(\"mouseenter\", wrapperMouseEnterHandler);\n wrapper.removeEventListener(\"mouseleave\", wrapperMouseLeaveHandler);\n leftResizeHandle.removeEventListener(\n \"mousedown\",\n leftResizeHandleMouseDownHandler,\n );\n leftResizeHandle.removeEventListener(\n \"touchstart\",\n leftResizeHandleMouseDownHandler,\n );\n rightResizeHandle.removeEventListener(\n \"mousedown\",\n rightResizeHandleMouseDownHandler,\n );\n rightResizeHandle.removeEventListener(\n \"touchstart\",\n rightResizeHandleMouseDownHandler,\n );\n },\n };\n};\n","export const parseImageElement = (imageElement: HTMLImageElement) => {\n const url = imageElement.src || undefined;\n const previewWidth = imageElement.width || undefined;\n const name = imageElement.alt || undefined;\n\n return { url, previewWidth, name };\n};\n","import { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport {\n BlockFromConfig,\n createBlockConfig,\n createBlockSpec,\n} from \"../../schema/index.js\";\nimport { defaultProps, parseDefaultProps } from \"../defaultProps.js\";\nimport { parseFigureElement } from \"../File/helpers/parse/parseFigureElement.js\";\nimport { createResizableFileBlockWrapper } from \"../File/helpers/render/createResizableFileBlockWrapper.js\";\nimport { createFigureWithCaption } from \"../File/helpers/toExternalHTML/createFigureWithCaption.js\";\nimport { createLinkWithCaption } from \"../File/helpers/toExternalHTML/createLinkWithCaption.js\";\nimport { parseImageElement } from \"./parseImageElement.js\";\n\nexport const FILE_IMAGE_ICON_SVG =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M5 11.1005L7 9.1005L12.5 14.6005L16 11.1005L19 14.1005V5H5V11.1005ZM4 3H20C20.5523 3 21 3.44772 21 4V20C21 20.5523 20.5523 21 20 21H4C3.44772 21 3 20.5523 3 20V4C3 3.44772 3.44772 3 4 3ZM15.5 10C14.6716 10 14 9.32843 14 8.5C14 7.67157 14.6716 7 15.5 7C16.3284 7 17 7.67157 17 8.5C17 9.32843 16.3284 10 15.5 10Z\"></path></svg>';\n\nexport interface ImageOptions {\n icon?: string;\n}\n\nexport type ImageBlockConfig = ReturnType<typeof createImageBlockConfig>;\n\nexport const createImageBlockConfig = createBlockConfig(\n (_ctx: ImageOptions = {}) =>\n ({\n type: \"image\" as const,\n propSchema: {\n textAlignment: defaultProps.textAlignment,\n backgroundColor: defaultProps.backgroundColor,\n // File name.\n name: {\n default: \"\" as const,\n },\n // File url.\n url: {\n default: \"\" as const,\n },\n // File caption.\n caption: {\n default: \"\" as const,\n },\n\n showPreview: {\n default: true,\n },\n // File preview width in px.\n previewWidth: {\n default: undefined,\n type: \"number\" as const,\n },\n },\n content: \"none\" as const,\n }) as const,\n);\n\nexport const imageParse =\n (_config: ImageOptions = {}) =>\n (element: HTMLElement) => {\n if (element.tagName === \"IMG\") {\n // Ignore if parent figure has already been parsed.\n if (element.closest(\"figure\")) {\n return undefined;\n }\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseImageElement(element as HTMLImageElement),\n backgroundColor,\n };\n }\n\n if (element.tagName === \"FIGURE\") {\n const parsedFigure = parseFigureElement(element, \"img\");\n if (!parsedFigure) {\n return undefined;\n }\n\n const { targetElement, caption } = parsedFigure;\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseImageElement(targetElement as HTMLImageElement),\n backgroundColor,\n caption,\n };\n }\n\n return undefined;\n };\n\nexport const imageRender =\n (config: ImageOptions = {}) =>\n (\n block: BlockFromConfig<ReturnType<typeof createImageBlockConfig>, any, any>,\n editor: BlockNoteEditor<\n Record<\"image\", ReturnType<typeof createImageBlockConfig>>,\n any,\n any\n >,\n ) => {\n const icon = document.createElement(\"div\");\n icon.innerHTML = config.icon ?? FILE_IMAGE_ICON_SVG;\n\n const imageWrapper = document.createElement(\"div\");\n imageWrapper.className = \"bn-visual-media-wrapper\";\n\n const image = document.createElement(\"img\");\n image.className = \"bn-visual-media\";\n if (editor.resolveFileUrl) {\n editor.resolveFileUrl(block.props.url).then((downloadUrl) => {\n image.src = downloadUrl;\n });\n } else {\n image.src = block.props.url;\n }\n\n image.alt = block.props.name || block.props.caption || \"BlockNote image\";\n image.contentEditable = \"false\";\n image.draggable = false;\n imageWrapper.appendChild(image);\n\n return createResizableFileBlockWrapper(\n block,\n editor,\n { dom: imageWrapper },\n imageWrapper,\n icon.firstElementChild as HTMLElement,\n );\n };\n\nexport const imageToExternalHTML =\n (_config: ImageOptions = {}) =>\n (\n block: BlockFromConfig<ReturnType<typeof createImageBlockConfig>, any, any>,\n _editor: BlockNoteEditor<\n Record<\"image\", ReturnType<typeof createImageBlockConfig>>,\n any,\n any\n >,\n ) => {\n if (!block.props.url) {\n const div = document.createElement(\"p\");\n div.textContent = \"Add image\";\n\n return {\n dom: div,\n };\n }\n\n let image;\n if (block.props.showPreview) {\n image = document.createElement(\"img\");\n image.src = block.props.url;\n image.alt = block.props.name || block.props.caption || \"BlockNote image\";\n if (block.props.previewWidth) {\n image.width = block.props.previewWidth;\n }\n } else {\n image = document.createElement(\"a\");\n image.href = block.props.url;\n image.textContent = block.props.name || block.props.url;\n }\n\n if (block.props.caption) {\n if (block.props.showPreview) {\n return createFigureWithCaption(image, block.props.caption);\n } else {\n return createLinkWithCaption(image, block.props.caption);\n }\n }\n\n return {\n dom: image,\n };\n };\n\nexport const createImageBlockSpec = createBlockSpec(\n createImageBlockConfig,\n (config) => ({\n meta: {\n fileBlockAccept: [\"image/*\"],\n },\n parse: imageParse(config),\n render: imageRender(config),\n toExternalHTML: imageToExternalHTML(config),\n runsBefore: [\"file\"],\n }),\n);\n","import { EditorState, Transaction } from \"prosemirror-state\";\n\nimport {\n getBlockInfo,\n getNearestBlockPos,\n} from \"../../../getBlockInfoFromPos.js\";\nimport { getPmSchema } from \"../../../pmUtil.js\";\n\nexport const splitBlockCommand = (\n posInBlock: number,\n keepType?: boolean,\n keepProps?: boolean,\n) => {\n return ({\n state,\n dispatch,\n }: {\n state: EditorState;\n dispatch: ((args?: any) => any) | undefined;\n }) => {\n if (dispatch) {\n return splitBlockTr(state.tr, posInBlock, keepType, keepProps);\n }\n\n return true;\n };\n};\n\nexport const splitBlockTr = (\n tr: Transaction,\n posInBlock: number,\n keepType?: boolean,\n keepProps?: boolean,\n): boolean => {\n const nearestBlockContainerPos = getNearestBlockPos(tr.doc, posInBlock);\n\n const info = getBlockInfo(nearestBlockContainerPos);\n\n if (!info.isBlockContainer) {\n return false;\n }\n const schema = getPmSchema(tr);\n\n const types = [\n {\n type: info.bnBlock.node.type, // always keep blockcontainer type\n attrs: keepProps ? { ...info.bnBlock.node.attrs, id: undefined } : {},\n },\n {\n type: keepType ? info.blockContent.node.type : schema.nodes[\"paragraph\"],\n attrs: keepProps ? { ...info.blockContent.node.attrs } : {},\n },\n ];\n\n tr.split(posInBlock, 2, types);\n\n return true;\n};\n","import { splitBlockTr } from \"../../api/blockManipulation/commands/splitBlock/splitBlock.js\";\nimport { updateBlockTr } from \"../../api/blockManipulation/commands/updateBlock/updateBlock.js\";\nimport { getBlockInfoFromTransaction } from \"../../api/getBlockInfoFromPos.js\";\nimport { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\n\nexport const handleEnter = (\n editor: BlockNoteEditor<any, any, any>,\n listItemType: string,\n) => {\n const { blockInfo, selectionEmpty } = editor.transact((tr) => {\n return {\n blockInfo: getBlockInfoFromTransaction(tr),\n selectionEmpty: tr.selection.anchor === tr.selection.head,\n };\n });\n\n if (!blockInfo.isBlockContainer) {\n return false;\n }\n const { bnBlock: blockContainer, blockContent } = blockInfo;\n\n if (!(blockContent.node.type.name === listItemType) || !selectionEmpty) {\n return false;\n }\n\n if (blockContent.node.childCount === 0) {\n editor.transact((tr) => {\n updateBlockTr(tr, blockContainer.beforePos, {\n type: \"paragraph\",\n props: {},\n });\n });\n return true;\n } else if (blockContent.node.childCount > 0) {\n return editor.transact((tr) => {\n tr.deleteSelection();\n return splitBlockTr(tr, tr.selection.from, true);\n });\n }\n\n return false;\n};\n","import { DOMParser, Fragment, Schema } from \"prosemirror-model\";\n\n/**\n * This function is used to parse the content of a list item external HTML node.\n *\n * Due to a change in how prosemirror-model handles parsing elements, we have additional flexibility in how we can \"fit\" content into a list item.\n *\n * We've decided to take an approach that is similar to Notion. The core rules of the algorithm are:\n *\n * - If the first child of an `li` has ONLY text content, take the text content, and flatten it into the list item. Subsequent siblings are carried over as is, as children of the list item.\n * - e.g. `<li><h1>Hello</h1><p>World</p></li> -> <li>Hello<blockGroup><blockContainer><p>World</p></blockContainer></blockGroup></li>`\n * - Else, take the content and insert it as children instead.\n * - e.g. `<li><img src=\"url\" /></li> -> <li><p></p><blockGroup><blockContainer><img src=\"url\" /></blockContainer></blockGroup></li>`\n *\n * This ensures that a list item's content is always valid ProseMirror content. Smoothing over differences between how external HTML may be rendered, and how ProseMirror expects content to be structured.\n */\nexport function getListItemContent(\n /**\n * The `li` element to parse.\n */\n _node: Node,\n /**\n * The schema to use for parsing.\n */\n schema: Schema,\n /**\n * The name of the list item node.\n */\n name: string,\n): Fragment {\n /**\n * To actually implement this algorithm, we need to leverage ProseMirror's \"fitting\" algorithm.\n * Where, if content is parsed which doesn't fit into the current node, it will be moved into the parent node.\n *\n * This allows us to parse multiple pieces of content from within the list item (even though it normally would not match the list item's schema) and \"throw\" the excess content into the list item's children.\n *\n * The expected return value is a `Fragment` which contains the list item's content as the first element, and the children wrapped in a blockGroup node. Like so:\n * ```\n * Fragment<[Node<Text>, Node<BlockGroup<Node<BlockContainer<any>>>>]>\n * ```\n */\n const parser = DOMParser.fromSchema(schema);\n\n // TODO: This will be unnecessary in the future: https://github.com/ProseMirror/prosemirror-model/commit/166188d4f9db96eb86fb7de62e72049c86c9dd79\n const node = _node as HTMLElement;\n\n // Move the `li` element's content into a new `div` element\n // This is a hacky workaround to not re-trigger list item parsing,\n // when we are looking to understand what the list item's content actually is, in terms of the schema.\n const clonedNodeDiv = document.createElement(\"div\");\n // Mark the `div` element as a `blockGroup` to make the parsing easier.\n clonedNodeDiv.setAttribute(\"data-node-type\", \"blockGroup\");\n // Clone all children of the `li` element into the new `div` element\n for (const child of Array.from(node.childNodes)) {\n clonedNodeDiv.appendChild(child.cloneNode(true));\n }\n\n // Parses children of the `li` element into a `blockGroup` with `blockContainer` node children\n // This is the structure of list item children, so parsing into this structure allows for\n // easy separation of list item content from child list item content.\n let blockGroupNode = parser.parse(clonedNodeDiv, {\n topNode: schema.nodes.blockGroup.create(),\n });\n\n // There is an edge case where a list item's content may contain a `<input>` element.\n // Causing it to be recognized as a `checkListItem`.\n // We want to skip this, and just parse the list item's content as is.\n if (blockGroupNode.firstChild?.firstChild?.type.name === \"checkListItem\") {\n // We skip the first child, by cutting it out of the `blockGroup` node.\n // and continuing with the rest of the algorithm.\n blockGroupNode = blockGroupNode.copy(\n blockGroupNode.content.cut(\n blockGroupNode.firstChild.firstChild.nodeSize + 2,\n ),\n );\n }\n\n // Structure above is `blockGroup<blockContainer<any>[]>`\n // We want to extract the first `blockContainer` node's content, and see if it is a text block.\n const listItemsFirstChild = blockGroupNode.firstChild?.firstChild;\n\n // If the first node is not a text block, then it's first child is not compatible with the list item node.\n if (!listItemsFirstChild?.isTextblock) {\n // So, we do not try inserting anything into the list item, and instead return anything we found as children for the list item.\n return Fragment.from(blockGroupNode);\n }\n\n // If it is a text block, then we know it only contains text content.\n // So, we extract it, and insert its content into the `listItemNode`.\n // The remaining nodes in the `blockGroup` stay in-place.\n const listItemNode = schema.nodes[name].create(\n {},\n listItemsFirstChild.content,\n );\n\n // We have `blockGroup<listItemsFirstChild, ...blockContainer<any>[]>`\n // We want to extract out the rest of the nodes as `<...blockContainer<any>[]>`\n const remainingListItemChildren = blockGroupNode.content.cut(\n // +2 for the `blockGroup` node's start and end markers\n listItemsFirstChild.nodeSize + 2,\n );\n const hasRemainingListItemChildren = remainingListItemChildren.size > 0;\n\n if (hasRemainingListItemChildren) {\n // Copy the remaining list item children back into the `blockGroup` node.\n // This will make it back into: `blockGroup<...blockContainer<any>[]>`\n const listItemsChildren = blockGroupNode.copy(remainingListItemChildren);\n\n // Return the `listItem` node's content, then add the parsed children after to be lifted out by ProseMirror \"fitting\" algorithm.\n return listItemNode.content.addToEnd(listItemsChildren);\n }\n\n // Otherwise, just return the `listItem` node's content.\n return listItemNode.content;\n}\n","import { createBlockNoteExtension } from \"../../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../../schema/index.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n parseDefaultProps,\n} from \"../../defaultProps.js\";\nimport { handleEnter } from \"../../utils/listItemEnterHandler.js\";\nimport { getListItemContent } from \"../getListItemContent.js\";\n\nexport type BulletListItemBlockConfig = ReturnType<\n typeof createBulletListItemBlockConfig\n>;\n\nexport const createBulletListItemBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"bulletListItem\" as const,\n propSchema: {\n ...defaultProps,\n },\n content: \"inline\",\n }) as const,\n);\n\nexport const createBulletListItemBlockSpec = createBlockSpec(\n createBulletListItemBlockConfig,\n {\n meta: {\n isolating: false,\n },\n parse(element) {\n if (element.tagName !== \"LI\") {\n return undefined;\n }\n\n const parent = element.parentElement;\n\n if (parent === null) {\n return undefined;\n }\n\n if (\n parent.tagName === \"UL\" ||\n (parent.tagName === \"DIV\" && parent.parentElement?.tagName === \"UL\")\n ) {\n return parseDefaultProps(element);\n }\n\n return undefined;\n },\n // As `li` elements can contain multiple paragraphs, we need to merge their contents\n // into a single one so that ProseMirror can parse everything correctly.\n parseContent: ({ el, schema }) =>\n getListItemContent(el, schema, \"bulletListItem\"),\n render() {\n // We use a <p> tag, because for <li> tags we'd need a <ul> element to put\n // them in to be semantically correct, which we can't have due to the\n // schema.\n const dom = document.createElement(\"p\");\n\n return {\n dom,\n contentDOM: dom,\n };\n },\n toExternalHTML(block) {\n const li = document.createElement(\"li\");\n const p = document.createElement(\"p\");\n addDefaultPropsExternalHTML(block.props, li);\n li.appendChild(p);\n\n return {\n dom: li,\n contentDOM: p,\n };\n },\n },\n [\n createBlockNoteExtension({\n key: \"bullet-list-item-shortcuts\",\n keyboardShortcuts: {\n Enter: ({ editor }) => {\n return handleEnter(editor, \"bulletListItem\");\n },\n \"Mod-Shift-8\": ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"bulletListItem\",\n props: {},\n });\n return true;\n },\n },\n inputRules: [\n {\n find: new RegExp(`^[-+*]\\\\s$`),\n replace() {\n return {\n type: \"bulletListItem\",\n props: {},\n };\n },\n },\n ],\n }),\n ],\n);\n","import { createBlockNoteExtension } from \"../../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../../schema/index.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n parseDefaultProps,\n} from \"../../defaultProps.js\";\nimport { handleEnter } from \"../../utils/listItemEnterHandler.js\";\nimport { getListItemContent } from \"../getListItemContent.js\";\n\nexport type CheckListItemBlockConfig = ReturnType<\n typeof createCheckListItemConfig\n>;\n\nexport const createCheckListItemConfig = createBlockConfig(\n () =>\n ({\n type: \"checkListItem\" as const,\n propSchema: {\n ...defaultProps,\n checked: { default: false, type: \"boolean\" },\n },\n content: \"inline\",\n }) as const,\n);\n\nexport const createCheckListItemBlockSpec = createBlockSpec(\n createCheckListItemConfig,\n {\n meta: {\n isolating: false,\n },\n parse(element) {\n if (element.tagName === \"input\") {\n // Ignore if we already parsed an ancestor list item to avoid double-parsing.\n if (element.closest(\"[data-content-type]\") || element.closest(\"li\")) {\n return undefined;\n }\n\n if ((element as HTMLInputElement).type === \"checkbox\") {\n return { checked: (element as HTMLInputElement).checked };\n }\n return undefined;\n }\n if (element.tagName !== \"LI\") {\n return undefined;\n }\n\n const parent = element.parentElement;\n\n if (parent === null) {\n return undefined;\n }\n\n if (\n parent.tagName === \"UL\" ||\n (parent.tagName === \"DIV\" && parent.parentElement?.tagName === \"UL\")\n ) {\n const checkbox =\n (element.querySelector(\"input[type=checkbox]\") as HTMLInputElement) ||\n null;\n\n if (checkbox === null) {\n return undefined;\n }\n\n return { ...parseDefaultProps(element), checked: checkbox.checked };\n }\n\n return;\n },\n // As `li` elements can contain multiple paragraphs, we need to merge their contents\n // into a single one so that ProseMirror can parse everything correctly.\n parseContent: ({ el, schema }) =>\n getListItemContent(el, schema, \"checkListItem\"),\n render(block, editor) {\n const dom = document.createDocumentFragment();\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.checked = block.props.checked;\n if (block.props.checked) {\n checkbox.setAttribute(\"checked\", \"\");\n }\n checkbox.addEventListener(\"change\", () => {\n editor.updateBlock(block, { props: { checked: !block.props.checked } });\n });\n // We use a <p> tag, because for <li> tags we'd need a <ul> element to put\n // them in to be semantically correct, which we can't have due to the\n // schema.\n const paragraph = document.createElement(\"p\");\n\n dom.appendChild(checkbox);\n dom.appendChild(paragraph);\n\n return {\n dom,\n contentDOM: paragraph,\n };\n },\n toExternalHTML(block) {\n const dom = document.createElement(\"li\");\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.checked = block.props.checked;\n if (block.props.checked) {\n checkbox.setAttribute(\"checked\", \"\");\n }\n // We use a <p> tag, because for <li> tags we'd need a <ul> element to put\n // them in to be semantically correct, which we can't have due to the\n // schema.\n const paragraph = document.createElement(\"p\");\n addDefaultPropsExternalHTML(block.props, dom);\n\n dom.appendChild(checkbox);\n dom.appendChild(paragraph);\n\n return {\n dom,\n contentDOM: paragraph,\n };\n },\n runsBefore: [\"bulletListItem\"],\n },\n [\n createBlockNoteExtension({\n key: \"check-list-item-shortcuts\",\n keyboardShortcuts: {\n Enter: ({ editor }) => {\n return handleEnter(editor, \"checkListItem\");\n },\n \"Mod-Shift-9\": ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"checkListItem\",\n props: {},\n });\n return true;\n },\n },\n inputRules: [\n {\n find: new RegExp(`\\\\[\\\\s*\\\\]\\\\s$`),\n replace() {\n return {\n type: \"checkListItem\",\n props: {\n checked: false,\n },\n content: [],\n };\n },\n },\n {\n find: new RegExp(`\\\\[[Xx]\\\\]\\\\s$`),\n replace() {\n return {\n type: \"checkListItem\",\n props: {\n checked: true,\n },\n };\n },\n },\n ],\n }),\n ],\n);\n","import type { Node } from \"@tiptap/pm/model\";\nimport type { Transaction } from \"@tiptap/pm/state\";\nimport { Plugin, PluginKey } from \"@tiptap/pm/state\";\nimport { Decoration, DecorationSet } from \"@tiptap/pm/view\";\n\nimport { getBlockInfo } from \"../../../api/getBlockInfoFromPos.js\";\n\n// Loosely based on https://github.com/ueberdosis/tiptap/blob/7ac01ef0b816a535e903b5ca92492bff110a71ae/packages/extension-mathematics/src/MathematicsPlugin.ts (MIT)\n\ntype DecoSpec = {\n index: number;\n isFirst: boolean;\n hasStart: boolean;\n side: number;\n};\n\ntype Deco = Omit<Decoration, \"spec\"> & { spec: DecoSpec };\n\n/**\n * Calculate the index for a numbered list item based on its position and previous siblings\n */\nfunction calculateListItemIndex(\n node: Node,\n pos: number,\n tr: Transaction,\n map: Map<Node, number>,\n): { index: number; isFirst: boolean; hasStart: boolean } {\n let index: number = node.firstChild!.attrs[\"start\"] || 1;\n let isFirst = true;\n const hasStart = !!node.firstChild!.attrs[\"start\"];\n\n const blockInfo = getBlockInfo({\n posBeforeNode: pos,\n node,\n });\n\n if (!blockInfo.isBlockContainer) {\n throw new Error(\"impossible\");\n }\n\n // Check if this block is the start of a new ordered list\n const prevBlock = tr.doc.resolve(blockInfo.bnBlock.beforePos).nodeBefore;\n const prevBlockIndex = prevBlock ? map.get(prevBlock) : undefined;\n\n if (prevBlockIndex !== undefined) {\n index = prevBlockIndex + 1;\n isFirst = false;\n } else if (prevBlock) {\n // Because we only check the affected ranges, we may need to walk backwards to find the previous block's index\n // We can't just rely on the map, because the map is reset every `apply` call\n const prevBlockInfo = getBlockInfo({\n posBeforeNode: blockInfo.bnBlock.beforePos - prevBlock.nodeSize,\n node: prevBlock,\n });\n\n const isPrevBlockOrderedListItem =\n prevBlockInfo.blockNoteType === \"numberedListItem\";\n if (isPrevBlockOrderedListItem) {\n // recurse to get the index of the previous block\n const itemIndex = calculateListItemIndex(\n prevBlock,\n blockInfo.bnBlock.beforePos - prevBlock.nodeSize,\n tr,\n map,\n );\n index = itemIndex.index + 1;\n isFirst = false;\n }\n }\n // Note: we set the map late, so that when we recurse, we can rely on the map to get the previous block's index in one lookup\n map.set(node, index);\n\n return { index, isFirst, hasStart };\n}\n\n/**\n * Get the decorations for the current state based on the previous state,\n * and the transaction that was applied to get to the current state\n */\nfunction getDecorations(\n tr: Transaction,\n previousPluginState: { decorations: DecorationSet },\n) {\n const map = new Map<Node, number>();\n\n const nextDecorationSet = previousPluginState.decorations.map(\n tr.mapping,\n tr.doc,\n );\n const decorationsToAdd = [] as Deco[];\n\n tr.doc.nodesBetween(0, tr.doc.nodeSize - 2, (node, pos) => {\n if (\n node.type.name === \"blockContainer\" &&\n node.firstChild!.type.name === \"numberedListItem\"\n ) {\n const { index, isFirst, hasStart } = calculateListItemIndex(\n node,\n pos,\n tr,\n map,\n );\n\n // Check if decoration already exists with the same properties (for perf reasons)\n const existingDecorations = nextDecorationSet.find(\n pos,\n pos + node.nodeSize,\n (deco: DecoSpec) =>\n deco.index === index &&\n deco.isFirst === isFirst &&\n deco.hasStart === hasStart,\n );\n\n if (existingDecorations.length === 0) {\n // Create a widget decoration to display the index\n decorationsToAdd.push(\n // move in by 1 to account for the block container\n Decoration.node(pos + 1, pos + node.nodeSize - 1, {\n \"data-index\": index.toString(),\n }),\n );\n }\n }\n });\n\n // Remove any decorations that exist at the same position, they will be replaced by the new decorations\n const decorationsToRemove = decorationsToAdd.flatMap((deco) =>\n nextDecorationSet.find(deco.from, deco.to),\n );\n\n return {\n decorations: nextDecorationSet\n // Remove existing decorations that are going to be replaced\n .remove(decorationsToRemove)\n // Add any new decorations\n .add(tr.doc, decorationsToAdd),\n };\n}\n\n/**\n * This plugin adds decorations to numbered list items to display their index.\n */\nexport const NumberedListIndexingDecorationPlugin = () => {\n return new Plugin<{ decorations: DecorationSet }>({\n key: new PluginKey(\"numbered-list-indexing-decorations\"),\n\n state: {\n init(_config, state) {\n // We create an empty transaction to get the decorations for the initial state based on the initial content\n return getDecorations(state.tr, {\n decorations: DecorationSet.empty,\n });\n },\n apply(tr, previousPluginState) {\n if (\n !tr.docChanged &&\n !tr.selectionSet &&\n previousPluginState.decorations\n ) {\n // Just reuse the existing decorations, since nothing should have changed\n return previousPluginState;\n }\n return getDecorations(tr, previousPluginState);\n },\n },\n\n props: {\n decorations(state) {\n return this.getState(state)?.decorations ?? DecorationSet.empty;\n },\n },\n });\n};\n","import { createBlockNoteExtension } from \"../../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../../schema/index.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n parseDefaultProps,\n} from \"../../defaultProps.js\";\nimport { handleEnter } from \"../../utils/listItemEnterHandler.js\";\nimport { getListItemContent } from \"../getListItemContent.js\";\nimport { NumberedListIndexingDecorationPlugin } from \"./IndexingPlugin.js\";\n\nexport type NumberedListItemBlockConfig = ReturnType<\n typeof createNumberedListItemBlockConfig\n>;\n\nexport const createNumberedListItemBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"numberedListItem\" as const,\n propSchema: {\n ...defaultProps,\n start: { default: undefined, type: \"number\" } as const,\n },\n content: \"inline\",\n }) as const,\n);\n\nexport const createNumberedListItemBlockSpec = createBlockSpec(\n createNumberedListItemBlockConfig,\n {\n meta: {\n isolating: false,\n },\n parse(element) {\n if (element.tagName !== \"LI\") {\n return undefined;\n }\n\n const parent = element.parentElement;\n\n if (parent === null) {\n return undefined;\n }\n\n if (\n parent.tagName === \"OL\" ||\n (parent.tagName === \"DIV\" && parent.parentElement?.tagName === \"OL\")\n ) {\n const startIndex = parseInt(parent.getAttribute(\"start\") || \"1\");\n\n const defaultProps = parseDefaultProps(element);\n\n if (element.previousElementSibling || startIndex === 1) {\n return defaultProps;\n }\n\n return {\n ...defaultProps,\n start: startIndex,\n };\n }\n\n return undefined;\n },\n // As `li` elements can contain multiple paragraphs, we need to merge their contents\n // into a single one so that ProseMirror can parse everything correctly.\n parseContent: ({ el, schema }) =>\n getListItemContent(el, schema, \"numberedListItem\"),\n render() {\n // We use a <p> tag, because for <li> tags we'd need a <ul> element to put\n // them in to be semantically correct, which we can't have due to the\n // schema.\n const dom = document.createElement(\"p\");\n\n return {\n dom,\n contentDOM: dom,\n };\n },\n toExternalHTML(block) {\n const li = document.createElement(\"li\");\n const p = document.createElement(\"p\");\n addDefaultPropsExternalHTML(block.props, li);\n li.appendChild(p);\n\n return {\n dom: li,\n contentDOM: p,\n };\n },\n },\n [\n createBlockNoteExtension({\n key: \"numbered-list-item-shortcuts\",\n inputRules: [\n {\n find: new RegExp(`^(\\\\d+)\\\\.\\\\s$`),\n replace({ match }) {\n const start = parseInt(match[1]);\n return {\n type: \"numberedListItem\",\n props: {\n start: start !== 1 ? start : undefined,\n },\n };\n },\n },\n ],\n keyboardShortcuts: {\n Enter: ({ editor }) => {\n return handleEnter(editor, \"numberedListItem\");\n },\n \"Mod-Shift-7\": ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"numberedListItem\",\n props: {},\n });\n return true;\n },\n },\n plugins: [NumberedListIndexingDecorationPlugin()],\n }),\n ],\n);\n","import { createBlockNoteExtension } from \"../../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../../schema/index.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n} from \"../../defaultProps.js\";\nimport { createToggleWrapper } from \"../../ToggleWrapper/createToggleWrapper.js\";\nimport { handleEnter } from \"../../utils/listItemEnterHandler.js\";\n\nexport type ToggleListItemBlockConfig = ReturnType<\n typeof createToggleListItemBlockConfig\n>;\n\nexport const createToggleListItemBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"toggleListItem\" as const,\n propSchema: {\n ...defaultProps,\n },\n content: \"inline\" as const,\n }) as const,\n);\n\nexport const createToggleListItemBlockSpec = createBlockSpec(\n createToggleListItemBlockConfig,\n {\n meta: {\n isolating: false,\n },\n render(block, editor) {\n const paragraphEl = document.createElement(\"p\");\n const toggleWrapper = createToggleWrapper(\n block as any,\n editor,\n paragraphEl,\n );\n return { ...toggleWrapper, contentDOM: paragraphEl };\n },\n toExternalHTML(block) {\n const li = document.createElement(\"li\");\n const p = document.createElement(\"p\");\n addDefaultPropsExternalHTML(block.props, li);\n li.appendChild(p);\n\n return {\n dom: li,\n contentDOM: p,\n };\n },\n },\n [\n createBlockNoteExtension({\n key: \"toggle-list-item-shortcuts\",\n keyboardShortcuts: {\n Enter: ({ editor }) => {\n return handleEnter(editor, \"toggleListItem\");\n },\n \"Mod-Shift-6\": ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"toggleListItem\",\n props: {},\n });\n return true;\n },\n },\n }),\n ],\n);\n","import {\n BlockSchema,\n createBlockConfig,\n createBlockSpec,\n InlineContentSchema,\n StyleSchema,\n} from \"../../schema/index.js\";\nimport { BlockNoteSchema } from \"../BlockNoteSchema.js\";\n\nexport type PageBreakBlockConfig = ReturnType<\n typeof createPageBreakBlockConfig\n>;\n\nexport const createPageBreakBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"pageBreak\" as const,\n propSchema: {},\n content: \"none\",\n }) as const,\n);\n\nexport const createPageBreakBlockSpec = createBlockSpec(\n createPageBreakBlockConfig,\n {\n parse(element) {\n if (\n element.tagName === \"DIV\" &&\n element.hasAttribute(\"data-page-break\")\n ) {\n return {};\n }\n\n return undefined;\n },\n render() {\n const pageBreak = document.createElement(\"div\");\n\n pageBreak.setAttribute(\"data-page-break\", \"\");\n\n return {\n dom: pageBreak,\n };\n },\n toExternalHTML() {\n const pageBreak = document.createElement(\"div\");\n\n pageBreak.setAttribute(\"data-page-break\", \"\");\n\n return {\n dom: pageBreak,\n };\n },\n },\n);\n\n/**\n * Adds page break support to the given schema.\n */\nexport const withPageBreak = <\n B extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n schema: BlockNoteSchema<B, I, S>,\n) => {\n return schema.extend({\n blockSpecs: {\n pageBreak: createPageBreakBlockSpec(),\n },\n });\n};\n","import { createBlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n parseDefaultProps,\n} from \"../defaultProps.js\";\n\nexport type ParagraphBlockConfig = ReturnType<\n typeof createParagraphBlockConfig\n>;\n\nexport const createParagraphBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"paragraph\" as const,\n propSchema: defaultProps,\n content: \"inline\" as const,\n }) as const,\n);\n\nexport const createParagraphBlockSpec = createBlockSpec(\n createParagraphBlockConfig,\n {\n meta: {\n isolating: false,\n },\n parse: (e) => {\n if (e.tagName !== \"P\") {\n return undefined;\n }\n\n // Edge case for things like images directly inside paragraph.\n if (!e.textContent?.trim()) {\n return undefined;\n }\n\n return parseDefaultProps(e);\n },\n render: () => {\n const dom = document.createElement(\"p\");\n return {\n dom,\n contentDOM: dom,\n };\n },\n toExternalHTML: (block) => {\n const dom = document.createElement(\"p\");\n addDefaultPropsExternalHTML(block.props, dom);\n return {\n dom,\n contentDOM: dom,\n };\n },\n runsBefore: [\"default\"],\n },\n [\n createBlockNoteExtension({\n key: \"paragraph-shortcuts\",\n keyboardShortcuts: {\n \"Mod-Alt-0\": ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"paragraph\",\n props: {},\n });\n return true;\n },\n },\n }),\n ],\n);\n","import { createBlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\nimport {\n addDefaultPropsExternalHTML,\n defaultProps,\n parseDefaultProps,\n} from \"../defaultProps.js\";\n\nexport type QuoteBlockConfig = ReturnType<typeof createQuoteBlockConfig>;\n\nexport const createQuoteBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"quote\" as const,\n propSchema: {\n backgroundColor: defaultProps.backgroundColor,\n textColor: defaultProps.textColor,\n },\n content: \"inline\" as const,\n }) as const,\n);\n\nexport const createQuoteBlockSpec = createBlockSpec(\n createQuoteBlockConfig,\n {\n meta: {\n isolating: false,\n },\n parse(element) {\n if (element.tagName === \"BLOCKQUOTE\") {\n const { backgroundColor, textColor } = parseDefaultProps(element);\n\n return { backgroundColor, textColor };\n }\n\n return undefined;\n },\n render() {\n const quote = document.createElement(\"blockquote\");\n\n return {\n dom: quote,\n contentDOM: quote,\n };\n },\n toExternalHTML(block) {\n const quote = document.createElement(\"blockquote\");\n addDefaultPropsExternalHTML(block.props, quote);\n\n return {\n dom: quote,\n contentDOM: quote,\n };\n },\n },\n [\n createBlockNoteExtension({\n key: \"quote-block-shortcuts\",\n keyboardShortcuts: {\n \"Mod-Alt-q\": ({ editor }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !==\n \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"quote\",\n props: {},\n });\n return true;\n },\n },\n inputRules: [\n {\n find: new RegExp(`^>\\\\s$`),\n replace() {\n return {\n type: \"quote\",\n props: {},\n };\n },\n },\n ],\n }),\n ],\n);\n","import { callOrReturn, Extension, getExtensionField } from \"@tiptap/core\";\nimport { columnResizing, goToNextCell, tableEditing } from \"prosemirror-tables\";\n\nexport const RESIZE_MIN_WIDTH = 35;\nexport const EMPTY_CELL_WIDTH = 120;\nexport const EMPTY_CELL_HEIGHT = 31;\n\nexport const TableExtension = Extension.create({\n name: \"BlockNoteTableExtension\",\n\n addProseMirrorPlugins: () => {\n return [\n columnResizing({\n cellMinWidth: RESIZE_MIN_WIDTH,\n defaultCellMinWidth: EMPTY_CELL_WIDTH,\n // We set this to null as we implement our own node view in the table\n // block content. This node view is the same as what's used by default,\n // but is wrapped in a `blockContent` HTML element.\n View: null,\n }),\n tableEditing(),\n ];\n },\n\n addKeyboardShortcuts() {\n return {\n // Makes enter create a new line within the cell.\n Enter: () => {\n if (\n this.editor.state.selection.empty &&\n this.editor.state.selection.$head.parent.type.name ===\n \"tableParagraph\"\n ) {\n this.editor.commands.insertContent({ type: \"hardBreak\" });\n\n return true;\n }\n\n return false;\n },\n // Ensures that backspace won't delete the table if the text cursor is at\n // the start of a cell and the selection is empty.\n Backspace: () => {\n const selection = this.editor.state.selection;\n const selectionIsEmpty = selection.empty;\n const selectionIsAtStartOfNode = selection.$head.parentOffset === 0;\n const selectionIsInTableParagraphNode =\n selection.$head.node().type.name === \"tableParagraph\";\n\n return (\n selectionIsEmpty &&\n selectionIsAtStartOfNode &&\n selectionIsInTableParagraphNode\n );\n },\n // Enables navigating cells using the tab key.\n Tab: () => {\n return this.editor.commands.command(({ state, dispatch, view }) =>\n goToNextCell(1)(state, dispatch, view),\n );\n },\n \"Shift-Tab\": () => {\n return this.editor.commands.command(({ state, dispatch, view }) =>\n goToNextCell(-1)(state, dispatch, view),\n );\n },\n };\n },\n\n extendNodeSchema(extension) {\n const context = {\n name: extension.name,\n options: extension.options,\n storage: extension.storage,\n };\n\n return {\n tableRole: callOrReturn(\n getExtensionField(extension, \"tableRole\", context),\n ),\n };\n },\n});\n","import { Node, mergeAttributes } from \"@tiptap/core\";\nimport { DOMParser, Fragment, Node as PMNode, Schema } from \"prosemirror-model\";\nimport { TableView } from \"prosemirror-tables\";\nimport { NodeView } from \"prosemirror-view\";\nimport { createBlockNoteExtension } from \"../../editor/BlockNoteExtension.js\";\nimport {\n BlockConfig,\n createBlockSpecFromTiptapNode,\n} from \"../../schema/index.js\";\nimport { mergeCSSClasses } from \"../../util/browser.js\";\nimport { createDefaultBlockDOMOutputSpec } from \"../defaultBlockHelpers.js\";\nimport { defaultProps } from \"../defaultProps.js\";\nimport { EMPTY_CELL_WIDTH, TableExtension } from \"./TableExtension.js\";\n\nexport const tablePropSchema = {\n textColor: defaultProps.textColor,\n};\n\nconst TiptapTableHeader = Node.create<{\n HTMLAttributes: Record<string, any>;\n}>({\n name: \"tableHeader\",\n\n addOptions() {\n return {\n HTMLAttributes: {},\n };\n },\n\n /**\n * We allow table headers and cells to have multiple tableContent nodes because\n * when merging cells, prosemirror-tables will concat the contents of the cells naively.\n * This would cause that content to overflow into other cells when prosemirror tries to enforce the cell structure.\n *\n * So, we manually fix this up when reading back in the `nodeToBlock` and only ever place a single tableContent back into the cell.\n */\n content: \"tableContent+\",\n\n addAttributes() {\n return {\n colspan: {\n default: 1,\n },\n rowspan: {\n default: 1,\n },\n colwidth: {\n default: null,\n parseHTML: (element) => {\n const colwidth = element.getAttribute(\"colwidth\");\n const value = colwidth\n ? colwidth.split(\",\").map((width) => parseInt(width, 10))\n : null;\n\n return value;\n },\n },\n };\n },\n\n tableRole: \"header_cell\",\n\n isolating: true,\n\n parseHTML() {\n return [\n {\n tag: \"th\",\n // As `th` elements can contain multiple paragraphs, we need to merge their contents\n // into a single one so that ProseMirror can parse everything correctly.\n getContent: (node, schema) =>\n parseTableContent(node as HTMLElement, schema),\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"th\",\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n});\n\nconst TiptapTableCell = Node.create<{\n HTMLAttributes: Record<string, any>;\n}>({\n name: \"tableCell\",\n\n addOptions() {\n return {\n HTMLAttributes: {},\n };\n },\n\n content: \"tableContent+\",\n\n addAttributes() {\n return {\n colspan: {\n default: 1,\n },\n rowspan: {\n default: 1,\n },\n colwidth: {\n default: null,\n parseHTML: (element) => {\n const colwidth = element.getAttribute(\"colwidth\");\n const value = colwidth\n ? colwidth.split(\",\").map((width) => parseInt(width, 10))\n : null;\n\n return value;\n },\n },\n };\n },\n\n tableRole: \"cell\",\n\n isolating: true,\n\n parseHTML() {\n return [\n {\n tag: \"td\",\n // As `td` elements can contain multiple paragraphs, we need to merge their contents\n // into a single one so that ProseMirror can parse everything correctly.\n getContent: (node, schema) =>\n parseTableContent(node as HTMLElement, schema),\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"td\",\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n});\n\nconst TiptapTableNode = Node.create({\n name: \"table\",\n content: \"tableRow+\",\n group: \"blockContent\",\n tableRole: \"table\",\n\n marks: \"deletion insertion modification\",\n isolating: true,\n\n parseHTML() {\n return [\n {\n tag: \"table\",\n },\n ];\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const domOutputSpec = createDefaultBlockDOMOutputSpec(\n this.name,\n \"table\",\n {\n ...(this.options.domAttributes?.blockContent || {}),\n ...HTMLAttributes,\n },\n this.options.domAttributes?.inlineContent || {},\n );\n\n // Need to manually add colgroup element\n const colGroup = document.createElement(\"colgroup\");\n for (const tableCell of node.children[0].children) {\n const colWidths: null | (number | undefined)[] =\n tableCell.attrs[\"colwidth\"];\n\n if (colWidths) {\n for (const colWidth of tableCell.attrs[\"colwidth\"]) {\n const col = document.createElement(\"col\");\n if (colWidth) {\n col.style = `width: ${colWidth}px`;\n }\n\n colGroup.appendChild(col);\n }\n } else {\n colGroup.appendChild(document.createElement(\"col\"));\n }\n }\n\n domOutputSpec.dom.firstChild?.appendChild(colGroup);\n\n return domOutputSpec;\n },\n\n // This node view is needed for the `columnResizing` plugin. By default, the\n // plugin adds its own node view, which overrides how the node is rendered vs\n // `renderHTML`. This means that the wrapping `blockContent` HTML element is\n // no longer rendered. The `columnResizing` plugin uses the `TableView` as its\n // default node view. `BlockNoteTableView` extends it by wrapping it in a\n // `blockContent` element, so the DOM structure is consistent with other block\n // types.\n addNodeView() {\n return ({ node, HTMLAttributes }) => {\n class BlockNoteTableView extends TableView {\n constructor(\n public node: PMNode,\n public cellMinWidth: number,\n public blockContentHTMLAttributes: Record<string, string>,\n ) {\n super(node, cellMinWidth);\n\n const blockContent = document.createElement(\"div\");\n blockContent.className = mergeCSSClasses(\n \"bn-block-content\",\n blockContentHTMLAttributes.class,\n );\n blockContent.setAttribute(\"data-content-type\", \"table\");\n for (const [attribute, value] of Object.entries(\n blockContentHTMLAttributes,\n )) {\n if (attribute !== \"class\") {\n blockContent.setAttribute(attribute, value);\n }\n }\n\n const tableWrapper = this.dom;\n\n const tableWrapperInner = document.createElement(\"div\");\n tableWrapperInner.className = \"tableWrapper-inner\";\n tableWrapperInner.appendChild(tableWrapper.firstChild!);\n\n tableWrapper.appendChild(tableWrapperInner);\n\n blockContent.appendChild(tableWrapper);\n const floatingContainer = document.createElement(\"div\");\n floatingContainer.className = \"table-widgets-container\";\n floatingContainer.style.position = \"relative\";\n tableWrapper.appendChild(floatingContainer);\n\n this.dom = blockContent;\n }\n\n ignoreMutation(record: MutationRecord): boolean {\n return (\n !(record.target as HTMLElement).closest(\".tableWrapper-inner\") ||\n super.ignoreMutation(record)\n );\n }\n }\n\n return new BlockNoteTableView(node, EMPTY_CELL_WIDTH, {\n ...(this.options.domAttributes?.blockContent || {}),\n ...HTMLAttributes,\n }) as NodeView; // needs cast, tiptap types (wrongly) doesn't support return tableview here\n };\n },\n});\n\nconst TiptapTableParagraph = Node.create({\n name: \"tableParagraph\",\n group: \"tableContent\",\n content: \"inline*\",\n\n parseHTML() {\n return [\n {\n tag: \"p\",\n getAttrs: (element) => {\n if (typeof element === \"string\" || !element.textContent) {\n return false;\n }\n\n // Only parse in internal HTML.\n if (!element.closest(\"[data-content-type]\")) {\n return false;\n }\n\n const parent = element.parentElement;\n\n if (parent === null) {\n return false;\n }\n\n if (parent.tagName === \"TD\" || parent.tagName === \"TH\") {\n return {};\n }\n\n return false;\n },\n node: \"tableParagraph\",\n },\n ];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\"p\", HTMLAttributes, 0];\n },\n});\n\n/**\n * This extension allows you to create table rows.\n * @see https://www.tiptap.dev/api/nodes/table-row\n */\nconst TiptapTableRow = Node.create<{\n HTMLAttributes: Record<string, any>;\n}>({\n name: \"tableRow\",\n\n addOptions() {\n return {\n HTMLAttributes: {},\n };\n },\n\n content: \"(tableCell | tableHeader)+\",\n\n tableRole: \"row\",\n marks: \"deletion insertion modification\",\n parseHTML() {\n return [{ tag: \"tr\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n return [\n \"tr\",\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes),\n 0,\n ];\n },\n});\n\n/*\n * This will flatten a node's content to fit into a table cell's paragraph.\n */\nfunction parseTableContent(node: HTMLElement, schema: Schema) {\n const parser = DOMParser.fromSchema(schema);\n\n // This will parse the content of the table paragraph as though it were a blockGroup.\n // Resulting in a structure like:\n // <blockGroup>\n // <blockContainer>\n // <p>Hello</p>\n // </blockContainer>\n // <blockContainer>\n // <p>Hello</p>\n // </blockContainer>\n // </blockGroup>\n const parsedContent = parser.parse(node, {\n topNode: schema.nodes.blockGroup.create(),\n });\n const extractedContent: PMNode[] = [];\n\n // Try to extract any content within the blockContainer.\n parsedContent.content.descendants((child) => {\n // As long as the child is an inline node, we can append it to the fragment.\n if (child.isInline) {\n // And append it to the fragment\n extractedContent.push(child);\n return false;\n }\n\n return undefined;\n });\n\n return Fragment.fromArray(extractedContent);\n}\n\nexport type TableBlockConfig = BlockConfig<\n \"table\",\n {\n textColor: {\n default: \"default\";\n };\n },\n \"table\"\n>;\n\nexport const createTableBlockSpec = () =>\n createBlockSpecFromTiptapNode(\n { node: TiptapTableNode, type: \"table\", content: \"table\" },\n tablePropSchema,\n [\n createBlockNoteExtension({\n key: \"table-extensions\",\n tiptapExtensions: [\n TableExtension,\n TiptapTableParagraph,\n TiptapTableHeader,\n TiptapTableCell,\n TiptapTableRow,\n ],\n }),\n ],\n );\n\n// We need to declare this here because we aren't using the table extensions from tiptap, so the types are not automatically inferred.\ndeclare module \"@tiptap/core\" {\n interface NodeConfig {\n tableRole?: string;\n }\n}\n","export const parseVideoElement = (videoElement: HTMLVideoElement) => {\n const url = videoElement.src || undefined;\n const previewWidth = videoElement.width || undefined;\n\n return { url, previewWidth };\n};\n","import { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\nimport { defaultProps, parseDefaultProps } from \"../defaultProps.js\";\nimport { parseFigureElement } from \"../File/helpers/parse/parseFigureElement.js\";\nimport { createResizableFileBlockWrapper } from \"../File/helpers/render/createResizableFileBlockWrapper.js\";\nimport { createFigureWithCaption } from \"../File/helpers/toExternalHTML/createFigureWithCaption.js\";\nimport { createLinkWithCaption } from \"../File/helpers/toExternalHTML/createLinkWithCaption.js\";\nimport { parseVideoElement } from \"./parseVideoElement.js\";\n\nexport const FILE_VIDEO_ICON_SVG =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M2 3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082C21.556 3 22 3.44495 22 3.9934V20.0066C22 20.5552 21.5447 21 21.0082 21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934ZM8 5V19H16V5H8ZM4 5V7H6V5H4ZM18 5V7H20V5H18ZM4 9V11H6V9H4ZM18 9V11H20V9H18ZM4 13V15H6V13H4ZM18 13V15H20V13H18ZM4 17V19H6V17H4ZM18 17V19H20V17H18Z\"></path></svg>';\n\nexport interface VideoOptions {\n icon?: string;\n}\n\nexport type VideoBlockConfig = ReturnType<typeof createVideoBlockConfig>;\n\nexport const createVideoBlockConfig = createBlockConfig(\n (_ctx: VideoOptions) => ({\n type: \"video\" as const,\n propSchema: {\n textAlignment: defaultProps.textAlignment,\n backgroundColor: defaultProps.backgroundColor,\n name: { default: \"\" as const },\n url: { default: \"\" as const },\n caption: { default: \"\" as const },\n showPreview: { default: true },\n previewWidth: { default: undefined, type: \"number\" as const },\n },\n content: \"none\" as const,\n }),\n);\n\nexport const videoParse = (_config: VideoOptions) => (element: HTMLElement) => {\n if (element.tagName === \"VIDEO\") {\n // Ignore if parent figure has already been parsed.\n if (element.closest(\"figure\")) {\n return undefined;\n }\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseVideoElement(element as HTMLVideoElement),\n backgroundColor,\n };\n }\n\n if (element.tagName === \"FIGURE\") {\n const parsedFigure = parseFigureElement(element, \"video\");\n if (!parsedFigure) {\n return undefined;\n }\n\n const { targetElement, caption } = parsedFigure;\n\n const { backgroundColor } = parseDefaultProps(element);\n\n return {\n ...parseVideoElement(targetElement as HTMLVideoElement),\n backgroundColor,\n caption,\n };\n }\n\n return undefined;\n};\n\nexport const createVideoBlockSpec = createBlockSpec(\n createVideoBlockConfig,\n (config) => ({\n meta: {\n fileBlockAccept: [\"video/*\"],\n },\n parse: videoParse(config),\n render(block, editor) {\n const icon = document.createElement(\"div\");\n icon.innerHTML = config.icon ?? FILE_VIDEO_ICON_SVG;\n\n const videoWrapper = document.createElement(\"div\");\n videoWrapper.className = \"bn-visual-media-wrapper\";\n\n const video = document.createElement(\"video\");\n video.className = \"bn-visual-media\";\n if (editor.resolveFileUrl) {\n editor.resolveFileUrl(block.props.url).then((downloadUrl) => {\n video.src = downloadUrl;\n });\n } else {\n video.src = block.props.url;\n }\n video.controls = true;\n video.contentEditable = \"false\";\n video.draggable = false;\n video.width = block.props.previewWidth;\n videoWrapper.appendChild(video);\n\n return createResizableFileBlockWrapper(\n block,\n editor,\n { dom: videoWrapper },\n videoWrapper,\n icon.firstElementChild as HTMLElement,\n );\n },\n toExternalHTML(block) {\n if (!block.props.url) {\n const div = document.createElement(\"p\");\n div.textContent = \"Add video\";\n\n return {\n dom: div,\n };\n }\n\n let video;\n if (block.props.showPreview) {\n video = document.createElement(\"video\");\n video.src = block.props.url;\n if (block.props.previewWidth) {\n video.width = block.props.previewWidth;\n }\n } else {\n video = document.createElement(\"a\");\n video.href = block.props.url;\n video.textContent = block.props.name || block.props.url;\n }\n\n if (block.props.caption) {\n if (block.props.showPreview) {\n return createFigureWithCaption(video, block.props.caption);\n } else {\n return createLinkWithCaption(video, block.props.caption);\n }\n }\n\n return {\n dom: video,\n };\n },\n runsBefore: [\"file\"],\n }),\n);\n","/**\n * Uploads a file to tmpfiles.org and returns the URL to the uploaded file.\n *\n * @warning This function should only be used for development purposes, replace with your own backend!\n */\nexport const uploadToTmpFilesDotOrg_DEV_ONLY = async (\n file: File,\n): Promise<string> => {\n const body = new FormData();\n body.append(\"file\", file);\n\n const ret = await fetch(\"https://tmpfiles.org/api/v1/upload\", {\n method: \"POST\",\n body: body,\n });\n return (await ret.json()).data.url.replace(\n \"tmpfiles.org/\",\n \"tmpfiles.org/dl/\",\n );\n};\n","import { CellSelection } from \"prosemirror-tables\";\nimport type { BlockNoteEditor } from \"../editor/BlockNoteEditor.js\";\nimport { BlockConfig, PropSchema, PropSpec } from \"../schema/index.js\";\nimport { Block } from \"./defaultBlocks.js\";\nimport { Selection } from \"prosemirror-state\";\n\nexport function editorHasBlockWithType<\n BType extends string,\n Props extends\n | PropSchema\n | Record<string, \"boolean\" | \"number\" | \"string\">\n | undefined = undefined,\n>(\n editor: BlockNoteEditor<any, any, any>,\n blockType: BType,\n props?: Props,\n): editor is BlockNoteEditor<\n {\n [BT in BType]: Props extends PropSchema\n ? BlockConfig<BT, Props>\n : Props extends Record<string, \"boolean\" | \"number\" | \"string\">\n ? BlockConfig<\n BT,\n {\n [PN in keyof Props]: {\n default: undefined;\n type: Props[PN];\n values?: any[];\n };\n }\n >\n : BlockConfig<BT, PropSchema>;\n },\n any,\n any\n> {\n if (!(blockType in editor.schema.blockSpecs)) {\n return false;\n }\n\n if (!props) {\n return true;\n }\n\n for (const [propName, propSpec] of Object.entries(props)) {\n if (!(propName in editor.schema.blockSpecs[blockType].config.propSchema)) {\n return false;\n }\n\n if (typeof propSpec === \"string\") {\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .default &&\n typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .default !== propSpec\n ) {\n return false;\n }\n\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName].type &&\n editor.schema.blockSpecs[blockType].config.propSchema[propName].type !==\n propSpec\n ) {\n return false;\n }\n } else {\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .default !== propSpec.default\n ) {\n return false;\n }\n\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .default === undefined &&\n propSpec.default === undefined\n ) {\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .type !== propSpec.type\n ) {\n return false;\n }\n }\n\n if (\n typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .values !== typeof propSpec.values\n ) {\n return false;\n }\n\n if (\n typeof editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .values === \"object\" &&\n typeof propSpec.values === \"object\"\n ) {\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName].values\n .length !== propSpec.values.length\n ) {\n return false;\n }\n\n for (\n let i = 0;\n i <\n editor.schema.blockSpecs[blockType].config.propSchema[propName].values\n .length;\n i++\n ) {\n if (\n editor.schema.blockSpecs[blockType].config.propSchema[propName]\n .values[i] !== propSpec.values[i]\n ) {\n return false;\n }\n }\n }\n }\n }\n\n return true;\n}\n\nexport function blockHasType<\n BType extends string,\n Props extends\n | PropSchema\n | Record<string, \"boolean\" | \"number\" | \"string\">\n | undefined = undefined,\n>(\n block: Block<any, any, any>,\n editor: BlockNoteEditor<any, any, any>,\n blockType: BType,\n props?: Props,\n): block is Block<\n {\n [BT in BType]: Props extends PropSchema\n ? BlockConfig<BT, Props>\n : Props extends Record<string, \"boolean\" | \"number\" | \"string\">\n ? BlockConfig<\n BT,\n {\n [PN in keyof Props]: PropSpec<\n Props[PN] extends \"boolean\"\n ? boolean\n : Props[PN] extends \"number\"\n ? number\n : Props[PN] extends \"string\"\n ? string\n : never\n >;\n }\n >\n : BlockConfig<BT, PropSchema>;\n },\n any,\n any\n> {\n return (\n editorHasBlockWithType(editor, blockType, props) && block.type === blockType\n );\n}\n\nexport function isTableCellSelection(\n selection: Selection,\n): selection is CellSelection {\n return selection instanceof CellSelection;\n}\n","import { Block, PartialBlock } from \"../../blocks/defaultBlocks.js\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\n\nimport { editorHasBlockWithType } from \"../../blocks/defaultBlockTypeGuards.js\";\nimport {\n BlockSchema,\n InlineContentSchema,\n StyleSchema,\n isStyledTextInlineContent,\n} from \"../../schema/index.js\";\nimport { formatKeyboardShortcut } from \"../../util/browser.js\";\nimport { DefaultSuggestionItem } from \"./DefaultSuggestionItem.js\";\n\n// Sets the editor's text cursor position to the next content editable block,\n// so either a block with inline content or a table. The last block is always a\n// paragraph, so this function won't try to set the cursor position past the\n// last block.\nfunction setSelectionToNextContentEditableBlock<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(editor: BlockNoteEditor<BSchema, I, S>) {\n let block: Block<BSchema, I, S> | undefined =\n editor.getTextCursorPosition().block;\n let contentType = editor.schema.blockSchema[block.type].content;\n\n while (contentType === \"none\") {\n block = editor.getTextCursorPosition().nextBlock;\n if (block === undefined) {\n return;\n }\n contentType = editor.schema.blockSchema[block.type].content as\n | \"inline\"\n | \"table\"\n | \"none\";\n editor.setTextCursorPosition(block, \"end\");\n }\n}\n\n// Checks if the current block is empty or only contains a slash, and if so,\n// updates the current block instead of inserting a new one below. If the new\n// block doesn't contain editable content, the cursor is moved to the next block\n// that does.\nexport function insertOrUpdateBlock<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n editor: BlockNoteEditor<BSchema, I, S>,\n block: PartialBlock<BSchema, I, S>,\n): Block<BSchema, I, S> {\n const currentBlock = editor.getTextCursorPosition().block;\n\n if (currentBlock.content === undefined) {\n throw new Error(\"Slash Menu open in a block that doesn't contain content.\");\n }\n\n let newBlock: Block<BSchema, I, S>;\n\n if (\n Array.isArray(currentBlock.content) &&\n ((currentBlock.content.length === 1 &&\n isStyledTextInlineContent(currentBlock.content[0]) &&\n currentBlock.content[0].type === \"text\" &&\n currentBlock.content[0].text === \"/\") ||\n currentBlock.content.length === 0)\n ) {\n newBlock = editor.updateBlock(currentBlock, block);\n // We make sure to reset the cursor position to the new block as calling\n // `updateBlock` may move it out. This generally happens when the content\n // changes, or the update makes the block multi-column.\n editor.setTextCursorPosition(newBlock);\n } else {\n newBlock = editor.insertBlocks([block], currentBlock, \"after\")[0];\n editor.setTextCursorPosition(editor.getTextCursorPosition().nextBlock!);\n }\n\n setSelectionToNextContentEditableBlock(editor);\n\n return newBlock;\n}\n\nexport function getDefaultSlashMenuItems<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(editor: BlockNoteEditor<BSchema, I, S>) {\n const items: DefaultSuggestionItem[] = [];\n\n if (editorHasBlockWithType(editor, \"heading\", { level: \"number\" })) {\n items.push(\n {\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: 1 },\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Alt-1\"),\n key: \"heading\",\n ...editor.dictionary.slash_menu.heading,\n },\n {\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: 2 },\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Alt-2\"),\n key: \"heading_2\",\n ...editor.dictionary.slash_menu.heading_2,\n },\n {\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: 3 },\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Alt-3\"),\n key: \"heading_3\",\n ...editor.dictionary.slash_menu.heading_3,\n },\n );\n }\n\n if (editorHasBlockWithType(editor, \"quote\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"quote\",\n });\n },\n key: \"quote\",\n ...editor.dictionary.slash_menu.quote,\n });\n }\n\n if (editorHasBlockWithType(editor, \"toggleListItem\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"toggleListItem\",\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Shift-6\"),\n key: \"toggle_list\",\n ...editor.dictionary.slash_menu.toggle_list,\n });\n }\n\n if (editorHasBlockWithType(editor, \"numberedListItem\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"numberedListItem\",\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Shift-7\"),\n key: \"numbered_list\",\n ...editor.dictionary.slash_menu.numbered_list,\n });\n }\n\n if (editorHasBlockWithType(editor, \"bulletListItem\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"bulletListItem\",\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Shift-8\"),\n key: \"bullet_list\",\n ...editor.dictionary.slash_menu.bullet_list,\n });\n }\n\n if (editorHasBlockWithType(editor, \"checkListItem\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"checkListItem\",\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Shift-9\"),\n key: \"check_list\",\n ...editor.dictionary.slash_menu.check_list,\n });\n }\n\n if (editorHasBlockWithType(editor, \"paragraph\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"paragraph\",\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Alt-0\"),\n key: \"paragraph\",\n ...editor.dictionary.slash_menu.paragraph,\n });\n }\n\n if (editorHasBlockWithType(editor, \"codeBlock\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"codeBlock\",\n });\n },\n badge: formatKeyboardShortcut(\"Mod-Alt-c\"),\n key: \"code_block\",\n ...editor.dictionary.slash_menu.code_block,\n });\n }\n\n if (editorHasBlockWithType(editor, \"table\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"table\",\n content: {\n type: \"tableContent\",\n rows: [\n {\n cells: [\"\", \"\", \"\"],\n },\n {\n cells: [\"\", \"\", \"\"],\n },\n ],\n } as any,\n });\n },\n badge: undefined,\n key: \"table\",\n ...editor.dictionary.slash_menu.table,\n });\n }\n\n if (editorHasBlockWithType(editor, \"image\", { url: \"string\" })) {\n items.push({\n onItemClick: () => {\n const insertedBlock = insertOrUpdateBlock(editor, {\n type: \"image\",\n });\n\n // Immediately open the file toolbar\n editor.transact((tr) =>\n tr.setMeta(editor.filePanel!.plugins[0], {\n block: insertedBlock,\n }),\n );\n },\n key: \"image\",\n ...editor.dictionary.slash_menu.image,\n });\n }\n\n if (editorHasBlockWithType(editor, \"video\", { url: \"string\" })) {\n items.push({\n onItemClick: () => {\n const insertedBlock = insertOrUpdateBlock(editor, {\n type: \"video\",\n });\n\n // Immediately open the file toolbar\n editor.transact((tr) =>\n tr.setMeta(editor.filePanel!.plugins[0], {\n block: insertedBlock,\n }),\n );\n },\n key: \"video\",\n ...editor.dictionary.slash_menu.video,\n });\n }\n\n if (editorHasBlockWithType(editor, \"audio\", { url: \"string\" })) {\n items.push({\n onItemClick: () => {\n const insertedBlock = insertOrUpdateBlock(editor, {\n type: \"audio\",\n });\n\n // Immediately open the file toolbar\n editor.transact((tr) =>\n tr.setMeta(editor.filePanel!.plugins[0], {\n block: insertedBlock,\n }),\n );\n },\n key: \"audio\",\n ...editor.dictionary.slash_menu.audio,\n });\n }\n\n if (editorHasBlockWithType(editor, \"file\", { url: \"string\" })) {\n items.push({\n onItemClick: () => {\n const insertedBlock = insertOrUpdateBlock(editor, {\n type: \"file\",\n });\n\n // Immediately open the file toolbar\n editor.transact((tr) =>\n tr.setMeta(editor.filePanel!.plugins[0], {\n block: insertedBlock,\n }),\n );\n },\n key: \"file\",\n ...editor.dictionary.slash_menu.file,\n });\n }\n\n if (\n editorHasBlockWithType(editor, \"heading\", {\n level: \"number\",\n isToggleable: \"boolean\",\n })\n ) {\n items.push(\n {\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: 1, isToggleable: true },\n });\n },\n key: \"toggle_heading\",\n ...editor.dictionary.slash_menu.toggle_heading,\n },\n {\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: 2, isToggleable: true },\n });\n },\n\n key: \"toggle_heading_2\",\n ...editor.dictionary.slash_menu.toggle_heading_2,\n },\n {\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: 3, isToggleable: true },\n });\n },\n key: \"toggle_heading_3\",\n ...editor.dictionary.slash_menu.toggle_heading_3,\n },\n );\n }\n\n if (editorHasBlockWithType(editor, \"heading\", { level: \"number\" })) {\n (editor.schema.blockSchema.heading.propSchema.level.values || [])\n .filter((level): level is 4 | 5 | 6 => level > 3)\n .forEach((level) => {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"heading\",\n props: { level: level },\n });\n },\n key: `heading_${level}`,\n ...editor.dictionary.slash_menu[`heading_${level}`],\n });\n });\n }\n\n items.push({\n onItemClick: () => {\n editor.openSuggestionMenu(\":\", {\n deleteTriggerCharacter: true,\n ignoreQueryLength: true,\n });\n },\n key: \"emoji\",\n ...editor.dictionary.slash_menu.emoji,\n });\n\n return items;\n}\n\nexport function filterSuggestionItems<\n T extends { title: string; aliases?: readonly string[] },\n>(items: T[], query: string) {\n return items.filter(\n ({ title, aliases }) =>\n title.toLowerCase().includes(query.toLowerCase()) ||\n (aliases &&\n aliases.filter((alias) =>\n alias.toLowerCase().includes(query.toLowerCase()),\n ).length !== 0),\n );\n}\n","import { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport { DefaultSuggestionItem } from \"../../extensions/SuggestionMenu/DefaultSuggestionItem.js\";\nimport { insertOrUpdateBlock } from \"../../extensions/SuggestionMenu/getDefaultSlashMenuItems.js\";\nimport {\n BlockSchema,\n InlineContentSchema,\n StyleSchema,\n} from \"../../schema/index.js\";\nimport { createPageBreakBlockConfig } from \"./block.js\";\n\nexport function checkPageBreakBlocksInSchema<\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(\n editor: BlockNoteEditor<any, I, S>,\n): editor is BlockNoteEditor<\n {\n pageBreak: ReturnType<typeof createPageBreakBlockConfig>;\n },\n I,\n S\n> {\n return \"pageBreak\" in editor.schema.blockSchema;\n}\n\nexport function getPageBreakSlashMenuItems<\n BSchema extends BlockSchema,\n I extends InlineContentSchema,\n S extends StyleSchema,\n>(editor: BlockNoteEditor<BSchema, I, S>) {\n const items: (Omit<DefaultSuggestionItem, \"key\"> & { key: \"page_break\" })[] =\n [];\n\n if (checkPageBreakBlocksInSchema(editor)) {\n items.push({\n ...editor.dictionary.slash_menu.page_break,\n onItemClick: () => {\n insertOrUpdateBlock(editor, {\n type: \"pageBreak\",\n });\n },\n key: \"page_break\",\n });\n }\n\n return items;\n}\n","import Bold from \"@tiptap/extension-bold\";\nimport Code from \"@tiptap/extension-code\";\nimport Italic from \"@tiptap/extension-italic\";\nimport Strike from \"@tiptap/extension-strike\";\nimport Underline from \"@tiptap/extension-underline\";\nimport {\n createAudioBlockSpec,\n createBulletListItemBlockSpec,\n createCheckListItemBlockSpec,\n createCodeBlockSpec,\n createFileBlockSpec,\n createHeadingBlockSpec,\n createImageBlockSpec,\n createNumberedListItemBlockSpec,\n createParagraphBlockSpec,\n createQuoteBlockSpec,\n createToggleListItemBlockSpec,\n createVideoBlockSpec,\n defaultProps,\n} from \"./index.js\";\nimport {\n BlockNoDefaults,\n BlockSchema,\n InlineContentSchema,\n InlineContentSpecs,\n PartialBlockNoDefaults,\n StyleSchema,\n StyleSpecs,\n createStyleSpec,\n createStyleSpecFromTipTapMark,\n getInlineContentSchemaFromSpecs,\n getStyleSchemaFromSpecs,\n} from \"../schema/index.js\";\nimport { createTableBlockSpec } from \"./Table/block.js\";\nimport { COLORS_DEFAULT } from \"../editor/defaultColors.js\";\n\nexport const defaultBlockSpecs = {\n audio: createAudioBlockSpec(),\n bulletListItem: createBulletListItemBlockSpec(),\n checkListItem: createCheckListItemBlockSpec(),\n codeBlock: createCodeBlockSpec(),\n file: createFileBlockSpec(),\n heading: createHeadingBlockSpec(),\n image: createImageBlockSpec(),\n numberedListItem: createNumberedListItemBlockSpec(),\n paragraph: createParagraphBlockSpec(),\n quote: createQuoteBlockSpec(),\n table: createTableBlockSpec(),\n toggleListItem: createToggleListItemBlockSpec(),\n video: createVideoBlockSpec(),\n} as const;\n\n// underscore is used that in case a user overrides DefaultBlockSchema,\n// they can still access the original default block schema\nexport type _DefaultBlockSchema = {\n [K in keyof typeof defaultBlockSpecs]: (typeof defaultBlockSpecs)[K][\"config\"];\n};\nexport type DefaultBlockSchema = _DefaultBlockSchema;\n\nconst TextColor = createStyleSpec(\n {\n type: \"textColor\",\n propSchema: \"string\",\n },\n {\n render: () => {\n const span = document.createElement(\"span\");\n\n return {\n dom: span,\n contentDOM: span,\n };\n },\n toExternalHTML: (value) => {\n const span = document.createElement(\"span\");\n if (value !== defaultProps.textColor.default) {\n span.style.color =\n value in COLORS_DEFAULT ? COLORS_DEFAULT[value].text : value;\n }\n\n return {\n dom: span,\n contentDOM: span,\n };\n },\n parse: (element) => {\n if (element.tagName === \"SPAN\" && element.style.color) {\n return element.style.color;\n }\n\n return undefined;\n },\n },\n);\n\nconst BackgroundColor = createStyleSpec(\n {\n type: \"backgroundColor\",\n propSchema: \"string\",\n },\n {\n render: () => {\n const span = document.createElement(\"span\");\n\n return {\n dom: span,\n contentDOM: span,\n };\n },\n toExternalHTML: (value) => {\n const span = document.createElement(\"span\");\n if (value !== defaultProps.backgroundColor.default) {\n span.style.backgroundColor =\n value in COLORS_DEFAULT ? COLORS_DEFAULT[value].background : value;\n }\n\n return {\n dom: span,\n contentDOM: span,\n };\n },\n parse: (element) => {\n if (element.tagName === \"SPAN\" && element.style.backgroundColor) {\n return element.style.backgroundColor;\n }\n\n return undefined;\n },\n },\n);\n\nexport const defaultStyleSpecs = {\n bold: createStyleSpecFromTipTapMark(Bold, \"boolean\"),\n italic: createStyleSpecFromTipTapMark(Italic, \"boolean\"),\n underline: createStyleSpecFromTipTapMark(Underline, \"boolean\"),\n strike: createStyleSpecFromTipTapMark(Strike, \"boolean\"),\n code: createStyleSpecFromTipTapMark(Code, \"boolean\"),\n textColor: TextColor,\n backgroundColor: BackgroundColor,\n} satisfies StyleSpecs;\n\nexport const defaultStyleSchema = getStyleSchemaFromSpecs(defaultStyleSpecs);\n\n// underscore is used that in case a user overrides DefaultStyleSchema,\n// they can still access the original default style schema\nexport type _DefaultStyleSchema = typeof defaultStyleSchema;\nexport type DefaultStyleSchema = _DefaultStyleSchema;\n\nexport const defaultInlineContentSpecs = {\n text: { config: \"text\", implementation: {} as any },\n link: { config: \"link\", implementation: {} as any },\n} satisfies InlineContentSpecs;\n\nexport const defaultInlineContentSchema = getInlineContentSchemaFromSpecs(\n defaultInlineContentSpecs,\n);\n\n// underscore is used that in case a user overrides DefaultInlineContentSchema,\n// they can still access the original default inline content schema\nexport type _DefaultInlineContentSchema = typeof defaultInlineContentSchema;\nexport type DefaultInlineContentSchema = _DefaultInlineContentSchema;\n\nexport type PartialBlock<\n BSchema extends BlockSchema = DefaultBlockSchema,\n I extends InlineContentSchema = DefaultInlineContentSchema,\n S extends StyleSchema = DefaultStyleSchema,\n> = PartialBlockNoDefaults<BSchema, I, S>;\n\nexport type Block<\n BSchema extends BlockSchema = DefaultBlockSchema,\n I extends InlineContentSchema = DefaultInlineContentSchema,\n S extends StyleSchema = DefaultStyleSchema,\n> = BlockNoDefaults<BSchema, I, S>;\n","import {\n BlockSchema,\n BlockSchemaFromSpecs,\n BlockSpecs,\n CustomBlockNoteSchema,\n InlineContentSchema,\n InlineContentSchemaFromSpecs,\n InlineContentSpecs,\n StyleSchema,\n StyleSchemaFromSpecs,\n StyleSpecs,\n} from \"../schema/index.js\";\nimport {\n defaultBlockSpecs,\n defaultInlineContentSpecs,\n defaultStyleSpecs,\n} from \"./defaultBlocks.js\";\n\nexport class BlockNoteSchema<\n BSchema extends BlockSchema,\n ISchema extends InlineContentSchema,\n SSchema extends StyleSchema,\n> extends CustomBlockNoteSchema<BSchema, ISchema, SSchema> {\n public static create<\n BSpecs extends BlockSpecs | undefined = undefined,\n ISpecs extends InlineContentSpecs | undefined = undefined,\n SSpecs extends StyleSpecs | undefined = undefined,\n >(options?: {\n /**\n * A list of custom block types that should be available in the editor.\n */\n blockSpecs?: BSpecs;\n /**\n * A list of custom InlineContent types that should be available in the editor.\n */\n inlineContentSpecs?: ISpecs;\n /**\n * A list of custom Styles that should be available in the editor.\n */\n styleSpecs?: SSpecs;\n }): BlockNoteSchema<\n BSpecs extends undefined\n ? BlockSchemaFromSpecs<typeof defaultBlockSpecs>\n : BlockSchemaFromSpecs<NonNullable<BSpecs>>,\n ISpecs extends undefined\n ? InlineContentSchemaFromSpecs<typeof defaultInlineContentSpecs>\n : InlineContentSchemaFromSpecs<NonNullable<ISpecs>>,\n SSpecs extends undefined\n ? StyleSchemaFromSpecs<typeof defaultStyleSpecs>\n : StyleSchemaFromSpecs<NonNullable<SSpecs>>\n > {\n return new BlockNoteSchema<any, any, any>({\n blockSpecs: options?.blockSpecs ?? defaultBlockSpecs,\n inlineContentSpecs:\n options?.inlineContentSpecs ?? defaultInlineContentSpecs,\n styleSpecs: options?.styleSpecs ?? defaultStyleSpecs,\n });\n }\n}\n"],"names":["removeDuplicates","array","by","seen","item","key","findDuplicates","items","filtered","el","index","UniqueID","Extension","testOptions","v4","element","attributes","defaultIdAttributes","dragSourceElement","transformPasted","Plugin","PluginKey","transactions","oldState","newState","docChanges","transaction","filterTransactions","tr","_b","_a","types","attributeName","generateID","transform","combineTransactionSteps","mapping","getChangedRanges","newRange","newNodes","findChildrenInRange","node","newIds","id","duplicatedNewIds","pos","initialDoc","jsonNode","deleted","view","handleDragstart","event","slice","removeId","fragment","list","nodeWithoutId","Fragment","Slice","isLinkInlineContent","content","isPartialLinkInlineContent","isStyledTextInlineContent","mapTableCell","isTableCell","isPartialTableCell","_c","_d","_e","getColspan","cell","getRowspan","UnreachableCaseError","val","assertEmpty","obj","throwError","dataTest","rest","isAppleOS","formatKeyboardShortcut","shortcut","ctrlText","mergeCSSClasses","classes","c","isSafari","createDefaultBlockDOMOutputSpec","blockName","htmlTag","blockContentHTMLAttributes","inlineContentHTMLAttributes","blockContent","attribute","value","inlineContent","defaultBlockToHTML","block","editor","blockToNode","toDOM","renderSpec","mergeParagraphs","separator","paragraphs","firstParagraph","i","paragraph","camelToDataKebab","str","filenameFromURL","url","parts","propsToAttributes","propSchema","tiptapAttributes","name","spec","asNumber","getBlockFromPos","getPos","tipTapEditor","type","blockIdentifier","wrapInBlockStructure","blockType","blockProps","isFileBlock","domAttributes","attr","prop","defaultValue","createBlockSpecFromTiptapNode","config","extensions","applyNonSelectableBlockFix","nodeView","getParseRules","implementation","rules","props","schema","clone","DOMParser","addNodeAndExtensionsToSpec","blockConfig","blockImplementation","priority","Node","HTMLAttributes","div","blockContentDOMAttributes","createBlockConfig","callback","createBlockSpec","blockConfigOrCreator","blockImplementationOrCreator","extensionsOrCreator","options","output","getNearestBlockPos","doc","$pos","depth","allBlockContainerPositions","resolvedPos","position","getBlockInfoWithManualOffset","bnBlockBeforePosOffset","bnBlockNode","bnBlockBeforePos","bnBlockAfterPos","bnBlock","blockGroup","offset","blockContentNode","blockContentBeforePos","blockContentAfterPos","blockGroupNode","blockGroupBeforePos","blockGroupAfterPos","getBlockInfo","posInfo","getBlockInfoFromResolvedPos","getBlockInfoFromSelection","state","getBlockInfoFromTransaction","getPmSchema","trOrNode","getBlockNoteEditor","getBlockNoteSchema","getBlockSchema","getInlineContentSchema","getStyleSchema","getBlockCache","contentNodeToTableContent","contentNode","inlineContentSchema","styleSchema","ret","headerMatrix","rowNode","_offset","rowIndex","row","cellNode","colWidth","cellIndex","child","contentNodeToInlineContent","acc","contentPartial","last","first","isHeader","currentContent","nodeToCustomInlineContent","styles","linkMark","mark","icConfig","nodeToBlock","blockSchema","blockCache","cachedBlock","blockInfo","blockSpec","children","docToBlocks","blocks","prosemirrorSliceToSlicedBlocks","processNode","openStart","openEnd","blockCutAtStart","blockCutAtEnd","blockContainer","isFirstBlock","isLastBlock","childGroup","childBlocks","addInlineContentAttributes","inlineContentType","inlineContentProps","addInlineContentKeyboardShortcuts","createInternalInlineContentSpec","createInlineContentSpecFromTipTapNode","getInlineContentSchemaFromSpecs","specs","stylePropsToAttributes","addStyleAttributes","styleType","styleValue","createInternalStyleSpec","createStyleSpecFromTipTapMark","markInstance","DOMSerializer","getStyleSchemaFromSpecs","getStyleParseRules","customParseFunction","htmlElement","stringValue","createStyleSpec","styleConfig","styleImplementation","Mark","renderResult","toposort","dag","inDegrees","countInDegrees","roots","nonRoots","getRootsAndNonRoots","sorted","newRoots","root","dependents","dependent","currentDegree","newDegree","toposortReverse","deps","reverse","counts","vx","currentCount","deg","reversedDeps","dependsOn","dependsOnName","createDependencyGraph","removeUndefined","CustomBlockNoteSchema","opts","__publicField","blockSpecs","inlineContentSpecs","styleSpecs","defaultSet","specDef","sortedSpecs","defaultIndex","set","getPriority","blockDef","getTableCellOccupancyGrid","height","width","getDimensionsOfTable","grid","findNextAvailable","col","j","rowspan","colspan","startRow","startCol","getTableRowsFromOccupancyGrid","occupancyGrid","getAbsoluteTableCells","relativeCellIndices","r","rowWidth","getRelativeTableCells","absoluteCellIndices","occupancyCell","getCellsAtRowHandle","relativeRowIndex","absoluteRow","cells","_v","getCellsAtColumnHandle","relativeColumnIndex","absoluteCol","moveColumn","fromColIndex","toColIndex","absoluteSourceCol","absoluteTargetCol","sourceCell","moveRow","fromRowIndex","toRowIndex","absoluteSourceRow","absoluteTargetRow","sourceRow","isCellEmpty","s","cropEmptyRowsOrColumns","removeEmpty","emptyColsOnRight","cellsToRemove","emptyRowsOnBottom","rowsToRemove","addRowsOrColumns","addType","numToAdd","newRow","_","colIndex","canRowBeDraggedInto","draggingIndex","targetRowIndex","targetCells","endRowIndex","startRowIndex","canColumnBeDraggedInto","targetColumnIndex","endColumnIndex","startColumnIndex","areInSameColumn","from","to","anchorAbsoluteCellIndices","headAbsoluteCellIndices","styledTextToNodes","styledText","marks","style","text","linkToNodes","link","styledTextArrayToNodes","nodes","inlineContentToNodes","blockOrInlineContentToContentNode","tableContentToNodes","tableContent","rowNodes","headerRows","headerCols","columnWidths","columnNodes","isHeaderRow","isHeaderCol","attrs","absoluteCellIndex","colwidth","groupNode","getNodeById","targetNode","posBeforeNode","isNodeBlock","updateBlockCommand","posBeforeBlock","dispatch","updateBlockTr","replaceFromPos","replaceToPos","cellAnchor","captureCellAnchor","pmSchema","oldNodeType","newNodeType","newBnBlockNodeType","replaceFromOffset","replaceToOffset","updateChildren","updateBlockContentNode","existingBlock","restoreCellAnchor","start","end","contentDepth","startDepth","endDepth","childNodes","ReplaceStep","updateBlock","blockToUpdate","update","blockContainerNode","sel","TextSelection","$head","cellDepth","tableDepth","d","cellPos","tablePos","table","map","TableMap","rel","idx","textStart","a","relCellPos","textPos","textNode","max","head","COLORS_DEFAULT","COLORS_DARK_MODE_DEFAULT","defaultProps","parseDefaultProps","addDefaultPropsExternalHTML","getBackgroundColorAttribute","getTextColorAttribute","getTextAlignmentAttribute","parseFigureElement","figureElement","targetTag","targetElement","captionElement","caption","createAddFileButton","buttonIcon","addFileButton","addFileButtonIcon","addFileButtonText","addFileButtonMouseDownHandler","addFileButtonClickHandler","FILE_ICON_SVG","createFileNameWithIcon","file","icon","fileName","createFileBlockWrapper","wrapper","destroyUploadStartHandler","blockId","loading","fileNameWithIcon","createFigureWithCaption","figure","createLinkWithCaption","fileCaption","parseAudioElement","audioElement","FILE_AUDIO_ICON_SVG","createAudioBlockConfig","_ctx","audioParse","_config","backgroundColor","parsedFigure","audioRender","audio","downloadUrl","audioToExternalHTML","_editor","createAudioBlockSpec","EventEmitter","fn","args","callbacks","BlockNoteExtension","_args","plugin","createBlockNoteExtension","x","createCodeBlockConfig","defaultLanguage","createCodeBlockSpec","e","code","parser","pre","removeSelectChangeListener","select","handleLanguageChange","language","selectWrapper","option","$from","nextBlock","isAtEnd","endsWithDoubleNewline","newBlock","match","languageName","getLanguageId","aliases","parseEmbedElement","embedElement","createFileBlockConfig","fileParse","createFileBlockSpec","fileSrcLink","defaultToggledState","isToggled","createToggleWrapper","renderedElement","toggledState","dom","toggleWrapper","toggleButton","toggleButtonMouseDown","toggleButtonOnClick","toggleAddBlockButton","toggleAddBlockButtonMouseDown","toggleAddBlockButtonOnClick","updatedBlock","childCount","onEditorChange","newChildCount","mutation","HEADING_LEVELS","createHeadingBlockConfig","defaultLevel","levels","allowToggleHeadings","createHeadingBlockSpec","level","cursorPosition","createResizableFileBlockWrapper","resizeHandlesContainerElement","destroy","leftResizeHandle","rightResizeHandle","eventCaptureElement","resizeParams","windowMouseMoveHandler","newWidth","clientX","windowMouseUpHandler","wrapperMouseEnterHandler","wrapperMouseLeaveHandler","leftResizeHandleMouseDownHandler","rightResizeHandleMouseDownHandler","parseImageElement","imageElement","previewWidth","FILE_IMAGE_ICON_SVG","createImageBlockConfig","imageParse","imageRender","imageWrapper","image","imageToExternalHTML","createImageBlockSpec","splitBlockCommand","posInBlock","keepType","keepProps","splitBlockTr","nearestBlockContainerPos","info","handleEnter","listItemType","selectionEmpty","getListItemContent","_node","clonedNodeDiv","listItemsFirstChild","listItemNode","remainingListItemChildren","listItemsChildren","createBulletListItemBlockConfig","createBulletListItemBlockSpec","parent","li","p","createCheckListItemConfig","createCheckListItemBlockSpec","checkbox","calculateListItemIndex","isFirst","hasStart","prevBlock","prevBlockIndex","getDecorations","previousPluginState","nextDecorationSet","decorationsToAdd","deco","Decoration","decorationsToRemove","NumberedListIndexingDecorationPlugin","DecorationSet","createNumberedListItemBlockConfig","createNumberedListItemBlockSpec","startIndex","createToggleListItemBlockConfig","createToggleListItemBlockSpec","paragraphEl","createPageBreakBlockConfig","createPageBreakBlockSpec","pageBreak","withPageBreak","createParagraphBlockConfig","createParagraphBlockSpec","createQuoteBlockConfig","createQuoteBlockSpec","textColor","quote","RESIZE_MIN_WIDTH","EMPTY_CELL_WIDTH","EMPTY_CELL_HEIGHT","TableExtension","columnResizing","tableEditing","selection","selectionIsEmpty","selectionIsAtStartOfNode","selectionIsInTableParagraphNode","goToNextCell","extension","context","callOrReturn","getExtensionField","tablePropSchema","TiptapTableHeader","parseTableContent","mergeAttributes","TiptapTableCell","TiptapTableNode","domOutputSpec","colGroup","tableCell","BlockNoteTableView","TableView","cellMinWidth","tableWrapper","tableWrapperInner","floatingContainer","record","TiptapTableParagraph","TiptapTableRow","parsedContent","extractedContent","createTableBlockSpec","parseVideoElement","videoElement","FILE_VIDEO_ICON_SVG","createVideoBlockConfig","videoParse","createVideoBlockSpec","videoWrapper","video","uploadToTmpFilesDotOrg_DEV_ONLY","body","editorHasBlockWithType","propName","propSpec","blockHasType","isTableCellSelection","CellSelection","setSelectionToNextContentEditableBlock","contentType","insertOrUpdateBlock","currentBlock","getDefaultSlashMenuItems","insertedBlock","filterSuggestionItems","query","title","alias","checkPageBreakBlocksInSchema","getPageBreakSlashMenuItems","defaultBlockSpecs","TextColor","span","BackgroundColor","defaultStyleSpecs","Bold","Italic","Underline","Strike","Code","defaultStyleSchema","defaultInlineContentSpecs","defaultInlineContentSchema","BlockNoteSchema"],"mappings":"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"}
|