@prosekit/extensions 0.12.0 → 0.12.2

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 (50) hide show
  1. package/dist/{drop-indicator-BMvWUDXz.js → drop-indicator-B1QHFb5m.js} +1 -1
  2. package/dist/{drop-indicator-BMvWUDXz.js.map → drop-indicator-B1QHFb5m.js.map} +1 -1
  3. package/dist/{enter-rule-D-p4ykfv.js → enter-rule-CzWOZF_Z.js} +1 -1
  4. package/dist/{enter-rule-D-p4ykfv.js.map → enter-rule-CzWOZF_Z.js.map} +1 -1
  5. package/dist/{file-DKoIIa7q.js → file-DrfcSid-.js} +1 -1
  6. package/dist/{file-DKoIIa7q.js.map → file-DrfcSid-.js.map} +1 -1
  7. package/dist/{index-DdjnBeho.d.ts → index-oIc1a2f2.d.ts} +1 -1
  8. package/dist/{index-DdjnBeho.d.ts.map → index-oIc1a2f2.d.ts.map} +1 -1
  9. package/dist/{input-rule-COGr_GBb.js → input-rule-dmsb3j6w.js} +1 -1
  10. package/dist/{input-rule-COGr_GBb.js.map → input-rule-dmsb3j6w.js.map} +1 -1
  11. package/dist/{mark-rule-v2E7B4C0.js → mark-rule-BcLB4Uv2.js} +1 -1
  12. package/dist/{mark-rule-v2E7B4C0.js.map → mark-rule-BcLB4Uv2.js.map} +1 -1
  13. package/dist/{paste-rule-qSz46pqD.js → paste-rule-pVb4sqvJ.js} +1 -1
  14. package/dist/{paste-rule-qSz46pqD.js.map → paste-rule-pVb4sqvJ.js.map} +1 -1
  15. package/dist/prosekit-extensions-blockquote.js +1 -1
  16. package/dist/prosekit-extensions-bold.d.ts.map +1 -1
  17. package/dist/prosekit-extensions-bold.js +1 -1
  18. package/dist/prosekit-extensions-code-block.d.ts +1 -1
  19. package/dist/prosekit-extensions-code-block.js +3 -3
  20. package/dist/prosekit-extensions-code-block.js.map +1 -1
  21. package/dist/prosekit-extensions-code.d.ts.map +1 -1
  22. package/dist/prosekit-extensions-code.js +1 -1
  23. package/dist/prosekit-extensions-drop-indicator.js +1 -1
  24. package/dist/prosekit-extensions-enter-rule.js +1 -1
  25. package/dist/prosekit-extensions-file.d.ts +1 -1
  26. package/dist/prosekit-extensions-file.js +1 -1
  27. package/dist/prosekit-extensions-heading.js +1 -1
  28. package/dist/prosekit-extensions-horizontal-rule.js +1 -1
  29. package/dist/prosekit-extensions-image.d.ts +1 -1
  30. package/dist/prosekit-extensions-image.js +1 -1
  31. package/dist/prosekit-extensions-input-rule.js +1 -1
  32. package/dist/prosekit-extensions-italic.js +1 -1
  33. package/dist/prosekit-extensions-link.js +4 -4
  34. package/dist/prosekit-extensions-list.js +2 -2
  35. package/dist/prosekit-extensions-loro.js +1 -1
  36. package/dist/prosekit-extensions-loro.js.map +1 -1
  37. package/dist/prosekit-extensions-mark-rule.js +1 -1
  38. package/dist/prosekit-extensions-paste-rule.js +1 -1
  39. package/dist/prosekit-extensions-placeholder.js +2 -2
  40. package/dist/prosekit-extensions-strike.js +1 -1
  41. package/dist/prosekit-extensions-table.js +2 -2
  42. package/dist/prosekit-extensions-yjs.js +2 -2
  43. package/dist/prosekit-extensions-yjs.js.map +1 -1
  44. package/dist/{shiki-highlighter-chunk-DcY3Ud8v.d.ts → shiki-highlighter-chunk-rkzofy4z.d.ts} +1 -1
  45. package/dist/{shiki-highlighter-chunk-DcY3Ud8v.d.ts.map → shiki-highlighter-chunk-rkzofy4z.d.ts.map} +1 -1
  46. package/dist/shiki-highlighter-chunk.d.ts +1 -1
  47. package/dist/{table-BLjD91VB.js → table-BRDh_9mG.js} +2 -2
  48. package/dist/{table-BLjD91VB.js.map → table-BRDh_9mG.js.map} +1 -1
  49. package/package.json +9 -9
  50. package/src/testing/keyboard.ts +2 -3
@@ -55,4 +55,4 @@ function defineDropIndicator(options) {
55
55
 
56
56
  //#endregion
57
57
  export { defineDropIndicator as t };
58
- //# sourceMappingURL=drop-indicator-BMvWUDXz.js.map
58
+ //# sourceMappingURL=drop-indicator-B1QHFb5m.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drop-indicator-BMvWUDXz.js","names":["showHandler: ShowHandler","hideHandler: VoidFunction","dragHandler: DragEventHandler"],"sources":["../src/drop-indicator/drop-indicator-facet.ts","../src/drop-indicator/drop-indicator.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport type {\n DragEventHandler,\n DropIndicatorPluginOptions,\n ShowHandler,\n} from 'prosemirror-drop-indicator'\nimport { createDropIndicatorPlugin } from 'prosemirror-drop-indicator'\n\n/**\n * @internal\n */\nexport function defineDropIndicatorPayload(\n payload: DropIndicatorPluginOptions,\n): PlainExtension {\n return defineFacetPayload(dropIndicatorFacet, [payload]) as PlainExtension\n}\n\nconst dropIndicatorFacet = defineFacet<DropIndicatorPluginOptions, PluginPayload>({\n parent: pluginFacet,\n singleton: true,\n reducer: (payloads: DropIndicatorPluginOptions[]): PluginPayload => {\n let showHandlers = payloads.map(p => p.onShow).filter(x => !!x)\n let hideHandlers = payloads.map(p => p.onHide).filter(x => !!x)\n let dragHandlers = payloads.map(p => p.onDrag).filter(x => !!x)\n\n let showHandler: ShowHandler = (options) => {\n for (let fn of showHandlers) {\n fn(options)\n }\n }\n\n let hideHandler: VoidFunction = () => {\n for (let fn of hideHandlers) {\n fn()\n }\n }\n\n let dragHandler: DragEventHandler = (options): boolean => {\n for (let fn of dragHandlers) {\n if (fn(options) === false) return false\n }\n return true\n }\n\n if (showHandlers.length === 0) {\n // No `onShow` event handler, so we don't need to create a plugin.\n return []\n }\n\n return createDropIndicatorPlugin({\n onDrag: dragHandler,\n onShow: showHandler,\n onHide: hideHandler,\n })\n },\n})\n","import type { PlainExtension } from '@prosekit/core'\nimport type { DropIndicatorPluginOptions } from 'prosemirror-drop-indicator'\n\nimport { defineDropIndicatorPayload } from './drop-indicator-facet'\n\n/**\n * @internal\n */\nexport type DropIndicatorExtension = PlainExtension\n\n/**\n * Defines an extension that controls the behavior of the drop indicator.\n *\n * This extension itself doesn't draw the drop indicator, but it provides the\n * necessary callbacks to do so. You probably don't want to use this extension\n * directly, but rather use the `<DropIndicator>` component.\n *\n * You can add this extension multiple times. If any extension has `onDrag`\n * callback defined, and it returns `false`, then the drop point will be\n * discarded.\n *\n * @public\n */\nexport function defineDropIndicator(\n options?: DropIndicatorOptions,\n): DropIndicatorExtension {\n return defineDropIndicatorPayload(options ?? {})\n}\n\n/**\n * Options for {@link defineDropIndicator}.\n *\n * @public\n */\nexport interface DropIndicatorOptions extends DropIndicatorPluginOptions {}\n"],"mappings":";;;;;;;AAiBA,SAAgB,2BACd,SACgB;AAChB,QAAO,mBAAmB,oBAAoB,CAAC,QAAQ,CAAC;;AAG1D,MAAM,qBAAqB,YAAuD;CAChF,QAAQ;CACR,WAAW;CACX,UAAU,aAA0D;EAClE,IAAI,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,QAAO,MAAK,CAAC,CAAC,EAAE;EAC/D,IAAI,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,QAAO,MAAK,CAAC,CAAC,EAAE;EAC/D,IAAI,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,QAAO,MAAK,CAAC,CAAC,EAAE;EAE/D,IAAIA,eAA4B,YAAY;AAC1C,QAAK,IAAI,MAAM,aACb,IAAG,QAAQ;;EAIf,IAAIC,oBAAkC;AACpC,QAAK,IAAI,MAAM,aACb,KAAI;;EAIR,IAAIC,eAAiC,YAAqB;AACxD,QAAK,IAAI,MAAM,aACb,KAAI,GAAG,QAAQ,KAAK,MAAO,QAAO;AAEpC,UAAO;;AAGT,MAAI,aAAa,WAAW,EAE1B,QAAO,EAAE;AAGX,SAAO,0BAA0B;GAC/B,QAAQ;GACR,QAAQ;GACR,QAAQ;GACT,CAAC;;CAEL,CAAC;;;;;;;;;;;;;;;;;ACtCF,SAAgB,oBACd,SACwB;AACxB,QAAO,2BAA2B,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"drop-indicator-B1QHFb5m.js","names":["showHandler: ShowHandler","hideHandler: VoidFunction","dragHandler: DragEventHandler"],"sources":["../src/drop-indicator/drop-indicator-facet.ts","../src/drop-indicator/drop-indicator.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport type {\n DragEventHandler,\n DropIndicatorPluginOptions,\n ShowHandler,\n} from 'prosemirror-drop-indicator'\nimport { createDropIndicatorPlugin } from 'prosemirror-drop-indicator'\n\n/**\n * @internal\n */\nexport function defineDropIndicatorPayload(\n payload: DropIndicatorPluginOptions,\n): PlainExtension {\n return defineFacetPayload(dropIndicatorFacet, [payload]) as PlainExtension\n}\n\nconst dropIndicatorFacet = defineFacet<DropIndicatorPluginOptions, PluginPayload>({\n parent: pluginFacet,\n singleton: true,\n reducer: (payloads: DropIndicatorPluginOptions[]): PluginPayload => {\n let showHandlers = payloads.map(p => p.onShow).filter(x => !!x)\n let hideHandlers = payloads.map(p => p.onHide).filter(x => !!x)\n let dragHandlers = payloads.map(p => p.onDrag).filter(x => !!x)\n\n let showHandler: ShowHandler = (options) => {\n for (let fn of showHandlers) {\n fn(options)\n }\n }\n\n let hideHandler: VoidFunction = () => {\n for (let fn of hideHandlers) {\n fn()\n }\n }\n\n let dragHandler: DragEventHandler = (options): boolean => {\n for (let fn of dragHandlers) {\n if (fn(options) === false) return false\n }\n return true\n }\n\n if (showHandlers.length === 0) {\n // No `onShow` event handler, so we don't need to create a plugin.\n return []\n }\n\n return createDropIndicatorPlugin({\n onDrag: dragHandler,\n onShow: showHandler,\n onHide: hideHandler,\n })\n },\n})\n","import type { PlainExtension } from '@prosekit/core'\nimport type { DropIndicatorPluginOptions } from 'prosemirror-drop-indicator'\n\nimport { defineDropIndicatorPayload } from './drop-indicator-facet'\n\n/**\n * @internal\n */\nexport type DropIndicatorExtension = PlainExtension\n\n/**\n * Defines an extension that controls the behavior of the drop indicator.\n *\n * This extension itself doesn't draw the drop indicator, but it provides the\n * necessary callbacks to do so. You probably don't want to use this extension\n * directly, but rather use the `<DropIndicator>` component.\n *\n * You can add this extension multiple times. If any extension has `onDrag`\n * callback defined, and it returns `false`, then the drop point will be\n * discarded.\n *\n * @public\n */\nexport function defineDropIndicator(\n options?: DropIndicatorOptions,\n): DropIndicatorExtension {\n return defineDropIndicatorPayload(options ?? {})\n}\n\n/**\n * Options for {@link defineDropIndicator}.\n *\n * @public\n */\nexport interface DropIndicatorOptions extends DropIndicatorPluginOptions {}\n"],"mappings":";;;;;;;AAiBA,SAAgB,2BACd,SACgB;AAChB,QAAO,mBAAmB,oBAAoB,CAAC,QAAQ,CAAC;;AAG1D,MAAM,qBAAqB,YAAuD;CAChF,QAAQ;CACR,WAAW;CACX,UAAU,aAA0D;EAClE,IAAI,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,QAAO,MAAK,CAAC,CAAC,EAAE;EAC/D,IAAI,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,QAAO,MAAK,CAAC,CAAC,EAAE;EAC/D,IAAI,eAAe,SAAS,KAAI,MAAK,EAAE,OAAO,CAAC,QAAO,MAAK,CAAC,CAAC,EAAE;EAE/D,IAAIA,eAA4B,YAAY;AAC1C,QAAK,IAAI,MAAM,aACb,IAAG,QAAQ;;EAIf,IAAIC,oBAAkC;AACpC,QAAK,IAAI,MAAM,aACb,KAAI;;EAIR,IAAIC,eAAiC,YAAqB;AACxD,QAAK,IAAI,MAAM,aACb,KAAI,GAAG,QAAQ,KAAK,MAAO,QAAO;AAEpC,UAAO;;AAGT,MAAI,aAAa,WAAW,EAE1B,QAAO,EAAE;AAGX,SAAO,0BAA0B;GAC/B,QAAQ;GACR,QAAQ;GACR,QAAQ;GACT,CAAC;;CAEL,CAAC;;;;;;;;;;;;;;;;;ACtCF,SAAgB,oBACd,SACwB;AACxB,QAAO,2BAA2B,WAAW,EAAE,CAAC"}
@@ -93,4 +93,4 @@ const MAX_MATCH = 200;
93
93
 
94
94
  //#endregion
95
95
  export { defineTextBlockEnterRule as n, defineEnterRule as t };
96
- //# sourceMappingURL=enter-rule-D-p4ykfv.js.map
96
+ //# sourceMappingURL=enter-rule-CzWOZF_Z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"enter-rule-D-p4ykfv.js","names":["regex: RegExp","handler: EnterRuleHandler","stop: boolean","rules: EnterRule[]","command: Command"],"sources":["../src/enter-rule/index.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n getNodeType,\n isTextSelection,\n maybeRun,\n OBJECT_REPLACEMENT_CHARACTER,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport { keydownHandler } from '@prosekit/pm/keymap'\nimport type {\n Attrs,\n NodeType,\n} from '@prosekit/pm/model'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n type Command,\n type EditorState,\n type Transaction,\n} from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\n/**\n * @public\n *\n * Options for {@link EnterRuleHandler}.\n */\nexport interface EnterRuleHandlerOptions {\n /**\n * The current editor state.\n */\n state: EditorState\n\n /**\n * The start position of the matched text.\n */\n from: number\n\n /**\n * The end position of the matched text.\n */\n to: number\n\n /**\n * The matched result from the regular expression.\n */\n match: RegExpExecArray\n}\n\n/**\n * @public\n */\nexport type EnterRuleHandler = (options: EnterRuleHandlerOptions) => Transaction | null\n\n/**\n * Options for {@link defineEnterRule}.\n *\n * @public\n */\nexport type EnterRuleOptions = {\n /**\n * The regular expression to match against. It should end with `$`.\n */\n regex: RegExp\n\n /**\n * A function to be called when an enter rule is triggered.\n */\n handler: EnterRuleHandler\n\n /**\n * Whether to stop further handlers from being called if this rule is triggered.\n *\n * @default false\n */\n stop?: boolean\n}\n\n/**\n * Options for {@link defineTextBlockEnterRule}.\n *\n * @public\n */\nexport interface TextBlockEnterRuleOptions {\n /**\n * The regular expression to match against. It should end with `$`.\n */\n regex: RegExp\n\n /**\n * The node type to replace the matched text with.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node. If a function is provided, it will be called\n * with the matched result from the regular expression.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * Whether to stop further handlers from being called if this rule is triggered.\n *\n * @default true\n */\n stop?: boolean\n}\n\n/**\n * Defines an enter rule. An enter rule applies when the text directly in front of\n * the cursor matches `regex` and user presses Enter. The `regex` should end\n * with `$`.\n *\n * @param options\n *\n * @public\n */\nexport function defineEnterRule({\n regex,\n handler,\n stop = false,\n}: EnterRuleOptions): PlainExtension {\n const rule: EnterRule = new EnterRule(regex, handler, stop)\n return defineFacetPayload(enterRule, [rule]) as PlainExtension\n}\n\n/**\n * Defines an enter rule that replaces the matched text with a block node.\n *\n * See also {@link defineEnterRule}.\n *\n * @param options\n *\n * @public\n */\nexport function defineTextBlockEnterRule({\n regex,\n type,\n attrs,\n stop = true,\n}: TextBlockEnterRuleOptions): PlainExtension {\n return defineEnterRule({\n regex,\n handler: ({ state, from, to, match }) => {\n const nodeType = getNodeType(state.schema, type)\n const $start = state.doc.resolve(from)\n\n if (\n !$start\n .node(-1)\n .canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)\n ) {\n return null\n }\n\n const nodeAttrs = maybeRun(attrs, match)\n return state.tr\n .delete(from, to)\n .setBlockType(from, from, nodeType, nodeAttrs)\n },\n stop,\n })\n}\n\n/**\n * @internal\n */\nclass EnterRule {\n constructor(\n readonly regex: RegExp,\n readonly handler: EnterRuleHandler,\n readonly stop: boolean,\n ) {}\n}\n\nconst enterRule = defineFacet<EnterRule, PluginPayload>({\n reduce: () => {\n let rules: EnterRule[] = []\n\n const command: Command = (state, dispatch, view) => {\n if (!view) return false\n return execRules(view, rules, dispatch)\n }\n const handler = keydownHandler({ Enter: command })\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-enter-rule'),\n props: { handleKeyDown: handler },\n })\n\n return function reducer(inputs) {\n rules = inputs\n return plugin\n }\n },\n\n parent: pluginFacet,\n})\n\nfunction execRules(\n view: EditorView,\n rules: readonly EnterRule[],\n dispatch?: (tr: Transaction) => void,\n): boolean {\n if (view.composing) return false\n const state = view.state\n const selection = state.selection\n if (!isTextSelection(selection)) return false\n const $cursor = selection.$cursor\n if (!$cursor || $cursor.parent.type.spec.code) return false\n\n const textBefore = $cursor.parent.textBetween(\n Math.max(0, $cursor.parentOffset - MAX_MATCH),\n $cursor.parentOffset,\n null,\n OBJECT_REPLACEMENT_CHARACTER,\n )\n\n for (const rule of rules) {\n rule.regex.lastIndex = 0\n const match = rule.regex.exec(textBefore)\n const tr = match\n && rule.handler({\n state,\n from: $cursor.pos - match[0].length,\n to: $cursor.pos,\n match,\n })\n if (!tr) continue\n dispatch?.(tr)\n\n if (rule.stop) {\n return true\n }\n }\n return false\n}\n\nconst MAX_MATCH = 200\n"],"mappings":";;;;;;;;;;;;;;AAwHA,SAAgB,gBAAgB,EAC9B,OACA,SACA,OAAO,SAC4B;AAEnC,QAAO,mBAAmB,WAAW,CADb,IAAI,UAAU,OAAO,SAAS,KAAK,CAChB,CAAC;;;;;;;;;;;AAY9C,SAAgB,yBAAyB,EACvC,OACA,MACA,OACA,OAAO,QACqC;AAC5C,QAAO,gBAAgB;EACrB;EACA,UAAU,EAAE,OAAO,MAAM,IAAI,YAAY;GACvC,MAAM,WAAW,YAAY,MAAM,QAAQ,KAAK;GAChD,MAAM,SAAS,MAAM,IAAI,QAAQ,KAAK;AAEtC,OACE,CAAC,OACE,KAAK,GAAG,CACR,eAAe,OAAO,MAAM,GAAG,EAAE,OAAO,WAAW,GAAG,EAAE,SAAS,CAEpE,QAAO;GAGT,MAAM,YAAY,SAAS,OAAO,MAAM;AACxC,UAAO,MAAM,GACV,OAAO,MAAM,GAAG,CAChB,aAAa,MAAM,MAAM,UAAU,UAAU;;EAElD;EACD,CAAC;;;;;AAMJ,IAAM,YAAN,MAAgB;CACd,YACE,AAASA,OACT,AAASC,SACT,AAASC,MACT;EAHS;EACA;EACA;;;AAIb,MAAM,YAAY,YAAsC;CACtD,cAAc;EACZ,IAAIC,QAAqB,EAAE;EAE3B,MAAMC,WAAoB,OAAO,UAAU,SAAS;AAClD,OAAI,CAAC,KAAM,QAAO;AAClB,UAAO,UAAU,MAAM,OAAO,SAAS;;EAEzC,MAAM,UAAU,eAAe,EAAE,OAAO,SAAS,CAAC;EAClD,MAAM,SAAS,IAAI,kBAAkB;GACnC,KAAK,IAAI,UAAU,sBAAsB;GACzC,OAAO,EAAE,eAAe,SAAS;GAClC,CAAC;AAEF,SAAO,SAAS,QAAQ,QAAQ;AAC9B,WAAQ;AACR,UAAO;;;CAIX,QAAQ;CACT,CAAC;AAEF,SAAS,UACP,MACA,OACA,UACS;AACT,KAAI,KAAK,UAAW,QAAO;CAC3B,MAAM,QAAQ,KAAK;CACnB,MAAM,YAAY,MAAM;AACxB,KAAI,CAAC,gBAAgB,UAAU,CAAE,QAAO;CACxC,MAAM,UAAU,UAAU;AAC1B,KAAI,CAAC,WAAW,QAAQ,OAAO,KAAK,KAAK,KAAM,QAAO;CAEtD,MAAM,aAAa,QAAQ,OAAO,YAChC,KAAK,IAAI,GAAG,QAAQ,eAAe,UAAU,EAC7C,QAAQ,cACR,MACA,6BACD;AAED,MAAK,MAAM,QAAQ,OAAO;AACxB,OAAK,MAAM,YAAY;EACvB,MAAM,QAAQ,KAAK,MAAM,KAAK,WAAW;EACzC,MAAM,KAAK,SACN,KAAK,QAAQ;GACd;GACA,MAAM,QAAQ,MAAM,MAAM,GAAG;GAC7B,IAAI,QAAQ;GACZ;GACD,CAAC;AACJ,MAAI,CAAC,GAAI;AACT,aAAW,GAAG;AAEd,MAAI,KAAK,KACP,QAAO;;AAGX,QAAO;;AAGT,MAAM,YAAY"}
1
+ {"version":3,"file":"enter-rule-CzWOZF_Z.js","names":["regex: RegExp","handler: EnterRuleHandler","stop: boolean","rules: EnterRule[]","command: Command"],"sources":["../src/enter-rule/index.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n getNodeType,\n isTextSelection,\n maybeRun,\n OBJECT_REPLACEMENT_CHARACTER,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport { keydownHandler } from '@prosekit/pm/keymap'\nimport type {\n Attrs,\n NodeType,\n} from '@prosekit/pm/model'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n type Command,\n type EditorState,\n type Transaction,\n} from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\n/**\n * @public\n *\n * Options for {@link EnterRuleHandler}.\n */\nexport interface EnterRuleHandlerOptions {\n /**\n * The current editor state.\n */\n state: EditorState\n\n /**\n * The start position of the matched text.\n */\n from: number\n\n /**\n * The end position of the matched text.\n */\n to: number\n\n /**\n * The matched result from the regular expression.\n */\n match: RegExpExecArray\n}\n\n/**\n * @public\n */\nexport type EnterRuleHandler = (options: EnterRuleHandlerOptions) => Transaction | null\n\n/**\n * Options for {@link defineEnterRule}.\n *\n * @public\n */\nexport type EnterRuleOptions = {\n /**\n * The regular expression to match against. It should end with `$`.\n */\n regex: RegExp\n\n /**\n * A function to be called when an enter rule is triggered.\n */\n handler: EnterRuleHandler\n\n /**\n * Whether to stop further handlers from being called if this rule is triggered.\n *\n * @default false\n */\n stop?: boolean\n}\n\n/**\n * Options for {@link defineTextBlockEnterRule}.\n *\n * @public\n */\nexport interface TextBlockEnterRuleOptions {\n /**\n * The regular expression to match against. It should end with `$`.\n */\n regex: RegExp\n\n /**\n * The node type to replace the matched text with.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node. If a function is provided, it will be called\n * with the matched result from the regular expression.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * Whether to stop further handlers from being called if this rule is triggered.\n *\n * @default true\n */\n stop?: boolean\n}\n\n/**\n * Defines an enter rule. An enter rule applies when the text directly in front of\n * the cursor matches `regex` and user presses Enter. The `regex` should end\n * with `$`.\n *\n * @param options\n *\n * @public\n */\nexport function defineEnterRule({\n regex,\n handler,\n stop = false,\n}: EnterRuleOptions): PlainExtension {\n const rule: EnterRule = new EnterRule(regex, handler, stop)\n return defineFacetPayload(enterRule, [rule]) as PlainExtension\n}\n\n/**\n * Defines an enter rule that replaces the matched text with a block node.\n *\n * See also {@link defineEnterRule}.\n *\n * @param options\n *\n * @public\n */\nexport function defineTextBlockEnterRule({\n regex,\n type,\n attrs,\n stop = true,\n}: TextBlockEnterRuleOptions): PlainExtension {\n return defineEnterRule({\n regex,\n handler: ({ state, from, to, match }) => {\n const nodeType = getNodeType(state.schema, type)\n const $start = state.doc.resolve(from)\n\n if (\n !$start\n .node(-1)\n .canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)\n ) {\n return null\n }\n\n const nodeAttrs = maybeRun(attrs, match)\n return state.tr\n .delete(from, to)\n .setBlockType(from, from, nodeType, nodeAttrs)\n },\n stop,\n })\n}\n\n/**\n * @internal\n */\nclass EnterRule {\n constructor(\n readonly regex: RegExp,\n readonly handler: EnterRuleHandler,\n readonly stop: boolean,\n ) {}\n}\n\nconst enterRule = defineFacet<EnterRule, PluginPayload>({\n reduce: () => {\n let rules: EnterRule[] = []\n\n const command: Command = (state, dispatch, view) => {\n if (!view) return false\n return execRules(view, rules, dispatch)\n }\n const handler = keydownHandler({ Enter: command })\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-enter-rule'),\n props: { handleKeyDown: handler },\n })\n\n return function reducer(inputs) {\n rules = inputs\n return plugin\n }\n },\n\n parent: pluginFacet,\n})\n\nfunction execRules(\n view: EditorView,\n rules: readonly EnterRule[],\n dispatch?: (tr: Transaction) => void,\n): boolean {\n if (view.composing) return false\n const state = view.state\n const selection = state.selection\n if (!isTextSelection(selection)) return false\n const $cursor = selection.$cursor\n if (!$cursor || $cursor.parent.type.spec.code) return false\n\n const textBefore = $cursor.parent.textBetween(\n Math.max(0, $cursor.parentOffset - MAX_MATCH),\n $cursor.parentOffset,\n null,\n OBJECT_REPLACEMENT_CHARACTER,\n )\n\n for (const rule of rules) {\n rule.regex.lastIndex = 0\n const match = rule.regex.exec(textBefore)\n const tr = match\n && rule.handler({\n state,\n from: $cursor.pos - match[0].length,\n to: $cursor.pos,\n match,\n })\n if (!tr) continue\n dispatch?.(tr)\n\n if (rule.stop) {\n return true\n }\n }\n return false\n}\n\nconst MAX_MATCH = 200\n"],"mappings":";;;;;;;;;;;;;;AAwHA,SAAgB,gBAAgB,EAC9B,OACA,SACA,OAAO,SAC4B;AAEnC,QAAO,mBAAmB,WAAW,CADb,IAAI,UAAU,OAAO,SAAS,KAAK,CAChB,CAAC;;;;;;;;;;;AAY9C,SAAgB,yBAAyB,EACvC,OACA,MACA,OACA,OAAO,QACqC;AAC5C,QAAO,gBAAgB;EACrB;EACA,UAAU,EAAE,OAAO,MAAM,IAAI,YAAY;GACvC,MAAM,WAAW,YAAY,MAAM,QAAQ,KAAK;GAChD,MAAM,SAAS,MAAM,IAAI,QAAQ,KAAK;AAEtC,OACE,CAAC,OACE,KAAK,GAAG,CACR,eAAe,OAAO,MAAM,GAAG,EAAE,OAAO,WAAW,GAAG,EAAE,SAAS,CAEpE,QAAO;GAGT,MAAM,YAAY,SAAS,OAAO,MAAM;AACxC,UAAO,MAAM,GACV,OAAO,MAAM,GAAG,CAChB,aAAa,MAAM,MAAM,UAAU,UAAU;;EAElD;EACD,CAAC;;;;;AAMJ,IAAM,YAAN,MAAgB;CACd,YACE,AAASA,OACT,AAASC,SACT,AAASC,MACT;EAHS;EACA;EACA;;;AAIb,MAAM,YAAY,YAAsC;CACtD,cAAc;EACZ,IAAIC,QAAqB,EAAE;EAE3B,MAAMC,WAAoB,OAAO,UAAU,SAAS;AAClD,OAAI,CAAC,KAAM,QAAO;AAClB,UAAO,UAAU,MAAM,OAAO,SAAS;;EAEzC,MAAM,UAAU,eAAe,EAAE,OAAO,SAAS,CAAC;EAClD,MAAM,SAAS,IAAI,kBAAkB;GACnC,KAAK,IAAI,UAAU,sBAAsB;GACzC,OAAO,EAAE,eAAe,SAAS;GAClC,CAAC;AAEF,SAAO,SAAS,QAAQ,QAAQ;AAC9B,WAAQ;AACR,UAAO;;;CAIX,QAAQ;CACT,CAAC;AAEF,SAAS,UACP,MACA,OACA,UACS;AACT,KAAI,KAAK,UAAW,QAAO;CAC3B,MAAM,QAAQ,KAAK;CACnB,MAAM,YAAY,MAAM;AACxB,KAAI,CAAC,gBAAgB,UAAU,CAAE,QAAO;CACxC,MAAM,UAAU,UAAU;AAC1B,KAAI,CAAC,WAAW,QAAQ,OAAO,KAAK,KAAK,KAAM,QAAO;CAEtD,MAAM,aAAa,QAAQ,OAAO,YAChC,KAAK,IAAI,GAAG,QAAQ,eAAe,UAAU,EAC7C,QAAQ,cACR,MACA,6BACD;AAED,MAAK,MAAM,QAAQ,OAAO;AACxB,OAAK,MAAM,YAAY;EACvB,MAAM,QAAQ,KAAK,MAAM,KAAK,WAAW;EACzC,MAAM,KAAK,SACN,KAAK,QAAQ;GACd;GACA,MAAM,QAAQ,MAAM,MAAM,GAAG;GAC7B,IAAI,QAAQ;GACZ;GACD,CAAC;AACJ,MAAI,CAAC,GAAI;AACT,aAAW,GAAG;AAEd,MAAI,KAAK,KACP,QAAO;;AAGX,QAAO;;AAGT,MAAM,YAAY"}
@@ -129,4 +129,4 @@ const store = /* @__PURE__ */ new Map();
129
129
 
130
130
  //#endregion
131
131
  export { defineFilePasteHandler as n, defineFileDropHandler as r, UploadTask as t };
132
- //# sourceMappingURL=file-DKoIIa7q.js.map
132
+ //# sourceMappingURL=file-DrfcSid-.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-DKoIIa7q.js","names":["getFiles","facet","getFiles","dropHandler: DropHandler","pasteHandler: PasteHandler"],"sources":["../src/file/helpers.ts","../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"sourcesContent":["import type { EditorView } from '@prosekit/pm/view'\n\ntype FileHandler<E extends Event> = (options: {\n view: EditorView\n event: E\n file: File\n}) => boolean | void\n\nfunction handleFile<E extends Event>(\n view: EditorView,\n event: E,\n file: File,\n handlers: FileHandler<E>[],\n) {\n // The last item in `handlers` should has the highest priority.\n for (let i = handlers.length - 1; i >= 0; i--) {\n const handler = handlers[i]\n if (handler({ view, event, file })) {\n return true\n }\n }\n return false\n}\n\nexport function handleEvent<E extends Event>(\n view: EditorView,\n event: E,\n handlers: FileHandler<E>[],\n getFiles: (event: E) => File[],\n): boolean {\n const files = getFiles(event)\n let handled = false\n for (const file of files) {\n if (handleFile(view, event, file, handlers)) {\n handled = true\n }\n }\n return handled\n}\n","import {\n defineFacet,\n defineFacetPayload,\n editorEventFacet,\n type DropHandler,\n type EditorEventPayload,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { handleEvent } from './helpers'\n\nexport interface FileDropHandlerOptions {\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * The event that triggered the drop.\n */\n event: DragEvent\n\n /**\n * The file that was dropped.\n */\n file: File\n\n /**\n * The position of the document where the file was dropped.\n */\n pos: number\n}\n\n/**\n * A function that handles one of the files in a drop event.\n *\n * Returns `true` if the file was handled and thus should not be handled by\n * other handlers.\n */\nexport type FileDropHandler = (\n options: FileDropHandlerOptions,\n) => boolean | void\n\nexport function defineFileDropHandler(\n handler: FileDropHandler,\n): PlainExtension {\n return defineFacetPayload(facet, [handler]) as PlainExtension\n}\n\nfunction getFiles(event: DragEvent) {\n return Array.from(event.dataTransfer?.files ?? [])\n}\n\nconst facet = defineFacet<FileDropHandler, EditorEventPayload>({\n parent: editorEventFacet,\n singleton: true,\n reducer: (handlers: FileDropHandler[]): EditorEventPayload => {\n const dropHandler: DropHandler = (view, event): boolean => {\n const position = view.posAtCoords({ left: event.x, top: event.y })\n if (!position) {\n return false\n }\n const pos = position.inside > 0 ? position.inside : position.pos\n\n return handleEvent<DragEvent>(\n view,\n event,\n handlers.map((handler) => (options) => handler({ ...options, pos })),\n getFiles,\n )\n }\n return ['drop', dropHandler]\n },\n})\n","import {\n defineFacet,\n defineFacetPayload,\n editorEventFacet,\n type EditorEventPayload,\n type PasteHandler,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { handleEvent } from './helpers'\n\nexport interface FilePasteHandlerOptions {\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * The event that triggered the paste.\n */\n event: ClipboardEvent\n\n /**\n * The file that was pasted.\n */\n file: File\n}\n\n/**\n * A function that handles one of the files in a paste event.\n *\n * Returns `true` if the file was handled and thus should not be handled by\n * other handlers.\n */\nexport type FilePasteHandler = (\n options: FilePasteHandlerOptions,\n) => boolean | void\n\nexport function defineFilePasteHandler(\n handler: FilePasteHandler,\n): PlainExtension {\n return defineFacetPayload(facet, [handler]) as PlainExtension\n}\n\nfunction getFiles(event: ClipboardEvent) {\n return Array.from(event.clipboardData?.files ?? [])\n}\n\nconst facet = defineFacet<FilePasteHandler, EditorEventPayload>({\n parent: editorEventFacet,\n singleton: true,\n reducer: (handlers: FilePasteHandler[]): EditorEventPayload => {\n const pasteHandler: PasteHandler = (view, event): boolean => {\n return handleEvent<ClipboardEvent>(view, event, handlers, getFiles)\n }\n return ['paste', pasteHandler]\n },\n})\n","import { ProseKitError } from '@prosekit/core'\n\n/**\n * An interface representing the upload progress.\n */\nexport interface UploadProgress {\n // A number representing the amount of work already performed by the\n // underlying process.\n loaded: number\n // A number representing the total amount of work that the underlying\n // process is in the progress of performing.\n total: number\n}\n\nexport interface UploaderOptions {\n /**\n * The file to be uploaded.\n */\n file: File\n\n /**\n * A callback function that should be called with the upload progress updates.\n */\n onProgress: (progress: UploadProgress) => void\n}\n\n/**\n * The implementation of the actual upload function. You need to implement this\n * function to upload files to your desired destination.\n */\nexport type Uploader<Result> = (options: UploaderOptions) => Promise<Result>\n\n/**\n * A class that represents a upload task.\n */\nexport class UploadTask<Result> {\n /**\n * An [object URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)\n * representing the file to be uploaded. This URL will be revoked once the\n * upload is complete successfully.\n */\n readonly objectURL: string\n\n /**\n * A boolean indicating whether the upload is complete (either successfully or with an error).\n */\n protected done = false\n\n /**\n * If the upload is complete successfully, this will be the result of the upload.\n */\n protected result: Result | undefined\n\n /**\n * If the upload is complete with an error, this will be the error that occurred.\n */\n protected error: Error | undefined\n\n /**\n * A promise that fulfills once the upload is complete, or rejects if an error occurs.\n */\n readonly finished: Promise<Result>\n\n private subscribers: ((progress: UploadProgress) => void)[] = []\n\n /**\n * Creates a new upload task. You can find the upload task by its object URL\n * later using `UploadTask.get()`.\n *\n * @param options - The options for the upload task.\n */\n constructor({ file, uploader }: { file: File; uploader: Uploader<Result> }) {\n this.objectURL = URL.createObjectURL(file)\n this.finished = new Promise((resolve, reject) => {\n const maybePromise = uploader({\n file,\n onProgress: (progress) => {\n for (const subscriber of this.subscribers) {\n subscriber(progress)\n }\n },\n })\n Promise.resolve(maybePromise).then(\n (result) => {\n this.done = true\n URL.revokeObjectURL(this.objectURL)\n this.result = result\n resolve(result)\n },\n (err) => {\n this.done = true\n const error = new ProseKitError('[prosekit] Failed to upload file', { cause: err })\n this.error = error\n reject(error)\n },\n )\n })\n store.set(this.objectURL, this)\n }\n\n /**\n * Subscribes to progress updates. Returns a function to unsubscribe.\n */\n public subscribeProgress(\n callback: (progress: UploadProgress) => void,\n ): VoidFunction {\n this.subscribers.push(callback)\n return () => {\n this.subscribers = this.subscribers.filter(\n (subscriber) => subscriber !== callback,\n )\n }\n }\n\n /**\n * Finds an upload task from the global store by its object URL.\n */\n static get<Result = unknown>(\n objectURL: string,\n ): UploadTask<Result> | undefined {\n return store.get(objectURL) as UploadTask<Result> | undefined\n }\n\n /**\n * Deletes an upload task from the global store by its object URL.\n */\n static delete(objectURL: string): void {\n store.delete(objectURL)\n }\n}\n\nconst store = new Map<string, UploadTask<unknown>>()\n"],"mappings":";;;AAQA,SAAS,WACP,MACA,OACA,MACA,UACA;AAEA,MAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,UAAU,SAAS;AACzB,MAAI,QAAQ;GAAE;GAAM;GAAO;GAAM,CAAC,CAChC,QAAO;;AAGX,QAAO;;AAGT,SAAgB,YACd,MACA,OACA,UACA,YACS;CACT,MAAM,QAAQA,WAAS,MAAM;CAC7B,IAAI,UAAU;AACd,MAAK,MAAM,QAAQ,MACjB,KAAI,WAAW,MAAM,OAAO,MAAM,SAAS,CACzC,WAAU;AAGd,QAAO;;;;;ACOT,SAAgB,sBACd,SACgB;AAChB,QAAO,mBAAmBC,SAAO,CAAC,QAAQ,CAAC;;AAG7C,SAASC,WAAS,OAAkB;AAClC,QAAO,MAAM,KAAK,MAAM,cAAc,SAAS,EAAE,CAAC;;AAGpD,MAAMD,UAAQ,YAAiD;CAC7D,QAAQ;CACR,WAAW;CACX,UAAU,aAAoD;EAC5D,MAAME,eAA4B,MAAM,UAAmB;GACzD,MAAM,WAAW,KAAK,YAAY;IAAE,MAAM,MAAM;IAAG,KAAK,MAAM;IAAG,CAAC;AAClE,OAAI,CAAC,SACH,QAAO;GAET,MAAM,MAAM,SAAS,SAAS,IAAI,SAAS,SAAS,SAAS;AAE7D,UAAO,YACL,MACA,OACA,SAAS,KAAK,aAAa,YAAY,QAAQ;IAAE,GAAG;IAAS;IAAK,CAAC,CAAC,EACpED,WACD;;AAEH,SAAO,CAAC,QAAQ,YAAY;;CAE/B,CAAC;;;;ACnCF,SAAgB,uBACd,SACgB;AAChB,QAAO,mBAAmB,OAAO,CAAC,QAAQ,CAAC;;AAG7C,SAAS,SAAS,OAAuB;AACvC,QAAO,MAAM,KAAK,MAAM,eAAe,SAAS,EAAE,CAAC;;AAGrD,MAAM,QAAQ,YAAkD;CAC9D,QAAQ;CACR,WAAW;CACX,UAAU,aAAqD;EAC7D,MAAME,gBAA8B,MAAM,UAAmB;AAC3D,UAAO,YAA4B,MAAM,OAAO,UAAU,SAAS;;AAErE,SAAO,CAAC,SAAS,aAAa;;CAEjC,CAAC;;;;;;;ACvBF,IAAa,aAAb,MAAgC;;;;;;;CAoC9B,YAAY,EAAE,MAAM,YAAwD;cAzB3D;qBAiB6C,EAAE;AAS9D,OAAK,YAAY,IAAI,gBAAgB,KAAK;AAC1C,OAAK,WAAW,IAAI,SAAS,SAAS,WAAW;GAC/C,MAAM,eAAe,SAAS;IAC5B;IACA,aAAa,aAAa;AACxB,UAAK,MAAM,cAAc,KAAK,YAC5B,YAAW,SAAS;;IAGzB,CAAC;AACF,WAAQ,QAAQ,aAAa,CAAC,MAC3B,WAAW;AACV,SAAK,OAAO;AACZ,QAAI,gBAAgB,KAAK,UAAU;AACnC,SAAK,SAAS;AACd,YAAQ,OAAO;OAEhB,QAAQ;AACP,SAAK,OAAO;IACZ,MAAM,QAAQ,IAAI,cAAc,oCAAoC,EAAE,OAAO,KAAK,CAAC;AACnF,SAAK,QAAQ;AACb,WAAO,MAAM;KAEhB;IACD;AACF,QAAM,IAAI,KAAK,WAAW,KAAK;;;;;CAMjC,AAAO,kBACL,UACc;AACd,OAAK,YAAY,KAAK,SAAS;AAC/B,eAAa;AACX,QAAK,cAAc,KAAK,YAAY,QACjC,eAAe,eAAe,SAChC;;;;;;CAOL,OAAO,IACL,WACgC;AAChC,SAAO,MAAM,IAAI,UAAU;;;;;CAM7B,OAAO,OAAO,WAAyB;AACrC,QAAM,OAAO,UAAU;;;AAI3B,MAAM,wBAAQ,IAAI,KAAkC"}
1
+ {"version":3,"file":"file-DrfcSid-.js","names":["getFiles","facet","getFiles","dropHandler: DropHandler","pasteHandler: PasteHandler"],"sources":["../src/file/helpers.ts","../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"sourcesContent":["import type { EditorView } from '@prosekit/pm/view'\n\ntype FileHandler<E extends Event> = (options: {\n view: EditorView\n event: E\n file: File\n}) => boolean | void\n\nfunction handleFile<E extends Event>(\n view: EditorView,\n event: E,\n file: File,\n handlers: FileHandler<E>[],\n) {\n // The last item in `handlers` should has the highest priority.\n for (let i = handlers.length - 1; i >= 0; i--) {\n const handler = handlers[i]\n if (handler({ view, event, file })) {\n return true\n }\n }\n return false\n}\n\nexport function handleEvent<E extends Event>(\n view: EditorView,\n event: E,\n handlers: FileHandler<E>[],\n getFiles: (event: E) => File[],\n): boolean {\n const files = getFiles(event)\n let handled = false\n for (const file of files) {\n if (handleFile(view, event, file, handlers)) {\n handled = true\n }\n }\n return handled\n}\n","import {\n defineFacet,\n defineFacetPayload,\n editorEventFacet,\n type DropHandler,\n type EditorEventPayload,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { handleEvent } from './helpers'\n\nexport interface FileDropHandlerOptions {\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * The event that triggered the drop.\n */\n event: DragEvent\n\n /**\n * The file that was dropped.\n */\n file: File\n\n /**\n * The position of the document where the file was dropped.\n */\n pos: number\n}\n\n/**\n * A function that handles one of the files in a drop event.\n *\n * Returns `true` if the file was handled and thus should not be handled by\n * other handlers.\n */\nexport type FileDropHandler = (\n options: FileDropHandlerOptions,\n) => boolean | void\n\nexport function defineFileDropHandler(\n handler: FileDropHandler,\n): PlainExtension {\n return defineFacetPayload(facet, [handler]) as PlainExtension\n}\n\nfunction getFiles(event: DragEvent) {\n return Array.from(event.dataTransfer?.files ?? [])\n}\n\nconst facet = defineFacet<FileDropHandler, EditorEventPayload>({\n parent: editorEventFacet,\n singleton: true,\n reducer: (handlers: FileDropHandler[]): EditorEventPayload => {\n const dropHandler: DropHandler = (view, event): boolean => {\n const position = view.posAtCoords({ left: event.x, top: event.y })\n if (!position) {\n return false\n }\n const pos = position.inside > 0 ? position.inside : position.pos\n\n return handleEvent<DragEvent>(\n view,\n event,\n handlers.map((handler) => (options) => handler({ ...options, pos })),\n getFiles,\n )\n }\n return ['drop', dropHandler]\n },\n})\n","import {\n defineFacet,\n defineFacetPayload,\n editorEventFacet,\n type EditorEventPayload,\n type PasteHandler,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { handleEvent } from './helpers'\n\nexport interface FilePasteHandlerOptions {\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * The event that triggered the paste.\n */\n event: ClipboardEvent\n\n /**\n * The file that was pasted.\n */\n file: File\n}\n\n/**\n * A function that handles one of the files in a paste event.\n *\n * Returns `true` if the file was handled and thus should not be handled by\n * other handlers.\n */\nexport type FilePasteHandler = (\n options: FilePasteHandlerOptions,\n) => boolean | void\n\nexport function defineFilePasteHandler(\n handler: FilePasteHandler,\n): PlainExtension {\n return defineFacetPayload(facet, [handler]) as PlainExtension\n}\n\nfunction getFiles(event: ClipboardEvent) {\n return Array.from(event.clipboardData?.files ?? [])\n}\n\nconst facet = defineFacet<FilePasteHandler, EditorEventPayload>({\n parent: editorEventFacet,\n singleton: true,\n reducer: (handlers: FilePasteHandler[]): EditorEventPayload => {\n const pasteHandler: PasteHandler = (view, event): boolean => {\n return handleEvent<ClipboardEvent>(view, event, handlers, getFiles)\n }\n return ['paste', pasteHandler]\n },\n})\n","import { ProseKitError } from '@prosekit/core'\n\n/**\n * An interface representing the upload progress.\n */\nexport interface UploadProgress {\n // A number representing the amount of work already performed by the\n // underlying process.\n loaded: number\n // A number representing the total amount of work that the underlying\n // process is in the progress of performing.\n total: number\n}\n\nexport interface UploaderOptions {\n /**\n * The file to be uploaded.\n */\n file: File\n\n /**\n * A callback function that should be called with the upload progress updates.\n */\n onProgress: (progress: UploadProgress) => void\n}\n\n/**\n * The implementation of the actual upload function. You need to implement this\n * function to upload files to your desired destination.\n */\nexport type Uploader<Result> = (options: UploaderOptions) => Promise<Result>\n\n/**\n * A class that represents a upload task.\n */\nexport class UploadTask<Result> {\n /**\n * An [object URL](https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL)\n * representing the file to be uploaded. This URL will be revoked once the\n * upload is complete successfully.\n */\n readonly objectURL: string\n\n /**\n * A boolean indicating whether the upload is complete (either successfully or with an error).\n */\n protected done = false\n\n /**\n * If the upload is complete successfully, this will be the result of the upload.\n */\n protected result: Result | undefined\n\n /**\n * If the upload is complete with an error, this will be the error that occurred.\n */\n protected error: Error | undefined\n\n /**\n * A promise that fulfills once the upload is complete, or rejects if an error occurs.\n */\n readonly finished: Promise<Result>\n\n private subscribers: ((progress: UploadProgress) => void)[] = []\n\n /**\n * Creates a new upload task. You can find the upload task by its object URL\n * later using `UploadTask.get()`.\n *\n * @param options - The options for the upload task.\n */\n constructor({ file, uploader }: { file: File; uploader: Uploader<Result> }) {\n this.objectURL = URL.createObjectURL(file)\n this.finished = new Promise((resolve, reject) => {\n const maybePromise = uploader({\n file,\n onProgress: (progress) => {\n for (const subscriber of this.subscribers) {\n subscriber(progress)\n }\n },\n })\n Promise.resolve(maybePromise).then(\n (result) => {\n this.done = true\n URL.revokeObjectURL(this.objectURL)\n this.result = result\n resolve(result)\n },\n (err) => {\n this.done = true\n const error = new ProseKitError('[prosekit] Failed to upload file', { cause: err })\n this.error = error\n reject(error)\n },\n )\n })\n store.set(this.objectURL, this)\n }\n\n /**\n * Subscribes to progress updates. Returns a function to unsubscribe.\n */\n public subscribeProgress(\n callback: (progress: UploadProgress) => void,\n ): VoidFunction {\n this.subscribers.push(callback)\n return () => {\n this.subscribers = this.subscribers.filter(\n (subscriber) => subscriber !== callback,\n )\n }\n }\n\n /**\n * Finds an upload task from the global store by its object URL.\n */\n static get<Result = unknown>(\n objectURL: string,\n ): UploadTask<Result> | undefined {\n return store.get(objectURL) as UploadTask<Result> | undefined\n }\n\n /**\n * Deletes an upload task from the global store by its object URL.\n */\n static delete(objectURL: string): void {\n store.delete(objectURL)\n }\n}\n\nconst store = new Map<string, UploadTask<unknown>>()\n"],"mappings":";;;AAQA,SAAS,WACP,MACA,OACA,MACA,UACA;AAEA,MAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,UAAU,SAAS;AACzB,MAAI,QAAQ;GAAE;GAAM;GAAO;GAAM,CAAC,CAChC,QAAO;;AAGX,QAAO;;AAGT,SAAgB,YACd,MACA,OACA,UACA,YACS;CACT,MAAM,QAAQA,WAAS,MAAM;CAC7B,IAAI,UAAU;AACd,MAAK,MAAM,QAAQ,MACjB,KAAI,WAAW,MAAM,OAAO,MAAM,SAAS,CACzC,WAAU;AAGd,QAAO;;;;;ACOT,SAAgB,sBACd,SACgB;AAChB,QAAO,mBAAmBC,SAAO,CAAC,QAAQ,CAAC;;AAG7C,SAASC,WAAS,OAAkB;AAClC,QAAO,MAAM,KAAK,MAAM,cAAc,SAAS,EAAE,CAAC;;AAGpD,MAAMD,UAAQ,YAAiD;CAC7D,QAAQ;CACR,WAAW;CACX,UAAU,aAAoD;EAC5D,MAAME,eAA4B,MAAM,UAAmB;GACzD,MAAM,WAAW,KAAK,YAAY;IAAE,MAAM,MAAM;IAAG,KAAK,MAAM;IAAG,CAAC;AAClE,OAAI,CAAC,SACH,QAAO;GAET,MAAM,MAAM,SAAS,SAAS,IAAI,SAAS,SAAS,SAAS;AAE7D,UAAO,YACL,MACA,OACA,SAAS,KAAK,aAAa,YAAY,QAAQ;IAAE,GAAG;IAAS;IAAK,CAAC,CAAC,EACpED,WACD;;AAEH,SAAO,CAAC,QAAQ,YAAY;;CAE/B,CAAC;;;;ACnCF,SAAgB,uBACd,SACgB;AAChB,QAAO,mBAAmB,OAAO,CAAC,QAAQ,CAAC;;AAG7C,SAAS,SAAS,OAAuB;AACvC,QAAO,MAAM,KAAK,MAAM,eAAe,SAAS,EAAE,CAAC;;AAGrD,MAAM,QAAQ,YAAkD;CAC9D,QAAQ;CACR,WAAW;CACX,UAAU,aAAqD;EAC7D,MAAME,gBAA8B,MAAM,UAAmB;AAC3D,UAAO,YAA4B,MAAM,OAAO,UAAU,SAAS;;AAErE,SAAO,CAAC,SAAS,aAAa;;CAEjC,CAAC;;;;;;;ACvBF,IAAa,aAAb,MAAgC;;;;;;;CAoC9B,YAAY,EAAE,MAAM,YAAwD;cAzB3D;qBAiB6C,EAAE;AAS9D,OAAK,YAAY,IAAI,gBAAgB,KAAK;AAC1C,OAAK,WAAW,IAAI,SAAS,SAAS,WAAW;GAC/C,MAAM,eAAe,SAAS;IAC5B;IACA,aAAa,aAAa;AACxB,UAAK,MAAM,cAAc,KAAK,YAC5B,YAAW,SAAS;;IAGzB,CAAC;AACF,WAAQ,QAAQ,aAAa,CAAC,MAC3B,WAAW;AACV,SAAK,OAAO;AACZ,QAAI,gBAAgB,KAAK,UAAU;AACnC,SAAK,SAAS;AACd,YAAQ,OAAO;OAEhB,QAAQ;AACP,SAAK,OAAO;IACZ,MAAM,QAAQ,IAAI,cAAc,oCAAoC,EAAE,OAAO,KAAK,CAAC;AACnF,SAAK,QAAQ;AACb,WAAO,MAAM;KAEhB;IACD;AACF,QAAM,IAAI,KAAK,WAAW,KAAK;;;;;CAMjC,AAAO,kBACL,UACc;AACd,OAAK,YAAY,KAAK,SAAS;AAC/B,eAAa;AACX,QAAK,cAAc,KAAK,YAAY,QACjC,eAAe,eAAe,SAChC;;;;;;CAOL,OAAO,IACL,WACgC;AAChC,SAAO,MAAM,IAAI,UAAU;;;;;CAM7B,OAAO,OAAO,WAAyB;AACrC,QAAM,OAAO,UAAU;;;AAI3B,MAAM,wBAAQ,IAAI,KAAkC"}
@@ -131,4 +131,4 @@ declare class UploadTask<Result> {
131
131
  }
132
132
  //#endregion
133
133
  export { FilePasteHandler as a, FileDropHandler as c, UploaderOptions as i, FileDropHandlerOptions as l, UploadTask as n, FilePasteHandlerOptions as o, Uploader as r, defineFilePasteHandler as s, UploadProgress as t, defineFileDropHandler as u };
134
- //# sourceMappingURL=index-DdjnBeho.d.ts.map
134
+ //# sourceMappingURL=index-oIc1a2f2.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-DdjnBeho.d.ts","names":[],"sources":["../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"sourcesContent":[],"mappings":";;;;UAYiB,sBAAA;;AAAjB;;EASS,IAAA,EALD,UAKC;EAKD;;AAcR;EAIgB,KAAA,EAvBP,SAuBO;;;;EChCC,IAAA,EDcT,ICdS;EAIT;;;EAUI,GAAA,EAAA,MAAA;AASZ;AAIA;;;;AClCA;AASA;AAgBY,KFUA,eAAA,GEVQ,CAAA,OAAA,EFWT,sBEXS,EAAA,GAAA,OAAA,GAAA,IAAA;AAAqB,iBFczB,qBAAA,CEdyB,OAAA,EFe9B,eEf8B,CAAA,EFgBtC,cEhBsC;;;UDlBxB,uBAAA;;ADAjB;;EASS,IAAA,ECLD,UDKC;EAKD;;AAcR;EAIgB,KAAA,ECvBP,cDuBO;;;;EChCC,IAAA,EAcT,IAdS;;;;;AAuBjB;AAIA;;KAJY,gBAAA,aACD;iBAGK,sBAAA,UACL,mBACR;;;;;;UCpCc,cAAA;EFOA,MAAA,EAAA,MAAA;EAIT,KAAA,EAAA,MAAA;;AAUA,UEZS,eAAA,CFYT;EAAI;AAcZ;AAIA;QE1BQ;;;ADNR;EAIQ,UAAA,EAAA,CAAA,QAAA,ECOiB,cDPjB,EAAA,GAAA,IAAA;;;;AAmBR;AAIA;KCTY,6BAA6B,oBAAoB,QAAQ;;;AAzBrE;AASiB,cAqBJ,UArBmB,CAAA,MAIxB,CAAA,CAAA;EAYI;;;;;EAKC,SAAA,SAAU,EAAA,MAAA;EAgBH;;;EAUC,UAAA,IAAA,EAAA,OAAA;EAUL;;;EAAmD,UAAA,MAAA,EApB/C,MAoB+C,GAAA,SAAA;EAAT;;;EAgD1C,UAAA,KAAA,EA/DG,KA+DH,GAAA,SAAA;EAAX;;;qBA1DgB,QAAQ;;;;;;;;;;;;UAUa;cAAgB,SAAS;;;;;yCAiC1C,0BACpB;;;;mDAcA,WAAW"}
1
+ {"version":3,"file":"index-oIc1a2f2.d.ts","names":[],"sources":["../src/file/file-drop-handler.ts","../src/file/file-paste-handler.ts","../src/file/file-upload.ts"],"sourcesContent":[],"mappings":";;;;UAYiB,sBAAA;;AAAjB;;EASS,IAAA,EALD,UAKC;EAKD;;AAcR;EAIgB,KAAA,EAvBP,SAuBO;;;;EChCC,IAAA,EDcT,ICdS;EAIT;;;EAUI,GAAA,EAAA,MAAA;AASZ;AAIA;;;;AClCA;AASA;AAgBY,KFUA,eAAA,GEVQ,CAAA,OAAA,EFWT,sBEXS,EAAA,GAAA,OAAA,GAAA,IAAA;AAAqB,iBFczB,qBAAA,CEdyB,OAAA,EFe9B,eEf8B,CAAA,EFgBtC,cEhBsC;;;UDlBxB,uBAAA;;ADAjB;;EASS,IAAA,ECLD,UDKC;EAKD;;AAcR;EAIgB,KAAA,ECvBP,cDuBO;;;;EChCC,IAAA,EAcT,IAdS;;;;;AAuBjB;AAIA;;KAJY,gBAAA,aACD;iBAGK,sBAAA,UACL,mBACR;;;;;;UCpCc,cAAA;EFOA,MAAA,EAAA,MAAA;EAIT,KAAA,EAAA,MAAA;;AAUA,UEZS,eAAA,CFYT;EAAI;AAcZ;AAIA;QE1BQ;;;ADNR;EAIQ,UAAA,EAAA,CAAA,QAAA,ECOiB,cDPjB,EAAA,GAAA,IAAA;;;;AAmBR;AAIA;KCTY,6BAA6B,oBAAoB,QAAQ;;;AAzBrE;AASiB,cAqBJ,UArBmB,CAAA,MAIxB,CAAA,CAAA;EAYI;;;;;EAKC,SAAA,SAAU,EAAA,MAAA;EAgBH;;;EAUC,UAAA,IAAA,EAAA,OAAA;EAUL;;;EAAmD,UAAA,MAAA,EApB/C,MAoB+C,GAAA,SAAA;EAAT;;;EAgD1C,UAAA,KAAA,EA/DG,KA+DH,GAAA,SAAA;EAAX;;;qBA1DgB,QAAQ;;;;;;;;;;;;UAUa;cAAgB,SAAS;;;;;yCAiC1C,0BACpB;;;;mDAcA,WAAW"}
@@ -87,4 +87,4 @@ const inputRuleFacet = defineFacet({
87
87
 
88
88
  //#endregion
89
89
  export { defineWrappingInputRule as a, defineTextBlockInputRule as i, defineInputRule as n, defineMarkInputRule as r, createMarkInputRule as t };
90
- //# sourceMappingURL=input-rule-COGr_GBb.js.map
90
+ //# sourceMappingURL=input-rule-dmsb3j6w.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-rule-COGr_GBb.js","names":[],"sources":["../src/input-rule/index.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n getMarkType,\n getNodeType,\n isMarkAbsent,\n maybeRun,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport {\n InputRule,\n inputRules,\n textblockTypeInputRule,\n wrappingInputRule,\n} from '@prosekit/pm/inputrules'\nimport type {\n Attrs,\n MarkType,\n NodeType,\n ProseMirrorNode,\n Schema,\n} from '@prosekit/pm/model'\nimport type { Plugin } from '@prosekit/pm/state'\n\n/**\n * Defines an input rule extension.\n *\n * @param rule - The ProseMirror input rule to add.\n *\n * @public\n */\nexport function defineInputRule(rule: InputRule): PlainExtension {\n return defineInputRuleFacetPayload(() => rule)\n}\n\n/**\n * Options for {@link defineMarkInputRule}.\n *\n * @public\n */\nexport interface MarkInputRuleOptions {\n /**\n * The regular expression to match against, which should end with `$` and has\n * exactly one capture group. All other matched text outside the capture group\n * will be deleted.\n */\n regex: RegExp\n\n /**\n * The type of mark to set.\n */\n type: string | MarkType\n\n /**\n * Attributes to set on the mark.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * Whether this rule should fire inside marks marked as [code](https://prosemirror.net/docs/ref/#model.MarkSpec.code).\n *\n * @default `false`\n */\n inCodeMark?: boolean\n}\n\n/**\n * @internal\n */\nexport function createMarkInputRule({\n regex,\n type,\n attrs = null,\n inCodeMark = false,\n}: MarkInputRuleOptions): InputRule {\n const rule = new InputRule(regex, (state, match, start, end) => {\n const { tr, schema } = state\n const [fullText, markText] = match\n\n if (!markText) {\n return null\n }\n\n const markStart = start + fullText.indexOf(markText)\n const markEnd = markStart + markText.length\n\n if (!(start <= markStart && markStart < markEnd && markEnd <= end)) {\n // Incorrect regex.\n return null\n }\n\n const markType = getMarkType(schema, type)\n const mark = markType.create(maybeRun(attrs, match))\n\n if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs)) {\n // The mark is already active.\n return null\n }\n\n const initialStoredMarks = tr.storedMarks ?? []\n\n tr.addMark(markStart, markEnd, mark)\n\n if (markEnd < end) {\n tr.delete(markEnd, end)\n }\n if (start < markStart) {\n tr.delete(start, markStart)\n }\n\n // Make sure not to reactivate any marks which had previously been\n // deactivated. By keeping track of the initial stored marks we are able to\n // discard any unintended consequences of deleting text and adding it again.\n tr.setStoredMarks(initialStoredMarks)\n\n return tr\n }, { inCodeMark })\n\n return rule\n}\n\n/**\n * Defines an input rule for automatically adding inline marks when a given\n * pattern is typed.\n *\n * @public\n */\nexport function defineMarkInputRule(\n options: MarkInputRuleOptions,\n): PlainExtension {\n return defineInputRule(createMarkInputRule(options))\n}\n\n/**\n * Defines an input rule that changes the type of a textblock when the matched\n * text is typed into it.\n *\n * See also [textblockTypeInputRule](https://prosemirror.net/docs/ref/#inputrules.textblockTypeInputRule)\n *\n * @param options\n *\n * @public\n */\nexport function defineTextBlockInputRule({\n regex,\n type,\n attrs,\n}: {\n /**\n * The regular expression to match against, which should end with `$`. It\n * usually also starts with `^` to that it is only matched at the start of a\n * textblock.\n */\n regex: RegExp\n\n /**\n * The node type to replace the matched text with.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n}): PlainExtension {\n return defineInputRuleFacetPayload(({ schema }): InputRule => {\n const nodeType = getNodeType(schema, type)\n return textblockTypeInputRule(regex, nodeType, attrs)\n })\n}\n\n/**\n * Defines an input rule for automatically wrapping a textblock when a given\n * string is typed.\n *\n * See also [wrappingInputRule](https://prosemirror.net/docs/ref/#inputrules.wrappingInputRule)\n *\n * @param options\n *\n * @public\n */\nexport function defineWrappingInputRule({\n regex,\n type,\n attrs,\n join,\n}: {\n /**\n * The regular expression to match against, which should end with `$`. It\n * usually also starts with `^` to that it is only matched at the start of a\n * textblock.\n */\n regex: RegExp\n\n /**\n * The type of node to wrap in.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * By default, if there's a node with the same type above the newly wrapped\n * node, the rule will try to\n * [join](https://prosemirror.net/docs/ref/#transform.Transform.join) those\n * two nodes. You can pass a join predicate, which takes a regular expression\n * match and the node before the wrapped node, and can return a boolean to\n * indicate whether a join should happen.\n */\n join?: (match: RegExpMatchArray, node: ProseMirrorNode) => boolean\n}): PlainExtension {\n return defineInputRuleFacetPayload(({ schema }): InputRule => {\n const nodeType = getNodeType(schema, type)\n return wrappingInputRule(regex, nodeType, attrs, join)\n })\n}\n\nfunction defineInputRuleFacetPayload(input: InputRulePayload): PlainExtension {\n return defineFacetPayload(inputRuleFacet, [input]) as PlainExtension\n}\n\ntype InputRulePayload = (context: { schema: Schema }) => InputRule\n\nconst inputRuleFacet = defineFacet<InputRulePayload, PluginPayload>({\n reducer: (inputs: InputRulePayload[]): PluginPayload => {\n return (context): Plugin[] => {\n const rules: InputRule[] = inputs.flatMap((callback) => callback(context))\n return [inputRules({ rules })]\n }\n },\n parent: pluginFacet,\n})\n"],"mappings":";;;;;;;;;;;AAiCA,SAAgB,gBAAgB,MAAiC;AAC/D,QAAO,kCAAkC,KAAK;;;;;AAqChD,SAAgB,oBAAoB,EAClC,OACA,MACA,QAAQ,MACR,aAAa,SACqB;AA4ClC,QA3Ca,IAAI,UAAU,QAAQ,OAAO,OAAO,OAAO,QAAQ;EAC9D,MAAM,EAAE,IAAI,WAAW;EACvB,MAAM,CAAC,UAAU,YAAY;AAE7B,MAAI,CAAC,SACH,QAAO;EAGT,MAAM,YAAY,QAAQ,SAAS,QAAQ,SAAS;EACpD,MAAM,UAAU,YAAY,SAAS;AAErC,MAAI,EAAE,SAAS,aAAa,YAAY,WAAW,WAAW,KAE5D,QAAO;EAGT,MAAM,WAAW,YAAY,QAAQ,KAAK;EAC1C,MAAM,OAAO,SAAS,OAAO,SAAS,OAAO,MAAM,CAAC;AAEpD,MAAI,CAAC,aAAa,GAAG,KAAK,WAAW,SAAS,UAAU,MAAM,CAE5D,QAAO;EAGT,MAAM,qBAAqB,GAAG,eAAe,EAAE;AAE/C,KAAG,QAAQ,WAAW,SAAS,KAAK;AAEpC,MAAI,UAAU,IACZ,IAAG,OAAO,SAAS,IAAI;AAEzB,MAAI,QAAQ,UACV,IAAG,OAAO,OAAO,UAAU;AAM7B,KAAG,eAAe,mBAAmB;AAErC,SAAO;IACN,EAAE,YAAY,CAAC;;;;;;;;AAWpB,SAAgB,oBACd,SACgB;AAChB,QAAO,gBAAgB,oBAAoB,QAAQ,CAAC;;;;;;;;;;;;AAatD,SAAgB,yBAAyB,EACvC,OACA,MACA,SAkBiB;AACjB,QAAO,6BAA6B,EAAE,aAAwB;AAE5D,SAAO,uBAAuB,OADb,YAAY,QAAQ,KAAK,EACK,MAAM;GACrD;;;;;;;;;;;;AAaJ,SAAgB,wBAAwB,EACtC,OACA,MACA,OACA,QA4BiB;AACjB,QAAO,6BAA6B,EAAE,aAAwB;AAE5D,SAAO,kBAAkB,OADR,YAAY,QAAQ,KAAK,EACA,OAAO,KAAK;GACtD;;AAGJ,SAAS,4BAA4B,OAAyC;AAC5E,QAAO,mBAAmB,gBAAgB,CAAC,MAAM,CAAC;;AAKpD,MAAM,iBAAiB,YAA6C;CAClE,UAAU,WAA8C;AACtD,UAAQ,YAAsB;AAE5B,UAAO,CAAC,WAAW,EAAE,OADM,OAAO,SAAS,aAAa,SAAS,QAAQ,CAAC,EAC9C,CAAC,CAAC;;;CAGlC,QAAQ;CACT,CAAC"}
1
+ {"version":3,"file":"input-rule-dmsb3j6w.js","names":[],"sources":["../src/input-rule/index.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n getMarkType,\n getNodeType,\n isMarkAbsent,\n maybeRun,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport {\n InputRule,\n inputRules,\n textblockTypeInputRule,\n wrappingInputRule,\n} from '@prosekit/pm/inputrules'\nimport type {\n Attrs,\n MarkType,\n NodeType,\n ProseMirrorNode,\n Schema,\n} from '@prosekit/pm/model'\nimport type { Plugin } from '@prosekit/pm/state'\n\n/**\n * Defines an input rule extension.\n *\n * @param rule - The ProseMirror input rule to add.\n *\n * @public\n */\nexport function defineInputRule(rule: InputRule): PlainExtension {\n return defineInputRuleFacetPayload(() => rule)\n}\n\n/**\n * Options for {@link defineMarkInputRule}.\n *\n * @public\n */\nexport interface MarkInputRuleOptions {\n /**\n * The regular expression to match against, which should end with `$` and has\n * exactly one capture group. All other matched text outside the capture group\n * will be deleted.\n */\n regex: RegExp\n\n /**\n * The type of mark to set.\n */\n type: string | MarkType\n\n /**\n * Attributes to set on the mark.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * Whether this rule should fire inside marks marked as [code](https://prosemirror.net/docs/ref/#model.MarkSpec.code).\n *\n * @default `false`\n */\n inCodeMark?: boolean\n}\n\n/**\n * @internal\n */\nexport function createMarkInputRule({\n regex,\n type,\n attrs = null,\n inCodeMark = false,\n}: MarkInputRuleOptions): InputRule {\n const rule = new InputRule(regex, (state, match, start, end) => {\n const { tr, schema } = state\n const [fullText, markText] = match\n\n if (!markText) {\n return null\n }\n\n const markStart = start + fullText.indexOf(markText)\n const markEnd = markStart + markText.length\n\n if (!(start <= markStart && markStart < markEnd && markEnd <= end)) {\n // Incorrect regex.\n return null\n }\n\n const markType = getMarkType(schema, type)\n const mark = markType.create(maybeRun(attrs, match))\n\n if (!isMarkAbsent(tr.doc, markStart, markEnd, markType, attrs)) {\n // The mark is already active.\n return null\n }\n\n const initialStoredMarks = tr.storedMarks ?? []\n\n tr.addMark(markStart, markEnd, mark)\n\n if (markEnd < end) {\n tr.delete(markEnd, end)\n }\n if (start < markStart) {\n tr.delete(start, markStart)\n }\n\n // Make sure not to reactivate any marks which had previously been\n // deactivated. By keeping track of the initial stored marks we are able to\n // discard any unintended consequences of deleting text and adding it again.\n tr.setStoredMarks(initialStoredMarks)\n\n return tr\n }, { inCodeMark })\n\n return rule\n}\n\n/**\n * Defines an input rule for automatically adding inline marks when a given\n * pattern is typed.\n *\n * @public\n */\nexport function defineMarkInputRule(\n options: MarkInputRuleOptions,\n): PlainExtension {\n return defineInputRule(createMarkInputRule(options))\n}\n\n/**\n * Defines an input rule that changes the type of a textblock when the matched\n * text is typed into it.\n *\n * See also [textblockTypeInputRule](https://prosemirror.net/docs/ref/#inputrules.textblockTypeInputRule)\n *\n * @param options\n *\n * @public\n */\nexport function defineTextBlockInputRule({\n regex,\n type,\n attrs,\n}: {\n /**\n * The regular expression to match against, which should end with `$`. It\n * usually also starts with `^` to that it is only matched at the start of a\n * textblock.\n */\n regex: RegExp\n\n /**\n * The node type to replace the matched text with.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n}): PlainExtension {\n return defineInputRuleFacetPayload(({ schema }): InputRule => {\n const nodeType = getNodeType(schema, type)\n return textblockTypeInputRule(regex, nodeType, attrs)\n })\n}\n\n/**\n * Defines an input rule for automatically wrapping a textblock when a given\n * string is typed.\n *\n * See also [wrappingInputRule](https://prosemirror.net/docs/ref/#inputrules.wrappingInputRule)\n *\n * @param options\n *\n * @public\n */\nexport function defineWrappingInputRule({\n regex,\n type,\n attrs,\n join,\n}: {\n /**\n * The regular expression to match against, which should end with `$`. It\n * usually also starts with `^` to that it is only matched at the start of a\n * textblock.\n */\n regex: RegExp\n\n /**\n * The type of node to wrap in.\n */\n type: string | NodeType\n\n /**\n * Attributes to set on the node.\n */\n attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)\n\n /**\n * By default, if there's a node with the same type above the newly wrapped\n * node, the rule will try to\n * [join](https://prosemirror.net/docs/ref/#transform.Transform.join) those\n * two nodes. You can pass a join predicate, which takes a regular expression\n * match and the node before the wrapped node, and can return a boolean to\n * indicate whether a join should happen.\n */\n join?: (match: RegExpMatchArray, node: ProseMirrorNode) => boolean\n}): PlainExtension {\n return defineInputRuleFacetPayload(({ schema }): InputRule => {\n const nodeType = getNodeType(schema, type)\n return wrappingInputRule(regex, nodeType, attrs, join)\n })\n}\n\nfunction defineInputRuleFacetPayload(input: InputRulePayload): PlainExtension {\n return defineFacetPayload(inputRuleFacet, [input]) as PlainExtension\n}\n\ntype InputRulePayload = (context: { schema: Schema }) => InputRule\n\nconst inputRuleFacet = defineFacet<InputRulePayload, PluginPayload>({\n reducer: (inputs: InputRulePayload[]): PluginPayload => {\n return (context): Plugin[] => {\n const rules: InputRule[] = inputs.flatMap((callback) => callback(context))\n return [inputRules({ rules })]\n }\n },\n parent: pluginFacet,\n})\n"],"mappings":";;;;;;;;;;;AAiCA,SAAgB,gBAAgB,MAAiC;AAC/D,QAAO,kCAAkC,KAAK;;;;;AAqChD,SAAgB,oBAAoB,EAClC,OACA,MACA,QAAQ,MACR,aAAa,SACqB;AA4ClC,QA3Ca,IAAI,UAAU,QAAQ,OAAO,OAAO,OAAO,QAAQ;EAC9D,MAAM,EAAE,IAAI,WAAW;EACvB,MAAM,CAAC,UAAU,YAAY;AAE7B,MAAI,CAAC,SACH,QAAO;EAGT,MAAM,YAAY,QAAQ,SAAS,QAAQ,SAAS;EACpD,MAAM,UAAU,YAAY,SAAS;AAErC,MAAI,EAAE,SAAS,aAAa,YAAY,WAAW,WAAW,KAE5D,QAAO;EAGT,MAAM,WAAW,YAAY,QAAQ,KAAK;EAC1C,MAAM,OAAO,SAAS,OAAO,SAAS,OAAO,MAAM,CAAC;AAEpD,MAAI,CAAC,aAAa,GAAG,KAAK,WAAW,SAAS,UAAU,MAAM,CAE5D,QAAO;EAGT,MAAM,qBAAqB,GAAG,eAAe,EAAE;AAE/C,KAAG,QAAQ,WAAW,SAAS,KAAK;AAEpC,MAAI,UAAU,IACZ,IAAG,OAAO,SAAS,IAAI;AAEzB,MAAI,QAAQ,UACV,IAAG,OAAO,OAAO,UAAU;AAM7B,KAAG,eAAe,mBAAmB;AAErC,SAAO;IACN,EAAE,YAAY,CAAC;;;;;;;;AAWpB,SAAgB,oBACd,SACgB;AAChB,QAAO,gBAAgB,oBAAoB,QAAQ,CAAC;;;;;;;;;;;;AAatD,SAAgB,yBAAyB,EACvC,OACA,MACA,SAkBiB;AACjB,QAAO,6BAA6B,EAAE,aAAwB;AAE5D,SAAO,uBAAuB,OADb,YAAY,QAAQ,KAAK,EACK,MAAM;GACrD;;;;;;;;;;;;AAaJ,SAAgB,wBAAwB,EACtC,OACA,MACA,OACA,QA4BiB;AACjB,QAAO,6BAA6B,EAAE,aAAwB;AAE5D,SAAO,kBAAkB,OADR,YAAY,QAAQ,KAAK,EACA,OAAO,KAAK;GACtD;;AAGJ,SAAS,4BAA4B,OAAyC;AAC5E,QAAO,mBAAmB,gBAAgB,CAAC,MAAM,CAAC;;AAKpD,MAAM,iBAAiB,YAA6C;CAClE,UAAU,WAA8C;AACtD,UAAQ,YAAsB;AAE5B,UAAO,CAAC,WAAW,EAAE,OADM,OAAO,SAAS,aAAa,SAAS,QAAQ,CAAC,EAC9C,CAAC,CAAC;;;CAGlC,QAAQ;CACT,CAAC"}
@@ -157,4 +157,4 @@ const markRuleFacet = defineFacet({
157
157
 
158
158
  //#endregion
159
159
  export { defineMarkRule as t };
160
- //# sourceMappingURL=mark-rule-v2E7B4C0.js.map
160
+ //# sourceMappingURL=mark-rule-BcLB4Uv2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mark-rule-v2E7B4C0.js","names":["stack: Array<[start: number, node: ProseMirrorNode]>","ranges: Array<[number, number]>","start","ranges: MarkRange[]","result: MarkRange[]","mark","tr","toRemove: MarkRange[]","toCreate: MarkRange[]","rules: MarkRuleOptions[]"],"sources":["../src/mark-rule/range.ts","../src/mark-rule/apply.ts","../src/mark-rule/mark-rule.ts"],"sourcesContent":["import type {\n ProseMirrorNode,\n ResolvedPos,\n} from '@prosekit/pm/model'\nimport type {\n EditorState,\n Transaction,\n} from '@prosekit/pm/state'\nimport type { ProsemirrorNode } from 'prosemirror-flat-list'\n\nfunction getSpanTextRanges($from: ResolvedPos, $to: ResolvedPos) {\n const nodeRange = $from.blockRange($to)\n if (!nodeRange) {\n return []\n }\n\n const stack: Array<[start: number, node: ProseMirrorNode]> = []\n let start = nodeRange.start\n\n for (let i = nodeRange.startIndex; i < nodeRange.endIndex; i++) {\n const child = nodeRange.parent.child(i)\n stack.push([start, child])\n start += child.nodeSize\n }\n\n const ranges: Array<[number, number]> = []\n\n while (stack.length > 0) {\n const [start, node] = stack.pop()!\n if (node.type.spec.code) {\n continue\n }\n\n if (node.type.isTextblock) {\n ranges.push([start + 1, start + 1 + node.content.size])\n continue\n }\n\n node.forEach((child, offset) => {\n stack.push([start + offset + 1, child])\n })\n }\n\n return ranges\n}\n\nfunction getInlineTextRange(\n $from: ResolvedPos,\n $to: ResolvedPos,\n): [number, number] {\n return [$from.start(), $to.end()]\n}\n\nfunction getTextRanges(\n doc: ProsemirrorNode,\n from: number,\n to: number,\n): Array<[number, number]> {\n const $from = doc.resolve(from)\n const $to = doc.resolve(to)\n\n if ($from.sameParent($to) && $from.parent.isTextblock) {\n return [getInlineTextRange($from, $to)]\n } else {\n const nodeRange = $from.blockRange($to)\n if (!nodeRange) {\n return []\n }\n\n return getSpanTextRanges($from, $to)\n }\n}\n\nfunction getMapRange(\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n) {\n let lo = oldState.selection.from\n let hi = oldState.selection.to\n\n for (const tr of transactions) {\n for (const map of tr.mapping.maps) {\n lo = map.map(lo)\n hi = map.map(hi)\n\n map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {\n lo = Math.min(lo, hi, newStart)\n hi = Math.max(lo, hi, newEnd)\n })\n }\n }\n\n lo = Math.min(lo, hi, newState.selection.from)\n hi = Math.min(lo, hi, newState.selection.to)\n\n return [lo, hi] as const\n}\n\nexport function getCheckRanges(\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n): Array<[number, number]> {\n const [from, to] = getMapRange(transactions, oldState, newState)\n return getTextRanges(newState.doc, from, to)\n}\n","import {\n getMarkType,\n maybeRun,\n OBJECT_REPLACEMENT_CHARACTER,\n} from '@prosekit/core'\nimport type {\n Mark,\n ProseMirrorNode,\n} from '@prosekit/pm/model'\nimport type {\n EditorState,\n Transaction,\n} from '@prosekit/pm/state'\n\nimport { getCheckRanges } from './range'\nimport type { MarkRuleOptions } from './types'\n\ntype MarkRange = [from: number, to: number, mark: Mark]\n\nfunction getExpectedMarkings(\n rules: MarkRuleOptions[],\n doc: ProseMirrorNode,\n from: number,\n to: number,\n): MarkRange[] {\n const text = doc.textBetween(from, to, null, OBJECT_REPLACEMENT_CHARACTER)\n const ranges: MarkRange[] = []\n\n for (const rule of rules) {\n rule.regex.lastIndex = 0\n const matches = text.matchAll(rule.regex)\n const markType = getMarkType(doc.type.schema, rule.type)\n\n for (const match of matches) {\n const index = match.index\n if (index == null) continue\n const attrs = maybeRun(rule.attrs, match)\n const mark = markType.create(attrs)\n ranges.push([from + index, from + index + match[0].length, mark])\n }\n }\n\n // Sort by start position. If start positions are equal, the longer match\n // should be prioritized.\n ranges.sort((a, b) => a[0] - b[0] || b[1] - a[1])\n\n // Remove overlapped marks.\n const result: MarkRange[] = []\n let freeIndex = 0\n\n for (const range of ranges) {\n if (range[0] >= freeIndex) {\n result.push(range)\n freeIndex = range[1]\n }\n }\n\n return result\n}\n\nfunction getReceivedMarkings(\n rules: MarkRuleOptions[],\n doc: ProseMirrorNode,\n from: number,\n to: number,\n): MarkRange[] {\n const result: MarkRange[] = []\n const schema = doc.type.schema\n const markTypes = rules.map((rule) => getMarkType(schema, rule.type))\n\n doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isInline) {\n return\n }\n\n for (const markType of markTypes) {\n const mark = node.marks.find((mark) => mark.type === markType)\n if (mark) {\n result.push([pos, pos + node.nodeSize, mark])\n }\n }\n })\n return result\n}\n\nfunction markRangeEquals(a: MarkRange, b: MarkRange): boolean {\n return a[0] === b[0] && a[1] === b[1] && a[2].eq(b[2])\n}\n\nfunction markRangeDiffs(a: MarkRange[], b: MarkRange[]): MarkRange[] {\n return a.filter((x) => !b.some((y) => markRangeEquals(x, y)))\n}\n\nexport function applyMarkRules(\n rules: MarkRuleOptions[],\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n): Transaction | null {\n if (transactions.length === 0 || transactions.every((tr) => !tr.docChanged)) {\n return null\n }\n\n const ranges = getCheckRanges(transactions, oldState, newState)\n\n const toRemove: MarkRange[] = []\n const toCreate: MarkRange[] = []\n\n for (const [from, to] of ranges) {\n const expected = getExpectedMarkings(rules, newState.doc, from, to)\n const received = getReceivedMarkings(rules, newState.doc, from, to)\n\n toRemove.push(...markRangeDiffs(received, expected))\n toCreate.push(...markRangeDiffs(expected, received))\n }\n\n if (toCreate.length === 0 && toRemove.length === 0) {\n return null\n }\n\n const tr = newState.tr\n for (const [from, to, mark] of toRemove) {\n tr.removeMark(from, to, mark)\n }\n for (const [from, to, mark] of toCreate) {\n tr.addMark(from, to, mark)\n }\n return tr\n}\n","import {\n defineFacet,\n defineFacetPayload,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n type EditorState,\n type Transaction,\n} from '@prosekit/pm/state'\n\nimport { applyMarkRules } from './apply'\nimport type { MarkRuleOptions } from './types'\n\n/**\n * A mark rule is something that can automatically apply marks to text if it\n * matches a certain pattern, and remove them if it doesn't match anymore.\n */\nexport function defineMarkRule(options: MarkRuleOptions): PlainExtension {\n return defineFacetPayload(markRuleFacet, [options]) as PlainExtension\n}\n\nconst markRuleFacet = defineFacet<MarkRuleOptions, PluginPayload>({\n reduce: () => {\n let rules: MarkRuleOptions[] = []\n\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-mark-rule'),\n appendTransaction: (\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n ) => {\n return applyMarkRules(rules, transactions, oldState, newState)\n },\n })\n\n return function reducer(input) {\n rules = input\n return plugin\n }\n },\n\n parent: pluginFacet,\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"mark-rule-BcLB4Uv2.js","names":["stack: Array<[start: number, node: ProseMirrorNode]>","ranges: Array<[number, number]>","start","ranges: MarkRange[]","result: MarkRange[]","mark","tr","toRemove: MarkRange[]","toCreate: MarkRange[]","rules: MarkRuleOptions[]"],"sources":["../src/mark-rule/range.ts","../src/mark-rule/apply.ts","../src/mark-rule/mark-rule.ts"],"sourcesContent":["import type {\n ProseMirrorNode,\n ResolvedPos,\n} from '@prosekit/pm/model'\nimport type {\n EditorState,\n Transaction,\n} from '@prosekit/pm/state'\nimport type { ProsemirrorNode } from 'prosemirror-flat-list'\n\nfunction getSpanTextRanges($from: ResolvedPos, $to: ResolvedPos) {\n const nodeRange = $from.blockRange($to)\n if (!nodeRange) {\n return []\n }\n\n const stack: Array<[start: number, node: ProseMirrorNode]> = []\n let start = nodeRange.start\n\n for (let i = nodeRange.startIndex; i < nodeRange.endIndex; i++) {\n const child = nodeRange.parent.child(i)\n stack.push([start, child])\n start += child.nodeSize\n }\n\n const ranges: Array<[number, number]> = []\n\n while (stack.length > 0) {\n const [start, node] = stack.pop()!\n if (node.type.spec.code) {\n continue\n }\n\n if (node.type.isTextblock) {\n ranges.push([start + 1, start + 1 + node.content.size])\n continue\n }\n\n node.forEach((child, offset) => {\n stack.push([start + offset + 1, child])\n })\n }\n\n return ranges\n}\n\nfunction getInlineTextRange(\n $from: ResolvedPos,\n $to: ResolvedPos,\n): [number, number] {\n return [$from.start(), $to.end()]\n}\n\nfunction getTextRanges(\n doc: ProsemirrorNode,\n from: number,\n to: number,\n): Array<[number, number]> {\n const $from = doc.resolve(from)\n const $to = doc.resolve(to)\n\n if ($from.sameParent($to) && $from.parent.isTextblock) {\n return [getInlineTextRange($from, $to)]\n } else {\n const nodeRange = $from.blockRange($to)\n if (!nodeRange) {\n return []\n }\n\n return getSpanTextRanges($from, $to)\n }\n}\n\nfunction getMapRange(\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n) {\n let lo = oldState.selection.from\n let hi = oldState.selection.to\n\n for (const tr of transactions) {\n for (const map of tr.mapping.maps) {\n lo = map.map(lo)\n hi = map.map(hi)\n\n map.forEach((_oldStart, _oldEnd, newStart, newEnd) => {\n lo = Math.min(lo, hi, newStart)\n hi = Math.max(lo, hi, newEnd)\n })\n }\n }\n\n lo = Math.min(lo, hi, newState.selection.from)\n hi = Math.min(lo, hi, newState.selection.to)\n\n return [lo, hi] as const\n}\n\nexport function getCheckRanges(\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n): Array<[number, number]> {\n const [from, to] = getMapRange(transactions, oldState, newState)\n return getTextRanges(newState.doc, from, to)\n}\n","import {\n getMarkType,\n maybeRun,\n OBJECT_REPLACEMENT_CHARACTER,\n} from '@prosekit/core'\nimport type {\n Mark,\n ProseMirrorNode,\n} from '@prosekit/pm/model'\nimport type {\n EditorState,\n Transaction,\n} from '@prosekit/pm/state'\n\nimport { getCheckRanges } from './range'\nimport type { MarkRuleOptions } from './types'\n\ntype MarkRange = [from: number, to: number, mark: Mark]\n\nfunction getExpectedMarkings(\n rules: MarkRuleOptions[],\n doc: ProseMirrorNode,\n from: number,\n to: number,\n): MarkRange[] {\n const text = doc.textBetween(from, to, null, OBJECT_REPLACEMENT_CHARACTER)\n const ranges: MarkRange[] = []\n\n for (const rule of rules) {\n rule.regex.lastIndex = 0\n const matches = text.matchAll(rule.regex)\n const markType = getMarkType(doc.type.schema, rule.type)\n\n for (const match of matches) {\n const index = match.index\n if (index == null) continue\n const attrs = maybeRun(rule.attrs, match)\n const mark = markType.create(attrs)\n ranges.push([from + index, from + index + match[0].length, mark])\n }\n }\n\n // Sort by start position. If start positions are equal, the longer match\n // should be prioritized.\n ranges.sort((a, b) => a[0] - b[0] || b[1] - a[1])\n\n // Remove overlapped marks.\n const result: MarkRange[] = []\n let freeIndex = 0\n\n for (const range of ranges) {\n if (range[0] >= freeIndex) {\n result.push(range)\n freeIndex = range[1]\n }\n }\n\n return result\n}\n\nfunction getReceivedMarkings(\n rules: MarkRuleOptions[],\n doc: ProseMirrorNode,\n from: number,\n to: number,\n): MarkRange[] {\n const result: MarkRange[] = []\n const schema = doc.type.schema\n const markTypes = rules.map((rule) => getMarkType(schema, rule.type))\n\n doc.nodesBetween(from, to, (node, pos) => {\n if (!node.isInline) {\n return\n }\n\n for (const markType of markTypes) {\n const mark = node.marks.find((mark) => mark.type === markType)\n if (mark) {\n result.push([pos, pos + node.nodeSize, mark])\n }\n }\n })\n return result\n}\n\nfunction markRangeEquals(a: MarkRange, b: MarkRange): boolean {\n return a[0] === b[0] && a[1] === b[1] && a[2].eq(b[2])\n}\n\nfunction markRangeDiffs(a: MarkRange[], b: MarkRange[]): MarkRange[] {\n return a.filter((x) => !b.some((y) => markRangeEquals(x, y)))\n}\n\nexport function applyMarkRules(\n rules: MarkRuleOptions[],\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n): Transaction | null {\n if (transactions.length === 0 || transactions.every((tr) => !tr.docChanged)) {\n return null\n }\n\n const ranges = getCheckRanges(transactions, oldState, newState)\n\n const toRemove: MarkRange[] = []\n const toCreate: MarkRange[] = []\n\n for (const [from, to] of ranges) {\n const expected = getExpectedMarkings(rules, newState.doc, from, to)\n const received = getReceivedMarkings(rules, newState.doc, from, to)\n\n toRemove.push(...markRangeDiffs(received, expected))\n toCreate.push(...markRangeDiffs(expected, received))\n }\n\n if (toCreate.length === 0 && toRemove.length === 0) {\n return null\n }\n\n const tr = newState.tr\n for (const [from, to, mark] of toRemove) {\n tr.removeMark(from, to, mark)\n }\n for (const [from, to, mark] of toCreate) {\n tr.addMark(from, to, mark)\n }\n return tr\n}\n","import {\n defineFacet,\n defineFacetPayload,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n type EditorState,\n type Transaction,\n} from '@prosekit/pm/state'\n\nimport { applyMarkRules } from './apply'\nimport type { MarkRuleOptions } from './types'\n\n/**\n * A mark rule is something that can automatically apply marks to text if it\n * matches a certain pattern, and remove them if it doesn't match anymore.\n */\nexport function defineMarkRule(options: MarkRuleOptions): PlainExtension {\n return defineFacetPayload(markRuleFacet, [options]) as PlainExtension\n}\n\nconst markRuleFacet = defineFacet<MarkRuleOptions, PluginPayload>({\n reduce: () => {\n let rules: MarkRuleOptions[] = []\n\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-mark-rule'),\n appendTransaction: (\n transactions: readonly Transaction[],\n oldState: EditorState,\n newState: EditorState,\n ) => {\n return applyMarkRules(rules, transactions, oldState, newState)\n },\n })\n\n return function reducer(input) {\n rules = input\n return plugin\n }\n },\n\n parent: pluginFacet,\n})\n"],"mappings":"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"}
@@ -159,4 +159,4 @@ function replaceMarkInInlineNode(options, node) {
159
159
 
160
160
  //#endregion
161
161
  export { definePasteRule as n, defineMarkPasteRule as t };
162
- //# sourceMappingURL=paste-rule-qSz46pqD.js.map
162
+ //# sourceMappingURL=paste-rule-pVb4sqvJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paste-rule-qSz46pqD.js","names":["handlers: PasteRulePayload[]","chunks: Array<[string, RegExpExecArray | undefined]>","match: RegExpExecArray | null","children: ProseMirrorNode[]","newChildren: ProseMirrorNode[]","nodes: ProseMirrorNode[]","text"],"sources":["../src/paste-rule/paste-rule-plugin.ts","../src/paste-rule/paste-rule.ts","../src/paste-rule/split-text-by-regex.ts","../src/paste-rule/mark-paste-rule.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n} from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\ntype PasteRulePayload = (options: { slice: Slice; view: EditorView; plain: boolean }) => Slice\n\n/**\n * @internal\n */\nconst pasteRuleFacet = defineFacet<PasteRulePayload, PluginPayload>({\n reduce: () => {\n let handlers: PasteRulePayload[] = []\n\n const transformPasted = (slice: Slice, view: EditorView, plain: boolean): Slice => {\n for (const handler of handlers) {\n slice = handler({ slice, view, plain })\n }\n return slice\n }\n\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-paste-rule'),\n props: {\n transformPasted,\n },\n })\n\n return (inputs: PasteRulePayload[]) => {\n // Last added rule (highest priority) is applied first\n handlers = [...inputs].reverse()\n return plugin\n }\n },\n singleton: true,\n parent: pluginFacet,\n})\n\n/**\n * @internal\n */\nexport function definePasteRulePlugin(payload: PasteRulePayload): PlainExtension {\n return defineFacetPayload(pasteRuleFacet, [payload]) as PlainExtension\n}\n","import type { PlainExtension } from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { definePasteRulePlugin } from './paste-rule-plugin'\n\n/**\n * @public\n *\n * Options for {@link PasteRuleHandler}.\n */\nexport interface PasteRuleHandlerOptions {\n /**\n * The slice to be pasted.\n */\n slice: Slice\n\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * Whether the pasted content is treated as plain text. This is true when the\n * `Shift` key is held when pasting.\n */\n plain: boolean\n}\n\n/**\n * @public\n *\n * Can be used to transform pasted or dragged-and-dropped content before it is\n * applied to the document.\n */\nexport type PasteRuleHandler = (options: PasteRuleHandlerOptions) => Slice\n\n/**\n * Options for {@link definePasteRule}.\n *\n * @public\n */\nexport interface PasteRuleOptions {\n /**\n * A function to be called when a paste rule is triggered.\n */\n handler: PasteRuleHandler\n}\n\n/**\n * Defines a paste rule. This rule allows you to modify pasted or dragged\n * content before it is inserted into the document.\n *\n * @param options\n *\n * @public\n */\nexport function definePasteRule({ handler }: PasteRuleOptions): PlainExtension {\n return definePasteRulePlugin(handler)\n}\n","/**\n * Splits text into chunks based on regex matches, preserving both matched and unmatched segments.\n * Returns an array of tuples where each tuple contains a text segment and either the match data\n * (for matched segments) or undefined (for unmatched segments).\n */\nexport function splitTextByRegex(\n text: string,\n regex: RegExp,\n): Array<[string, RegExpExecArray | undefined]> | undefined {\n regex.lastIndex = 0\n\n const chunks: Array<[string, RegExpExecArray | undefined]> = []\n let lastIndex = 0\n let match: RegExpExecArray | null\n let matched = false\n\n while ((match = regex.exec(text))) {\n const start = match.index\n const end = regex.lastIndex\n\n // Push the unmatched prefix, if any.\n if (start > lastIndex) {\n chunks.push([text.slice(lastIndex, start), undefined])\n }\n\n // Push the matched segment.\n chunks.push([text.slice(start, end), match])\n matched = true\n\n if (lastIndex === end) {\n // Safeguard against zero-width matches that would otherwise cause an infinite loop.\n return\n }\n lastIndex = end\n }\n\n if (matched && lastIndex < text.length) {\n chunks.push([text.slice(lastIndex), undefined])\n }\n\n regex.lastIndex = 0\n\n return matched ? chunks : undefined\n}\n","import {\n getMarkType,\n type PlainExtension,\n} from '@prosekit/core'\nimport type {\n Attrs,\n MarkType,\n ProseMirrorNode,\n} from '@prosekit/pm/model'\nimport {\n Fragment,\n Slice,\n} from '@prosekit/pm/model'\n\nimport { definePasteRule } from './paste-rule'\nimport { splitTextByRegex } from './split-text-by-regex'\n\n/**\n * The options for {@link defineMarkPasteRule}.\n *\n * @public\n */\nexport interface MarkPasteRuleOptions {\n /**\n * The regular expression to match against. It must have a `g` flag to match\n * all instances of the mark.\n */\n regex: RegExp\n\n /**\n * The mark type to apply to the matched text.\n */\n type: string | MarkType\n\n /**\n * A function used to compute attributes to set on the mark created by this\n * rule. When it returns `false`, the rule won't match. When it returns `null`\n * or `undefined`, that is interpreted as an empty/default set of attributes.\n * @default null\n */\n getAttrs?: (match: RegExpExecArray) => Attrs | null | undefined | false\n\n /**\n * Optional function to determine if a text node should be skipped.\n * Default behavior: skip code nodes and nodes that already have the target mark.\n */\n shouldSkip?: (node: ProseMirrorNode) => boolean\n}\n\n/**\n * Defines a paste rule that applies marks based on regex patterns.\n *\n * @public\n */\nexport function defineMarkPasteRule(options: MarkPasteRuleOptions): PlainExtension {\n return definePasteRule({\n handler: ({ slice, view, plain }) => {\n if (plain) {\n return slice\n }\n\n const markType = getMarkType(view.state.schema, options.type)\n\n return replaceMarkInSlice({\n markType,\n regex: options.regex,\n getAttrs: options.getAttrs,\n shouldSkip: options.shouldSkip,\n }, slice)\n },\n })\n}\n\ninterface MarkPasteRuleHandlerOptions {\n markType: MarkType\n regex: RegExp\n getAttrs?: (match: RegExpExecArray) => Attrs | null | undefined | false\n shouldSkip?: (node: ProseMirrorNode) => boolean\n}\n\nfunction replaceMarkInSlice(options: MarkPasteRuleHandlerOptions, slice: Slice): Slice {\n const newFragment = replaceMarkInFragment(options, slice.content)\n if (!newFragment) {\n return slice\n }\n return new Slice(newFragment, slice.openStart, slice.openEnd)\n}\n\nfunction replaceMarkInFragment(options: MarkPasteRuleHandlerOptions, fragment: Fragment): Fragment | undefined {\n let changed = false\n let children: ProseMirrorNode[] = []\n\n for (const child of fragment.content) {\n const newChild = replaceMarkInNode(options, child)\n if (newChild) {\n changed = true\n }\n children.push(newChild || child)\n }\n\n if (changed) {\n return Fragment.from(children)\n }\n\n return\n}\n\nfunction replaceMarkInNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode | undefined {\n if (node.type.spec.code) {\n return\n }\n if (node.type.isInline) {\n return\n }\n if (node.type.isTextblock) {\n return replaceMarkInTextblockNode(options, node)\n }\n\n const newChildren = replaceMarkInFragment(options, node.content)\n if (!newChildren) {\n return\n }\n return node.copy(newChildren)\n}\n\nfunction replaceMarkInTextblockNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode | undefined {\n const newChildren: ProseMirrorNode[] = []\n let changed = false\n\n for (const inlineNode of node.content.content) {\n const newInlineNodes = replaceMarkInInlineNode(options, inlineNode)\n if (newInlineNodes) {\n changed = true\n newChildren.push(...newInlineNodes)\n } else {\n newChildren.push(inlineNode)\n }\n }\n if (changed) {\n return node.copy(Fragment.from(newChildren))\n }\n return\n}\n\nfunction replaceMarkInInlineNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode[] | undefined {\n const text = node.text\n if (!text) {\n return\n }\n\n const { markType, shouldSkip } = options\n\n // Use custom skip logic if provided, otherwise use default\n if (shouldSkip) {\n if (shouldSkip(node)) {\n return\n }\n } else {\n // Default skip logic: skip if already has the target mark or has code mark\n if (node.marks.some((mark) => mark.type === markType)) {\n return\n }\n if (node.marks.some((mark) => mark.type.spec.code)) {\n return\n }\n }\n\n const chunks = splitTextByRegex(text, options.regex)\n if (!chunks) {\n return\n }\n\n const schema = node.type.schema\n const nodes: ProseMirrorNode[] = []\n\n for (const [text, match] of chunks) {\n if (!text) {\n continue\n }\n if (match) {\n const attrs = options.getAttrs?.(match) ?? null\n if (attrs !== false) {\n const mark = markType.create(attrs)\n nodes.push(schema.text(text, [...node.marks, mark]))\n } else {\n nodes.push(schema.text(text, node.marks))\n }\n } else {\n nodes.push(schema.text(text, node.marks))\n }\n }\n\n return nodes\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"paste-rule-pVb4sqvJ.js","names":["handlers: PasteRulePayload[]","chunks: Array<[string, RegExpExecArray | undefined]>","match: RegExpExecArray | null","children: ProseMirrorNode[]","newChildren: ProseMirrorNode[]","nodes: ProseMirrorNode[]","text"],"sources":["../src/paste-rule/paste-rule-plugin.ts","../src/paste-rule/paste-rule.ts","../src/paste-rule/split-text-by-regex.ts","../src/paste-rule/mark-paste-rule.ts"],"sourcesContent":["import {\n defineFacet,\n defineFacetPayload,\n pluginFacet,\n type PlainExtension,\n type PluginPayload,\n} from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport {\n PluginKey,\n ProseMirrorPlugin,\n} from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\n\ntype PasteRulePayload = (options: { slice: Slice; view: EditorView; plain: boolean }) => Slice\n\n/**\n * @internal\n */\nconst pasteRuleFacet = defineFacet<PasteRulePayload, PluginPayload>({\n reduce: () => {\n let handlers: PasteRulePayload[] = []\n\n const transformPasted = (slice: Slice, view: EditorView, plain: boolean): Slice => {\n for (const handler of handlers) {\n slice = handler({ slice, view, plain })\n }\n return slice\n }\n\n const plugin = new ProseMirrorPlugin({\n key: new PluginKey('prosekit-paste-rule'),\n props: {\n transformPasted,\n },\n })\n\n return (inputs: PasteRulePayload[]) => {\n // Last added rule (highest priority) is applied first\n handlers = [...inputs].reverse()\n return plugin\n }\n },\n singleton: true,\n parent: pluginFacet,\n})\n\n/**\n * @internal\n */\nexport function definePasteRulePlugin(payload: PasteRulePayload): PlainExtension {\n return defineFacetPayload(pasteRuleFacet, [payload]) as PlainExtension\n}\n","import type { PlainExtension } from '@prosekit/core'\nimport type { Slice } from '@prosekit/pm/model'\nimport type { EditorView } from '@prosekit/pm/view'\n\nimport { definePasteRulePlugin } from './paste-rule-plugin'\n\n/**\n * @public\n *\n * Options for {@link PasteRuleHandler}.\n */\nexport interface PasteRuleHandlerOptions {\n /**\n * The slice to be pasted.\n */\n slice: Slice\n\n /**\n * The editor view.\n */\n view: EditorView\n\n /**\n * Whether the pasted content is treated as plain text. This is true when the\n * `Shift` key is held when pasting.\n */\n plain: boolean\n}\n\n/**\n * @public\n *\n * Can be used to transform pasted or dragged-and-dropped content before it is\n * applied to the document.\n */\nexport type PasteRuleHandler = (options: PasteRuleHandlerOptions) => Slice\n\n/**\n * Options for {@link definePasteRule}.\n *\n * @public\n */\nexport interface PasteRuleOptions {\n /**\n * A function to be called when a paste rule is triggered.\n */\n handler: PasteRuleHandler\n}\n\n/**\n * Defines a paste rule. This rule allows you to modify pasted or dragged\n * content before it is inserted into the document.\n *\n * @param options\n *\n * @public\n */\nexport function definePasteRule({ handler }: PasteRuleOptions): PlainExtension {\n return definePasteRulePlugin(handler)\n}\n","/**\n * Splits text into chunks based on regex matches, preserving both matched and unmatched segments.\n * Returns an array of tuples where each tuple contains a text segment and either the match data\n * (for matched segments) or undefined (for unmatched segments).\n */\nexport function splitTextByRegex(\n text: string,\n regex: RegExp,\n): Array<[string, RegExpExecArray | undefined]> | undefined {\n regex.lastIndex = 0\n\n const chunks: Array<[string, RegExpExecArray | undefined]> = []\n let lastIndex = 0\n let match: RegExpExecArray | null\n let matched = false\n\n while ((match = regex.exec(text))) {\n const start = match.index\n const end = regex.lastIndex\n\n // Push the unmatched prefix, if any.\n if (start > lastIndex) {\n chunks.push([text.slice(lastIndex, start), undefined])\n }\n\n // Push the matched segment.\n chunks.push([text.slice(start, end), match])\n matched = true\n\n if (lastIndex === end) {\n // Safeguard against zero-width matches that would otherwise cause an infinite loop.\n return\n }\n lastIndex = end\n }\n\n if (matched && lastIndex < text.length) {\n chunks.push([text.slice(lastIndex), undefined])\n }\n\n regex.lastIndex = 0\n\n return matched ? chunks : undefined\n}\n","import {\n getMarkType,\n type PlainExtension,\n} from '@prosekit/core'\nimport type {\n Attrs,\n MarkType,\n ProseMirrorNode,\n} from '@prosekit/pm/model'\nimport {\n Fragment,\n Slice,\n} from '@prosekit/pm/model'\n\nimport { definePasteRule } from './paste-rule'\nimport { splitTextByRegex } from './split-text-by-regex'\n\n/**\n * The options for {@link defineMarkPasteRule}.\n *\n * @public\n */\nexport interface MarkPasteRuleOptions {\n /**\n * The regular expression to match against. It must have a `g` flag to match\n * all instances of the mark.\n */\n regex: RegExp\n\n /**\n * The mark type to apply to the matched text.\n */\n type: string | MarkType\n\n /**\n * A function used to compute attributes to set on the mark created by this\n * rule. When it returns `false`, the rule won't match. When it returns `null`\n * or `undefined`, that is interpreted as an empty/default set of attributes.\n * @default null\n */\n getAttrs?: (match: RegExpExecArray) => Attrs | null | undefined | false\n\n /**\n * Optional function to determine if a text node should be skipped.\n * Default behavior: skip code nodes and nodes that already have the target mark.\n */\n shouldSkip?: (node: ProseMirrorNode) => boolean\n}\n\n/**\n * Defines a paste rule that applies marks based on regex patterns.\n *\n * @public\n */\nexport function defineMarkPasteRule(options: MarkPasteRuleOptions): PlainExtension {\n return definePasteRule({\n handler: ({ slice, view, plain }) => {\n if (plain) {\n return slice\n }\n\n const markType = getMarkType(view.state.schema, options.type)\n\n return replaceMarkInSlice({\n markType,\n regex: options.regex,\n getAttrs: options.getAttrs,\n shouldSkip: options.shouldSkip,\n }, slice)\n },\n })\n}\n\ninterface MarkPasteRuleHandlerOptions {\n markType: MarkType\n regex: RegExp\n getAttrs?: (match: RegExpExecArray) => Attrs | null | undefined | false\n shouldSkip?: (node: ProseMirrorNode) => boolean\n}\n\nfunction replaceMarkInSlice(options: MarkPasteRuleHandlerOptions, slice: Slice): Slice {\n const newFragment = replaceMarkInFragment(options, slice.content)\n if (!newFragment) {\n return slice\n }\n return new Slice(newFragment, slice.openStart, slice.openEnd)\n}\n\nfunction replaceMarkInFragment(options: MarkPasteRuleHandlerOptions, fragment: Fragment): Fragment | undefined {\n let changed = false\n let children: ProseMirrorNode[] = []\n\n for (const child of fragment.content) {\n const newChild = replaceMarkInNode(options, child)\n if (newChild) {\n changed = true\n }\n children.push(newChild || child)\n }\n\n if (changed) {\n return Fragment.from(children)\n }\n\n return\n}\n\nfunction replaceMarkInNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode | undefined {\n if (node.type.spec.code) {\n return\n }\n if (node.type.isInline) {\n return\n }\n if (node.type.isTextblock) {\n return replaceMarkInTextblockNode(options, node)\n }\n\n const newChildren = replaceMarkInFragment(options, node.content)\n if (!newChildren) {\n return\n }\n return node.copy(newChildren)\n}\n\nfunction replaceMarkInTextblockNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode | undefined {\n const newChildren: ProseMirrorNode[] = []\n let changed = false\n\n for (const inlineNode of node.content.content) {\n const newInlineNodes = replaceMarkInInlineNode(options, inlineNode)\n if (newInlineNodes) {\n changed = true\n newChildren.push(...newInlineNodes)\n } else {\n newChildren.push(inlineNode)\n }\n }\n if (changed) {\n return node.copy(Fragment.from(newChildren))\n }\n return\n}\n\nfunction replaceMarkInInlineNode(options: MarkPasteRuleHandlerOptions, node: ProseMirrorNode): ProseMirrorNode[] | undefined {\n const text = node.text\n if (!text) {\n return\n }\n\n const { markType, shouldSkip } = options\n\n // Use custom skip logic if provided, otherwise use default\n if (shouldSkip) {\n if (shouldSkip(node)) {\n return\n }\n } else {\n // Default skip logic: skip if already has the target mark or has code mark\n if (node.marks.some((mark) => mark.type === markType)) {\n return\n }\n if (node.marks.some((mark) => mark.type.spec.code)) {\n return\n }\n }\n\n const chunks = splitTextByRegex(text, options.regex)\n if (!chunks) {\n return\n }\n\n const schema = node.type.schema\n const nodes: ProseMirrorNode[] = []\n\n for (const [text, match] of chunks) {\n if (!text) {\n continue\n }\n if (match) {\n const attrs = options.getAttrs?.(match) ?? null\n if (attrs !== false) {\n const mark = markType.create(attrs)\n nodes.push(schema.text(text, [...node.marks, mark]))\n } else {\n nodes.push(schema.text(text, node.marks))\n }\n } else {\n nodes.push(schema.text(text, node.marks))\n }\n }\n\n return nodes\n}\n"],"mappings":";;;;;;;;AAmBA,MAAM,iBAAiB,YAA6C;CAClE,cAAc;EACZ,IAAIA,WAA+B,EAAE;EAErC,MAAM,mBAAmB,OAAc,MAAkB,UAA0B;AACjF,QAAK,MAAM,WAAW,SACpB,SAAQ,QAAQ;IAAE;IAAO;IAAM;IAAO,CAAC;AAEzC,UAAO;;EAGT,MAAM,SAAS,IAAI,kBAAkB;GACnC,KAAK,IAAI,UAAU,sBAAsB;GACzC,OAAO,EACL,iBACD;GACF,CAAC;AAEF,UAAQ,WAA+B;AAErC,cAAW,CAAC,GAAG,OAAO,CAAC,SAAS;AAChC,UAAO;;;CAGX,WAAW;CACX,QAAQ;CACT,CAAC;;;;AAKF,SAAgB,sBAAsB,SAA2C;AAC/E,QAAO,mBAAmB,gBAAgB,CAAC,QAAQ,CAAC;;;;;;;;;;;;;ACMtD,SAAgB,gBAAgB,EAAE,WAA6C;AAC7E,QAAO,sBAAsB,QAAQ;;;;;;;;;;ACrDvC,SAAgB,iBACd,MACA,OAC0D;AAC1D,OAAM,YAAY;CAElB,MAAMC,SAAuD,EAAE;CAC/D,IAAI,YAAY;CAChB,IAAIC;CACJ,IAAI,UAAU;AAEd,QAAQ,QAAQ,MAAM,KAAK,KAAK,EAAG;EACjC,MAAM,QAAQ,MAAM;EACpB,MAAM,MAAM,MAAM;AAGlB,MAAI,QAAQ,UACV,QAAO,KAAK,CAAC,KAAK,MAAM,WAAW,MAAM,EAAE,OAAU,CAAC;AAIxD,SAAO,KAAK,CAAC,KAAK,MAAM,OAAO,IAAI,EAAE,MAAM,CAAC;AAC5C,YAAU;AAEV,MAAI,cAAc,IAEhB;AAEF,cAAY;;AAGd,KAAI,WAAW,YAAY,KAAK,OAC9B,QAAO,KAAK,CAAC,KAAK,MAAM,UAAU,EAAE,OAAU,CAAC;AAGjD,OAAM,YAAY;AAElB,QAAO,UAAU,SAAS;;;;;;;;;;ACY5B,SAAgB,oBAAoB,SAA+C;AACjF,QAAO,gBAAgB,EACrB,UAAU,EAAE,OAAO,MAAM,YAAY;AACnC,MAAI,MACF,QAAO;AAKT,SAAO,mBAAmB;GACxB,UAHe,YAAY,KAAK,MAAM,QAAQ,QAAQ,KAAK;GAI3D,OAAO,QAAQ;GACf,UAAU,QAAQ;GAClB,YAAY,QAAQ;GACrB,EAAE,MAAM;IAEZ,CAAC;;AAUJ,SAAS,mBAAmB,SAAsC,OAAqB;CACrF,MAAM,cAAc,sBAAsB,SAAS,MAAM,QAAQ;AACjE,KAAI,CAAC,YACH,QAAO;AAET,QAAO,IAAI,MAAM,aAAa,MAAM,WAAW,MAAM,QAAQ;;AAG/D,SAAS,sBAAsB,SAAsC,UAA0C;CAC7G,IAAI,UAAU;CACd,IAAIC,WAA8B,EAAE;AAEpC,MAAK,MAAM,SAAS,SAAS,SAAS;EACpC,MAAM,WAAW,kBAAkB,SAAS,MAAM;AAClD,MAAI,SACF,WAAU;AAEZ,WAAS,KAAK,YAAY,MAAM;;AAGlC,KAAI,QACF,QAAO,SAAS,KAAK,SAAS;;AAMlC,SAAS,kBAAkB,SAAsC,MAAoD;AACnH,KAAI,KAAK,KAAK,KAAK,KACjB;AAEF,KAAI,KAAK,KAAK,SACZ;AAEF,KAAI,KAAK,KAAK,YACZ,QAAO,2BAA2B,SAAS,KAAK;CAGlD,MAAM,cAAc,sBAAsB,SAAS,KAAK,QAAQ;AAChE,KAAI,CAAC,YACH;AAEF,QAAO,KAAK,KAAK,YAAY;;AAG/B,SAAS,2BAA2B,SAAsC,MAAoD;CAC5H,MAAMC,cAAiC,EAAE;CACzC,IAAI,UAAU;AAEd,MAAK,MAAM,cAAc,KAAK,QAAQ,SAAS;EAC7C,MAAM,iBAAiB,wBAAwB,SAAS,WAAW;AACnE,MAAI,gBAAgB;AAClB,aAAU;AACV,eAAY,KAAK,GAAG,eAAe;QAEnC,aAAY,KAAK,WAAW;;AAGhC,KAAI,QACF,QAAO,KAAK,KAAK,SAAS,KAAK,YAAY,CAAC;;AAKhD,SAAS,wBAAwB,SAAsC,MAAsD;CAC3H,MAAM,OAAO,KAAK;AAClB,KAAI,CAAC,KACH;CAGF,MAAM,EAAE,UAAU,eAAe;AAGjC,KAAI,YACF;MAAI,WAAW,KAAK,CAClB;QAEG;AAEL,MAAI,KAAK,MAAM,MAAM,SAAS,KAAK,SAAS,SAAS,CACnD;AAEF,MAAI,KAAK,MAAM,MAAM,SAAS,KAAK,KAAK,KAAK,KAAK,CAChD;;CAIJ,MAAM,SAAS,iBAAiB,MAAM,QAAQ,MAAM;AACpD,KAAI,CAAC,OACH;CAGF,MAAM,SAAS,KAAK,KAAK;CACzB,MAAMC,QAA2B,EAAE;AAEnC,MAAK,MAAM,CAACC,QAAM,UAAU,QAAQ;AAClC,MAAI,CAACA,OACH;AAEF,MAAI,OAAO;GACT,MAAM,QAAQ,QAAQ,WAAW,MAAM,IAAI;AAC3C,OAAI,UAAU,OAAO;IACnB,MAAM,OAAO,SAAS,OAAO,MAAM;AACnC,UAAM,KAAK,OAAO,KAAKA,QAAM,CAAC,GAAG,KAAK,OAAO,KAAK,CAAC,CAAC;SAEpD,OAAM,KAAK,OAAO,KAAKA,QAAM,KAAK,MAAM,CAAC;QAG3C,OAAM,KAAK,OAAO,KAAKA,QAAM,KAAK,MAAM,CAAC;;AAI7C,QAAO"}
@@ -1,4 +1,4 @@
1
- import { a as defineWrappingInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { a as defineWrappingInputRule } from "./input-rule-dmsb3j6w.js";
2
2
  import { defineCommands, defineKeymap, defineNodeSpec, insertNode, isAtBlockStart, toggleWrap, union, wrap } from "@prosekit/core";
3
3
  import { joinBackward } from "@prosekit/pm/commands";
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-bold.d.ts","names":[],"sources":["../src/bold/bold-commands.ts","../src/bold/bold-spec.ts","../src/bold/bold.ts","../src/bold/bold-input-rule.ts","../src/bold/bold-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,aDNqB;;;;;;ADTvC,iBGCI,mBAAA,CAAA,CHDoB,EGCG,cHDM;;;;;;AAAjC,iBIAI,gBAAA,CAAA,CJAoB,EIAA,cJAS"}
1
+ {"version":3,"file":"prosekit-extensions-bold.d.ts","names":[],"sources":["../src/bold/bold-commands.ts","../src/bold/bold-spec.ts","../src/bold/bold.ts","../src/bold/bold-input-rule.ts","../src/bold/bold-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 { r as defineMarkInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { r as defineMarkInputRule } from "./input-rule-dmsb3j6w.js";
2
2
  import { canUseRegexLookbehind, defineCommands, defineKeymap, defineMarkSpec, toggleMark, union } from "@prosekit/core";
3
3
 
4
4
  //#region src/bold/bold-commands.ts
@@ -1,4 +1,4 @@
1
- import { r as ShikiHighlighterOptions } from "./shiki-highlighter-chunk-DcY3Ud8v.js";
1
+ import { r as ShikiHighlighterOptions } from "./shiki-highlighter-chunk-rkzofy4z.js";
2
2
  import { Extension, PlainExtension, Union } from "@prosekit/core";
3
3
  import { Parser } from "prosemirror-highlight";
4
4
  import { BundledLanguage as ShikiBundledLanguage, BundledLanguageInfo as ShikiBundledLanguageInfo, BundledTheme as ShikiBundledTheme, BundledThemeInfo as ShikiBundledThemeInfo, SpecialLanguage, bundledLanguagesInfo as shikiBundledLanguagesInfo, bundledThemesInfo as shikiBundledThemesInfo } from "shiki";
@@ -1,5 +1,5 @@
1
- import { i as defineTextBlockInputRule } from "./input-rule-COGr_GBb.js";
2
- import { n as defineTextBlockEnterRule } from "./enter-rule-D-p4ykfv.js";
1
+ import { i as defineTextBlockInputRule } from "./input-rule-dmsb3j6w.js";
2
+ import { n as defineTextBlockEnterRule } from "./enter-rule-CzWOZF_Z.js";
3
3
  import { defaultBlockAt, defineCommands, defineKeymap, defineNodeSpec, definePlugin, insertNode, setBlockType, setNodeAttrs, toggleNode, union } from "@prosekit/core";
4
4
  import { TextSelection } from "@prosekit/pm/state";
5
5
  import { createHighlightPlugin } from "prosemirror-highlight";
@@ -235,7 +235,7 @@ function createLazyParser(highlighterOptions) {
235
235
  *
236
236
  * @public
237
237
  */
238
- function defineCodeBlockShiki({ themes = ["one-dark-pro"], langs = ["text"],...rest } = {}) {
238
+ function defineCodeBlockShiki({ themes = ["one-dark-pro"], langs = ["text"], ...rest } = {}) {
239
239
  return defineCodeBlockHighlight({ parser: createLazyParser({
240
240
  themes,
241
241
  langs,
@@ -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":";;;;;;;;;;;;;;AA4BA,SAAgB,0BAAsD;AACpE,QAAO,eAAe;EACpB,eAAe,UAA2B;AACxC,UAAO,aAAa;IAAE,MAAM;IAAa;IAAO,CAAC;;EAEnD,kBAAkB,UAA2B;AAC3C,UAAO,WAAW;IAAE,MAAM;IAAa;IAAO,CAAC;;EAEjD,kBAAkB,UAA2B;AAC3C,UAAO,WAAW;IAAE,MAAM;IAAa;IAAO,CAAC;;EAEjD,oBAAoB,UAA0B;AAC5C,UAAO,aAAa;IAAE,MAAM;IAAa;IAAO,CAAC;;EAEpD,CAAC;;;;;;;;;;AC9BJ,SAAgB,2BAA2C;AACzD,QAAO,yBAAyB;EAC9B,OAAO;EACP,MAAM;EACN,OAAO;EACR,CAAC;;;;;;;AAQJ,SAAgB,2BAA2C;AACzD,QAAO,yBAAyB;EAC9B,OAAO;EACP,MAAM;EACN,OAAO;EACR,CAAC;;AAGJ,SAAS,SAAS,OAAyC;AACzD,QAAO,EAAE,UAAU,MAAM,MAAM,IAAI;;;;;;;;ACrBrC,SAAgB,wBAAwC;AACtD,QAAO,aAAa,EAClB,OAAO,gBACR,CAAC;;;;;;AAOJ,MAAMA,kBAA2B,OAAO,aAAa;AACnD,KAAI,CAAC,MAAM,UAAU,MACnB,QAAO;CAGT,MAAM,EAAE,UAAU,MAAM;CACxB,MAAM,SAAS,MAAM;AACrB,KACE,OAAO,eACJ,OAAO,KAAK,KAAK,QACjB,MAAM,iBAAiB,OAAO,QAAQ,QACtC,OAAO,YAAY,SAAS,OAAO,EACtC;EACA,MAAM,cAAc,MAAM,KAAK,GAAG;EAClC,MAAM,cAAc,MAAM,WAAW,GAAG;EACxC,MAAM,OAAO,eAAe,YAAY,eAAe,YAAY,CAAC;AAEpE,MAAI,CAAC,QAAQ,CAAC,YAAY,eAAe,aAAa,aAAa,KAAK,CACtE,QAAO;AAGT,MAAI,UAAU;GACZ,MAAM,EAAE,OAAO;AACf,MAAG,OAAO,MAAM,MAAM,GAAG,MAAM,IAAI;GACnC,MAAM,MAAM,GAAG,UAAU,MAAM,OAAO;GACtC,MAAM,OAAO,KAAK,eAAe;AACjC,OAAI,MAAM;AACR,OAAG,YAAY,KAAK,KAAK,KAAK;AAC9B,OAAG,aAAa,cAAc,KAAK,GAAG,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;AAC3D,aAAS,GAAG,gBAAgB,CAAC;;;AAIjC,SAAO;;AAGT,QAAO;;;;;;;;;;ACtCT,SAAgB,sBAA8C;AAC5D,QAAO,eAAe;EACpB,MAAM;EACN,SAAS;EACT,OAAO;EACP,MAAM;EACN,UAAU;EACV,OAAO;EACP,OAAO,EAAE,UAAU;GAAE,SAAS;GAAI,UAAU;GAAU,EAAE;EACxD,UAAU,CACR;GACE,KAAK;GACL,oBAAoB;GACpB,WAAW,SAAyB;AAGlC,WAAO,EAAE,UAFQ,2BAA2B,KAAK,IAC5C,2BAA2B,KAAK,cAAc,OAAO,CAAC,EACxC;;GAEtB,CACF;EACD,MAAM,MAAM;GACV,MAAM,EAAE,aAAa,KAAK;AAC1B,UAAO;IACL;IACA,EAAE,iBAAiB,YAAY,QAAW;IAE1C;KAAC;KAAQ,EAAE,OAAO,WAAW,YAAY,aAAa,QAAW;KAAE;KAAE;IACtE;;EAEJ,CAAC;;AAGJ,SAAS,2BAA2B,SAAiD;AACnF,KAAI,CAAC,QACH,QAAO;CAGT,MAAM,OAAO,QAAQ,aAAa,gBAAgB;AAClD,KAAI,KACF,QAAO;CAIT,MAAM,QADY,QAAQ,UACF,MAAM,iBAAiB;AAC/C,KAAI,MACF,QAAO,MAAM;AAGf,QAAO;;;;;;;;;;;;;;;;AChCT,SAAgB,kBAAsC;AACpD,QAAO,MACL,qBAAqB,EACrB,0BAA0B,EAC1B,0BAA0B,EAC1B,uBAAuB,EACvB,yBAAyB,CAC1B;;;;;;;;;;;;;;;ACXH,SAAgB,yBAAyB,EACvC,UACuC;AACvC,QAAO,aACL,sBAAsB,EAAE,QAAQ,CAAC,CAClC;;;;;ACjCH,IAAIC;AAEJ,eAAe,OAAO;CACpB,MAAM,EAAE,qDAA2B,MAAM,OAAO;AAChD,UAASC;;AAGX,SAAgB,uBACd,SACmB;AACnB,KAAI,CAAC,OACH,QAAO,EAAE,SAAS,MAAM,EAAE;AAE5B,QAAO,OAAO,QAAQ;;;;;;;;ACNxB,SAAgB,iBACd,oBACQ;CACR,IAAIC;AAEJ,QAAO,SAAS,WAAW,SAAS;EAClC,MAAM,WAAY,QAAQ,YAAY;EACtC,MAAM,EAAE,aAAa,YAAY,uBAAuB;GACtD,GAAG;GACH,OAAO,CAAC,SAAS;GAClB,CAAC;AAEF,MAAI,CAAC,YACH,QAAO;AAGT,MAAI,CAAC,OACH,UAAS,aAAa,aAAa,EACjC,OAAO,mBAAmB,OAAO,IAClC,CAAC;AAEJ,SAAO,OAAO,QAAQ;;;;;;;;;;;;;;;;;;ACiB1B,SAAgB,qBAAqB,EACnC,SAAS,CAAC,eAAe,EACzB,QAAQ,CAAC,OAAO,EAChB,GAAG,SACsB,EAAE,EAAa;AAExC,QAAO,yBAAyB,EAAE,QADnB,iBAAiB;EAAE;EAAQ;EAAO,GAAG;EAAM,CAAC,EACjB,CAAC"}
@@ -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;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
+ {"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,aDNqB;;;;;;ADTvC,iBGCI,mBAAA,CAAA,CHDoB,EGCG,cHDM;;;;;;AAAjC,iBIAI,gBAAA,CAAA,CJAoB,EIAA,cJAS"}
@@ -1,4 +1,4 @@
1
- import { r as defineMarkInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { r as defineMarkInputRule } from "./input-rule-dmsb3j6w.js";
2
2
  import { canUseRegexLookbehind, defineCommands, defineKeymap, defineMarkSpec, toggleMark, union } from "@prosekit/core";
3
3
 
4
4
  //#region src/code/code-commands.ts
@@ -1,3 +1,3 @@
1
- import { t as defineDropIndicator } from "./drop-indicator-BMvWUDXz.js";
1
+ import { t as defineDropIndicator } from "./drop-indicator-B1QHFb5m.js";
2
2
 
3
3
  export { defineDropIndicator };
@@ -1,3 +1,3 @@
1
- import { n as defineTextBlockEnterRule, t as defineEnterRule } from "./enter-rule-D-p4ykfv.js";
1
+ import { n as defineTextBlockEnterRule, t as defineEnterRule } from "./enter-rule-CzWOZF_Z.js";
2
2
 
3
3
  export { defineEnterRule, defineTextBlockEnterRule };
@@ -1,2 +1,2 @@
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";
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-oIc1a2f2.js";
2
2
  export { FileDropHandler, FileDropHandlerOptions, FilePasteHandler, FilePasteHandlerOptions, UploadProgress, UploadTask, Uploader, UploaderOptions, defineFileDropHandler, defineFilePasteHandler };
@@ -1,3 +1,3 @@
1
- import { n as defineFilePasteHandler, r as defineFileDropHandler, t as UploadTask } from "./file-DKoIIa7q.js";
1
+ import { n as defineFilePasteHandler, r as defineFileDropHandler, t as UploadTask } from "./file-DrfcSid-.js";
2
2
 
3
3
  export { UploadTask, defineFileDropHandler, defineFilePasteHandler };
@@ -1,4 +1,4 @@
1
- import { i as defineTextBlockInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { i as defineTextBlockInputRule } from "./input-rule-dmsb3j6w.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,4 +1,4 @@
1
- import { n as defineInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { n as defineInputRule } from "./input-rule-dmsb3j6w.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,4 +1,4 @@
1
- import { l as FileDropHandlerOptions, n as UploadTask, o as FilePasteHandlerOptions, r as Uploader } from "./index-DdjnBeho.js";
1
+ import { l as FileDropHandlerOptions, n as UploadTask, o as FilePasteHandlerOptions, r as Uploader } from "./index-oIc1a2f2.js";
2
2
  import { Extension, PlainExtension, Union } from "@prosekit/core";
3
3
  import { Command } from "@prosekit/pm/state";
4
4
  import { EditorView } from "@prosekit/pm/view";
@@ -1,4 +1,4 @@
1
- import { n as defineFilePasteHandler, r as defineFileDropHandler, t as UploadTask } from "./file-DKoIIa7q.js";
1
+ import { n as defineFilePasteHandler, r as defineFileDropHandler, t as UploadTask } from "./file-DrfcSid-.js";
2
2
  import { ProseKitError, defineCommands, defineNodeSpec, insertNode, union } from "@prosekit/core";
3
3
 
4
4
  //#region src/image/image-commands/insert-image.ts
@@ -1,3 +1,3 @@
1
- import { a as defineWrappingInputRule, i as defineTextBlockInputRule, n as defineInputRule, r as defineMarkInputRule, t as createMarkInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { a as defineWrappingInputRule, i as defineTextBlockInputRule, n as defineInputRule, r as defineMarkInputRule, t as createMarkInputRule } from "./input-rule-dmsb3j6w.js";
2
2
 
3
3
  export { createMarkInputRule, defineInputRule, defineMarkInputRule, defineTextBlockInputRule, defineWrappingInputRule };
@@ -1,4 +1,4 @@
1
- import { r as defineMarkInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { r as defineMarkInputRule } from "./input-rule-dmsb3j6w.js";
2
2
  import { canUseRegexLookbehind, defineCommands, defineKeymap, defineMarkSpec, toggleMark, union } from "@prosekit/core";
3
3
 
4
4
  //#region src/italic/italic-commands.ts
@@ -1,7 +1,7 @@
1
- import { n as defineInputRule } from "./input-rule-COGr_GBb.js";
2
- import { t as defineEnterRule } from "./enter-rule-D-p4ykfv.js";
3
- import { t as defineMarkRule } from "./mark-rule-v2E7B4C0.js";
4
- import { t as defineMarkPasteRule } from "./paste-rule-qSz46pqD.js";
1
+ import { n as defineInputRule } from "./input-rule-dmsb3j6w.js";
2
+ import { t as defineEnterRule } from "./enter-rule-CzWOZF_Z.js";
3
+ import { t as defineMarkRule } from "./mark-rule-BcLB4Uv2.js";
4
+ import { t as defineMarkPasteRule } from "./paste-rule-pVb4sqvJ.js";
5
5
  import { addMark, defineCommands, defineMarkSpec, expandMark, removeMark, toggleMark, union } from "@prosekit/core";
6
6
  import { InputRule } from "@prosekit/pm/inputrules";
7
7
 
@@ -1,5 +1,5 @@
1
- import { n as defineInputRule } from "./input-rule-COGr_GBb.js";
2
- import { t as defineDropIndicator } from "./drop-indicator-BMvWUDXz.js";
1
+ import { n as defineInputRule } from "./input-rule-dmsb3j6w.js";
2
+ import { t as defineDropIndicator } from "./drop-indicator-B1QHFb5m.js";
3
3
  import { defineClipboardSerializer, defineCommands, defineKeymap, defineNodeSpec, definePlugin, insertNode, union } from "@prosekit/core";
4
4
  import { Plugin } from "@prosekit/pm/state";
5
5
  import { chainCommands, deleteSelection } from "@prosekit/pm/commands";
@@ -13,7 +13,7 @@ function defineLoroCommands() {
13
13
  //#endregion
14
14
  //#region src/loro/loro-cursor-plugin.ts
15
15
  function defineLoroCursorPlugin(options) {
16
- const { awareness,...rest } = options;
16
+ const { awareness, ...rest } = options;
17
17
  return definePlugin(LoroCursorPlugin(awareness, rest));
18
18
  }
19
19
 
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-loro.js","names":["keymap: Keymap","undo"],"sources":["../src/loro/loro-commands.ts","../src/loro/loro-cursor-plugin.ts","../src/loro/loro-keymap.ts","../src/loro/loro-sync-plugin.ts","../src/loro/loro-undo-plugin.ts","../src/loro/loro.ts"],"sourcesContent":["import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n redo,\n undo,\n} from 'loro-prosemirror'\n\nconst commands = {\n undo: () => undo,\n redo: () => redo,\n} as const\n\n/**\n * @internal\n */\nexport type LoroCommandsExtension = Extension<{\n Commands: {\n undo: []\n redo: []\n }\n}>\n\nexport function defineLoroCommands(): LoroCommandsExtension {\n return defineCommands(commands)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type {\n EditorState,\n Selection,\n} from '@prosekit/pm/state'\nimport type { DecorationAttrs } from '@prosekit/pm/view'\nimport type { PeerID } from 'loro-crdt'\nimport {\n LoroCursorPlugin,\n type CursorAwareness,\n} from 'loro-prosemirror'\n\nexport interface LoroCursorOptions {\n awareness: CursorAwareness\n getSelection?: (state: EditorState) => Selection\n createCursor?: (user: PeerID) => Element\n createSelection?: (user: PeerID) => DecorationAttrs\n}\n\nexport function defineLoroCursorPlugin(\n options: LoroCursorOptions,\n): PlainExtension {\n const { awareness, ...rest } = options\n return definePlugin(LoroCursorPlugin(awareness, rest))\n}\n","import {\n defineKeymap,\n isApple,\n type Keymap,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n redo,\n undo,\n} from 'loro-prosemirror'\n\nconst keymap: Keymap = {\n 'Mod-z': undo,\n 'Shift-Mod-z': redo,\n}\n\nif (!isApple) {\n keymap['Mod-y'] = redo\n}\n\nexport function defineLoroKeymap(): PlainExtension {\n return defineKeymap(keymap)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n LoroSyncPlugin,\n type LoroSyncPluginProps,\n} from 'loro-prosemirror'\n\nexport function defineLoroSyncPlugin(\n options: LoroSyncPluginProps,\n): PlainExtension {\n return definePlugin(LoroSyncPlugin(options))\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n LoroUndoPlugin,\n type LoroUndoPluginProps,\n} from 'loro-prosemirror'\n\nexport function defineLoroUndoPlugin(options: LoroUndoPluginProps): PlainExtension {\n return definePlugin(LoroUndoPlugin(options))\n}\n","import {\n Priority,\n union,\n withPriority,\n type PlainExtension,\n type Union,\n} from '@prosekit/core'\nimport type {\n CursorAwareness,\n LoroDocType,\n LoroSyncPluginProps,\n LoroUndoPluginProps,\n} from 'loro-prosemirror'\n\nimport {\n defineLoroCommands,\n type LoroCommandsExtension,\n} from './loro-commands'\nimport {\n defineLoroCursorPlugin,\n type LoroCursorOptions,\n} from './loro-cursor-plugin'\nimport { defineLoroKeymap } from './loro-keymap'\nimport { defineLoroSyncPlugin } from './loro-sync-plugin'\nimport { defineLoroUndoPlugin } from './loro-undo-plugin'\n\nexport interface LoroOptions {\n /**\n * The Loro instance handles the state of shared data.\n */\n doc: LoroDocType\n\n /**\n * The Awareness instance.\n */\n awareness: CursorAwareness\n\n /**\n * Extra options for `LoroSyncPlugin`.\n */\n sync?: Omit<LoroSyncPluginProps, 'doc'>\n\n /**\n * Extra options for the `LoroUndoPlugin`.\n */\n undo?: Omit<LoroUndoPluginProps, 'doc'>\n\n /**\n * Extra options for `LoroCursorPlugin`.\n */\n cursor?: Omit<LoroCursorOptions, 'awareness'>\n}\n\n/**\n * @internal\n */\nexport type LoroExtension = Union<[LoroCommandsExtension, PlainExtension]>\n\n/**\n * @public\n */\nexport function defineLoro(options: LoroOptions): LoroExtension {\n const { doc, awareness, sync, undo, cursor } = options\n\n return withPriority(\n union([\n defineLoroKeymap(),\n defineLoroCommands(),\n defineLoroCursorPlugin({ ...cursor, awareness }),\n defineLoroUndoPlugin({ ...undo, doc }),\n defineLoroSyncPlugin({ ...sync, doc }),\n ]),\n Priority.high,\n )\n}\n"],"mappings":";;;;AASA,MAAM,WAAW;CACf,YAAY;CACZ,YAAY;CACb;AAYD,SAAgB,qBAA4C;AAC1D,QAAO,eAAe,SAAS;;;;;ACHjC,SAAgB,uBACd,SACgB;CAChB,MAAM,EAAE,UAAW,GAAG,SAAS;AAC/B,QAAO,aAAa,iBAAiB,WAAW,KAAK,CAAC;;;;;ACfxD,MAAMA,SAAiB;CACrB,SAAS;CACT,eAAe;CAChB;AAED,IAAI,CAAC,QACH,QAAO,WAAW;AAGpB,SAAgB,mBAAmC;AACjD,QAAO,aAAa,OAAO;;;;;ACZ7B,SAAgB,qBACd,SACgB;AAChB,QAAO,aAAa,eAAe,QAAQ,CAAC;;;;;ACH9C,SAAgB,qBAAqB,SAA8C;AACjF,QAAO,aAAa,eAAe,QAAQ,CAAC;;;;;;;;ACmD9C,SAAgB,WAAW,SAAqC;CAC9D,MAAM,EAAE,KAAK,WAAW,MAAM,cAAM,WAAW;AAE/C,QAAO,aACL,MAAM;EACJ,kBAAkB;EAClB,oBAAoB;EACpB,uBAAuB;GAAE,GAAG;GAAQ;GAAW,CAAC;EAChD,qBAAqB;GAAE,GAAGC;GAAM;GAAK,CAAC;EACtC,qBAAqB;GAAE,GAAG;GAAM;GAAK,CAAC;EACvC,CAAC,EACF,SAAS,KACV"}
1
+ {"version":3,"file":"prosekit-extensions-loro.js","names":["keymap: Keymap","undo"],"sources":["../src/loro/loro-commands.ts","../src/loro/loro-cursor-plugin.ts","../src/loro/loro-keymap.ts","../src/loro/loro-sync-plugin.ts","../src/loro/loro-undo-plugin.ts","../src/loro/loro.ts"],"sourcesContent":["import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n redo,\n undo,\n} from 'loro-prosemirror'\n\nconst commands = {\n undo: () => undo,\n redo: () => redo,\n} as const\n\n/**\n * @internal\n */\nexport type LoroCommandsExtension = Extension<{\n Commands: {\n undo: []\n redo: []\n }\n}>\n\nexport function defineLoroCommands(): LoroCommandsExtension {\n return defineCommands(commands)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type {\n EditorState,\n Selection,\n} from '@prosekit/pm/state'\nimport type { DecorationAttrs } from '@prosekit/pm/view'\nimport type { PeerID } from 'loro-crdt'\nimport {\n LoroCursorPlugin,\n type CursorAwareness,\n} from 'loro-prosemirror'\n\nexport interface LoroCursorOptions {\n awareness: CursorAwareness\n getSelection?: (state: EditorState) => Selection\n createCursor?: (user: PeerID) => Element\n createSelection?: (user: PeerID) => DecorationAttrs\n}\n\nexport function defineLoroCursorPlugin(\n options: LoroCursorOptions,\n): PlainExtension {\n const { awareness, ...rest } = options\n return definePlugin(LoroCursorPlugin(awareness, rest))\n}\n","import {\n defineKeymap,\n isApple,\n type Keymap,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n redo,\n undo,\n} from 'loro-prosemirror'\n\nconst keymap: Keymap = {\n 'Mod-z': undo,\n 'Shift-Mod-z': redo,\n}\n\nif (!isApple) {\n keymap['Mod-y'] = redo\n}\n\nexport function defineLoroKeymap(): PlainExtension {\n return defineKeymap(keymap)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n LoroSyncPlugin,\n type LoroSyncPluginProps,\n} from 'loro-prosemirror'\n\nexport function defineLoroSyncPlugin(\n options: LoroSyncPluginProps,\n): PlainExtension {\n return definePlugin(LoroSyncPlugin(options))\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n LoroUndoPlugin,\n type LoroUndoPluginProps,\n} from 'loro-prosemirror'\n\nexport function defineLoroUndoPlugin(options: LoroUndoPluginProps): PlainExtension {\n return definePlugin(LoroUndoPlugin(options))\n}\n","import {\n Priority,\n union,\n withPriority,\n type PlainExtension,\n type Union,\n} from '@prosekit/core'\nimport type {\n CursorAwareness,\n LoroDocType,\n LoroSyncPluginProps,\n LoroUndoPluginProps,\n} from 'loro-prosemirror'\n\nimport {\n defineLoroCommands,\n type LoroCommandsExtension,\n} from './loro-commands'\nimport {\n defineLoroCursorPlugin,\n type LoroCursorOptions,\n} from './loro-cursor-plugin'\nimport { defineLoroKeymap } from './loro-keymap'\nimport { defineLoroSyncPlugin } from './loro-sync-plugin'\nimport { defineLoroUndoPlugin } from './loro-undo-plugin'\n\nexport interface LoroOptions {\n /**\n * The Loro instance handles the state of shared data.\n */\n doc: LoroDocType\n\n /**\n * The Awareness instance.\n */\n awareness: CursorAwareness\n\n /**\n * Extra options for `LoroSyncPlugin`.\n */\n sync?: Omit<LoroSyncPluginProps, 'doc'>\n\n /**\n * Extra options for the `LoroUndoPlugin`.\n */\n undo?: Omit<LoroUndoPluginProps, 'doc'>\n\n /**\n * Extra options for `LoroCursorPlugin`.\n */\n cursor?: Omit<LoroCursorOptions, 'awareness'>\n}\n\n/**\n * @internal\n */\nexport type LoroExtension = Union<[LoroCommandsExtension, PlainExtension]>\n\n/**\n * @public\n */\nexport function defineLoro(options: LoroOptions): LoroExtension {\n const { doc, awareness, sync, undo, cursor } = options\n\n return withPriority(\n union([\n defineLoroKeymap(),\n defineLoroCommands(),\n defineLoroCursorPlugin({ ...cursor, awareness }),\n defineLoroUndoPlugin({ ...undo, doc }),\n defineLoroSyncPlugin({ ...sync, doc }),\n ]),\n Priority.high,\n )\n}\n"],"mappings":";;;;AASA,MAAM,WAAW;CACf,YAAY;CACZ,YAAY;CACb;AAYD,SAAgB,qBAA4C;AAC1D,QAAO,eAAe,SAAS;;;;;ACHjC,SAAgB,uBACd,SACgB;CAChB,MAAM,EAAE,WAAW,GAAG,SAAS;AAC/B,QAAO,aAAa,iBAAiB,WAAW,KAAK,CAAC;;;;;ACfxD,MAAMA,SAAiB;CACrB,SAAS;CACT,eAAe;CAChB;AAED,IAAI,CAAC,QACH,QAAO,WAAW;AAGpB,SAAgB,mBAAmC;AACjD,QAAO,aAAa,OAAO;;;;;ACZ7B,SAAgB,qBACd,SACgB;AAChB,QAAO,aAAa,eAAe,QAAQ,CAAC;;;;;ACH9C,SAAgB,qBAAqB,SAA8C;AACjF,QAAO,aAAa,eAAe,QAAQ,CAAC;;;;;;;;ACmD9C,SAAgB,WAAW,SAAqC;CAC9D,MAAM,EAAE,KAAK,WAAW,MAAM,cAAM,WAAW;AAE/C,QAAO,aACL,MAAM;EACJ,kBAAkB;EAClB,oBAAoB;EACpB,uBAAuB;GAAE,GAAG;GAAQ;GAAW,CAAC;EAChD,qBAAqB;GAAE,GAAGC;GAAM;GAAK,CAAC;EACtC,qBAAqB;GAAE,GAAG;GAAM;GAAK,CAAC;EACvC,CAAC,EACF,SAAS,KACV"}
@@ -1,3 +1,3 @@
1
- import { t as defineMarkRule } from "./mark-rule-v2E7B4C0.js";
1
+ import { t as defineMarkRule } from "./mark-rule-BcLB4Uv2.js";
2
2
 
3
3
  export { defineMarkRule };
@@ -1,3 +1,3 @@
1
- import { n as definePasteRule, t as defineMarkPasteRule } from "./paste-rule-qSz46pqD.js";
1
+ import { n as definePasteRule, t as defineMarkPasteRule } from "./paste-rule-pVb4sqvJ.js";
2
2
 
3
3
  export { defineMarkPasteRule, definePasteRule };
@@ -1,5 +1,5 @@
1
- import "./drop-indicator-BMvWUDXz.js";
2
- import { p as findTable } from "./table-BLjD91VB.js";
1
+ import "./drop-indicator-B1QHFb5m.js";
2
+ import { p as findTable } from "./table-BRDh_9mG.js";
3
3
  import { definePlugin, isInCodeBlock, maybeRun } from "@prosekit/core";
4
4
  import { Plugin, PluginKey } from "@prosekit/pm/state";
5
5
  import { Decoration, DecorationSet } from "@prosekit/pm/view";
@@ -1,4 +1,4 @@
1
- import { r as defineMarkInputRule } from "./input-rule-COGr_GBb.js";
1
+ import { r as defineMarkInputRule } from "./input-rule-dmsb3j6w.js";
2
2
  import { canUseRegexLookbehind, defineCommands, defineKeymap, defineMarkSpec, toggleMark, union } from "@prosekit/core";
3
3
 
4
4
  //#region src/strike/index.ts
@@ -1,4 +1,4 @@
1
- import "./drop-indicator-BMvWUDXz.js";
2
- import { _ as insertTable, a as defineTableSpec, c as defineTableCommands, d as selectTableCell, f as selectTable, g as moveTableColumn, h as moveTableRow, i as defineTableRowSpec, l as selectTableRow, m as isCellSelection, n as defineTableCellSpec, o as defineTablePlugins, p as findTable, r as defineTableHeaderCellSpec, s as defineTableDropIndicator, t as defineTable, u as selectTableColumn, v as exitTable } from "./table-BLjD91VB.js";
1
+ import "./drop-indicator-B1QHFb5m.js";
2
+ import { _ as insertTable, a as defineTableSpec, c as defineTableCommands, d as selectTableCell, f as selectTable, g as moveTableColumn, h as moveTableRow, i as defineTableRowSpec, l as selectTableRow, m as isCellSelection, n as defineTableCellSpec, o as defineTablePlugins, p as findTable, r as defineTableHeaderCellSpec, s as defineTableDropIndicator, t as defineTable, u as selectTableColumn, v as exitTable } from "./table-BRDh_9mG.js";
3
3
 
4
4
  export { defineTable, defineTableCellSpec, defineTableCommands, defineTableDropIndicator, defineTableHeaderCellSpec, defineTablePlugins, defineTableRowSpec, defineTableSpec, exitTable, findTable, insertTable, isCellSelection, moveTableColumn, moveTableRow, selectTable, selectTableCell, selectTableColumn, selectTableRow };
@@ -13,7 +13,7 @@ function defineYjsCommands() {
13
13
  //#endregion
14
14
  //#region src/yjs/yjs-cursor-plugin.ts
15
15
  function defineYjsCursorPlugin(options) {
16
- const { awareness,...rest } = options;
16
+ const { awareness, ...rest } = options;
17
17
  return definePlugin(yCursorPlugin(awareness, rest));
18
18
  }
19
19
 
@@ -31,7 +31,7 @@ function defineYjsKeymap() {
31
31
  //#endregion
32
32
  //#region src/yjs/yjs-sync-plugin.ts
33
33
  function defineYjsSyncPlugin(options) {
34
- const { fragment,...rest } = options;
34
+ const { fragment, ...rest } = options;
35
35
  return definePlugin(ySyncPlugin(fragment, rest));
36
36
  }
37
37
 
@@ -1 +1 @@
1
- {"version":3,"file":"prosekit-extensions-yjs.js","names":["keymap: Keymap","yUndoPlugin","originalYUndoPlugin"],"sources":["../src/yjs/yjs-commands.ts","../src/yjs/yjs-cursor-plugin.ts","../src/yjs/yjs-keymap.ts","../src/yjs/yjs-sync-plugin.ts","../src/yjs/yjs-undo-plugin.ts","../src/yjs/yjs.ts"],"sourcesContent":["import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n redoCommand,\n undoCommand,\n} from 'y-prosemirror'\n\nconst commands = {\n undo: () => undoCommand,\n redo: () => redoCommand,\n} as const\n\n/**\n * @internal\n */\nexport type YjsCommandsExtension = Extension<{\n Commands: {\n undo: []\n redo: []\n }\n}>\n\nexport function defineYjsCommands(): YjsCommandsExtension {\n return defineCommands(commands)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { Plugin } from '@prosekit/pm/state'\nimport { yCursorPlugin } from 'y-prosemirror'\nimport type { Awareness } from 'y-protocols/awareness'\n\n/**\n * Options for `y-prosemirror`'s `yCursorPlugin`.\n */\nexport type YjsCursorPluginOptions = NonNullable<\n Parameters<typeof yCursorPlugin>[1]\n>\n\nexport interface YjsCursorOptions extends YjsCursorPluginOptions {\n awareness: Awareness\n}\n\nexport function defineYjsCursorPlugin(\n options: YjsCursorOptions,\n): PlainExtension {\n const { awareness, ...rest } = options\n return definePlugin(yCursorPlugin(awareness, rest) as Plugin)\n}\n","import {\n defineKeymap,\n isApple,\n type Keymap,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n redoCommand,\n undoCommand,\n} from 'y-prosemirror'\n\nconst keymap: Keymap = {\n 'Mod-z': undoCommand,\n 'Shift-Mod-z': redoCommand,\n}\n\nif (!isApple) {\n keymap['Mod-y'] = redoCommand\n}\n\nexport function defineYjsKeymap(): PlainExtension {\n return defineKeymap(keymap)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { Plugin } from '@prosekit/pm/state'\nimport { ySyncPlugin } from 'y-prosemirror'\nimport type * as Y from 'yjs'\n\n/**\n * Options for `y-prosemirror`'s `ySyncPlugin`.\n */\nexport type YjsSyncPluginOptions = NonNullable<\n Parameters<typeof ySyncPlugin>[1]\n>\n\nexport interface YjsSyncOptions extends YjsSyncPluginOptions {\n fragment: Y.XmlFragment\n}\n\nexport function defineYjsSyncPlugin(options: YjsSyncOptions): PlainExtension {\n const { fragment, ...rest } = options\n return definePlugin(ySyncPlugin(fragment, rest) as Plugin)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { ProseMirrorPlugin } from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\nimport {\n yUndoPlugin as originalYUndoPlugin,\n yUndoPluginKey,\n} from 'y-prosemirror'\nimport type { UndoManager as YjsUndoManager } from 'yjs'\n\ntype UndoManager = YjsUndoManager & { restore: () => void }\n\n/**\n * @see https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n */\nfunction fixYUndoPlugin(yUndoPluginInstance: ProseMirrorPlugin) {\n const originalUndoPluginView = yUndoPluginInstance.spec.view\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const pluginState = yUndoPluginKey.getState(view.state)\n if (!pluginState) {\n return {}\n }\n\n const undoManager = pluginState.undoManager as UndoManager\n\n if (undoManager.restore) {\n undoManager.restore()\n undoManager.restore = () => {}\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager)\n\n const observers = undoManager._observers\n\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager)\n }\n\n undoManager.doc.on(\n 'afterTransaction',\n undoManager.afterTransactionHandler,\n )\n\n undoManager._observers = observers\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy()\n }\n },\n }\n }\n}\n\n/**\n * Options for the `y-prosemirror`'s `yUndoPlugin`.\n */\nexport type YjsUndoPluginOptions = NonNullable<\n Parameters<typeof originalYUndoPlugin>[0]\n>\n\nexport interface YjsUndoOptions extends YjsUndoPluginOptions {}\n\n/**\n * @internal\n */\nfunction yUndoPlugin(options?: YjsUndoOptions) {\n const yUndoPluginInstance = originalYUndoPlugin(options)\n fixYUndoPlugin(yUndoPluginInstance)\n return yUndoPluginInstance\n}\n\n/**\n * @internal\n */\nexport function defineYjsUndoPlugin(options: YjsUndoOptions): PlainExtension {\n return definePlugin(yUndoPlugin(options))\n}\n","import {\n Priority,\n union,\n withPriority,\n type PlainExtension,\n type Union,\n} from '@prosekit/core'\nimport type { Awareness } from 'y-protocols/awareness'\nimport type * as Y from 'yjs'\n\nimport {\n defineYjsCommands,\n type YjsCommandsExtension,\n} from './yjs-commands'\nimport {\n defineYjsCursorPlugin,\n type YjsCursorPluginOptions,\n} from './yjs-cursor-plugin'\nimport { defineYjsKeymap } from './yjs-keymap'\nimport {\n defineYjsSyncPlugin,\n type YjsSyncPluginOptions,\n} from './yjs-sync-plugin'\nimport {\n defineYjsUndoPlugin,\n type YjsUndoPluginOptions,\n} from './yjs-undo-plugin'\n\nexport interface YjsOptions {\n /**\n * The Yjs instance handles the state of shared data.\n */\n doc: Y.Doc\n\n /**\n * The Awareness instance.\n */\n awareness: Awareness\n\n /**\n * The Yjs XmlFragment to use. If not provided,\n * `doc.getXmlFragment('prosemirror')` will be used.\n */\n fragment?: Y.XmlFragment\n\n /**\n * Options for `y-prosemirror`'s `ySyncPlugin`.\n */\n sync?: YjsSyncPluginOptions\n\n /**\n * Options for the `y-prosemirror`'s `yUndoPlugin`.\n */\n undo?: YjsUndoPluginOptions\n\n /**\n * Options for `y-prosemirror`'s `yCursorPlugin`.\n */\n cursor?: YjsCursorPluginOptions\n}\n\n/**\n * @internal\n */\nexport type YjsExtension = Union<[YjsCommandsExtension, PlainExtension]>\n\n/**\n * @public\n */\nexport function defineYjs(options: YjsOptions): YjsExtension {\n const { doc, awareness, sync, undo, cursor } = options\n const fragment = options.fragment ?? doc.getXmlFragment('prosemirror')\n\n return withPriority(\n union([\n defineYjsKeymap(),\n defineYjsCommands(),\n defineYjsCursorPlugin({ ...cursor, awareness }),\n defineYjsUndoPlugin({ ...undo }),\n defineYjsSyncPlugin({ ...sync, fragment }),\n ]),\n Priority.high,\n )\n}\n"],"mappings":";;;;AASA,MAAM,WAAW;CACf,YAAY;CACZ,YAAY;CACb;AAYD,SAAgB,oBAA0C;AACxD,QAAO,eAAe,SAAS;;;;;ACNjC,SAAgB,sBACd,SACgB;CAChB,MAAM,EAAE,UAAW,GAAG,SAAS;AAC/B,QAAO,aAAa,cAAc,WAAW,KAAK,CAAW;;;;;ACZ/D,MAAMA,SAAiB;CACrB,SAAS;CACT,eAAe;CAChB;AAED,IAAI,CAAC,QACH,QAAO,WAAW;AAGpB,SAAgB,kBAAkC;AAChD,QAAO,aAAa,OAAO;;;;;ACF7B,SAAgB,oBAAoB,SAAyC;CAC3E,MAAM,EAAE,SAAU,GAAG,SAAS;AAC9B,QAAO,aAAa,YAAY,UAAU,KAAK,CAAW;;;;;;;;ACJ5D,SAAS,eAAe,qBAAwC;CAC9D,MAAM,yBAAyB,oBAAoB,KAAK;AACxD,qBAAoB,KAAK,QAAQ,SAAqB;EACpD,MAAM,cAAc,eAAe,SAAS,KAAK,MAAM;AACvD,MAAI,CAAC,YACH,QAAO,EAAE;EAGX,MAAM,cAAc,YAAY;AAEhC,MAAI,YAAY,SAAS;AACvB,eAAY,SAAS;AACrB,eAAY,gBAAgB;;EAG9B,MAAM,UAAU,yBACZ,uBAAuB,KAAK,GAC5B;AAEJ,SAAO,EACL,eAAe;GACb,MAAM,iBAAiB,YAAY,eAAe,IAAI,YAAY;GAElE,MAAM,YAAY,YAAY;AAE9B,eAAY,gBAAgB;AAC1B,QAAI,eACF,aAAY,eAAe,IAAI,YAAY;AAG7C,gBAAY,IAAI,GACd,oBACA,YAAY,wBACb;AAED,gBAAY,aAAa;;AAG3B,OAAI,SAAS,QACX,SAAQ,SAAS;KAGtB;;;;;;AAgBL,SAASC,cAAY,SAA0B;CAC7C,MAAM,sBAAsBC,YAAoB,QAAQ;AACxD,gBAAe,oBAAoB;AACnC,QAAO;;;;;AAMT,SAAgB,oBAAoB,SAAyC;AAC3E,QAAO,aAAaD,cAAY,QAAQ,CAAC;;;;;;;;AChB3C,SAAgB,UAAU,SAAmC;CAC3D,MAAM,EAAE,KAAK,WAAW,MAAM,MAAM,WAAW;CAC/C,MAAM,WAAW,QAAQ,YAAY,IAAI,eAAe,cAAc;AAEtE,QAAO,aACL,MAAM;EACJ,iBAAiB;EACjB,mBAAmB;EACnB,sBAAsB;GAAE,GAAG;GAAQ;GAAW,CAAC;EAC/C,oBAAoB,EAAE,GAAG,MAAM,CAAC;EAChC,oBAAoB;GAAE,GAAG;GAAM;GAAU,CAAC;EAC3C,CAAC,EACF,SAAS,KACV"}
1
+ {"version":3,"file":"prosekit-extensions-yjs.js","names":["keymap: Keymap","yUndoPlugin","originalYUndoPlugin"],"sources":["../src/yjs/yjs-commands.ts","../src/yjs/yjs-cursor-plugin.ts","../src/yjs/yjs-keymap.ts","../src/yjs/yjs-sync-plugin.ts","../src/yjs/yjs-undo-plugin.ts","../src/yjs/yjs.ts"],"sourcesContent":["import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n redoCommand,\n undoCommand,\n} from 'y-prosemirror'\n\nconst commands = {\n undo: () => undoCommand,\n redo: () => redoCommand,\n} as const\n\n/**\n * @internal\n */\nexport type YjsCommandsExtension = Extension<{\n Commands: {\n undo: []\n redo: []\n }\n}>\n\nexport function defineYjsCommands(): YjsCommandsExtension {\n return defineCommands(commands)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { Plugin } from '@prosekit/pm/state'\nimport { yCursorPlugin } from 'y-prosemirror'\nimport type { Awareness } from 'y-protocols/awareness'\n\n/**\n * Options for `y-prosemirror`'s `yCursorPlugin`.\n */\nexport type YjsCursorPluginOptions = NonNullable<\n Parameters<typeof yCursorPlugin>[1]\n>\n\nexport interface YjsCursorOptions extends YjsCursorPluginOptions {\n awareness: Awareness\n}\n\nexport function defineYjsCursorPlugin(\n options: YjsCursorOptions,\n): PlainExtension {\n const { awareness, ...rest } = options\n return definePlugin(yCursorPlugin(awareness, rest) as Plugin)\n}\n","import {\n defineKeymap,\n isApple,\n type Keymap,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n redoCommand,\n undoCommand,\n} from 'y-prosemirror'\n\nconst keymap: Keymap = {\n 'Mod-z': undoCommand,\n 'Shift-Mod-z': redoCommand,\n}\n\nif (!isApple) {\n keymap['Mod-y'] = redoCommand\n}\n\nexport function defineYjsKeymap(): PlainExtension {\n return defineKeymap(keymap)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { Plugin } from '@prosekit/pm/state'\nimport { ySyncPlugin } from 'y-prosemirror'\nimport type * as Y from 'yjs'\n\n/**\n * Options for `y-prosemirror`'s `ySyncPlugin`.\n */\nexport type YjsSyncPluginOptions = NonNullable<\n Parameters<typeof ySyncPlugin>[1]\n>\n\nexport interface YjsSyncOptions extends YjsSyncPluginOptions {\n fragment: Y.XmlFragment\n}\n\nexport function defineYjsSyncPlugin(options: YjsSyncOptions): PlainExtension {\n const { fragment, ...rest } = options\n return definePlugin(ySyncPlugin(fragment, rest) as Plugin)\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport type { ProseMirrorPlugin } from '@prosekit/pm/state'\nimport type { EditorView } from '@prosekit/pm/view'\nimport {\n yUndoPlugin as originalYUndoPlugin,\n yUndoPluginKey,\n} from 'y-prosemirror'\nimport type { UndoManager as YjsUndoManager } from 'yjs'\n\ntype UndoManager = YjsUndoManager & { restore: () => void }\n\n/**\n * @see https://github.com/yjs/y-prosemirror/issues/114 and https://github.com/yjs/y-prosemirror/issues/102\n */\nfunction fixYUndoPlugin(yUndoPluginInstance: ProseMirrorPlugin) {\n const originalUndoPluginView = yUndoPluginInstance.spec.view\n yUndoPluginInstance.spec.view = (view: EditorView) => {\n const pluginState = yUndoPluginKey.getState(view.state)\n if (!pluginState) {\n return {}\n }\n\n const undoManager = pluginState.undoManager as UndoManager\n\n if (undoManager.restore) {\n undoManager.restore()\n undoManager.restore = () => {}\n }\n\n const viewRet = originalUndoPluginView\n ? originalUndoPluginView(view)\n : undefined\n\n return {\n destroy: () => {\n const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager)\n\n const observers = undoManager._observers\n\n undoManager.restore = () => {\n if (hasUndoManSelf) {\n undoManager.trackedOrigins.add(undoManager)\n }\n\n undoManager.doc.on(\n 'afterTransaction',\n undoManager.afterTransactionHandler,\n )\n\n undoManager._observers = observers\n }\n\n if (viewRet?.destroy) {\n viewRet.destroy()\n }\n },\n }\n }\n}\n\n/**\n * Options for the `y-prosemirror`'s `yUndoPlugin`.\n */\nexport type YjsUndoPluginOptions = NonNullable<\n Parameters<typeof originalYUndoPlugin>[0]\n>\n\nexport interface YjsUndoOptions extends YjsUndoPluginOptions {}\n\n/**\n * @internal\n */\nfunction yUndoPlugin(options?: YjsUndoOptions) {\n const yUndoPluginInstance = originalYUndoPlugin(options)\n fixYUndoPlugin(yUndoPluginInstance)\n return yUndoPluginInstance\n}\n\n/**\n * @internal\n */\nexport function defineYjsUndoPlugin(options: YjsUndoOptions): PlainExtension {\n return definePlugin(yUndoPlugin(options))\n}\n","import {\n Priority,\n union,\n withPriority,\n type PlainExtension,\n type Union,\n} from '@prosekit/core'\nimport type { Awareness } from 'y-protocols/awareness'\nimport type * as Y from 'yjs'\n\nimport {\n defineYjsCommands,\n type YjsCommandsExtension,\n} from './yjs-commands'\nimport {\n defineYjsCursorPlugin,\n type YjsCursorPluginOptions,\n} from './yjs-cursor-plugin'\nimport { defineYjsKeymap } from './yjs-keymap'\nimport {\n defineYjsSyncPlugin,\n type YjsSyncPluginOptions,\n} from './yjs-sync-plugin'\nimport {\n defineYjsUndoPlugin,\n type YjsUndoPluginOptions,\n} from './yjs-undo-plugin'\n\nexport interface YjsOptions {\n /**\n * The Yjs instance handles the state of shared data.\n */\n doc: Y.Doc\n\n /**\n * The Awareness instance.\n */\n awareness: Awareness\n\n /**\n * The Yjs XmlFragment to use. If not provided,\n * `doc.getXmlFragment('prosemirror')` will be used.\n */\n fragment?: Y.XmlFragment\n\n /**\n * Options for `y-prosemirror`'s `ySyncPlugin`.\n */\n sync?: YjsSyncPluginOptions\n\n /**\n * Options for the `y-prosemirror`'s `yUndoPlugin`.\n */\n undo?: YjsUndoPluginOptions\n\n /**\n * Options for `y-prosemirror`'s `yCursorPlugin`.\n */\n cursor?: YjsCursorPluginOptions\n}\n\n/**\n * @internal\n */\nexport type YjsExtension = Union<[YjsCommandsExtension, PlainExtension]>\n\n/**\n * @public\n */\nexport function defineYjs(options: YjsOptions): YjsExtension {\n const { doc, awareness, sync, undo, cursor } = options\n const fragment = options.fragment ?? doc.getXmlFragment('prosemirror')\n\n return withPriority(\n union([\n defineYjsKeymap(),\n defineYjsCommands(),\n defineYjsCursorPlugin({ ...cursor, awareness }),\n defineYjsUndoPlugin({ ...undo }),\n defineYjsSyncPlugin({ ...sync, fragment }),\n ]),\n Priority.high,\n )\n}\n"],"mappings":";;;;AASA,MAAM,WAAW;CACf,YAAY;CACZ,YAAY;CACb;AAYD,SAAgB,oBAA0C;AACxD,QAAO,eAAe,SAAS;;;;;ACNjC,SAAgB,sBACd,SACgB;CAChB,MAAM,EAAE,WAAW,GAAG,SAAS;AAC/B,QAAO,aAAa,cAAc,WAAW,KAAK,CAAW;;;;;ACZ/D,MAAMA,SAAiB;CACrB,SAAS;CACT,eAAe;CAChB;AAED,IAAI,CAAC,QACH,QAAO,WAAW;AAGpB,SAAgB,kBAAkC;AAChD,QAAO,aAAa,OAAO;;;;;ACF7B,SAAgB,oBAAoB,SAAyC;CAC3E,MAAM,EAAE,UAAU,GAAG,SAAS;AAC9B,QAAO,aAAa,YAAY,UAAU,KAAK,CAAW;;;;;;;;ACJ5D,SAAS,eAAe,qBAAwC;CAC9D,MAAM,yBAAyB,oBAAoB,KAAK;AACxD,qBAAoB,KAAK,QAAQ,SAAqB;EACpD,MAAM,cAAc,eAAe,SAAS,KAAK,MAAM;AACvD,MAAI,CAAC,YACH,QAAO,EAAE;EAGX,MAAM,cAAc,YAAY;AAEhC,MAAI,YAAY,SAAS;AACvB,eAAY,SAAS;AACrB,eAAY,gBAAgB;;EAG9B,MAAM,UAAU,yBACZ,uBAAuB,KAAK,GAC5B;AAEJ,SAAO,EACL,eAAe;GACb,MAAM,iBAAiB,YAAY,eAAe,IAAI,YAAY;GAElE,MAAM,YAAY,YAAY;AAE9B,eAAY,gBAAgB;AAC1B,QAAI,eACF,aAAY,eAAe,IAAI,YAAY;AAG7C,gBAAY,IAAI,GACd,oBACA,YAAY,wBACb;AAED,gBAAY,aAAa;;AAG3B,OAAI,SAAS,QACX,SAAQ,SAAS;KAGtB;;;;;;AAgBL,SAASC,cAAY,SAA0B;CAC7C,MAAM,sBAAsBC,YAAoB,QAAQ;AACxD,gBAAe,oBAAoB;AACnC,QAAO;;;;;AAMT,SAAgB,oBAAoB,SAAyC;AAC3E,QAAO,aAAaD,cAAY,QAAQ,CAAC;;;;;;;;AChB3C,SAAgB,UAAU,SAAmC;CAC3D,MAAM,EAAE,KAAK,WAAW,MAAM,MAAM,WAAW;CAC/C,MAAM,WAAW,QAAQ,YAAY,IAAI,eAAe,cAAc;AAEtE,QAAO,aACL,MAAM;EACJ,iBAAiB;EACjB,mBAAmB;EACnB,sBAAsB;GAAE,GAAG;GAAQ;GAAW,CAAC;EAC/C,oBAAoB,EAAE,GAAG,MAAM,CAAC;EAChC,oBAAoB;GAAE,GAAG;GAAM;GAAU,CAAC;EAC3C,CAAC,EACF,SAAS,KACV"}
@@ -16,4 +16,4 @@ type HighlighterResult = {
16
16
  declare function createOrGetHighlighter(options: HighlighterOptions): HighlighterResult;
17
17
  //#endregion
18
18
  export { createOrGetHighlighter as i, HighlighterResult as n, ShikiHighlighterOptions as r, HighlighterOptions as t };
19
- //# sourceMappingURL=shiki-highlighter-chunk-DcY3Ud8v.d.ts.map
19
+ //# sourceMappingURL=shiki-highlighter-chunk-rkzofy4z.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shiki-highlighter-chunk-DcY3Ud8v.d.ts","names":[],"sources":["../src/code-block/shiki-highlighter-chunk.ts"],"sourcesContent":[],"mappings":";;;UAeiB,uBAAA,SAAgC,0BAA0B,iBAAiB;AAA3E,UAEA,kBAAA,SAA2B,IAFH,CAEQ,uBAFR,EAAA,OAAA,GAAA,QAAA,CAAA,CAAA;EAAkC,MAAA,EAGjE,YAHiE,EAAA;EAAiB,KAAA,EAAA,CAIlF,eAJkF,GAIhE,eAJgE,CAAA,EAAA;;AAAlB,KAwC9D,iBAAA,GAxC8D;EAEzD,WAAA,EAwCA,WAxCmB;EAAa,OAAA,CAAA,EAAA,SAAA;CACvC,GAAA;EACA,WAAA,CAAA,EAAA,SAAA;EAAkB,OAAA,EA2Cf,OA3Ce,CAAA,IAAA,CAAA;CAFgB;AAAI,iBAgDhC,sBAAA,CAhDgC,OAAA,EAiDrC,kBAjDqC,CAAA,EAkD7C,iBAlD6C"}
1
+ {"version":3,"file":"shiki-highlighter-chunk-rkzofy4z.d.ts","names":[],"sources":["../src/code-block/shiki-highlighter-chunk.ts"],"sourcesContent":[],"mappings":";;;UAeiB,uBAAA,SAAgC,0BAA0B,iBAAiB;AAA3E,UAEA,kBAAA,SAA2B,IAFH,CAEQ,uBAFR,EAAA,OAAA,GAAA,QAAA,CAAA,CAAA;EAAkC,MAAA,EAGjE,YAHiE,EAAA;EAAiB,KAAA,EAAA,CAIlF,eAJkF,GAIhE,eAJgE,CAAA,EAAA;;AAAlB,KAwC9D,iBAAA,GAxC8D;EAEzD,WAAA,EAwCA,WAxCmB;EAAa,OAAA,CAAA,EAAA,SAAA;CACvC,GAAA;EACA,WAAA,CAAA,EAAA,SAAA;EAAkB,OAAA,EA2Cf,OA3Ce,CAAA,IAAA,CAAA;CAFgB;AAAI,iBAgDhC,sBAAA,CAhDgC,OAAA,EAiDrC,kBAjDqC,CAAA,EAkD7C,iBAlD6C"}
@@ -1,2 +1,2 @@
1
- import { i as createOrGetHighlighter, n as HighlighterResult, r as ShikiHighlighterOptions, t as HighlighterOptions } from "./shiki-highlighter-chunk-DcY3Ud8v.js";
1
+ import { i as createOrGetHighlighter, n as HighlighterResult, r as ShikiHighlighterOptions, t as HighlighterOptions } from "./shiki-highlighter-chunk-rkzofy4z.js";
2
2
  export { HighlighterOptions, HighlighterResult, ShikiHighlighterOptions, createOrGetHighlighter };
@@ -1,4 +1,4 @@
1
- import { t as defineDropIndicator } from "./drop-indicator-BMvWUDXz.js";
1
+ import { t as defineDropIndicator } from "./drop-indicator-B1QHFb5m.js";
2
2
  import { defaultBlockAt, defineCommands, defineNodeSpec, definePlugin, getNodeType, insertNode, union } from "@prosekit/core";
3
3
  import { TextSelection } from "@prosekit/pm/state";
4
4
  import { CellSelection, TableMap, addColumnAfter, addColumnBefore, addRowAfter, addRowBefore, columnResizing, deleteCellSelection, deleteColumn, deleteRow, deleteTable, findCellPos, findCellRange, findTable, mergeCells, moveTableColumn, moveTableRow, splitCell, tableEditing, tableNodes } from "prosemirror-tables";
@@ -285,4 +285,4 @@ function defineTable() {
285
285
 
286
286
  //#endregion
287
287
  export { insertTable as _, defineTableSpec as a, defineTableCommands as c, selectTableCell as d, selectTable as f, moveTableColumn as g, moveTableRow as h, defineTableRowSpec as i, selectTableRow as l, isCellSelection as m, defineTableCellSpec as n, defineTablePlugins as o, findTable as p, defineTableHeaderCellSpec as r, defineTableDropIndicator as s, defineTable as t, selectTableColumn as u, exitTable as v };
288
- //# sourceMappingURL=table-BLjD91VB.js.map
288
+ //# sourceMappingURL=table-BRDh_9mG.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"table-BLjD91VB.js","names":["exitTable: Command","onDrag: DragEventHandler","match: boolean"],"sources":["../src/table/table-commands/exit-table.ts","../src/table/table-commands/insert-table.ts","../src/table/table-utils.ts","../src/table/table-commands/select-table.ts","../src/table/table-commands/select-table-cell.ts","../src/table/table-commands/select-table-column.ts","../src/table/table-commands/select-table-row.ts","../src/table/table-commands.ts","../src/table/table-drop-indicator.ts","../src/table/table-plugins.ts","../src/table/table-spec.ts","../src/table/table.ts"],"sourcesContent":["import { defaultBlockAt } from '@prosekit/core'\nimport { TextSelection } from '@prosekit/pm/state'\nimport type { Command } from '@prosekit/pm/state'\nimport type { TableRole } from 'prosemirror-tables'\n\n/**\n * When the selection is in a table node, create a default block after the table\n * table, and move the cursor there.\n *\n * @public\n */\nexport const exitTable: Command = (state, dispatch) => {\n const { $head, $anchor } = state.selection\n\n if (!$head.sameParent($anchor)) {\n return false\n }\n\n let tableStart = -1\n let tableDepth = -1\n for (let depth = $head.depth; depth >= 0; depth--) {\n const node = $head.node(depth)\n if ((node.type.spec.tableRole as TableRole) === 'table') {\n tableStart = $head.before(depth)\n tableDepth = depth\n }\n }\n\n if (tableStart < 0 || tableDepth <= 0) {\n return false\n }\n\n const above = $head.node(tableDepth - 1)\n const after = $head.indexAfter(tableDepth - 1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n const node = type?.createAndFill()\n\n if (!type || !node || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n if (dispatch) {\n const pos = $head.after(tableDepth)\n const tr = state.tr.replaceWith(pos, pos, node)\n tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1))\n dispatch(tr.scrollIntoView())\n }\n return true\n}\n","import {\n getNodeType,\n insertNode,\n} from '@prosekit/core'\nimport type { Schema } from '@prosekit/pm/model'\nimport type { Command } from '@prosekit/pm/state'\n\nfunction createEmptyTable(\n schema: Schema,\n row: number,\n col: number,\n header: boolean,\n) {\n const tableType = getNodeType(schema, 'table')\n const tableRowType = getNodeType(schema, 'tableRow')\n const tableCellType = getNodeType(schema, 'tableCell')\n const tableHeaderCellType = getNodeType(schema, 'tableHeaderCell')\n\n if (header) {\n const headerCell = tableHeaderCellType.createAndFill()!\n const headerCells = repeat(headerCell, col)\n const headerRow = tableRowType.createAndFill(null, headerCells)!\n\n const bodyCell = tableCellType.createAndFill()!\n const bodyCells = repeat(bodyCell, col)\n const bodyRow = tableRowType.createAndFill(null, bodyCells)!\n const bodyRows = repeat(bodyRow, row - 1)\n\n return tableType.createAndFill(null, [headerRow, ...bodyRows])!\n } else {\n const bodyCell = tableCellType.createAndFill()!\n const bodyCells = repeat(bodyCell, col)\n const bodyRow = tableRowType.createAndFill(null, bodyCells)!\n const bodyRows = repeat(bodyRow, row)\n\n return tableType.createAndFill(null, bodyRows)!\n }\n}\n\nfunction repeat<T>(node: T, length: number): T[] {\n return Array<T>(length).fill(node)\n}\n\n/**\n * @public\n */\nexport interface InsertTableOptions {\n /**\n * The number of rows in the table.\n */\n row: number\n\n /**\n * The number of columns in the table.\n */\n col: number\n\n /**\n * Whether the table has a header row.\n *\n * @default false\n */\n header?: boolean\n}\n\n/**\n * Insert a table node with the given number of rows and columns, and optionally\n * a header row.\n *\n * @param options\n *\n * @public\n */\nexport function insertTable(options: InsertTableOptions): Command {\n return (state, dispatch, view) => {\n const { row, col, header = false } = options\n const table = createEmptyTable(state.schema, row, col, header)\n return insertNode({ node: table })(state, dispatch, view)\n }\n}\n","import { CellSelection } from 'prosemirror-tables'\n\nexport {\n findCellPos,\n findCellRange,\n findTable,\n} from 'prosemirror-tables'\n\n/**\n * Checks if the given object is a `CellSelection` instance.\n *\n * @public\n */\nexport function isCellSelection(value: unknown): value is CellSelection {\n return value instanceof CellSelection\n}\n","import type { Command } from '@prosekit/pm/state'\nimport {\n CellSelection,\n TableMap,\n} from 'prosemirror-tables'\n\nimport { findTable } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableOptions {\n /**\n * A hit position of the table to select from. By default, the selection\n * anchor will be used.\n */\n pos?: number\n}\n\n/**\n * @public\n */\nexport function selectTable(options?: SelectTableOptions): Command {\n return (state, dispatch) => {\n const $pos = options?.pos\n ? state.doc.resolve(options.pos)\n : state.selection.$anchor\n const table = findTable($pos)\n if (!table) {\n return false\n }\n const map = TableMap.get(table.node)\n if (map.map.length === 0) {\n return false\n }\n if (dispatch) {\n let tr = state.tr\n const firstCellPosInTable = map.map[0]\n const lastCellPosInTable = map.map[map.map.length - 1]\n const firstCellPos = table.pos + firstCellPosInTable + 1\n const lastCellPos = table.pos + lastCellPosInTable + 1\n const $firstCellPos = tr.doc.resolve(firstCellPos)\n const $lastCellPos = tr.doc.resolve(lastCellPos)\n const selection = new CellSelection($firstCellPos, $lastCellPos)\n tr = tr.setSelection(selection)\n dispatch?.(tr)\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellPos } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableCellOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n pos?: number\n}\n\n/**\n * @public\n */\nexport function selectTableCell(options?: SelectTableCellOptions): Command {\n return (state, dispatch) => {\n const $cellPos = findCellPos(\n state.doc,\n options?.pos ?? state.selection.anchor,\n )\n if (!$cellPos) {\n return false\n }\n if (dispatch) {\n const selection = new CellSelection($cellPos)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellRange } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableColumnOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n anchor?: number\n\n /**\n * A hit position of the table cell to select to. By default, the selection\n * head will be used.\n */\n head?: number\n}\n\n/**\n * @public\n */\nexport function selectTableColumn(options?: SelectTableColumnOptions): Command {\n return (state, dispatch) => {\n const range = findCellRange(state.selection, options?.anchor, options?.head)\n if (!range) {\n return false\n }\n if (dispatch) {\n const [$anchorCell, $headCell] = range\n const selection = CellSelection.colSelection($anchorCell, $headCell)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellRange } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableRowOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n anchor?: number\n\n /**\n * A hit position of the table cell to select to. By default, the selection\n * head will be used.\n */\n head?: number\n}\n\n/**\n * @public\n */\nexport function selectTableRow(options?: SelectTableRowOptions): Command {\n return (state, dispatch) => {\n const range = findCellRange(state.selection, options?.anchor, options?.head)\n if (!range) {\n return false\n }\n if (dispatch) {\n const [$anchorCell, $headCell] = range\n const selection = CellSelection.rowSelection($anchorCell, $headCell)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n addColumnAfter,\n addColumnBefore,\n addRowAfter,\n addRowBefore,\n deleteColumn,\n deleteRow,\n deleteTable,\n mergeCells,\n splitCell,\n} from 'prosemirror-tables'\n\nimport { deleteCellSelection } from './table-commands/delete-cell-selection'\nimport { exitTable } from './table-commands/exit-table'\nimport {\n insertTable,\n type InsertTableOptions,\n} from './table-commands/insert-table'\nimport {\n moveTableColumn,\n type MoveTableColumnOptions,\n} from './table-commands/move-table-column'\nimport {\n moveTableRow,\n type MoveTableRowOptions,\n} from './table-commands/move-table-row'\nimport {\n selectTable,\n type SelectTableOptions,\n} from './table-commands/select-table'\nimport {\n selectTableCell,\n type SelectTableCellOptions,\n} from './table-commands/select-table-cell'\nimport {\n selectTableColumn,\n type SelectTableColumnOptions,\n} from './table-commands/select-table-column'\nimport {\n selectTableRow,\n type SelectTableRowOptions,\n} from './table-commands/select-table-row'\n\n/**\n * @internal\n */\nexport type TableCommandsExtension = Extension<{\n Commands: {\n insertTable: [options: InsertTableOptions]\n exitTable: []\n\n selectTable: [options?: SelectTableOptions]\n selectTableCell: [options?: SelectTableCellOptions]\n selectTableColumn: [options?: SelectTableColumnOptions]\n selectTableRow: [options?: SelectTableRowOptions]\n\n addTableColumnBefore: []\n addTableColumnAfter: []\n addTableRowAbove: []\n addTableRowBelow: []\n\n deleteTable: []\n deleteTableColumn: []\n deleteTableRow: []\n deleteCellSelection: []\n\n mergeTableCells: []\n splitTableCell: []\n\n moveTableRow: [options: MoveTableRowOptions]\n moveTableColumn: [options: MoveTableColumnOptions]\n }\n}>\n\n/**\n * Adds commands for working with `table` nodes.\n *\n * @public\n */\nexport function defineTableCommands(): TableCommandsExtension {\n return defineCommands({\n insertTable,\n exitTable: () => exitTable,\n\n selectTable,\n selectTableCell,\n selectTableColumn,\n selectTableRow,\n\n addTableColumnBefore: () => addColumnBefore,\n addTableColumnAfter: () => addColumnAfter,\n addTableRowAbove: () => addRowBefore,\n addTableRowBelow: () => addRowAfter,\n\n deleteTable: () => deleteTable,\n deleteTableColumn: () => deleteColumn,\n deleteTableRow: () => deleteRow,\n deleteCellSelection: () => deleteCellSelection,\n\n mergeTableCells: () => mergeCells,\n splitTableCell: () => splitCell,\n\n moveTableRow,\n moveTableColumn,\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport type { DragEventHandler } from '../drop-indicator'\nimport { defineDropIndicator } from '../drop-indicator'\n\n/**\n * Hides the drop indicator when dragging a table column or row by using the\n * table handle.\n *\n * @internal\n */\nexport function defineTableDropIndicator(): PlainExtension {\n return defineDropIndicator({\n onDrag,\n })\n}\n\nconst matchMap = new WeakMap<DataTransfer, boolean>()\n\nconst onDrag: DragEventHandler = ({ event }): boolean => {\n const dataTransfer = event.dataTransfer\n if (!dataTransfer) return true\n\n let match: boolean\n\n if (matchMap.has(dataTransfer)) {\n match = matchMap.get(dataTransfer)!\n } else {\n // On Safari, accessing `dataTransfer.types` is more than 10x slower than in\n // Chrome. This becomes a bottleneck when `onDrag` is called frequently, so\n // we cache the result in a WeakMap.\n const types = dataTransfer.types\n match = types.includes('application/x-prosekit-table-handle-drag')\n matchMap.set(dataTransfer, match)\n }\n\n // Don't show the drop indicator when the drag event has\n // \"application/x-prosekit-table-handle-drag\" type.\n return !match\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n columnResizing,\n tableEditing,\n} from 'prosemirror-tables'\n\n/**\n * @public\n */\nexport function defineTablePlugins(): PlainExtension {\n return definePlugin([tableEditing(), columnResizing()])\n}\n","import {\n defineNodeSpec,\n type Extension,\n} from '@prosekit/core'\nimport type {\n AttributeSpec,\n Attrs,\n} from '@prosekit/pm/model'\nimport { tableNodes } from 'prosemirror-tables'\n\nconst cellContent = 'block+'\n\n/**\n * @public\n */\nexport interface CellAttrs {\n colspan?: number\n rowspan?: number\n colwidth?: number[] | null\n}\n\nconst cellAttrs = {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n colwidth: { default: null },\n} satisfies Record<string, AttributeSpec>\n\n/**\n * @internal\n */\nexport type TableSpecExtension = Extension<{\n Nodes: {\n table: Attrs\n }\n}>\n\nconst specs = tableNodes({\n tableGroup: 'block',\n cellContent,\n cellAttributes: {},\n})\n\n/**\n * @internal\n */\nexport function defineTableSpec(): TableSpecExtension {\n return defineNodeSpec({\n ...specs['table'],\n content: 'tableRow+',\n name: 'table',\n })\n}\n\n/**\n * @internal\n */\nexport type TableRowSpecExtension = Extension<{\n Nodes: {\n tableRow: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineTableRowSpec(): TableRowSpecExtension {\n return defineNodeSpec({\n ...specs['table_row'],\n content: '(tableCell | tableHeaderCell)*',\n name: 'tableRow',\n })\n}\n\n/**\n * @internal\n */\nexport type TableCellSpecExtension = Extension<{\n Nodes: {\n tableCell: CellAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineTableCellSpec(): TableCellSpecExtension {\n return defineNodeSpec({\n ...specs['table_cell'],\n name: 'tableCell',\n attrs: cellAttrs,\n })\n}\n\n/**\n * @internal\n */\nexport type TableHeaderCellSpecExtension = Extension<{\n Nodes: {\n tableHeaderCell: CellAttrs\n }\n}>\n\nexport function defineTableHeaderCellSpec(): TableHeaderCellSpecExtension {\n return defineNodeSpec({\n ...specs['table_header'],\n name: 'tableHeaderCell',\n attrs: cellAttrs,\n })\n}\n","import {\n union,\n type Union,\n} from '@prosekit/core'\n\nimport {\n defineTableCommands,\n type TableCommandsExtension,\n} from './table-commands'\nimport { defineTableDropIndicator } from './table-drop-indicator'\nimport { defineTablePlugins } from './table-plugins'\nimport {\n defineTableCellSpec,\n defineTableHeaderCellSpec,\n defineTableRowSpec,\n defineTableSpec,\n type TableCellSpecExtension,\n type TableHeaderCellSpecExtension,\n type TableRowSpecExtension,\n type TableSpecExtension,\n} from './table-spec'\n\n/**\n * @internal\n */\nexport type TableExtension = Union<\n [\n TableSpecExtension,\n TableRowSpecExtension,\n TableCellSpecExtension,\n TableHeaderCellSpecExtension,\n TableCommandsExtension,\n ]\n>\n\n/**\n * @public\n */\nexport function defineTable(): TableExtension {\n return union(\n defineTableSpec(),\n defineTableRowSpec(),\n defineTableCellSpec(),\n defineTableHeaderCellSpec(),\n defineTablePlugins(),\n defineTableCommands(),\n defineTableDropIndicator(),\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-BRDh_9mG.js","names":["exitTable: Command","onDrag: DragEventHandler","match: boolean"],"sources":["../src/table/table-commands/exit-table.ts","../src/table/table-commands/insert-table.ts","../src/table/table-utils.ts","../src/table/table-commands/select-table.ts","../src/table/table-commands/select-table-cell.ts","../src/table/table-commands/select-table-column.ts","../src/table/table-commands/select-table-row.ts","../src/table/table-commands.ts","../src/table/table-drop-indicator.ts","../src/table/table-plugins.ts","../src/table/table-spec.ts","../src/table/table.ts"],"sourcesContent":["import { defaultBlockAt } from '@prosekit/core'\nimport { TextSelection } from '@prosekit/pm/state'\nimport type { Command } from '@prosekit/pm/state'\nimport type { TableRole } from 'prosemirror-tables'\n\n/**\n * When the selection is in a table node, create a default block after the table\n * table, and move the cursor there.\n *\n * @public\n */\nexport const exitTable: Command = (state, dispatch) => {\n const { $head, $anchor } = state.selection\n\n if (!$head.sameParent($anchor)) {\n return false\n }\n\n let tableStart = -1\n let tableDepth = -1\n for (let depth = $head.depth; depth >= 0; depth--) {\n const node = $head.node(depth)\n if ((node.type.spec.tableRole as TableRole) === 'table') {\n tableStart = $head.before(depth)\n tableDepth = depth\n }\n }\n\n if (tableStart < 0 || tableDepth <= 0) {\n return false\n }\n\n const above = $head.node(tableDepth - 1)\n const after = $head.indexAfter(tableDepth - 1)\n const type = defaultBlockAt(above.contentMatchAt(after))\n const node = type?.createAndFill()\n\n if (!type || !node || !above.canReplaceWith(after, after, type)) {\n return false\n }\n\n if (dispatch) {\n const pos = $head.after(tableDepth)\n const tr = state.tr.replaceWith(pos, pos, node)\n tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1))\n dispatch(tr.scrollIntoView())\n }\n return true\n}\n","import {\n getNodeType,\n insertNode,\n} from '@prosekit/core'\nimport type { Schema } from '@prosekit/pm/model'\nimport type { Command } from '@prosekit/pm/state'\n\nfunction createEmptyTable(\n schema: Schema,\n row: number,\n col: number,\n header: boolean,\n) {\n const tableType = getNodeType(schema, 'table')\n const tableRowType = getNodeType(schema, 'tableRow')\n const tableCellType = getNodeType(schema, 'tableCell')\n const tableHeaderCellType = getNodeType(schema, 'tableHeaderCell')\n\n if (header) {\n const headerCell = tableHeaderCellType.createAndFill()!\n const headerCells = repeat(headerCell, col)\n const headerRow = tableRowType.createAndFill(null, headerCells)!\n\n const bodyCell = tableCellType.createAndFill()!\n const bodyCells = repeat(bodyCell, col)\n const bodyRow = tableRowType.createAndFill(null, bodyCells)!\n const bodyRows = repeat(bodyRow, row - 1)\n\n return tableType.createAndFill(null, [headerRow, ...bodyRows])!\n } else {\n const bodyCell = tableCellType.createAndFill()!\n const bodyCells = repeat(bodyCell, col)\n const bodyRow = tableRowType.createAndFill(null, bodyCells)!\n const bodyRows = repeat(bodyRow, row)\n\n return tableType.createAndFill(null, bodyRows)!\n }\n}\n\nfunction repeat<T>(node: T, length: number): T[] {\n return Array<T>(length).fill(node)\n}\n\n/**\n * @public\n */\nexport interface InsertTableOptions {\n /**\n * The number of rows in the table.\n */\n row: number\n\n /**\n * The number of columns in the table.\n */\n col: number\n\n /**\n * Whether the table has a header row.\n *\n * @default false\n */\n header?: boolean\n}\n\n/**\n * Insert a table node with the given number of rows and columns, and optionally\n * a header row.\n *\n * @param options\n *\n * @public\n */\nexport function insertTable(options: InsertTableOptions): Command {\n return (state, dispatch, view) => {\n const { row, col, header = false } = options\n const table = createEmptyTable(state.schema, row, col, header)\n return insertNode({ node: table })(state, dispatch, view)\n }\n}\n","import { CellSelection } from 'prosemirror-tables'\n\nexport {\n findCellPos,\n findCellRange,\n findTable,\n} from 'prosemirror-tables'\n\n/**\n * Checks if the given object is a `CellSelection` instance.\n *\n * @public\n */\nexport function isCellSelection(value: unknown): value is CellSelection {\n return value instanceof CellSelection\n}\n","import type { Command } from '@prosekit/pm/state'\nimport {\n CellSelection,\n TableMap,\n} from 'prosemirror-tables'\n\nimport { findTable } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableOptions {\n /**\n * A hit position of the table to select from. By default, the selection\n * anchor will be used.\n */\n pos?: number\n}\n\n/**\n * @public\n */\nexport function selectTable(options?: SelectTableOptions): Command {\n return (state, dispatch) => {\n const $pos = options?.pos\n ? state.doc.resolve(options.pos)\n : state.selection.$anchor\n const table = findTable($pos)\n if (!table) {\n return false\n }\n const map = TableMap.get(table.node)\n if (map.map.length === 0) {\n return false\n }\n if (dispatch) {\n let tr = state.tr\n const firstCellPosInTable = map.map[0]\n const lastCellPosInTable = map.map[map.map.length - 1]\n const firstCellPos = table.pos + firstCellPosInTable + 1\n const lastCellPos = table.pos + lastCellPosInTable + 1\n const $firstCellPos = tr.doc.resolve(firstCellPos)\n const $lastCellPos = tr.doc.resolve(lastCellPos)\n const selection = new CellSelection($firstCellPos, $lastCellPos)\n tr = tr.setSelection(selection)\n dispatch?.(tr)\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellPos } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableCellOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n pos?: number\n}\n\n/**\n * @public\n */\nexport function selectTableCell(options?: SelectTableCellOptions): Command {\n return (state, dispatch) => {\n const $cellPos = findCellPos(\n state.doc,\n options?.pos ?? state.selection.anchor,\n )\n if (!$cellPos) {\n return false\n }\n if (dispatch) {\n const selection = new CellSelection($cellPos)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellRange } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableColumnOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n anchor?: number\n\n /**\n * A hit position of the table cell to select to. By default, the selection\n * head will be used.\n */\n head?: number\n}\n\n/**\n * @public\n */\nexport function selectTableColumn(options?: SelectTableColumnOptions): Command {\n return (state, dispatch) => {\n const range = findCellRange(state.selection, options?.anchor, options?.head)\n if (!range) {\n return false\n }\n if (dispatch) {\n const [$anchorCell, $headCell] = range\n const selection = CellSelection.colSelection($anchorCell, $headCell)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import type { Command } from '@prosekit/pm/state'\nimport { CellSelection } from 'prosemirror-tables'\n\nimport { findCellRange } from '../table-utils'\n\n/**\n * @public\n */\nexport interface SelectTableRowOptions {\n /**\n * A hit position of the table cell to select from. By default, the selection\n * anchor will be used.\n */\n anchor?: number\n\n /**\n * A hit position of the table cell to select to. By default, the selection\n * head will be used.\n */\n head?: number\n}\n\n/**\n * @public\n */\nexport function selectTableRow(options?: SelectTableRowOptions): Command {\n return (state, dispatch) => {\n const range = findCellRange(state.selection, options?.anchor, options?.head)\n if (!range) {\n return false\n }\n if (dispatch) {\n const [$anchorCell, $headCell] = range\n const selection = CellSelection.rowSelection($anchorCell, $headCell)\n dispatch(state.tr.setSelection(selection))\n }\n return true\n }\n}\n","import {\n defineCommands,\n type Extension,\n} from '@prosekit/core'\nimport {\n addColumnAfter,\n addColumnBefore,\n addRowAfter,\n addRowBefore,\n deleteColumn,\n deleteRow,\n deleteTable,\n mergeCells,\n splitCell,\n} from 'prosemirror-tables'\n\nimport { deleteCellSelection } from './table-commands/delete-cell-selection'\nimport { exitTable } from './table-commands/exit-table'\nimport {\n insertTable,\n type InsertTableOptions,\n} from './table-commands/insert-table'\nimport {\n moveTableColumn,\n type MoveTableColumnOptions,\n} from './table-commands/move-table-column'\nimport {\n moveTableRow,\n type MoveTableRowOptions,\n} from './table-commands/move-table-row'\nimport {\n selectTable,\n type SelectTableOptions,\n} from './table-commands/select-table'\nimport {\n selectTableCell,\n type SelectTableCellOptions,\n} from './table-commands/select-table-cell'\nimport {\n selectTableColumn,\n type SelectTableColumnOptions,\n} from './table-commands/select-table-column'\nimport {\n selectTableRow,\n type SelectTableRowOptions,\n} from './table-commands/select-table-row'\n\n/**\n * @internal\n */\nexport type TableCommandsExtension = Extension<{\n Commands: {\n insertTable: [options: InsertTableOptions]\n exitTable: []\n\n selectTable: [options?: SelectTableOptions]\n selectTableCell: [options?: SelectTableCellOptions]\n selectTableColumn: [options?: SelectTableColumnOptions]\n selectTableRow: [options?: SelectTableRowOptions]\n\n addTableColumnBefore: []\n addTableColumnAfter: []\n addTableRowAbove: []\n addTableRowBelow: []\n\n deleteTable: []\n deleteTableColumn: []\n deleteTableRow: []\n deleteCellSelection: []\n\n mergeTableCells: []\n splitTableCell: []\n\n moveTableRow: [options: MoveTableRowOptions]\n moveTableColumn: [options: MoveTableColumnOptions]\n }\n}>\n\n/**\n * Adds commands for working with `table` nodes.\n *\n * @public\n */\nexport function defineTableCommands(): TableCommandsExtension {\n return defineCommands({\n insertTable,\n exitTable: () => exitTable,\n\n selectTable,\n selectTableCell,\n selectTableColumn,\n selectTableRow,\n\n addTableColumnBefore: () => addColumnBefore,\n addTableColumnAfter: () => addColumnAfter,\n addTableRowAbove: () => addRowBefore,\n addTableRowBelow: () => addRowAfter,\n\n deleteTable: () => deleteTable,\n deleteTableColumn: () => deleteColumn,\n deleteTableRow: () => deleteRow,\n deleteCellSelection: () => deleteCellSelection,\n\n mergeTableCells: () => mergeCells,\n splitTableCell: () => splitCell,\n\n moveTableRow,\n moveTableColumn,\n })\n}\n","import type { PlainExtension } from '@prosekit/core'\n\nimport type { DragEventHandler } from '../drop-indicator'\nimport { defineDropIndicator } from '../drop-indicator'\n\n/**\n * Hides the drop indicator when dragging a table column or row by using the\n * table handle.\n *\n * @internal\n */\nexport function defineTableDropIndicator(): PlainExtension {\n return defineDropIndicator({\n onDrag,\n })\n}\n\nconst matchMap = new WeakMap<DataTransfer, boolean>()\n\nconst onDrag: DragEventHandler = ({ event }): boolean => {\n const dataTransfer = event.dataTransfer\n if (!dataTransfer) return true\n\n let match: boolean\n\n if (matchMap.has(dataTransfer)) {\n match = matchMap.get(dataTransfer)!\n } else {\n // On Safari, accessing `dataTransfer.types` is more than 10x slower than in\n // Chrome. This becomes a bottleneck when `onDrag` is called frequently, so\n // we cache the result in a WeakMap.\n const types = dataTransfer.types\n match = types.includes('application/x-prosekit-table-handle-drag')\n matchMap.set(dataTransfer, match)\n }\n\n // Don't show the drop indicator when the drag event has\n // \"application/x-prosekit-table-handle-drag\" type.\n return !match\n}\n","import {\n definePlugin,\n type PlainExtension,\n} from '@prosekit/core'\nimport {\n columnResizing,\n tableEditing,\n} from 'prosemirror-tables'\n\n/**\n * @public\n */\nexport function defineTablePlugins(): PlainExtension {\n return definePlugin([tableEditing(), columnResizing()])\n}\n","import {\n defineNodeSpec,\n type Extension,\n} from '@prosekit/core'\nimport type {\n AttributeSpec,\n Attrs,\n} from '@prosekit/pm/model'\nimport { tableNodes } from 'prosemirror-tables'\n\nconst cellContent = 'block+'\n\n/**\n * @public\n */\nexport interface CellAttrs {\n colspan?: number\n rowspan?: number\n colwidth?: number[] | null\n}\n\nconst cellAttrs = {\n colspan: { default: 1 },\n rowspan: { default: 1 },\n colwidth: { default: null },\n} satisfies Record<string, AttributeSpec>\n\n/**\n * @internal\n */\nexport type TableSpecExtension = Extension<{\n Nodes: {\n table: Attrs\n }\n}>\n\nconst specs = tableNodes({\n tableGroup: 'block',\n cellContent,\n cellAttributes: {},\n})\n\n/**\n * @internal\n */\nexport function defineTableSpec(): TableSpecExtension {\n return defineNodeSpec({\n ...specs['table'],\n content: 'tableRow+',\n name: 'table',\n })\n}\n\n/**\n * @internal\n */\nexport type TableRowSpecExtension = Extension<{\n Nodes: {\n tableRow: Attrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineTableRowSpec(): TableRowSpecExtension {\n return defineNodeSpec({\n ...specs['table_row'],\n content: '(tableCell | tableHeaderCell)*',\n name: 'tableRow',\n })\n}\n\n/**\n * @internal\n */\nexport type TableCellSpecExtension = Extension<{\n Nodes: {\n tableCell: CellAttrs\n }\n}>\n\n/**\n * @internal\n */\nexport function defineTableCellSpec(): TableCellSpecExtension {\n return defineNodeSpec({\n ...specs['table_cell'],\n name: 'tableCell',\n attrs: cellAttrs,\n })\n}\n\n/**\n * @internal\n */\nexport type TableHeaderCellSpecExtension = Extension<{\n Nodes: {\n tableHeaderCell: CellAttrs\n }\n}>\n\nexport function defineTableHeaderCellSpec(): TableHeaderCellSpecExtension {\n return defineNodeSpec({\n ...specs['table_header'],\n name: 'tableHeaderCell',\n attrs: cellAttrs,\n })\n}\n","import {\n union,\n type Union,\n} from '@prosekit/core'\n\nimport {\n defineTableCommands,\n type TableCommandsExtension,\n} from './table-commands'\nimport { defineTableDropIndicator } from './table-drop-indicator'\nimport { defineTablePlugins } from './table-plugins'\nimport {\n defineTableCellSpec,\n defineTableHeaderCellSpec,\n defineTableRowSpec,\n defineTableSpec,\n type TableCellSpecExtension,\n type TableHeaderCellSpecExtension,\n type TableRowSpecExtension,\n type TableSpecExtension,\n} from './table-spec'\n\n/**\n * @internal\n */\nexport type TableExtension = Union<\n [\n TableSpecExtension,\n TableRowSpecExtension,\n TableCellSpecExtension,\n TableHeaderCellSpecExtension,\n TableCommandsExtension,\n ]\n>\n\n/**\n * @public\n */\nexport function defineTable(): TableExtension {\n return union(\n defineTableSpec(),\n defineTableRowSpec(),\n defineTableCellSpec(),\n defineTableHeaderCellSpec(),\n defineTablePlugins(),\n defineTableCommands(),\n defineTableDropIndicator(),\n )\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.12.0",
4
+ "version": "0.12.2",
5
5
  "private": false,
6
6
  "description": "A collection of common extensions for ProseKit",
7
7
  "author": {
@@ -216,9 +216,9 @@
216
216
  "prosemirror-highlight": "^0.13.0",
217
217
  "prosemirror-search": "^1.1.0",
218
218
  "prosemirror-tables": "^1.8.1",
219
- "shiki": "^3.14.0",
220
- "@prosekit/core": "^0.8.4",
221
- "@prosekit/pm": "^0.1.13"
219
+ "shiki": "^3.15.0",
220
+ "@prosekit/pm": "^0.1.14",
221
+ "@prosekit/core": "^0.8.7"
222
222
  },
223
223
  "peerDependencies": {
224
224
  "loro-crdt": ">= 0.16.7",
@@ -244,19 +244,19 @@
244
244
  "@types/diffable-html": "^5.0.2",
245
245
  "diffable-html": "^6.0.1",
246
246
  "just-pick": "^4.2.0",
247
- "loro-crdt": "^1.8.8",
248
- "loro-prosemirror": "^0.3.6",
247
+ "loro-crdt": "^1.9.0",
248
+ "loro-prosemirror": "^0.3.7",
249
249
  "rehype-parse": "^9.0.1",
250
250
  "rehype-remark": "^10.0.1",
251
251
  "remark-gfm": "^4.0.1",
252
252
  "remark-html": "^16.0.1",
253
253
  "remark-parse": "^11.0.0",
254
254
  "remark-stringify": "^11.0.0",
255
- "tsdown": "^0.15.12",
256
- "type-fest": "^5.1.0",
255
+ "tsdown": "^0.16.5",
256
+ "type-fest": "^5.2.0",
257
257
  "typescript": "~5.9.3",
258
258
  "unified": "^11.0.5",
259
- "vitest": "^4.0.5",
259
+ "vitest": "^4.0.10",
260
260
  "y-prosemirror": "^1.3.7",
261
261
  "y-protocols": "^1.0.6",
262
262
  "yjs": "^13.6.27",
@@ -11,8 +11,7 @@ import { userEvent } from 'vitest/browser'
11
11
  *
12
12
  * @internal
13
13
  */
14
-
15
- export async function pressKey(input: string) {
14
+ export async function pressKey(input: string): Promise<void> {
16
15
  const keys = input.split('-').map((key) => {
17
16
  if (key.toLowerCase() === 'mod') {
18
17
  return isApple ? 'Meta' : 'Control'
@@ -31,6 +30,6 @@ export async function pressKey(input: string) {
31
30
  return await userEvent.keyboard(seq.join(''))
32
31
  }
33
32
 
34
- export async function inputText(input: string) {
33
+ export async function inputText(input: string): Promise<void> {
35
34
  return await userEvent.keyboard(input)
36
35
  }