@prosekit/extensions 0.11.6 → 0.12.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 (98) hide show
  1. package/dist/{drop-indicator-E7nCfdnR.js → drop-indicator-BMvWUDXz.js} +2 -2
  2. package/dist/{drop-indicator-E7nCfdnR.js.map → drop-indicator-BMvWUDXz.js.map} +1 -1
  3. package/dist/{enter-rule-RdhEA900.js → enter-rule-D-p4ykfv.js} +3 -4
  4. package/dist/enter-rule-D-p4ykfv.js.map +1 -0
  5. package/dist/{file-DVUhe5KJ.js → file-DKoIIa7q.js} +3 -5
  6. package/dist/{file-DVUhe5KJ.js.map → file-DKoIIa7q.js.map} +1 -1
  7. package/dist/{index-DY6lIIYV.d.ts → index-DdjnBeho.d.ts} +2 -2
  8. package/dist/index-DdjnBeho.d.ts.map +1 -0
  9. package/dist/{input-rule-B17tpW4m.js → input-rule-COGr_GBb.js} +5 -8
  10. package/dist/input-rule-COGr_GBb.js.map +1 -0
  11. package/dist/{mark-rule-CGmswjQ_.js → mark-rule-v2E7B4C0.js} +2 -2
  12. package/dist/{mark-rule-CGmswjQ_.js.map → mark-rule-v2E7B4C0.js.map} +1 -1
  13. package/dist/{paste-rule-BIztzELg.js → paste-rule-qSz46pqD.js} +3 -4
  14. package/dist/{paste-rule-BIztzELg.js.map → paste-rule-qSz46pqD.js.map} +1 -1
  15. package/dist/prosekit-extensions-autocomplete.d.ts.map +1 -1
  16. package/dist/prosekit-extensions-autocomplete.js +1 -2
  17. package/dist/prosekit-extensions-autocomplete.js.map +1 -1
  18. package/dist/prosekit-extensions-blockquote.d.ts.map +1 -1
  19. package/dist/prosekit-extensions-blockquote.js +1 -1
  20. package/dist/prosekit-extensions-bold.d.ts.map +1 -1
  21. package/dist/prosekit-extensions-bold.js +1 -1
  22. package/dist/prosekit-extensions-code-block.d.ts +1 -1
  23. package/dist/prosekit-extensions-code-block.d.ts.map +1 -1
  24. package/dist/prosekit-extensions-code-block.js +4 -5
  25. package/dist/prosekit-extensions-code-block.js.map +1 -1
  26. package/dist/prosekit-extensions-code.d.ts.map +1 -1
  27. package/dist/prosekit-extensions-code.js +1 -1
  28. package/dist/prosekit-extensions-commit.d.ts.map +1 -1
  29. package/dist/prosekit-extensions-commit.js +2 -4
  30. package/dist/prosekit-extensions-commit.js.map +1 -1
  31. package/dist/prosekit-extensions-doc.d.ts.map +1 -1
  32. package/dist/prosekit-extensions-drop-cursor.d.ts.map +1 -1
  33. package/dist/prosekit-extensions-drop-indicator.d.ts.map +1 -1
  34. package/dist/prosekit-extensions-drop-indicator.js +1 -1
  35. package/dist/prosekit-extensions-enter-rule.d.ts.map +1 -1
  36. package/dist/prosekit-extensions-enter-rule.js +1 -1
  37. package/dist/prosekit-extensions-file.d.ts +1 -1
  38. package/dist/prosekit-extensions-file.js +1 -1
  39. package/dist/prosekit-extensions-hard-break.d.ts.map +1 -1
  40. package/dist/prosekit-extensions-heading.d.ts.map +1 -1
  41. package/dist/prosekit-extensions-heading.js +1 -1
  42. package/dist/prosekit-extensions-horizontal-rule.d.ts.map +1 -1
  43. package/dist/prosekit-extensions-horizontal-rule.js +1 -1
  44. package/dist/prosekit-extensions-image.d.ts +86 -30
  45. package/dist/prosekit-extensions-image.d.ts.map +1 -1
  46. package/dist/prosekit-extensions-image.js +93 -52
  47. package/dist/prosekit-extensions-image.js.map +1 -1
  48. package/dist/prosekit-extensions-input-rule.d.ts.map +1 -1
  49. package/dist/prosekit-extensions-input-rule.js +1 -1
  50. package/dist/prosekit-extensions-italic.d.ts.map +1 -1
  51. package/dist/prosekit-extensions-italic.js +1 -1
  52. package/dist/prosekit-extensions-link.d.ts.map +1 -1
  53. package/dist/prosekit-extensions-link.js +4 -4
  54. package/dist/prosekit-extensions-list.d.ts.map +1 -1
  55. package/dist/prosekit-extensions-list.js +37 -10
  56. package/dist/prosekit-extensions-list.js.map +1 -1
  57. package/dist/prosekit-extensions-loro.d.ts.map +1 -1
  58. package/dist/prosekit-extensions-mark-rule.d.ts.map +1 -1
  59. package/dist/prosekit-extensions-mark-rule.js +1 -1
  60. package/dist/prosekit-extensions-mention.d.ts.map +1 -1
  61. package/dist/prosekit-extensions-paragraph.d.ts.map +1 -1
  62. package/dist/prosekit-extensions-paste-rule.d.ts.map +1 -1
  63. package/dist/prosekit-extensions-paste-rule.js +1 -1
  64. package/dist/prosekit-extensions-placeholder.d.ts.map +1 -1
  65. package/dist/prosekit-extensions-placeholder.js +3 -4
  66. package/dist/prosekit-extensions-placeholder.js.map +1 -1
  67. package/dist/prosekit-extensions-search.d.ts.map +1 -1
  68. package/dist/prosekit-extensions-search.js +1 -2
  69. package/dist/prosekit-extensions-search.js.map +1 -1
  70. package/dist/prosekit-extensions-strike.d.ts.map +1 -1
  71. package/dist/prosekit-extensions-strike.js +1 -1
  72. package/dist/prosekit-extensions-table.d.ts.map +1 -1
  73. package/dist/prosekit-extensions-table.js +2 -2
  74. package/dist/prosekit-extensions-text-align.d.ts.map +1 -1
  75. package/dist/prosekit-extensions-text.d.ts.map +1 -1
  76. package/dist/prosekit-extensions-underline.d.ts.map +1 -1
  77. package/dist/prosekit-extensions-yjs.d.ts.map +1 -1
  78. package/dist/{shiki-highlighter-chunk-Cwu1Jr9o.d.ts → shiki-highlighter-chunk-DcY3Ud8v.d.ts} +2 -2
  79. package/dist/shiki-highlighter-chunk-DcY3Ud8v.d.ts.map +1 -0
  80. package/dist/shiki-highlighter-chunk.d.ts +1 -1
  81. package/dist/{table-BNwuK7xg.js → table-BLjD91VB.js} +11 -20
  82. package/dist/{table-BNwuK7xg.js.map → table-BLjD91VB.js.map} +1 -1
  83. package/package.json +14 -14
  84. package/src/file/file-upload.ts +2 -10
  85. package/src/image/image-commands/insert-image.ts +14 -0
  86. package/src/image/image-commands/upload-image.ts +137 -0
  87. package/src/image/image-commands.ts +7 -12
  88. package/src/image/image-upload-handler.ts +10 -70
  89. package/src/image/index.ts +8 -3
  90. package/src/link/index.spec.ts +1 -1
  91. package/src/list/list-serializer.ts +57 -3
  92. package/src/list/list.spec.ts +129 -0
  93. package/src/testing/keyboard.ts +1 -1
  94. package/src/testing/markdown.ts +3 -0
  95. package/dist/enter-rule-RdhEA900.js.map +0 -1
  96. package/dist/index-DY6lIIYV.d.ts.map +0 -1
  97. package/dist/input-rule-B17tpW4m.js.map +0 -1
  98. package/dist/shiki-highlighter-chunk-Cwu1Jr9o.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-code-block.js","names":["existCodeBlock: Command","loaded: ((options: HighlighterOptions) => HighlighterResult) | undefined","createOrGetHighlighter","parser: Parser | undefined"],"sources":["../src/code-block/code-block-commands.ts","../src/code-block/code-block-input-rule.ts","../src/code-block/code-block-keymap.ts","../src/code-block/code-block-spec.ts","../src/code-block/code-block.ts","../src/code-block/code-block-highlight.ts","../src/code-block/shiki-highlighter.ts","../src/code-block/shiki-parser.ts","../src/code-block/code-block-shiki.ts"],"sourcesContent":["import {\n defineCommands,\n insertNode,\n setBlockType,\n setNodeAttrs,\n toggleNode,\n type Extension,\n} from '@prosekit/core'\n\nimport type { CodeBlockAttrs } from './code-block-types'\n\n/**\n * @internal\n */\nexport type CodeBlockCommandsExtension = Extension<{\n Commands: {\n setCodeBlock: [attrs?: CodeBlockAttrs]\n insertCodeBlock: [attrs?: CodeBlockAttrs]\n toggleCodeBlock: [attrs?: CodeBlockAttrs]\n setCodeBlockAttrs: [attrs: CodeBlockAttrs]\n }\n}>\n\n/**\n * Adds commands for working with `codeBlock` nodes.\n *\n * @public\n */\nexport function defineCodeBlockCommands(): CodeBlockCommandsExtension {\n return defineCommands({\n setCodeBlock: (attrs?: CodeBlockAttrs) => {\n return setBlockType({ type: 'codeBlock', attrs })\n },\n insertCodeBlock: (attrs?: CodeBlockAttrs) => {\n return insertNode({ type: 'codeBlock', attrs })\n },\n toggleCodeBlock: (attrs?: CodeBlockAttrs) => {\n return toggleNode({ type: 'codeBlock', attrs })\n },\n setCodeBlockAttrs: (attrs: CodeBlockAttrs) => {\n return setNodeAttrs({ type: 'codeBlock', attrs })\n },\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport { defineTextBlockEnterRule } from '../enter-rule'\nimport { defineTextBlockInputRule } from '../input-rule'\n\nimport type { CodeBlockAttrs } from './code-block-types'\n\n/**\n * Adds input rules for `codeBlock` nodes.\n *\n * @public\n */\nexport function defineCodeBlockInputRule(): PlainExtension {\n return defineTextBlockInputRule({\n regex: /^```(\\S*)\\s$/,\n type: 'codeBlock',\n attrs: getAttrs,\n })\n}\n\n/**\n * Adds enter rules for `codeBlock` nodes.\n *\n * @public\n */\nexport function defineCodeBlockEnterRule(): PlainExtension {\n return defineTextBlockEnterRule({\n regex: /^```(\\S*)$/,\n type: 'codeBlock',\n attrs: getAttrs,\n })\n}\n\nfunction getAttrs(match: RegExpMatchArray): CodeBlockAttrs {\n return { language: match[1] || '' }\n}\n","import {\n defaultBlockAt,\n defineKeymap,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n TextSelection,\n type Command,\n} from '@prosekit/pm/state'\n\n/**\n * Defines the keymap for code blocks.\n */\nexport function defineCodeBlockKeymap(): PlainExtension {\n return defineKeymap({\n Enter: existCodeBlock,\n })\n}\n\n/**\n * Exit a code block and insert a default block below if the cursor is at the\n * end of the code block and the code block is ended with two new lines.\n */\nconst existCodeBlock: Command = (state, dispatch) => {\n if (!state.selection.empty) {\n return false\n }\n\n const { $head } = state.selection\n const parent = $head.parent\n if (\n parent.isTextblock\n && parent.type.spec.code\n && $head.parentOffset === parent.content.size\n && parent.textContent.endsWith('\\n\\n')\n ) {\n const grandParent = $head.node(-1)\n const insertIndex = $head.indexAfter(-1)\n const type = defaultBlockAt(grandParent.contentMatchAt(insertIndex))\n\n if (!type || !grandParent.canReplaceWith(insertIndex, insertIndex, type)) {\n return false\n }\n\n if (dispatch) {\n const { tr } = state\n tr.delete($head.pos - 2, $head.pos)\n const pos = tr.selection.$head.after()\n const node = type.createAndFill()\n if (node) {\n tr.replaceWith(pos, pos, node)\n tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1))\n dispatch(tr.scrollIntoView())\n }\n }\n\n return true\n }\n\n return false\n}\n","import {\n defineNodeSpec,\n type Extension,\n} from '@prosekit/core'\n\nimport type { CodeBlockAttrs } from './code-block-types'\n\n/**\n * @internal\n */\nexport type CodeBlockSpecExtension = Extension<{\n Nodes: {\n codeBlock: CodeBlockAttrs\n }\n}>\n\n/**\n * Defines the `codeBlock` node spec.\n *\n * @public\n */\nexport function defineCodeBlockSpec(): CodeBlockSpecExtension {\n return defineNodeSpec({\n name: 'codeBlock',\n content: 'text*',\n group: 'block',\n code: true,\n defining: true,\n marks: '',\n attrs: { language: { default: '', validate: 'string' } },\n parseDOM: [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n getAttrs: (node): CodeBlockAttrs => {\n const language = extractLanguageFromElement(node)\n || extractLanguageFromElement(node.querySelector('code'))\n return { language }\n },\n },\n ],\n toDOM(node) {\n const { language } = node.attrs as CodeBlockAttrs\n return [\n 'pre',\n { 'data-language': language || undefined },\n // `class: language-${language}` is used by remark-rehype to highlight the code block\n ['code', { class: language ? `language-${language}` : undefined }, 0],\n ]\n },\n })\n}\n\nfunction extractLanguageFromElement(element: HTMLElement | null | undefined): string {\n if (!element) {\n return ''\n }\n\n const attr = element.getAttribute('data-language')\n if (attr) {\n return attr\n }\n\n const className = element.className\n const match = className.match(/language-(\\w+)/)\n if (match) {\n return match[1]\n }\n\n return ''\n}\n","import {\n union,\n type Union,\n} from '@prosekit/core'\n\nimport {\n defineCodeBlockCommands,\n type CodeBlockCommandsExtension,\n} from './code-block-commands'\nimport {\n defineCodeBlockEnterRule,\n defineCodeBlockInputRule,\n} from './code-block-input-rule'\nimport { defineCodeBlockKeymap } from './code-block-keymap'\nimport {\n defineCodeBlockSpec,\n type CodeBlockSpecExtension,\n} from './code-block-spec'\n\n/**\n * @internal\n */\nexport type CodeBlockExtension = Union<\n [CodeBlockSpecExtension, CodeBlockCommandsExtension]\n>\n\n/**\n * Adds `codeBlock` nodes to the editor. This includes the following extensions:\n *\n * - {@link defineCodeBlockSpec}\n * - {@link defineCodeBlockInputRule}\n * - {@link defineCodeBlockEnterRule}\n * - {@link defineCodeBlockKeymap}\n * - {@link defineCodeBlockCommands}.\n *\n * @public\n */\nexport function defineCodeBlock(): CodeBlockExtension {\n return union(\n defineCodeBlockSpec(),\n defineCodeBlockInputRule(),\n defineCodeBlockEnterRule(),\n defineCodeBlockKeymap(),\n defineCodeBlockCommands(),\n )\n}\n","import {\n definePlugin,\n type Extension,\n} from '@prosekit/core'\nimport {\n createHighlightPlugin,\n type Parser,\n} from 'prosemirror-highlight'\n\n/**\n * @public\n *\n * An alias for the `Parser` type from the `prosemirror-highlight` package.\n */\nexport type HighlightParser = Parser\n\n/**\n * @public\n */\nexport type CodeBlockHighlightOptions = {\n parser: HighlightParser\n}\n\n/**\n * Adds syntax highlighting to code blocks. This function requires a `Parser`\n * instance from the `prosemirror-highlight` package. See the\n * [documentation](https://github.com/ocavue/prosemirror-highlight) for more\n * information.\n *\n * @param options\n *\n * @public\n */\nexport function defineCodeBlockHighlight({\n parser,\n}: CodeBlockHighlightOptions): Extension {\n return definePlugin(\n createHighlightPlugin({ parser }),\n )\n}\n","import type {\n HighlighterOptions,\n HighlighterResult,\n} from './shiki-highlighter-chunk'\n\nlet loaded: ((options: HighlighterOptions) => HighlighterResult) | undefined\n\nasync function load() {\n const { createOrGetHighlighter } = await import('./shiki-highlighter-chunk')\n loaded = createOrGetHighlighter\n}\n\nexport function createOrGetHighlighter(\n options: HighlighterOptions,\n): HighlighterResult {\n if (!loaded) {\n return { promise: load() }\n }\n return loaded(options)\n}\n\nexport type { HighlighterOptions }\n","import type { Parser } from 'prosemirror-highlight'\nimport { createParser } from 'prosemirror-highlight/shiki'\n\nimport type { ShikiBundledLanguage } from './shiki-bundle'\nimport {\n createOrGetHighlighter,\n type HighlighterOptions,\n} from './shiki-highlighter'\n\n/**\n * @internal\n */\nexport function createLazyParser(\n highlighterOptions: HighlighterOptions,\n): Parser {\n let parser: Parser | undefined\n\n return function lazyParser(options) {\n const language = (options.language || '') as ShikiBundledLanguage\n const { highlighter, promise } = createOrGetHighlighter({\n ...highlighterOptions,\n langs: [language],\n })\n\n if (!highlighter) {\n return promise\n }\n\n if (!parser) {\n parser = createParser(highlighter, {\n theme: highlighterOptions.themes[0],\n })\n }\n return parser(options)\n }\n}\n","import type { Extension } from '@prosekit/core'\nimport type { SpecialLanguage } from 'shiki'\n\nimport { defineCodeBlockHighlight } from './code-block-highlight'\nimport type {\n ShikiBundledLanguage,\n ShikiBundledTheme,\n} from './shiki-bundle'\nimport type { ShikiHighlighterOptions } from './shiki-highlighter-chunk'\nimport { createLazyParser } from './shiki-parser'\n\n/**\n * The options to configure the Shiki highlighter.\n *\n * @public\n */\nexport interface CodeBlockShikiOptions extends Omit<ShikiHighlighterOptions, 'themes' | 'langs' | 'engine'> {\n /**\n * A list of Shiki themes to pre-load. The first theme in the list will be\n * used to render the code block.\n *\n * @default ['one-dark-pro']\n */\n themes?: ShikiBundledTheme[]\n\n /**\n * A list of Shiki languages to pre-load.\n *\n * @default ['text']\n */\n langs?: (ShikiBundledLanguage | SpecialLanguage)[]\n\n /**\n * The RegExp engine to use. By default, the JavaScript engine is used.\n */\n engine?: ShikiHighlighterOptions['engine']\n}\n\n/**\n * Adds syntax highlighting to code blocks using the [Shiki](https://github.com/shikijs/shiki) package.\n *\n * It will set two CSS variables on the code block elements:\n *\n * - `--prosemirror-highlight`: sets text color\n * - `--prosemirror-highlight-bg`: sets background color\n *\n * @param options - The options to configure the Shiki highlighter.\n *\n * @public\n */\nexport function defineCodeBlockShiki({\n themes = ['one-dark-pro'],\n langs = ['text'],\n ...rest\n}: CodeBlockShikiOptions = {}): Extension {\n const parser = createLazyParser({ themes, langs, ...rest })\n return defineCodeBlockHighlight({ parser })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"prosekit-extensions-code-block.js","names":["existCodeBlock: Command","loaded: ((options: HighlighterOptions) => HighlighterResult) | undefined","createOrGetHighlighter","parser: Parser | undefined"],"sources":["../src/code-block/code-block-commands.ts","../src/code-block/code-block-input-rule.ts","../src/code-block/code-block-keymap.ts","../src/code-block/code-block-spec.ts","../src/code-block/code-block.ts","../src/code-block/code-block-highlight.ts","../src/code-block/shiki-highlighter.ts","../src/code-block/shiki-parser.ts","../src/code-block/code-block-shiki.ts"],"sourcesContent":["import {\n defineCommands,\n insertNode,\n setBlockType,\n setNodeAttrs,\n toggleNode,\n type Extension,\n} from '@prosekit/core'\n\nimport type { CodeBlockAttrs } from './code-block-types'\n\n/**\n * @internal\n */\nexport type CodeBlockCommandsExtension = Extension<{\n Commands: {\n setCodeBlock: [attrs?: CodeBlockAttrs]\n insertCodeBlock: [attrs?: CodeBlockAttrs]\n toggleCodeBlock: [attrs?: CodeBlockAttrs]\n setCodeBlockAttrs: [attrs: CodeBlockAttrs]\n }\n}>\n\n/**\n * Adds commands for working with `codeBlock` nodes.\n *\n * @public\n */\nexport function defineCodeBlockCommands(): CodeBlockCommandsExtension {\n return defineCommands({\n setCodeBlock: (attrs?: CodeBlockAttrs) => {\n return setBlockType({ type: 'codeBlock', attrs })\n },\n insertCodeBlock: (attrs?: CodeBlockAttrs) => {\n return insertNode({ type: 'codeBlock', attrs })\n },\n toggleCodeBlock: (attrs?: CodeBlockAttrs) => {\n return toggleNode({ type: 'codeBlock', attrs })\n },\n setCodeBlockAttrs: (attrs: CodeBlockAttrs) => {\n return setNodeAttrs({ type: 'codeBlock', attrs })\n },\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport { defineTextBlockEnterRule } from '../enter-rule'\nimport { defineTextBlockInputRule } from '../input-rule'\n\nimport type { CodeBlockAttrs } from './code-block-types'\n\n/**\n * Adds input rules for `codeBlock` nodes.\n *\n * @public\n */\nexport function defineCodeBlockInputRule(): PlainExtension {\n return defineTextBlockInputRule({\n regex: /^```(\\S*)\\s$/,\n type: 'codeBlock',\n attrs: getAttrs,\n })\n}\n\n/**\n * Adds enter rules for `codeBlock` nodes.\n *\n * @public\n */\nexport function defineCodeBlockEnterRule(): PlainExtension {\n return defineTextBlockEnterRule({\n regex: /^```(\\S*)$/,\n type: 'codeBlock',\n attrs: getAttrs,\n })\n}\n\nfunction getAttrs(match: RegExpMatchArray): CodeBlockAttrs {\n return { language: match[1] || '' }\n}\n","import {\n defaultBlockAt,\n defineKeymap,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n TextSelection,\n type Command,\n} from '@prosekit/pm/state'\n\n/**\n * Defines the keymap for code blocks.\n */\nexport function defineCodeBlockKeymap(): PlainExtension {\n return defineKeymap({\n Enter: existCodeBlock,\n })\n}\n\n/**\n * Exit a code block and insert a default block below if the cursor is at the\n * end of the code block and the code block is ended with two new lines.\n */\nconst existCodeBlock: Command = (state, dispatch) => {\n if (!state.selection.empty) {\n return false\n }\n\n const { $head } = state.selection\n const parent = $head.parent\n if (\n parent.isTextblock\n && parent.type.spec.code\n && $head.parentOffset === parent.content.size\n && parent.textContent.endsWith('\\n\\n')\n ) {\n const grandParent = $head.node(-1)\n const insertIndex = $head.indexAfter(-1)\n const type = defaultBlockAt(grandParent.contentMatchAt(insertIndex))\n\n if (!type || !grandParent.canReplaceWith(insertIndex, insertIndex, type)) {\n return false\n }\n\n if (dispatch) {\n const { tr } = state\n tr.delete($head.pos - 2, $head.pos)\n const pos = tr.selection.$head.after()\n const node = type.createAndFill()\n if (node) {\n tr.replaceWith(pos, pos, node)\n tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1))\n dispatch(tr.scrollIntoView())\n }\n }\n\n return true\n }\n\n return false\n}\n","import {\n defineNodeSpec,\n type Extension,\n} from '@prosekit/core'\n\nimport type { CodeBlockAttrs } from './code-block-types'\n\n/**\n * @internal\n */\nexport type CodeBlockSpecExtension = Extension<{\n Nodes: {\n codeBlock: CodeBlockAttrs\n }\n}>\n\n/**\n * Defines the `codeBlock` node spec.\n *\n * @public\n */\nexport function defineCodeBlockSpec(): CodeBlockSpecExtension {\n return defineNodeSpec({\n name: 'codeBlock',\n content: 'text*',\n group: 'block',\n code: true,\n defining: true,\n marks: '',\n attrs: { language: { default: '', validate: 'string' } },\n parseDOM: [\n {\n tag: 'pre',\n preserveWhitespace: 'full',\n getAttrs: (node): CodeBlockAttrs => {\n const language = extractLanguageFromElement(node)\n || extractLanguageFromElement(node.querySelector('code'))\n return { language }\n },\n },\n ],\n toDOM(node) {\n const { language } = node.attrs as CodeBlockAttrs\n return [\n 'pre',\n { 'data-language': language || undefined },\n // `class: language-${language}` is used by remark-rehype to highlight the code block\n ['code', { class: language ? `language-${language}` : undefined }, 0],\n ]\n },\n })\n}\n\nfunction extractLanguageFromElement(element: HTMLElement | null | undefined): string {\n if (!element) {\n return ''\n }\n\n const attr = element.getAttribute('data-language')\n if (attr) {\n return attr\n }\n\n const className = element.className\n const match = className.match(/language-(\\w+)/)\n if (match) {\n return match[1]\n }\n\n return ''\n}\n","import {\n union,\n type Union,\n} from '@prosekit/core'\n\nimport {\n defineCodeBlockCommands,\n type CodeBlockCommandsExtension,\n} from './code-block-commands'\nimport {\n defineCodeBlockEnterRule,\n defineCodeBlockInputRule,\n} from './code-block-input-rule'\nimport { defineCodeBlockKeymap } from './code-block-keymap'\nimport {\n defineCodeBlockSpec,\n type CodeBlockSpecExtension,\n} from './code-block-spec'\n\n/**\n * @internal\n */\nexport type CodeBlockExtension = Union<\n [CodeBlockSpecExtension, CodeBlockCommandsExtension]\n>\n\n/**\n * Adds `codeBlock` nodes to the editor. This includes the following extensions:\n *\n * - {@link defineCodeBlockSpec}\n * - {@link defineCodeBlockInputRule}\n * - {@link defineCodeBlockEnterRule}\n * - {@link defineCodeBlockKeymap}\n * - {@link defineCodeBlockCommands}.\n *\n * @public\n */\nexport function defineCodeBlock(): CodeBlockExtension {\n return union(\n defineCodeBlockSpec(),\n defineCodeBlockInputRule(),\n defineCodeBlockEnterRule(),\n defineCodeBlockKeymap(),\n defineCodeBlockCommands(),\n )\n}\n","import {\n definePlugin,\n type Extension,\n} from '@prosekit/core'\nimport {\n createHighlightPlugin,\n type Parser,\n} from 'prosemirror-highlight'\n\n/**\n * @public\n *\n * An alias for the `Parser` type from the `prosemirror-highlight` package.\n */\nexport type HighlightParser = Parser\n\n/**\n * @public\n */\nexport type CodeBlockHighlightOptions = {\n parser: HighlightParser\n}\n\n/**\n * Adds syntax highlighting to code blocks. This function requires a `Parser`\n * instance from the `prosemirror-highlight` package. See the\n * [documentation](https://github.com/ocavue/prosemirror-highlight) for more\n * information.\n *\n * @param options\n *\n * @public\n */\nexport function defineCodeBlockHighlight({\n parser,\n}: CodeBlockHighlightOptions): Extension {\n return definePlugin(\n createHighlightPlugin({ parser }),\n )\n}\n","import type {\n HighlighterOptions,\n HighlighterResult,\n} from './shiki-highlighter-chunk'\n\nlet loaded: ((options: HighlighterOptions) => HighlighterResult) | undefined\n\nasync function load() {\n const { createOrGetHighlighter } = await import('./shiki-highlighter-chunk')\n loaded = createOrGetHighlighter\n}\n\nexport function createOrGetHighlighter(\n options: HighlighterOptions,\n): HighlighterResult {\n if (!loaded) {\n return { promise: load() }\n }\n return loaded(options)\n}\n\nexport type { HighlighterOptions }\n","import type { Parser } from 'prosemirror-highlight'\nimport { createParser } from 'prosemirror-highlight/shiki'\n\nimport type { ShikiBundledLanguage } from './shiki-bundle'\nimport {\n createOrGetHighlighter,\n type HighlighterOptions,\n} from './shiki-highlighter'\n\n/**\n * @internal\n */\nexport function createLazyParser(\n highlighterOptions: HighlighterOptions,\n): Parser {\n let parser: Parser | undefined\n\n return function lazyParser(options) {\n const language = (options.language || '') as ShikiBundledLanguage\n const { highlighter, promise } = createOrGetHighlighter({\n ...highlighterOptions,\n langs: [language],\n })\n\n if (!highlighter) {\n return promise\n }\n\n if (!parser) {\n parser = createParser(highlighter, {\n theme: highlighterOptions.themes[0],\n })\n }\n return parser(options)\n }\n}\n","import type { Extension } from '@prosekit/core'\nimport type { SpecialLanguage } from 'shiki'\n\nimport { defineCodeBlockHighlight } from './code-block-highlight'\nimport type {\n ShikiBundledLanguage,\n ShikiBundledTheme,\n} from './shiki-bundle'\nimport type { ShikiHighlighterOptions } from './shiki-highlighter-chunk'\nimport { createLazyParser } from './shiki-parser'\n\n/**\n * The options to configure the Shiki highlighter.\n *\n * @public\n */\nexport interface CodeBlockShikiOptions extends Omit<ShikiHighlighterOptions, 'themes' | 'langs' | 'engine'> {\n /**\n * A list of Shiki themes to pre-load. The first theme in the list will be\n * used to render the code block.\n *\n * @default ['one-dark-pro']\n */\n themes?: ShikiBundledTheme[]\n\n /**\n * A list of Shiki languages to pre-load.\n *\n * @default ['text']\n */\n langs?: (ShikiBundledLanguage | SpecialLanguage)[]\n\n /**\n * The RegExp engine to use. By default, the JavaScript engine is used.\n */\n engine?: ShikiHighlighterOptions['engine']\n}\n\n/**\n * Adds syntax highlighting to code blocks using the [Shiki](https://github.com/shikijs/shiki) package.\n *\n * It will set two CSS variables on the code block elements:\n *\n * - `--prosemirror-highlight`: sets text color\n * - `--prosemirror-highlight-bg`: sets background color\n *\n * @param options - The options to configure the Shiki highlighter.\n *\n * @public\n */\nexport function defineCodeBlockShiki({\n themes = ['one-dark-pro'],\n langs = ['text'],\n ...rest\n}: CodeBlockShikiOptions = {}): Extension {\n const parser = createLazyParser({ themes, langs, ...rest })\n return defineCodeBlockHighlight({ parser })\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-code.d.ts","names":[],"sources":["../src/code/code-commands.ts","../src/code/code-spec.ts","../src/code/code.ts","../src/code/code-input-rule.ts","../src/code/code-keymap.ts"],"sourcesContent":[],"mappings":";;;;;;;AASY,KAAA,qBAAA,GAAwB,SAAA,CAAA;EASpB,QAAA,EAAA;;;;ACThB;;;AAAgC,iBDShB,kBAAA,CAAA,CCTgB,EDSM,qBCTN;;;;;ADAhC;AASgB,KCTJ,iBAAA,GAAoB,SDSM,CAAA;;UCP5B;;AAFV,CAAA,CAAA;;;;AAAyC,iBASzB,cAAA,CAAA,CATyB,EASP,iBATO;;;;ADAzC;AASA;KECY,aAAA,GAAgB,OAAO,mBAAmB;;;ADVtD;AAA6B,iBCeb,UAAA,CAAA,CDfa,ECeC,aDfD;;;;;;ADAjB,iBGCI,mBAAA,CAAA,CHDoB,EGCG,cHDM;;;;;;AAAjC,iBIAI,gBAAA,CAAA,CJAoB,EIAA,cJAS"}
1
+ {"version":3,"file":"prosekit-extensions-code.d.ts","names":[],"sources":["../src/code/code-commands.ts","../src/code/code-spec.ts","../src/code/code.ts","../src/code/code-input-rule.ts","../src/code/code-keymap.ts"],"sourcesContent":[],"mappings":";;;;;;;AASY,KAAA,qBAAA,GAAwB,SAAA,CAAA;EASpB,QAAA,EAAA;;;;ACThB;AASA;;iBDAgB,kBAAA,CAAA,GAAsB;;;;;AATtC;AASgB,KCTJ,iBAAA,GAAoB,SDSM,CAAA;;UCP5B;;AAFV,CAAA,CAAA;AASA;;;iBAAgB,cAAA,CAAA,GAAkB;;;;ADTlC;AASA;KECY,aAAA,GAAgB,OAAO,mBAAmB;;;ADVtD;AASgB,iBCMA,UAAA,CAAA,CDNkB,ECMJ,aDNI;;;;;;ADTtB,iBGCI,mBAAA,CAAA,CHDoB,EGCG,cHDM;;;;;;AAAjC,iBIAI,gBAAA,CAAA,CJAoB,EIAA,cJAS"}
@@ -1,4 +1,4 @@
1
- import { defineMarkInputRule } from "./input-rule-B17tpW4m.js";
1
+ import { r as defineMarkInputRule } from "./input-rule-COGr_GBb.js";
2
2
  import { canUseRegexLookbehind, defineCommands, defineKeymap, defineMarkSpec, toggleMark, union } from "@prosekit/core";
3
3
 
4
4
  //#region src/code/code-commands.ts
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-commit.d.ts","names":[],"sources":["../src/commit/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAmB2B;UAejB,MAAA,CAAM;;;;EAaC,GAAA,EATV,QASU;EA2MR;;;QAAoC,EAhNnC,QAgNmC;EAAc;AAAA;;;OAsC/C,EAjPH,QAiPG,EAAA;;;AASW;;iBA/Cd,kBAAA,CAwDqC,MAAA,EAxDV,MAwDU,CAAA,EAxDD,cAwDC;cAjDxC,cAAA,CAiDyD;EAAc,QAAA,MAAA;;;;;;;YAxCjE;;;;YAsBA;;;;YASA;;;;;iBASH,oBAAA,iBAAqC,iBAAiB"}
1
+ {"version":3,"file":"prosekit-extensions-commit.d.ts","names":[],"sources":["../src/commit/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAmB2B;UAejB,MAAA,CAIH;EAIG;;;EAgND,GAAA,EApNF,QAoNE;EAOH;;;EAwCM,MAAA,EA/PF,QA+PE;EAAW;AAAA;;;SA1Pd;;;;;iBA2MA,kBAAA,SAA2B,SAAS;cAOvC,cAAA;;;;;;;;YASM;;;;YAsBA;;;;YASA;;;;;iBASH,oBAAA,iBAAqC,iBAAiB"}
@@ -53,8 +53,7 @@ function decorateDeletionSlice(slice) {
53
53
  return [render];
54
54
  }
55
55
  function decorateDeletion(doc, from, to, pos) {
56
- const slice = doc.slice(from, to);
57
- const renders = decorateDeletionSlice(slice);
56
+ const renders = decorateDeletionSlice(doc.slice(from, to));
58
57
  const count = renders.length;
59
58
  return renders.map((render, index) => Decoration.widget(pos, render, {
60
59
  side: -20 - count + index,
@@ -142,9 +141,8 @@ var CommitRecorder = class {
142
141
  * Define an extension that can record the changes in the editor.
143
142
  */
144
143
  function defineCommitRecorder(commitRecorder) {
145
- const key = new PluginKey("prosekit-commit-recorder");
146
144
  return definePlugin(new ProseMirrorPlugin({
147
- key,
145
+ key: new PluginKey("prosekit-commit-recorder"),
148
146
  state: {
149
147
  init: (_, state) => {
150
148
  commitRecorder.init(state.doc);
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-commit.js","names":["decorations: Decoration[]","commit: Commit"],"sources":["../src/commit/index.ts"],"sourcesContent":["import {\n defineDefaultState,\n definePlugin,\n jsonFromNode,\n union,\n type NodeJSON,\n type PlainExtension,\n type StepJSON,\n} from '@prosekit/core'\nimport {\n DOMSerializer,\n Fragment,\n Slice,\n type ProseMirrorNode,\n} from '@prosekit/pm/model'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n type Transaction,\n} from '@prosekit/pm/state'\nimport { Step } from '@prosekit/pm/transform'\nimport {\n Decoration,\n DecorationSet,\n type EditorView,\n} from '@prosekit/pm/view'\nimport {\n ChangeSet,\n type Change,\n} from 'prosemirror-changeset'\n\n/**\n * A JSON representation of a commit.\n */\ninterface Commit {\n /**\n * The current doc node in the JSON format\n */\n doc: NodeJSON\n /**\n * The parent node in the JSON format\n */\n parent: NodeJSON\n /**\n * An array of steps in the JSON format that transform the parent node to the\n * current doc node.\n */\n steps: StepJSON[]\n}\n\nfunction getChanges(\n doc: ProseMirrorNode,\n parent: ProseMirrorNode,\n steps: Step[],\n): readonly Change[] {\n const initSet = ChangeSet.create(parent)\n const currSet = initSet.addSteps(\n doc,\n steps.map((step) => step.getMap()),\n null,\n )\n return currSet.changes\n}\n\nfunction renderDivWeight(view: EditorView): HTMLElement {\n const document = view.dom.ownerDocument\n return document.createElement('div')\n}\n\nfunction decorateDeletionSlice(\n slice: Slice,\n): Array<(view: EditorView) => HTMLElement> {\n // Get the fragment of the deleted content\n let { openStart, openEnd, content } = slice\n\n while (openStart > 0 && openEnd > 0 && content.childCount === 1) {\n openStart--\n openEnd--\n content = content.child(0).content\n }\n\n // Nothing to render\n if (content.childCount === 0) {\n return []\n }\n\n // For example, if the slice is\n // {\n // openStart: 1,\n // openEnd: 1,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <span>Hello</span>\n // <div></div>\n // <span>World</span>\n if (openStart > 0 && openEnd > 0 && content.childCount === 2) {\n const head = Fragment.from([content.child(0)])\n const tail = Fragment.from([content.child(1)])\n return [\n ...decorateDeletionSlice(new Slice(head, openStart, openStart)),\n renderDivWeight,\n ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd)),\n ]\n }\n\n // For example, if the slice is\n // {\n // openStart: 1,\n // openEnd: 0,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <span>Hello</span>\n // <div><p>World</p></div>\n if (openStart > 0 && content.childCount >= 2) {\n const nodes = content.content\n const head = Fragment.from(nodes.slice(0, 1))\n const body = Fragment.from(nodes.slice(1))\n\n return [\n ...decorateDeletionSlice(new Slice(head, openStart, openStart)),\n ...decorateDeletionSlice(new Slice(body, 0, openEnd)),\n ]\n }\n\n // For example, if the slice is\n // {\n // openStart: 0,\n // openEnd: 1,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <div><p>Hello</p></div>\n // <span>World</span>\n if (openEnd > 0 && content.childCount >= 2) {\n const nodes = content.content\n const body = Fragment.from(nodes.slice(0, -1))\n const tail = Fragment.from(nodes.slice(-1))\n return [\n ...decorateDeletionSlice(new Slice(body, openStart, 0)),\n ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd)),\n ]\n }\n\n const schema = content.child(0).type.schema\n const isInline = content.child(0).isInline\n\n const render = (view: EditorView): HTMLElement => {\n const document = view.dom.ownerDocument\n\n // Render the fragment to HTML\n const element = document.createElement(isInline ? 'span' : 'div')\n const serializer = DOMSerializer.fromSchema(schema)\n serializer.serializeFragment(content, { document }, element)\n\n // Add the class to the element\n element.classList.add('prosekit-commit-deletion')\n return element\n }\n\n return [render]\n}\n\nfunction decorateDeletion(\n /** The doc node before the deletion */\n doc: ProseMirrorNode,\n /** The start position of the deleted text in the doc node */\n from: number,\n /** The end position of the deleted text in the doc node */\n to: number,\n /** The insert position of the decoration in the doc node after the change */\n pos: number,\n): Decoration[] {\n const slice = doc.slice(from, to)\n\n const renders = decorateDeletionSlice(slice)\n const count = renders.length\n\n return renders.map((render, index) =>\n Decoration.widget(pos, render, {\n side: -20 - count + index,\n // Ensure the text in the decoration is able to be selected.\n ignoreSelection: true,\n })\n )\n}\n\nfunction decorateAddition(\n /** The start position of the inserted text in the doc node */\n from: number,\n /** The end position of the inserted text in the doc node */\n to: number,\n): Decoration {\n return Decoration.inline(from, to, { class: 'prosekit-commit-addition' })\n}\n\nfunction decorateChange(prev: ProseMirrorNode, change: Change): Decoration[] {\n const { fromA, toA, fromB, toB } = change\n const decorations: Decoration[] = []\n\n if (fromA < toA) {\n decorations.push(...decorateDeletion(prev, fromA, toA, fromB))\n }\n if (fromB < toB) {\n decorations.push(decorateAddition(fromB, toB))\n }\n\n return decorations\n}\n\nfunction decorateCommit(\n doc: ProseMirrorNode,\n parent: ProseMirrorNode,\n steps: Step[],\n): DecorationSet {\n const changes = getChanges(doc, parent, steps)\n const decorations = changes.flatMap((change) => decorateChange(parent, change))\n return DecorationSet.create(doc, decorations)\n}\n\nfunction defineCommitDecoration(commit: Commit): PlainExtension {\n const key = new PluginKey<DecorationSet>('prosekit-commit-decoration')\n\n return definePlugin(({ schema }): ProseMirrorPlugin => {\n const parent = schema.nodeFromJSON(commit.parent)\n const steps = commit.steps.map((step) => Step.fromJSON(schema, step))\n\n return new ProseMirrorPlugin({\n key,\n state: {\n init: (_, instance): DecorationSet => {\n return decorateCommit(instance.doc, parent, steps)\n },\n apply: (tr, deco: DecorationSet): DecorationSet => {\n return deco.map(tr.mapping, tr.doc)\n },\n },\n props: {\n decorations: (state): DecorationSet | undefined => {\n return key.getState(state)\n },\n },\n })\n })\n}\n\n/**\n * Define an extension to display the changes from the given commit in the editor.\n */\nfunction defineCommitViewer(commit: Commit): PlainExtension {\n return union(\n defineDefaultState({ defaultDoc: commit.doc }),\n defineCommitDecoration(commit),\n )\n}\n\nclass CommitRecorder {\n private parent: ProseMirrorNode | null = null\n private doc: ProseMirrorNode | null = null\n private steps: Step[] = []\n\n /**\n * Return a commit object including all changes since the last commit. `null`\n * will be returned if there is no change.\n */\n commit(): Commit | null {\n if (\n !this.parent\n || !this.doc\n || this.steps.length === 0\n || this.parent.eq(this.doc)\n ) {\n return null\n }\n\n const commit: Commit = {\n doc: jsonFromNode(this.doc),\n parent: jsonFromNode(this.parent),\n steps: this.steps.map((step) => step.toJSON() as StepJSON),\n }\n this.init(this.doc)\n return commit\n }\n\n /**\n * @internal\n */\n init(doc: ProseMirrorNode): void {\n this.doc = doc\n this.parent = doc\n this.steps = []\n }\n\n /**\n * @internal\n */\n apply(tr: Transaction): void {\n this.steps.push(...tr.steps)\n this.doc = tr.doc\n }\n}\n\n/**\n * Define an extension that can record the changes in the editor.\n */\nfunction defineCommitRecorder(commitRecorder: CommitRecorder): PlainExtension {\n const key = new PluginKey<DecorationSet>('prosekit-commit-recorder')\n\n return definePlugin(\n new ProseMirrorPlugin({\n key,\n state: {\n init: (_, state): void => {\n commitRecorder.init(state.doc)\n },\n apply: (tr): void => {\n commitRecorder.apply(tr)\n },\n },\n }),\n )\n}\n\nexport {\n CommitRecorder,\n defineCommitRecorder,\n defineCommitViewer,\n type Commit,\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"prosekit-extensions-commit.js","names":["decorations: Decoration[]","commit: Commit"],"sources":["../src/commit/index.ts"],"sourcesContent":["import {\n defineDefaultState,\n definePlugin,\n jsonFromNode,\n union,\n type NodeJSON,\n type PlainExtension,\n type StepJSON,\n} from '@prosekit/core'\nimport {\n DOMSerializer,\n Fragment,\n Slice,\n type ProseMirrorNode,\n} from '@prosekit/pm/model'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n type Transaction,\n} from '@prosekit/pm/state'\nimport { Step } from '@prosekit/pm/transform'\nimport {\n Decoration,\n DecorationSet,\n type EditorView,\n} from '@prosekit/pm/view'\nimport {\n ChangeSet,\n type Change,\n} from 'prosemirror-changeset'\n\n/**\n * A JSON representation of a commit.\n */\ninterface Commit {\n /**\n * The current doc node in the JSON format\n */\n doc: NodeJSON\n /**\n * The parent node in the JSON format\n */\n parent: NodeJSON\n /**\n * An array of steps in the JSON format that transform the parent node to the\n * current doc node.\n */\n steps: StepJSON[]\n}\n\nfunction getChanges(\n doc: ProseMirrorNode,\n parent: ProseMirrorNode,\n steps: Step[],\n): readonly Change[] {\n const initSet = ChangeSet.create(parent)\n const currSet = initSet.addSteps(\n doc,\n steps.map((step) => step.getMap()),\n null,\n )\n return currSet.changes\n}\n\nfunction renderDivWeight(view: EditorView): HTMLElement {\n const document = view.dom.ownerDocument\n return document.createElement('div')\n}\n\nfunction decorateDeletionSlice(\n slice: Slice,\n): Array<(view: EditorView) => HTMLElement> {\n // Get the fragment of the deleted content\n let { openStart, openEnd, content } = slice\n\n while (openStart > 0 && openEnd > 0 && content.childCount === 1) {\n openStart--\n openEnd--\n content = content.child(0).content\n }\n\n // Nothing to render\n if (content.childCount === 0) {\n return []\n }\n\n // For example, if the slice is\n // {\n // openStart: 1,\n // openEnd: 1,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <span>Hello</span>\n // <div></div>\n // <span>World</span>\n if (openStart > 0 && openEnd > 0 && content.childCount === 2) {\n const head = Fragment.from([content.child(0)])\n const tail = Fragment.from([content.child(1)])\n return [\n ...decorateDeletionSlice(new Slice(head, openStart, openStart)),\n renderDivWeight,\n ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd)),\n ]\n }\n\n // For example, if the slice is\n // {\n // openStart: 1,\n // openEnd: 0,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <span>Hello</span>\n // <div><p>World</p></div>\n if (openStart > 0 && content.childCount >= 2) {\n const nodes = content.content\n const head = Fragment.from(nodes.slice(0, 1))\n const body = Fragment.from(nodes.slice(1))\n\n return [\n ...decorateDeletionSlice(new Slice(head, openStart, openStart)),\n ...decorateDeletionSlice(new Slice(body, 0, openEnd)),\n ]\n }\n\n // For example, if the slice is\n // {\n // openStart: 0,\n // openEnd: 1,\n // content: <p>Hello</p><p>World</p>\n // }\n // We should render the following decorations:\n // <div><p>Hello</p></div>\n // <span>World</span>\n if (openEnd > 0 && content.childCount >= 2) {\n const nodes = content.content\n const body = Fragment.from(nodes.slice(0, -1))\n const tail = Fragment.from(nodes.slice(-1))\n return [\n ...decorateDeletionSlice(new Slice(body, openStart, 0)),\n ...decorateDeletionSlice(new Slice(tail, openEnd, openEnd)),\n ]\n }\n\n const schema = content.child(0).type.schema\n const isInline = content.child(0).isInline\n\n const render = (view: EditorView): HTMLElement => {\n const document = view.dom.ownerDocument\n\n // Render the fragment to HTML\n const element = document.createElement(isInline ? 'span' : 'div')\n const serializer = DOMSerializer.fromSchema(schema)\n serializer.serializeFragment(content, { document }, element)\n\n // Add the class to the element\n element.classList.add('prosekit-commit-deletion')\n return element\n }\n\n return [render]\n}\n\nfunction decorateDeletion(\n /** The doc node before the deletion */\n doc: ProseMirrorNode,\n /** The start position of the deleted text in the doc node */\n from: number,\n /** The end position of the deleted text in the doc node */\n to: number,\n /** The insert position of the decoration in the doc node after the change */\n pos: number,\n): Decoration[] {\n const slice = doc.slice(from, to)\n\n const renders = decorateDeletionSlice(slice)\n const count = renders.length\n\n return renders.map((render, index) =>\n Decoration.widget(pos, render, {\n side: -20 - count + index,\n // Ensure the text in the decoration is able to be selected.\n ignoreSelection: true,\n })\n )\n}\n\nfunction decorateAddition(\n /** The start position of the inserted text in the doc node */\n from: number,\n /** The end position of the inserted text in the doc node */\n to: number,\n): Decoration {\n return Decoration.inline(from, to, { class: 'prosekit-commit-addition' })\n}\n\nfunction decorateChange(prev: ProseMirrorNode, change: Change): Decoration[] {\n const { fromA, toA, fromB, toB } = change\n const decorations: Decoration[] = []\n\n if (fromA < toA) {\n decorations.push(...decorateDeletion(prev, fromA, toA, fromB))\n }\n if (fromB < toB) {\n decorations.push(decorateAddition(fromB, toB))\n }\n\n return decorations\n}\n\nfunction decorateCommit(\n doc: ProseMirrorNode,\n parent: ProseMirrorNode,\n steps: Step[],\n): DecorationSet {\n const changes = getChanges(doc, parent, steps)\n const decorations = changes.flatMap((change) => decorateChange(parent, change))\n return DecorationSet.create(doc, decorations)\n}\n\nfunction defineCommitDecoration(commit: Commit): PlainExtension {\n const key = new PluginKey<DecorationSet>('prosekit-commit-decoration')\n\n return definePlugin(({ schema }): ProseMirrorPlugin => {\n const parent = schema.nodeFromJSON(commit.parent)\n const steps = commit.steps.map((step) => Step.fromJSON(schema, step))\n\n return new ProseMirrorPlugin({\n key,\n state: {\n init: (_, instance): DecorationSet => {\n return decorateCommit(instance.doc, parent, steps)\n },\n apply: (tr, deco: DecorationSet): DecorationSet => {\n return deco.map(tr.mapping, tr.doc)\n },\n },\n props: {\n decorations: (state): DecorationSet | undefined => {\n return key.getState(state)\n },\n },\n })\n })\n}\n\n/**\n * Define an extension to display the changes from the given commit in the editor.\n */\nfunction defineCommitViewer(commit: Commit): PlainExtension {\n return union(\n defineDefaultState({ defaultDoc: commit.doc }),\n defineCommitDecoration(commit),\n )\n}\n\nclass CommitRecorder {\n private parent: ProseMirrorNode | null = null\n private doc: ProseMirrorNode | null = null\n private steps: Step[] = []\n\n /**\n * Return a commit object including all changes since the last commit. `null`\n * will be returned if there is no change.\n */\n commit(): Commit | null {\n if (\n !this.parent\n || !this.doc\n || this.steps.length === 0\n || this.parent.eq(this.doc)\n ) {\n return null\n }\n\n const commit: Commit = {\n doc: jsonFromNode(this.doc),\n parent: jsonFromNode(this.parent),\n steps: this.steps.map((step) => step.toJSON() as StepJSON),\n }\n this.init(this.doc)\n return commit\n }\n\n /**\n * @internal\n */\n init(doc: ProseMirrorNode): void {\n this.doc = doc\n this.parent = doc\n this.steps = []\n }\n\n /**\n * @internal\n */\n apply(tr: Transaction): void {\n this.steps.push(...tr.steps)\n this.doc = tr.doc\n }\n}\n\n/**\n * Define an extension that can record the changes in the editor.\n */\nfunction defineCommitRecorder(commitRecorder: CommitRecorder): PlainExtension {\n const key = new PluginKey<DecorationSet>('prosekit-commit-recorder')\n\n return definePlugin(\n new ProseMirrorPlugin({\n key,\n state: {\n init: (_, state): void => {\n commitRecorder.init(state.doc)\n },\n apply: (tr): void => {\n commitRecorder.apply(tr)\n },\n },\n }),\n )\n}\n\nexport {\n CommitRecorder,\n defineCommitRecorder,\n defineCommitViewer,\n type Commit,\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-doc.d.ts","names":[],"sources":["../src/doc/index.ts"],"sourcesContent":[],"mappings":";;;;;;;AASA;AAAwB,KAAZ,YAAA,GAAe,SAAH,CAAA;OAA6B,EAAA;IAA1B,GAAA,EAA0B,KAA1B;EAAS,CAAA;AAKpC,CAAA,CAAA;;;;iBAAgB,SAAA,CAAA,GAAa"}
1
+ {"version":3,"file":"prosekit-extensions-doc.d.ts","names":[],"sources":["../src/doc/index.ts"],"sourcesContent":[],"mappings":";;;;;;;AASA;AAKgB,KALJ,YAAA,GAAe,SAKE,CAAA;;SALwB;;;;;;iBAKrC,SAAA,CAAA,GAAa"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-drop-cursor.d.ts","names":[],"sources":["../src/drop-cursor/drop-cursor.ts"],"sourcesContent":[],"mappings":";;;UAMiB,iBAAA;;AAAjB;AAwBA;AAWA;;OACY,CAAA,EAAA,MAAA,GAAA,KAAA;;;;;;;;;;;;;;;KAZA,mBAAA,GAAsB;;;;;;;;;;iBAWlB,gBAAA,WACJ,oBACT"}
1
+ {"version":3,"file":"prosekit-extensions-drop-cursor.d.ts","names":[],"sources":["../src/drop-cursor/drop-cursor.ts"],"sourcesContent":[],"mappings":";;;UAMiB,iBAAA;;AAAjB;AAwBA;AAWA;;;;;;;;;;;;;;;;;KAXY,mBAAA,GAAsB;;;;;;;;;;iBAWlB,gBAAA,WACJ,oBACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-drop-indicator.d.ts","names":[],"sources":["../src/drop-indicator/drop-indicator.ts"],"sourcesContent":[],"mappings":";;;;;;;AAQA;AAegB,KAfJ,sBAAA,GAAyB,cAeF;;;;;AAWnC;;;;;;;;;iBAXgB,mBAAA,WACJ,uBACT;;;;;;UASc,oBAAA,SAA6B"}
1
+ {"version":3,"file":"prosekit-extensions-drop-indicator.d.ts","names":[],"sources":["../src/drop-indicator/drop-indicator.ts"],"sourcesContent":[],"mappings":";;;;;;;AAQA;AAegB,KAfJ,sBAAA,GAAyB,cAgBzB;AAUZ;;;;;;;;;;;;;iBAXgB,mBAAA,WACJ,uBACT;;;;;;UASc,oBAAA,SAA6B"}
@@ -1,3 +1,3 @@
1
- import { defineDropIndicator } from "./drop-indicator-E7nCfdnR.js";
1
+ import { t as defineDropIndicator } from "./drop-indicator-BMvWUDXz.js";
2
2
 
3
3
  export { defineDropIndicator };
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-enter-rule.d.ts","names":[],"sources":["../src/enter-rule/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;AA8BA;;;AAmBS,UAnBQ,uBAAA,CAmBR;EAAe;AAMxB;;OAAyC,EArBhC,WAqBgC;;;AAOzC;EAA4B,IAAA,EAAA,MAAA;;;;EAwBX,EAAA,EAAA,MAAA;EAAyB;;;OAehC,EApDD,eAoDC;;;;AAmBV;AAA+B,KAjEnB,gBAAA,GAiEmB,CAAA,OAAA,EAjEU,uBAiEV,EAAA,GAjEsC,WAiEtC,GAAA,IAAA;;;;;;AAIK,KA9DxB,gBAAA,GA8DwB;EAcpB;;;OAEd,EA1EO,MA0EP;;;;SAG6B,EAxEpB,gBAwEoB;EAAc;;;;;;;;;;;;UAzD5B,yBAAA;;;;SAIR;;;;iBAKQ;;;;;UAMP,wBAAwB,qBAAqB;;;;;;;;;;;;;;;;;iBAmBvC,eAAA;;;;GAIb,mBAAmB;;;;;;;;;;iBAcN,wBAAA;;;;;GAKb,4BAA4B"}
1
+ {"version":3,"file":"prosekit-extensions-enter-rule.d.ts","names":[],"sources":["../src/enter-rule/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;AA8BA;AAyBA;AAOA;AAwBiB,UAxDA,uBAAA,CAwDyB;EAIjC;;;EAWyB,KAAA,EAnEzB,WAmEyB;EAAqB;;AAmBvD;EACE,IAAA,EAAA,MAAA;EACA;;;EAEoB,EAAA,EAAA,MAAA;EAAc;AAcpC;;EAEE,KAAA,EA3FO,eA2FP;;;;;AAG2C,KAxFjC,gBAAA,GAwFiC,CAAA,OAAA,EAxFJ,uBAwFI,EAAA,GAxFwB,WAwFxB,GAAA,IAAA;;;;;;KAjFjC,gBAAA;;;;SAIH;;;;WAKE;;;;;;;;;;;;;UAeM,yBAAA;;;;SAIR;;;;iBAKQ;;;;;UAMP,wBAAwB,qBAAqB;;;;;;;;;;;;;;;;;iBAmBvC,eAAA;;;;GAIb,mBAAmB;;;;;;;;;;iBAcN,wBAAA;;;;;GAKb,4BAA4B"}
@@ -1,3 +1,3 @@
1
- import { defineEnterRule, defineTextBlockEnterRule } from "./enter-rule-RdhEA900.js";
1
+ import { n as defineTextBlockEnterRule, t as defineEnterRule } from "./enter-rule-D-p4ykfv.js";
2
2
 
3
3
  export { defineEnterRule, defineTextBlockEnterRule };
@@ -1,2 +1,2 @@
1
- import { FileDropHandler, FileDropHandlerOptions, FilePasteHandler, FilePasteHandlerOptions, UploadProgress, UploadTask, Uploader, UploaderOptions, defineFileDropHandler, defineFilePasteHandler } from "./index-DY6lIIYV.js";
1
+ import { a as FilePasteHandler, c as FileDropHandler, i as UploaderOptions, l as FileDropHandlerOptions, n as UploadTask, o as FilePasteHandlerOptions, r as Uploader, s as defineFilePasteHandler, t as UploadProgress, u as defineFileDropHandler } from "./index-DdjnBeho.js";
2
2
  export { FileDropHandler, FileDropHandlerOptions, FilePasteHandler, FilePasteHandlerOptions, UploadProgress, UploadTask, Uploader, UploaderOptions, defineFileDropHandler, defineFilePasteHandler };
@@ -1,3 +1,3 @@
1
- import { UploadTask, defineFileDropHandler, defineFilePasteHandler } from "./file-DVUhe5KJ.js";
1
+ import { n as defineFilePasteHandler, r as defineFileDropHandler, t as UploadTask } from "./file-DKoIIa7q.js";
2
2
 
3
3
  export { UploadTask, defineFileDropHandler, defineFilePasteHandler };
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-hard-break.d.ts","names":[],"sources":["../src/hard-break/hard-break-commands.ts","../src/hard-break/hard-break-spec.ts","../src/hard-break/hard-break.ts","../src/hard-break/hard-break-keymap.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAUY,KAAA,0BAAA,GAA6B,SAAA,CAAA;EAgBzB,QAAA,EAAA;;;;;ACRhB;;iBDQgB,uBAAA,CAAA,GAA2B;;;;;;AAhB/B,KCDA,sBAAA,GAAyB,SDCI,CAAA;EAgBzB,KAAA,EAAA;eCfD;;;AAFf;;;AAAqC,iBASrB,mBAAA,CAAA,CATqB,EASE,sBATF;;;;;ADCrC;AAgBgB,KERJ,kBAAA,GAAqB,KFQM,CAAA,CEPpC,wBAAwB;ADV3B;;;AAAqC,iBCgBrB,eAAA,CAAA,CDhBqB,ECgBF,kBDhBE;;;;;;iBECrB,qBAAA,CAAA,GAAyB"}
1
+ {"version":3,"file":"prosekit-extensions-hard-break.d.ts","names":[],"sources":["../src/hard-break/hard-break-commands.ts","../src/hard-break/hard-break-spec.ts","../src/hard-break/hard-break.ts","../src/hard-break/hard-break-keymap.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAUY,KAAA,0BAAA,GAA6B,SAAA,CAAA;EAgBzB,QAAA,EAAA;;;;;AERhB;;AAC2B,iBFOX,uBAAA,CAAA,CEPW,EFOgB,0BEPhB;;;;;;AFTf,KCDA,sBAAA,GAAyB,SDCI,CAAA;EAgBzB,KAAA,EAAA;eCfD;;;AAFf;AASA;;iBAAgB,mBAAA,CAAA,GAAuB;;;;;ADRvC;AAgBgB,KERJ,kBAAA,GAAqB,KFQM,CAAA,CEPpC,wBAAwB;ADV3B;AASA;;iBCOgB,eAAA,CAAA,GAAmB;;;;;;iBCfnB,qBAAA,CAAA,GAAyB"}
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-heading.d.ts","names":[],"sources":["../src/heading/heading-types.ts","../src/heading/heading-commands.ts","../src/heading/heading-spec.ts","../src/heading/heading.ts","../src/heading/heading-input-rule.ts","../src/heading/heading-keymap.ts"],"sourcesContent":[],"mappings":";;;UAAiB,YAAA;;;;;;AAAjB;;KCaY,wBAAA,GAA2B;;IAA3B,UAAA,EAAA,CAAA,KAAA,GAEa,YAFW,GAAA,SAAA,CAAA;IAAA,aAAA,EAAA,CAAA,KAAA,GAGR,YAHQ,GAAA,SAAA,CAAA;IAEX,aAAA,EAAA,CAAA,KAAA,GAEG,YAFH,GAAA,SAAA,CAAA;;;;;AASzB;iBAAgB,qBAAA,CAAA,GAAyB;;;;ADxBzC;;KEUY,oBAAA,GAAuB;;IDGvB,OAAA,ECDC,YDCD;EAAwB,CAAA;;;;;AAAY,iBCMhC,iBAAA,CAAA,CDNgC,ECMX,oBDNW;;;ADbhD;;;KGmBY,gBAAA,GAAmB,OAC5B,oBFPS,EEOa,wBFPW;;;;AAAY,iBEahC,aAAA,CAAA,CFbgC,EEaf,gBFbe;;;;;ADbhD;;;;ACaY,iBGDI,sBAAA,CAAA,CHCoB,EGDM,cHCN;;;;;ADbpC;iBK6BgB,mBAAA,CAAA,GAAuB"}
1
+ {"version":3,"file":"prosekit-extensions-heading.d.ts","names":[],"sources":["../src/heading/heading-types.ts","../src/heading/heading-commands.ts","../src/heading/heading-spec.ts","../src/heading/heading.ts","../src/heading/heading-input-rule.ts","../src/heading/heading-keymap.ts"],"sourcesContent":[],"mappings":";;;UAAiB,YAAA;;;;;;AAAjB;;KCaY,wBAAA,GAA2B;;IAA3B,UAAA,EAAA,CAAA,KAAA,GAEa,YAFW,GAAA,SAAA,CAAA;IAEX,aAAA,EAAA,CAAA,KAAA,GACG,YADH,GAAA,SAAA,CAAA;IACG,aAAA,EAAA,CAAA,KAAA,GACA,YADA,GAAA,SAAA,CAAA;EACA,CAAA;CAJW,CAAA;;AAWvC;;iBAAgB,qBAAA,CAAA,GAAyB;;;;ADxBzC;;KEUY,oBAAA,GAAuB;;IDGvB,OAAA,ECDC,YDCD;EAEa,CAAA;CACG,CAAA;;;;AAQZ,iBCLA,iBAAA,CAAA,CDKyB,ECLJ,oBDKI;;;ADxBzC;;;KGmBY,gBAAA,GAAmB,OAC5B,oBFPS,EEOa,wBFLA,CACG,CAAA;;;;AAQZ,iBEEA,aAAA,CAAA,CFFqB,EEEJ,gBFFQ;;;;;ADxBzC;;;;ACaY,iBGDI,sBAAA,CAAA,CHCoB,EGDM,cHCN;;;;;ADbpC;iBK6BgB,mBAAA,CAAA,GAAuB"}
@@ -1,4 +1,4 @@
1
- import { defineTextBlockInputRule } from "./input-rule-B17tpW4m.js";
1
+ import { i as defineTextBlockInputRule } from "./input-rule-COGr_GBb.js";
2
2
  import { defineCommands, defineKeymap, defineNodeSpec, insertNode, isAtBlockStart, setBlockType, toggleNode, union, unsetBlockType, withSkipCodeBlock } from "@prosekit/core";
3
3
 
4
4
  //#region src/heading/heading-commands.ts
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-horizontal-rule.d.ts","names":[],"sources":["../src/horizontal-rule/horizontal-rule-commands.ts","../src/horizontal-rule/horizontal-rule-spec.ts","../src/horizontal-rule/horizontal-rule.ts","../src/horizontal-rule/horizontal-rule-input-rule.ts"],"sourcesContent":[],"mappings":";;;;;KAWY,+BAAA,GAAkC;;;EAAlC,CAAA;AASZ,CAAA,CAAA;AAcA;;;iBAdgB,oBAAA,CAAA,GAAwB;ACd5B,iBD4BI,4BAAA,CAAA,CC5BuB,ED4BS,+BC5BT;;;KAA3B,2BAAA,GAA8B;;oBAEtB;EDGR,CAAA;AASZ,CAAA,CAAA;AAcgB,iBCtBA,wBAAA,CAAA,CDsBgC,ECtBJ,2BDsBmC;;;KEnBnE,uBAAA,GAA0B,OACnC,6BAA6B,+BFLpB,CASZ,CAAA;AAcA;;;iBEZgB,oBAAA,CAAA,GAAwB;;;;;;iBCVxB,6BAAA,CAAA,GAAiC"}
1
+ {"version":3,"file":"prosekit-extensions-horizontal-rule.d.ts","names":[],"sources":["../src/horizontal-rule/horizontal-rule-commands.ts","../src/horizontal-rule/horizontal-rule-spec.ts","../src/horizontal-rule/horizontal-rule.ts","../src/horizontal-rule/horizontal-rule-input-rule.ts"],"sourcesContent":[],"mappings":";;;;;KAWY,+BAAA,GAAkC;;;EAAlC,CAAA;AASZ,CAAA,CAAA;AAcA;;;iBAdgB,oBAAA,CAAA,GAAwB;ACd5B,iBD4BI,4BAAA,CAAA,CC5B0B,ED4BM,+BC5BG;;;KAAvC,2BAAA,GAA8B;;oBAEtB;EDGR,CAAA;AASZ,CAAA,CAAA;AAcgB,iBCtBA,wBAAA,CAAA,CDsBgC,ECtBJ,2BDsBI;;;KEnBpC,uBAAA,GAA0B,OACnC,6BAA6B,+BFLpB,CASZ,CAAA;AAcA;;;iBEZgB,oBAAA,CAAA,GAAwB;;;;;;iBCVxB,6BAAA,CAAA,GAAiC"}
@@ -1,4 +1,4 @@
1
- import { defineInputRule } from "./input-rule-B17tpW4m.js";
1
+ import { n as defineInputRule } from "./input-rule-COGr_GBb.js";
2
2
  import { defineCommands, defineNodeSpec, getNodeType, union } from "@prosekit/core";
3
3
  import { InputRule } from "@prosekit/pm/inputrules";
4
4
  import { Fragment, Slice } from "@prosekit/pm/model";
@@ -1,7 +1,81 @@
1
- import { FileDropHandlerOptions, FilePasteHandlerOptions, UploadTask, Uploader } from "./index-DY6lIIYV.js";
1
+ import { l as FileDropHandlerOptions, n as UploadTask, o as FilePasteHandlerOptions, r as Uploader } from "./index-DdjnBeho.js";
2
2
  import { Extension, PlainExtension, Union } from "@prosekit/core";
3
3
  import { Command } from "@prosekit/pm/state";
4
+ import { EditorView } from "@prosekit/pm/view";
4
5
 
6
+ //#region src/image/image-commands/upload-image.d.ts
7
+
8
+ /**
9
+ * Options for {@link uploadImage}.
10
+ *
11
+ * @public
12
+ */
13
+ interface UploadImageOptions {
14
+ /**
15
+ * The uploader used to upload the file. It should return a promise that
16
+ * resolves to the URL of the uploaded image.
17
+ */
18
+ uploader: Uploader<string>;
19
+ /**
20
+ * The file that will be uploaded.
21
+ */
22
+ file: File;
23
+ /**
24
+ * The position where the image should be inserted. If not provided, the
25
+ * image is inserted at the current selection.
26
+ */
27
+ pos?: number;
28
+ /**
29
+ * A handler to be called when an error occurs during the upload.
30
+ */
31
+ onError?: ImageUploadErrorHandler;
32
+ }
33
+ /**
34
+ * Options for the {@link ImageUploadErrorHandler} callback.
35
+ *
36
+ * @public
37
+ */
38
+ interface ImageUploadErrorHandlerOptions {
39
+ /**
40
+ * The file that was uploaded.
41
+ */
42
+ file: File;
43
+ /**
44
+ * The error that occurred during the upload.
45
+ */
46
+ error: unknown;
47
+ /**
48
+ * The upload task that was used to upload the file.
49
+ */
50
+ uploadTask: UploadTask<string>;
51
+ }
52
+ /**
53
+ * A handler to be called when an error occurs during the upload.
54
+ *
55
+ * @public
56
+ */
57
+ type ImageUploadErrorHandler = (options: ImageUploadErrorHandlerOptions) => void;
58
+ /**
59
+ * Returns a command that uploads an image file and inserts an image node with a
60
+ * temporary URL which is replaced once the upload completes.
61
+ *
62
+ * @param options
63
+ *
64
+ * @public
65
+ */
66
+ declare function uploadImage({
67
+ uploader,
68
+ file,
69
+ pos,
70
+ onError
71
+ }: UploadImageOptions): Command;
72
+ /**
73
+ * Replaces the temporary image URL with the final uploaded URL.
74
+ *
75
+ * @internal
76
+ */
77
+ declare function replaceImageURL(view: EditorView, oldURL: string, newURL: string): void;
78
+ //#endregion
5
79
  //#region src/image/image-spec.d.ts
6
80
  /**
7
81
  * @public
@@ -31,15 +105,9 @@ declare function defineImageSpec(): ImageSpecExtension;
31
105
  type ImageCommandsExtension = Extension<{
32
106
  Commands: {
33
107
  insertImage: [attrs?: ImageAttrs];
108
+ uploadImage: [options: UploadImageOptions];
34
109
  };
35
110
  }>;
36
- /**
37
- * Returns a command that inserts an image node with the given attributes at the
38
- * current selection position.
39
- *
40
- * @public
41
- */
42
- declare function insertImage(attrs?: ImageAttrs): Command;
43
111
  /**
44
112
  * @internal
45
113
  */
@@ -55,6 +123,15 @@ type ImageExtension = Union<[ImageSpecExtension, ImageCommandsExtension]>;
55
123
  */
56
124
  declare function defineImage(): ImageExtension;
57
125
  //#endregion
126
+ //#region src/image/image-commands/insert-image.d.ts
127
+ /**
128
+ * Returns a command that inserts an image node with the given attributes at the
129
+ * current selection position.
130
+ *
131
+ * @public
132
+ */
133
+ declare function insertImage(attrs?: ImageAttrs): Command;
134
+ //#endregion
58
135
  //#region src/image/image-upload-handler.d.ts
59
136
  /**
60
137
  * A predicate to determine if the pasted file should be uploaded and inserted as an image.
@@ -67,27 +144,6 @@ type ImageCanDropPredicate = (options: FileDropHandlerOptions) => boolean;
67
144
  /**
68
145
  * A handler to be called when an error occurs during the upload.
69
146
  */
70
- type ImageUploadErrorHandler = (options: ImageUploadErrorHandlerOptions) => void;
71
- /**
72
- * Options for the {@link ImageUploadErrorHandler} callback.
73
- */
74
- interface ImageUploadErrorHandlerOptions {
75
- /**
76
- * The file that was uploaded.
77
- */
78
- file: File;
79
- /**
80
- * The error that occurred during the upload.
81
- */
82
- error: unknown;
83
- /**
84
- * The upload task that was used to upload the file.
85
- */
86
- uploadTask: UploadTask<string>;
87
- }
88
- /**
89
- * Options for {@link defineImageUploadHandler}.
90
- */
91
147
  interface ImageUploadHandlerOptions {
92
148
  /**
93
149
  * The uploader used to upload the file. It should return a promise that
@@ -123,5 +179,5 @@ declare function defineImageUploadHandler({
123
179
  onError
124
180
  }: ImageUploadHandlerOptions): PlainExtension;
125
181
  //#endregion
126
- export { type ImageAttrs, type ImageCanDropPredicate, type ImageCanPastePredicate, type ImageCommandsExtension, type ImageExtension, type ImageSpecExtension, type ImageUploadErrorHandler, type ImageUploadErrorHandlerOptions, type ImageUploadHandlerOptions, defineImage, defineImageCommands, defineImageSpec, defineImageUploadHandler, insertImage };
182
+ export { type ImageAttrs, type ImageCanDropPredicate, type ImageCanPastePredicate, type ImageCommandsExtension, type ImageExtension, type ImageSpecExtension, type ImageUploadErrorHandler, type ImageUploadErrorHandlerOptions, type ImageUploadHandlerOptions, type UploadImageOptions, defineImage, defineImageCommands, defineImageSpec, defineImageUploadHandler, insertImage, replaceImageURL, uploadImage };
127
183
  //# sourceMappingURL=prosekit-extensions-image.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-image.d.ts","names":[],"sources":["../src/image/image-spec.ts","../src/image/image-commands.ts","../src/image/image.ts","../src/image/image-upload-handler.ts"],"sourcesContent":[],"mappings":";;;;;;;;UAQiB,UAAA;EAAA,GAAA,CAAA,EAAA,MAAA,GAAU,IAAA;EASf,KAAA,CAAA,EAAA,MAAA,GAAA,IAAkB;EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;AAS9B;KATY,kBAAA,GAAqB;;WAEtB;ECPC,CAAA;CAAsB,CAAA;;;;AAYlB,iBDEA,eAAA,CAAA,CCFW,EDEQ,kBCFR;;;;;ADhB3B;AASY,KCLA,sBAAA,GAAyB,SDKP,CAAA;EAAA,QAAA,EAAA;IAEnB,WAAA,EAAA,CAAA,KAAA,GCLe,UDKf,CAAA;;CAF+B,CAAA;AAS1C;;;;ACdA;;AAE0B,iBAUV,WAAA,CAVU,KAAA,CAAA,EAUU,UAVV,CAAA,EAUuB,OAVvB;;;AAU1B;AAA2B,iBAOX,mBAAA,CAAA,CAPW,EAOY,sBAPZ;;;;;ADhB3B;AASY,KEAA,cAAA,GAAiB,KFAC,CAAA,CEAM,kBFAN,EEA0B,sBFA1B,CAAA,CAAA;;;;AAAY,iBEK1B,WAAA,CAAA,CFL0B,EEKX,cFLW;;;;;;AATzB,KGgBL,sBAAA,GHhBe,CAAA,OAAA,EGgBoB,uBHhBpB,EAAA,GAAA,OAAA;AAS3B;;;AAAiC,KGYrB,qBAAA,GHZqB,CAAA,OAAA,EGYa,sBHZb,EAAA,GAAA,OAAA;;AASjC;;KGQY,uBAAA,aAAoC;;AFtBhD;;AAE0B,UEyBT,8BAAA,CFzBS;;;AAU1B;EAA2B,IAAA,EEmBnB,IFnBmB;;;;EAOX,KAAA,EAAA,OAAA;;;;ECdJ,UAAA,ECkCE,UDlCY,CAAA,MAAA,CAAA;;;;;AAAQ,UCwCjB,yBAAA,CDxCiB;EAKlB;;;;ECEJ,QAAA,EAsCA,QAtCA,CAAA,MAAsB,CAAA;EAKtB;AAKZ;AAKA;;UAIQ,CAAA,EAwBK,sBAxBL;;;AAcR;;SAKY,CAAA,EAUA,qBAVA;;;;;EAiCI,OAAA,CAAA,EAlBJ,uBAkB4B;;;;;;;;AAKK,iBAL7B,wBAAA,CAK6B;EAAA,QAAA;EAAA,QAAA;EAAA,OAAA;EAAA;AAAA,CAAA,EAA1C,yBAA0C,CAAA,EAAd,cAAc"}
1
+ {"version":3,"file":"prosekit-extensions-image.d.ts","names":[],"sources":["../src/image/image-commands/upload-image.ts","../src/image/image-spec.ts","../src/image/image-commands.ts","../src/image/image.ts","../src/image/image-commands/insert-image.ts","../src/image/image-upload-handler.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;AAkBA;;AASQ,UATS,kBAAA,CAST;EASI;;AAQZ;AAoBA;EAUgB,QAAA,EAnDJ,QAmDe,CAAA,MAAA,CAAA;EAAG;;;EAAqB,IAAA,EA/C3C,IA+C2C;EAAW;;;AAsC9D;;;;ACxGA;EASY,OAAA,CAAA,EDmBA,uBCnBkB;AAS9B;;;;ACXA;;AAG2B,UF0BV,8BAAA,CE1BU;EAHU;;AAUrC;QFuBQ;;;AG/BR;EAAoC,KAAA,EAAA,OAAA;EAAoB;;;EAKxC,UAAA,EHkCF,UGlCa,CAAA,MAAI,CAAA;;;;ACX/B;;;KJqDY,uBAAA,aAAoC;AKzChD;AAKA;AAKA;;;;;;AAsCgB,iBLGA,WAAA,CKHwB;EAAA,QAAA;EAAA,IAAA;EAAA,GAAA;EAAA;AAAA,CAAA,ELGsB,kBKHtB,CAAA,ELG2C,OKH3C;;;;;;AAKT,iBLoCf,eAAA,CKpCe,IAAA,ELqCvB,UKrCuB,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,IAAA;;;;;;UJpEd,UAAA;;EDUA,KAAA,CAAA,EAAA,MAAA,GAAA,IAAkB;EAKvB,MAAA,CAAA,EAAA,MAAA,GAAA,IAAA;;;;AAqBZ;AAoBY,KC/CA,kBAAA,GAAqB,SD+CE,CAAa;EAUhC,KAAA,EAAA;IAAc,KAAA,ECvDnB,UDuDmB;EAAU,CAAA;CAAM,CAAA;;;;AAA4C,iBChD1E,eAAA,CAAA,CDgD0E,EChDvD,kBDgDuD;;;;;;AAxDzE,KEHL,sBAAA,GAAyB,SFGF,CAAA;EAKvB,QAAA,EAAA;IAIJ,WAAA,EAAA,CAAA,KAAA,GEVkB,UFUlB,CAAA;IASI,WAAA,EAAA,CAAA,OAAA,EElBe,kBFkBf,CAAA;EAAuB,CAAA;AAQnC,CAAA,CAAA;AAoBA;AAUA;;AAAwC,iBEjDxB,mBAAA,CAAA,CFiDwB,EEjDD,sBFiDC;;;;;;AAxDvB,KGDL,cAAA,GAAiB,KHCM,CAAA,CGDC,kBHCD,EGDqB,sBHCrB,CAAA,CAAA;;;;AAkBA,iBGdnB,WAAA,CAAA,CHcmB,EGdJ,cHcI;;;;;;;AAlBnC;;AASQ,iBIhBQ,WAAA,CJgBR,KAAA,CAAA,EIhB4B,UJgB5B,CAAA,EIhByC,OJgBzC;;;;;;AATS,KKKL,sBAAA,GLLuB,CAAA,OAAA,EKKY,uBLLZ,EAAA,GAAA,OAAA;;;;AAkBA,KKRvB,qBAAA,GLQuB,CAAA,OAAA,EKRW,sBLQX,EAAA,GAAA,OAAA;AAQnC;AAoBA;AAUA;AAA8B,UKzCb,yBAAA,CLyCa;EAAU;;;;EAA2C,QAAA,EKpCvE,QLoCuE,CAAA,MAAA,CAAA;EAAO;AAsC1F;;;aKrEa;EJnCI;AASjB;AASA;;YIsBY;;AHjCZ;;;EAAqC,OAAA,CAAA,EGsCzB,uBHtCyB;;AAUrC;;;;ACRA;;AAAwD,iBEsDxC,wBAAA,CFtDwC;EAAA,QAAA;EAAA,QAAA;EAAA,OAAA;EAAA;AAAA,CAAA,EE2DrD,yBF3DqD,CAAA,EE2DzB,cF3DyB"}
@@ -1,7 +1,7 @@
1
- import { UploadTask, defineFileDropHandler, defineFilePasteHandler } from "./file-DVUhe5KJ.js";
1
+ import { n as defineFilePasteHandler, r as defineFileDropHandler, t as UploadTask } from "./file-DKoIIa7q.js";
2
2
  import { ProseKitError, defineCommands, defineNodeSpec, insertNode, union } from "@prosekit/core";
3
3
 
4
- //#region src/image/image-commands.ts
4
+ //#region src/image/image-commands/insert-image.ts
5
5
  /**
6
6
  * Returns a command that inserts an image node with the given attributes at the
7
7
  * current selection position.
@@ -14,11 +14,87 @@ function insertImage(attrs) {
14
14
  attrs
15
15
  });
16
16
  }
17
+
18
+ //#endregion
19
+ //#region src/image/image-commands/upload-image.ts
20
+ /**
21
+ * Returns a command that uploads an image file and inserts an image node with a
22
+ * temporary URL which is replaced once the upload completes.
23
+ *
24
+ * @param options
25
+ *
26
+ * @public
27
+ */
28
+ function uploadImage({ uploader, file, pos, onError }) {
29
+ return (state, dispatch, view) => {
30
+ const uploadTask = new UploadTask({
31
+ file,
32
+ uploader
33
+ });
34
+ const objectURL = uploadTask.objectURL;
35
+ const attrs = { src: objectURL };
36
+ uploadTask.finished.then((resultURL) => {
37
+ if (view && view.isDestroyed) return;
38
+ else if (typeof resultURL !== "string") {
39
+ const error = new ProseKitError(`Unexpected upload result. Expected a string but got ${typeof resultURL}`);
40
+ onError?.({
41
+ file,
42
+ error,
43
+ uploadTask
44
+ });
45
+ } else if (!view) {
46
+ const error = new ProseKitError("View must be available to replace the image URL");
47
+ onError?.({
48
+ file,
49
+ error,
50
+ uploadTask
51
+ });
52
+ } else {
53
+ replaceImageURL(view, objectURL, resultURL);
54
+ UploadTask.delete(objectURL);
55
+ }
56
+ }).catch((error) => {
57
+ onError?.({
58
+ file,
59
+ error,
60
+ uploadTask
61
+ });
62
+ });
63
+ return insertNode({
64
+ type: "image",
65
+ attrs,
66
+ pos
67
+ })(state, dispatch, view);
68
+ };
69
+ }
70
+ /**
71
+ * Replaces the temporary image URL with the final uploaded URL.
72
+ *
73
+ * @internal
74
+ */
75
+ function replaceImageURL(view, oldURL, newURL) {
76
+ const positions = [];
77
+ view.state.doc.descendants((node, pos) => {
78
+ if (node.type.name === "image") {
79
+ if (node.attrs.src === oldURL) positions.push(pos);
80
+ }
81
+ });
82
+ if (positions.length === 0) return;
83
+ const tr = view.state.tr;
84
+ for (const pos of positions) tr.setNodeAttribute(pos, "src", newURL);
85
+ view.dispatch(tr);
86
+ }
87
+
88
+ //#endregion
89
+ //#region src/image/image-commands.ts
17
90
  /**
18
91
  * @internal
19
92
  */
20
93
  function defineImageCommands() {
21
- return defineCommands({ insertImage });
94
+ return defineCommands({
95
+ insertImage,
96
+ uploadImage
97
+ });
22
98
  }
23
99
 
24
100
  //#endregion
@@ -98,63 +174,28 @@ const defaultOnError = ({ error }) => {
98
174
  * @param options
99
175
  */
100
176
  function defineImageUploadHandler({ uploader, canPaste = defaultCanUpload, canDrop = defaultCanUpload, onError = defaultOnError }) {
101
- const handleInsert = (view, file, pos) => {
102
- const uploadTask = new UploadTask({
103
- file,
104
- uploader
105
- });
106
- const objectURL = uploadTask.objectURL;
107
- const attrs = { src: objectURL };
108
- uploadTask.finished.then((resultURL) => {
109
- if (view.isDestroyed) return;
110
- else if (typeof resultURL !== "string") {
111
- const error = new ProseKitError(`Unexpected upload result. Expected a string but got ${typeof resultURL}`);
112
- onError({
113
- file,
114
- error,
115
- uploadTask
116
- });
117
- } else {
118
- replaceImageURL(view, objectURL, resultURL);
119
- UploadTask.delete(objectURL);
120
- }
121
- }).catch((error) => {
122
- onError({
123
- file,
124
- error,
125
- uploadTask
126
- });
127
- });
128
- return insertNode({
129
- type: "image",
130
- attrs,
131
- pos
132
- })(view.state, view.dispatch, view);
133
- };
134
177
  const handlePaste = (options) => {
135
178
  if (!canPaste(options)) return false;
136
- return handleInsert(options.view, options.file);
179
+ const { view, file } = options;
180
+ return uploadImage({
181
+ uploader,
182
+ file,
183
+ onError
184
+ })(view.state, view.dispatch, view);
137
185
  };
138
186
  const handleDrop = (options) => {
139
187
  if (!canDrop(options)) return false;
140
- return handleInsert(options.view, options.file, options.pos);
188
+ const { view, file, pos } = options;
189
+ return uploadImage({
190
+ uploader,
191
+ file,
192
+ onError,
193
+ pos
194
+ })(view.state, view.dispatch, view);
141
195
  };
142
196
  return union(defineFilePasteHandler(handlePaste), defineFileDropHandler(handleDrop));
143
197
  }
144
- function replaceImageURL(view, oldURL, newURL) {
145
- const positions = [];
146
- view.state.doc.descendants((node, pos) => {
147
- if (node.type.name === "image") {
148
- if (node.attrs.src === oldURL) positions.push(pos);
149
- }
150
- });
151
- if (positions.length > 0) {
152
- const tr = view.state.tr;
153
- for (const pos of positions) tr.setNodeAttribute(pos, "src", newURL);
154
- view.dispatch(tr);
155
- }
156
- }
157
198
 
158
199
  //#endregion
159
- export { defineImage, defineImageCommands, defineImageSpec, defineImageUploadHandler, insertImage };
200
+ export { defineImage, defineImageCommands, defineImageSpec, defineImageUploadHandler, insertImage, replaceImageURL, uploadImage };
160
201
  //# sourceMappingURL=prosekit-extensions-image.js.map