@blocknote/core 0.42.3 → 0.44.0

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.
Files changed (200) hide show
  1. package/dist/BlockNoteExtension-BWw0r8Gy.cjs +2 -0
  2. package/dist/BlockNoteExtension-BWw0r8Gy.cjs.map +1 -0
  3. package/dist/BlockNoteExtension-C2X7LW-V.js +25 -0
  4. package/dist/BlockNoteExtension-C2X7LW-V.js.map +1 -0
  5. package/dist/BlockNoteSchema-B4gm-Qco.cjs +2 -0
  6. package/dist/BlockNoteSchema-B4gm-Qco.cjs.map +1 -0
  7. package/dist/BlockNoteSchema-C-l154WP.js +270 -0
  8. package/dist/BlockNoteSchema-C-l154WP.js.map +1 -0
  9. package/dist/EventEmitter-CLwfmbqG.cjs +2 -0
  10. package/dist/EventEmitter-CLwfmbqG.cjs.map +1 -0
  11. package/dist/EventEmitter-CjSwpTbz.js +27 -0
  12. package/dist/EventEmitter-CjSwpTbz.js.map +1 -0
  13. package/dist/ShowSelection-BW37oJ6h.cjs +2 -0
  14. package/dist/ShowSelection-BW37oJ6h.cjs.map +1 -0
  15. package/dist/ShowSelection-Dz-NEase.js +43 -0
  16. package/dist/ShowSelection-Dz-NEase.js.map +1 -0
  17. package/dist/TrailingNode-B_zPMWxw.js +2098 -0
  18. package/dist/TrailingNode-B_zPMWxw.js.map +1 -0
  19. package/dist/TrailingNode-CRHrgOnK.cjs +2 -0
  20. package/dist/TrailingNode-CRHrgOnK.cjs.map +1 -0
  21. package/dist/{blockToNode-DIfPWLH8.js → blockToNode-DBNbhwwC.js} +33 -33
  22. package/dist/blockToNode-DBNbhwwC.js.map +1 -0
  23. package/dist/blockToNode-w7H99R6p.cjs.map +1 -1
  24. package/dist/blocknote.cjs +4 -4
  25. package/dist/blocknote.cjs.map +1 -1
  26. package/dist/blocknote.js +2496 -5686
  27. package/dist/blocknote.js.map +1 -1
  28. package/dist/blocks.cjs +1 -1
  29. package/dist/blocks.js +71 -70
  30. package/dist/blocks.js.map +1 -1
  31. package/dist/comments.cjs +1 -1
  32. package/dist/comments.cjs.map +1 -1
  33. package/dist/comments.js +451 -137
  34. package/dist/comments.js.map +1 -1
  35. package/dist/defaultBlocks-DLJ4Q1_J.cjs +6 -0
  36. package/dist/defaultBlocks-DLJ4Q1_J.cjs.map +1 -0
  37. package/dist/{BlockNoteSchema-Bi-eeHal.js → defaultBlocks-DgA_mtQV.js} +974 -1027
  38. package/dist/defaultBlocks-DgA_mtQV.js.map +1 -0
  39. package/dist/extensions.cjs +2 -0
  40. package/dist/extensions.cjs.map +1 -0
  41. package/dist/extensions.js +57 -0
  42. package/dist/extensions.js.map +1 -0
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/dist/webpack-stats.json +1 -1
  45. package/dist/yjs.js +1 -1
  46. package/package.json +9 -3
  47. package/src/api/nodeConversions/blockToNode.ts +1 -1
  48. package/src/api/nodeConversions/nodeToBlock.ts +1 -1
  49. package/src/blocks/Code/block.ts +4 -4
  50. package/src/blocks/Divider/block.ts +2 -2
  51. package/src/blocks/File/helpers/render/createAddFileButton.ts +7 -5
  52. package/src/blocks/Heading/block.ts +23 -20
  53. package/src/blocks/ListItem/BulletListItem/block.ts +2 -2
  54. package/src/blocks/ListItem/CheckListItem/block.ts +2 -2
  55. package/src/blocks/ListItem/NumberedListItem/block.ts +3 -3
  56. package/src/blocks/ListItem/ToggleListItem/block.ts +2 -2
  57. package/src/blocks/PageBreak/getPageBreakSlashMenuItems.ts +2 -2
  58. package/src/blocks/Paragraph/block.ts +2 -2
  59. package/src/blocks/Quote/block.ts +2 -2
  60. package/src/blocks/Table/block.ts +4 -3
  61. package/src/blocks/ToggleWrapper/createToggleWrapper.ts +2 -1
  62. package/src/comments/extension.ts +353 -0
  63. package/src/comments/index.ts +2 -1
  64. package/src/comments/types.ts +8 -0
  65. package/src/{extensions/Comments → comments}/userstore/UserStore.ts +2 -2
  66. package/src/editor/BlockNoteEditor.test.ts +2 -23
  67. package/src/editor/BlockNoteEditor.ts +60 -453
  68. package/src/editor/BlockNoteExtension.test.ts +103 -0
  69. package/src/editor/BlockNoteExtension.ts +174 -56
  70. package/src/editor/managers/EventManager.ts +64 -35
  71. package/src/editor/managers/ExtensionManager/extensions.ts +214 -0
  72. package/src/editor/managers/ExtensionManager/index.ts +514 -0
  73. package/src/editor/managers/ExtensionManager/symbol.ts +6 -0
  74. package/src/editor/managers/SelectionManager.ts +5 -1
  75. package/src/editor/managers/StateManager.ts +29 -17
  76. package/src/editor/managers/index.ts +1 -5
  77. package/src/extensions/BlockChange/{BlockChangePlugin.ts → BlockChange.ts} +27 -29
  78. package/src/extensions/Collaboration/{ForkYDocPlugin.test.ts → ForkYDoc.test.ts} +6 -5
  79. package/src/extensions/Collaboration/ForkYDoc.ts +158 -0
  80. package/src/extensions/Collaboration/YCursorPlugin.ts +183 -0
  81. package/src/extensions/Collaboration/YSync.ts +16 -0
  82. package/src/extensions/Collaboration/YUndo.ts +12 -0
  83. package/src/extensions/Collaboration/schemaMigration/SchemaMigration.ts +59 -0
  84. package/src/extensions/DropCursor/DropCursor.ts +26 -0
  85. package/src/extensions/FilePanel/FilePanel.ts +41 -0
  86. package/src/extensions/FormattingToolbar/FormattingToolbar.ts +119 -0
  87. package/src/extensions/History/History.ts +11 -0
  88. package/src/extensions/LinkToolbar/LinkToolbar.ts +121 -0
  89. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.ts +74 -0
  90. package/src/extensions/Placeholder/Placeholder.ts +148 -0
  91. package/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.ts → PreviousBlockType.ts} +9 -13
  92. package/src/extensions/ShowSelection/{ShowSelectionPlugin.ts → ShowSelection.ts} +27 -33
  93. package/src/extensions/SideMenu/{SideMenuPlugin.ts → SideMenu.ts} +63 -83
  94. package/src/extensions/SuggestionMenu/{SuggestionPlugin.ts → SuggestionMenu.ts} +71 -77
  95. package/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts +29 -44
  96. package/src/extensions/TableHandles/{TableHandlesPlugin.ts → TableHandles.ts} +416 -437
  97. package/src/extensions/TrailingNode/{TrailingNodeExtension.ts → TrailingNode.ts} +8 -17
  98. package/src/extensions/index.ts +24 -0
  99. package/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.ts +1 -1
  100. package/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.ts +21 -16
  101. package/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.ts +1 -1
  102. package/src/extensions/tiptap-extensions/index.ts +31 -0
  103. package/src/index.ts +1 -13
  104. package/src/schema/blocks/createSpec.ts +14 -11
  105. package/src/schema/blocks/internal.ts +2 -2
  106. package/src/schema/blocks/types.ts +8 -5
  107. package/src/schema/schema.ts +11 -36
  108. package/src/util/topo-sort.ts +46 -0
  109. package/types/src/comments/extension.d.ts +70 -0
  110. package/types/src/comments/index.d.ts +2 -1
  111. package/types/src/comments/types.d.ts +8 -0
  112. package/types/src/{extensions/Comments → comments}/userstore/UserStore.d.ts +2 -2
  113. package/types/src/editor/BlockNoteEditor.d.ts +34 -105
  114. package/types/src/editor/BlockNoteExtension.d.ts +87 -22
  115. package/types/src/editor/managers/EventManager.d.ts +25 -16
  116. package/types/src/editor/managers/ExtensionManager/extensions.d.ts +8 -0
  117. package/types/src/editor/managers/ExtensionManager/index.d.ts +83 -0
  118. package/types/src/editor/managers/ExtensionManager/symbol.d.ts +5 -0
  119. package/types/src/editor/managers/StateManager.d.ts +1 -12
  120. package/types/src/editor/managers/index.d.ts +1 -2
  121. package/types/src/extensions/BlockChange/BlockChange.d.ts +16 -0
  122. package/types/src/extensions/Collaboration/ForkYDoc.d.ts +34 -0
  123. package/types/src/extensions/Collaboration/ForkYDoc.test.d.ts +1 -0
  124. package/types/src/extensions/Collaboration/YCursorPlugin.d.ts +24 -0
  125. package/types/src/extensions/Collaboration/YSync.d.ts +8 -0
  126. package/types/src/extensions/Collaboration/YUndo.d.ts +12 -0
  127. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigration.d.ts +8 -0
  128. package/types/src/extensions/DropCursor/DropCursor.d.ts +5 -0
  129. package/types/src/extensions/FilePanel/FilePanel.d.ts +11 -0
  130. package/types/src/extensions/FormattingToolbar/FormattingToolbar.d.ts +9 -0
  131. package/types/src/extensions/History/History.d.ts +6 -0
  132. package/types/src/extensions/LinkToolbar/LinkToolbar.d.ts +24 -0
  133. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboard.d.ts +5 -0
  134. package/types/src/extensions/Placeholder/Placeholder.d.ts +6 -0
  135. package/types/src/extensions/PreviousBlockType/{PreviousBlockTypePlugin.d.ts → PreviousBlockType.d.ts} +9 -5
  136. package/types/src/extensions/ShowSelection/ShowSelection.d.ts +21 -0
  137. package/types/src/extensions/SideMenu/{SideMenuPlugin.d.ts → SideMenu.d.ts} +11 -15
  138. package/types/src/extensions/SuggestionMenu/SuggestionMenu.d.ts +54 -0
  139. package/types/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.d.ts +1 -1
  140. package/types/src/extensions/TableHandles/{TableHandlesPlugin.d.ts → TableHandles.d.ts} +28 -31
  141. package/types/src/extensions/TrailingNode/TrailingNode.d.ts +8 -0
  142. package/types/src/extensions/index.d.ts +24 -0
  143. package/types/src/extensions/{KeyboardShortcuts → tiptap-extensions/KeyboardShortcuts}/KeyboardShortcutsExtension.d.ts +1 -1
  144. package/types/src/extensions/tiptap-extensions/index.d.ts +11 -0
  145. package/types/src/index.d.ts +1 -13
  146. package/types/src/schema/blocks/createSpec.d.ts +4 -4
  147. package/types/src/schema/blocks/internal.d.ts +2 -2
  148. package/types/src/schema/blocks/types.d.ts +5 -5
  149. package/types/src/util/topo-sort.d.ts +8 -0
  150. package/dist/BlockNoteSchema-Bi-eeHal.js.map +0 -1
  151. package/dist/BlockNoteSchema-DjDaA2C3.cjs +0 -6
  152. package/dist/BlockNoteSchema-DjDaA2C3.cjs.map +0 -1
  153. package/dist/blockToNode-DIfPWLH8.js.map +0 -1
  154. package/src/comments/models/User.ts +0 -8
  155. package/src/editor/BlockNoteExtensions.ts +0 -325
  156. package/src/editor/managers/CollaborationManager.ts +0 -212
  157. package/src/editor/managers/ExtensionManager.ts +0 -130
  158. package/src/extensions/Collaboration/CursorPlugin.ts +0 -189
  159. package/src/extensions/Collaboration/ForkYDocPlugin.ts +0 -192
  160. package/src/extensions/Collaboration/SyncPlugin.ts +0 -18
  161. package/src/extensions/Collaboration/UndoPlugin.ts +0 -18
  162. package/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.ts +0 -59
  163. package/src/extensions/Comments/CommentsPlugin.ts +0 -392
  164. package/src/extensions/FilePanel/FilePanelPlugin.ts +0 -206
  165. package/src/extensions/FormattingToolbar/FormattingToolbarPlugin.ts +0 -363
  166. package/src/extensions/LinkToolbar/LinkToolbarPlugin.ts +0 -380
  167. package/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.ts +0 -75
  168. package/src/extensions/Placeholder/PlaceholderPlugin.ts +0 -147
  169. package/types/src/comments/models/User.d.ts +0 -8
  170. package/types/src/editor/BlockNoteExtensions.d.ts +0 -43
  171. package/types/src/editor/managers/CollaborationManager.d.ts +0 -115
  172. package/types/src/editor/managers/ExtensionManager.d.ts +0 -68
  173. package/types/src/extensions/BlockChange/BlockChangePlugin.d.ts +0 -15
  174. package/types/src/extensions/Collaboration/CursorPlugin.d.ts +0 -37
  175. package/types/src/extensions/Collaboration/ForkYDocPlugin.d.ts +0 -41
  176. package/types/src/extensions/Collaboration/SyncPlugin.d.ts +0 -7
  177. package/types/src/extensions/Collaboration/UndoPlugin.d.ts +0 -9
  178. package/types/src/extensions/Collaboration/schemaMigration/SchemaMigrationPlugin.d.ts +0 -7
  179. package/types/src/extensions/Comments/CommentsPlugin.d.ts +0 -66
  180. package/types/src/extensions/FilePanel/FilePanelPlugin.d.ts +0 -31
  181. package/types/src/extensions/FormattingToolbar/FormattingToolbarPlugin.d.ts +0 -41
  182. package/types/src/extensions/LinkToolbar/LinkToolbarPlugin.d.ts +0 -42
  183. package/types/src/extensions/NodeSelectionKeyboard/NodeSelectionKeyboardPlugin.d.ts +0 -5
  184. package/types/src/extensions/Placeholder/PlaceholderPlugin.d.ts +0 -6
  185. package/types/src/extensions/ShowSelection/ShowSelectionPlugin.d.ts +0 -15
  186. package/types/src/extensions/SuggestionMenu/SuggestionPlugin.d.ts +0 -31
  187. package/types/src/extensions/TrailingNode/TrailingNodeExtension.d.ts +0 -13
  188. /package/src/{extensions/Comments/CommentMark.ts → comments/mark.ts} +0 -0
  189. /package/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.ts +0 -0
  190. /package/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.ts +0 -0
  191. /package/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.ts +0 -0
  192. /package/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.ts +0 -0
  193. /package/types/src/{extensions/Comments/CommentMark.d.ts → comments/mark.d.ts} +0 -0
  194. /package/types/src/{extensions/Collaboration/ForkYDocPlugin.test.d.ts → editor/BlockNoteExtension.test.d.ts} +0 -0
  195. /package/types/src/extensions/{BackgroundColor → tiptap-extensions/BackgroundColor}/BackgroundColorExtension.d.ts +0 -0
  196. /package/types/src/extensions/{HardBreak → tiptap-extensions/HardBreak}/HardBreak.d.ts +0 -0
  197. /package/types/src/extensions/{Suggestions → tiptap-extensions/Suggestions}/SuggestionMarks.d.ts +0 -0
  198. /package/types/src/extensions/{TextAlignment → tiptap-extensions/TextAlignment}/TextAlignmentExtension.d.ts +0 -0
  199. /package/types/src/extensions/{TextColor → tiptap-extensions/TextColor}/TextColorExtension.d.ts +0 -0
  200. /package/types/src/extensions/{UniqueID → tiptap-extensions/UniqueID}/UniqueID.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultBlocks-DLJ4Q1_J.cjs","sources":["../src/util/browser.ts","../src/blocks/defaultBlockHelpers.ts","../src/util/string.ts","../src/schema/blocks/internal.ts","../src/schema/blocks/createSpec.ts","../src/schema/inlineContent/internal.ts","../src/schema/styles/internal.ts","../src/schema/styles/createSpec.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/extensions/FilePanel/FilePanel.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/blocks/Code/shiki.ts","../src/blocks/Code/block.ts","../src/blocks/Divider/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/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/defaultBlockTypeGuards.ts","../src/api/positionMapping.ts","../src/extensions/SuggestionMenu/SuggestionMenu.ts","../src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts","../src/blocks/defaultBlocks.ts"],"sourcesContent":["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\nexport function isVideoUrl(url: string) {\n const videoExtensions = [\n \"mp4\",\n \"webm\",\n \"ogg\",\n \"mov\",\n \"mkv\",\n \"flv\",\n \"avi\",\n \"wmv\",\n \"m4v\",\n ];\n try {\n const pathname = new URL(url).pathname;\n const ext = pathname.split(\".\").pop()?.toLowerCase() || \"\";\n return videoExtensions.includes(ext);\n } catch (_) {\n return false;\n }\n}\n","import { Attribute, Attributes, Editor, Node } from \"@tiptap/core\";\nimport { defaultBlockToHTML } from \"../../blocks/defaultBlockHelpers.js\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport type { ExtensionFactoryInstance } 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?: ExtensionFactoryInstance[],\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 {\n Extension,\n ExtensionFactoryInstance,\n} 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?: (ExtensionFactoryInstance | Extension)[],\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 ...blockImplementation,\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 | ExtensionFactoryInstance[]\n | (TOptions extends undefined\n ? () => ExtensionFactoryInstance[]\n : (options: Partial<TOptions>) => ExtensionFactoryInstance[]),\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 | ExtensionFactoryInstance[]\n | (TOptions extends undefined\n ? () => ExtensionFactoryInstance[]\n : (options: Partial<TOptions>) => ExtensionFactoryInstance[]),\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 | ExtensionFactoryInstance[]\n | (TOptions extends undefined\n ? () => ExtensionFactoryInstance[]\n : (options: Partial<TOptions>) => ExtensionFactoryInstance[]),\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 { 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 runsBefore?: string[];\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 // By default, styles can overlap each other, so the rules should not\n // completely consume the element they parse (which can have multiple\n // styles).\n consuming: false,\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 ...styleImplementation,\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","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 {\n createExtension,\n createStore,\n} from \"../../editor/BlockNoteExtension.js\";\n\nexport const FilePanelExtension = createExtension(({ editor }) => {\n const store = createStore<string | undefined>(undefined);\n\n function closeMenu() {\n store.setState(undefined);\n }\n\n return {\n key: \"filePanel\",\n store,\n mount({ signal }) {\n // Reset the menu when the document changes.\n const unsubscribeOnChange = editor.onChange(\n closeMenu,\n // Don't trigger if the changes are caused by a remote user.\n false,\n );\n\n // reset the menu when the selection changes\n const unsubscribeOnSelectionChange = editor.onSelectionChange(\n closeMenu,\n // Don't trigger if the changes are caused by a remote user.\n false,\n );\n\n signal.addEventListener(\"abort\", () => {\n unsubscribeOnChange();\n unsubscribeOnSelectionChange();\n });\n },\n closeMenu,\n showMenu(blockId: string) {\n store.setState(blockId);\n },\n } as const;\n});\n","import type { BlockNoteEditor } from \"../../../../editor/BlockNoteEditor.js\";\nimport { FilePanelExtension } from \"../../../../extensions/FilePanel/FilePanel.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 event.stopPropagation();\n };\n // Opens the file toolbar.\n const addFileButtonClickHandler = () => {\n if (!editor.isEditable) {\n return;\n }\n\n editor.getExtension(FilePanelExtension)?.showMenu(block.id);\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","import type { HighlighterGeneric } from \"@shikijs/types\";\nimport { Parser, createHighlightPlugin } from \"prosemirror-highlight\";\nimport { createParser } from \"prosemirror-highlight/shiki\";\nimport { CodeBlockOptions, getLanguageId } from \"./block.js\";\n\nexport const shikiParserSymbol = Symbol.for(\"blocknote.shikiParser\");\nexport const shikiHighlighterPromiseSymbol = Symbol.for(\n \"blocknote.shikiHighlighterPromise\",\n);\n\nexport function lazyShikiPlugin(options: CodeBlockOptions) {\n const globalThisForShiki = globalThis as {\n [shikiHighlighterPromiseSymbol]?: Promise<HighlighterGeneric<any, any>>;\n [shikiParserSymbol]?: Parser;\n };\n\n let highlighter: HighlighterGeneric<any, any> | undefined;\n let parser: Parser | undefined;\n let hasWarned = false;\n const lazyParser: Parser = (parserOptions) => {\n if (!options.createHighlighter) {\n if (process.env.NODE_ENV === \"development\" && !hasWarned) {\n // eslint-disable-next-line no-console\n console.log(\n \"For syntax highlighting of code blocks, you must provide a `createCodeBlockSpec({ createHighlighter: () => ... })` function\",\n );\n hasWarned = true;\n }\n return [];\n }\n if (!highlighter) {\n globalThisForShiki[shikiHighlighterPromiseSymbol] =\n globalThisForShiki[shikiHighlighterPromiseSymbol] ||\n options.createHighlighter();\n\n return globalThisForShiki[shikiHighlighterPromiseSymbol].then(\n (createdHighlighter) => {\n highlighter = createdHighlighter;\n },\n );\n }\n const language = getLanguageId(options, parserOptions.language!);\n\n if (\n !language ||\n language === \"text\" ||\n language === \"none\" ||\n language === \"plaintext\" ||\n language === \"txt\"\n ) {\n return [];\n }\n\n if (!highlighter.getLoadedLanguages().includes(language)) {\n return highlighter.loadLanguage(language);\n }\n\n if (!parser) {\n parser =\n globalThisForShiki[shikiParserSymbol] ||\n createParser(highlighter as any);\n globalThisForShiki[shikiParserSymbol] = parser;\n }\n\n return parser(parserOptions);\n };\n\n return createHighlightPlugin({\n parser: lazyParser,\n languageExtractor: (node) => node.attrs.language,\n nodeTypes: [\"codeBlock\"],\n });\n}\n","import type { HighlighterGeneric } from \"@shikijs/types\";\nimport { createExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\nimport { lazyShikiPlugin } from \"./shiki.js\";\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 preserveWhitespace: \"full\",\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 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 select.value =\n block.props.language || options.defaultLanguage || \"text\";\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 removeSelectChangeListener = () =>\n select.removeEventListener(\"change\", handleLanguageChange);\n\n const selectWrapper = document.createElement(\"div\");\n selectWrapper.contentEditable = \"false\";\n\n selectWrapper.appendChild(select);\n wrapper.appendChild(selectWrapper);\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 createExtension({\n key: \"code-block-highlighter\",\n prosemirrorPlugins: [lazyShikiPlugin(options)],\n }),\n createExtension({\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","import { createExtension } from \"../../editor/BlockNoteExtension.js\";\nimport { createBlockConfig, createBlockSpec } from \"../../schema/index.js\";\n\nexport type DividerBlockConfig = ReturnType<typeof createDividerBlockConfig>;\n\nexport const createDividerBlockConfig = createBlockConfig(\n () =>\n ({\n type: \"divider\" as const,\n propSchema: {},\n content: \"none\",\n }) as const,\n);\n\nexport const createDividerBlockSpec = createBlockSpec(\n createDividerBlockConfig,\n {\n meta: {\n isolating: false,\n },\n parse(element) {\n if (element.tagName === \"HR\") {\n return {};\n }\n\n return undefined;\n },\n render() {\n const dom = document.createElement(\"hr\");\n\n return {\n dom,\n };\n },\n },\n [\n createExtension({\n key: \"divider-block-shortcuts\",\n inputRules: [\n {\n find: new RegExp(`^---$`),\n replace() {\n return { type: \"divider\", props: {}, content: [] };\n },\n },\n ],\n }),\n ],\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.isEditable &&\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 (editor.isEditable && 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 { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport { createExtension } 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\nconst createHeadingKeyboardShortcut =\n (level: number) =>\n ({ editor }: { editor: BlockNoteEditor<any, any, any> }) => {\n const cursorPosition = editor.getTextCursorPosition();\n\n if (\n editor.schema.blockSchema[cursorPosition.block.type].content !== \"inline\"\n ) {\n return false;\n }\n\n editor.updateBlock(cursorPosition.block, {\n type: \"heading\",\n props: { level },\n });\n\n return true;\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 createExtension({\n key: \"heading-shortcuts\",\n keyboardShortcuts: Object.fromEntries(\n levels.map((level) => [\n `Mod-Alt-${level}`,\n createHeadingKeyboardShortcut(level),\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 { getBlockInfoFromSelection } from \"../../../api/getBlockInfoFromPos.js\";\nimport { createExtension } 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 createExtension({\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({ editor }) {\n const blockInfo = getBlockInfoFromSelection(\n editor.prosemirrorState,\n );\n\n if (blockInfo.blockNoteType === \"heading\") {\n return;\n }\n return {\n type: \"bulletListItem\",\n props: {},\n };\n },\n },\n ],\n }),\n ],\n);\n","import { createExtension } 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\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 createExtension({\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 const blockNode = tr.doc.nodeAt(pos + 1);\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 + 1 + blockNode!.nodeSize, {\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 { getBlockInfoFromSelection } from \"../../../api/getBlockInfoFromPos.js\";\nimport { createExtension } 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 createExtension({\n key: \"numbered-list-item-shortcuts\",\n inputRules: [\n {\n find: new RegExp(`^(\\\\d+)\\\\.\\\\s$`),\n replace({ match, editor }) {\n const blockInfo = getBlockInfoFromSelection(\n editor.prosemirrorState,\n );\n\n if (blockInfo.blockNoteType === \"heading\") {\n return;\n }\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 prosemirrorPlugins: [NumberedListIndexingDecorationPlugin()],\n }),\n ],\n);\n","import { createExtension } 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 createExtension({\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 { createExtension } 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 createExtension({\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 { createExtension } 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 createExtension({\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 { CellSelection, TableView } from \"prosemirror-tables\";\nimport { NodeView } from \"prosemirror-view\";\n\nimport { createExtension } from \"../../editor/BlockNoteExtension.js\";\nimport {\n BlockConfig,\n createBlockSpecFromTiptapNode,\n TableContent,\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 createExtension({\n key: \"table-extensions\",\n tiptapExtensions: [\n TableExtension,\n TiptapTableParagraph,\n TiptapTableHeader,\n TiptapTableCell,\n TiptapTableRow,\n ],\n }),\n // Extension for keyboard shortcut which deletes the table if it's empty\n // and all cells are selected. Uses a separate extension as it needs\n // priority over keyboard handlers in the `TableExtension`'s\n // `tableEditing` plugin.\n createExtension({\n key: \"table-keyboard-delete\",\n keyboardShortcuts: {\n Backspace: ({ editor }) => {\n if (!(editor.prosemirrorState.selection instanceof CellSelection)) {\n return false;\n }\n\n const block = editor.getTextCursorPosition().block;\n const content = block.content as TableContent<any, any>;\n\n let numCells = 0;\n for (const row of content.rows) {\n for (const cell of row.cells) {\n // Returns `false` if any cell isn't empty.\n if (\n (\"type\" in cell && cell.content.length > 0) ||\n (!(\"type\" in cell) && cell.length > 0)\n ) {\n return false;\n }\n\n numCells++;\n }\n }\n\n // Need to use ProseMirror API to check number of selected cells.\n let selectionNumCells = 0;\n editor.prosemirrorState.selection.forEachCell(() => {\n selectionNumCells++;\n });\n\n if (selectionNumCells < numCells) {\n return false;\n }\n\n editor.transact(() => {\n const selectionBlock =\n editor.getPrevBlock(block) || editor.getNextBlock(block);\n if (selectionBlock) {\n editor.setTextCursorPosition(block);\n }\n\n editor.removeBlocks([block]);\n });\n\n return true;\n },\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","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 !== undefined &&\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 undefined &&\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 for (const value of propSpec.values) {\n if (\n !editor.schema.blockSpecs[blockType].config.propSchema[\n propName\n ].values.includes(value)\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 { Mapping } from \"prosemirror-transform\";\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from \"y-prosemirror\";\nimport type { BlockNoteEditor } from \"../editor/BlockNoteEditor.js\";\nimport * as Y from \"yjs\";\nimport type { ProsemirrorBinding } from \"y-prosemirror\";\n\n/**\n * This is used to track a mapping for each editor. The mapping stores the mappings for each transaction since the first transaction that was tracked.\n */\nconst editorToMapping = new Map<BlockNoteEditor<any, any, any>, Mapping>();\n\n/**\n * This initializes a single mapping for an editor instance.\n */\nfunction getMapping(editor: BlockNoteEditor<any, any, any>) {\n if (editorToMapping.has(editor)) {\n // Mapping already initialized, so we don't need to do anything\n return editorToMapping.get(editor)!;\n }\n const mapping = new Mapping();\n editor._tiptapEditor.on(\"transaction\", ({ transaction }) => {\n mapping.appendMapping(transaction.mapping);\n });\n editor._tiptapEditor.on(\"destroy\", () => {\n // Cleanup the mapping when the editor is destroyed\n editorToMapping.delete(editor);\n });\n\n // There only is one mapping per editor, so we can just set it\n editorToMapping.set(editor, mapping);\n\n return mapping;\n}\n\n/**\n * This is used to keep track of positions of elements in the editor.\n * It is needed because y-prosemirror's sync plugin can disrupt normal prosemirror position mapping.\n *\n * It is specifically made to be able to be used whether the editor is being used in a collaboratively, or single user, providing the same API.\n *\n * @param editor The editor to track the position of.\n * @param position The position to track.\n * @param side The side of the position to track. \"left\" is the default. \"right\" would move with the change if the change is in the right direction.\n * @returns A function that returns the position of the element.\n */\nexport function trackPosition(\n /**\n * The editor to track the position of.\n */\n editor: BlockNoteEditor<any, any, any>,\n /**\n * The position to track.\n */\n position: number,\n /**\n * This is the side of the position to track. \"left\" is the default. \"right\" would move with the change if the change is in the right direction.\n */\n side: \"left\" | \"right\" = \"left\",\n): () => number {\n const ySyncPluginState = ySyncPluginKey.getState(editor.prosemirrorState) as {\n doc: Y.Doc;\n binding: ProsemirrorBinding;\n };\n\n if (!ySyncPluginState) {\n // No y-prosemirror sync plugin, so we need to track the mapping manually\n // This will initialize the mapping for this editor, if needed\n const mapping = getMapping(editor);\n\n // This is the start point of tracking the mapping\n const trackedMapLength = mapping.maps.length;\n\n return () => {\n const pos = mapping\n // Only read the history of the mapping that we care about\n .slice(trackedMapLength)\n .map(position, side === \"left\" ? -1 : 1);\n\n return pos;\n };\n }\n\n const relativePosition = absolutePositionToRelativePosition(\n // Track the position after the position if we are on the right side\n position + (side === \"right\" ? 1 : -1),\n ySyncPluginState.binding.type,\n ySyncPluginState.binding.mapping,\n );\n\n return () => {\n const curYSyncPluginState = ySyncPluginKey.getState(\n editor.prosemirrorState,\n ) as typeof ySyncPluginState;\n const pos = relativePositionToAbsolutePosition(\n curYSyncPluginState.doc,\n curYSyncPluginState.binding.type,\n relativePosition,\n curYSyncPluginState.binding.mapping,\n );\n\n // This can happen if the element is garbage collected\n if (pos === null) {\n throw new Error(\"Position not found, cannot track positions\");\n }\n\n return pos + (side === \"right\" ? -1 : 1);\n };\n}\n","import { findParentNode } from \"@tiptap/core\";\nimport { EditorState, Plugin, PluginKey } from \"prosemirror-state\";\nimport { Decoration, DecorationSet, EditorView } from \"prosemirror-view\";\n\nimport { trackPosition } from \"../../api/positionMapping.js\";\nimport {\n createExtension,\n createStore,\n} from \"../../editor/BlockNoteExtension.js\";\nimport { UiElementPosition } from \"../../extensions-shared/UiElementPosition.js\";\nimport { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\n\nconst findBlock = findParentNode((node) => node.type.name === \"blockContainer\");\n\nexport type SuggestionMenuState = UiElementPosition & {\n query: string;\n ignoreQueryLength?: boolean;\n};\n\nclass SuggestionMenuView {\n public state?: SuggestionMenuState;\n public emitUpdate: (triggerCharacter: string) => void;\n private rootEl?: Document | ShadowRoot;\n pluginState: SuggestionPluginState;\n\n constructor(\n private readonly editor: BlockNoteEditor<any, any, any>,\n emitUpdate: (menuName: string, state: SuggestionMenuState) => void,\n view: EditorView,\n ) {\n this.pluginState = undefined;\n\n this.emitUpdate = (menuName: string) => {\n if (!this.state) {\n throw new Error(\"Attempting to update uninitialized suggestions menu\");\n }\n\n emitUpdate(menuName, {\n ...this.state,\n ignoreQueryLength: this.pluginState?.ignoreQueryLength,\n });\n };\n\n this.rootEl = view.root;\n\n // Setting capture=true ensures that any parent container of the editor that\n // gets scrolled will trigger the scroll event. Scroll events do not bubble\n // and so won't propagate to the document by default.\n this.rootEl?.addEventListener(\"scroll\", this.handleScroll, true);\n }\n\n handleScroll = () => {\n if (this.state?.show) {\n const decorationNode = this.rootEl?.querySelector(\n `[data-decoration-id=\"${this.pluginState!.decorationId}\"]`,\n );\n if (!decorationNode) {\n return;\n }\n this.state.referencePos = decorationNode\n .getBoundingClientRect()\n .toJSON() as DOMRect;\n this.emitUpdate(this.pluginState!.triggerCharacter!);\n }\n };\n\n update(view: EditorView, prevState: EditorState) {\n const prev: SuggestionPluginState =\n suggestionMenuPluginKey.getState(prevState);\n const next: SuggestionPluginState = suggestionMenuPluginKey.getState(\n view.state,\n );\n\n // See how the state changed\n const started = prev === undefined && next !== undefined;\n const stopped = prev !== undefined && next === undefined;\n const changed = prev !== undefined && next !== undefined;\n\n // Cancel when suggestion isn't active\n if (!started && !changed && !stopped) {\n return;\n }\n\n this.pluginState = stopped ? prev : next;\n\n if (stopped || !this.editor.isEditable) {\n if (this.state) {\n this.state.show = false;\n }\n this.emitUpdate(this.pluginState!.triggerCharacter);\n\n return;\n }\n\n const decorationNode = this.rootEl?.querySelector(\n `[data-decoration-id=\"${this.pluginState!.decorationId}\"]`,\n );\n\n if (this.editor.isEditable && decorationNode) {\n this.state = {\n show: true,\n referencePos: decorationNode\n .getBoundingClientRect()\n .toJSON() as DOMRect,\n query: this.pluginState!.query,\n };\n\n this.emitUpdate(this.pluginState!.triggerCharacter!);\n }\n }\n\n destroy() {\n this.rootEl?.removeEventListener(\"scroll\", this.handleScroll, true);\n }\n\n closeMenu = () => {\n this.editor.transact((tr) => tr.setMeta(suggestionMenuPluginKey, null));\n };\n\n clearQuery = () => {\n if (this.pluginState === undefined) {\n return;\n }\n\n this.editor._tiptapEditor\n .chain()\n .focus()\n // TODO need to make an API for this\n .deleteRange({\n from:\n this.pluginState.queryStartPos() -\n (this.pluginState.deleteTriggerCharacter\n ? this.pluginState.triggerCharacter!.length\n : 0),\n to: this.editor.transact((tr) => tr.selection.from),\n })\n .run();\n };\n}\n\ntype SuggestionPluginState =\n | {\n triggerCharacter: string;\n deleteTriggerCharacter: boolean;\n queryStartPos: () => number;\n query: string;\n decorationId: string;\n ignoreQueryLength?: boolean;\n }\n | undefined;\n\nconst suggestionMenuPluginKey = new PluginKey(\"SuggestionMenuPlugin\");\n\n/**\n * A ProseMirror plugin for suggestions, designed to make '/'-commands possible as well as mentions.\n *\n * This is basically a simplified version of TipTap's [Suggestions](https://github.com/ueberdosis/tiptap/tree/db92a9b313c5993b723c85cd30256f1d4a0b65e1/packages/suggestion) plugin.\n *\n * This version is adapted from the aforementioned version in the following ways:\n * - This version supports generic items instead of only strings (to allow for more advanced filtering for example)\n * - This version hides some unnecessary complexity from the user of the plugin.\n * - This version handles key events differently\n */\nexport const SuggestionMenu = createExtension(({ editor }) => {\n const triggerCharacters: string[] = [];\n let view: SuggestionMenuView | undefined = undefined;\n const store = createStore<\n (SuggestionMenuState & { triggerCharacter: string }) | undefined\n >(undefined);\n return {\n key: \"suggestionMenu\",\n store,\n addTriggerCharacter: (triggerCharacter: string) => {\n triggerCharacters.push(triggerCharacter);\n },\n removeTriggerCharacter: (triggerCharacter: string) => {\n triggerCharacters.splice(triggerCharacters.indexOf(triggerCharacter), 1);\n },\n closeMenu: () => {\n view?.closeMenu();\n },\n clearQuery: () => {\n view?.clearQuery();\n },\n shown: () => {\n return view?.state?.show || false;\n },\n openSuggestionMenu: (\n triggerCharacter: string,\n pluginState?: {\n deleteTriggerCharacter?: boolean;\n ignoreQueryLength?: boolean;\n },\n ) => {\n if (editor.headless) {\n return;\n }\n\n editor.focus();\n\n editor.transact((tr) => {\n if (pluginState?.deleteTriggerCharacter) {\n tr.insertText(triggerCharacter);\n }\n tr.scrollIntoView().setMeta(suggestionMenuPluginKey, {\n triggerCharacter: triggerCharacter,\n deleteTriggerCharacter: pluginState?.deleteTriggerCharacter || false,\n ignoreQueryLength: pluginState?.ignoreQueryLength || false,\n });\n });\n },\n // TODO this whole plugin needs to be refactored (but I've done the minimal)\n prosemirrorPlugins: [\n new Plugin({\n key: suggestionMenuPluginKey,\n\n view: (v) => {\n view = new SuggestionMenuView(\n editor,\n (triggerCharacter, state) => {\n store.setState({ ...state, triggerCharacter });\n },\n v,\n );\n return view;\n },\n\n state: {\n // Initialize the plugin's internal state.\n init(): SuggestionPluginState {\n return undefined;\n },\n\n // Apply changes to the plugin state from an editor transaction.\n apply: (\n transaction,\n prev,\n _oldState,\n newState,\n ): SuggestionPluginState => {\n // Ignore transactions in code blocks.\n if (transaction.selection.$from.parent.type.spec.code) {\n return prev;\n }\n\n // Either contains the trigger character if the menu should be shown,\n // or null if it should be hidden.\n const suggestionPluginTransactionMeta: {\n triggerCharacter: string;\n deleteTriggerCharacter?: boolean;\n ignoreQueryLength?: boolean;\n } | null = transaction.getMeta(suggestionMenuPluginKey);\n\n if (\n typeof suggestionPluginTransactionMeta === \"object\" &&\n suggestionPluginTransactionMeta !== null\n ) {\n if (prev) {\n // Close the previous menu if it exists\n view?.closeMenu();\n }\n const trackedPosition = trackPosition(\n editor,\n newState.selection.from -\n // Need to account for the trigger char that was inserted, so we offset the position by the length of the trigger character.\n suggestionPluginTransactionMeta.triggerCharacter.length,\n );\n return {\n triggerCharacter:\n suggestionPluginTransactionMeta.triggerCharacter,\n deleteTriggerCharacter:\n suggestionPluginTransactionMeta.deleteTriggerCharacter !==\n false,\n // When reading the queryStartPos, we offset the result by the length of the trigger character, to make it easy on the caller\n queryStartPos: () =>\n trackedPosition() +\n suggestionPluginTransactionMeta.triggerCharacter.length,\n query: \"\",\n decorationId: `id_${Math.floor(Math.random() * 0xffffffff)}`,\n ignoreQueryLength:\n suggestionPluginTransactionMeta?.ignoreQueryLength,\n };\n }\n\n // Checks if the menu is hidden, in which case it doesn't need to be hidden or updated.\n if (prev === undefined) {\n return prev;\n }\n\n // Checks if the menu should be hidden.\n if (\n // Highlighting text should hide the menu.\n newState.selection.from !== newState.selection.to ||\n // Transactions with plugin metadata should hide the menu.\n suggestionPluginTransactionMeta === null ||\n // Certain mouse events should hide the menu.\n // TODO: Change to global mousedown listener.\n transaction.getMeta(\"focus\") ||\n transaction.getMeta(\"blur\") ||\n transaction.getMeta(\"pointer\") ||\n // Moving the caret before the character which triggered the menu should hide it.\n (prev.triggerCharacter !== undefined &&\n newState.selection.from < prev.queryStartPos()) ||\n // Moving the caret to a new block should hide the menu.\n !newState.selection.$from.sameParent(\n newState.doc.resolve(prev.queryStartPos()),\n )\n ) {\n return undefined;\n }\n\n const next = { ...prev };\n\n // Updates the current query.\n next.query = newState.doc.textBetween(\n prev.queryStartPos(),\n newState.selection.from,\n );\n\n return next;\n },\n },\n\n props: {\n handleTextInput(view, from, to, text) {\n // only on insert\n if (from === to) {\n const doc = view.state.doc;\n for (const str of triggerCharacters) {\n const snippet =\n str.length > 1\n ? doc.textBetween(from - str.length, from) + text\n : text;\n\n if (str === snippet) {\n view.dispatch(view.state.tr.insertText(text));\n view.dispatch(\n view.state.tr\n .setMeta(suggestionMenuPluginKey, {\n triggerCharacter: snippet,\n })\n .scrollIntoView(),\n );\n return true;\n }\n }\n }\n return false;\n },\n\n // Setup decorator on the currently active suggestion.\n decorations(state) {\n const suggestionPluginState: SuggestionPluginState = (\n this as Plugin\n ).getState(state);\n\n if (suggestionPluginState === undefined) {\n return null;\n }\n\n // If the menu was opened programmatically by another extension, it may not use a trigger character. In this\n // case, the decoration is set on the whole block instead, as the decoration range would otherwise be empty.\n if (!suggestionPluginState.deleteTriggerCharacter) {\n const blockNode = findBlock(state.selection);\n if (blockNode) {\n return DecorationSet.create(state.doc, [\n Decoration.node(\n blockNode.pos,\n blockNode.pos + blockNode.node.nodeSize,\n {\n nodeName: \"span\",\n class: \"bn-suggestion-decorator\",\n \"data-decoration-id\": suggestionPluginState.decorationId,\n },\n ),\n ]);\n }\n }\n // Creates an inline decoration around the trigger character.\n return DecorationSet.create(state.doc, [\n Decoration.inline(\n suggestionPluginState.queryStartPos() -\n suggestionPluginState.triggerCharacter!.length,\n suggestionPluginState.queryStartPos(),\n {\n nodeName: \"span\",\n class: \"bn-suggestion-decorator\",\n \"data-decoration-id\": suggestionPluginState.decorationId,\n },\n ),\n ]);\n },\n },\n }),\n ],\n } as const;\n});\n","import { Block, PartialBlock } from \"../../blocks/defaultBlocks.js\";\nimport { editorHasBlockWithType } from \"../../blocks/defaultBlockTypeGuards.js\";\nimport type { BlockNoteEditor } from \"../../editor/BlockNoteEditor.js\";\nimport {\n BlockSchema,\n InlineContentSchema,\n StyleSchema,\n isStyledTextInlineContent,\n} from \"../../schema/index.js\";\nimport { formatKeyboardShortcut } from \"../../util/browser.js\";\nimport { FilePanelExtension } from \"../FilePanel/FilePanel.js\";\nimport { DefaultSuggestionItem } from \"./DefaultSuggestionItem.js\";\nimport { SuggestionMenu } from \"./SuggestionMenu.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 insertOrUpdateBlockForSlashMenu<\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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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, \"divider\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlockForSlashMenu(editor, { type: \"divider\" });\n },\n key: \"divider\",\n ...editor.dictionary.slash_menu.divider,\n });\n }\n\n if (editorHasBlockWithType(editor, \"table\")) {\n items.push({\n onItemClick: () => {\n insertOrUpdateBlockForSlashMenu(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 = insertOrUpdateBlockForSlashMenu(editor, {\n type: \"image\",\n });\n\n // Immediately open the file toolbar\n editor.getExtension(FilePanelExtension)?.showMenu(insertedBlock.id);\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 = insertOrUpdateBlockForSlashMenu(editor, {\n type: \"video\",\n });\n\n // Immediately open the file toolbar\n editor.getExtension(FilePanelExtension)?.showMenu(insertedBlock.id);\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 = insertOrUpdateBlockForSlashMenu(editor, {\n type: \"audio\",\n });\n\n // Immediately open the file toolbar\n editor.getExtension(FilePanelExtension)?.showMenu(insertedBlock.id);\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 = insertOrUpdateBlockForSlashMenu(editor, {\n type: \"file\",\n });\n\n // Immediately open the file toolbar\n editor.getExtension(FilePanelExtension)?.showMenu(insertedBlock.id);\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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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 insertOrUpdateBlockForSlashMenu(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.getExtension(SuggestionMenu)?.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 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 { COLORS_DEFAULT } from \"../editor/defaultColors.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 {\n createAudioBlockSpec,\n createBulletListItemBlockSpec,\n createCheckListItemBlockSpec,\n createCodeBlockSpec,\n createDividerBlockSpec,\n createFileBlockSpec,\n createHeadingBlockSpec,\n createImageBlockSpec,\n createNumberedListItemBlockSpec,\n createParagraphBlockSpec,\n createQuoteBlockSpec,\n createToggleListItemBlockSpec,\n createVideoBlockSpec,\n defaultProps,\n} from \"./index.js\";\nimport { createTableBlockSpec } from \"./Table/block.js\";\n\nexport const defaultBlockSpecs = {\n audio: createAudioBlockSpec(),\n bulletListItem: createBulletListItemBlockSpec(),\n checkListItem: createCheckListItemBlockSpec(),\n codeBlock: createCodeBlockSpec(),\n divider: createDividerBlockSpec(),\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"],"names":["isAppleOS","formatKeyboardShortcut","shortcut","ctrlText","mergeCSSClasses","classes","c","isSafari","createDefaultBlockDOMOutputSpec","blockName","htmlTag","blockContentHTMLAttributes","inlineContentHTMLAttributes","blockContent","attribute","value","inlineContent","defaultBlockToHTML","block","editor","node","blockToNode","toDOM","renderSpec","mergeParagraphs","element","separator","paragraphs","firstParagraph","i","paragraph","camelToDataKebab","str","filenameFromURL","url","parts","isVideoUrl","videoExtensions","ext","_a","propsToAttributes","propSchema","tiptapAttributes","name","spec","asNumber","attributes","getBlockFromPos","getPos","tipTapEditor","type","pos","blockIdentifier","wrapInBlockStructure","blockType","blockProps","isFileBlock","domAttributes","attr","prop","defaultValue","createBlockSpecFromTiptapNode","config","extensions","applyNonSelectableBlockFix","nodeView","event","getParseRules","implementation","rules","props","schema","clone","DOMParser","Fragment","addNodeAndExtensionsToSpec","blockConfig","blockImplementation","priority","Node","_b","_c","_d","HTMLAttributes","div","blockContentDOMAttributes","createBlockConfig","callback","createBlockSpec","blockConfigOrCreator","blockImplementationOrCreator","extensionsOrCreator","options","output","addInlineContentAttributes","inlineContentType","inlineContentProps","addInlineContentKeyboardShortcuts","resolvedPos","createInternalInlineContentSpec","createInlineContentSpecFromTipTapNode","getInlineContentSchemaFromSpecs","specs","key","stylePropsToAttributes","addStyleAttributes","styleType","styleValue","createInternalStyleSpec","createStyleSpecFromTipTapMark","mark","markInstance","DOMSerializer","getStyleSchemaFromSpecs","getStyleParseRules","customParseFunction","htmlElement","stringValue","createStyleSpec","styleConfig","styleImplementation","Mark","renderResult","getNodeById","id","doc","targetNode","posBeforeNode","isNodeBlock","updateBlockCommand","posBeforeBlock","tr","dispatch","updateBlockTr","replaceFromPos","replaceToPos","blockInfo","getBlockInfoFromResolvedPos","cellAnchor","captureCellAnchor","pmSchema","getPmSchema","oldNodeType","newNodeType","newBnBlockNodeType","replaceFromOffset","replaceToOffset","updateChildren","updateBlockContentNode","existingBlock","nodeToBlock","restoreCellAnchor","content","inlineContentToNodes","tableContentToNodes","UnreachableCaseError","start","end","contentDepth","startDepth","endDepth","Slice","childNodes","child","ReplaceStep","updateBlock","blockToUpdate","update","posInfo","blockContainerNode","sel","TextSelection","$head","cellDepth","tableDepth","d","cellPos","tablePos","table","map","TableMap","rel","idx","row","col","textStart","offset","a","cellIndex","relCellPos","textPos","textNode","max","head","COLORS_DEFAULT","COLORS_DARK_MODE_DEFAULT","defaultProps","parseDefaultProps","addDefaultPropsExternalHTML","getBackgroundColorAttribute","attributeName","getTextColorAttribute","getTextAlignmentAttribute","parseFigureElement","figureElement","targetTag","targetElement","captionElement","caption","FilePanelExtension","createExtension","store","createStore","closeMenu","signal","unsubscribeOnChange","unsubscribeOnSelectionChange","blockId","createAddFileButton","buttonIcon","addFileButton","addFileButtonIcon","addFileButtonText","addFileButtonMouseDownHandler","addFileButtonClickHandler","FILE_ICON_SVG","createFileNameWithIcon","file","icon","fileName","createFileBlockWrapper","wrapper","destroyUploadStartHandler","loading","ret","fileNameWithIcon","createFigureWithCaption","figure","createLinkWithCaption","fileCaption","parseAudioElement","audioElement","FILE_AUDIO_ICON_SVG","createAudioBlockConfig","_ctx","audioParse","_config","backgroundColor","parsedFigure","audioRender","audio","downloadUrl","audioToExternalHTML","_editor","createAudioBlockSpec","shikiParserSymbol","shikiHighlighterPromiseSymbol","lazyShikiPlugin","globalThisForShiki","highlighter","parser","hasWarned","lazyParser","parserOptions","createdHighlighter","language","getLanguageId","createParser","createHighlightPlugin","createCodeBlockConfig","defaultLanguage","createCodeBlockSpec","e","code","el","pre","removeSelectChangeListener","select","option","handleLanguageChange","selectWrapper","$from","nextBlock","isAtEnd","endsWithDoubleNewline","newBlock","match","languageName","aliases","createDividerBlockConfig","createDividerBlockSpec","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","createHeadingKeyboardShortcut","level","cursorPosition","createHeadingBlockConfig","defaultLevel","levels","allowToggleHeadings","createHeadingBlockSpec","createResizableFileBlockWrapper","resizeHandlesContainerElement","destroy","leftResizeHandle","rightResizeHandle","eventCaptureElement","resizeParams","width","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","state","splitBlockTr","nearestBlockContainerPos","getNearestBlockPos","info","getBlockInfo","types","handleEnter","listItemType","selectionEmpty","getBlockInfoFromTransaction","blockContainer","getListItemContent","_node","clonedNodeDiv","blockGroupNode","listItemsFirstChild","listItemNode","remainingListItemChildren","listItemsChildren","createBulletListItemBlockConfig","createBulletListItemBlockSpec","parent","li","p","getBlockInfoFromSelection","createCheckListItemConfig","createCheckListItemBlockSpec","checkbox","calculateListItemIndex","index","isFirst","hasStart","prevBlock","prevBlockIndex","getDecorations","previousPluginState","nextDecorationSet","decorationsToAdd","deco","blockNode","Decoration","decorationsToRemove","NumberedListIndexingDecorationPlugin","Plugin","PluginKey","DecorationSet","createNumberedListItemBlockConfig","createNumberedListItemBlockSpec","startIndex","createToggleListItemBlockConfig","createToggleListItemBlockSpec","paragraphEl","createParagraphBlockConfig","createParagraphBlockSpec","createQuoteBlockConfig","createQuoteBlockSpec","textColor","quote","RESIZE_MIN_WIDTH","EMPTY_CELL_WIDTH","EMPTY_CELL_HEIGHT","TableExtension","Extension","columnResizing","tableEditing","selection","selectionIsEmpty","selectionIsAtStartOfNode","selectionIsInTableParagraphNode","view","goToNextCell","extension","context","callOrReturn","getExtensionField","tablePropSchema","TiptapTableHeader","colwidth","parseTableContent","mergeAttributes","TiptapTableCell","TiptapTableNode","domOutputSpec","colGroup","tableCell","colWidth","BlockNoteTableView","TableView","cellMinWidth","tableWrapper","tableWrapperInner","floatingContainer","record","TiptapTableParagraph","TiptapTableRow","parsedContent","extractedContent","createTableBlockSpec","CellSelection","numCells","cell","selectionNumCells","parseVideoElement","videoElement","FILE_VIDEO_ICON_SVG","createVideoBlockConfig","videoParse","createVideoBlockSpec","videoWrapper","video","editorHasBlockWithType","propName","propSpec","blockHasType","isTableCellSelection","editorToMapping","getMapping","mapping","Mapping","transaction","trackPosition","position","side","ySyncPluginState","ySyncPluginKey","trackedMapLength","relativePosition","absolutePositionToRelativePosition","curYSyncPluginState","relativePositionToAbsolutePosition","findBlock","findParentNode","SuggestionMenuView","emitUpdate","__publicField","decorationNode","suggestionMenuPluginKey","menuName","prevState","prev","next","started","stopped","SuggestionMenu","triggerCharacters","triggerCharacter","pluginState","v","_oldState","newState","suggestionPluginTransactionMeta","trackedPosition","from","to","text","snippet","suggestionPluginState","setSelectionToNextContentEditableBlock","contentType","insertOrUpdateBlockForSlashMenu","currentBlock","isStyledTextInlineContent","getDefaultSlashMenuItems","items","insertedBlock","filterSuggestionItems","query","title","alias","defaultBlockSpecs","TextColor","span","BackgroundColor","defaultStyleSpecs","Bold","Italic","Underline","Strike","Code","defaultStyleSchema","defaultInlineContentSpecs","defaultInlineContentSchema"],"mappings":"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"}